Browse code

Merged PKCS#11 patch. Pre-2.1_beta3

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

james authored on 2005/10/13 17:38:41
Showing 21 changed files
... ...
@@ -212,4 +212,8 @@ GNU Public License (GPL)
212 212
   In the Windows binary distribution of OpenVPN, the
213 213
   GPL is reproduced below.
214 214
 
215
+RSA Security Inc. License
216
+------------------------
217
+
218
+  This software is using RSA Security Inc. PKCS #11 Cryptographic Token Interface (Cryptoki).
215 219
 
... ...
@@ -3,8 +3,9 @@ Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
3 3
 
4 4
 $Id$
5 5
 
6
-2005.10.xx -- Version 2.1-beta3
6
+2005.10.14 -- Version 2.1-beta3
7 7
 
8
+* Added PKCS#11 support (Alon Bar-Lev).
8 9
 * NOTE TO PACKAGE MAINTAINERS: Moved "plugin"
9 10
   directory to "plugins".  This is
10 11
   to work around a strange problem with the
... ...
@@ -65,6 +65,7 @@ openvpn_SOURCES = \
65 65
 	multi.c multi.h \
66 66
         ntlm.c ntlm.h \
67 67
 	occ.c occ.h occ-inline.h \
68
+	pkcs11.c pkcs11.h \
68 69
 	openvpn.c openvpn.h \
69 70
 	openvpn-plugin.h \
70 71
 	options.c options.h \
... ...
@@ -74,6 +74,9 @@ typedef unsigned long in_addr_t;
74 74
 /* Enable management server capability */
75 75
 #define ENABLE_MANAGEMENT 1
76 76
 
77
+/* Enable PKCS#11 support */
78
+#define ENABLE_PKCS11 1
79
+
77 80
 /* Enable HTTP proxy support */
78 81
 #define ENABLE_HTTP_PROXY 1
79 82
 
... ...
@@ -25,7 +25,7 @@ dnl Process this file with autoconf to produce a configure script.
25 25
 
26 26
 AC_PREREQ(2.50)
27 27
 
28
-AC_INIT([OpenVPN], [2.1_beta2], [openvpn-users@lists.sourceforge.net], [openvpn])
28
+AC_INIT([OpenVPN], [2.1_beta3], [openvpn-users@lists.sourceforge.net], [openvpn])
29 29
 AM_CONFIG_HEADER(config.h)
30 30
 AC_CONFIG_SRCDIR(syshead.h)
31 31
 
... ...
@@ -71,6 +71,12 @@ AC_ARG_ENABLE(management,
71 71
    [MANAGEMENT="yes"]
72 72
 )
73 73
 
74
+AC_ARG_ENABLE(pkcs11,
75
+   [  --disable-pkcs11        Disable pkcs11 support],
76
+   [PKCS11="$enableval"],
77
+   [PKCS11="yes"]
78
+)
79
+
74 80
 AC_ARG_ENABLE(socks,
75 81
    [  --disable-socks         Disable Socks support],
76 82
    [SOCKS="$enableval"],
... ...
@@ -584,6 +590,11 @@ if test "$MANAGEMENT" = "yes"; then
584 584
    AC_DEFINE(ENABLE_MANAGEMENT, 1, [Enable management server capability])
585 585
 fi
586 586
 
587
+dnl enable pkcs11 capability
588
+if test "$PKCS11" = "yes"; then
589
+   AC_DEFINE(ENABLE_PKCS11, 1, [Enable PKCS#11 capability])
590
+fi
591
+
587 592
 dnl enable socks 
588 593
 if test "$SOCKS" = "yes"; then
589 594
    AC_DEFINE(ENABLE_SOCKS, 1, [Enable Socks proxy support])
590 595
new file mode 100644
... ...
@@ -0,0 +1,66 @@
0
+/* cryptoki.h include file for PKCS #11. */
1
+/* $Revision: 1.4 $ */
2
+
3
+/* License to copy and use this software is granted provided that it is
4
+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
5
+ * (Cryptoki)" in all material mentioning or referencing this software.
6
+
7
+ * License is also granted to make and use derivative works provided that
8
+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
9
+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or 
10
+ * referencing the derived work.
11
+
12
+ * RSA Security Inc. makes no representations concerning either the 
13
+ * merchantability of this software or the suitability of this software for
14
+ * any particular purpose. It is provided "as is" without express or implied
15
+ * warranty of any kind.
16
+ */
17
+
18
+/* This is a sample file containing the top level include directives
19
+ * for building Win32 Cryptoki libraries and applications.
20
+ */
21
+
22
+#ifndef ___CRYPTOKI_H_INC___
23
+#define ___CRYPTOKI_H_INC___
24
+
25
+#pragma pack(push, cryptoki, 1)
26
+
27
+/* Specifies that the function is a DLL entry point. */
28
+#define CK_IMPORT_SPEC __declspec(dllimport)
29
+
30
+/* Define CRYPTOKI_EXPORTS during the build of cryptoki libraries. Do
31
+ * not define it in applications.
32
+ */
33
+#ifdef CRYPTOKI_EXPORTS
34
+/* Specified that the function is an exported DLL entry point. */
35
+#define CK_EXPORT_SPEC __declspec(dllexport) 
36
+#else
37
+#define CK_EXPORT_SPEC CK_IMPORT_SPEC 
38
+#endif
39
+
40
+/* Ensures the calling convention for Win32 builds */
41
+#define CK_CALL_SPEC __cdecl
42
+
43
+#define CK_PTR *
44
+
45
+#define CK_DEFINE_FUNCTION(returnType, name) \
46
+  returnType CK_EXPORT_SPEC CK_CALL_SPEC name
47
+
48
+#define CK_DECLARE_FUNCTION(returnType, name) \
49
+  returnType CK_EXPORT_SPEC CK_CALL_SPEC name
50
+
51
+#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
52
+  returnType CK_IMPORT_SPEC (CK_CALL_SPEC CK_PTR name)
53
+
54
+#define CK_CALLBACK_FUNCTION(returnType, name) \
55
+  returnType (CK_CALL_SPEC CK_PTR name)
56
+
57
+#ifndef NULL_PTR
58
+#define NULL_PTR 0
59
+#endif
60
+
61
+#include "pkcs11/pkcs11.h"
62
+
63
+#pragma pack(pop, cryptoki)
64
+
65
+#endif /* ___CRYPTOKI_H_INC___ */
0 66
new file mode 100644
... ...
@@ -0,0 +1,35 @@
0
+/* cryptoki.h include file for PKCS #11. */
1
+/* $Revision: 1.4 $ */
2
+
3
+/* License to copy and use this software is granted provided that it is
4
+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
5
+ * (Cryptoki)" in all material mentioning or referencing this software.
6
+
7
+ * License is also granted to make and use derivative works provided that
8
+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
9
+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or 
10
+ * referencing the derived work.
11
+
12
+ * RSA Security Inc. makes no representations concerning either the 
13
+ * merchantability of this software or the suitability of this software for
14
+ * any particular purpose. It is provided "as is" without express or implied
15
+ * warranty of any kind.
16
+ */
17
+
18
+#ifndef ___CRYPTOKI_H_INC___
19
+#define ___CRYPTOKI_H_INC___
20
+
21
+#define CK_PTR *
22
+
23
+#define CK_DEFINE_FUNCTION(returnType, name) returnType name
24
+#define CK_DECLARE_FUNCTION(returnType, name) returnType name
25
+#define CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name)
26
+#define CK_CALLBACK_FUNCTION(returnType, name) returnType (* name)
27
+
28
+#ifndef NULL_PTR
29
+#define NULL_PTR 0
30
+#endif
31
+
32
+#include "pkcs11/pkcs11.h"
33
+
34
+#endif /* ___CRYPTOKI_H_INC___ */
... ...
@@ -127,6 +127,7 @@
127 127
 #define D_MANAGEMENT_DEBUG   LOGLEV(7, 70, M_DEBUG)  /* show --management debug info */
128 128
 #define D_PLUGIN_DEBUG       LOGLEV(7, 70, M_DEBUG)  /* show verbose plugin calls */
129 129
 #define D_SOCKET_DEBUG       LOGLEV(7, 70, M_DEBUG)  /* show socket.[ch] debugging info */
130
+#define D_SHOW_PKCS11        LOGLEV(7, 70, M_DEBUG)  /* show PKCS#11 actions */
130 131
 #define D_ALIGN_DEBUG        LOGLEV(7, 70, M_DEBUG)  /* show verbose struct alignment info */
131 132
 #define D_PACKET_TRUNC_DEBUG LOGLEV(7, 70, M_DEBUG)  /* PACKET_TRUNCATION_CHECK verbose */
132 133
 
... ...
@@ -151,6 +152,7 @@
151 151
 #define D_LINK_RW_VERBOSE    LOGLEV(9, 70, M_DEBUG)  /* show link reads/writes with greater verbosity */
152 152
 #define D_STREAM_DEBUG       LOGLEV(9, 70, M_DEBUG)  /* show TCP stream debug info */
153 153
 #define D_WIN32_IO           LOGLEV(9, 70, M_DEBUG)  /* win32 I/O debugging info */
154
+#define D_PKCS11_DEBUG       LOGLEV(9, 70, M_DEBUG)  /* show PKCS#11 debugging */
154 155
 
155 156
 #define D_SHAPER_DEBUG       LOGLEV(10, 70, M_DEBUG) /* show traffic shaper info */
156 157
 
... ...
@@ -38,6 +38,7 @@
38 38
 #include "otime.h"
39 39
 #include "pool.h"
40 40
 #include "gremlin.h"
41
+#include "pkcs11.h"
41 42
 
42 43
 #include "memdbg.h"
43 44
 
... ...
@@ -110,6 +111,14 @@ context_init_1 (struct context *c)
110 110
   /* Certificate password input */
111 111
   if (c->options.key_pass_file)
112 112
     pem_password_setup (c->options.key_pass_file);
113
+
114
+#if defined(ENABLE_PKCS11)
115
+  {
116
+    int i;
117
+    for (i=0;i<MAX_PARMS && c->options.pkcs11_providers[i] != NULL;i++)
118
+     add_pkcs11 (c->options.pkcs11_providers[i], c->options.pkcs11_sign_mode[i]);
119
+  }
120
+#endif
113 121
 #endif
114 122
   
115 123
 #if P2MP
... ...
@@ -223,6 +232,12 @@ uninit_static (void)
223 223
 
224 224
 #ifdef USE_CRYPTO
225 225
   free_ssl_lib ();
226
+
227
+#ifdef USE_SSL
228
+#ifdef ENABLE_PKCS11
229
+  free_pkcs11 ();
230
+#endif
231
+#endif
226 232
 #endif
227 233
 
228 234
 #if defined(MEASURE_TLS_HANDSHAKE_STATS) && defined(USE_CRYPTO) && defined(USE_SSL)
... ...
@@ -11,11 +11,11 @@ H=/c/src
11 11
 
12 12
 # Output NSIS-ready tree here (will be deleted
13 13
 # if already exists).
14
-OUT=$H/openvpn-build
14
+OUT=$H/21
15 15
 
16 16
 # Source distribution is here.  Can be the top
17 17
 # level directory of exploded tarball.
18
-IN=/y/openvpn/20/openvpn
18
+IN=/y/openvpn/21/openvpn
19 19
 
20 20
 # Already built OpenSSL tree.
21 21
 SSL=$H/openssl-0.9.7g
... ...
@@ -54,9 +54,11 @@ gcc -O2 $SCRIPTS/u2d.c -o $U2D
54 54
 echo BUILD output dir from source
55 55
 rm -rf $OUT
56 56
 mkdir $OUT
57
+mkdir $OUT/pkcs11
57 58
 
58 59
 cp $IN/*.[ch] $OUT
59 60
 rm -f $OUT/config.h
61
+cp $IN/pkcs11/*.h $OUT/pkcs11
60 62
 
61 63
 if [ $MISC ]; then
62 64
   cp $MISC/*.* $OUT
... ...
@@ -96,6 +96,7 @@ HEADERS = \
96 96
 	ntlm.h \
97 97
 	occ-inline.h \
98 98
 	occ.h \
99
+	pkcs11.h \
99 100
         openvpn.h \
100 101
 	openvpn-plugin.h \
101 102
 	options.h \
... ...
@@ -150,6 +151,7 @@ OBJS =  base64.o \
150 150
 	multi.o \
151 151
 	ntlm.o \
152 152
 	occ.o \
153
+	pkcs11.o \
153 154
         openvpn.o \
154 155
 	options.o \
155 156
 	otime.o \
... ...
@@ -81,6 +81,7 @@ HEADERS = \
81 81
 	ntlm.h \
82 82
 	occ-inline.h \
83 83
 	occ.h \
84
+	pkcs11.h \
84 85
         openvpn.h \
85 86
 	openvpn-plugin.h \
86 87
 	options.h \
... ...
@@ -135,6 +136,7 @@ OBJS =  base64.obj \
135 135
 	multi.obj \
136 136
 	ntlm.obj \
137 137
 	occ.obj \
138
+	pkcs11.obj \
138 139
         openvpn.obj \
139 140
 	options.obj \
140 141
 	otime.obj \
... ...
@@ -202,6 +202,13 @@ openvpn \- secure IP tunnel daemon.
202 202
 [\ \fB\-\-ping\-restart\fR\ \fIn\fR\ ]
203 203
 [\ \fB\-\-ping\-timer\-rem\fR\ ]
204 204
 [\ \fB\-\-ping\fR\ \fIn\fR\ ]
205
+[\ \fB\-\-pkcs11\-providers\fR\ \fIprovider...\fR\ ]
206
+[\ \fB\-\-pkcs11\-sign\-mode\fR\ \fImode...\fR\ ]
207
+[\ \fB\-\-pkcs11\-slot\-type\fR\ \fItype\fR\ ]
208
+[\ \fB\-\-pkcs11\-slot\fR\ \fIname\fR\ ]
209
+[\ \fB\-\-pkcs11\-id\-type\fR\ \fItype\fR\ ]
210
+[\ \fB\-\-pkcs11\-id\fR\ \fIname\fR\ ]
211
+[\ \fB\-\-pkcs11\-protected\-authentication\fR\ ]
205 212
 [\ \fB\-\-pkcs12\fR\ \fIfile\fR\ ]
206 213
 [\ \fB\-\-plugin\fR\ \fImodule\-pathname\ init\-string\fR\ ]
207 214
 [\ \fB\-\-port\fR\ \fIport\fR\ ]
... ...
@@ -239,6 +246,8 @@ openvpn \- secure IP tunnel daemon.
239 239
 [\ \fB\-\-show\-ciphers\fR\ ]
240 240
 [\ \fB\-\-show\-digests\fR\ ]
241 241
 [\ \fB\-\-show\-engines\fR\ ]
242
+[\ \fB\-\-show\-pkcs11\-slots\fR\ \fIprovider\fR\ ]
243
+[\ \fB\-\-show\-pkcs11\-objects\fR\ \fIprovider\ slot\fR\ ]
242 244
 [\ \fB\-\-show\-net\-up\fR\ ]
243 245
 [\ \fB\-\-show\-net\fR\ ]
244 246
 [\ \fB\-\-show\-tls\fR\ ]
... ...
@@ -3513,6 +3522,73 @@ and
3513 3513
 .B --key.
3514 3514
 .\"*********************************************************
3515 3515
 .TP
3516
+.B --pkcs11-providers provider...
3517
+Specify a RSA Security Inc. PKCS #11 Cryptographic Token Interface (Cryptoki) providers
3518
+to load.
3519
+This option can be used instead of
3520
+.B --cert, --key,
3521
+and
3522
+.B --pkcs12.
3523
+.\"*********************************************************
3524
+.TP
3525
+.B --pkcs11-sign-mode mode...
3526
+Specify which method to use in order to sign data. A different mode can be specified
3527
+for each provider. Mode can be one of the following:
3528
+
3529
+.B 'auto'
3530
+(default) -- Try to determind automatically.
3531
+.br
3532
+.B 'recover'
3533
+-- Use SignRecover.
3534
+.br
3535
+.B 'sign'
3536
+-- Use Sign.
3537
+.br
3538
+.\"*********************************************************
3539
+.TP
3540
+.B --pkcs11-slot-type type
3541
+Specify how to locate the correct slot. Type can be one of the following:
3542
+
3543
+.B 'id'
3544
+-- Locate the slot by a numeric id. The format is [provider:]id, for example, slot 2 of provider 1
3545
+is encoded as 1:2. If you have only one provider you can omit the provider number.
3546
+The provider number is set by the order specified in the --pkcs11-providers option.
3547
+.br
3548
+.B 'name'
3549
+-- Locate the slot by its name.
3550
+.br
3551
+.B 'label'
3552
+-- Locate the slot by the label of the token that reside within.
3553
+.br
3554
+.\"*********************************************************
3555
+.TP
3556
+.B --pkcs11-slot name
3557
+Specify a name of the slot to search for.
3558
+.\"*********************************************************
3559
+.TP
3560
+.B --pkcs11-id-type type
3561
+Specify how to locate the correct objects. Type can be one of the following:
3562
+
3563
+.B 'id'
3564
+-- Locate by the id attribte, name should be hex encoded string.
3565
+.br
3566
+.B 'label'
3567
+-- Locate by the label attribute, name should be string.
3568
+.br
3569
+.B 'subject'
3570
+-- Locate by certificate subject attribute, name should be string.
3571
+.br
3572
+.\"*********************************************************
3573
+.TP
3574
+.B --pkcs11-id name
3575
+Specify a name of the object to search for.
3576
+.\"*********************************************************
3577
+.TP
3578
+.B --pkcs11-protected-authentication
3579
+Use PKCS#11 protected authentication path, useful for biometric and external
3580
+keypad devices.
3581
+.\"*********************************************************
3582
+.TP
3516 3583
 .B --cryptoapicert select-string
3517 3584
 Load the certificate and private key from the
3518 3585
 Windows Certificate System Store (Windows Only).
... ...
@@ -4306,6 +4382,18 @@ must be the middle two addresses of a /30 subnet (netmask 255.255.255.252).
4306 4306
 Show OpenVPN's view of the system routing table and network
4307 4307
 adapter list.
4308 4308
 .\"*********************************************************
4309
+.SS PKCS#11 Standalone Options:
4310
+.\"*********************************************************
4311
+.TP
4312
+.B --show-pkcs11-slots provider
4313
+(Standalone)
4314
+Show PKCS#11 provider slot list.
4315
+.\"*********************************************************
4316
+.TP
4317
+.B --show-pkcs11-objects provider slot
4318
+(Standalone)
4319
+Show PKCS#11 token object list.
4320
+.\"*********************************************************
4309 4321
 .SH SCRIPTING AND ENVIRONMENTAL VARIABLES
4310 4322
 OpenVPN exports a series
4311 4323
 of environmental variables for use by user-defined scripts.
... ...
@@ -45,6 +45,7 @@
45 45
 #include "misc.h"
46 46
 #include "socket.h"
47 47
 #include "packet_id.h"
48
+#include "pkcs11.h"
48 49
 #include "win32.h"
49 50
 #include "push.h"
50 51
 #include "pool.h"
... ...
@@ -406,6 +407,24 @@ static const char usage_message[] =
406 406
   "--key file      : Local private key in .pem format.\n"
407 407
   "--pkcs12 file   : PKCS#12 file containing local private key, local certificate\n"
408 408
   "                  and root CA certificate.\n"
409
+#ifdef ENABLE_PKCS11
410
+  "--pkcs11-providers provider ... : PKCS#11 provider to load.\n"
411
+  "--pkcs11-sign-mode mode ... : PKCS#11 signature method.\n"
412
+  "                              auto    : Try  to determind automatically (default).\n"
413
+  "                              recover : Use SignRecover.\n"
414
+  "                              sign    : Use Sign.\n"
415
+  "--pkcs11-slot-type method   : Slot locate method:\n"
416
+  "                              id      : By slot id (numeric [prov#:]slot#).\n"
417
+  "                              name    : By slot name.\n"
418
+  "                              label   : By the card label that resides in slot.\n"
419
+  "--pkcs11-slot name          : The slot name.\n"
420
+  "--pkcs11-id-type method     : Certificate and key locate method:\n"
421
+  "                              id      : By the object id (hex format).\n"
422
+  "                              label   : By the object label (string).\n"
423
+  "                              subject : By certificate subject (String).\n"
424
+  "--pkcs11-id name            : The object name.\n"
425
+  "--pkcs11-protected-authentication : Use PKCS#11 protected authentication path.\n"
426
+#endif
409 427
 #ifdef WIN32
410 428
   "--cryptoapicert select-string : Load the certificate and private key from the\n"
411 429
   "                  Windows Certificate System Store.\n"
... ...
@@ -517,6 +536,14 @@ static const char usage_message[] =
517 517
   "--dev tunX|tapX : tun/tap device\n"
518 518
   "--dev-type dt   : Device type.  See tunnel options above for details.\n"
519 519
 #endif
520
+#ifdef USE_SSL
521
+#ifdef ENABLE_PKCS11
522
+  "\n"
523
+  "PKCS#11 specific:\n"
524
+  "--show-pkcs11-slots provider        : Show PKCS#11 provider available slots.\n"
525
+  "--show-pkcs11-objects provider slot : Show PKCS#11 token objects.\n" 
526
+#endif
527
+#endif
520 528
  ;
521 529
 
522 530
 #endif /* !ENABLE_SMALL */
... ...
@@ -601,6 +628,9 @@ init_options (struct options *o)
601 601
   o->renegotiate_seconds = 3600;
602 602
   o->handshake_window = 60;
603 603
   o->transition_window = 3600;
604
+#ifdef ENABLE_PKCS11
605
+  o->pkcs11_protected_authentication = false;
606
+#endif
604 607
 #endif
605 608
 #endif
606 609
 }
... ...
@@ -1114,6 +1144,23 @@ show_settings (const struct options *o)
1114 1114
   SHOW_STR (cert_file);
1115 1115
   SHOW_STR (priv_key_file);
1116 1116
   SHOW_STR (pkcs12_file);
1117
+#ifdef ENABLE_PKCS11
1118
+  {
1119
+    int i;
1120
+    for (i=0;i<MAX_PARMS && o->pkcs11_providers[i] != NULL;i++)
1121
+      SHOW_PARM (pkcs11_providers, o->pkcs11_providers[i], "%s");
1122
+  }
1123
+  {
1124
+    int i;
1125
+    for (i=0;i<MAX_PARMS && o->pkcs11_sign_mode[i] != NULL;i++)
1126
+      SHOW_PARM (pkcs11_sign_mode, o->pkcs11_sign_mode[i], "%s");
1127
+  }
1128
+  SHOW_STR (pkcs11_slot_type);
1129
+  SHOW_STR (pkcs11_slot);
1130
+  SHOW_STR (pkcs11_id_type);
1131
+  SHOW_STR (pkcs11_id);
1132
+  SHOW_BOOL (pkcs11_protected_authentication);
1133
+#endif
1117 1134
 #ifdef WIN32
1118 1135
   SHOW_STR (cryptoapi_cert);
1119 1136
 #endif
... ...
@@ -1570,6 +1617,58 @@ options_postprocess (struct options *options, bool first_time)
1570 1570
     }
1571 1571
   if (options->tls_server || options->tls_client)
1572 1572
     {
1573
+#ifdef ENABLE_PKCS11
1574
+      if (options->pkcs11_providers[0])
1575
+       {
1576
+        int j;
1577
+        notnull (options->ca_file, "CA file (--ca)");
1578
+	
1579
+	for (j=0;j<MAX_PARMS && options->pkcs11_sign_mode[j] != NULL;j++)
1580
+	 {
1581
+	  if (
1582
+	   !string_defined_equal (options->pkcs11_sign_mode[j], "auto") &&
1583
+	   !string_defined_equal (options->pkcs11_sign_mode[j], "recover") &&
1584
+	   !string_defined_equal (options->pkcs11_sign_mode[j], "sign")
1585
+	  )
1586
+	    msg(M_USAGE, "Parameter --pkcs11-sign-mode value is invalid.");
1587
+	 }
1588
+
1589
+	if (
1590
+	  !string_defined_equal (options->pkcs11_slot_type, "id") &&
1591
+	  !string_defined_equal (options->pkcs11_slot_type, "name") &&
1592
+	  !string_defined_equal (options->pkcs11_slot_type, "label")
1593
+	)
1594
+	  msg(M_USAGE, "Parameter --pkcs11-slot-type value is invalid.");
1595
+
1596
+	notnull (options->pkcs11_slot, "PKCS#11 slot name (--pkcs11-slot)");
1597
+
1598
+	if (
1599
+	  !string_defined_equal (options->pkcs11_id_type, "id") &&
1600
+	  !string_defined_equal (options->pkcs11_id_type, "label") &&
1601
+	  !string_defined_equal (options->pkcs11_id_type, "subject")
1602
+	)
1603
+	  msg(M_USAGE, "Parameter --pkcs11-id-type value is invalid.");
1604
+
1605
+	notnull (options->pkcs11_id, "PKCS#11 id (--pkcs11-id)");
1606
+
1607
+	if (options->pkcs11_protected_authentication && options->key_pass_file != NULL)
1608
+	  msg(M_USAGE, "Parameter --askpass cannot be used when --pkcs11-protected-authentication is also specified.");
1609
+	if (!options->pkcs11_protected_authentication && options->key_pass_file == NULL)
1610
+	  msg (M_USAGE, "Please specify one of --askpass or --pkcs11-protected-autentication options.");
1611
+
1612
+	if (options->cert_file)
1613
+	  msg(M_USAGE, "Parameter --cert cannot be used when --pkcs11-provider is also specified.");
1614
+	if (options->priv_key_file)
1615
+	  msg(M_USAGE, "Parameter --key cannot be used when --pkcs11-provider is also specified.");
1616
+	if (options->pkcs12_file)
1617
+	  msg(M_USAGE, "Parameter --pkcs12 cannot be used when --pkcs11-provider is also specified.");
1618
+#ifdef WIN32
1619
+	if (options->cryptoapi_cert)
1620
+	  msg(M_USAGE, "Parameter --cryptoapicert cannot be used when --pkcs11-provider is also specified.");
1621
+#endif
1622
+       }
1623
+      else
1624
+#endif
1573 1625
 #ifdef WIN32
1574 1626
       if (options->cryptoapi_cert)
1575 1627
 	{
... ...
@@ -1650,6 +1749,14 @@ options_postprocess (struct options *options, bool first_time)
1650 1650
       MUST_BE_UNDEF (crl_file);
1651 1651
       MUST_BE_UNDEF (key_method);
1652 1652
       MUST_BE_UNDEF (ns_cert_type);
1653
+#ifdef ENABLE_PKCS11
1654
+      MUST_BE_UNDEF (pkcs11_providers[0]);
1655
+      MUST_BE_UNDEF (pkcs11_sign_mode[0]);
1656
+      MUST_BE_UNDEF (pkcs11_slot_type);
1657
+      MUST_BE_UNDEF (pkcs11_slot);
1658
+      MUST_BE_UNDEF (pkcs11_id_type);
1659
+      MUST_BE_UNDEF (pkcs11_id);
1660
+#endif
1653 1661
 
1654 1662
       if (pull)
1655 1663
 	msg (M_USAGE, err, "--pull");
... ...
@@ -4554,6 +4661,83 @@ add_option (struct options *options,
4554 4554
       VERIFY_PERMISSION (OPT_P_GENERAL);
4555 4555
       options->cert_file = p[1];
4556 4556
     }
4557
+#ifdef ENABLE_PKCS11
4558
+  else if (streq (p[0], "show-pkcs11-slots") && p[1])
4559
+    {
4560
+      char *module =  p[i++];
4561
+      VERIFY_PERMISSION (OPT_P_GENERAL);
4562
+      show_pkcs11_slots (M_INFO|M_NOPREFIX, M_WARN|M_NOPREFIX, module);
4563
+      openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
4564
+    }
4565
+  else if (streq (p[0], "show-pkcs11-objects") && p[1] && p[2])
4566
+    {
4567
+      char *provider =  p[i++];
4568
+      char *slot = p[i++];
4569
+      struct gc_arena gc = gc_new ();
4570
+      struct buffer pass_prompt = alloc_buf_gc (128, &gc);
4571
+      char pin[256];
4572
+
4573
+      VERIFY_PERMISSION (OPT_P_GENERAL);
4574
+
4575
+      buf_printf (&pass_prompt, "PIN:");
4576
+
4577
+      if (!get_console_input (BSTR (&pass_prompt), false, pin, sizeof (pin)))
4578
+        msg (M_FATAL, "Cannot read password from stdin");
4579
+      
4580
+      gc_free (&gc);
4581
+      
4582
+      show_pkcs11_objects (M_INFO|M_NOPREFIX, M_WARN|M_NOPREFIX, provider, slot, pin);
4583
+      openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
4584
+    }
4585
+  else if (streq (p[0], "pkcs11-providers") && p[1])
4586
+    {
4587
+      int j;
4588
+      
4589
+      VERIFY_PERMISSION (OPT_P_GENERAL);
4590
+
4591
+      for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j, ++i)
4592
+      	options->pkcs11_providers[j-1] = p[j];
4593
+    }
4594
+  else if (streq (p[0], "pkcs11-sign-mode") && p[1])
4595
+    {
4596
+      int j;
4597
+      
4598
+      VERIFY_PERMISSION (OPT_P_GENERAL);
4599
+
4600
+      for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j, ++i)
4601
+      	options->pkcs11_sign_mode[j-1] = p[j];
4602
+    }
4603
+  else if (streq (p[0], "pkcs11-slot-type") && p[1])
4604
+    {
4605
+      ++i;
4606
+      VERIFY_PERMISSION (OPT_P_GENERAL);
4607
+      options->pkcs11_slot_type = p[1];
4608
+    }
4609
+  else if (streq (p[0], "pkcs11-slot") && p[1])
4610
+    {
4611
+      ++i;
4612
+      VERIFY_PERMISSION (OPT_P_GENERAL);
4613
+      options->pkcs11_slot = p[1];
4614
+    }
4615
+  else if (streq (p[0], "pkcs11-id-type") && p[1])
4616
+    {
4617
+      ++i;
4618
+      VERIFY_PERMISSION (OPT_P_GENERAL);
4619
+      options->pkcs11_id_type = p[1];
4620
+    }
4621
+  else if (streq (p[0], "pkcs11-id") && p[1])
4622
+    {
4623
+      ++i;
4624
+      VERIFY_PERMISSION (OPT_P_GENERAL);
4625
+      options->pkcs11_id = p[1];
4626
+    }
4627
+  else if (streq (p[0], "pkcs11-protected-authentication"))
4628
+    {
4629
+      ++i;
4630
+      VERIFY_PERMISSION (OPT_P_GENERAL);
4631
+      options->pkcs11_protected_authentication = true;
4632
+    }
4633
+#endif
4557 4634
 #ifdef WIN32
4558 4635
   else if (streq (p[0], "cryptoapicert") && p[1])
4559 4636
     {
... ...
@@ -377,6 +377,13 @@ struct options
377 377
   const char *tls_remote;
378 378
   const char *crl_file;
379 379
   int ns_cert_type; /* set to 0, NS_SSL_SERVER, or NS_SSL_CLIENT */
380
+  const char *pkcs11_providers[MAX_PARMS];
381
+  const char *pkcs11_sign_mode[MAX_PARMS];
382
+  const char *pkcs11_slot_type;
383
+  const char *pkcs11_slot;
384
+  const char *pkcs11_id_type;
385
+  const char *pkcs11_id;
386
+  bool pkcs11_protected_authentication;
380 387
 #ifdef WIN32
381 388
   const char *cryptoapi_cert;
382 389
 #endif
383 390
new file mode 100644
... ...
@@ -0,0 +1,2392 @@
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
+/*
25
+ * The routines in this file deal with providing private key cryptography
26
+ * using RSA Security Inc. PKCS #11 Cryptographic Token Interface (Cryptoki).
27
+ *
28
+ */
29
+
30
+#if defined(WIN32)
31
+#include "config-win32.h"
32
+#else
33
+#include "config.h"
34
+#endif
35
+
36
+#if defined(USE_CRYPTO) && defined(USE_SSL) && defined(ENABLE_PKCS11)
37
+
38
+#include "syshead.h"
39
+#include "error.h"
40
+#include "misc.h"
41
+#include "ssl.h"
42
+
43
+#if !defined(IN)
44
+#define IN
45
+#endif
46
+#if !defined(OUT)
47
+#define OUT
48
+#endif
49
+
50
+#if defined(WIN32)
51
+#include "cryptoki-win32.h"
52
+#else
53
+#include "cryptoki.h"
54
+#endif
55
+
56
+#include "pkcs11.h"
57
+
58
+/*===========================================
59
+ * Constants
60
+ */
61
+
62
+#if OPENSSL_VERSION_NUMBER < 0x00907000L && defined(CRYPTO_LOCK_ENGINE)
63
+# define RSA_get_default_method RSA_get_default_openssl_method
64
+#else
65
+# ifdef HAVE_ENGINE_GET_DEFAULT_RSA
66
+#  include <openssl/engine.h>
67
+#  if OPENSSL_VERSION_NUMBER < 0x0090704fL
68
+#   define BROKEN_OPENSSL_ENGINE
69
+#  endif
70
+# endif
71
+#endif
72
+
73
+#define PKCS11_MAX_ATTRIBUTE_SIZE (10*1024)
74
+
75
+/*===========================================
76
+ * Types
77
+ */
78
+
79
+typedef struct pkcs11_provider_s {
80
+	struct pkcs11_provider_s *next;
81
+
82
+	bool fEnabled;
83
+	
84
+#if defined(WIN32)
85
+	HANDLE hLibrary;
86
+#else
87
+	void *hLibrary;
88
+#endif
89
+	CK_FUNCTION_LIST_PTR f;
90
+	bool fShouldFinalize;
91
+	char *szSignMode;
92
+} *pkcs11_provider_t;
93
+
94
+typedef struct pkcs11_session_s {
95
+
96
+	pkcs11_provider_t provider;
97
+
98
+	unsigned char *certificate;
99
+	int certificate_size;
100
+	unsigned char *certificate_id;
101
+	int certificate_id_size;
102
+
103
+	char *szPIN;
104
+	bool fLoginFailed;
105
+
106
+	CK_SLOT_ID slot;
107
+	bool fKeySignRecover;
108
+
109
+	CK_SESSION_HANDLE session;
110
+	CK_OBJECT_HANDLE key;
111
+} *pkcs11_session_t;
112
+
113
+/*===========================================
114
+ * Low level prototypes
115
+ */
116
+
117
+static
118
+void
119
+_fixupFixedString (
120
+	IN const char * const szSource,
121
+	OUT char * const szTarget,			// MUST BE >= nLength+1
122
+	IN const int nLength				// FIXED STRING LENGTH
123
+);
124
+static
125
+void
126
+_hexToBinary (
127
+	IN const char * const szSource,
128
+	OUT unsigned char * const target,
129
+	IN OUT int * const target_size
130
+);
131
+static
132
+CK_RV
133
+_pkcs11_getSlotById (
134
+	IN const pkcs11_session_t pkcs11_session,
135
+	IN const char * const szSlot
136
+);
137
+static
138
+CK_RV
139
+_pkcs11_getSlotByName (
140
+	IN const pkcs11_session_t pkcs11_session,
141
+	IN const char * const szName
142
+);
143
+static
144
+CK_RV
145
+_pkcs11_getSlotByLabel (
146
+	IN const pkcs11_session_t pkcs11_session,
147
+	IN const char * const szLabel
148
+);
149
+static
150
+CK_RV
151
+_pkcs11_getObjectById (
152
+	IN const pkcs11_session_t pkcs11_session,
153
+	IN const CK_OBJECT_CLASS class,
154
+	IN const unsigned char * const id,
155
+	IN const int id_size,
156
+	OUT CK_OBJECT_HANDLE * const handle
157
+);
158
+static
159
+CK_RV
160
+_pkcs11_loadCertificate (
161
+	IN const pkcs11_session_t pkcs11_session,
162
+	IN const char * const szIdType,
163
+	IN const char * const szId
164
+);
165
+static
166
+CK_RV
167
+_pkcs11_loadKeyProperties (
168
+	IN const pkcs11_session_t pkcs11_session
169
+);
170
+static
171
+bool
172
+_isBetterCertificate (
173
+	IN const unsigned char * const pCurrent,
174
+	IN const int nCurrentSize,
175
+	IN const unsigned char * const pNew,
176
+	IN const int nNewSize
177
+);
178
+
179
+/*=========================================
180
+ * Simplified functions prototypes
181
+ */
182
+
183
+static
184
+CK_RV
185
+pkcs11_addProvider (
186
+	IN const char * const szProvider,
187
+	IN const char * const szSignMode
188
+);
189
+static
190
+CK_RV
191
+pkcs11_finalize ();
192
+static
193
+CK_RV
194
+pkcs11_createSession (
195
+	IN const char * const szSlotType,
196
+	IN const char * const szSlot,
197
+	IN const char * const szIdType,
198
+	IN const char * const szId,
199
+	IN const char * const szPIN,
200
+	IN const bool fProtectedAuthentication,
201
+	OUT pkcs11_session_t * const pkcs11_session
202
+);
203
+static
204
+CK_RV
205
+pkcs11_freeSession (
206
+	IN const pkcs11_session_t pkcs11_session
207
+);
208
+static
209
+CK_RV
210
+pkcs11_login (
211
+	IN const pkcs11_session_t pkcs11_session
212
+);
213
+static
214
+CK_RV
215
+pkcs11_logout (
216
+	IN const pkcs11_session_t pkcs11_session
217
+);
218
+static
219
+CK_RV
220
+pkcs11_sign (
221
+	IN const pkcs11_session_t pkcs11_session,
222
+	IN const CK_MECHANISM_TYPE mech_type,
223
+	IN const unsigned char * const source,
224
+	IN const int source_size,
225
+	OUT unsigned char * const target,
226
+	IN OUT int * const target_size
227
+);
228
+static
229
+CK_RV
230
+pkcs11_signRecover (
231
+	IN const pkcs11_session_t pkcs11_session,
232
+	IN const CK_MECHANISM_TYPE mech_type,
233
+	IN const unsigned char * const source,
234
+	IN const int source_size,
235
+	OUT unsigned char * const target,
236
+	IN OUT int * const target_size
237
+);
238
+static
239
+CK_RV
240
+pkcs11_decrypt (
241
+	IN const pkcs11_session_t pkcs11_session,
242
+	IN const CK_MECHANISM_TYPE mech_type,
243
+	IN const unsigned char * const source,
244
+	IN const int source_size,
245
+	OUT unsigned char * const target,
246
+	IN OUT int * const target_size
247
+);
248
+static
249
+CK_RV
250
+pkcs11_getCertificate (
251
+	IN const pkcs11_session_t pkcs11_session,
252
+	OUT char * const certificate,
253
+	IN OUT int * const certificate_size
254
+);
255
+static
256
+char *
257
+pkcs11_getMessage (
258
+	IN const int rv
259
+);
260
+
261
+/*==========================================
262
+ * Static data
263
+ */
264
+
265
+static pkcs11_provider_t pkcs11_provider = NULL;
266
+
267
+/*==========================================
268
+ * Internal utility functions
269
+ */
270
+
271
+static
272
+void
273
+_fixupFixedString (
274
+	IN const char * const szSource,
275
+	OUT char * const szTarget,			// MUST BE >= nLength+1
276
+	IN const int nLength				// FIXED STRING LENGTH
277
+) {
278
+	char *p;
279
+
280
+	ASSERT (szSource!=NULL);
281
+	ASSERT (szTarget!=NULL);
282
+	
283
+	p = szTarget+nLength;
284
+	memmove (szTarget, szSource, nLength);
285
+	*p = '\0';
286
+	p--;
287
+	while (p >= szTarget && *p == ' ') {
288
+		*p = '\0';
289
+		p--;
290
+	}
291
+}
292
+
293
+static
294
+void
295
+_hexToBinary (
296
+	IN const char * const szSource,
297
+	OUT unsigned char * const target,
298
+	IN OUT int * const target_size
299
+) {
300
+	int target_max_size;
301
+	const char *p;
302
+	char buf[3] = {'\0', '\0', '\0'};
303
+	int i = 0;
304
+
305
+	ASSERT (szSource!=NULL);
306
+	ASSERT (target!=NULL);
307
+	ASSERT (target_size!=NULL);
308
+
309
+	target_max_size = *target_size;
310
+	p = szSource;
311
+	*target_size = 0;
312
+
313
+	while (*p != '\0' && *target_size < target_max_size) {
314
+		if (isxdigit (*p)) {
315
+			buf[i%2] = *p;
316
+
317
+			if ((i%2) == 1) {
318
+				int v;
319
+				sscanf (buf, "%x", &v);
320
+				target[*target_size] = v & 0xff;
321
+				(*target_size)++;
322
+			}
323
+
324
+			i++;
325
+		}
326
+		p++;
327
+	}
328
+}
329
+
330
+static
331
+bool
332
+_isBetterCertificate (
333
+	IN const unsigned char * const pCurrent,
334
+	IN const int nCurrentSize,
335
+	IN const unsigned char * const pNew,
336
+	IN const int nNewSize
337
+) {
338
+	/*
339
+	 * This function compare the notBefore
340
+	 * and select the most recent certificate
341
+	 * it does not deal with timezones...
342
+	 * When openssl will have ASN1_TIME compare function
343
+	 * it should be used.
344
+	 */
345
+
346
+	X509 *x509Current = NULL, *x509New = NULL;
347
+	char szNotBeforeCurrent[1024], szNotBeforeNew[1024];
348
+
349
+	/*
350
+	 * First certificae
351
+	 * always select
352
+	 */
353
+	if (nCurrentSize == 0) {
354
+		return true;
355
+	}
356
+
357
+	szNotBeforeCurrent[0] = '\0';
358
+	szNotBeforeNew[0] = '\0';
359
+
360
+	x509Current = X509_new ();
361
+	x509New = X509_new ();
362
+
363
+	if (x509Current != NULL && x509New != NULL) {
364
+		const unsigned char *p1, *p2;
365
+
366
+		p1 = pCurrent;
367
+		p2 = pNew;
368
+		if (
369
+			d2i_X509 (&x509Current, (unsigned char **)&p1, nCurrentSize) &&
370
+			d2i_X509 (&x509New, (unsigned char **)&p2, nNewSize)
371
+		) {
372
+			ASN1_TIME *notBeforeCurrent = X509_get_notBefore (x509Current);
373
+			ASN1_TIME *notBeforeNew = X509_get_notBefore (x509New);
374
+
375
+			if (
376
+				notBeforeCurrent != NULL &&
377
+				notBeforeNew != NULL &&
378
+				notBeforeCurrent->length < (int) sizeof (szNotBeforeCurrent) - 1 &&
379
+				notBeforeNew->length < (int) sizeof (szNotBeforeNew) - 1
380
+			) {
381
+				memmove (szNotBeforeCurrent, notBeforeCurrent->data, notBeforeCurrent->length);
382
+				szNotBeforeCurrent[notBeforeCurrent->length] = '\0';
383
+				memmove (szNotBeforeNew, notBeforeNew->data, notBeforeNew->length);
384
+				szNotBeforeNew[notBeforeNew->length] = '\0';
385
+			}
386
+		}
387
+	}
388
+
389
+	if (x509Current != NULL) {
390
+		X509_free (x509Current);
391
+		x509Current = NULL;
392
+	}
393
+	if (x509New != NULL) {
394
+		X509_free (x509New);
395
+		x509New = NULL;
396
+	}
397
+
398
+	return strcmp (szNotBeforeCurrent, szNotBeforeNew) < 0;
399
+}
400
+
401
+/*========================================
402
+ * Low level PKCS#11 functions
403
+ */
404
+
405
+static
406
+CK_RV
407
+_pkcs11_getSlotById (
408
+	IN const pkcs11_session_t pkcs11_session,
409
+	IN const char * const szSlot
410
+) {
411
+	pkcs11_provider_t provider;
412
+	int provider_number;
413
+	int slot_number;
414
+	int i;
415
+
416
+	ASSERT (pkcs11_session!=NULL);
417
+	ASSERT (szSlot!=NULL);
418
+
419
+	if (strchr (szSlot, ':') == NULL) {
420
+		provider_number = 0;
421
+		slot_number = atoi (szSlot);
422
+	}
423
+	else {
424
+		sscanf (szSlot, "%d:%d", &provider_number, &slot_number);
425
+	}
426
+
427
+	for (
428
+		i=0, provider=pkcs11_provider;
429
+		i < provider_number && provider != NULL;
430
+		i++, provider = provider->next
431
+	);
432
+
433
+	if (
434
+		provider == NULL ||
435
+		(
436
+			provider != NULL &&
437
+			!provider->fEnabled
438
+		)
439
+	) {
440
+		return CKR_SLOT_ID_INVALID;
441
+	}
442
+
443
+	pkcs11_session->provider = provider;
444
+	pkcs11_session->slot = slot_number;
445
+	return CKR_OK;
446
+}
447
+
448
+static
449
+CK_RV
450
+_pkcs11_getSlotByName (
451
+	IN const pkcs11_session_t pkcs11_session,
452
+	IN const char * const szName
453
+) {
454
+	CK_SLOT_ID slots[1024];
455
+	CK_ULONG slotnum;
456
+	CK_SLOT_ID s;
457
+	CK_RV rv;
458
+
459
+	pkcs11_provider_t provider;
460
+	bool fFound = false;
461
+
462
+	ASSERT (pkcs11_session!=NULL);
463
+	ASSERT (szName!=NULL);
464
+
465
+	for (
466
+		provider = pkcs11_provider;
467
+		(
468
+			provider != NULL &&
469
+			!fFound
470
+		);
471
+		provider = provider->next
472
+	) {
473
+		if (!provider->fEnabled) {
474
+			continue;
475
+		}
476
+
477
+		slotnum = sizeof (slots) / sizeof (CK_SLOT_ID);
478
+		if (
479
+			(rv = provider->f->C_GetSlotList (
480
+				TRUE,
481
+				slots,
482
+				&slotnum
483
+			)) == CKR_OK
484
+		) {
485
+			for (s=0;!fFound && s<slotnum;s++) {
486
+				CK_SLOT_INFO info;
487
+
488
+				if (
489
+					(rv = provider->f->C_GetSlotInfo (
490
+						slots[s],
491
+						&info
492
+					)) == CKR_OK
493
+				) {
494
+					char szCurrentName[sizeof (info.slotDescription)+1];
495
+	
496
+					_fixupFixedString (
497
+						info.slotDescription,
498
+						szCurrentName,
499
+						sizeof (info.slotDescription)
500
+					);
501
+
502
+					if (!strcmp (szCurrentName, szName)) {
503
+						fFound = true;
504
+						pkcs11_session->provider = provider;
505
+						pkcs11_session->slot = slots[s];
506
+					}
507
+				}
508
+			}
509
+		}
510
+	}
511
+
512
+	return fFound ? CKR_OK : CKR_SLOT_ID_INVALID;
513
+}
514
+
515
+static
516
+CK_RV
517
+_pkcs11_getSlotByLabel (
518
+	IN const pkcs11_session_t pkcs11_session,
519
+	IN const char * const szLabel
520
+) {
521
+	CK_SLOT_ID slots[1024];
522
+	CK_ULONG slotnum;
523
+	CK_SLOT_ID s;
524
+	CK_RV rv;
525
+
526
+	pkcs11_provider_t provider;
527
+	bool fFound = false;
528
+
529
+	ASSERT (pkcs11_session!=NULL);
530
+	ASSERT (szLabel!=NULL);
531
+
532
+	for (
533
+		provider = pkcs11_provider;
534
+		(
535
+			provider != NULL &&
536
+			!fFound
537
+		);
538
+		provider = provider->next
539
+	) {
540
+		if (!provider->fEnabled) {
541
+			continue;
542
+		}
543
+
544
+		slotnum = sizeof (slots) / sizeof (CK_SLOT_ID);
545
+		if (
546
+			(rv = provider->f->C_GetSlotList (
547
+				TRUE,
548
+				slots,
549
+				&slotnum
550
+			)) == CKR_OK
551
+		) {
552
+			for (s=0;!fFound && s<slotnum;s++) {
553
+				CK_TOKEN_INFO info;
554
+
555
+				if (
556
+					(rv = provider->f->C_GetTokenInfo (
557
+						slots[s],
558
+						&info
559
+					)) == CKR_OK
560
+				) {
561
+					char szCurrentLabel[sizeof (info.label)+1];
562
+			
563
+					_fixupFixedString (
564
+						info.label,
565
+						szCurrentLabel,
566
+						sizeof (info.label)
567
+					);
568
+
569
+					if (!strcmp (szCurrentLabel, szLabel)) {
570
+						fFound = true;
571
+						pkcs11_session->provider = provider;
572
+						pkcs11_session->slot = slots[s];
573
+					}
574
+				}
575
+			}
576
+		}
577
+	}
578
+
579
+	return fFound ? CKR_OK : CKR_SLOT_ID_INVALID;
580
+}
581
+
582
+static
583
+CK_RV
584
+_pkcs11_getObjectById (
585
+	IN const pkcs11_session_t pkcs11_session,
586
+	IN const CK_OBJECT_CLASS class,
587
+	IN const unsigned char * const id,
588
+	IN const int id_size,
589
+	OUT CK_OBJECT_HANDLE * const handle
590
+) {
591
+	CK_ULONG count;
592
+	bool fFound = false;
593
+	CK_RV rv;
594
+
595
+	CK_ATTRIBUTE filter[] = {
596
+		{CKA_CLASS, (void *)&class, sizeof (class)},
597
+		{CKA_ID, (void *)id, id_size}
598
+	};
599
+	
600
+	ASSERT (pkcs11_session!=NULL);
601
+	ASSERT (id!=NULL);
602
+	ASSERT (handle!=NULL);
603
+
604
+	if (
605
+		(rv = pkcs11_session->provider->f->C_FindObjectsInit (
606
+			pkcs11_session->session,
607
+			filter,
608
+			sizeof (filter) / sizeof (CK_ATTRIBUTE)
609
+		)) != CKR_OK
610
+	) {
611
+		return rv;
612
+	}
613
+
614
+	if (
615
+		(rv = pkcs11_session->provider->f->C_FindObjects (
616
+			pkcs11_session->session,
617
+			handle,
618
+			1,
619
+			&count
620
+		)) == CKR_OK 
621
+	) {
622
+		if (count > 0) {
623
+			fFound = true;
624
+		}
625
+	}
626
+
627
+	pkcs11_session->provider->f->C_FindObjectsFinal (
628
+		pkcs11_session->session
629
+	);
630
+
631
+	return fFound ? CKR_OK : CKR_FUNCTION_REJECTED;
632
+}
633
+
634
+static
635
+CK_RV
636
+_pkcs11_loadCertificate (
637
+	IN const pkcs11_session_t pkcs11_session,
638
+	IN const char * const szIdType,
639
+	IN const char * const szId
640
+) {
641
+	CK_OBJECT_HANDLE objects[10];
642
+	CK_ULONG objects_found;
643
+	CK_RV rv;
644
+
645
+	unsigned char selected_id[PKCS11_MAX_ATTRIBUTE_SIZE];
646
+	int selected_id_size = 0;
647
+	unsigned char selected_certificate[PKCS11_MAX_ATTRIBUTE_SIZE];
648
+	int selected_certificate_size = 0;
649
+
650
+	CK_OBJECT_CLASS cert_filter_class = CKO_CERTIFICATE;
651
+	unsigned char cert_filter_by[PKCS11_MAX_ATTRIBUTE_SIZE];
652
+	CK_ATTRIBUTE cert_filter[] = {
653
+		{CKA_CLASS, &cert_filter_class, sizeof (cert_filter_class)},
654
+		{0, cert_filter_by, 0}
655
+	};
656
+
657
+	ASSERT (pkcs11_session!=NULL);
658
+	ASSERT (szIdType!=NULL);
659
+	ASSERT (szId!=NULL);
660
+
661
+	if (!strcmp (szIdType, "label")) {
662
+		cert_filter[1].type = CKA_LABEL;
663
+		cert_filter[1].ulValueLen = (CK_ULONG)(
664
+			strlen (szId) < sizeof (cert_filter_by)  ?
665
+			strlen (szId) :
666
+			sizeof (cert_filter_by)
667
+		);
668
+		memmove (
669
+			cert_filter_by,
670
+			szId,
671
+			cert_filter[1].ulValueLen
672
+		);
673
+	}
674
+	else if (!strcmp (szIdType, "id")) {
675
+		int s = sizeof (cert_filter_by);
676
+
677
+		cert_filter[1].type = CKA_ID;
678
+		_hexToBinary (
679
+			szId,
680
+			cert_filter_by,
681
+			&s
682
+		);
683
+		cert_filter[1].ulValueLen = s;
684
+	}
685
+	else if (!strcmp (szIdType, "subject")) {
686
+		memmove (&cert_filter[1], &cert_filter[0], sizeof (CK_ATTRIBUTE));
687
+	}
688
+	else {
689
+		return CKR_ARGUMENTS_BAD;
690
+	}
691
+
692
+	if (
693
+		(rv = pkcs11_session->provider->f->C_FindObjectsInit (
694
+			pkcs11_session->session,
695
+			cert_filter,
696
+			sizeof (cert_filter) / sizeof (CK_ATTRIBUTE)
697
+		)) != CKR_OK
698
+	) {
699
+		return rv;
700
+	}
701
+
702
+	while (
703
+		(rv = pkcs11_session->provider->f->C_FindObjects (
704
+			pkcs11_session->session,
705
+			objects,
706
+			sizeof (objects) / sizeof (CK_OBJECT_HANDLE),
707
+			&objects_found
708
+		)) == CKR_OK &&
709
+		objects_found > 0
710
+	) { 
711
+		CK_ULONG i;
712
+		
713
+		for (i=0;i<objects_found;i++) {
714
+			unsigned char attrs_id[PKCS11_MAX_ATTRIBUTE_SIZE];
715
+			unsigned char attrs_value[PKCS11_MAX_ATTRIBUTE_SIZE];
716
+			CK_ATTRIBUTE attrs[] = {
717
+				{CKA_ID, attrs_id, sizeof (attrs_id)},
718
+				{CKA_VALUE, attrs_value, sizeof (attrs_value)}
719
+			};
720
+	
721
+			if (
722
+				pkcs11_session->provider->f->C_GetAttributeValue (
723
+					pkcs11_session->session,
724
+					objects[i],
725
+					attrs,
726
+					sizeof (attrs) / sizeof (CK_ATTRIBUTE)
727
+				) == CKR_OK
728
+			) {
729
+				bool fSelected = false;
730
+
731
+				if (!strcmp (szIdType, "subject")) {
732
+					X509 *x509 = NULL;
733
+					char szSubject[1024];
734
+					unsigned char *p;
735
+
736
+					x509 = X509_new ();
737
+
738
+					p = attrs_value;
739
+					if (d2i_X509 (&x509, &p, attrs[1].ulValueLen)) {
740
+  						X509_NAME_oneline (
741
+							X509_get_subject_name (x509),
742
+							szSubject,
743
+							sizeof (szSubject)
744
+						);
745
+						szSubject[sizeof (szSubject) - 1] = '\0';
746
+					}
747
+
748
+					if (x509 != NULL) {
749
+						X509_free (x509);
750
+						x509 = NULL;
751
+					}
752
+
753
+					if (!strcmp (szId, szSubject)) {
754
+						fSelected = true;
755
+					}
756
+				}
757
+				else {
758
+					fSelected = true;
759
+				}
760
+
761
+				if (
762
+					fSelected &&
763
+					_isBetterCertificate (
764
+						selected_certificate,
765
+						selected_certificate_size,
766
+						attrs_value,
767
+						attrs[1].ulValueLen
768
+					)
769
+				) {
770
+					selected_certificate_size = attrs[1].ulValueLen;
771
+					memmove (
772
+						selected_certificate,
773
+						attrs_value,
774
+						selected_certificate_size
775
+					);
776
+					selected_id_size = attrs[0].ulValueLen;
777
+					memmove (
778
+						selected_id,
779
+						attrs_id,
780
+						selected_id_size
781
+					);
782
+				}
783
+			}
784
+		}
785
+	}
786
+
787
+	pkcs11_session->provider->f->C_FindObjectsFinal (
788
+		pkcs11_session->session
789
+	);
790
+
791
+	if (selected_certificate_size == 0) {
792
+		return CKR_ATTRIBUTE_VALUE_INVALID;
793
+	}
794
+
795
+	if ((pkcs11_session->certificate = (unsigned char *)malloc (selected_certificate_size)) == NULL) {
796
+		return CKR_HOST_MEMORY;
797
+	}
798
+	pkcs11_session->certificate_size = selected_certificate_size;
799
+	memmove (
800
+		pkcs11_session->certificate,
801
+		selected_certificate,
802
+		selected_certificate_size
803
+	);
804
+	if ((pkcs11_session->certificate_id = (unsigned char *)malloc (selected_id_size)) == NULL) {
805
+		return CKR_HOST_MEMORY;
806
+	}
807
+	pkcs11_session->certificate_id_size = selected_id_size;
808
+	memmove (
809
+		pkcs11_session->certificate_id,
810
+		selected_id,
811
+		selected_id_size
812
+	);
813
+
814
+	return CKR_OK;
815
+}
816
+
817
+static
818
+CK_RV
819
+_pkcs11_loadKeyProperties (
820
+	IN const pkcs11_session_t pkcs11_session
821
+) {
822
+	CK_OBJECT_HANDLE key;
823
+	CK_RV rv;
824
+
825
+	CK_BBOOL key_attrs_sign_recover;
826
+	CK_BBOOL key_attrs_sign;
827
+	CK_ATTRIBUTE key_attrs[] = {
828
+		{CKA_SIGN, &key_attrs_sign_recover, sizeof (key_attrs_sign_recover)},
829
+		{CKA_SIGN_RECOVER, &key_attrs_sign, sizeof (key_attrs_sign)}
830
+	};
831
+
832
+	ASSERT (pkcs11_session!=NULL);
833
+
834
+	if (!strcmp (pkcs11_session->provider->szSignMode, "recover")) {
835
+		pkcs11_session->fKeySignRecover = true;
836
+	}
837
+	else if (!strcmp (pkcs11_session->provider->szSignMode, "sign")) {
838
+		pkcs11_session->fKeySignRecover = false;
839
+	}
840
+	else {
841
+		if (
842
+			(rv = _pkcs11_getObjectById (
843
+				pkcs11_session,
844
+				CKO_PRIVATE_KEY,
845
+				pkcs11_session->certificate_id,
846
+				pkcs11_session->certificate_id_size,
847
+				&key
848
+			)) != CKR_OK
849
+		) {
850
+			return rv;
851
+		}
852
+
853
+		if (
854
+			pkcs11_session->provider->f->C_GetAttributeValue (
855
+				pkcs11_session->session,
856
+				key,
857
+				key_attrs,
858
+				sizeof (key_attrs) / sizeof (CK_ATTRIBUTE)
859
+			) == CKR_OK
860
+		) {
861
+			if (key_attrs_sign_recover != CK_FALSE) {
862
+				pkcs11_session->fKeySignRecover = true;
863
+			}
864
+			else if (key_attrs_sign != CK_FALSE) {
865
+				pkcs11_session->fKeySignRecover = false;
866
+			}
867
+			else {
868
+				return CKR_KEY_TYPE_INCONSISTENT;
869
+			}
870
+		}
871
+
872
+	}
873
+
874
+	return CKR_OK;
875
+}
876
+
877
+/*=======================================
878
+ * Simplified PKCS#11 functions
879
+ */
880
+
881
+static
882
+CK_RV
883
+pkcs11_addProvider (
884
+	IN const char * const szProvider,
885
+	IN const char * const szSignMode
886
+) {
887
+	pkcs11_provider_t provider = NULL;
888
+	CK_C_GetFunctionList gfl = NULL;
889
+	CK_RV rv = CKR_OK;
890
+
891
+	ASSERT (szProvider!=NULL);
892
+
893
+	if (
894
+		rv == CKR_OK &&
895
+		(provider = (pkcs11_provider_t)malloc (sizeof (struct pkcs11_provider_s))) == NULL
896
+	) {
897
+		rv = CKR_HOST_MEMORY;
898
+	}
899
+
900
+	if (rv == CKR_OK) {
901
+		memset (provider, 0, sizeof (struct pkcs11_provider_s));
902
+		if (szSignMode == NULL) {
903
+			provider->szSignMode = strdup ("auto");
904
+		}
905
+		else {
906
+			provider->szSignMode = strdup (szSignMode);
907
+		}
908
+		if (provider->szSignMode == NULL) {
909
+			rv = CKR_HOST_MEMORY;
910
+		}
911
+	}
912
+		
913
+	if (rv == CKR_OK) {
914
+#if defined(WIN32)
915
+		provider->hLibrary = LoadLibrary (szProvider);
916
+#else
917
+		provider->hLibrary = dlopen (szProvider, RTLD_NOW);
918
+#endif
919
+		if (provider->hLibrary == NULL) {
920
+			rv = CKR_FUNCTION_FAILED;
921
+		}
922
+	}
923
+
924
+	if (rv == CKR_OK) {
925
+#if defined(WIN32)
926
+		gfl = (CK_C_GetFunctionList)GetProcAddress (
927
+			provider->hLibrary,
928
+			"C_GetFunctionList"
929
+		);
930
+#else
931
+		gfl = (CK_C_GetFunctionList)dlsym (
932
+			provider->hLibrary,
933
+			"C_GetFunctionList"
934
+		);
935
+#endif
936
+		if (gfl == NULL) {
937
+			rv = CKR_FUNCTION_FAILED;
938
+		}
939
+	}
940
+
941
+	if (rv == CKR_OK) {
942
+		rv = gfl (&provider->f);
943
+	}
944
+
945
+	if (rv == CKR_OK) {
946
+		if ((rv = provider->f->C_Initialize (NULL)) != CKR_OK) {
947
+			if (rv == CKR_CRYPTOKI_ALREADY_INITIALIZED) {
948
+				rv = CKR_OK;
949
+			}
950
+		}
951
+		else {
952
+			provider->fShouldFinalize = true;
953
+		}
954
+	}
955
+
956
+	if (rv == CKR_OK) {
957
+		provider->fEnabled = true;
958
+	}
959
+
960
+	if (provider != NULL) {
961
+		if (pkcs11_provider == NULL) {
962
+			pkcs11_provider = provider;
963
+		}
964
+		else {
965
+			pkcs11_provider_t last = NULL;
966
+	
967
+			for (
968
+				last = pkcs11_provider;
969
+				last->next != NULL;
970
+				last = last->next
971
+			);
972
+			last->next = provider;
973
+		}
974
+	}
975
+
976
+	return rv;
977
+}
978
+	
979
+static
980
+CK_RV
981
+pkcs11_finalize () {
982
+	
983
+	pkcs11_provider_t last = NULL;
984
+
985
+	for (
986
+		;
987
+		pkcs11_provider != NULL;
988
+		pkcs11_provider = pkcs11_provider->next
989
+	) {
990
+		if (last != NULL) {
991
+			free (last);
992
+		}
993
+		last = pkcs11_provider;
994
+		
995
+		if (pkcs11_provider->szSignMode != NULL) {
996
+			free (pkcs11_provider->szSignMode);
997
+			pkcs11_provider->szSignMode = NULL;
998
+		}
999
+	
1000
+		if (pkcs11_provider->fShouldFinalize) {
1001
+			pkcs11_provider->f->C_Finalize (NULL);
1002
+			pkcs11_provider->fShouldFinalize = false;
1003
+		}
1004
+
1005
+		if (pkcs11_provider->f != NULL) {
1006
+			pkcs11_provider->f = NULL;
1007
+		}
1008
+	
1009
+		if (pkcs11_provider->hLibrary != NULL) {
1010
+#if defined(WIN32)
1011
+			FreeLibrary (pkcs11_provider->hLibrary);
1012
+#else
1013
+			dlclose (pkcs11_provider->hLibrary);
1014
+#endif
1015
+			pkcs11_provider->hLibrary = NULL;
1016
+		}
1017
+	}
1018
+
1019
+	if (last != NULL) {
1020
+		free (last);
1021
+	}
1022
+
1023
+	return CKR_OK;
1024
+}
1025
+
1026
+static
1027
+CK_RV
1028
+pkcs11_createSession (
1029
+	IN const char * const szSlotType,
1030
+	IN const char * const szSlot,
1031
+	IN const char * const szIdType,
1032
+	IN const char * const szId,
1033
+	IN const char * const szPIN,
1034
+	IN const bool fProtectedAuthentication,
1035
+	OUT pkcs11_session_t * const p_pkcs11_session
1036
+) {
1037
+	pkcs11_session_t pkcs11_session;
1038
+	CK_RV rv = CKR_OK;
1039
+
1040
+	ASSERT (szSlotType!=NULL);
1041
+	ASSERT (szSlot!=NULL);
1042
+	ASSERT (szIdType!=NULL);
1043
+	ASSERT (szId!=NULL);
1044
+	ASSERT (szPIN!=NULL);
1045
+	ASSERT (p_pkcs11_session!=NULL);
1046
+	
1047
+	if (
1048
+		rv == CKR_OK &&
1049
+		(pkcs11_session = (pkcs11_session_t)malloc (sizeof (struct pkcs11_session_s))) == NULL
1050
+	) {
1051
+		rv = CKR_HOST_MEMORY;
1052
+	}
1053
+
1054
+	if (rv == CKR_OK) {
1055
+		*p_pkcs11_session = pkcs11_session;
1056
+		memset (pkcs11_session, 0, sizeof (struct pkcs11_session_s));
1057
+	}
1058
+	
1059
+	if (
1060
+		rv == CKR_OK &&
1061
+		!fProtectedAuthentication
1062
+	) {
1063
+		if ((pkcs11_session->szPIN = strdup (szPIN)) == NULL) {
1064
+			rv = CKR_HOST_MEMORY;
1065
+		}
1066
+	}
1067
+
1068
+	if (rv == CKR_OK) {
1069
+		pkcs11_session->fLoginFailed = false;
1070
+		pkcs11_session->key = -1;
1071
+		pkcs11_session->session = -1;
1072
+
1073
+		if (!strcmp (szSlotType, "id")) {
1074
+			rv = _pkcs11_getSlotById (pkcs11_session, szSlot);
1075
+		}
1076
+		else if (!strcmp (szSlotType, "name")) {
1077
+			rv = _pkcs11_getSlotByName (pkcs11_session, szSlot);
1078
+		}
1079
+		else if (!strcmp (szSlotType, "label")) {
1080
+			rv = _pkcs11_getSlotByLabel (pkcs11_session, szSlot);
1081
+		}
1082
+		else {
1083
+			rv = CKR_ARGUMENTS_BAD;
1084
+		}
1085
+	}
1086
+
1087
+	if (rv == CKR_OK) {
1088
+		rv = pkcs11_login (
1089
+			pkcs11_session
1090
+		);
1091
+	}
1092
+
1093
+	if (rv == CKR_OK) {
1094
+		rv = _pkcs11_loadCertificate (
1095
+			pkcs11_session,
1096
+			szIdType,
1097
+			szId
1098
+		);
1099
+	}
1100
+
1101
+	if (rv == CKR_OK) {
1102
+		rv = _pkcs11_loadKeyProperties (
1103
+			pkcs11_session
1104
+		);
1105
+	}
1106
+	
1107
+	pkcs11_logout (
1108
+		pkcs11_session
1109
+	);
1110
+
1111
+	return rv;
1112
+}
1113
+
1114
+CK_RV
1115
+pkcs11_freeSession (
1116
+	IN const pkcs11_session_t pkcs11_session
1117
+) {
1118
+	if (pkcs11_session != NULL) {
1119
+		pkcs11_logout (pkcs11_session);
1120
+
1121
+		if (pkcs11_session->szPIN != NULL) {
1122
+			free (pkcs11_session->szPIN);
1123
+		}
1124
+		if (pkcs11_session->certificate != NULL) {
1125
+			free (pkcs11_session->certificate);
1126
+		}
1127
+		if (pkcs11_session->certificate_id != NULL) {
1128
+			free (pkcs11_session->certificate_id);
1129
+		}
1130
+
1131
+		free (pkcs11_session);
1132
+	}
1133
+
1134
+	return CKR_OK;
1135
+}
1136
+
1137
+static
1138
+CK_RV
1139
+pkcs11_login (
1140
+	IN const pkcs11_session_t pkcs11_session
1141
+) {
1142
+	CK_RV rv = CKR_OK;
1143
+
1144
+	ASSERT (pkcs11_session!=NULL);
1145
+
1146
+	pkcs11_logout (pkcs11_session);
1147
+
1148
+	if (rv == CKR_OK) {
1149
+		rv = pkcs11_session->provider->f->C_OpenSession (
1150
+			pkcs11_session->slot,
1151
+			CKF_SERIAL_SESSION,
1152
+			NULL_PTR,
1153
+			NULL_PTR,
1154
+			&pkcs11_session->session
1155
+		);
1156
+	}
1157
+
1158
+	/*
1159
+	 * Do not lock the token
1160
+	 */
1161
+	if (
1162
+		rv == CKR_OK &&
1163
+		pkcs11_session->fLoginFailed
1164
+	) {
1165
+		rv = CKR_PIN_INVALID;
1166
+	}
1167
+
1168
+	if (
1169
+		rv == CKR_OK &&
1170
+		(rv = pkcs11_session->provider->f->C_Login (
1171
+			pkcs11_session->session,
1172
+			CKU_USER,
1173
+			pkcs11_session->szPIN,
1174
+			pkcs11_session->szPIN == NULL ? 0 : (CK_ULONG)strlen (pkcs11_session->szPIN)
1175
+		)) != CKR_OK
1176
+	) {
1177
+		if (rv == CKR_USER_ALREADY_LOGGED_IN) {
1178
+			rv = CKR_OK;
1179
+		}
1180
+		else {
1181
+			pkcs11_session->fLoginFailed = true;
1182
+		}
1183
+	}
1184
+
1185
+	if (
1186
+		rv == CKR_OK &&
1187
+		pkcs11_session->certificate_id != NULL
1188
+	) {
1189
+		rv = _pkcs11_getObjectById (
1190
+			pkcs11_session,
1191
+			CKO_PRIVATE_KEY,
1192
+			pkcs11_session->certificate_id,
1193
+			pkcs11_session->certificate_id_size,
1194
+			&pkcs11_session->key
1195
+		);
1196
+	}
1197
+
1198
+	if (rv != CKR_OK) {
1199
+		pkcs11_logout (pkcs11_session);
1200
+	}
1201
+
1202
+	return rv;
1203
+}
1204
+
1205
+static
1206
+CK_RV
1207
+pkcs11_logout (
1208
+	IN const pkcs11_session_t pkcs11_session
1209
+) {
1210
+	ASSERT (pkcs11_session!=NULL);
1211
+
1212
+	if (pkcs11_session->session != (unsigned int)-1) {
1213
+		pkcs11_session->provider->f->C_Logout (pkcs11_session->session);
1214
+		pkcs11_session->provider->f->C_CloseSession (pkcs11_session->session);
1215
+		pkcs11_session->key = -1;
1216
+		pkcs11_session->session = -1;
1217
+	}
1218
+
1219
+	return CKR_OK;
1220
+}
1221
+
1222
+static
1223
+CK_RV
1224
+pkcs11_sign (
1225
+	IN const pkcs11_session_t pkcs11_session,
1226
+	IN const CK_MECHANISM_TYPE mech_type,
1227
+	IN const unsigned char * const source,
1228
+	IN const int source_size,
1229
+	OUT unsigned char * const target,
1230
+	IN OUT int * const target_size
1231
+) {
1232
+	CK_MECHANISM mech = {
1233
+		mech_type, NULL, 0
1234
+	};
1235
+	CK_ULONG size;
1236
+	CK_RV rv;
1237
+
1238
+	ASSERT (pkcs11_session!=NULL);
1239
+	ASSERT (source!=NULL);
1240
+	ASSERT (target_size!=NULL);
1241
+
1242
+	if (
1243
+		(rv = pkcs11_session->provider->f->C_SignInit (
1244
+			pkcs11_session->session,
1245
+			&mech,
1246
+			pkcs11_session->key
1247
+		)) != CKR_OK
1248
+	) {
1249
+		return rv;
1250
+	}
1251
+
1252
+	size = *target_size;
1253
+	rv = pkcs11_session->provider->f->C_Sign (
1254
+		pkcs11_session->session,
1255
+		(CK_BYTE_PTR)source,
1256
+		source_size,
1257
+		(CK_BYTE_PTR)target,
1258
+		&size
1259
+	);
1260
+
1261
+	*target_size = (int)size;
1262
+
1263
+	return rv;
1264
+}
1265
+
1266
+static
1267
+CK_RV
1268
+pkcs11_signRecover (
1269
+	IN const pkcs11_session_t pkcs11_session,
1270
+	IN const CK_MECHANISM_TYPE mech_type,
1271
+	IN const unsigned char * const source,
1272
+	IN const int source_size,
1273
+	OUT unsigned char * const target,
1274
+	IN OUT int * const target_size
1275
+) {
1276
+	CK_MECHANISM mech = {
1277
+		mech_type, NULL, 0
1278
+	};
1279
+	CK_ULONG size;
1280
+	CK_RV rv;
1281
+
1282
+	ASSERT (pkcs11_session!=NULL);
1283
+	ASSERT (source!=NULL);
1284
+	ASSERT (target_size!=NULL);
1285
+
1286
+	if (
1287
+		(rv = pkcs11_session->provider->f->C_SignRecoverInit (
1288
+			pkcs11_session->session,
1289
+			&mech,
1290
+			pkcs11_session->key
1291
+		)) != CKR_OK
1292
+	) {
1293
+		return rv;
1294
+	}
1295
+
1296
+	size = *target_size;
1297
+	rv = pkcs11_session->provider->f->C_SignRecover (
1298
+		pkcs11_session->session,
1299
+		(CK_BYTE_PTR)source,
1300
+		source_size,
1301
+		(CK_BYTE_PTR)target,
1302
+		&size
1303
+	);
1304
+
1305
+	*target_size = (int)size;
1306
+
1307
+	return rv;
1308
+}
1309
+
1310
+static
1311
+CK_RV
1312
+pkcs11_decrypt (
1313
+	IN const pkcs11_session_t pkcs11_session,
1314
+	IN const CK_MECHANISM_TYPE mech_type,
1315
+	IN const unsigned char * const source,
1316
+	IN const int source_size,
1317
+	OUT unsigned char * const target,
1318
+	IN OUT int * const target_size
1319
+) {
1320
+	CK_MECHANISM mech = {
1321
+		mech_type, NULL, 0
1322
+	};
1323
+	CK_ULONG size;
1324
+	CK_RV rv;
1325
+
1326
+	ASSERT (pkcs11_session!=NULL);
1327
+	ASSERT (source!=NULL);
1328
+	ASSERT (target_size!=NULL);
1329
+
1330
+	if (
1331
+		(rv = pkcs11_session->provider->f->C_DecryptInit (
1332
+			pkcs11_session->session,
1333
+			&mech,
1334
+			pkcs11_session->key
1335
+		)) != CKR_OK
1336
+	) {
1337
+		return rv;
1338
+	}
1339
+
1340
+	size = *target_size;
1341
+	rv = pkcs11_session->provider->f->C_Decrypt (
1342
+		pkcs11_session->session,
1343
+		(CK_BYTE_PTR)source,
1344
+		source_size,
1345
+		(CK_BYTE_PTR)target,
1346
+		&size
1347
+	);
1348
+
1349
+	*target_size = (int)size;
1350
+
1351
+	return rv;
1352
+}
1353
+
1354
+static
1355
+CK_RV
1356
+pkcs11_getCertificate (
1357
+	IN const pkcs11_session_t pkcs11_session,
1358
+	OUT char * const certificate,
1359
+	IN OUT int * const certificate_size
1360
+) {
1361
+	ASSERT (certificate_size!=NULL);
1362
+
1363
+	*certificate_size = pkcs11_session->certificate_size;
1364
+
1365
+	if (certificate == NULL) {
1366
+		return CKR_OK;
1367
+	}
1368
+
1369
+	if (*certificate_size > pkcs11_session->certificate_size) {
1370
+		return CKR_BUFFER_TOO_SMALL;
1371
+	}
1372
+
1373
+	memmove (certificate, pkcs11_session->certificate, *certificate_size);	
1374
+
1375
+	return CKR_OK;
1376
+}
1377
+
1378
+static
1379
+char *
1380
+pkcs11_getMessage (
1381
+	IN const int rv
1382
+) {
1383
+	switch (rv) {
1384
+		case CKR_OK: return "CKR_OK";
1385
+		case CKR_CANCEL: return "CKR_CANCEL";
1386
+		case CKR_HOST_MEMORY: return "CKR_HOST_MEMORY";
1387
+		case CKR_SLOT_ID_INVALID: return "CKR_SLOT_ID_INVALID";
1388
+		case CKR_GENERAL_ERROR: return "CKR_GENERAL_ERROR";
1389
+		case CKR_FUNCTION_FAILED: return "CKR_FUNCTION_FAILED";
1390
+		case CKR_ARGUMENTS_BAD: return "CKR_ARGUMENTS_BAD";
1391
+		case CKR_NO_EVENT: return "CKR_NO_EVENT";
1392
+		case CKR_NEED_TO_CREATE_THREADS: return "CKR_NEED_TO_CREATE_THREADS";
1393
+		case CKR_CANT_LOCK: return "CKR_CANT_LOCK";
1394
+		case CKR_ATTRIBUTE_READ_ONLY: return "CKR_ATTRIBUTE_READ_ONLY";
1395
+		case CKR_ATTRIBUTE_SENSITIVE: return "CKR_ATTRIBUTE_SENSITIVE";
1396
+		case CKR_ATTRIBUTE_TYPE_INVALID: return "CKR_ATTRIBUTE_TYPE_INVALID";
1397
+		case CKR_ATTRIBUTE_VALUE_INVALID: return "CKR_ATTRIBUTE_VALUE_INVALID";
1398
+		case CKR_DATA_INVALID: return "CKR_DATA_INVALID";
1399
+		case CKR_DATA_LEN_RANGE: return "CKR_DATA_LEN_RANGE";
1400
+		case CKR_DEVICE_ERROR: return "CKR_DEVICE_ERROR";
1401
+		case CKR_DEVICE_MEMORY: return "CKR_DEVICE_MEMORY";
1402
+		case CKR_DEVICE_REMOVED: return "CKR_DEVICE_REMOVED";
1403
+		case CKR_ENCRYPTED_DATA_INVALID: return "CKR_ENCRYPTED_DATA_INVALID";
1404
+		case CKR_ENCRYPTED_DATA_LEN_RANGE: return "CKR_ENCRYPTED_DATA_LEN_RANGE";
1405
+		case CKR_FUNCTION_CANCELED: return "CKR_FUNCTION_CANCELED";
1406
+		case CKR_FUNCTION_NOT_PARALLEL: return "CKR_FUNCTION_NOT_PARALLEL";
1407
+		case CKR_FUNCTION_NOT_SUPPORTED: return "CKR_FUNCTION_NOT_SUPPORTED";
1408
+		case CKR_KEY_HANDLE_INVALID: return "CKR_KEY_HANDLE_INVALID";
1409
+		case CKR_KEY_SIZE_RANGE: return "CKR_KEY_SIZE_RANGE";
1410
+		case CKR_KEY_TYPE_INCONSISTENT: return "CKR_KEY_TYPE_INCONSISTENT";
1411
+		case CKR_KEY_NOT_NEEDED: return "CKR_KEY_NOT_NEEDED";
1412
+		case CKR_KEY_CHANGED: return "CKR_KEY_CHANGED";
1413
+		case CKR_KEY_NEEDED: return "CKR_KEY_NEEDED";
1414
+		case CKR_KEY_INDIGESTIBLE: return "CKR_KEY_INDIGESTIBLE";
1415
+		case CKR_KEY_FUNCTION_NOT_PERMITTED: return "CKR_KEY_FUNCTION_NOT_PERMITTED";
1416
+		case CKR_KEY_NOT_WRAPPABLE: return "CKR_KEY_NOT_WRAPPABLE";
1417
+		case CKR_KEY_UNEXTRACTABLE: return "CKR_KEY_UNEXTRACTABLE";
1418
+		case CKR_MECHANISM_INVALID: return "CKR_MECHANISM_INVALID";
1419
+		case CKR_MECHANISM_PARAM_INVALID: return "CKR_MECHANISM_PARAM_INVALID";
1420
+		case CKR_OBJECT_HANDLE_INVALID: return "CKR_OBJECT_HANDLE_INVALID";
1421
+		case CKR_OPERATION_ACTIVE: return "CKR_OPERATION_ACTIVE";
1422
+		case CKR_OPERATION_NOT_INITIALIZED: return "CKR_OPERATION_NOT_INITIALIZED";
1423
+		case CKR_PIN_INCORRECT: return "CKR_PIN_INCORRECT";
1424
+		case CKR_PIN_INVALID: return "CKR_PIN_INVALID";
1425
+		case CKR_PIN_LEN_RANGE: return "CKR_PIN_LEN_RANGE";
1426
+		case CKR_PIN_EXPIRED: return "CKR_PIN_EXPIRED";
1427
+		case CKR_PIN_LOCKED: return "CKR_PIN_LOCKED";
1428
+		case CKR_SESSION_CLOSED: return "CKR_SESSION_CLOSED";
1429
+		case CKR_SESSION_COUNT: return "CKR_SESSION_COUNT";
1430
+		case CKR_SESSION_HANDLE_INVALID: return "CKR_SESSION_HANDLE_INVALID";
1431
+		case CKR_SESSION_PARALLEL_NOT_SUPPORTED: return "CKR_SESSION_PARALLEL_NOT_SUPPORTED";
1432
+		case CKR_SESSION_READ_ONLY: return "CKR_SESSION_READ_ONLY";
1433
+		case CKR_SESSION_EXISTS: return "CKR_SESSION_EXISTS";
1434
+		case CKR_SESSION_READ_ONLY_EXISTS: return "CKR_SESSION_READ_ONLY_EXISTS";
1435
+		case CKR_SESSION_READ_WRITE_SO_EXISTS: return "CKR_SESSION_READ_WRITE_SO_EXISTS";
1436
+		case CKR_SIGNATURE_INVALID: return "CKR_SIGNATURE_INVALID";
1437
+		case CKR_SIGNATURE_LEN_RANGE: return "CKR_SIGNATURE_LEN_RANGE";
1438
+		case CKR_TEMPLATE_INCOMPLETE: return "CKR_TEMPLATE_INCOMPLETE";
1439
+		case CKR_TEMPLATE_INCONSISTENT: return "CKR_TEMPLATE_INCONSISTENT";
1440
+		case CKR_TOKEN_NOT_PRESENT: return "CKR_TOKEN_NOT_PRESENT";
1441
+		case CKR_TOKEN_NOT_RECOGNIZED: return "CKR_TOKEN_NOT_RECOGNIZED";
1442
+		case CKR_TOKEN_WRITE_PROTECTED: return "CKR_TOKEN_WRITE_PROTECTED";
1443
+		case CKR_UNWRAPPING_KEY_HANDLE_INVALID: return "CKR_UNWRAPPING_KEY_HANDLE_INVALID";
1444
+		case CKR_UNWRAPPING_KEY_SIZE_RANGE: return "CKR_UNWRAPPING_KEY_SIZE_RANGE";
1445
+		case CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT: return "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT";
1446
+		case CKR_USER_ALREADY_LOGGED_IN: return "CKR_USER_ALREADY_LOGGED_IN";
1447
+		case CKR_USER_NOT_LOGGED_IN: return "CKR_USER_NOT_LOGGED_IN";
1448
+		case CKR_USER_PIN_NOT_INITIALIZED: return "CKR_USER_PIN_NOT_INITIALIZED";
1449
+		case CKR_USER_TYPE_INVALID: return "CKR_USER_TYPE_INVALID";
1450
+		case CKR_USER_ANOTHER_ALREADY_LOGGED_IN: return "CKR_USER_ANOTHER_ALREADY_LOGGED_IN";
1451
+		case CKR_USER_TOO_MANY_TYPES: return "CKR_USER_TOO_MANY_TYPES";
1452
+		case CKR_WRAPPED_KEY_INVALID: return "CKR_WRAPPED_KEY_INVALID";
1453
+		case CKR_WRAPPED_KEY_LEN_RANGE: return "CKR_WRAPPED_KEY_LEN_RANGE";
1454
+		case CKR_WRAPPING_KEY_HANDLE_INVALID: return "CKR_WRAPPING_KEY_HANDLE_INVALID";
1455
+		case CKR_WRAPPING_KEY_SIZE_RANGE: return "CKR_WRAPPING_KEY_SIZE_RANGE";
1456
+		case CKR_WRAPPING_KEY_TYPE_INCONSISTENT: return "CKR_WRAPPING_KEY_TYPE_INCONSISTENT";
1457
+		case CKR_RANDOM_SEED_NOT_SUPPORTED: return "CKR_RANDOM_SEED_NOT_SUPPORTED";
1458
+		case CKR_RANDOM_NO_RNG: return "CKR_RANDOM_NO_RNG";
1459
+		case CKR_DOMAIN_PARAMS_INVALID: return "CKR_DOMAIN_PARAMS_INVALID";
1460
+		case CKR_BUFFER_TOO_SMALL: return "CKR_BUFFER_TOO_SMALL";
1461
+		case CKR_SAVED_STATE_INVALID: return "CKR_SAVED_STATE_INVALID";
1462
+		case CKR_INFORMATION_SENSITIVE: return "CKR_INFORMATION_SENSITIVE";
1463
+		case CKR_STATE_UNSAVEABLE: return "CKR_STATE_UNSAVEABLE";
1464
+		case CKR_CRYPTOKI_NOT_INITIALIZED: return "CKR_CRYPTOKI_NOT_INITIALIZED";
1465
+		case CKR_CRYPTOKI_ALREADY_INITIALIZED: return "CKR_CRYPTOKI_ALREADY_INITIALIZED";
1466
+		case CKR_MUTEX_BAD: return "CKR_MUTEX_BAD";
1467
+		case CKR_MUTEX_NOT_LOCKED: return "CKR_MUTEX_NOT_LOCKED";
1468
+		case CKR_FUNCTION_REJECTED: return "CKR_FUNCTION_REJECTED";
1469
+		case CKR_VENDOR_DEFINED: return "CKR_VENDOR_DEFINED";
1470
+		default: return "Unknown PKCS#11 error";
1471
+	}
1472
+}
1473
+
1474
+/*==========================================
1475
+ * openvpn interface
1476
+ */
1477
+
1478
+typedef struct openssl_session_s {
1479
+	int (*orig_finish)(RSA *rsa);
1480
+	pkcs11_session_t pkcs11_session;
1481
+} *openssl_session_t;
1482
+
1483
+static
1484
+pkcs11_session_t
1485
+_openssl_get_pkcs11_session (const RSA *rsa) {
1486
+	openssl_session_t session;
1487
+	
1488
+	ASSERT (rsa!=NULL);
1489
+	session = (openssl_session_t)RSA_get_app_data (rsa);
1490
+	ASSERT (session!=NULL);
1491
+	ASSERT (session->pkcs11_session!=NULL);
1492
+
1493
+	return session->pkcs11_session;
1494
+}
1495
+
1496
+static
1497
+int
1498
+openssl_pkcs11_priv_enc (
1499
+	int flen,
1500
+	const unsigned char *from,
1501
+	unsigned char *to,
1502
+	RSA *rsa,
1503
+	int padding
1504
+) {
1505
+	msg(M_WARN, "PKCS#11: Private key encryption not supported");
1506
+	return -1;
1507
+}
1508
+
1509
+static
1510
+int
1511
+openssl_pkcs11_priv_dec (
1512
+	int flen, const unsigned char *from,
1513
+	unsigned char *to,
1514
+	RSA *rsa,
1515
+	int padding
1516
+) {
1517
+	pkcs11_session_t pkcs11_session = _openssl_get_pkcs11_session (rsa);
1518
+	CK_RV rv = CKR_OK;
1519
+
1520
+	msg (
1521
+		D_PKCS11_DEBUG,
1522
+		"PKCS#11: openssl_pkcs11_priv_dec entered - flen=%d, from=%p, to=%p, rsa=%p, padding=%d",
1523
+		flen,
1524
+		from,
1525
+		to,
1526
+		rsa,
1527
+		padding
1528
+	);
1529
+
1530
+	ASSERT (from!=NULL);
1531
+	ASSERT (to!=NULL);
1532
+
1533
+	msg (
1534
+		D_SHOW_PKCS11,
1535
+		"PKCS#11: Performing decryption using private key"
1536
+	);
1537
+
1538
+	if (padding != RSA_PKCS1_PADDING) {
1539
+		rv = CKR_ARGUMENTS_BAD;
1540
+	}
1541
+
1542
+	if (
1543
+		rv == CKR_OK &&
1544
+		(rv = pkcs11_login (pkcs11_session)) != CKR_OK
1545
+	) {
1546
+		msg (M_WARN, "PKCS#11: Cannot login to token %ld:'%s'", rv, pkcs11_getMessage (rv));
1547
+	}
1548
+	
1549
+	if (
1550
+		rv == CKR_OK &&
1551
+		(rv = pkcs11_decrypt (
1552
+			pkcs11_session,
1553
+			CKM_RSA_PKCS,
1554
+			from,
1555
+			flen,
1556
+			to,
1557
+			&flen
1558
+		)) != CKR_OK
1559
+	) {
1560
+		msg (M_WARN, "PKCS#11: Cannot decrypt using private key %ld:'%s'", rv, pkcs11_getMessage (rv));
1561
+	}
1562
+
1563
+	pkcs11_logout (pkcs11_session);
1564
+
1565
+	msg (
1566
+		D_PKCS11_DEBUG,
1567
+		"PKCS#11: openssl_pkcs11_priv_dec - return rv=%ld",
1568
+		rv
1569
+	);
1570
+	
1571
+	return rv == CKR_OK ? 1 : -1; 
1572
+}
1573
+
1574
+static
1575
+int
1576
+openssl_pkcs11_sign (
1577
+	int type,
1578
+	const unsigned char *m,
1579
+	unsigned int m_len,
1580
+	unsigned char *sigret,
1581
+	unsigned int *siglen,
1582
+	const RSA *rsa
1583
+) {
1584
+	pkcs11_session_t pkcs11_session = _openssl_get_pkcs11_session (rsa);
1585
+	CK_RV rv = CKR_OK;
1586
+
1587
+	msg (
1588
+		D_PKCS11_DEBUG,
1589
+		"PKCS#11: openssl_pkcs11_priv_sign entered - type=%d, m=%p, m_len=%u, signret=%p, signlen=%p, rsa=%p",
1590
+		type,
1591
+		m,
1592
+		m_len,
1593
+		sigret,
1594
+		siglen,
1595
+		rsa
1596
+	);
1597
+
1598
+	ASSERT (m!=NULL);
1599
+	ASSERT (siglen!=NULL);
1600
+
1601
+	msg (
1602
+		D_SHOW_PKCS11,
1603
+		"PKCS#11: Performing signature"
1604
+	);
1605
+
1606
+	*siglen = RSA_size(rsa);
1607
+
1608
+	if (
1609
+		rv == CKR_OK &&
1610
+		(rv = pkcs11_login (pkcs11_session)) != CKR_OK
1611
+	) {
1612
+		msg (M_WARN, "PKCS#11: Cannot login to token %ld:'%s'", rv, pkcs11_getMessage (rv));
1613
+	}
1614
+	
1615
+	if (rv == CKR_OK) {
1616
+		if (pkcs11_session->fKeySignRecover) {
1617
+			if (
1618
+				(rv = pkcs11_signRecover (
1619
+					pkcs11_session,
1620
+					CKM_RSA_PKCS,
1621
+					m,
1622
+					m_len,
1623
+					sigret,
1624
+					siglen
1625
+				)) != CKR_OK
1626
+			) {
1627
+				msg (M_WARN, "PKCS#11: Cannot perform signature-recover %ld:'%s'", rv, pkcs11_getMessage (rv));
1628
+			}
1629
+		}
1630
+		else {
1631
+			if (
1632
+				(rv = pkcs11_sign (
1633
+					pkcs11_session,
1634
+					CKM_RSA_PKCS,
1635
+					m,
1636
+					m_len,
1637
+					sigret,
1638
+					siglen
1639
+				)) != CKR_OK
1640
+			) {
1641
+				msg (M_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11_getMessage (rv));
1642
+			}
1643
+		}
1644
+	}
1645
+
1646
+	pkcs11_logout (pkcs11_session);
1647
+
1648
+	msg (
1649
+		D_PKCS11_DEBUG,
1650
+		"PKCS#11: openssl_pkcs11_priv_sign - return rv=%ld",
1651
+		rv
1652
+	);
1653
+	
1654
+	return rv == CKR_OK ? 1 : -1; 
1655
+}
1656
+
1657
+static
1658
+int
1659
+openssl_pkcs11_finish(RSA *rsa) {
1660
+	pkcs11_session_t pkcs11_session = _openssl_get_pkcs11_session (rsa);
1661
+	openssl_session_t openssl_session;
1662
+
1663
+	msg (
1664
+		D_PKCS11_DEBUG,
1665
+		"PKCS#11: openssl_pkcs11_finish - entered - rsa=%p",
1666
+		rsa
1667
+	);
1668
+
1669
+	openssl_session = (openssl_session_t)RSA_get_app_data (rsa);
1670
+
1671
+	RSA_set_app_data (rsa, NULL);
1672
+	pkcs11_freeSession (pkcs11_session);
1673
+	
1674
+	if (openssl_session->orig_finish != NULL) {
1675
+		openssl_session->orig_finish (rsa);
1676
+
1677
+#ifdef BROKEN_OPENSSL_ENGINE
1678
+		{
1679
+			/* We get called TWICE here, once for
1680
+			 * releasing the key and also for
1681
+			 * releasing the engine.
1682
+			 * To prevent endless recursion, FIRST
1683
+			 * clear rsa->engine, THEN call engine->finish
1684
+			 */
1685
+			ENGINE *e = rsa->engine;
1686
+			rsa->engine = NULL;
1687
+			if (e) {
1688
+				ENGINE_finish(e);
1689
+			}
1690
+		}
1691
+#endif
1692
+	}
1693
+
1694
+	free  (openssl_session);
1695
+
1696
+	msg (
1697
+		D_PKCS11_DEBUG,
1698
+		"PKCS#11: openssl_pkcs11_finish - return"
1699
+	);
1700
+	
1701
+	return 1;
1702
+}
1703
+
1704
+static RSA_METHOD *
1705
+openssl_pkcs11_get_rsa_method(RSA *rsa)
1706
+{
1707
+	static RSA_METHOD smart_rsa;
1708
+	const RSA_METHOD *def = RSA_get_default_method();
1709
+
1710
+	ASSERT (rsa);
1711
+
1712
+	/* use the OpenSSL version */
1713
+	memmove (&smart_rsa, def, sizeof(smart_rsa));
1714
+
1715
+	/* save original */
1716
+	((openssl_session_t)RSA_get_app_data (rsa))->orig_finish = def->finish;
1717
+
1718
+	smart_rsa.name = "pkcs11";
1719
+	smart_rsa.rsa_priv_enc = openssl_pkcs11_priv_enc;
1720
+	smart_rsa.rsa_priv_dec = openssl_pkcs11_priv_dec;
1721
+	smart_rsa.rsa_sign = openssl_pkcs11_sign;
1722
+	smart_rsa.finish = openssl_pkcs11_finish;
1723
+	smart_rsa.flags  = RSA_METHOD_FLAG_NO_CHECK | RSA_FLAG_EXT_PKEY;
1724
+	return &smart_rsa;
1725
+}
1726
+
1727
+
1728
+#ifdef BROKEN_OPENSSL_ENGINE
1729
+static void broken_openssl_init() __attribute__ ((constructor));
1730
+static void  broken_openssl_init()
1731
+{
1732
+	SSL_library_init();
1733
+	ENGINE_load_openssl();
1734
+	ENGINE_register_all_RSA();
1735
+}
1736
+#endif
1737
+
1738
+int
1739
+SSL_CTX_use_pkcs11 (
1740
+	IN OUT SSL_CTX * const ssl_ctx,
1741
+	IN const char * const pkcs11_slot_type,
1742
+	IN const char * const pkcs11_slot,
1743
+	IN const char * const pkcs11_id_type,
1744
+	IN const char * const pkcs11_id,
1745
+	IN const char * const pin,
1746
+	IN const bool pkcs11_protected_authentication
1747
+) {
1748
+	X509 *x509 = NULL;
1749
+	RSA *rsa = NULL;
1750
+	EVP_PKEY *pubkey = NULL;
1751
+	openssl_session_t openssl_session = NULL;
1752
+	bool fShouldFreeOpenSSLSession = true;
1753
+	CK_RV rv = CKR_OK;
1754
+
1755
+	unsigned char certificate[10*1024];
1756
+	int certificate_size;
1757
+	unsigned char *p;
1758
+	bool fOK = true;
1759
+
1760
+	msg (
1761
+		D_PKCS11_DEBUG,
1762
+		"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",
1763
+		ssl_ctx,
1764
+		pkcs11_slot_type,
1765
+		pkcs11_slot,
1766
+		pkcs11_id_type,
1767
+		pkcs11_id,
1768
+		pkcs11_protected_authentication ? 1 : 0
1769
+	);
1770
+
1771
+	ASSERT (ssl_ctx!=NULL);
1772
+	ASSERT (pkcs11_slot_type!=NULL);
1773
+	ASSERT (pkcs11_slot!=NULL);
1774
+	ASSERT (pkcs11_id_type!=NULL);
1775
+	ASSERT (pkcs11_id!=NULL);
1776
+	if (!pkcs11_protected_authentication) {
1777
+		ASSERT (pin!=NULL);
1778
+	}
1779
+
1780
+	if (
1781
+		fOK &&
1782
+		(openssl_session = (openssl_session_t)malloc (sizeof (struct openssl_session_s))) == NULL
1783
+	) {
1784
+		fOK = false;
1785
+		msg (M_WARN, "PKCS#11: Cannot allocate memory");
1786
+	}
1787
+
1788
+	if (fOK) {
1789
+		memset (openssl_session, 0, sizeof (struct openssl_session_s));
1790
+	}
1791
+	
1792
+	if (
1793
+		fOK &&
1794
+		(rv = pkcs11_createSession (
1795
+			pkcs11_slot_type,
1796
+			pkcs11_slot,
1797
+			pkcs11_id_type,
1798
+			pkcs11_id,
1799
+			pin,
1800
+			pkcs11_protected_authentication,
1801
+			&openssl_session->pkcs11_session
1802
+		)) != CKR_OK
1803
+	) {
1804
+		fOK = false;
1805
+		msg (M_WARN, "PKCS#11: Cannot set parameters %ld-'%s'", rv, pkcs11_getMessage (rv));
1806
+	}
1807
+
1808
+	if (
1809
+		fOK &&
1810
+		(x509 = X509_new ()) == NULL
1811
+	) {
1812
+		fOK = false;
1813
+		msg (M_WARN, "PKCS#11: Unable to allocate certificate object");
1814
+	}
1815
+
1816
+	certificate_size = sizeof (certificate);
1817
+	if (
1818
+		fOK &&
1819
+		(rv = pkcs11_getCertificate (
1820
+			openssl_session->pkcs11_session,
1821
+			certificate,
1822
+			&certificate_size
1823
+		)) != CKR_OK
1824
+	) { 
1825
+		fOK = false;
1826
+		msg (M_WARN, "PKCS#11: Cannot read X.509 certificate from token %ld-'%s'", rv, pkcs11_getMessage (rv));
1827
+	}
1828
+
1829
+	p = certificate;
1830
+	if (
1831
+		fOK &&
1832
+		!d2i_X509 (&x509, &p, certificate_size)
1833
+	) {
1834
+		fOK = false;
1835
+		msg (M_WARN, "PKCS#11: Unable to parse X.509 certificate");
1836
+	}
1837
+
1838
+	if (
1839
+		fOK &&
1840
+		(pubkey = X509_get_pubkey (x509)) == NULL
1841
+	) {
1842
+		fOK = false;
1843
+		msg (M_WARN, "PKCS#11: Cannot get public key");
1844
+	}
1845
+	
1846
+	if (
1847
+		fOK &&
1848
+		pubkey->type != EVP_PKEY_RSA
1849
+	) {
1850
+		fOK = false;
1851
+		msg (M_WARN, "PKCS#11: Invalid public key algorithm");
1852
+	}
1853
+
1854
+	if (
1855
+		fOK &&
1856
+		(rsa = EVP_PKEY_get1_RSA (pubkey)) == NULL
1857
+	) {
1858
+		fOK = false;
1859
+		msg (M_WARN, "PKCS#11: Cannot get RSA key");
1860
+	}
1861
+
1862
+	if (fOK) {
1863
+		RSA_set_app_data (rsa, openssl_session);
1864
+		RSA_set_method (rsa, openssl_pkcs11_get_rsa_method (rsa));
1865
+		rsa->flags |= RSA_FLAG_SIGN_VER;
1866
+
1867
+		// it will be freed when rsa usage count will be zero
1868
+		fShouldFreeOpenSSLSession = false;
1869
+	}
1870
+	
1871
+#ifdef BROKEN_OPENSSL_ENGINE
1872
+	if (fOK) {
1873
+		if (!rsa->engine)
1874
+			rsa->engine = ENGINE_get_default_RSA();
1875
+
1876
+		ENGINE_set_RSA(ENGINE_get_default_RSA(), openssl_pkcs11_get_rsa_method(rsa));
1877
+		msg(M_WARN, "PKCS#11: OpenSSL engine support is broken! Workaround enabled");
1878
+	}
1879
+#endif
1880
+
1881
+	if (
1882
+		fOK &&
1883
+		!SSL_CTX_use_certificate (ssl_ctx, x509)
1884
+	) {
1885
+		fOK = false;
1886
+		msg (M_WARN, "PKCS#11: Cannot set certificate for openssl");
1887
+	}
1888
+
1889
+	if (
1890
+		fOK &&
1891
+		!SSL_CTX_use_RSAPrivateKey (ssl_ctx, rsa)
1892
+	) {
1893
+		fOK = false;
1894
+		msg (M_WARN, "PKCS#11: Cannot set private key for openssl");
1895
+	}
1896
+
1897
+	/*
1898
+	 * openssl objects have reference
1899
+	 * count, so release them
1900
+	 */
1901
+	if (pubkey != NULL) {
1902
+		EVP_PKEY_free (pubkey);
1903
+		pubkey = NULL;
1904
+	}
1905
+
1906
+	if (x509 != NULL) {
1907
+		X509_free (x509);
1908
+		x509 = NULL;
1909
+	}
1910
+
1911
+	if (rsa != NULL) {
1912
+		RSA_free (rsa);
1913
+		rsa = NULL;
1914
+	}
1915
+
1916
+	if (fShouldFreeOpenSSLSession) {
1917
+		if (openssl_session != NULL) {
1918
+			if (openssl_session->pkcs11_session != NULL) {
1919
+				pkcs11_freeSession (openssl_session->pkcs11_session);
1920
+			}
1921
+			free (openssl_session);
1922
+			openssl_session = NULL;
1923
+		}
1924
+	}
1925
+
1926
+	msg (
1927
+		D_PKCS11_DEBUG,
1928
+		"PKCS#11: SSL_CTX_use_pkcs11 - return fOK=%d, rv=%ld",
1929
+		fOK ? 1 : 0,
1930
+		rv
1931
+	);
1932
+
1933
+	return fOK;
1934
+}
1935
+
1936
+void
1937
+add_pkcs11 (
1938
+	IN const char * const provider,
1939
+	IN const char * const sign_mode
1940
+) {
1941
+	CK_RV rv;
1942
+
1943
+	msg (
1944
+		D_PKCS11_DEBUG,
1945
+		"PKCS#11: add_pkcs11 - entered - provider='%s', sign_mode='%s'",
1946
+		provider,
1947
+		sign_mode == NULL ? "default" : sign_mode
1948
+	);
1949
+
1950
+	msg (
1951
+		M_INFO,
1952
+		"PKCS#11: Adding PKCS#11 provider '%s'",
1953
+		provider
1954
+	);
1955
+
1956
+	if ((rv = pkcs11_addProvider (provider, sign_mode)) != CKR_OK) {
1957
+		msg (M_WARN, "PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv, pkcs11_getMessage (rv));
1958
+	}
1959
+
1960
+	msg (
1961
+		D_PKCS11_DEBUG,
1962
+		"PKCS#11: add_pkcs11 - return"
1963
+	);
1964
+}
1965
+
1966
+void
1967
+free_pkcs11 () {
1968
+	msg (
1969
+		D_PKCS11_DEBUG,
1970
+		"PKCS#11: free_pkcs11 - entered"
1971
+	);
1972
+
1973
+	pkcs11_finalize ();
1974
+
1975
+	msg (
1976
+		D_PKCS11_DEBUG,
1977
+		"PKCS#11: free_pkcs11 - return"
1978
+	);
1979
+}
1980
+
1981
+void
1982
+show_pkcs11_slots (
1983
+	IN const int msglev,
1984
+	IN const int warnlev,
1985
+	IN const char * const provider
1986
+) {
1987
+	CK_INFO info;
1988
+	CK_SLOT_ID slots[1024];
1989
+	CK_ULONG slotnum;
1990
+	CK_SLOT_ID s;
1991
+	CK_RV rv;
1992
+
1993
+	ASSERT (provider!=NULL);
1994
+
1995
+	if (
1996
+		(rv = pkcs11_addProvider (provider, NULL)) != CKR_OK
1997
+	) {
1998
+		msg (M_FATAL, "PKCS#11: Cannot initialize provider %ld-'%s'", rv, pkcs11_getMessage (rv));
1999
+	}
2000
+
2001
+	if (
2002
+		(rv = pkcs11_provider->f->C_GetInfo (&info)) != CKR_OK
2003
+	) {
2004
+		msg (warnlev, "PKCS#11: Cannot get PKCS#11 provider information %ld-'%s'", rv, pkcs11_getMessage (rv));
2005
+	}
2006
+	else {
2007
+		char szManufacturerID[sizeof (info.manufacturerID)+1];
2008
+
2009
+		_fixupFixedString (
2010
+			info.manufacturerID,
2011
+			szManufacturerID,
2012
+			sizeof (info.manufacturerID)
2013
+		);
2014
+
2015
+		msg (
2016
+			msglev,
2017
+			(
2018
+			 	"Provider Information:\n"
2019
+				"\tcryptokiVersion: %u.%u\n"
2020
+				"\tmanufacturerID: %s\n"
2021
+				"\tflags: %d\n"
2022
+			),
2023
+			info.cryptokiVersion.major,
2024
+			info.cryptokiVersion.minor,
2025
+			szManufacturerID,
2026
+			(unsigned)info.flags
2027
+		);
2028
+	}
2029
+	
2030
+	slotnum = sizeof (slots) / sizeof (CK_SLOT_ID);
2031
+	if (
2032
+		(rv = pkcs11_provider->f->C_GetSlotList (
2033
+			FALSE,
2034
+			slots,
2035
+			&slotnum
2036
+		)) != CKR_OK
2037
+	) {
2038
+		msg (warnlev, "PKCS#11: Cannot get slot list %ld-'%s'", rv, pkcs11_getMessage (rv));
2039
+	}
2040
+	else {
2041
+		msg (
2042
+			msglev,
2043
+			(
2044
+			 	"The following slots are available for use with this provider.\n"
2045
+				"Each slot shown below may be used as a parameter to a\n"
2046
+				"--pkcs11-slot-type and --pkcs11-slot options.\n"
2047
+				"\n"
2048
+				"Slots: (id - name)"
2049
+			)
2050
+		);
2051
+		for (s=0;s<slotnum;s++) {
2052
+			CK_SLOT_INFO info;
2053
+
2054
+			if (
2055
+				(rv = pkcs11_provider->f->C_GetSlotInfo (
2056
+					slots[s],
2057
+					&info
2058
+				)) == CKR_OK
2059
+			) {
2060
+				char szCurrentName[sizeof (info.slotDescription)+1];
2061
+			
2062
+				_fixupFixedString (
2063
+					info.slotDescription,
2064
+					szCurrentName,
2065
+					sizeof (info.slotDescription)
2066
+				);
2067
+
2068
+				msg (msglev, "\t%lu - %s", slots[s], szCurrentName);
2069
+			}
2070
+		}
2071
+	}
2072
+
2073
+	pkcs11_finalize ();
2074
+}
2075
+
2076
+void
2077
+show_pkcs11_objects (
2078
+	IN const int msglev,
2079
+	IN const int warnlev,
2080
+	IN const char * const provider,
2081
+	IN const char * const slot,
2082
+	IN const char * const pin
2083
+) {
2084
+	CK_OBJECT_HANDLE objects[10];
2085
+	CK_SESSION_HANDLE session;
2086
+	CK_ULONG objects_found;
2087
+	CK_TOKEN_INFO info;
2088
+	CK_SLOT_ID s;
2089
+	CK_RV rv;
2090
+
2091
+	ASSERT (provider!=NULL);
2092
+	ASSERT (slot!=NULL);
2093
+	ASSERT (pin!=NULL);
2094
+
2095
+	s = atoi (slot);
2096
+
2097
+	if (
2098
+		(rv = pkcs11_addProvider (provider, NULL)) != CKR_OK
2099
+	) {
2100
+		msg (M_FATAL, "PKCS#11: Cannot initialize provider %ld-'%s'", rv, pkcs11_getMessage (rv));
2101
+	}
2102
+
2103
+	if (
2104
+		(rv = pkcs11_provider->f->C_GetTokenInfo (
2105
+			s,
2106
+			&info
2107
+		)) != CKR_OK
2108
+	) {
2109
+		msg (warnlev, "PKCS#11: Cannot get token information for slot %ld %ld-'%s'", s, rv, pkcs11_getMessage (rv));
2110
+	}
2111
+	else {
2112
+		char szLabel[sizeof (info.label)+1];
2113
+		char szManufacturerID[sizeof (info.manufacturerID)+1];
2114
+		char szModel[sizeof (info.model)+1];
2115
+		char szSerialNumber[sizeof (info.serialNumber)+1];
2116
+		
2117
+		_fixupFixedString (
2118
+			info.label,
2119
+			szLabel,
2120
+			sizeof (info.label)
2121
+		);
2122
+		_fixupFixedString (
2123
+			info.manufacturerID,
2124
+			szManufacturerID,
2125
+			sizeof (info.manufacturerID)
2126
+		);
2127
+		_fixupFixedString (
2128
+			info.model,
2129
+			szModel,
2130
+			sizeof (info.model)
2131
+		);
2132
+		_fixupFixedString (
2133
+			info.serialNumber,
2134
+			szSerialNumber,
2135
+			sizeof (info.serialNumber)
2136
+		);
2137
+
2138
+		msg (
2139
+			msglev,
2140
+			(
2141
+			 	"Token Information:\n"
2142
+				"\tlabel:\t\t%s\n"
2143
+				"\tmanufacturerID:\t%s\n"
2144
+				"\tmodel:\t\t%s\n"
2145
+				"\tserialNumber:\t%s\n"
2146
+				"\tflags:\t\t%08x\n"
2147
+				"\n"
2148
+				"You can access this token using\n"
2149
+				"--pkcs11-slot-type \"label\" --pkcs11-slot \"%s\" options.\n"
2150
+			),
2151
+			szLabel,
2152
+			szManufacturerID,
2153
+			szModel,
2154
+			szSerialNumber,
2155
+			(unsigned)info.flags,
2156
+			szLabel
2157
+		);
2158
+	}
2159
+
2160
+	if (
2161
+		(rv = pkcs11_provider->f->C_OpenSession (
2162
+			s,
2163
+			CKF_SERIAL_SESSION,
2164
+			NULL_PTR,
2165
+			NULL_PTR,
2166
+			&session
2167
+		)) != CKR_OK
2168
+	) {
2169
+		msg (M_FATAL, "PKCS#11: Cannot open session to slot %ld %ld-'%s'", s, rv, pkcs11_getMessage (rv));
2170
+	}
2171
+
2172
+	if (
2173
+		(rv = pkcs11_provider->f->C_Login (
2174
+			session,
2175
+			CKU_USER,
2176
+			(CK_CHAR_PTR)pin,
2177
+			(CK_ULONG)strlen (pin)
2178
+		)) != CKR_OK &&
2179
+		rv != CKR_USER_ALREADY_LOGGED_IN
2180
+	) {
2181
+		msg (M_FATAL, "PKCS#11: Cannot login to token on slot %ld %ld-'%s'", s, rv, pkcs11_getMessage (rv));
2182
+	}
2183
+
2184
+	if (
2185
+		(rv = pkcs11_provider->f->C_FindObjectsInit (
2186
+			session,
2187
+			NULL,
2188
+			0
2189
+		)) != CKR_OK
2190
+	) {
2191
+		msg (M_FATAL, "PKCS#11: Cannot query objects for token on slot %ld %ld-'%s'", s, rv, pkcs11_getMessage (rv));
2192
+	}
2193
+
2194
+	msg (
2195
+		msglev,
2196
+		"The following objects are available for use with this token.\n"
2197
+		"Each object shown below may be used as a parameter to\n"
2198
+		"--pkcs11-id-type and --pkcs11-id options.\n"
2199
+	);
2200
+
2201
+	while (
2202
+		(rv = pkcs11_provider->f->C_FindObjects (
2203
+			session,
2204
+			objects,
2205
+			sizeof (objects) / sizeof (CK_OBJECT_HANDLE),
2206
+			&objects_found
2207
+		)) == CKR_OK &&
2208
+		objects_found > 0
2209
+	) { 
2210
+		CK_ULONG i;
2211
+		
2212
+		for (i=0;i<objects_found;i++) {
2213
+			CK_OBJECT_CLASS attrs_class;
2214
+			unsigned char attrs_id[PKCS11_MAX_ATTRIBUTE_SIZE];
2215
+			unsigned char attrs_label[PKCS11_MAX_ATTRIBUTE_SIZE];
2216
+			CK_ATTRIBUTE attrs[] = {
2217
+				{CKA_CLASS, &attrs_class, sizeof (attrs_class)},
2218
+				{CKA_ID, attrs_id, sizeof (attrs_id)},
2219
+				{CKA_LABEL, attrs_label, sizeof (attrs_label)-1}
2220
+			};
2221
+	
2222
+			if (
2223
+				pkcs11_provider->f->C_GetAttributeValue (
2224
+					session,
2225
+					objects[i],
2226
+					attrs,
2227
+					sizeof (attrs) / sizeof (CK_ATTRIBUTE)
2228
+				) == CKR_OK
2229
+			) {
2230
+				int id_len = attrs[1].ulValueLen;
2231
+				int j;
2232
+					
2233
+				attrs_label[attrs[2].ulValueLen] = 0;
2234
+
2235
+				msg (
2236
+					msglev,
2237
+					(
2238
+					 	"Object\n"
2239
+						"\tLabel:\t\t%s\n"
2240
+						"\tId:"
2241
+					),
2242
+					attrs_label
2243
+				);
2244
+
2245
+					
2246
+				for (j=0;j<id_len;j+=16) {
2247
+					char szLine[3*16+1];
2248
+					int k;
2249
+
2250
+					szLine[0] = '\0';
2251
+					for (k=0;k<16 && j+k<id_len;k++) {
2252
+						sprintf (szLine+strlen (szLine), "%02x ", attrs_id[j+k]);
2253
+					}
2254
+
2255
+					msg (msglev, "\t\t%s", szLine);
2256
+				}
2257
+
2258
+				if (attrs_class == CKO_CERTIFICATE) {
2259
+					unsigned char certificate[PKCS11_MAX_ATTRIBUTE_SIZE];
2260
+					CK_ATTRIBUTE attrs_cert[] = {
2261
+						{CKA_VALUE, certificate, sizeof (certificate)}
2262
+					};
2263
+
2264
+					msg (msglev, "\tType:\t\tCertificate");
2265
+
2266
+					if (
2267
+						pkcs11_provider->f->C_GetAttributeValue (
2268
+							session,
2269
+							objects[i],
2270
+							attrs_cert,
2271
+							sizeof (attrs_cert) / sizeof (CK_ATTRIBUTE)
2272
+						) == CKR_OK
2273
+					) {
2274
+						X509 *x509 = NULL;
2275
+						BIO *bioSerial = NULL;
2276
+
2277
+						char szSubject[1024];
2278
+						char szSerial[1024];
2279
+						char szNotBefore[1024];
2280
+
2281
+						szSubject[0] = '\0';
2282
+						szSerial[0] = '\0';
2283
+						szNotBefore[0] = '\0';
2284
+
2285
+						if ((x509 = X509_new ()) == NULL) {
2286
+							msg (warnlev, "Cannot create x509 context");
2287
+						}
2288
+						else {
2289
+							unsigned char *p;
2290
+
2291
+							p = certificate;
2292
+							if (d2i_X509 (&x509, &p, attrs_cert[0].ulValueLen)) {
2293
+
2294
+								ASN1_TIME *notBefore = X509_get_notBefore (x509);
2295
+								if (notBefore != NULL && notBefore->length < (int) sizeof (szNotBefore) - 1) {
2296
+									memmove (szNotBefore, notBefore->data, notBefore->length);
2297
+									szNotBefore[notBefore->length] = '\0';
2298
+								}
2299
+
2300
+  								X509_NAME_oneline (
2301
+									X509_get_subject_name (x509),
2302
+									szSubject,
2303
+									sizeof (szSubject)
2304
+								);
2305
+								szSubject[sizeof (szSubject) - 1] = '\0';
2306
+							}
2307
+						}
2308
+
2309
+						if ((bioSerial = BIO_new (BIO_s_mem ())) == NULL) {
2310
+							msg (warnlev, "Cannot create BIO context");
2311
+						}
2312
+						else {
2313
+							int n;
2314
+
2315
+							i2a_ASN1_INTEGER(bioSerial, X509_get_serialNumber (x509));
2316
+							n = BIO_read (bioSerial, szSerial, sizeof (szSerial)-1);
2317
+							if (n<0) {
2318
+								szSerial[0] = '\0';
2319
+							}
2320
+							else {
2321
+								szSerial[n] = '\0';
2322
+							}
2323
+						}
2324
+
2325
+
2326
+						if (x509 != NULL) {
2327
+							X509_free (x509);
2328
+							x509 = NULL;
2329
+						}
2330
+						if (bioSerial != NULL) {
2331
+							BIO_free_all (bioSerial);
2332
+							bioSerial = NULL;
2333
+						}
2334
+
2335
+						msg (
2336
+							msglev,
2337
+							(
2338
+							 	"\tsubject:\t%s\n"
2339
+								"\tserialNumber:\t%s\n"
2340
+								"\tnotBefore:\t%s"
2341
+							),
2342
+							szSubject,
2343
+							szSerial,
2344
+							szNotBefore
2345
+						);
2346
+					}
2347
+				}
2348
+				else if (attrs_class == CKO_PRIVATE_KEY) {
2349
+					CK_BBOOL sign_recover;
2350
+					CK_BBOOL sign;
2351
+					CK_ATTRIBUTE attrs_key[] = {
2352
+						{CKA_SIGN, &sign_recover, sizeof (sign_recover)},
2353
+						{CKA_SIGN_RECOVER, &sign, sizeof (sign)}
2354
+					};
2355
+
2356
+					msg (msglev, "\tType:\t\tPrivate Key");
2357
+
2358
+					if (
2359
+						pkcs11_provider->f->C_GetAttributeValue (
2360
+							session,
2361
+							objects[i],
2362
+							attrs_key,
2363
+							sizeof (attrs_key) / sizeof (CK_ATTRIBUTE)
2364
+						) == CKR_OK
2365
+					) {
2366
+						msg (
2367
+							msglev,
2368
+							(
2369
+								"\tSign:\t\t%s\n"
2370
+								"\tSign Recover:\t%s"
2371
+							),
2372
+							sign ? "TRUE" : "FALSE",
2373
+							sign_recover ? "TRUE" : "FALSE"
2374
+						);
2375
+					}
2376
+				}
2377
+				else {
2378
+					msg (msglev, "\tType:\t\tUnsupported");
2379
+				}
2380
+			}
2381
+		}
2382
+	}
2383
+	pkcs11_provider->f->C_FindObjectsFinal (session);
2384
+	pkcs11_provider->f->C_Logout (session);
2385
+	pkcs11_provider->f->C_CloseSession (session);
2386
+	pkcs11_finalize ();
2387
+}
2388
+
2389
+#else
2390
+static void dummy (void) {}
2391
+#endif /* USE_OPENSC && USE_SSL && USE_CRYPTO */
0 2392
new file mode 100644
... ...
@@ -0,0 +1,64 @@
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 OPENVPN_PKCS11_H
25
+#define OPENVPN_PKCS11_H
26
+
27
+int
28
+SSL_CTX_use_pkcs11 (
29
+	SSL_CTX * const ssl_ctx,
30
+	const char * const pkcs11_slot_type,
31
+	const char * const pkcs11_slot,
32
+	const char * const pkcs11_id_type,
33
+	const char * const pkcs11_id,
34
+	const char * const pin,
35
+	const bool pkcs11_protected_authentication
36
+);
37
+
38
+void
39
+add_pkcs11 (
40
+	const char * const provider,
41
+	const char * const sign_mode
42
+);
43
+
44
+void
45
+free_pkcs11 ();
46
+
47
+void
48
+show_pkcs11_slots (
49
+	const int msglev,
50
+	const int warnlev,
51
+	const char * const provider
52
+);
53
+
54
+void
55
+show_pkcs11_objects (
56
+	const int msglev,
57
+	const int warnlev,
58
+	const char * const provider,
59
+	const char * const slot,
60
+	const char * const pin
61
+);
62
+
63
+#endif
0 64
new file mode 100644
... ...
@@ -0,0 +1,299 @@
0
+/* pkcs11.h include file for PKCS #11. */
1
+/* $Revision: 1.4 $ */
2
+
3
+/* License to copy and use this software is granted provided that it is
4
+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
5
+ * (Cryptoki)" in all material mentioning or referencing this software.
6
+
7
+ * License is also granted to make and use derivative works provided that
8
+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
9
+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or 
10
+ * referencing the derived work.
11
+
12
+ * RSA Security Inc. makes no representations concerning either the 
13
+ * merchantability of this software or the suitability of this software for
14
+ * any particular purpose. It is provided "as is" without express or implied
15
+ * warranty of any kind.
16
+ */
17
+
18
+#ifndef _PKCS11_H_
19
+#define _PKCS11_H_ 1
20
+
21
+#ifdef __cplusplus
22
+extern "C" {
23
+#endif
24
+
25
+/* Before including this file (pkcs11.h) (or pkcs11t.h by
26
+ * itself), 6 platform-specific macros must be defined.  These
27
+ * macros are described below, and typical definitions for them
28
+ * are also given.  Be advised that these definitions can depend
29
+ * on both the platform and the compiler used (and possibly also
30
+ * on whether a Cryptoki library is linked statically or
31
+ * dynamically).
32
+ *
33
+ * In addition to defining these 6 macros, the packing convention
34
+ * for Cryptoki structures should be set.  The Cryptoki
35
+ * convention on packing is that structures should be 1-byte
36
+ * aligned.
37
+ *
38
+ * If you're using Microsoft Developer Studio 5.0 to produce
39
+ * Win32 stuff, this might be done by using the following
40
+ * preprocessor directive before including pkcs11.h or pkcs11t.h:
41
+ *
42
+ * #pragma pack(push, cryptoki, 1)
43
+ *
44
+ * and using the following preprocessor directive after including
45
+ * pkcs11.h or pkcs11t.h:
46
+ *
47
+ * #pragma pack(pop, cryptoki)
48
+ *
49
+ * If you're using an earlier version of Microsoft Developer
50
+ * Studio to produce Win16 stuff, this might be done by using
51
+ * the following preprocessor directive before including
52
+ * pkcs11.h or pkcs11t.h:
53
+ *
54
+ * #pragma pack(1)
55
+ *
56
+ * In a UNIX environment, you're on your own for this.  You might
57
+ * not need to do (or be able to do!) anything.
58
+ *
59
+ *
60
+ * Now for the macros:
61
+ *
62
+ *
63
+ * 1. CK_PTR: The indirection string for making a pointer to an
64
+ * object.  It can be used like this:
65
+ *
66
+ * typedef CK_BYTE CK_PTR CK_BYTE_PTR;
67
+ *
68
+ * If you're using Microsoft Developer Studio 5.0 to produce
69
+ * Win32 stuff, it might be defined by:
70
+ *
71
+ * #define CK_PTR *
72
+ *
73
+ * If you're using an earlier version of Microsoft Developer
74
+ * Studio to produce Win16 stuff, it might be defined by:
75
+ *
76
+ * #define CK_PTR far *
77
+ *
78
+ * In a typical UNIX environment, it might be defined by:
79
+ *
80
+ * #define CK_PTR *
81
+ *
82
+ *
83
+ * 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes
84
+ * an exportable Cryptoki library function definition out of a
85
+ * return type and a function name.  It should be used in the
86
+ * following fashion to define the exposed Cryptoki functions in
87
+ * a Cryptoki library:
88
+ *
89
+ * CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
90
+ *   CK_VOID_PTR pReserved
91
+ * )
92
+ * {
93
+ *   ...
94
+ * }
95
+ *
96
+ * If you're using Microsoft Developer Studio 5.0 to define a
97
+ * function in a Win32 Cryptoki .dll, it might be defined by:
98
+ *
99
+ * #define CK_DEFINE_FUNCTION(returnType, name) \
100
+ *   returnType __declspec(dllexport) name
101
+ *
102
+ * If you're using an earlier version of Microsoft Developer
103
+ * Studio to define a function in a Win16 Cryptoki .dll, it
104
+ * might be defined by:
105
+ *
106
+ * #define CK_DEFINE_FUNCTION(returnType, name) \
107
+ *   returnType __export _far _pascal name
108
+ *
109
+ * In a UNIX environment, it might be defined by:
110
+ *
111
+ * #define CK_DEFINE_FUNCTION(returnType, name) \
112
+ *   returnType name
113
+ *
114
+ *
115
+ * 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
116
+ * an importable Cryptoki library function declaration out of a
117
+ * return type and a function name.  It should be used in the
118
+ * following fashion:
119
+ *
120
+ * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
121
+ *   CK_VOID_PTR pReserved
122
+ * );
123
+ *
124
+ * If you're using Microsoft Developer Studio 5.0 to declare a
125
+ * function in a Win32 Cryptoki .dll, it might be defined by:
126
+ *
127
+ * #define CK_DECLARE_FUNCTION(returnType, name) \
128
+ *   returnType __declspec(dllimport) name
129
+ *
130
+ * If you're using an earlier version of Microsoft Developer
131
+ * Studio to declare a function in a Win16 Cryptoki .dll, it
132
+ * might be defined by:
133
+ *
134
+ * #define CK_DECLARE_FUNCTION(returnType, name) \
135
+ *   returnType __export _far _pascal name
136
+ *
137
+ * In a UNIX environment, it might be defined by:
138
+ *
139
+ * #define CK_DECLARE_FUNCTION(returnType, name) \
140
+ *   returnType name
141
+ *
142
+ *
143
+ * 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
144
+ * which makes a Cryptoki API function pointer declaration or
145
+ * function pointer type declaration out of a return type and a
146
+ * function name.  It should be used in the following fashion:
147
+ *
148
+ * // Define funcPtr to be a pointer to a Cryptoki API function
149
+ * // taking arguments args and returning CK_RV.
150
+ * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
151
+ *
152
+ * or
153
+ *
154
+ * // Define funcPtrType to be the type of a pointer to a
155
+ * // Cryptoki API function taking arguments args and returning
156
+ * // CK_RV, and then define funcPtr to be a variable of type
157
+ * // funcPtrType.
158
+ * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
159
+ * funcPtrType funcPtr;
160
+ *
161
+ * If you're using Microsoft Developer Studio 5.0 to access
162
+ * functions in a Win32 Cryptoki .dll, in might be defined by:
163
+ *
164
+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
165
+ *   returnType __declspec(dllimport) (* name)
166
+ *
167
+ * If you're using an earlier version of Microsoft Developer
168
+ * Studio to access functions in a Win16 Cryptoki .dll, it might
169
+ * be defined by:
170
+ *
171
+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
172
+ *   returnType __export _far _pascal (* name)
173
+ *
174
+ * In a UNIX environment, it might be defined by:
175
+ *
176
+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
177
+ *   returnType (* name)
178
+ *
179
+ *
180
+ * 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
181
+ * a function pointer type for an application callback out of
182
+ * a return type for the callback and a name for the callback.
183
+ * It should be used in the following fashion:
184
+ *
185
+ * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
186
+ *
187
+ * to declare a function pointer, myCallback, to a callback
188
+ * which takes arguments args and returns a CK_RV.  It can also
189
+ * be used like this:
190
+ *
191
+ * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
192
+ * myCallbackType myCallback;
193
+ *
194
+ * If you're using Microsoft Developer Studio 5.0 to do Win32
195
+ * Cryptoki development, it might be defined by:
196
+ *
197
+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
198
+ *   returnType (* name)
199
+ *
200
+ * If you're using an earlier version of Microsoft Developer
201
+ * Studio to do Win16 development, it might be defined by:
202
+ *
203
+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
204
+ *   returnType _far _pascal (* name)
205
+ *
206
+ * In a UNIX environment, it might be defined by:
207
+ *
208
+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
209
+ *   returnType (* name)
210
+ *
211
+ *
212
+ * 6. NULL_PTR: This macro is the value of a NULL pointer.
213
+ *
214
+ * In any ANSI/ISO C environment (and in many others as well),
215
+ * this should best be defined by
216
+ *
217
+ * #ifndef NULL_PTR
218
+ * #define NULL_PTR 0
219
+ * #endif
220
+ */
221
+
222
+
223
+/* All the various Cryptoki types and #define'd values are in the
224
+ * file pkcs11t.h. */
225
+#include "pkcs11t.h"
226
+
227
+#define __PASTE(x,y)      x##y
228
+
229
+
230
+/* ==============================================================
231
+ * Define the "extern" form of all the entry points.
232
+ * ==============================================================
233
+ */
234
+
235
+#define CK_NEED_ARG_LIST  1
236
+#define CK_PKCS11_FUNCTION_INFO(name) \
237
+  extern CK_DECLARE_FUNCTION(CK_RV, name)
238
+
239
+/* pkcs11f.h has all the information about the Cryptoki
240
+ * function prototypes. */
241
+#include "pkcs11f.h"
242
+
243
+#undef CK_NEED_ARG_LIST
244
+#undef CK_PKCS11_FUNCTION_INFO
245
+
246
+
247
+/* ==============================================================
248
+ * Define the typedef form of all the entry points.  That is, for
249
+ * each Cryptoki function C_XXX, define a type CK_C_XXX which is
250
+ * a pointer to that kind of function.
251
+ * ==============================================================
252
+ */
253
+
254
+#define CK_NEED_ARG_LIST  1
255
+#define CK_PKCS11_FUNCTION_INFO(name) \
256
+  typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
257
+
258
+/* pkcs11f.h has all the information about the Cryptoki
259
+ * function prototypes. */
260
+#include "pkcs11f.h"
261
+
262
+#undef CK_NEED_ARG_LIST
263
+#undef CK_PKCS11_FUNCTION_INFO
264
+
265
+
266
+/* ==============================================================
267
+ * Define structed vector of entry points.  A CK_FUNCTION_LIST
268
+ * contains a CK_VERSION indicating a library's Cryptoki version
269
+ * and then a whole slew of function pointers to the routines in
270
+ * the library.  This type was declared, but not defined, in
271
+ * pkcs11t.h.
272
+ * ==============================================================
273
+ */
274
+
275
+#define CK_PKCS11_FUNCTION_INFO(name) \
276
+  __PASTE(CK_,name) name;
277
+  
278
+struct CK_FUNCTION_LIST {
279
+
280
+  CK_VERSION    version;  /* Cryptoki version */
281
+
282
+/* Pile all the function pointers into the CK_FUNCTION_LIST. */
283
+/* pkcs11f.h has all the information about the Cryptoki
284
+ * function prototypes. */
285
+#include "pkcs11f.h"
286
+
287
+};
288
+
289
+#undef CK_PKCS11_FUNCTION_INFO
290
+
291
+
292
+#undef __PASTE
293
+
294
+#ifdef __cplusplus
295
+}
296
+#endif
297
+
298
+#endif
0 299
new file mode 100644
... ...
@@ -0,0 +1,912 @@
0
+/* pkcs11f.h include file for PKCS #11. */
1
+/* $Revision: 1.4 $ */
2
+
3
+/* License to copy and use this software is granted provided that it is
4
+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
5
+ * (Cryptoki)" in all material mentioning or referencing this software.
6
+
7
+ * License is also granted to make and use derivative works provided that
8
+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
9
+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or 
10
+ * referencing the derived work.
11
+
12
+ * RSA Security Inc. makes no representations concerning either the 
13
+ * merchantability of this software or the suitability of this software for
14
+ * any particular purpose. It is provided "as is" without express or implied
15
+ * warranty of any kind.
16
+ */
17
+
18
+/* This header file contains pretty much everything about all the */
19
+/* Cryptoki function prototypes.  Because this information is */
20
+/* used for more than just declaring function prototypes, the */
21
+/* order of the functions appearing herein is important, and */
22
+/* should not be altered. */
23
+
24
+/* General-purpose */
25
+
26
+/* C_Initialize initializes the Cryptoki library. */
27
+CK_PKCS11_FUNCTION_INFO(C_Initialize)
28
+#ifdef CK_NEED_ARG_LIST
29
+(
30
+  CK_VOID_PTR   pInitArgs  /* if this is not NULL_PTR, it gets
31
+                            * cast to CK_C_INITIALIZE_ARGS_PTR
32
+                            * and dereferenced */
33
+);
34
+#endif
35
+
36
+
37
+/* C_Finalize indicates that an application is done with the
38
+ * Cryptoki library. */
39
+CK_PKCS11_FUNCTION_INFO(C_Finalize)
40
+#ifdef CK_NEED_ARG_LIST
41
+(
42
+  CK_VOID_PTR   pReserved  /* reserved.  Should be NULL_PTR */
43
+);
44
+#endif
45
+
46
+
47
+/* C_GetInfo returns general information about Cryptoki. */
48
+CK_PKCS11_FUNCTION_INFO(C_GetInfo)
49
+#ifdef CK_NEED_ARG_LIST
50
+(
51
+  CK_INFO_PTR   pInfo  /* location that receives information */
52
+);
53
+#endif
54
+
55
+
56
+/* C_GetFunctionList returns the function list. */
57
+CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
58
+#ifdef CK_NEED_ARG_LIST
59
+(
60
+  CK_FUNCTION_LIST_PTR_PTR ppFunctionList  /* receives pointer to
61
+                                            * function list */
62
+);
63
+#endif
64
+
65
+
66
+
67
+/* Slot and token management */
68
+
69
+/* C_GetSlotList obtains a list of slots in the system. */
70
+CK_PKCS11_FUNCTION_INFO(C_GetSlotList)
71
+#ifdef CK_NEED_ARG_LIST
72
+(
73
+  CK_BBOOL       tokenPresent,  /* only slots with tokens? */
74
+  CK_SLOT_ID_PTR pSlotList,     /* receives array of slot IDs */
75
+  CK_ULONG_PTR   pulCount       /* receives number of slots */
76
+);
77
+#endif
78
+
79
+
80
+/* C_GetSlotInfo obtains information about a particular slot in
81
+ * the system. */
82
+CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
83
+#ifdef CK_NEED_ARG_LIST
84
+(
85
+  CK_SLOT_ID       slotID,  /* the ID of the slot */
86
+  CK_SLOT_INFO_PTR pInfo    /* receives the slot information */
87
+);
88
+#endif
89
+
90
+
91
+/* C_GetTokenInfo obtains information about a particular token
92
+ * in the system. */
93
+CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo)
94
+#ifdef CK_NEED_ARG_LIST
95
+(
96
+  CK_SLOT_ID        slotID,  /* ID of the token's slot */
97
+  CK_TOKEN_INFO_PTR pInfo    /* receives the token information */
98
+);
99
+#endif
100
+
101
+
102
+/* C_GetMechanismList obtains a list of mechanism types
103
+ * supported by a token. */
104
+CK_PKCS11_FUNCTION_INFO(C_GetMechanismList)
105
+#ifdef CK_NEED_ARG_LIST
106
+(
107
+  CK_SLOT_ID            slotID,          /* ID of token's slot */
108
+  CK_MECHANISM_TYPE_PTR pMechanismList,  /* gets mech. array */
109
+  CK_ULONG_PTR          pulCount         /* gets # of mechs. */
110
+);
111
+#endif
112
+
113
+
114
+/* C_GetMechanismInfo obtains information about a particular
115
+ * mechanism possibly supported by a token. */
116
+CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
117
+#ifdef CK_NEED_ARG_LIST
118
+(
119
+  CK_SLOT_ID            slotID,  /* ID of the token's slot */
120
+  CK_MECHANISM_TYPE     type,    /* type of mechanism */
121
+  CK_MECHANISM_INFO_PTR pInfo    /* receives mechanism info */
122
+);
123
+#endif
124
+
125
+
126
+/* C_InitToken initializes a token. */
127
+CK_PKCS11_FUNCTION_INFO(C_InitToken)
128
+#ifdef CK_NEED_ARG_LIST
129
+/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */
130
+(
131
+  CK_SLOT_ID      slotID,    /* ID of the token's slot */
132
+  CK_UTF8CHAR_PTR pPin,      /* the SO's initial PIN */
133
+  CK_ULONG        ulPinLen,  /* length in bytes of the PIN */
134
+  CK_UTF8CHAR_PTR pLabel     /* 32-byte token label (blank padded) */
135
+);
136
+#endif
137
+
138
+
139
+/* C_InitPIN initializes the normal user's PIN. */
140
+CK_PKCS11_FUNCTION_INFO(C_InitPIN)
141
+#ifdef CK_NEED_ARG_LIST
142
+(
143
+  CK_SESSION_HANDLE hSession,  /* the session's handle */
144
+  CK_UTF8CHAR_PTR   pPin,      /* the normal user's PIN */
145
+  CK_ULONG          ulPinLen   /* length in bytes of the PIN */
146
+);
147
+#endif
148
+
149
+
150
+/* C_SetPIN modifies the PIN of the user who is logged in. */
151
+CK_PKCS11_FUNCTION_INFO(C_SetPIN)
152
+#ifdef CK_NEED_ARG_LIST
153
+(
154
+  CK_SESSION_HANDLE hSession,  /* the session's handle */
155
+  CK_UTF8CHAR_PTR   pOldPin,   /* the old PIN */
156
+  CK_ULONG          ulOldLen,  /* length of the old PIN */
157
+  CK_UTF8CHAR_PTR   pNewPin,   /* the new PIN */
158
+  CK_ULONG          ulNewLen   /* length of the new PIN */
159
+);
160
+#endif
161
+
162
+
163
+
164
+/* Session management */
165
+
166
+/* C_OpenSession opens a session between an application and a
167
+ * token. */
168
+CK_PKCS11_FUNCTION_INFO(C_OpenSession)
169
+#ifdef CK_NEED_ARG_LIST
170
+(
171
+  CK_SLOT_ID            slotID,        /* the slot's ID */
172
+  CK_FLAGS              flags,         /* from CK_SESSION_INFO */
173
+  CK_VOID_PTR           pApplication,  /* passed to callback */
174
+  CK_NOTIFY             Notify,        /* callback function */
175
+  CK_SESSION_HANDLE_PTR phSession      /* gets session handle */
176
+);
177
+#endif
178
+
179
+
180
+/* C_CloseSession closes a session between an application and a
181
+ * token. */
182
+CK_PKCS11_FUNCTION_INFO(C_CloseSession)
183
+#ifdef CK_NEED_ARG_LIST
184
+(
185
+  CK_SESSION_HANDLE hSession  /* the session's handle */
186
+);
187
+#endif
188
+
189
+
190
+/* C_CloseAllSessions closes all sessions with a token. */
191
+CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions)
192
+#ifdef CK_NEED_ARG_LIST
193
+(
194
+  CK_SLOT_ID     slotID  /* the token's slot */
195
+);
196
+#endif
197
+
198
+
199
+/* C_GetSessionInfo obtains information about the session. */
200
+CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo)
201
+#ifdef CK_NEED_ARG_LIST
202
+(
203
+  CK_SESSION_HANDLE   hSession,  /* the session's handle */
204
+  CK_SESSION_INFO_PTR pInfo      /* receives session info */
205
+);
206
+#endif
207
+
208
+
209
+/* C_GetOperationState obtains the state of the cryptographic operation
210
+ * in a session. */
211
+CK_PKCS11_FUNCTION_INFO(C_GetOperationState)
212
+#ifdef CK_NEED_ARG_LIST
213
+(
214
+  CK_SESSION_HANDLE hSession,             /* session's handle */
215
+  CK_BYTE_PTR       pOperationState,      /* gets state */
216
+  CK_ULONG_PTR      pulOperationStateLen  /* gets state length */
217
+);
218
+#endif
219
+
220
+
221
+/* C_SetOperationState restores the state of the cryptographic
222
+ * operation in a session. */
223
+CK_PKCS11_FUNCTION_INFO(C_SetOperationState)
224
+#ifdef CK_NEED_ARG_LIST
225
+(
226
+  CK_SESSION_HANDLE hSession,            /* session's handle */
227
+  CK_BYTE_PTR      pOperationState,      /* holds state */
228
+  CK_ULONG         ulOperationStateLen,  /* holds state length */
229
+  CK_OBJECT_HANDLE hEncryptionKey,       /* en/decryption key */
230
+  CK_OBJECT_HANDLE hAuthenticationKey    /* sign/verify key */
231
+);
232
+#endif
233
+
234
+
235
+/* C_Login logs a user into a token. */
236
+CK_PKCS11_FUNCTION_INFO(C_Login)
237
+#ifdef CK_NEED_ARG_LIST
238
+(
239
+  CK_SESSION_HANDLE hSession,  /* the session's handle */
240
+  CK_USER_TYPE      userType,  /* the user type */
241
+  CK_UTF8CHAR_PTR   pPin,      /* the user's PIN */
242
+  CK_ULONG          ulPinLen   /* the length of the PIN */
243
+);
244
+#endif
245
+
246
+
247
+/* C_Logout logs a user out from a token. */
248
+CK_PKCS11_FUNCTION_INFO(C_Logout)
249
+#ifdef CK_NEED_ARG_LIST
250
+(
251
+  CK_SESSION_HANDLE hSession  /* the session's handle */
252
+);
253
+#endif
254
+
255
+
256
+
257
+/* Object management */
258
+
259
+/* C_CreateObject creates a new object. */
260
+CK_PKCS11_FUNCTION_INFO(C_CreateObject)
261
+#ifdef CK_NEED_ARG_LIST
262
+(
263
+  CK_SESSION_HANDLE hSession,    /* the session's handle */
264
+  CK_ATTRIBUTE_PTR  pTemplate,   /* the object's template */
265
+  CK_ULONG          ulCount,     /* attributes in template */
266
+  CK_OBJECT_HANDLE_PTR phObject  /* gets new object's handle. */
267
+);
268
+#endif
269
+
270
+
271
+/* C_CopyObject copies an object, creating a new object for the
272
+ * copy. */
273
+CK_PKCS11_FUNCTION_INFO(C_CopyObject)
274
+#ifdef CK_NEED_ARG_LIST
275
+(
276
+  CK_SESSION_HANDLE    hSession,    /* the session's handle */
277
+  CK_OBJECT_HANDLE     hObject,     /* the object's handle */
278
+  CK_ATTRIBUTE_PTR     pTemplate,   /* template for new object */
279
+  CK_ULONG             ulCount,     /* attributes in template */
280
+  CK_OBJECT_HANDLE_PTR phNewObject  /* receives handle of copy */
281
+);
282
+#endif
283
+
284
+
285
+/* C_DestroyObject destroys an object. */
286
+CK_PKCS11_FUNCTION_INFO(C_DestroyObject)
287
+#ifdef CK_NEED_ARG_LIST
288
+(
289
+  CK_SESSION_HANDLE hSession,  /* the session's handle */
290
+  CK_OBJECT_HANDLE  hObject    /* the object's handle */
291
+);
292
+#endif
293
+
294
+
295
+/* C_GetObjectSize gets the size of an object in bytes. */
296
+CK_PKCS11_FUNCTION_INFO(C_GetObjectSize)
297
+#ifdef CK_NEED_ARG_LIST
298
+(
299
+  CK_SESSION_HANDLE hSession,  /* the session's handle */
300
+  CK_OBJECT_HANDLE  hObject,   /* the object's handle */
301
+  CK_ULONG_PTR      pulSize    /* receives size of object */
302
+);
303
+#endif
304
+
305
+
306
+/* C_GetAttributeValue obtains the value of one or more object
307
+ * attributes. */
308
+CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
309
+#ifdef CK_NEED_ARG_LIST
310
+(
311
+  CK_SESSION_HANDLE hSession,   /* the session's handle */
312
+  CK_OBJECT_HANDLE  hObject,    /* the object's handle */
313
+  CK_ATTRIBUTE_PTR  pTemplate,  /* specifies attrs; gets vals */
314
+  CK_ULONG          ulCount     /* attributes in template */
315
+);
316
+#endif
317
+
318
+
319
+/* C_SetAttributeValue modifies the value of one or more object
320
+ * attributes */
321
+CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue)
322
+#ifdef CK_NEED_ARG_LIST
323
+(
324
+  CK_SESSION_HANDLE hSession,   /* the session's handle */
325
+  CK_OBJECT_HANDLE  hObject,    /* the object's handle */
326
+  CK_ATTRIBUTE_PTR  pTemplate,  /* specifies attrs and values */
327
+  CK_ULONG          ulCount     /* attributes in template */
328
+);
329
+#endif
330
+
331
+
332
+/* C_FindObjectsInit initializes a search for token and session
333
+ * objects that match a template. */
334
+CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit)
335
+#ifdef CK_NEED_ARG_LIST
336
+(
337
+  CK_SESSION_HANDLE hSession,   /* the session's handle */
338
+  CK_ATTRIBUTE_PTR  pTemplate,  /* attribute values to match */
339
+  CK_ULONG          ulCount     /* attrs in search template */
340
+);
341
+#endif
342
+
343
+
344
+/* C_FindObjects continues a search for token and session
345
+ * objects that match a template, obtaining additional object
346
+ * handles. */
347
+CK_PKCS11_FUNCTION_INFO(C_FindObjects)
348
+#ifdef CK_NEED_ARG_LIST
349
+(
350
+ CK_SESSION_HANDLE    hSession,          /* session's handle */
351
+ CK_OBJECT_HANDLE_PTR phObject,          /* gets obj. handles */
352
+ CK_ULONG             ulMaxObjectCount,  /* max handles to get */
353
+ CK_ULONG_PTR         pulObjectCount     /* actual # returned */
354
+);
355
+#endif
356
+
357
+
358
+/* C_FindObjectsFinal finishes a search for token and session
359
+ * objects. */
360
+CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal)
361
+#ifdef CK_NEED_ARG_LIST
362
+(
363
+  CK_SESSION_HANDLE hSession  /* the session's handle */
364
+);
365
+#endif
366
+
367
+
368
+
369
+/* Encryption and decryption */
370
+
371
+/* C_EncryptInit initializes an encryption operation. */
372
+CK_PKCS11_FUNCTION_INFO(C_EncryptInit)
373
+#ifdef CK_NEED_ARG_LIST
374
+(
375
+  CK_SESSION_HANDLE hSession,    /* the session's handle */
376
+  CK_MECHANISM_PTR  pMechanism,  /* the encryption mechanism */
377
+  CK_OBJECT_HANDLE  hKey         /* handle of encryption key */
378
+);
379
+#endif
380
+
381
+
382
+/* C_Encrypt encrypts single-part data. */
383
+CK_PKCS11_FUNCTION_INFO(C_Encrypt)
384
+#ifdef CK_NEED_ARG_LIST
385
+(
386
+  CK_SESSION_HANDLE hSession,            /* session's handle */
387
+  CK_BYTE_PTR       pData,               /* the plaintext data */
388
+  CK_ULONG          ulDataLen,           /* bytes of plaintext */
389
+  CK_BYTE_PTR       pEncryptedData,      /* gets ciphertext */
390
+  CK_ULONG_PTR      pulEncryptedDataLen  /* gets c-text size */
391
+);
392
+#endif
393
+
394
+
395
+/* C_EncryptUpdate continues a multiple-part encryption
396
+ * operation. */
397
+CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate)
398
+#ifdef CK_NEED_ARG_LIST
399
+(
400
+  CK_SESSION_HANDLE hSession,           /* session's handle */
401
+  CK_BYTE_PTR       pPart,              /* the plaintext data */
402
+  CK_ULONG          ulPartLen,          /* plaintext data len */
403
+  CK_BYTE_PTR       pEncryptedPart,     /* gets ciphertext */
404
+  CK_ULONG_PTR      pulEncryptedPartLen /* gets c-text size */
405
+);
406
+#endif
407
+
408
+
409
+/* C_EncryptFinal finishes a multiple-part encryption
410
+ * operation. */
411
+CK_PKCS11_FUNCTION_INFO(C_EncryptFinal)
412
+#ifdef CK_NEED_ARG_LIST
413
+(
414
+  CK_SESSION_HANDLE hSession,                /* session handle */
415
+  CK_BYTE_PTR       pLastEncryptedPart,      /* last c-text */
416
+  CK_ULONG_PTR      pulLastEncryptedPartLen  /* gets last size */
417
+);
418
+#endif
419
+
420
+
421
+/* C_DecryptInit initializes a decryption operation. */
422
+CK_PKCS11_FUNCTION_INFO(C_DecryptInit)
423
+#ifdef CK_NEED_ARG_LIST
424
+(
425
+  CK_SESSION_HANDLE hSession,    /* the session's handle */
426
+  CK_MECHANISM_PTR  pMechanism,  /* the decryption mechanism */
427
+  CK_OBJECT_HANDLE  hKey         /* handle of decryption key */
428
+);
429
+#endif
430
+
431
+
432
+/* C_Decrypt decrypts encrypted data in a single part. */
433
+CK_PKCS11_FUNCTION_INFO(C_Decrypt)
434
+#ifdef CK_NEED_ARG_LIST
435
+(
436
+  CK_SESSION_HANDLE hSession,           /* session's handle */
437
+  CK_BYTE_PTR       pEncryptedData,     /* ciphertext */
438
+  CK_ULONG          ulEncryptedDataLen, /* ciphertext length */
439
+  CK_BYTE_PTR       pData,              /* gets plaintext */
440
+  CK_ULONG_PTR      pulDataLen          /* gets p-text size */
441
+);
442
+#endif
443
+
444
+
445
+/* C_DecryptUpdate continues a multiple-part decryption
446
+ * operation. */
447
+CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate)
448
+#ifdef CK_NEED_ARG_LIST
449
+(
450
+  CK_SESSION_HANDLE hSession,            /* session's handle */
451
+  CK_BYTE_PTR       pEncryptedPart,      /* encrypted data */
452
+  CK_ULONG          ulEncryptedPartLen,  /* input length */
453
+  CK_BYTE_PTR       pPart,               /* gets plaintext */
454
+  CK_ULONG_PTR      pulPartLen           /* p-text size */
455
+);
456
+#endif
457
+
458
+
459
+/* C_DecryptFinal finishes a multiple-part decryption
460
+ * operation. */
461
+CK_PKCS11_FUNCTION_INFO(C_DecryptFinal)
462
+#ifdef CK_NEED_ARG_LIST
463
+(
464
+  CK_SESSION_HANDLE hSession,       /* the session's handle */
465
+  CK_BYTE_PTR       pLastPart,      /* gets plaintext */
466
+  CK_ULONG_PTR      pulLastPartLen  /* p-text size */
467
+);
468
+#endif
469
+
470
+
471
+
472
+/* Message digesting */
473
+
474
+/* C_DigestInit initializes a message-digesting operation. */
475
+CK_PKCS11_FUNCTION_INFO(C_DigestInit)
476
+#ifdef CK_NEED_ARG_LIST
477
+(
478
+  CK_SESSION_HANDLE hSession,   /* the session's handle */
479
+  CK_MECHANISM_PTR  pMechanism  /* the digesting mechanism */
480
+);
481
+#endif
482
+
483
+
484
+/* C_Digest digests data in a single part. */
485
+CK_PKCS11_FUNCTION_INFO(C_Digest)
486
+#ifdef CK_NEED_ARG_LIST
487
+(
488
+  CK_SESSION_HANDLE hSession,     /* the session's handle */
489
+  CK_BYTE_PTR       pData,        /* data to be digested */
490
+  CK_ULONG          ulDataLen,    /* bytes of data to digest */
491
+  CK_BYTE_PTR       pDigest,      /* gets the message digest */
492
+  CK_ULONG_PTR      pulDigestLen  /* gets digest length */
493
+);
494
+#endif
495
+
496
+
497
+/* C_DigestUpdate continues a multiple-part message-digesting
498
+ * operation. */
499
+CK_PKCS11_FUNCTION_INFO(C_DigestUpdate)
500
+#ifdef CK_NEED_ARG_LIST
501
+(
502
+  CK_SESSION_HANDLE hSession,  /* the session's handle */
503
+  CK_BYTE_PTR       pPart,     /* data to be digested */
504
+  CK_ULONG          ulPartLen  /* bytes of data to be digested */
505
+);
506
+#endif
507
+
508
+
509
+/* C_DigestKey continues a multi-part message-digesting
510
+ * operation, by digesting the value of a secret key as part of
511
+ * the data already digested. */
512
+CK_PKCS11_FUNCTION_INFO(C_DigestKey)
513
+#ifdef CK_NEED_ARG_LIST
514
+(
515
+  CK_SESSION_HANDLE hSession,  /* the session's handle */
516
+  CK_OBJECT_HANDLE  hKey       /* secret key to digest */
517
+);
518
+#endif
519
+
520
+
521
+/* C_DigestFinal finishes a multiple-part message-digesting
522
+ * operation. */
523
+CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
524
+#ifdef CK_NEED_ARG_LIST
525
+(
526
+  CK_SESSION_HANDLE hSession,     /* the session's handle */
527
+  CK_BYTE_PTR       pDigest,      /* gets the message digest */
528
+  CK_ULONG_PTR      pulDigestLen  /* gets byte count of digest */
529
+);
530
+#endif
531
+
532
+
533
+
534
+/* Signing and MACing */
535
+
536
+/* C_SignInit initializes a signature (private key encryption)
537
+ * operation, where the signature is (will be) an appendix to
538
+ * the data, and plaintext cannot be recovered from the
539
+ *signature. */
540
+CK_PKCS11_FUNCTION_INFO(C_SignInit)
541
+#ifdef CK_NEED_ARG_LIST
542
+(
543
+  CK_SESSION_HANDLE hSession,    /* the session's handle */
544
+  CK_MECHANISM_PTR  pMechanism,  /* the signature mechanism */
545
+  CK_OBJECT_HANDLE  hKey         /* handle of signature key */
546
+);
547
+#endif
548
+
549
+
550
+/* C_Sign signs (encrypts with private key) data in a single
551
+ * part, where the signature is (will be) an appendix to the
552
+ * data, and plaintext cannot be recovered from the signature. */
553
+CK_PKCS11_FUNCTION_INFO(C_Sign)
554
+#ifdef CK_NEED_ARG_LIST
555
+(
556
+  CK_SESSION_HANDLE hSession,        /* the session's handle */
557
+  CK_BYTE_PTR       pData,           /* the data to sign */
558
+  CK_ULONG          ulDataLen,       /* count of bytes to sign */
559
+  CK_BYTE_PTR       pSignature,      /* gets the signature */
560
+  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
561
+);
562
+#endif
563
+
564
+
565
+/* C_SignUpdate continues a multiple-part signature operation,
566
+ * where the signature is (will be) an appendix to the data, 
567
+ * and plaintext cannot be recovered from the signature. */
568
+CK_PKCS11_FUNCTION_INFO(C_SignUpdate)
569
+#ifdef CK_NEED_ARG_LIST
570
+(
571
+  CK_SESSION_HANDLE hSession,  /* the session's handle */
572
+  CK_BYTE_PTR       pPart,     /* the data to sign */
573
+  CK_ULONG          ulPartLen  /* count of bytes to sign */
574
+);
575
+#endif
576
+
577
+
578
+/* C_SignFinal finishes a multiple-part signature operation, 
579
+ * returning the signature. */
580
+CK_PKCS11_FUNCTION_INFO(C_SignFinal)
581
+#ifdef CK_NEED_ARG_LIST
582
+(
583
+  CK_SESSION_HANDLE hSession,        /* the session's handle */
584
+  CK_BYTE_PTR       pSignature,      /* gets the signature */
585
+  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
586
+);
587
+#endif
588
+
589
+
590
+/* C_SignRecoverInit initializes a signature operation, where
591
+ * the data can be recovered from the signature. */
592
+CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit)
593
+#ifdef CK_NEED_ARG_LIST
594
+(
595
+  CK_SESSION_HANDLE hSession,   /* the session's handle */
596
+  CK_MECHANISM_PTR  pMechanism, /* the signature mechanism */
597
+  CK_OBJECT_HANDLE  hKey        /* handle of the signature key */
598
+);
599
+#endif
600
+
601
+
602
+/* C_SignRecover signs data in a single operation, where the
603
+ * data can be recovered from the signature. */
604
+CK_PKCS11_FUNCTION_INFO(C_SignRecover)
605
+#ifdef CK_NEED_ARG_LIST
606
+(
607
+  CK_SESSION_HANDLE hSession,        /* the session's handle */
608
+  CK_BYTE_PTR       pData,           /* the data to sign */
609
+  CK_ULONG          ulDataLen,       /* count of bytes to sign */
610
+  CK_BYTE_PTR       pSignature,      /* gets the signature */
611
+  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
612
+);
613
+#endif
614
+
615
+
616
+
617
+/* Verifying signatures and MACs */
618
+
619
+/* C_VerifyInit initializes a verification operation, where the
620
+ * signature is an appendix to the data, and plaintext cannot
621
+ *  cannot be recovered from the signature (e.g. DSA). */
622
+CK_PKCS11_FUNCTION_INFO(C_VerifyInit)
623
+#ifdef CK_NEED_ARG_LIST
624
+(
625
+  CK_SESSION_HANDLE hSession,    /* the session's handle */
626
+  CK_MECHANISM_PTR  pMechanism,  /* the verification mechanism */
627
+  CK_OBJECT_HANDLE  hKey         /* verification key */ 
628
+);
629
+#endif
630
+
631
+
632
+/* C_Verify verifies a signature in a single-part operation, 
633
+ * where the signature is an appendix to the data, and plaintext
634
+ * cannot be recovered from the signature. */
635
+CK_PKCS11_FUNCTION_INFO(C_Verify)
636
+#ifdef CK_NEED_ARG_LIST
637
+(
638
+  CK_SESSION_HANDLE hSession,       /* the session's handle */
639
+  CK_BYTE_PTR       pData,          /* signed data */
640
+  CK_ULONG          ulDataLen,      /* length of signed data */
641
+  CK_BYTE_PTR       pSignature,     /* signature */
642
+  CK_ULONG          ulSignatureLen  /* signature length*/
643
+);
644
+#endif
645
+
646
+
647
+/* C_VerifyUpdate continues a multiple-part verification
648
+ * operation, where the signature is an appendix to the data, 
649
+ * and plaintext cannot be recovered from the signature. */
650
+CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate)
651
+#ifdef CK_NEED_ARG_LIST
652
+(
653
+  CK_SESSION_HANDLE hSession,  /* the session's handle */
654
+  CK_BYTE_PTR       pPart,     /* signed data */
655
+  CK_ULONG          ulPartLen  /* length of signed data */
656
+);
657
+#endif
658
+
659
+
660
+/* C_VerifyFinal finishes a multiple-part verification
661
+ * operation, checking the signature. */
662
+CK_PKCS11_FUNCTION_INFO(C_VerifyFinal)
663
+#ifdef CK_NEED_ARG_LIST
664
+(
665
+  CK_SESSION_HANDLE hSession,       /* the session's handle */
666
+  CK_BYTE_PTR       pSignature,     /* signature to verify */
667
+  CK_ULONG          ulSignatureLen  /* signature length */
668
+);
669
+#endif
670
+
671
+
672
+/* C_VerifyRecoverInit initializes a signature verification
673
+ * operation, where the data is recovered from the signature. */
674
+CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit)
675
+#ifdef CK_NEED_ARG_LIST
676
+(
677
+  CK_SESSION_HANDLE hSession,    /* the session's handle */
678
+  CK_MECHANISM_PTR  pMechanism,  /* the verification mechanism */
679
+  CK_OBJECT_HANDLE  hKey         /* verification key */
680
+);
681
+#endif
682
+
683
+
684
+/* C_VerifyRecover verifies a signature in a single-part
685
+ * operation, where the data is recovered from the signature. */
686
+CK_PKCS11_FUNCTION_INFO(C_VerifyRecover)
687
+#ifdef CK_NEED_ARG_LIST
688
+(
689
+  CK_SESSION_HANDLE hSession,        /* the session's handle */
690
+  CK_BYTE_PTR       pSignature,      /* signature to verify */
691
+  CK_ULONG          ulSignatureLen,  /* signature length */
692
+  CK_BYTE_PTR       pData,           /* gets signed data */
693
+  CK_ULONG_PTR      pulDataLen       /* gets signed data len */
694
+);
695
+#endif
696
+
697
+
698
+
699
+/* Dual-function cryptographic operations */
700
+
701
+/* C_DigestEncryptUpdate continues a multiple-part digesting
702
+ * and encryption operation. */
703
+CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate)
704
+#ifdef CK_NEED_ARG_LIST
705
+(
706
+  CK_SESSION_HANDLE hSession,            /* session's handle */
707
+  CK_BYTE_PTR       pPart,               /* the plaintext data */
708
+  CK_ULONG          ulPartLen,           /* plaintext length */
709
+  CK_BYTE_PTR       pEncryptedPart,      /* gets ciphertext */
710
+  CK_ULONG_PTR      pulEncryptedPartLen  /* gets c-text length */
711
+);
712
+#endif
713
+
714
+
715
+/* C_DecryptDigestUpdate continues a multiple-part decryption and
716
+ * digesting operation. */
717
+CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate)
718
+#ifdef CK_NEED_ARG_LIST
719
+(
720
+  CK_SESSION_HANDLE hSession,            /* session's handle */
721
+  CK_BYTE_PTR       pEncryptedPart,      /* ciphertext */
722
+  CK_ULONG          ulEncryptedPartLen,  /* ciphertext length */
723
+  CK_BYTE_PTR       pPart,               /* gets plaintext */
724
+  CK_ULONG_PTR      pulPartLen           /* gets plaintext len */
725
+);
726
+#endif
727
+
728
+
729
+/* C_SignEncryptUpdate continues a multiple-part signing and
730
+ * encryption operation. */
731
+CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate)
732
+#ifdef CK_NEED_ARG_LIST
733
+(
734
+  CK_SESSION_HANDLE hSession,            /* session's handle */
735
+  CK_BYTE_PTR       pPart,               /* the plaintext data */
736
+  CK_ULONG          ulPartLen,           /* plaintext length */
737
+  CK_BYTE_PTR       pEncryptedPart,      /* gets ciphertext */
738
+  CK_ULONG_PTR      pulEncryptedPartLen  /* gets c-text length */
739
+);
740
+#endif
741
+
742
+
743
+/* C_DecryptVerifyUpdate continues a multiple-part decryption and
744
+ * verify operation. */
745
+CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate)
746
+#ifdef CK_NEED_ARG_LIST
747
+(
748
+  CK_SESSION_HANDLE hSession,            /* session's handle */
749
+  CK_BYTE_PTR       pEncryptedPart,      /* ciphertext */
750
+  CK_ULONG          ulEncryptedPartLen,  /* ciphertext length */
751
+  CK_BYTE_PTR       pPart,               /* gets plaintext */
752
+  CK_ULONG_PTR      pulPartLen           /* gets p-text length */
753
+);
754
+#endif
755
+
756
+
757
+
758
+/* Key management */
759
+
760
+/* C_GenerateKey generates a secret key, creating a new key
761
+ * object. */
762
+CK_PKCS11_FUNCTION_INFO(C_GenerateKey)
763
+#ifdef CK_NEED_ARG_LIST
764
+(
765
+  CK_SESSION_HANDLE    hSession,    /* the session's handle */
766
+  CK_MECHANISM_PTR     pMechanism,  /* key generation mech. */
767
+  CK_ATTRIBUTE_PTR     pTemplate,   /* template for new key */
768
+  CK_ULONG             ulCount,     /* # of attrs in template */
769
+  CK_OBJECT_HANDLE_PTR phKey        /* gets handle of new key */
770
+);
771
+#endif
772
+
773
+
774
+/* C_GenerateKeyPair generates a public-key/private-key pair, 
775
+ * creating new key objects. */
776
+CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair)
777
+#ifdef CK_NEED_ARG_LIST
778
+(
779
+  CK_SESSION_HANDLE    hSession,                    /* session
780
+                                                     * handle */
781
+  CK_MECHANISM_PTR     pMechanism,                  /* key-gen
782
+                                                     * mech. */
783
+  CK_ATTRIBUTE_PTR     pPublicKeyTemplate,          /* template
784
+                                                     * for pub.
785
+                                                     * key */
786
+  CK_ULONG             ulPublicKeyAttributeCount,   /* # pub.
787
+                                                     * attrs. */
788
+  CK_ATTRIBUTE_PTR     pPrivateKeyTemplate,         /* template
789
+                                                     * for priv.
790
+                                                     * key */
791
+  CK_ULONG             ulPrivateKeyAttributeCount,  /* # priv.
792
+                                                     * attrs. */
793
+  CK_OBJECT_HANDLE_PTR phPublicKey,                 /* gets pub.
794
+                                                     * key
795
+                                                     * handle */
796
+  CK_OBJECT_HANDLE_PTR phPrivateKey                 /* gets
797
+                                                     * priv. key
798
+                                                     * handle */
799
+);
800
+#endif
801
+
802
+
803
+/* C_WrapKey wraps (i.e., encrypts) a key. */
804
+CK_PKCS11_FUNCTION_INFO(C_WrapKey)
805
+#ifdef CK_NEED_ARG_LIST
806
+(
807
+  CK_SESSION_HANDLE hSession,        /* the session's handle */
808
+  CK_MECHANISM_PTR  pMechanism,      /* the wrapping mechanism */
809
+  CK_OBJECT_HANDLE  hWrappingKey,    /* wrapping key */
810
+  CK_OBJECT_HANDLE  hKey,            /* key to be wrapped */
811
+  CK_BYTE_PTR       pWrappedKey,     /* gets wrapped key */
812
+  CK_ULONG_PTR      pulWrappedKeyLen /* gets wrapped key size */
813
+);
814
+#endif
815
+
816
+
817
+/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
818
+ * key object. */
819
+CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
820
+#ifdef CK_NEED_ARG_LIST
821
+(
822
+  CK_SESSION_HANDLE    hSession,          /* session's handle */
823
+  CK_MECHANISM_PTR     pMechanism,        /* unwrapping mech. */
824
+  CK_OBJECT_HANDLE     hUnwrappingKey,    /* unwrapping key */
825
+  CK_BYTE_PTR          pWrappedKey,       /* the wrapped key */
826
+  CK_ULONG             ulWrappedKeyLen,   /* wrapped key len */
827
+  CK_ATTRIBUTE_PTR     pTemplate,         /* new key template */
828
+  CK_ULONG             ulAttributeCount,  /* template length */
829
+  CK_OBJECT_HANDLE_PTR phKey              /* gets new handle */
830
+);
831
+#endif
832
+
833
+
834
+/* C_DeriveKey derives a key from a base key, creating a new key
835
+ * object. */
836
+CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
837
+#ifdef CK_NEED_ARG_LIST
838
+(
839
+  CK_SESSION_HANDLE    hSession,          /* session's handle */
840
+  CK_MECHANISM_PTR     pMechanism,        /* key deriv. mech. */
841
+  CK_OBJECT_HANDLE     hBaseKey,          /* base key */
842
+  CK_ATTRIBUTE_PTR     pTemplate,         /* new key template */
843
+  CK_ULONG             ulAttributeCount,  /* template length */
844
+  CK_OBJECT_HANDLE_PTR phKey              /* gets new handle */
845
+);
846
+#endif
847
+
848
+
849
+
850
+/* Random number generation */
851
+
852
+/* C_SeedRandom mixes additional seed material into the token's
853
+ * random number generator. */
854
+CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
855
+#ifdef CK_NEED_ARG_LIST
856
+(
857
+  CK_SESSION_HANDLE hSession,  /* the session's handle */
858
+  CK_BYTE_PTR       pSeed,     /* the seed material */
859
+  CK_ULONG          ulSeedLen  /* length of seed material */
860
+);
861
+#endif
862
+
863
+
864
+/* C_GenerateRandom generates random data. */
865
+CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
866
+#ifdef CK_NEED_ARG_LIST
867
+(
868
+  CK_SESSION_HANDLE hSession,    /* the session's handle */
869
+  CK_BYTE_PTR       RandomData,  /* receives the random data */
870
+  CK_ULONG          ulRandomLen  /* # of bytes to generate */
871
+);
872
+#endif
873
+
874
+
875
+
876
+/* Parallel function management */
877
+
878
+/* C_GetFunctionStatus is a legacy function; it obtains an
879
+ * updated status of a function running in parallel with an
880
+ * application. */
881
+CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
882
+#ifdef CK_NEED_ARG_LIST
883
+(
884
+  CK_SESSION_HANDLE hSession  /* the session's handle */
885
+);
886
+#endif
887
+
888
+
889
+/* C_CancelFunction is a legacy function; it cancels a function
890
+ * running in parallel. */
891
+CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
892
+#ifdef CK_NEED_ARG_LIST
893
+(
894
+  CK_SESSION_HANDLE hSession  /* the session's handle */
895
+);
896
+#endif
897
+
898
+
899
+
900
+/* Functions added in for Cryptoki Version 2.01 or later */
901
+
902
+/* C_WaitForSlotEvent waits for a slot event (token insertion,
903
+ * removal, etc.) to occur. */
904
+CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
905
+#ifdef CK_NEED_ARG_LIST
906
+(
907
+  CK_FLAGS flags,        /* blocking/nonblocking flag */
908
+  CK_SLOT_ID_PTR pSlot,  /* location that receives the slot ID */
909
+  CK_VOID_PTR pRserved   /* reserved.  Should be NULL_PTR */
910
+);
911
+#endif
0 912
new file mode 100644
... ...
@@ -0,0 +1,1685 @@
0
+/* pkcs11t.h include file for PKCS #11. */
1
+/* $Revision: 1.6 $ */
2
+
3
+/* License to copy and use this software is granted provided that it is
4
+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
5
+ * (Cryptoki)" in all material mentioning or referencing this software.
6
+
7
+ * License is also granted to make and use derivative works provided that
8
+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
9
+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
10
+ * referencing the derived work.
11
+
12
+ * RSA Security Inc. makes no representations concerning either the
13
+ * merchantability of this software or the suitability of this software for
14
+ * any particular purpose. It is provided "as is" without express or implied
15
+ * warranty of any kind.
16
+ */
17
+
18
+/* See top of pkcs11.h for information about the macros that
19
+ * must be defined and the structure-packing conventions that
20
+ * must be set before including this file. */
21
+
22
+#ifndef _PKCS11T_H_
23
+#define _PKCS11T_H_ 1
24
+
25
+#define CK_TRUE 1
26
+#define CK_FALSE 0
27
+
28
+#ifndef CK_DISABLE_TRUE_FALSE
29
+#ifndef FALSE
30
+#define FALSE CK_FALSE
31
+#endif
32
+
33
+#ifndef TRUE
34
+#define TRUE CK_TRUE
35
+#endif
36
+#endif
37
+
38
+/* an unsigned 8-bit value */
39
+typedef unsigned char     CK_BYTE;
40
+
41
+/* an unsigned 8-bit character */
42
+typedef CK_BYTE           CK_CHAR;
43
+
44
+/* an 8-bit UTF-8 character */
45
+typedef CK_BYTE           CK_UTF8CHAR;
46
+
47
+/* a BYTE-sized Boolean flag */
48
+typedef CK_BYTE           CK_BBOOL;
49
+
50
+/* an unsigned value, at least 32 bits long */
51
+typedef unsigned long int CK_ULONG;
52
+
53
+/* a signed value, the same size as a CK_ULONG */
54
+/* CK_LONG is new for v2.0 */
55
+typedef long int          CK_LONG;
56
+
57
+/* at least 32 bits; each bit is a Boolean flag */
58
+typedef CK_ULONG          CK_FLAGS;
59
+
60
+
61
+/* some special values for certain CK_ULONG variables */
62
+#define CK_UNAVAILABLE_INFORMATION (~0UL)
63
+#define CK_EFFECTIVELY_INFINITE    0
64
+
65
+
66
+typedef CK_BYTE     CK_PTR   CK_BYTE_PTR;
67
+typedef CK_CHAR     CK_PTR   CK_CHAR_PTR;
68
+typedef CK_UTF8CHAR CK_PTR   CK_UTF8CHAR_PTR;
69
+typedef CK_ULONG    CK_PTR   CK_ULONG_PTR;
70
+typedef void        CK_PTR   CK_VOID_PTR;
71
+
72
+/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */
73
+typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR;
74
+
75
+
76
+/* The following value is always invalid if used as a session */
77
+/* handle or object handle */
78
+#define CK_INVALID_HANDLE 0
79
+
80
+
81
+typedef struct CK_VERSION {
82
+  CK_BYTE       major;  /* integer portion of version number */
83
+  CK_BYTE       minor;  /* 1/100ths portion of version number */
84
+} CK_VERSION;
85
+
86
+typedef CK_VERSION CK_PTR CK_VERSION_PTR;
87
+
88
+
89
+typedef struct CK_INFO {
90
+  /* manufacturerID and libraryDecription have been changed from
91
+   * CK_CHAR to CK_UTF8CHAR for v2.10 */
92
+  CK_VERSION    cryptokiVersion;     /* Cryptoki interface ver */
93
+  CK_UTF8CHAR   manufacturerID[32];  /* blank padded */
94
+  CK_FLAGS      flags;               /* must be zero */
95
+
96
+  /* libraryDescription and libraryVersion are new for v2.0 */
97
+  CK_UTF8CHAR   libraryDescription[32];  /* blank padded */
98
+  CK_VERSION    libraryVersion;          /* version of library */
99
+} CK_INFO;
100
+
101
+typedef CK_INFO CK_PTR    CK_INFO_PTR;
102
+
103
+
104
+/* CK_NOTIFICATION enumerates the types of notifications that
105
+ * Cryptoki provides to an application */
106
+/* CK_NOTIFICATION has been changed from an enum to a CK_ULONG
107
+ * for v2.0 */
108
+typedef CK_ULONG CK_NOTIFICATION;
109
+#define CKN_SURRENDER       0
110
+
111
+
112
+typedef CK_ULONG          CK_SLOT_ID;
113
+
114
+typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
115
+
116
+
117
+/* CK_SLOT_INFO provides information about a slot */
118
+typedef struct CK_SLOT_INFO {
119
+  /* slotDescription and manufacturerID have been changed from
120
+   * CK_CHAR to CK_UTF8CHAR for v2.10 */
121
+  CK_UTF8CHAR   slotDescription[64];  /* blank padded */
122
+  CK_UTF8CHAR   manufacturerID[32];   /* blank padded */
123
+  CK_FLAGS      flags;
124
+
125
+  /* hardwareVersion and firmwareVersion are new for v2.0 */
126
+  CK_VERSION    hardwareVersion;  /* version of hardware */
127
+  CK_VERSION    firmwareVersion;  /* version of firmware */
128
+} CK_SLOT_INFO;
129
+
130
+/* flags: bit flags that provide capabilities of the slot
131
+ *      Bit Flag              Mask        Meaning
132
+ */
133
+#define CKF_TOKEN_PRESENT     0x00000001  /* a token is there */
134
+#define CKF_REMOVABLE_DEVICE  0x00000002  /* removable devices*/
135
+#define CKF_HW_SLOT           0x00000004  /* hardware slot */
136
+
137
+typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
138
+
139
+
140
+/* CK_TOKEN_INFO provides information about a token */
141
+typedef struct CK_TOKEN_INFO {
142
+  /* label, manufacturerID, and model have been changed from
143
+   * CK_CHAR to CK_UTF8CHAR for v2.10 */
144
+  CK_UTF8CHAR   label[32];           /* blank padded */
145
+  CK_UTF8CHAR   manufacturerID[32];  /* blank padded */
146
+  CK_UTF8CHAR   model[16];           /* blank padded */
147
+  CK_CHAR       serialNumber[16];    /* blank padded */
148
+  CK_FLAGS      flags;               /* see below */
149
+
150
+  /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount,
151
+   * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been
152
+   * changed from CK_USHORT to CK_ULONG for v2.0 */
153
+  CK_ULONG      ulMaxSessionCount;     /* max open sessions */
154
+  CK_ULONG      ulSessionCount;        /* sess. now open */
155
+  CK_ULONG      ulMaxRwSessionCount;   /* max R/W sessions */
156
+  CK_ULONG      ulRwSessionCount;      /* R/W sess. now open */
157
+  CK_ULONG      ulMaxPinLen;           /* in bytes */
158
+  CK_ULONG      ulMinPinLen;           /* in bytes */
159
+  CK_ULONG      ulTotalPublicMemory;   /* in bytes */
160
+  CK_ULONG      ulFreePublicMemory;    /* in bytes */
161
+  CK_ULONG      ulTotalPrivateMemory;  /* in bytes */
162
+  CK_ULONG      ulFreePrivateMemory;   /* in bytes */
163
+
164
+  /* hardwareVersion, firmwareVersion, and time are new for
165
+   * v2.0 */
166
+  CK_VERSION    hardwareVersion;       /* version of hardware */
167
+  CK_VERSION    firmwareVersion;       /* version of firmware */
168
+  CK_CHAR       utcTime[16];           /* time */
169
+} CK_TOKEN_INFO;
170
+
171
+/* The flags parameter is defined as follows:
172
+ *      Bit Flag                    Mask        Meaning
173
+ */
174
+#define CKF_RNG                     0x00000001  /* has random #
175
+                                                 * generator */
176
+#define CKF_WRITE_PROTECTED         0x00000002  /* token is
177
+                                                 * write-
178
+                                                 * protected */
179
+#define CKF_LOGIN_REQUIRED          0x00000004  /* user must
180
+                                                 * login */
181
+#define CKF_USER_PIN_INITIALIZED    0x00000008  /* normal user's
182
+                                                 * PIN is set */
183
+
184
+/* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0.  If it is set,
185
+ * that means that *every* time the state of cryptographic
186
+ * operations of a session is successfully saved, all keys
187
+ * needed to continue those operations are stored in the state */
188
+#define CKF_RESTORE_KEY_NOT_NEEDED  0x00000020
189
+
190
+/* CKF_CLOCK_ON_TOKEN is new for v2.0.  If it is set, that means
191
+ * that the token has some sort of clock.  The time on that
192
+ * clock is returned in the token info structure */
193
+#define CKF_CLOCK_ON_TOKEN          0x00000040
194
+
195
+/* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0.  If it is
196
+ * set, that means that there is some way for the user to login
197
+ * without sending a PIN through the Cryptoki library itself */
198
+#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100
199
+
200
+/* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0.  If it is true,
201
+ * that means that a single session with the token can perform
202
+ * dual simultaneous cryptographic operations (digest and
203
+ * encrypt; decrypt and digest; sign and encrypt; and decrypt
204
+ * and sign) */
205
+#define CKF_DUAL_CRYPTO_OPERATIONS  0x00000200
206
+
207
+/* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the
208
+ * token has been initialized using C_InitializeToken or an
209
+ * equivalent mechanism outside the scope of PKCS #11.
210
+ * Calling C_InitializeToken when this flag is set will cause
211
+ * the token to be reinitialized. */
212
+#define CKF_TOKEN_INITIALIZED       0x00000400
213
+
214
+/* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is
215
+ * true, the token supports secondary authentication for
216
+ * private key objects. This flag is deprecated in v2.11 and
217
+   onwards. */
218
+#define CKF_SECONDARY_AUTHENTICATION  0x00000800
219
+
220
+/* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an
221
+ * incorrect user login PIN has been entered at least once
222
+ * since the last successful authentication. */
223
+#define CKF_USER_PIN_COUNT_LOW       0x00010000
224
+
225
+/* CKF_USER_PIN_FINAL_TRY if new for v2.10. If it is true,
226
+ * supplying an incorrect user PIN will it to become locked. */
227
+#define CKF_USER_PIN_FINAL_TRY       0x00020000
228
+
229
+/* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the
230
+ * user PIN has been locked. User login to the token is not
231
+ * possible. */
232
+#define CKF_USER_PIN_LOCKED          0x00040000
233
+
234
+/* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
235
+ * the user PIN value is the default value set by token
236
+ * initialization or manufacturing, or the PIN has been
237
+ * expired by the card. */
238
+#define CKF_USER_PIN_TO_BE_CHANGED   0x00080000
239
+
240
+/* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an
241
+ * incorrect SO login PIN has been entered at least once since
242
+ * the last successful authentication. */
243
+#define CKF_SO_PIN_COUNT_LOW         0x00100000
244
+
245
+/* CKF_SO_PIN_FINAL_TRY if new for v2.10. If it is true,
246
+ * supplying an incorrect SO PIN will it to become locked. */
247
+#define CKF_SO_PIN_FINAL_TRY         0x00200000
248
+
249
+/* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO
250
+ * PIN has been locked. SO login to the token is not possible.
251
+ */
252
+#define CKF_SO_PIN_LOCKED            0x00400000
253
+
254
+/* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
255
+ * the SO PIN value is the default value set by token
256
+ * initialization or manufacturing, or the PIN has been
257
+ * expired by the card. */
258
+#define CKF_SO_PIN_TO_BE_CHANGED     0x00800000
259
+
260
+typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
261
+
262
+
263
+/* CK_SESSION_HANDLE is a Cryptoki-assigned value that
264
+ * identifies a session */
265
+typedef CK_ULONG          CK_SESSION_HANDLE;
266
+
267
+typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR;
268
+
269
+
270
+/* CK_USER_TYPE enumerates the types of Cryptoki users */
271
+/* CK_USER_TYPE has been changed from an enum to a CK_ULONG for
272
+ * v2.0 */
273
+typedef CK_ULONG          CK_USER_TYPE;
274
+/* Security Officer */
275
+#define CKU_SO    0
276
+/* Normal user */
277
+#define CKU_USER  1
278
+/* Context specific (added in v2.20) */
279
+#define CKU_CONTEXT_SPECIFIC   2
280
+
281
+/* CK_STATE enumerates the session states */
282
+/* CK_STATE has been changed from an enum to a CK_ULONG for
283
+ * v2.0 */
284
+typedef CK_ULONG          CK_STATE;
285
+#define CKS_RO_PUBLIC_SESSION  0
286
+#define CKS_RO_USER_FUNCTIONS  1
287
+#define CKS_RW_PUBLIC_SESSION  2
288
+#define CKS_RW_USER_FUNCTIONS  3
289
+#define CKS_RW_SO_FUNCTIONS    4
290
+
291
+
292
+/* CK_SESSION_INFO provides information about a session */
293
+typedef struct CK_SESSION_INFO {
294
+  CK_SLOT_ID    slotID;
295
+  CK_STATE      state;
296
+  CK_FLAGS      flags;          /* see below */
297
+
298
+  /* ulDeviceError was changed from CK_USHORT to CK_ULONG for
299
+   * v2.0 */
300
+  CK_ULONG      ulDeviceError;  /* device-dependent error code */
301
+} CK_SESSION_INFO;
302
+
303
+/* The flags are defined in the following table:
304
+ *      Bit Flag                Mask        Meaning
305
+ */
306
+#define CKF_RW_SESSION          0x00000002  /* session is r/w */
307
+#define CKF_SERIAL_SESSION      0x00000004  /* no parallel */
308
+
309
+typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR;
310
+
311
+
312
+/* CK_OBJECT_HANDLE is a token-specific identifier for an
313
+ * object  */
314
+typedef CK_ULONG          CK_OBJECT_HANDLE;
315
+
316
+typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR;
317
+
318
+
319
+/* CK_OBJECT_CLASS is a value that identifies the classes (or
320
+ * types) of objects that Cryptoki recognizes.  It is defined
321
+ * as follows: */
322
+/* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for
323
+ * v2.0 */
324
+typedef CK_ULONG          CK_OBJECT_CLASS;
325
+
326
+/* The following classes of objects are defined: */
327
+/* CKO_HW_FEATURE is new for v2.10 */
328
+/* CKO_DOMAIN_PARAMETERS is new for v2.11 */
329
+/* CKO_MECHANISM is new for v2.20 */
330
+#define CKO_DATA              0x00000000
331
+#define CKO_CERTIFICATE       0x00000001
332
+#define CKO_PUBLIC_KEY        0x00000002
333
+#define CKO_PRIVATE_KEY       0x00000003
334
+#define CKO_SECRET_KEY        0x00000004
335
+#define CKO_HW_FEATURE        0x00000005
336
+#define CKO_DOMAIN_PARAMETERS 0x00000006
337
+#define CKO_MECHANISM         0x00000007
338
+#define CKO_VENDOR_DEFINED    0x80000000
339
+
340
+typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
341
+
342
+/* CK_HW_FEATURE_TYPE is new for v2.10. CK_HW_FEATURE_TYPE is a
343
+ * value that identifies the hardware feature type of an object
344
+ * with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. */
345
+typedef CK_ULONG          CK_HW_FEATURE_TYPE;
346
+
347
+/* The following hardware feature types are defined */
348
+/* CKH_USER_INTERFACE is new for v2.20 */
349
+#define CKH_MONOTONIC_COUNTER  0x00000001
350
+#define CKH_CLOCK           0x00000002
351
+#define CKH_USER_INTERFACE  0x00000003
352
+#define CKH_VENDOR_DEFINED  0x80000000
353
+
354
+/* CK_KEY_TYPE is a value that identifies a key type */
355
+/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */
356
+typedef CK_ULONG          CK_KEY_TYPE;
357
+
358
+/* the following key types are defined: */
359
+#define CKK_RSA             0x00000000
360
+#define CKK_DSA             0x00000001
361
+#define CKK_DH              0x00000002
362
+
363
+/* CKK_ECDSA and CKK_KEA are new for v2.0 */
364
+/* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred. */
365
+#define CKK_ECDSA           0x00000003
366
+#define CKK_EC              0x00000003
367
+#define CKK_X9_42_DH        0x00000004
368
+#define CKK_KEA             0x00000005
369
+
370
+#define CKK_GENERIC_SECRET  0x00000010
371
+#define CKK_RC2             0x00000011
372
+#define CKK_RC4             0x00000012
373
+#define CKK_DES             0x00000013
374
+#define CKK_DES2            0x00000014
375
+#define CKK_DES3            0x00000015
376
+
377
+/* all these key types are new for v2.0 */
378
+#define CKK_CAST            0x00000016
379
+#define CKK_CAST3           0x00000017
380
+/* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred. */
381
+#define CKK_CAST5           0x00000018
382
+#define CKK_CAST128         0x00000018
383
+#define CKK_RC5             0x00000019
384
+#define CKK_IDEA            0x0000001A
385
+#define CKK_SKIPJACK        0x0000001B
386
+#define CKK_BATON           0x0000001C
387
+#define CKK_JUNIPER         0x0000001D
388
+#define CKK_CDMF            0x0000001E
389
+#define CKK_AES             0x0000001F
390
+
391
+/* BlowFish and TwoFish are new for v2.20 */
392
+#define CKK_BLOWFISH        0x00000020
393
+#define CKK_TWOFISH         0x00000021
394
+
395
+#define CKK_VENDOR_DEFINED  0x80000000
396
+
397
+
398
+/* CK_CERTIFICATE_TYPE is a value that identifies a certificate
399
+ * type */
400
+/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG
401
+ * for v2.0 */
402
+typedef CK_ULONG          CK_CERTIFICATE_TYPE;
403
+
404
+/* The following certificate types are defined: */
405
+/* CKC_X_509_ATTR_CERT is new for v2.10 */
406
+/* CKC_WTLS is new for v2.20 */
407
+#define CKC_X_509           0x00000000
408
+#define CKC_X_509_ATTR_CERT 0x00000001
409
+#define CKC_WTLS            0x00000002
410
+#define CKC_VENDOR_DEFINED  0x80000000
411
+
412
+
413
+/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute
414
+ * type */
415
+/* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for
416
+ * v2.0 */
417
+typedef CK_ULONG          CK_ATTRIBUTE_TYPE;
418
+
419
+/* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which
420
+   consists of an array of values. */
421
+#define CKF_ARRAY_ATTRIBUTE    0x40000000
422
+
423
+/* The following attribute types are defined: */
424
+#define CKA_CLASS              0x00000000
425
+#define CKA_TOKEN              0x00000001
426
+#define CKA_PRIVATE            0x00000002
427
+#define CKA_LABEL              0x00000003
428
+#define CKA_APPLICATION        0x00000010
429
+#define CKA_VALUE              0x00000011
430
+
431
+/* CKA_OBJECT_ID is new for v2.10 */
432
+#define CKA_OBJECT_ID          0x00000012
433
+
434
+#define CKA_CERTIFICATE_TYPE   0x00000080
435
+#define CKA_ISSUER             0x00000081
436
+#define CKA_SERIAL_NUMBER      0x00000082
437
+
438
+/* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new
439
+ * for v2.10 */
440
+#define CKA_AC_ISSUER          0x00000083
441
+#define CKA_OWNER              0x00000084
442
+#define CKA_ATTR_TYPES         0x00000085
443
+
444
+/* CKA_TRUSTED is new for v2.11 */
445
+#define CKA_TRUSTED            0x00000086
446
+
447
+/* CKA_CERTIFICATE_CATEGORY ...
448
+ * CKA_CHECK_VALUE are new for v2.20 */
449
+#define CKA_CERTIFICATE_CATEGORY        0x00000087
450
+#define CKA_JAVA_MIDP_SECURITY_DOMAIN   0x00000088
451
+#define CKA_URL                         0x00000089
452
+#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY  0x0000008A
453
+#define CKA_HASH_OF_ISSUER_PUBLIC_KEY   0x0000008B
454
+#define CKA_CHECK_VALUE                 0x00000090
455
+
456
+#define CKA_KEY_TYPE           0x00000100
457
+#define CKA_SUBJECT            0x00000101
458
+#define CKA_ID                 0x00000102
459
+#define CKA_SENSITIVE          0x00000103
460
+#define CKA_ENCRYPT            0x00000104
461
+#define CKA_DECRYPT            0x00000105
462
+#define CKA_WRAP               0x00000106
463
+#define CKA_UNWRAP             0x00000107
464
+#define CKA_SIGN               0x00000108
465
+#define CKA_SIGN_RECOVER       0x00000109
466
+#define CKA_VERIFY             0x0000010A
467
+#define CKA_VERIFY_RECOVER     0x0000010B
468
+#define CKA_DERIVE             0x0000010C
469
+#define CKA_START_DATE         0x00000110
470
+#define CKA_END_DATE           0x00000111
471
+#define CKA_MODULUS            0x00000120
472
+#define CKA_MODULUS_BITS       0x00000121
473
+#define CKA_PUBLIC_EXPONENT    0x00000122
474
+#define CKA_PRIVATE_EXPONENT   0x00000123
475
+#define CKA_PRIME_1            0x00000124
476
+#define CKA_PRIME_2            0x00000125
477
+#define CKA_EXPONENT_1         0x00000126
478
+#define CKA_EXPONENT_2         0x00000127
479
+#define CKA_COEFFICIENT        0x00000128
480
+#define CKA_PRIME              0x00000130
481
+#define CKA_SUBPRIME           0x00000131
482
+#define CKA_BASE               0x00000132
483
+
484
+/* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */
485
+#define CKA_PRIME_BITS         0x00000133
486
+#define CKA_SUBPRIME_BITS      0x00000134
487
+#define CKA_SUB_PRIME_BITS     CKA_SUBPRIME_BITS
488
+/* (To retain backwards-compatibility) */
489
+
490
+#define CKA_VALUE_BITS         0x00000160
491
+#define CKA_VALUE_LEN          0x00000161
492
+
493
+/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
494
+ * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS,
495
+ * and CKA_EC_POINT are new for v2.0 */
496
+#define CKA_EXTRACTABLE        0x00000162
497
+#define CKA_LOCAL              0x00000163
498
+#define CKA_NEVER_EXTRACTABLE  0x00000164
499
+#define CKA_ALWAYS_SENSITIVE   0x00000165
500
+
501
+/* CKA_KEY_GEN_MECHANISM is new for v2.11 */
502
+#define CKA_KEY_GEN_MECHANISM  0x00000166
503
+
504
+#define CKA_MODIFIABLE         0x00000170
505
+
506
+/* CKA_ECDSA_PARAMS is deprecated in v2.11,
507
+ * CKA_EC_PARAMS is preferred. */
508
+#define CKA_ECDSA_PARAMS       0x00000180
509
+#define CKA_EC_PARAMS          0x00000180
510
+
511
+#define CKA_EC_POINT           0x00000181
512
+
513
+/* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
514
+ * are new for v2.10. Deprecated in v2.11 and onwards. */
515
+#define CKA_SECONDARY_AUTH     0x00000200
516
+#define CKA_AUTH_PIN_FLAGS     0x00000201
517
+
518
+/* CKA_ALWAYS_AUTHENTICATE ...
519
+ * CKA_UNWRAP_TEMPLATE are new for v2.20 */
520
+#define CKA_ALWAYS_AUTHENTICATE  0x00000202
521
+
522
+#define CKA_WRAP_WITH_TRUSTED    0x00000210
523
+#define CKA_WRAP_TEMPLATE        (CKF_ARRAY_ATTRIBUTE|0x00000211)
524
+#define CKA_UNWRAP_TEMPLATE      (CKF_ARRAY_ATTRIBUTE|0x00000212)
525
+
526
+/* CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET
527
+ * are new for v2.10 */
528
+#define CKA_HW_FEATURE_TYPE    0x00000300
529
+#define CKA_RESET_ON_INIT      0x00000301
530
+#define CKA_HAS_RESET          0x00000302
531
+
532
+/* The following attributes are new for v2.20 */
533
+#define CKA_PIXEL_X                     0x00000400
534
+#define CKA_PIXEL_Y                     0x00000401
535
+#define CKA_RESOLUTION                  0x00000402
536
+#define CKA_CHAR_ROWS                   0x00000403
537
+#define CKA_CHAR_COLUMNS                0x00000404
538
+#define CKA_COLOR                       0x00000405
539
+#define CKA_BITS_PER_PIXEL              0x00000406
540
+#define CKA_CHAR_SETS                   0x00000480
541
+#define CKA_ENCODING_METHODS            0x00000481
542
+#define CKA_MIME_TYPES                  0x00000482
543
+#define CKA_MECHANISM_TYPE              0x00000500
544
+#define CKA_REQUIRED_CMS_ATTRIBUTES     0x00000501
545
+#define CKA_DEFAULT_CMS_ATTRIBUTES      0x00000502
546
+#define CKA_SUPPORTED_CMS_ATTRIBUTES    0x00000503
547
+#define CKA_ALLOWED_MECHANISMS          (CKF_ARRAY_ATTRIBUTE|0x00000600)
548
+
549
+#define CKA_VENDOR_DEFINED     0x80000000
550
+
551
+
552
+/* CK_ATTRIBUTE is a structure that includes the type, length
553
+ * and value of an attribute */
554
+typedef struct CK_ATTRIBUTE {
555
+  CK_ATTRIBUTE_TYPE type;
556
+  CK_VOID_PTR       pValue;
557
+
558
+  /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */
559
+  CK_ULONG          ulValueLen;  /* in bytes */
560
+} CK_ATTRIBUTE;
561
+
562
+typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR;
563
+
564
+
565
+/* CK_DATE is a structure that defines a date */
566
+typedef struct CK_DATE{
567
+  CK_CHAR       year[4];   /* the year ("1900" - "9999") */
568
+  CK_CHAR       month[2];  /* the month ("01" - "12") */
569
+  CK_CHAR       day[2];    /* the day   ("01" - "31") */
570
+} CK_DATE;
571
+
572
+
573
+/* CK_MECHANISM_TYPE is a value that identifies a mechanism
574
+ * type */
575
+/* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for
576
+ * v2.0 */
577
+typedef CK_ULONG          CK_MECHANISM_TYPE;
578
+
579
+/* the following mechanism types are defined: */
580
+#define CKM_RSA_PKCS_KEY_PAIR_GEN      0x00000000
581
+#define CKM_RSA_PKCS                   0x00000001
582
+#define CKM_RSA_9796                   0x00000002
583
+#define CKM_RSA_X_509                  0x00000003
584
+
585
+/* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS
586
+ * are new for v2.0.  They are mechanisms which hash and sign */
587
+#define CKM_MD2_RSA_PKCS               0x00000004
588
+#define CKM_MD5_RSA_PKCS               0x00000005
589
+#define CKM_SHA1_RSA_PKCS              0x00000006
590
+
591
+/* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, and
592
+ * CKM_RSA_PKCS_OAEP are new for v2.10 */
593
+#define CKM_RIPEMD128_RSA_PKCS         0x00000007
594
+#define CKM_RIPEMD160_RSA_PKCS         0x00000008
595
+#define CKM_RSA_PKCS_OAEP              0x00000009
596
+
597
+/* CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31,
598
+ * CKM_RSA_PKCS_PSS, and CKM_SHA1_RSA_PKCS_PSS are new for v2.11 */
599
+#define CKM_RSA_X9_31_KEY_PAIR_GEN     0x0000000A
600
+#define CKM_RSA_X9_31                  0x0000000B
601
+#define CKM_SHA1_RSA_X9_31             0x0000000C
602
+#define CKM_RSA_PKCS_PSS               0x0000000D
603
+#define CKM_SHA1_RSA_PKCS_PSS          0x0000000E
604
+
605
+#define CKM_DSA_KEY_PAIR_GEN           0x00000010
606
+#define CKM_DSA                        0x00000011
607
+#define CKM_DSA_SHA1                   0x00000012
608
+#define CKM_DH_PKCS_KEY_PAIR_GEN       0x00000020
609
+#define CKM_DH_PKCS_DERIVE             0x00000021
610
+
611
+/* CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE,
612
+ * CKM_X9_42_DH_HYBRID_DERIVE, and CKM_X9_42_MQV_DERIVE are new for
613
+ * v2.11 */
614
+#define CKM_X9_42_DH_KEY_PAIR_GEN      0x00000030
615
+#define CKM_X9_42_DH_DERIVE            0x00000031
616
+#define CKM_X9_42_DH_HYBRID_DERIVE     0x00000032
617
+#define CKM_X9_42_MQV_DERIVE           0x00000033
618
+
619
+/* CKM_SHA256/384/512 are new for v2.20 */
620
+#define CKM_SHA256_RSA_PKCS            0x00000040
621
+#define CKM_SHA384_RSA_PKCS            0x00000041
622
+#define CKM_SHA512_RSA_PKCS            0x00000042
623
+#define CKM_SHA256_RSA_PKCS_PSS        0x00000043
624
+#define CKM_SHA384_RSA_PKCS_PSS        0x00000044
625
+#define CKM_SHA512_RSA_PKCS_PSS        0x00000045
626
+
627
+#define CKM_RC2_KEY_GEN                0x00000100
628
+#define CKM_RC2_ECB                    0x00000101
629
+#define CKM_RC2_CBC                    0x00000102
630
+#define CKM_RC2_MAC                    0x00000103
631
+
632
+/* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */
633
+#define CKM_RC2_MAC_GENERAL            0x00000104
634
+#define CKM_RC2_CBC_PAD                0x00000105
635
+
636
+#define CKM_RC4_KEY_GEN                0x00000110
637
+#define CKM_RC4                        0x00000111
638
+#define CKM_DES_KEY_GEN                0x00000120
639
+#define CKM_DES_ECB                    0x00000121
640
+#define CKM_DES_CBC                    0x00000122
641
+#define CKM_DES_MAC                    0x00000123
642
+
643
+/* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */
644
+#define CKM_DES_MAC_GENERAL            0x00000124
645
+#define CKM_DES_CBC_PAD                0x00000125
646
+
647
+#define CKM_DES2_KEY_GEN               0x00000130
648
+#define CKM_DES3_KEY_GEN               0x00000131
649
+#define CKM_DES3_ECB                   0x00000132
650
+#define CKM_DES3_CBC                   0x00000133
651
+#define CKM_DES3_MAC                   0x00000134
652
+
653
+/* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN,
654
+ * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC,
655
+ * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */
656
+#define CKM_DES3_MAC_GENERAL           0x00000135
657
+#define CKM_DES3_CBC_PAD               0x00000136
658
+#define CKM_CDMF_KEY_GEN               0x00000140
659
+#define CKM_CDMF_ECB                   0x00000141
660
+#define CKM_CDMF_CBC                   0x00000142
661
+#define CKM_CDMF_MAC                   0x00000143
662
+#define CKM_CDMF_MAC_GENERAL           0x00000144
663
+#define CKM_CDMF_CBC_PAD               0x00000145
664
+
665
+/* the following four DES mechanisms are new for v2.20 */
666
+#define CKM_DES_OFB64                  0x00000150
667
+#define CKM_DES_OFB8                   0x00000151
668
+#define CKM_DES_CFB64                  0x00000152
669
+#define CKM_DES_CFB8                   0x00000153
670
+
671
+#define CKM_MD2                        0x00000200
672
+
673
+/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */
674
+#define CKM_MD2_HMAC                   0x00000201
675
+#define CKM_MD2_HMAC_GENERAL           0x00000202
676
+
677
+#define CKM_MD5                        0x00000210
678
+
679
+/* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */
680
+#define CKM_MD5_HMAC                   0x00000211
681
+#define CKM_MD5_HMAC_GENERAL           0x00000212
682
+
683
+#define CKM_SHA_1                      0x00000220
684
+
685
+/* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */
686
+#define CKM_SHA_1_HMAC                 0x00000221
687
+#define CKM_SHA_1_HMAC_GENERAL         0x00000222
688
+
689
+/* CKM_RIPEMD128, CKM_RIPEMD128_HMAC,
690
+ * CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC,
691
+ * and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */
692
+#define CKM_RIPEMD128                  0x00000230
693
+#define CKM_RIPEMD128_HMAC             0x00000231
694
+#define CKM_RIPEMD128_HMAC_GENERAL     0x00000232
695
+#define CKM_RIPEMD160                  0x00000240
696
+#define CKM_RIPEMD160_HMAC             0x00000241
697
+#define CKM_RIPEMD160_HMAC_GENERAL     0x00000242
698
+
699
+/* CKM_SHA256/384/512 are new for v2.20 */
700
+#define CKM_SHA256                     0x00000250
701
+#define CKM_SHA256_HMAC                0x00000251
702
+#define CKM_SHA256_HMAC_GENERAL        0x00000252
703
+#define CKM_SHA384                     0x00000260
704
+#define CKM_SHA384_HMAC                0x00000261
705
+#define CKM_SHA384_HMAC_GENERAL        0x00000262
706
+#define CKM_SHA512                     0x00000270
707
+#define CKM_SHA512_HMAC                0x00000271
708
+#define CKM_SHA512_HMAC_GENERAL        0x00000272
709
+
710
+/* All of the following mechanisms are new for v2.0 */
711
+/* Note that CAST128 and CAST5 are the same algorithm */
712
+#define CKM_CAST_KEY_GEN               0x00000300
713
+#define CKM_CAST_ECB                   0x00000301
714
+#define CKM_CAST_CBC                   0x00000302
715
+#define CKM_CAST_MAC                   0x00000303
716
+#define CKM_CAST_MAC_GENERAL           0x00000304
717
+#define CKM_CAST_CBC_PAD               0x00000305
718
+#define CKM_CAST3_KEY_GEN              0x00000310
719
+#define CKM_CAST3_ECB                  0x00000311
720
+#define CKM_CAST3_CBC                  0x00000312
721
+#define CKM_CAST3_MAC                  0x00000313
722
+#define CKM_CAST3_MAC_GENERAL          0x00000314
723
+#define CKM_CAST3_CBC_PAD              0x00000315
724
+#define CKM_CAST5_KEY_GEN              0x00000320
725
+#define CKM_CAST128_KEY_GEN            0x00000320
726
+#define CKM_CAST5_ECB                  0x00000321
727
+#define CKM_CAST128_ECB                0x00000321
728
+#define CKM_CAST5_CBC                  0x00000322
729
+#define CKM_CAST128_CBC                0x00000322
730
+#define CKM_CAST5_MAC                  0x00000323
731
+#define CKM_CAST128_MAC                0x00000323
732
+#define CKM_CAST5_MAC_GENERAL          0x00000324
733
+#define CKM_CAST128_MAC_GENERAL        0x00000324
734
+#define CKM_CAST5_CBC_PAD              0x00000325
735
+#define CKM_CAST128_CBC_PAD            0x00000325
736
+#define CKM_RC5_KEY_GEN                0x00000330
737
+#define CKM_RC5_ECB                    0x00000331
738
+#define CKM_RC5_CBC                    0x00000332
739
+#define CKM_RC5_MAC                    0x00000333
740
+#define CKM_RC5_MAC_GENERAL            0x00000334
741
+#define CKM_RC5_CBC_PAD                0x00000335
742
+#define CKM_IDEA_KEY_GEN               0x00000340
743
+#define CKM_IDEA_ECB                   0x00000341
744
+#define CKM_IDEA_CBC                   0x00000342
745
+#define CKM_IDEA_MAC                   0x00000343
746
+#define CKM_IDEA_MAC_GENERAL           0x00000344
747
+#define CKM_IDEA_CBC_PAD               0x00000345
748
+#define CKM_GENERIC_SECRET_KEY_GEN     0x00000350
749
+#define CKM_CONCATENATE_BASE_AND_KEY   0x00000360
750
+#define CKM_CONCATENATE_BASE_AND_DATA  0x00000362
751
+#define CKM_CONCATENATE_DATA_AND_BASE  0x00000363
752
+#define CKM_XOR_BASE_AND_DATA          0x00000364
753
+#define CKM_EXTRACT_KEY_FROM_KEY       0x00000365
754
+#define CKM_SSL3_PRE_MASTER_KEY_GEN    0x00000370
755
+#define CKM_SSL3_MASTER_KEY_DERIVE     0x00000371
756
+#define CKM_SSL3_KEY_AND_MAC_DERIVE    0x00000372
757
+
758
+/* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN,
759
+ * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE, and
760
+ * CKM_TLS_MASTER_KEY_DERIVE_DH are new for v2.11 */
761
+#define CKM_SSL3_MASTER_KEY_DERIVE_DH  0x00000373
762
+#define CKM_TLS_PRE_MASTER_KEY_GEN     0x00000374
763
+#define CKM_TLS_MASTER_KEY_DERIVE      0x00000375
764
+#define CKM_TLS_KEY_AND_MAC_DERIVE     0x00000376
765
+#define CKM_TLS_MASTER_KEY_DERIVE_DH   0x00000377
766
+
767
+/* CKM_TLS_PRF is new for v2.20 */
768
+#define CKM_TLS_PRF                    0x00000378
769
+
770
+#define CKM_SSL3_MD5_MAC               0x00000380
771
+#define CKM_SSL3_SHA1_MAC              0x00000381
772
+#define CKM_MD5_KEY_DERIVATION         0x00000390
773
+#define CKM_MD2_KEY_DERIVATION         0x00000391
774
+#define CKM_SHA1_KEY_DERIVATION        0x00000392
775
+
776
+/* CKM_SHA256/384/512 are new for v2.20 */
777
+#define CKM_SHA256_KEY_DERIVATION      0x00000393
778
+#define CKM_SHA384_KEY_DERIVATION      0x00000394
779
+#define CKM_SHA512_KEY_DERIVATION      0x00000395
780
+
781
+#define CKM_PBE_MD2_DES_CBC            0x000003A0
782
+#define CKM_PBE_MD5_DES_CBC            0x000003A1
783
+#define CKM_PBE_MD5_CAST_CBC           0x000003A2
784
+#define CKM_PBE_MD5_CAST3_CBC          0x000003A3
785
+#define CKM_PBE_MD5_CAST5_CBC          0x000003A4
786
+#define CKM_PBE_MD5_CAST128_CBC        0x000003A4
787
+#define CKM_PBE_SHA1_CAST5_CBC         0x000003A5
788
+#define CKM_PBE_SHA1_CAST128_CBC       0x000003A5
789
+#define CKM_PBE_SHA1_RC4_128           0x000003A6
790
+#define CKM_PBE_SHA1_RC4_40            0x000003A7
791
+#define CKM_PBE_SHA1_DES3_EDE_CBC      0x000003A8
792
+#define CKM_PBE_SHA1_DES2_EDE_CBC      0x000003A9
793
+#define CKM_PBE_SHA1_RC2_128_CBC       0x000003AA
794
+#define CKM_PBE_SHA1_RC2_40_CBC        0x000003AB
795
+
796
+/* CKM_PKCS5_PBKD2 is new for v2.10 */
797
+#define CKM_PKCS5_PBKD2                0x000003B0
798
+
799
+#define CKM_PBA_SHA1_WITH_SHA1_HMAC    0x000003C0
800
+
801
+/* WTLS mechanisms are new for v2.20 */
802
+#define CKM_WTLS_PRE_MASTER_KEY_GEN         0x000003D0
803
+#define CKM_WTLS_MASTER_KEY_DERIVE          0x000003D1
804
+#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC   0x000003D2
805
+#define CKM_WTLS_PRF                        0x000003D3
806
+#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE  0x000003D4
807
+#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE  0x000003D5
808
+
809
+#define CKM_KEY_WRAP_LYNKS             0x00000400
810
+#define CKM_KEY_WRAP_SET_OAEP          0x00000401
811
+
812
+/* CKM_CMS_SIG is new for v2.20 */
813
+#define CKM_CMS_SIG                    0x00000500
814
+
815
+/* Fortezza mechanisms */
816
+#define CKM_SKIPJACK_KEY_GEN           0x00001000
817
+#define CKM_SKIPJACK_ECB64             0x00001001
818
+#define CKM_SKIPJACK_CBC64             0x00001002
819
+#define CKM_SKIPJACK_OFB64             0x00001003
820
+#define CKM_SKIPJACK_CFB64             0x00001004
821
+#define CKM_SKIPJACK_CFB32             0x00001005
822
+#define CKM_SKIPJACK_CFB16             0x00001006
823
+#define CKM_SKIPJACK_CFB8              0x00001007
824
+#define CKM_SKIPJACK_WRAP              0x00001008
825
+#define CKM_SKIPJACK_PRIVATE_WRAP      0x00001009
826
+#define CKM_SKIPJACK_RELAYX            0x0000100a
827
+#define CKM_KEA_KEY_PAIR_GEN           0x00001010
828
+#define CKM_KEA_KEY_DERIVE             0x00001011
829
+#define CKM_FORTEZZA_TIMESTAMP         0x00001020
830
+#define CKM_BATON_KEY_GEN              0x00001030
831
+#define CKM_BATON_ECB128               0x00001031
832
+#define CKM_BATON_ECB96                0x00001032
833
+#define CKM_BATON_CBC128               0x00001033
834
+#define CKM_BATON_COUNTER              0x00001034
835
+#define CKM_BATON_SHUFFLE              0x00001035
836
+#define CKM_BATON_WRAP                 0x00001036
837
+
838
+/* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11,
839
+ * CKM_EC_KEY_PAIR_GEN is preferred */
840
+#define CKM_ECDSA_KEY_PAIR_GEN         0x00001040
841
+#define CKM_EC_KEY_PAIR_GEN            0x00001040
842
+
843
+#define CKM_ECDSA                      0x00001041
844
+#define CKM_ECDSA_SHA1                 0x00001042
845
+
846
+/* CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE, and CKM_ECMQV_DERIVE
847
+ * are new for v2.11 */
848
+#define CKM_ECDH1_DERIVE               0x00001050
849
+#define CKM_ECDH1_COFACTOR_DERIVE      0x00001051
850
+#define CKM_ECMQV_DERIVE               0x00001052
851
+
852
+#define CKM_JUNIPER_KEY_GEN            0x00001060
853
+#define CKM_JUNIPER_ECB128             0x00001061
854
+#define CKM_JUNIPER_CBC128             0x00001062
855
+#define CKM_JUNIPER_COUNTER            0x00001063
856
+#define CKM_JUNIPER_SHUFFLE            0x00001064
857
+#define CKM_JUNIPER_WRAP               0x00001065
858
+#define CKM_FASTHASH                   0x00001070
859
+
860
+/* CKM_AES_KEY_GEN, CKM_AES_ECB, CKM_AES_CBC, CKM_AES_MAC,
861
+ * CKM_AES_MAC_GENERAL, CKM_AES_CBC_PAD, CKM_DSA_PARAMETER_GEN,
862
+ * CKM_DH_PKCS_PARAMETER_GEN, and CKM_X9_42_DH_PARAMETER_GEN are
863
+ * new for v2.11 */
864
+#define CKM_AES_KEY_GEN                0x00001080
865
+#define CKM_AES_ECB                    0x00001081
866
+#define CKM_AES_CBC                    0x00001082
867
+#define CKM_AES_MAC                    0x00001083
868
+#define CKM_AES_MAC_GENERAL            0x00001084
869
+#define CKM_AES_CBC_PAD                0x00001085
870
+
871
+/* BlowFish and TwoFish are new for v2.20 */
872
+#define CKM_BLOWFISH_KEY_GEN           0x00001090
873
+#define CKM_BLOWFISH_CBC               0x00001091
874
+#define CKM_TWOFISH_KEY_GEN            0x00001092
875
+#define CKM_TWOFISH_CBC                0x00001093
876
+
877
+
878
+/* CKM_xxx_ENCRYPT_DATA mechanisms are new for v2.20 */
879
+#define CKM_DES_ECB_ENCRYPT_DATA       0x00001100
880
+#define CKM_DES_CBC_ENCRYPT_DATA       0x00001101
881
+#define CKM_DES3_ECB_ENCRYPT_DATA      0x00001102
882
+#define CKM_DES3_CBC_ENCRYPT_DATA      0x00001103
883
+#define CKM_AES_ECB_ENCRYPT_DATA       0x00001104
884
+#define CKM_AES_CBC_ENCRYPT_DATA       0x00001105
885
+
886
+#define CKM_DSA_PARAMETER_GEN          0x00002000
887
+#define CKM_DH_PKCS_PARAMETER_GEN      0x00002001
888
+#define CKM_X9_42_DH_PARAMETER_GEN     0x00002002
889
+
890
+#define CKM_VENDOR_DEFINED             0x80000000
891
+
892
+typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR;
893
+
894
+
895
+/* CK_MECHANISM is a structure that specifies a particular
896
+ * mechanism  */
897
+typedef struct CK_MECHANISM {
898
+  CK_MECHANISM_TYPE mechanism;
899
+  CK_VOID_PTR       pParameter;
900
+
901
+  /* ulParameterLen was changed from CK_USHORT to CK_ULONG for
902
+   * v2.0 */
903
+  CK_ULONG          ulParameterLen;  /* in bytes */
904
+} CK_MECHANISM;
905
+
906
+typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR;
907
+
908
+
909
+/* CK_MECHANISM_INFO provides information about a particular
910
+ * mechanism */
911
+typedef struct CK_MECHANISM_INFO {
912
+    CK_ULONG    ulMinKeySize;
913
+    CK_ULONG    ulMaxKeySize;
914
+    CK_FLAGS    flags;
915
+} CK_MECHANISM_INFO;
916
+
917
+/* The flags are defined as follows:
918
+ *      Bit Flag               Mask        Meaning */
919
+#define CKF_HW                 0x00000001  /* performed by HW */
920
+
921
+/* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN,
922
+ * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER,
923
+ * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP,
924
+ * and CKF_DERIVE are new for v2.0.  They specify whether or not
925
+ * a mechanism can be used for a particular task */
926
+#define CKF_ENCRYPT            0x00000100
927
+#define CKF_DECRYPT            0x00000200
928
+#define CKF_DIGEST             0x00000400
929
+#define CKF_SIGN               0x00000800
930
+#define CKF_SIGN_RECOVER       0x00001000
931
+#define CKF_VERIFY             0x00002000
932
+#define CKF_VERIFY_RECOVER     0x00004000
933
+#define CKF_GENERATE           0x00008000
934
+#define CKF_GENERATE_KEY_PAIR  0x00010000
935
+#define CKF_WRAP               0x00020000
936
+#define CKF_UNWRAP             0x00040000
937
+#define CKF_DERIVE             0x00080000
938
+
939
+/* CKF_EC_F_P, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE,
940
+ * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11. They
941
+ * describe a token's EC capabilities not available in mechanism
942
+ * information. */
943
+#define CKF_EC_F_P             0x00100000
944
+#define CKF_EC_F_2M            0x00200000
945
+#define CKF_EC_ECPARAMETERS    0x00400000
946
+#define CKF_EC_NAMEDCURVE      0x00800000
947
+#define CKF_EC_UNCOMPRESS      0x01000000
948
+#define CKF_EC_COMPRESS        0x02000000
949
+
950
+#define CKF_EXTENSION          0x80000000 /* FALSE for this version */
951
+
952
+typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR;
953
+
954
+
955
+/* CK_RV is a value that identifies the return value of a
956
+ * Cryptoki function */
957
+/* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */
958
+typedef CK_ULONG          CK_RV;
959
+
960
+#define CKR_OK                                0x00000000
961
+#define CKR_CANCEL                            0x00000001
962
+#define CKR_HOST_MEMORY                       0x00000002
963
+#define CKR_SLOT_ID_INVALID                   0x00000003
964
+
965
+/* CKR_FLAGS_INVALID was removed for v2.0 */
966
+
967
+/* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */
968
+#define CKR_GENERAL_ERROR                     0x00000005
969
+#define CKR_FUNCTION_FAILED                   0x00000006
970
+
971
+/* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS,
972
+ * and CKR_CANT_LOCK are new for v2.01 */
973
+#define CKR_ARGUMENTS_BAD                     0x00000007
974
+#define CKR_NO_EVENT                          0x00000008
975
+#define CKR_NEED_TO_CREATE_THREADS            0x00000009
976
+#define CKR_CANT_LOCK                         0x0000000A
977
+
978
+#define CKR_ATTRIBUTE_READ_ONLY               0x00000010
979
+#define CKR_ATTRIBUTE_SENSITIVE               0x00000011
980
+#define CKR_ATTRIBUTE_TYPE_INVALID            0x00000012
981
+#define CKR_ATTRIBUTE_VALUE_INVALID           0x00000013
982
+#define CKR_DATA_INVALID                      0x00000020
983
+#define CKR_DATA_LEN_RANGE                    0x00000021
984
+#define CKR_DEVICE_ERROR                      0x00000030
985
+#define CKR_DEVICE_MEMORY                     0x00000031
986
+#define CKR_DEVICE_REMOVED                    0x00000032
987
+#define CKR_ENCRYPTED_DATA_INVALID            0x00000040
988
+#define CKR_ENCRYPTED_DATA_LEN_RANGE          0x00000041
989
+#define CKR_FUNCTION_CANCELED                 0x00000050
990
+#define CKR_FUNCTION_NOT_PARALLEL             0x00000051
991
+
992
+/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */
993
+#define CKR_FUNCTION_NOT_SUPPORTED            0x00000054
994
+
995
+#define CKR_KEY_HANDLE_INVALID                0x00000060
996
+
997
+/* CKR_KEY_SENSITIVE was removed for v2.0 */
998
+
999
+#define CKR_KEY_SIZE_RANGE                    0x00000062
1000
+#define CKR_KEY_TYPE_INCONSISTENT             0x00000063
1001
+
1002
+/* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED,
1003
+ * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED,
1004
+ * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for
1005
+ * v2.0 */
1006
+#define CKR_KEY_NOT_NEEDED                    0x00000064
1007
+#define CKR_KEY_CHANGED                       0x00000065
1008
+#define CKR_KEY_NEEDED                        0x00000066
1009
+#define CKR_KEY_INDIGESTIBLE                  0x00000067
1010
+#define CKR_KEY_FUNCTION_NOT_PERMITTED        0x00000068
1011
+#define CKR_KEY_NOT_WRAPPABLE                 0x00000069
1012
+#define CKR_KEY_UNEXTRACTABLE                 0x0000006A
1013
+
1014
+#define CKR_MECHANISM_INVALID                 0x00000070
1015
+#define CKR_MECHANISM_PARAM_INVALID           0x00000071
1016
+
1017
+/* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID
1018
+ * were removed for v2.0 */
1019
+#define CKR_OBJECT_HANDLE_INVALID             0x00000082
1020
+#define CKR_OPERATION_ACTIVE                  0x00000090
1021
+#define CKR_OPERATION_NOT_INITIALIZED         0x00000091
1022
+#define CKR_PIN_INCORRECT                     0x000000A0
1023
+#define CKR_PIN_INVALID                       0x000000A1
1024
+#define CKR_PIN_LEN_RANGE                     0x000000A2
1025
+
1026
+/* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */
1027
+#define CKR_PIN_EXPIRED                       0x000000A3
1028
+#define CKR_PIN_LOCKED                        0x000000A4
1029
+
1030
+#define CKR_SESSION_CLOSED                    0x000000B0
1031
+#define CKR_SESSION_COUNT                     0x000000B1
1032
+#define CKR_SESSION_HANDLE_INVALID            0x000000B3
1033
+#define CKR_SESSION_PARALLEL_NOT_SUPPORTED    0x000000B4
1034
+#define CKR_SESSION_READ_ONLY                 0x000000B5
1035
+#define CKR_SESSION_EXISTS                    0x000000B6
1036
+
1037
+/* CKR_SESSION_READ_ONLY_EXISTS and
1038
+ * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */
1039
+#define CKR_SESSION_READ_ONLY_EXISTS          0x000000B7
1040
+#define CKR_SESSION_READ_WRITE_SO_EXISTS      0x000000B8
1041
+
1042
+#define CKR_SIGNATURE_INVALID                 0x000000C0
1043
+#define CKR_SIGNATURE_LEN_RANGE               0x000000C1
1044
+#define CKR_TEMPLATE_INCOMPLETE               0x000000D0
1045
+#define CKR_TEMPLATE_INCONSISTENT             0x000000D1
1046
+#define CKR_TOKEN_NOT_PRESENT                 0x000000E0
1047
+#define CKR_TOKEN_NOT_RECOGNIZED              0x000000E1
1048
+#define CKR_TOKEN_WRITE_PROTECTED             0x000000E2
1049
+#define CKR_UNWRAPPING_KEY_HANDLE_INVALID     0x000000F0
1050
+#define CKR_UNWRAPPING_KEY_SIZE_RANGE         0x000000F1
1051
+#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT  0x000000F2
1052
+#define CKR_USER_ALREADY_LOGGED_IN            0x00000100
1053
+#define CKR_USER_NOT_LOGGED_IN                0x00000101
1054
+#define CKR_USER_PIN_NOT_INITIALIZED          0x00000102
1055
+#define CKR_USER_TYPE_INVALID                 0x00000103
1056
+
1057
+/* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES
1058
+ * are new to v2.01 */
1059
+#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN    0x00000104
1060
+#define CKR_USER_TOO_MANY_TYPES               0x00000105
1061
+
1062
+#define CKR_WRAPPED_KEY_INVALID               0x00000110
1063
+#define CKR_WRAPPED_KEY_LEN_RANGE             0x00000112
1064
+#define CKR_WRAPPING_KEY_HANDLE_INVALID       0x00000113
1065
+#define CKR_WRAPPING_KEY_SIZE_RANGE           0x00000114
1066
+#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT    0x00000115
1067
+#define CKR_RANDOM_SEED_NOT_SUPPORTED         0x00000120
1068
+
1069
+/* These are new to v2.0 */
1070
+#define CKR_RANDOM_NO_RNG                     0x00000121
1071
+
1072
+/* These are new to v2.11 */
1073
+#define CKR_DOMAIN_PARAMS_INVALID             0x00000130
1074
+
1075
+/* These are new to v2.0 */
1076
+#define CKR_BUFFER_TOO_SMALL                  0x00000150
1077
+#define CKR_SAVED_STATE_INVALID               0x00000160
1078
+#define CKR_INFORMATION_SENSITIVE             0x00000170
1079
+#define CKR_STATE_UNSAVEABLE                  0x00000180
1080
+
1081
+/* These are new to v2.01 */
1082
+#define CKR_CRYPTOKI_NOT_INITIALIZED          0x00000190
1083
+#define CKR_CRYPTOKI_ALREADY_INITIALIZED      0x00000191
1084
+#define CKR_MUTEX_BAD                         0x000001A0
1085
+#define CKR_MUTEX_NOT_LOCKED                  0x000001A1
1086
+
1087
+/* This is new to v2.20 */
1088
+#define CKR_FUNCTION_REJECTED                 0x00000200
1089
+
1090
+#define CKR_VENDOR_DEFINED                    0x80000000
1091
+
1092
+
1093
+/* CK_NOTIFY is an application callback that processes events */
1094
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)(
1095
+  CK_SESSION_HANDLE hSession,     /* the session's handle */
1096
+  CK_NOTIFICATION   event,
1097
+  CK_VOID_PTR       pApplication  /* passed to C_OpenSession */
1098
+);
1099
+
1100
+
1101
+/* CK_FUNCTION_LIST is a structure holding a Cryptoki spec
1102
+ * version and pointers of appropriate types to all the
1103
+ * Cryptoki functions */
1104
+/* CK_FUNCTION_LIST is new for v2.0 */
1105
+typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST;
1106
+
1107
+typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR;
1108
+
1109
+typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR;
1110
+
1111
+
1112
+/* CK_CREATEMUTEX is an application callback for creating a
1113
+ * mutex object */
1114
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)(
1115
+  CK_VOID_PTR_PTR ppMutex  /* location to receive ptr to mutex */
1116
+);
1117
+
1118
+
1119
+/* CK_DESTROYMUTEX is an application callback for destroying a
1120
+ * mutex object */
1121
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)(
1122
+  CK_VOID_PTR pMutex  /* pointer to mutex */
1123
+);
1124
+
1125
+
1126
+/* CK_LOCKMUTEX is an application callback for locking a mutex */
1127
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)(
1128
+  CK_VOID_PTR pMutex  /* pointer to mutex */
1129
+);
1130
+
1131
+
1132
+/* CK_UNLOCKMUTEX is an application callback for unlocking a
1133
+ * mutex */
1134
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)(
1135
+  CK_VOID_PTR pMutex  /* pointer to mutex */
1136
+);
1137
+
1138
+
1139
+/* CK_C_INITIALIZE_ARGS provides the optional arguments to
1140
+ * C_Initialize */
1141
+typedef struct CK_C_INITIALIZE_ARGS {
1142
+  CK_CREATEMUTEX CreateMutex;
1143
+  CK_DESTROYMUTEX DestroyMutex;
1144
+  CK_LOCKMUTEX LockMutex;
1145
+  CK_UNLOCKMUTEX UnlockMutex;
1146
+  CK_FLAGS flags;
1147
+  CK_VOID_PTR pReserved;
1148
+} CK_C_INITIALIZE_ARGS;
1149
+
1150
+/* flags: bit flags that provide capabilities of the slot
1151
+ *      Bit Flag                           Mask       Meaning
1152
+ */
1153
+#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001
1154
+#define CKF_OS_LOCKING_OK                  0x00000002
1155
+
1156
+typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
1157
+
1158
+
1159
+/* additional flags for parameters to functions */
1160
+
1161
+/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
1162
+#define CKF_DONT_BLOCK     1
1163
+
1164
+/* CK_RSA_PKCS_OAEP_MGF_TYPE is new for v2.10.
1165
+ * CK_RSA_PKCS_OAEP_MGF_TYPE  is used to indicate the Message
1166
+ * Generation Function (MGF) applied to a message block when
1167
+ * formatting a message block for the PKCS #1 OAEP encryption
1168
+ * scheme. */
1169
+typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE;
1170
+
1171
+typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR;
1172
+
1173
+/* The following MGFs are defined */
1174
+/* CKG_MGF1_SHA256, CKG_MGF1_SHA384, and CKG_MGF1_SHA512
1175
+ * are new for v2.20 */
1176
+#define CKG_MGF1_SHA1         0x00000001
1177
+#define CKG_MGF1_SHA256       0x00000002
1178
+#define CKG_MGF1_SHA384       0x00000003
1179
+#define CKG_MGF1_SHA512       0x00000004
1180
+
1181
+/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is new for v2.10.
1182
+ * CK_RSA_PKCS_OAEP_SOURCE_TYPE  is used to indicate the source
1183
+ * of the encoding parameter when formatting a message block
1184
+ * for the PKCS #1 OAEP encryption scheme. */
1185
+typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE;
1186
+
1187
+typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR;
1188
+
1189
+/* The following encoding parameter sources are defined */
1190
+#define CKZ_DATA_SPECIFIED    0x00000001
1191
+
1192
+/* CK_RSA_PKCS_OAEP_PARAMS is new for v2.10.
1193
+ * CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the
1194
+ * CKM_RSA_PKCS_OAEP mechanism. */
1195
+typedef struct CK_RSA_PKCS_OAEP_PARAMS {
1196
+        CK_MECHANISM_TYPE hashAlg;
1197
+        CK_RSA_PKCS_MGF_TYPE mgf;
1198
+        CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
1199
+        CK_VOID_PTR pSourceData;
1200
+        CK_ULONG ulSourceDataLen;
1201
+} CK_RSA_PKCS_OAEP_PARAMS;
1202
+
1203
+typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR;
1204
+
1205
+/* CK_RSA_PKCS_PSS_PARAMS is new for v2.11.
1206
+ * CK_RSA_PKCS_PSS_PARAMS provides the parameters to the
1207
+ * CKM_RSA_PKCS_PSS mechanism(s). */
1208
+typedef struct CK_RSA_PKCS_PSS_PARAMS {
1209
+        CK_MECHANISM_TYPE    hashAlg;
1210
+        CK_RSA_PKCS_MGF_TYPE mgf;
1211
+        CK_ULONG             sLen;
1212
+} CK_RSA_PKCS_PSS_PARAMS;
1213
+
1214
+typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR;
1215
+
1216
+/* CK_EC_KDF_TYPE is new for v2.11. */
1217
+typedef CK_ULONG CK_EC_KDF_TYPE;
1218
+
1219
+/* The following EC Key Derivation Functions are defined */
1220
+#define CKD_NULL                 0x00000001
1221
+#define CKD_SHA1_KDF             0x00000002
1222
+
1223
+/* CK_ECDH1_DERIVE_PARAMS is new for v2.11.
1224
+ * CK_ECDH1_DERIVE_PARAMS provides the parameters to the
1225
+ * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms,
1226
+ * where each party contributes one key pair.
1227
+ */
1228
+typedef struct CK_ECDH1_DERIVE_PARAMS {
1229
+  CK_EC_KDF_TYPE kdf;
1230
+  CK_ULONG ulSharedDataLen;
1231
+  CK_BYTE_PTR pSharedData;
1232
+  CK_ULONG ulPublicDataLen;
1233
+  CK_BYTE_PTR pPublicData;
1234
+} CK_ECDH1_DERIVE_PARAMS;
1235
+
1236
+typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR;
1237
+
1238
+
1239
+/* CK_ECDH2_DERIVE_PARAMS is new for v2.11.
1240
+ * CK_ECDH2_DERIVE_PARAMS provides the parameters to the
1241
+ * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs. */
1242
+typedef struct CK_ECDH2_DERIVE_PARAMS {
1243
+  CK_EC_KDF_TYPE kdf;
1244
+  CK_ULONG ulSharedDataLen;
1245
+  CK_BYTE_PTR pSharedData;
1246
+  CK_ULONG ulPublicDataLen;
1247
+  CK_BYTE_PTR pPublicData;
1248
+  CK_ULONG ulPrivateDataLen;
1249
+  CK_OBJECT_HANDLE hPrivateData;
1250
+  CK_ULONG ulPublicDataLen2;
1251
+  CK_BYTE_PTR pPublicData2;
1252
+} CK_ECDH2_DERIVE_PARAMS;
1253
+
1254
+typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR;
1255
+
1256
+typedef struct CK_ECMQV_DERIVE_PARAMS {
1257
+  CK_EC_KDF_TYPE kdf;
1258
+  CK_ULONG ulSharedDataLen;
1259
+  CK_BYTE_PTR pSharedData;
1260
+  CK_ULONG ulPublicDataLen;
1261
+  CK_BYTE_PTR pPublicData;
1262
+  CK_ULONG ulPrivateDataLen;
1263
+  CK_OBJECT_HANDLE hPrivateData;
1264
+  CK_ULONG ulPublicDataLen2;
1265
+  CK_BYTE_PTR pPublicData2;
1266
+  CK_OBJECT_HANDLE publicKey;
1267
+} CK_ECMQV_DERIVE_PARAMS;
1268
+
1269
+typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR;
1270
+
1271
+/* Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the
1272
+ * CKM_X9_42_DH_PARAMETER_GEN mechanisms (new for PKCS #11 v2.11) */
1273
+typedef CK_ULONG CK_X9_42_DH_KDF_TYPE;
1274
+typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR;
1275
+
1276
+/* The following X9.42 DH key derivation functions are defined
1277
+   (besides CKD_NULL already defined : */
1278
+#define CKD_SHA1_KDF_ASN1        0x00000003
1279
+#define CKD_SHA1_KDF_CONCATENATE 0x00000004
1280
+
1281
+/* CK_X9_42_DH1_DERIVE_PARAMS is new for v2.11.
1282
+ * CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the
1283
+ * CKM_X9_42_DH_DERIVE key derivation mechanism, where each party
1284
+ * contributes one key pair */
1285
+typedef struct CK_X9_42_DH1_DERIVE_PARAMS {
1286
+  CK_X9_42_DH_KDF_TYPE kdf;
1287
+  CK_ULONG ulOtherInfoLen;
1288
+  CK_BYTE_PTR pOtherInfo;
1289
+  CK_ULONG ulPublicDataLen;
1290
+  CK_BYTE_PTR pPublicData;
1291
+} CK_X9_42_DH1_DERIVE_PARAMS;
1292
+
1293
+typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR;
1294
+
1295
+/* CK_X9_42_DH2_DERIVE_PARAMS is new for v2.11.
1296
+ * CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the
1297
+ * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation
1298
+ * mechanisms, where each party contributes two key pairs */
1299
+typedef struct CK_X9_42_DH2_DERIVE_PARAMS {
1300
+  CK_X9_42_DH_KDF_TYPE kdf;
1301
+  CK_ULONG ulOtherInfoLen;
1302
+  CK_BYTE_PTR pOtherInfo;
1303
+  CK_ULONG ulPublicDataLen;
1304
+  CK_BYTE_PTR pPublicData;
1305
+  CK_ULONG ulPrivateDataLen;
1306
+  CK_OBJECT_HANDLE hPrivateData;
1307
+  CK_ULONG ulPublicDataLen2;
1308
+  CK_BYTE_PTR pPublicData2;
1309
+} CK_X9_42_DH2_DERIVE_PARAMS;
1310
+
1311
+typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR;
1312
+
1313
+typedef struct CK_X9_42_MQV_DERIVE_PARAMS {
1314
+  CK_X9_42_DH_KDF_TYPE kdf;
1315
+  CK_ULONG ulOtherInfoLen;
1316
+  CK_BYTE_PTR pOtherInfo;
1317
+  CK_ULONG ulPublicDataLen;
1318
+  CK_BYTE_PTR pPublicData;
1319
+  CK_ULONG ulPrivateDataLen;
1320
+  CK_OBJECT_HANDLE hPrivateData;
1321
+  CK_ULONG ulPublicDataLen2;
1322
+  CK_BYTE_PTR pPublicData2;
1323
+  CK_OBJECT_HANDLE publicKey;
1324
+} CK_X9_42_MQV_DERIVE_PARAMS;
1325
+
1326
+typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR;
1327
+
1328
+/* CK_KEA_DERIVE_PARAMS provides the parameters to the
1329
+ * CKM_KEA_DERIVE mechanism */
1330
+/* CK_KEA_DERIVE_PARAMS is new for v2.0 */
1331
+typedef struct CK_KEA_DERIVE_PARAMS {
1332
+  CK_BBOOL      isSender;
1333
+  CK_ULONG      ulRandomLen;
1334
+  CK_BYTE_PTR   pRandomA;
1335
+  CK_BYTE_PTR   pRandomB;
1336
+  CK_ULONG      ulPublicDataLen;
1337
+  CK_BYTE_PTR   pPublicData;
1338
+} CK_KEA_DERIVE_PARAMS;
1339
+
1340
+typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR;
1341
+
1342
+
1343
+/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and
1344
+ * CKM_RC2_MAC mechanisms.  An instance of CK_RC2_PARAMS just
1345
+ * holds the effective keysize */
1346
+typedef CK_ULONG          CK_RC2_PARAMS;
1347
+
1348
+typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR;
1349
+
1350
+
1351
+/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC
1352
+ * mechanism */
1353
+typedef struct CK_RC2_CBC_PARAMS {
1354
+  /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for
1355
+   * v2.0 */
1356
+  CK_ULONG      ulEffectiveBits;  /* effective bits (1-1024) */
1357
+
1358
+  CK_BYTE       iv[8];            /* IV for CBC mode */
1359
+} CK_RC2_CBC_PARAMS;
1360
+
1361
+typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR;
1362
+
1363
+
1364
+/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the
1365
+ * CKM_RC2_MAC_GENERAL mechanism */
1366
+/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */
1367
+typedef struct CK_RC2_MAC_GENERAL_PARAMS {
1368
+  CK_ULONG      ulEffectiveBits;  /* effective bits (1-1024) */
1369
+  CK_ULONG      ulMacLength;      /* Length of MAC in bytes */
1370
+} CK_RC2_MAC_GENERAL_PARAMS;
1371
+
1372
+typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \
1373
+  CK_RC2_MAC_GENERAL_PARAMS_PTR;
1374
+
1375
+
1376
+/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and
1377
+ * CKM_RC5_MAC mechanisms */
1378
+/* CK_RC5_PARAMS is new for v2.0 */
1379
+typedef struct CK_RC5_PARAMS {
1380
+  CK_ULONG      ulWordsize;  /* wordsize in bits */
1381
+  CK_ULONG      ulRounds;    /* number of rounds */
1382
+} CK_RC5_PARAMS;
1383
+
1384
+typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR;
1385
+
1386
+
1387
+/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC
1388
+ * mechanism */
1389
+/* CK_RC5_CBC_PARAMS is new for v2.0 */
1390
+typedef struct CK_RC5_CBC_PARAMS {
1391
+  CK_ULONG      ulWordsize;  /* wordsize in bits */
1392
+  CK_ULONG      ulRounds;    /* number of rounds */
1393
+  CK_BYTE_PTR   pIv;         /* pointer to IV */
1394
+  CK_ULONG      ulIvLen;     /* length of IV in bytes */
1395
+} CK_RC5_CBC_PARAMS;
1396
+
1397
+typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR;
1398
+
1399
+
1400
+/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the
1401
+ * CKM_RC5_MAC_GENERAL mechanism */
1402
+/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */
1403
+typedef struct CK_RC5_MAC_GENERAL_PARAMS {
1404
+  CK_ULONG      ulWordsize;   /* wordsize in bits */
1405
+  CK_ULONG      ulRounds;     /* number of rounds */
1406
+  CK_ULONG      ulMacLength;  /* Length of MAC in bytes */
1407
+} CK_RC5_MAC_GENERAL_PARAMS;
1408
+
1409
+typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \
1410
+  CK_RC5_MAC_GENERAL_PARAMS_PTR;
1411
+
1412
+
1413
+/* CK_MAC_GENERAL_PARAMS provides the parameters to most block
1414
+ * ciphers' MAC_GENERAL mechanisms.  Its value is the length of
1415
+ * the MAC */
1416
+/* CK_MAC_GENERAL_PARAMS is new for v2.0 */
1417
+typedef CK_ULONG          CK_MAC_GENERAL_PARAMS;
1418
+
1419
+typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
1420
+
1421
+/* CK_DES/AES_ECB/CBC_ENCRYPT_DATA_PARAMS are new for v2.20 */
1422
+typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS {
1423
+  CK_BYTE      iv[8];
1424
+  CK_BYTE_PTR  pData;
1425
+  CK_ULONG     length;
1426
+} CK_DES_CBC_ENCRYPT_DATA_PARAMS;
1427
+
1428
+typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR;
1429
+
1430
+typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS {
1431
+  CK_BYTE      iv[16];
1432
+  CK_BYTE_PTR  pData;
1433
+  CK_ULONG     length;
1434
+} CK_AES_CBC_ENCRYPT_DATA_PARAMS;
1435
+
1436
+typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR;
1437
+
1438
+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
1439
+ * CKM_SKIPJACK_PRIVATE_WRAP mechanism */
1440
+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */
1441
+typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS {
1442
+  CK_ULONG      ulPasswordLen;
1443
+  CK_BYTE_PTR   pPassword;
1444
+  CK_ULONG      ulPublicDataLen;
1445
+  CK_BYTE_PTR   pPublicData;
1446
+  CK_ULONG      ulPAndGLen;
1447
+  CK_ULONG      ulQLen;
1448
+  CK_ULONG      ulRandomLen;
1449
+  CK_BYTE_PTR   pRandomA;
1450
+  CK_BYTE_PTR   pPrimeP;
1451
+  CK_BYTE_PTR   pBaseG;
1452
+  CK_BYTE_PTR   pSubprimeQ;
1453
+} CK_SKIPJACK_PRIVATE_WRAP_PARAMS;
1454
+
1455
+typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \
1456
+  CK_SKIPJACK_PRIVATE_WRAP_PTR;
1457
+
1458
+
1459
+/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the
1460
+ * CKM_SKIPJACK_RELAYX mechanism */
1461
+/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */
1462
+typedef struct CK_SKIPJACK_RELAYX_PARAMS {
1463
+  CK_ULONG      ulOldWrappedXLen;
1464
+  CK_BYTE_PTR   pOldWrappedX;
1465
+  CK_ULONG      ulOldPasswordLen;
1466
+  CK_BYTE_PTR   pOldPassword;
1467
+  CK_ULONG      ulOldPublicDataLen;
1468
+  CK_BYTE_PTR   pOldPublicData;
1469
+  CK_ULONG      ulOldRandomLen;
1470
+  CK_BYTE_PTR   pOldRandomA;
1471
+  CK_ULONG      ulNewPasswordLen;
1472
+  CK_BYTE_PTR   pNewPassword;
1473
+  CK_ULONG      ulNewPublicDataLen;
1474
+  CK_BYTE_PTR   pNewPublicData;
1475
+  CK_ULONG      ulNewRandomLen;
1476
+  CK_BYTE_PTR   pNewRandomA;
1477
+} CK_SKIPJACK_RELAYX_PARAMS;
1478
+
1479
+typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \
1480
+  CK_SKIPJACK_RELAYX_PARAMS_PTR;
1481
+
1482
+
1483
+typedef struct CK_PBE_PARAMS {
1484
+  CK_BYTE_PTR      pInitVector;
1485
+  CK_UTF8CHAR_PTR  pPassword;
1486
+  CK_ULONG         ulPasswordLen;
1487
+  CK_BYTE_PTR      pSalt;
1488
+  CK_ULONG         ulSaltLen;
1489
+  CK_ULONG         ulIteration;
1490
+} CK_PBE_PARAMS;
1491
+
1492
+typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
1493
+
1494
+
1495
+/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the
1496
+ * CKM_KEY_WRAP_SET_OAEP mechanism */
1497
+/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */
1498
+typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS {
1499
+  CK_BYTE       bBC;     /* block contents byte */
1500
+  CK_BYTE_PTR   pX;      /* extra data */
1501
+  CK_ULONG      ulXLen;  /* length of extra data in bytes */
1502
+} CK_KEY_WRAP_SET_OAEP_PARAMS;
1503
+
1504
+typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \
1505
+  CK_KEY_WRAP_SET_OAEP_PARAMS_PTR;
1506
+
1507
+
1508
+typedef struct CK_SSL3_RANDOM_DATA {
1509
+  CK_BYTE_PTR  pClientRandom;
1510
+  CK_ULONG     ulClientRandomLen;
1511
+  CK_BYTE_PTR  pServerRandom;
1512
+  CK_ULONG     ulServerRandomLen;
1513
+} CK_SSL3_RANDOM_DATA;
1514
+
1515
+
1516
+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
1517
+  CK_SSL3_RANDOM_DATA RandomInfo;
1518
+  CK_VERSION_PTR pVersion;
1519
+} CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
1520
+
1521
+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \
1522
+  CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR;
1523
+
1524
+
1525
+typedef struct CK_SSL3_KEY_MAT_OUT {
1526
+  CK_OBJECT_HANDLE hClientMacSecret;
1527
+  CK_OBJECT_HANDLE hServerMacSecret;
1528
+  CK_OBJECT_HANDLE hClientKey;
1529
+  CK_OBJECT_HANDLE hServerKey;
1530
+  CK_BYTE_PTR      pIVClient;
1531
+  CK_BYTE_PTR      pIVServer;
1532
+} CK_SSL3_KEY_MAT_OUT;
1533
+
1534
+typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR;
1535
+
1536
+
1537
+typedef struct CK_SSL3_KEY_MAT_PARAMS {
1538
+  CK_ULONG                ulMacSizeInBits;
1539
+  CK_ULONG                ulKeySizeInBits;
1540
+  CK_ULONG                ulIVSizeInBits;
1541
+  CK_BBOOL                bIsExport;
1542
+  CK_SSL3_RANDOM_DATA     RandomInfo;
1543
+  CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
1544
+} CK_SSL3_KEY_MAT_PARAMS;
1545
+
1546
+typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
1547
+
1548
+/* CK_TLS_PRF_PARAMS is new for version 2.20 */
1549
+typedef struct CK_TLS_PRF_PARAMS {
1550
+  CK_BYTE_PTR  pSeed;
1551
+  CK_ULONG     ulSeedLen;
1552
+  CK_BYTE_PTR  pLabel;
1553
+  CK_ULONG     ulLabelLen;
1554
+  CK_BYTE_PTR  pOutput;
1555
+  CK_ULONG_PTR pulOutputLen;
1556
+} CK_TLS_PRF_PARAMS;
1557
+
1558
+typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR;
1559
+
1560
+/* WTLS is new for version 2.20 */
1561
+typedef struct CK_WTLS_RANDOM_DATA {
1562
+  CK_BYTE_PTR pClientRandom;
1563
+  CK_ULONG    ulClientRandomLen;
1564
+  CK_BYTE_PTR pServerRandom;
1565
+  CK_ULONG    ulServerRandomLen;
1566
+} CK_WTLS_RANDOM_DATA;
1567
+
1568
+typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR;
1569
+
1570
+typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS {
1571
+  CK_MECHANISM_TYPE   DigestMechanism;
1572
+  CK_WTLS_RANDOM_DATA RandomInfo;
1573
+  CK_BYTE_PTR         pVersion;
1574
+} CK_WTLS_MASTER_KEY_DERIVE_PARAMS;
1575
+
1576
+typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \
1577
+  CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR;
1578
+
1579
+typedef struct CK_WTLS_PRF_PARAMS {
1580
+  CK_MECHANISM_TYPE DigestMechanism;
1581
+  CK_BYTE_PTR       pSeed;
1582
+  CK_ULONG          ulSeedLen;
1583
+  CK_BYTE_PTR       pLabel;
1584
+  CK_ULONG          ulLabelLen;
1585
+  CK_BYTE_PTR       pOutput;
1586
+  CK_ULONG_PTR      pulOutputLen;
1587
+} CK_WTLS_PRF_PARAMS;
1588
+
1589
+typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR;
1590
+
1591
+typedef struct CK_WTLS_KEY_MAT_OUT {
1592
+  CK_OBJECT_HANDLE hMacSecret;
1593
+  CK_OBJECT_HANDLE hKey;
1594
+  CK_BYTE_PTR      pIV;
1595
+} CK_WTLS_KEY_MAT_OUT;
1596
+
1597
+typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR;
1598
+
1599
+typedef struct CK_WTLS_KEY_MAT_PARAMS {
1600
+  CK_MECHANISM_TYPE       DigestMechanism;
1601
+  CK_ULONG                ulMacSizeInBits;
1602
+  CK_ULONG                ulKeySizeInBits;
1603
+  CK_ULONG                ulIVSizeInBits;
1604
+  CK_ULONG                ulSequenceNumber;
1605
+  CK_BBOOL                bIsExport;
1606
+  CK_WTLS_RANDOM_DATA     RandomInfo;
1607
+  CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
1608
+} CK_WTLS_KEY_MAT_PARAMS;
1609
+
1610
+typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR;
1611
+
1612
+/* CMS is new for version 2.20 */
1613
+typedef struct CK_CMS_SIG_PARAMS {
1614
+  CK_OBJECT_HANDLE      certificateHandle;
1615
+  CK_MECHANISM_PTR      pSigningMechanism;
1616
+  CK_MECHANISM_PTR      pDigestMechanism;
1617
+  CK_UTF8CHAR_PTR       pContentType;
1618
+  CK_BYTE_PTR           pRequestedAttributes;
1619
+  CK_ULONG              ulRequestedAttributesLen;
1620
+  CK_BYTE_PTR           pRequiredAttributes;
1621
+  CK_ULONG              ulRequiredAttributesLen;
1622
+} CK_CMS_SIG_PARAMS;
1623
+
1624
+typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR;
1625
+
1626
+typedef struct CK_KEY_DERIVATION_STRING_DATA {
1627
+  CK_BYTE_PTR pData;
1628
+  CK_ULONG    ulLen;
1629
+} CK_KEY_DERIVATION_STRING_DATA;
1630
+
1631
+typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \
1632
+  CK_KEY_DERIVATION_STRING_DATA_PTR;
1633
+
1634
+
1635
+/* The CK_EXTRACT_PARAMS is used for the
1636
+ * CKM_EXTRACT_KEY_FROM_KEY mechanism.  It specifies which bit
1637
+ * of the base key should be used as the first bit of the
1638
+ * derived key */
1639
+/* CK_EXTRACT_PARAMS is new for v2.0 */
1640
+typedef CK_ULONG CK_EXTRACT_PARAMS;
1641
+
1642
+typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
1643
+
1644
+/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is new for v2.10.
1645
+ * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to
1646
+ * indicate the Pseudo-Random Function (PRF) used to generate
1647
+ * key bits using PKCS #5 PBKDF2. */
1648
+typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE;
1649
+
1650
+typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR;
1651
+
1652
+/* The following PRFs are defined in PKCS #5 v2.0. */
1653
+#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001
1654
+
1655
+
1656
+/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is new for v2.10.
1657
+ * CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the
1658
+ * source of the salt value when deriving a key using PKCS #5
1659
+ * PBKDF2. */
1660
+typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE;
1661
+
1662
+typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR;
1663
+
1664
+/* The following salt value sources are defined in PKCS #5 v2.0. */
1665
+#define CKZ_SALT_SPECIFIED        0x00000001
1666
+
1667
+/* CK_PKCS5_PBKD2_PARAMS is new for v2.10.
1668
+ * CK_PKCS5_PBKD2_PARAMS is a structure that provides the
1669
+ * parameters to the CKM_PKCS5_PBKD2 mechanism. */
1670
+typedef struct CK_PKCS5_PBKD2_PARAMS {
1671
+        CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE           saltSource;
1672
+        CK_VOID_PTR                                pSaltSourceData;
1673
+        CK_ULONG                                   ulSaltSourceDataLen;
1674
+        CK_ULONG                                   iterations;
1675
+        CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
1676
+        CK_VOID_PTR                                pPrfData;
1677
+        CK_ULONG                                   ulPrfDataLen;
1678
+        CK_UTF8CHAR_PTR                            pPassword;
1679
+        CK_ULONG_PTR                               ulPasswordLen;
1680
+} CK_PKCS5_PBKD2_PARAMS;
1681
+
1682
+typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
1683
+
1684
+#endif
... ...
@@ -52,6 +52,7 @@
52 52
 #include "perf.h"
53 53
 #include "status.h"
54 54
 #include "gremlin.h"
55
+#include "pkcs11.h"
55 56
 
56 57
 #ifdef WIN32
57 58
 #include "cryptoapi.h"
... ...
@@ -847,6 +848,26 @@ init_ssl (const struct options *options)
847 847
     {
848 848
       /* Use seperate PEM files for key, cert and CA certs */
849 849
 
850
+#ifdef ENABLE_PKCS11
851
+      if (options->pkcs11_providers[0])
852
+       {
853
+	char password[256];
854
+	password[0] = '\0';
855
+	if (
856
+		!options->pkcs11_protected_authentication &&
857
+		options->key_pass_file
858
+	) {
859
+	  pem_password_callback (password, sizeof(password) - 1, 0, NULL);
860
+	}
861
+
862
+        /* Load Certificate and Private Key */
863
+	if (!SSL_CTX_use_pkcs11 (ctx, options->pkcs11_slot_type, options->pkcs11_slot, options->pkcs11_id_type, options->pkcs11_id, password, options->pkcs11_protected_authentication))
864
+	  msg (M_SSLERR, "Cannot load certificate \"%s:%s\" from slot \"%s:%s\" using PKCS#11 interface",
865
+               options->pkcs11_id_type, options->pkcs11_id, options->pkcs11_slot_type, options->pkcs11_slot);
866
+       }
867
+      else
868
+#endif
869
+
850 870
 #ifdef WIN32
851 871
       if (options->cryptoapi_cert)
852 872
 	{