]> git.wh0rd.org - patches.git/blame - openssh-4.4p1pkcs11-0.17.patch
initial import
[patches.git] / openssh-4.4p1pkcs11-0.17.patch
CommitLineData
5e993f12 1diff -urNp openssh-4.4p1/authfd.c openssh-4.4p1+pkcs11-0.17/authfd.c
2--- openssh-4.4p1/authfd.c 2006-09-01 08:38:36.000000000 +0300
3+++ openssh-4.4p1+pkcs11-0.17/authfd.c 2006-10-12 13:59:59.000000000 +0200
4@@ -669,3 +669,79 @@ decode_reply(int type)
5 /* NOTREACHED */
6 return 0;
7 }
8+
9+#ifndef SSH_PKCS11_DISABLED
10+
11+int
12+ssh_pkcs11_add_provider (AuthenticationConnection *auth, const char *provider,
13+ int protected_authentication, const char *sign_mode, int cert_private)
14+{
15+ Buffer msg;
16+ int type;
17+ int code;
18+
19+ code = SSH_AGENTC_PKCS11_ADD_PROVIDER;
20+
21+ buffer_init(&msg);
22+ buffer_put_char(&msg, code);
23+ buffer_put_cstring(&msg, provider);
24+ buffer_put_int(&msg, protected_authentication);
25+ buffer_put_cstring(&msg, sign_mode == NULL ? "auto" : sign_mode);
26+ buffer_put_int(&msg, cert_private);
27+
28+ if (ssh_request_reply(auth, &msg, &msg) == 0) {
29+ buffer_free(&msg);
30+ return 0;
31+ }
32+ type = buffer_get_char(&msg);
33+ buffer_free(&msg);
34+ return decode_reply(type);
35+}
36+
37+int
38+ssh_pkcs11_id (AuthenticationConnection *auth, const pkcs11_identity *id, int remove)
39+{
40+ Buffer msg;
41+ int type;
42+ int code;
43+
44+ code = remove ? SSH_AGENTC_PKCS11_REMOVE_ID : SSH_AGENTC_PKCS11_ADD_ID;
45+
46+ buffer_init(&msg);
47+ buffer_put_char(&msg, code);
48+ buffer_put_cstring(&msg, id->id);
49+ buffer_put_int(&msg, id->pin_cache_period);
50+ buffer_put_cstring(&msg, id->cert_file == NULL ? "" : id->cert_file);
51+
52+ if (ssh_request_reply(auth, &msg, &msg) == 0) {
53+ buffer_free(&msg);
54+ return 0;
55+ }
56+ type = buffer_get_char(&msg);
57+ buffer_free(&msg);
58+ return decode_reply(type);
59+}
60+
61+int
62+ssh_pkcs11_set_ask_pin (AuthenticationConnection *auth, const char *pin_prog)
63+{
64+ Buffer msg;
65+ int type;
66+ int code;
67+
68+ code = SSH_AGENTC_PKCS11_SET_ASK_PIN;
69+
70+ buffer_init(&msg);
71+ buffer_put_char(&msg, code);
72+ buffer_put_cstring(&msg, pin_prog);
73+
74+ if (ssh_request_reply(auth, &msg, &msg) == 0) {
75+ buffer_free(&msg);
76+ return 0;
77+ }
78+ type = buffer_get_char(&msg);
79+ buffer_free(&msg);
80+ return decode_reply(type);
81+}
82+
83+#endif /* SSH_PKCS11_DISABLED */
84diff -urNp openssh-4.4p1/authfd.h openssh-4.4p1+pkcs11-0.17/authfd.h
85--- openssh-4.4p1/authfd.h 2006-08-05 05:39:39.000000000 +0300
86+++ openssh-4.4p1+pkcs11-0.17/authfd.h 2006-10-12 13:57:49.000000000 +0200
87@@ -16,6 +16,8 @@
88 #ifndef AUTHFD_H
89 #define AUTHFD_H
90
91+#include "pkcs11.h"
92+
93 /* Messages for the authentication agent connection. */
94 #define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1
95 #define SSH_AGENT_RSA_IDENTITIES_ANSWER 2
96@@ -49,6 +51,11 @@
97 #define SSH2_AGENTC_ADD_ID_CONSTRAINED 25
98 #define SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED 26
99
100+#define SSH_AGENTC_PKCS11_ADD_PROVIDER 27
101+#define SSH_AGENTC_PKCS11_ADD_ID 28
102+#define SSH_AGENTC_PKCS11_REMOVE_ID 29
103+#define SSH_AGENTC_PKCS11_SET_ASK_PIN 30
104+
105 #define SSH_AGENT_CONSTRAIN_LIFETIME 1
106 #define SSH_AGENT_CONSTRAIN_CONFIRM 2
107
108@@ -92,4 +99,11 @@ int
109 ssh_agent_sign(AuthenticationConnection *, Key *, u_char **, u_int *, u_char *,
110 u_int);
111
112+#ifndef SSH_PKCS11_DISABLED
113+int ssh_pkcs11_add_provider (AuthenticationConnection *, const char *,
114+ int, const char *, int);
115+int ssh_pkcs11_id (AuthenticationConnection *, const pkcs11_identity *, int remove);
116+int ssh_pkcs11_set_ask_pin (AuthenticationConnection *, const char *);
117+#endif /* SSH_PKCS11_DISABLED */
118+
119 #endif /* AUTHFD_H */
120diff -urNp openssh-4.4p1/ChangeLog.pkcs11 openssh-4.4p1+pkcs11-0.17/ChangeLog.pkcs11
121--- openssh-4.4p1/ChangeLog.pkcs11 1970-01-01 02:00:00.000000000 +0200
122+++ openssh-4.4p1+pkcs11-0.17/ChangeLog.pkcs11 2006-10-23 17:36:52.000000000 +0200
123@@ -0,0 +1,49 @@
124+20061023
125+ - (alonbl) Removed logit from ssh-agent, thanks to Denniston, Todd.
126+ - (alonbl) Release 0.17
127+
128+20061020
129+ - (alonbl) Major modification of ssh-add command-line parameters.
130+ Now, a complete serialized certificate needs to be specified, this
131+ in order to allow people to add id without forcing card to be available.
132+ But to allow complete silent addition a certificate file also needed.
133+ --pkcs11-show-ids is used in order to get a list of resources.
134+ --pkcs11-add-id --pkcs11-id <serialized id> \
135+ [--pkcs11-cert-file <cert_file>]
136+ - (alonbl) PKCS#11 release 0.16
137+
138+20061012
139+ - (alonbl) OpenSC bug workaround.
140+ - (alonbl) PKCS#11 release 0.15
141+
142+20060930
143+ - (alonbl) Some pkcs11-helper updates.
144+ - (alonbl) Rebase against 4.4p1.
145+ - (alonbl) PKCS#11 release 0.14
146+
147+20060709
148+ - (alonbl) PKCS#11 fixed handling multiproviders.
149+ - (alonbl) PKCS#11 release 0.13
150+
151+20060608
152+ - (alonbl) PKCS#11 modifed to match X.509-5.5 patch, works OK with focing
153+ ssh-rsa id.
154+ - (alonbl) PKCS#11 removed --pkcs11-x509-force-ssh argument.
155+ - (alonbl) PKCS#11 release 0.12
156+
157+20060527
158+ - (alonbl) PKCS#11 fix issues with gcc-2
159+ - (alonbl) PKCS#11 fix issues with openssl-0.9.6 (first) version.
160+ - (alonbl) PKCS#11 modified to match X.509-5.4 patch.
161+ - (alonbl) PKCS#11 add --pkcs11-x509-force-ssh argument to force ssh id out
162+ of X.509 certificate.
163+ - (alonbl) PKCS#11 release 0.11
164+
165+20060419
166+ - (alonbl) PKCS#11 fix handling empty attributes.
167+ - (alonbl) PKCS#11 release 0.10
168+
169+20060404
170+ - (alonbl) PKCS#11 code sync.
171+ - (alonbl) PKCS#11 release 0.09
172+
173diff -urNp openssh-4.4p1/config.h.in openssh-4.4p1+pkcs11-0.17/config.h.in
174--- openssh-4.4p1/config.h.in 2006-09-26 14:03:33.000000000 +0300
175+++ openssh-4.4p1+pkcs11-0.17/config.h.in 2006-09-28 16:31:03.000000000 +0300
176@@ -1217,6 +1217,12 @@
177 /* Use audit debugging module */
178 #undef SSH_AUDIT_EVENTS
179
180+/* Define if you don't want use PKCS#11 */
181+#undef SSH_PKCS11_DISABLED
182+
183+/* Define if you don't want use X509 with PKCS#11 */
184+#undef SSH_PKCS11_X509_DISABLED
185+
186 /* non-privileged user for privilege separation */
187 #undef SSH_PRIVSEP_USER
188
189diff -urNp openssh-4.4p1/configure openssh-4.4p1+pkcs11-0.17/configure
190--- openssh-4.4p1/configure 2006-09-26 14:03:41.000000000 +0300
191+++ openssh-4.4p1+pkcs11-0.17/configure 2006-09-28 16:33:53.000000000 +0300
192@@ -1307,6 +1307,7 @@ Optional Features:
193 --disable-libutil disable use of libutil (login() etc.) no
194 --disable-pututline disable use of pututline() etc. (uwtmp) no
195 --disable-pututxline disable use of pututxline() etc. (uwtmpx) no
196+ --disable-pkcs11 Disable PKCS#11 support
197
198 Optional Packages:
199 --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
200@@ -32163,6 +32164,33 @@ if test ! -z "$blibpath" ; then
201 echo "$as_me: WARNING: Please check and edit blibpath in LDFLAGS in Makefile" >&2;}
202 fi
203
204+ssh_pkcs11="yes"
205+ssh_pkcs11_x509="yes"
206+# Check whether --enable-pkcs11 was given.
207+if test "${enable_pkcs11+set}" = set; then
208+ enableval=$enable_pkcs11;
209+ if test "x$enableval" = "xno"; then
210+ ssh_pkcs11="no"
211+ fi
212+
213+
214+fi
215+
216+if test "x$ssh_pkcs11" = "xno"; then
217+
218+cat >>confdefs.h <<_ACEOF
219+#define SSH_PKCS11_DISABLED 1
220+_ACEOF
221+
222+fi
223+if test "x$ssh_x509" = "x"; then
224+
225+cat >>confdefs.h <<_ACEOF
226+#define SSH_PKCS11_X509_DISABLED 1
227+_ACEOF
228+
229+fi
230+
231 CFLAGS="$CFLAGS $werror_flags"
232
233
234@@ -33415,6 +33443,7 @@ echo " IP address in \$DISPLAY hac
235 echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG"
236 echo " BSD Auth support: $BSD_AUTH_MSG"
237 echo " Random number source: $RAND_MSG"
238+echo " PKCS#11 support: $ssh_pkcs11"
239 if test ! -z "$USE_RAND_HELPER" ; then
240 echo " ssh-rand-helper collects from: $RAND_HELPER_MSG"
241 fi
242diff -urNp openssh-4.4p1/configure.ac openssh-4.4p1+pkcs11-0.17/configure.ac
243--- openssh-4.4p1/configure.ac 2006-09-24 22:08:59.000000000 +0300
244+++ openssh-4.4p1+pkcs11-0.17/configure.ac 2006-09-28 08:05:35.000000000 +0300
245@@ -3912,6 +3912,27 @@ if test ! -z "$blibpath" ; then
246 AC_MSG_WARN([Please check and edit blibpath in LDFLAGS in Makefile])
247 fi
248
249+ssh_pkcs11="yes"
250+ssh_pkcs11_x509="yes"
251+AC_ARG_ENABLE(pkcs11,
252+ [ --disable-pkcs11 Disable PKCS#11 support],
253+ [
254+ if test "x$enableval" = "xno"; then
255+ ssh_pkcs11="no"
256+ fi
257+ ]
258+)
259+if test "x$ssh_pkcs11" = "xno"; then
260+ AC_DEFINE_UNQUOTED(
261+ SSH_PKCS11_DISABLED, 1,
262+ [Define if you don't want use PKCS#11])
263+fi
264+if test "x$ssh_x509" = "x"; then
265+ AC_DEFINE_UNQUOTED(
266+ SSH_PKCS11_X509_DISABLED, 1,
267+ [Define if you don't want use X509 with PKCS#11])
268+fi
269+
270 dnl Adding -Werror to CFLAGS early prevents configure tests from running.
271 dnl Add now.
272 CFLAGS="$CFLAGS $werror_flags"
273@@ -3973,6 +3994,7 @@ echo " IP address in \$DISPLAY hac
274 echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG"
275 echo " BSD Auth support: $BSD_AUTH_MSG"
276 echo " Random number source: $RAND_MSG"
277+echo " PKCS#11 support: $ssh_pkcs11"
278 if test ! -z "$USE_RAND_HELPER" ; then
279 echo " ssh-rand-helper collects from: $RAND_HELPER_MSG"
280 fi
281diff -urNp openssh-4.4p1/cryptoki.h openssh-4.4p1+pkcs11-0.17/cryptoki.h
282--- openssh-4.4p1/cryptoki.h 1970-01-01 02:00:00.000000000 +0200
283+++ openssh-4.4p1+pkcs11-0.17/cryptoki.h 2006-09-28 08:05:35.000000000 +0300
284@@ -0,0 +1,35 @@
285+/* cryptoki.h include file for PKCS #11. */
286+/* $Revision: 1.4 $ */
287+
288+/* License to copy and use this software is granted provided that it is
289+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
290+ * (Cryptoki)" in all material mentioning or referencing this software.
291+
292+ * License is also granted to make and use derivative works provided that
293+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
294+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
295+ * referencing the derived work.
296+
297+ * RSA Security Inc. makes no representations concerning either the
298+ * merchantability of this software or the suitability of this software for
299+ * any particular purpose. It is provided "as is" without express or implied
300+ * warranty of any kind.
301+ */
302+
303+#ifndef ___CRYPTOKI_H_INC___
304+#define ___CRYPTOKI_H_INC___
305+
306+#define CK_PTR *
307+
308+#define CK_DEFINE_FUNCTION(returnType, name) returnType name
309+#define CK_DECLARE_FUNCTION(returnType, name) returnType name
310+#define CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name)
311+#define CK_CALLBACK_FUNCTION(returnType, name) returnType (* name)
312+
313+#ifndef NULL_PTR
314+#define NULL_PTR 0
315+#endif
316+
317+#include "pkcs11-headers/pkcs11.h"
318+
319+#endif /* ___CRYPTOKI_H_INC___ */
320diff -urNp openssh-4.4p1/cryptoki-win32.h openssh-4.4p1+pkcs11-0.17/cryptoki-win32.h
321--- openssh-4.4p1/cryptoki-win32.h 1970-01-01 02:00:00.000000000 +0200
322+++ openssh-4.4p1+pkcs11-0.17/cryptoki-win32.h 2006-09-28 08:05:35.000000000 +0300
323@@ -0,0 +1,66 @@
324+/* cryptoki.h include file for PKCS #11. */
325+/* $Revision: 1.4 $ */
326+
327+/* License to copy and use this software is granted provided that it is
328+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
329+ * (Cryptoki)" in all material mentioning or referencing this software.
330+
331+ * License is also granted to make and use derivative works provided that
332+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
333+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
334+ * referencing the derived work.
335+
336+ * RSA Security Inc. makes no representations concerning either the
337+ * merchantability of this software or the suitability of this software for
338+ * any particular purpose. It is provided "as is" without express or implied
339+ * warranty of any kind.
340+ */
341+
342+/* This is a sample file containing the top level include directives
343+ * for building Win32 Cryptoki libraries and applications.
344+ */
345+
346+#ifndef ___CRYPTOKI_H_INC___
347+#define ___CRYPTOKI_H_INC___
348+
349+#pragma pack(push, cryptoki, 1)
350+
351+/* Specifies that the function is a DLL entry point. */
352+#define CK_IMPORT_SPEC __declspec(dllimport)
353+
354+/* Define CRYPTOKI_EXPORTS during the build of cryptoki libraries. Do
355+ * not define it in applications.
356+ */
357+#ifdef CRYPTOKI_EXPORTS
358+/* Specified that the function is an exported DLL entry point. */
359+#define CK_EXPORT_SPEC __declspec(dllexport)
360+#else
361+#define CK_EXPORT_SPEC CK_IMPORT_SPEC
362+#endif
363+
364+/* Ensures the calling convention for Win32 builds */
365+#define CK_CALL_SPEC __cdecl
366+
367+#define CK_PTR *
368+
369+#define CK_DEFINE_FUNCTION(returnType, name) \
370+ returnType CK_EXPORT_SPEC CK_CALL_SPEC name
371+
372+#define CK_DECLARE_FUNCTION(returnType, name) \
373+ returnType CK_EXPORT_SPEC CK_CALL_SPEC name
374+
375+#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
376+ returnType CK_IMPORT_SPEC (CK_CALL_SPEC CK_PTR name)
377+
378+#define CK_CALLBACK_FUNCTION(returnType, name) \
379+ returnType (CK_CALL_SPEC CK_PTR name)
380+
381+#ifndef NULL_PTR
382+#define NULL_PTR 0
383+#endif
384+
385+#include "pkcs11-headers/pkcs11.h"
386+
387+#pragma pack(pop, cryptoki)
388+
389+#endif /* ___CRYPTOKI_H_INC___ */
390diff -urNp openssh-4.4p1/LICENCE openssh-4.4p1+pkcs11-0.17/LICENCE
391--- openssh-4.4p1/LICENCE 2006-08-30 20:24:41.000000000 +0300
392+++ openssh-4.4p1+pkcs11-0.17/LICENCE 2006-09-28 08:05:35.000000000 +0300
393@@ -332,6 +332,9 @@ OpenSSH contains no GPL code.
394 * authorization. *
395 ****************************************************************************/
396
397+ d) PKCS #11: Cryptographic Token Interface Standard
398+
399+ This software uses RSA Security Inc. PKCS #11 Cryptographic Token Interface (Cryptoki).
400
401 ------
402 $OpenBSD: LICENCE,v 1.19 2004/08/30 09:18:08 markus Exp $
403diff -urNp openssh-4.4p1/Makefile.in openssh-4.4p1+pkcs11-0.17/Makefile.in
404--- openssh-4.4p1/Makefile.in 2006-09-12 14:54:10.000000000 +0300
405+++ openssh-4.4p1+pkcs11-0.17/Makefile.in 2006-09-28 08:05:35.000000000 +0300
406@@ -66,6 +66,7 @@ TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-a
407
408 LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \
409 canohost.o channels.o cipher.o cipher-acss.o cipher-aes.o \
410+ pkcs11.o pkcs11-helper.o \
411 cipher-bf1.o cipher-ctr.o cipher-3des1.o cleanup.o \
412 compat.o compress.o crc32.o deattack.o fatal.o hostfile.o \
413 log.o match.o md-sha256.o moduli.o nchan.o packet.o \
414diff -urNp openssh-4.4p1/pkcs11.c openssh-4.4p1+pkcs11-0.17/pkcs11.c
415--- openssh-4.4p1/pkcs11.c 1970-01-01 02:00:00.000000000 +0200
416+++ openssh-4.4p1+pkcs11-0.17/pkcs11.c 2006-10-23 17:35:54.000000000 +0200
417@@ -0,0 +1,1139 @@
418+/*
419+ * Copyright (c) 2005-2006 Alon Bar-Lev. All rights reserved.
420+ *
421+ * Redistribution and use in source and binary forms, with or without
422+ * modification, are permitted provided that the following conditions
423+ * are met:
424+ * 1. Redistributions of source code must retain the above copyright
425+ * notice, this list of conditions and the following disclaimer.
426+ * 2. Redistributions in binary form must reproduce the above copyright
427+ * notice, this list of conditions and the following disclaimer in the
428+ * documentation and/or other materials provided with the distribution.
429+ *
430+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
431+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
432+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
433+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
434+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
435+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
436+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
437+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
438+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
439+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
440+ */
441+
442+/*
443+ * The routines in this file deal with providing private key cryptography
444+ * using RSA Security Inc. PKCS #11 Cryptographic Token Interface (Cryptoki).
445+ *
446+ */
447+
448+#include "includes.h"
449+#include <sys/wait.h>
450+#include <errno.h>
451+
452+#if !defined(SSH_PKCS11_DISABLED)
453+
454+#include "pkcs11-helper.h"
455+#include "pkcs11.h"
456+#include "openssl/pem.h"
457+#include "misc.h"
458+
459+static
460+char *
461+ssh_from_x509 (X509 *x509);
462+
463+static char *s_szSetPINProg = NULL;
464+
465+static
466+unsigned
467+_pkcs11_msg_pkcs112openssh (
468+ IN const unsigned flags
469+) {
470+ unsigned openssh_flags;
471+
472+ switch (flags) {
473+ case PKCS11H_LOG_DEBUG2:
474+ openssh_flags = SYSLOG_LEVEL_DEBUG3;
475+ break;
476+ case PKCS11H_LOG_DEBUG1:
477+ openssh_flags = SYSLOG_LEVEL_DEBUG2;
478+ break;
479+ case PKCS11H_LOG_INFO:
480+ openssh_flags = SYSLOG_LEVEL_INFO;
481+ break;
482+ case PKCS11H_LOG_WARN:
483+ openssh_flags = SYSLOG_LEVEL_ERROR;
484+ break;
485+ case PKCS11H_LOG_ERROR:
486+ openssh_flags = SYSLOG_LEVEL_FATAL;
487+ break;
488+ default:
489+ openssh_flags = SYSLOG_LEVEL_FATAL;
490+ break;
491+ }
492+
493+ return openssh_flags;
494+}
495+
496+static
497+unsigned
498+_pkcs11_msg_openssh2pkcs11 (
499+ IN const unsigned flags
500+) {
501+ unsigned pkcs11_flags;
502+
503+ switch (flags) {
504+ case SYSLOG_LEVEL_DEBUG3:
505+ pkcs11_flags = PKCS11H_LOG_DEBUG2;
506+ break;
507+ case SYSLOG_LEVEL_DEBUG2:
508+ pkcs11_flags = PKCS11H_LOG_DEBUG1;
509+ break;
510+ case SYSLOG_LEVEL_INFO:
511+ pkcs11_flags = PKCS11H_LOG_INFO;
512+ break;
513+ case SYSLOG_LEVEL_ERROR:
514+ pkcs11_flags = PKCS11H_LOG_WARN;
515+ break;
516+ case SYSLOG_LEVEL_FATAL:
517+ pkcs11_flags = PKCS11H_LOG_ERROR;
518+ break;
519+ default:
520+ pkcs11_flags = PKCS11H_LOG_ERROR;
521+ break;
522+ }
523+
524+ return pkcs11_flags;
525+}
526+
527+static
528+void
529+_pkcs11_openssh_log (
530+ IN void * const pData,
531+ IN unsigned flags,
532+ IN const char * const szFormat,
533+ IN va_list args
534+) {
535+ do_log (_pkcs11_msg_pkcs112openssh (flags), szFormat, args);
536+}
537+
538+static
539+int
540+_pkcs11_ssh_prompt (
541+ IN const char * const szType,
542+ IN const char * const szPrompt,
543+ OUT char * const szInput,
544+ IN const int nMaxInput
545+) {
546+ pid_t pid = -1;
547+ int fds[2] = {-1, -1};
548+ int fOK = TRUE;
549+
550+ /*
551+ * Make sure we don't reuse PIN
552+ */
553+ if (fOK) {
554+ memset (szInput, 0, nMaxInput);
555+ }
556+
557+ if (fOK && s_szSetPINProg == NULL) {
558+ fOK = FALSE;
559+ }
560+
561+ if (fOK && pipe (fds) == -1) {
562+ fOK = FALSE;
563+ }
564+
565+ if (fOK && (pid = fork ()) == -1) {
566+ fOK = FALSE;
567+ }
568+
569+ if (fOK) {
570+ if (pid == 0) {
571+ close (fds[0]);
572+ fds[0] = -1;
573+
574+ if (fOK && dup2 (fds[1], 1) == -1) {
575+ fOK = FALSE;
576+ }
577+ if (fOK) {
578+ close (fds[1]);
579+ fds[1] = -1;
580+ }
581+
582+ if (fOK) {
583+ execl (
584+ s_szSetPINProg,
585+ s_szSetPINProg,
586+ "-t",
587+ szType,
588+ szPrompt,
589+ NULL
590+ );
591+ }
592+
593+ exit (1);
594+ }
595+ else {
596+ int status;
597+ int r = 0;
598+
599+ close (fds[1]);
600+ fds[1] = -1;
601+
602+ if (fOK) {
603+ while (
604+ (r=waitpid (pid, &status, 0)) == 0 ||
605+ (r == -1 && errno == EINTR)
606+ );
607+
608+ if (r == -1) {
609+ fOK = FALSE;
610+ }
611+ }
612+
613+ if (fOK && !WIFEXITED (status)) {
614+ fOK = FALSE;
615+ }
616+
617+ if (fOK && WEXITSTATUS (status) != 0) {
618+ fOK = FALSE;
619+ }
620+
621+ if (fOK) {
622+ if (!strcmp (szType, "password")) {
623+ if ((r = read (fds[0], szInput, nMaxInput)) == -1) {
624+ fOK = FALSE;
625+ r = 0;
626+ }
627+ }
628+ else {
629+ r = 0;
630+ }
631+ szInput[r] = '\0';
632+ }
633+
634+ if (fOK) {
635+ if (strlen (szInput) > 0 && szInput[strlen (szInput)-1] == '\n') {
636+ szInput[strlen (szInput)-1] = '\0';
637+ }
638+ /*
639+ * for DOS compatability
640+ */
641+ if (strlen (szInput) > 0 && szInput[strlen (szInput)-1] == '\r') {
642+ szInput[strlen (szInput)-1] = '\0';
643+ }
644+ }
645+ }
646+ }
647+
648+ if (fds[0] != -1) {
649+ close (fds[0]);
650+ fds[0] = -1;
651+ }
652+
653+ if (fds[1] != -1) {
654+ close (fds[1]);
655+ fds[1] = -1;
656+ }
657+
658+ return fOK;
659+}
660+
661+static
662+void
663+_pkcs11_ssh_print (
664+ IN void * const pData,
665+ IN const char * const szFormat,
666+ IN ...
667+) {
668+ va_list args;
669+
670+ va_start (args, szFormat);
671+ vprintf (szFormat, args);
672+ va_end (args);
673+}
674+
675+static
676+PKCS11H_BOOL
677+_pkcs11_ssh_token_prompt (
678+ IN void * const pData1,
679+ IN void * const pData2,
680+ IN const pkcs11h_token_id_t token,
681+ IN const unsigned retry
682+) {
683+ char szPrompt[1024];
684+ char szPIN[1024];
685+
686+ snprintf (szPrompt, sizeof (szPrompt), "Please insert token '%s' or cancel", token->display);
687+ return _pkcs11_ssh_prompt ("okcancel", szPrompt, szPIN, sizeof (szPIN));
688+}
689+
690+static
691+PKCS11H_BOOL
692+_pkcs11_ssh_pin_prompt (
693+ IN void * const pData1,
694+ IN void * const pData2,
695+ IN const pkcs11h_token_id_t token,
696+ IN const unsigned retry,
697+ OUT char * const szPIN,
698+ IN const size_t nMaxPIN
699+) {
700+ char szPrompt[1024];
701+
702+ snprintf (szPrompt, sizeof (szPrompt), "Please enter PIN for token '%s'", token->display);
703+ return _pkcs11_ssh_prompt ("password", szPrompt, szPIN, nMaxPIN);
704+}
705+
706+static
707+PKCS11H_BOOL
708+_pkcs11_ssh_pin_prompt_cli (
709+ IN void * const pData1,
710+ IN void * const pData2,
711+ IN const pkcs11h_token_id_t token,
712+ IN const unsigned retry,
713+ OUT char * const szPIN,
714+ IN const size_t nMaxPIN
715+) {
716+ char szPrompt[1024];
717+ snprintf (szPrompt, sizeof (szPrompt), "Please enter '%s' PIN or 'cancel': ", token->display);
718+ char *p = getpass (szPrompt);
719+
720+ strncpy (szPIN, p, nMaxPIN);
721+ szPIN[nMaxPIN-1] = '\0';
722+
723+ return strcmp (szPIN, "cancel") != 0;
724+}
725+
726+void
727+_pkcs11_do_log (
728+ IN LogLevel l,
729+ IN const char *f,
730+ IN ...
731+) {
732+ va_list args;
733+ va_start (args, f);
734+ do_log (l, f, args);
735+ va_end (args);
736+}
737+
738+int
739+pkcs11_initialize (
740+ const int fProtectedAuthentication,
741+ const int nPINCachePeriod
742+) {
743+ CK_RV rv = CKR_OK;
744+
745+ debug3 (
746+ "PKCS#11: pkcs11_initialize - entered fProtectedAuthentication=%d, nPINCachePeriod=%d",
747+ fProtectedAuthentication,
748+ nPINCachePeriod
749+ );
750+
751+ if (
752+ rv == CKR_OK &&
753+ (rv = pkcs11h_initialize ()) != CKR_OK
754+ ) {
755+ error ("PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage (rv));
756+ }
757+
758+ if (
759+ rv == CKR_OK &&
760+ (rv = pkcs11h_setLogHook (_pkcs11_openssh_log, NULL)) != CKR_OK
761+ ) {
762+ error ("PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv));
763+ }
764+
765+ /*
766+ * WARNING!!!
767+ * There is no way to get log level,
768+ * so set to minimum.
769+ * After fix in log.c it can be fixed.
770+ */
771+ if (rv == CKR_OK) {
772+ pkcs11h_setLogLevel (_pkcs11_msg_openssh2pkcs11 (SYSLOG_LEVEL_DEBUG3));
773+ }
774+
775+ if (
776+ rv == CKR_OK &&
777+ (rv = pkcs11h_setTokenPromptHook (_pkcs11_ssh_token_prompt, NULL)) != CKR_OK
778+ ) {
779+ error ("PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv));
780+ }
781+
782+ if (
783+ rv == CKR_OK &&
784+ (rv = pkcs11h_setPINPromptHook (_pkcs11_ssh_pin_prompt, NULL)) != CKR_OK
785+ ) {
786+ error ("PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv));
787+ }
788+
789+ if (
790+ rv == CKR_OK &&
791+ (rv = pkcs11h_setProtectedAuthentication (fProtectedAuthentication)) != CKR_OK
792+ ) {
793+ error ("PKCS#11: Cannot set protected authentication mode %ld-'%s'", rv, pkcs11h_getMessage (rv));
794+ }
795+
796+ if (
797+ rv == CKR_OK &&
798+ (rv = pkcs11h_setPINCachePeriod (nPINCachePeriod)) != CKR_OK
799+ ) {
800+ error ("PKCS#11: Cannot set PIN cache period %ld-'%s'", rv, pkcs11h_getMessage (rv));
801+ }
802+
803+ debug3 (
804+ "PKCS#11: pkcs11_initialize - return rv=%ld-'%s'",
805+ rv,
806+ pkcs11h_getMessage (rv)
807+ );
808+
809+ return rv == CKR_OK;
810+}
811+
812+void
813+pkcs11_terminate () {
814+ debug3 ("PKCS#11: pkcs11_terminate - entered");
815+
816+ pkcs11h_terminate ();
817+
818+ debug3 ("PKCS#11: pkcs11_terminate - return");
819+}
820+
821+void
822+pkcs11_forkFix () {
823+ pkcs11h_forkFixup ();
824+}
825+
826+int
827+pkcs11_setAskPIN (
828+ const char * const pin_prog
829+) {
830+ if (pin_prog != NULL) {
831+ if (s_szSetPINProg != NULL) {
832+ xfree (s_szSetPINProg);
833+ s_szSetPINProg = NULL;
834+ }
835+
836+ s_szSetPINProg = xstrdup (pin_prog);
837+ }
838+
839+ return 1;
840+}
841+
842+int
843+pkcs11_addProvider (
844+ const char * const provider,
845+ const int fProtectedAuthentication,
846+ const char * const sign_mode,
847+ const int fCertIsPrivate
848+) {
849+ unsigned maskSignMode = 0;
850+ CK_RV rv = CKR_OK;
851+
852+ PKCS11H_ASSERT (provider != NULL);
853+ PKCS11H_ASSERT (sign_mode != NULL);
854+
855+ debug3 (
856+ "PKCS#11: pkcs11_addProvider - entered - provider='%s', fProtectedAuthentication=%d, sign_mode='%s', fCertIsPrivate=%d",
857+ provider,
858+ fProtectedAuthentication ? 1 : 0,
859+ sign_mode == NULL ? "default" : sign_mode,
860+ fCertIsPrivate ? 1 : 0
861+ );
862+
863+ debug (
864+ "PKCS#11: Adding PKCS#11 provider '%s'",
865+ provider
866+ );
867+
868+ if (rv == CKR_OK) {
869+ if (sign_mode == NULL || !strcmp (sign_mode, "auto")) {
870+ maskSignMode = 0;
871+ }
872+ else if (!strcmp (sign_mode, "sign")) {
873+ maskSignMode = PKCS11H_SIGNMODE_MASK_SIGN;
874+ }
875+ else if (!strcmp (sign_mode, "recover")) {
876+ maskSignMode = PKCS11H_SIGNMODE_MASK_RECOVER;
877+ }
878+ else if (!strcmp (sign_mode, "any")) {
879+ maskSignMode = (
880+ PKCS11H_SIGNMODE_MASK_SIGN |
881+ PKCS11H_SIGNMODE_MASK_RECOVER
882+ );
883+ }
884+ else {
885+ error ("PKCS#11: Invalid sign mode '%s'", sign_mode);
886+ rv = CKR_ARGUMENTS_BAD;
887+ }
888+ }
889+
890+ if (
891+ rv == CKR_OK &&
892+ (rv = pkcs11h_addProvider (
893+ provider,
894+ provider,
895+ fProtectedAuthentication,
896+ maskSignMode,
897+ PKCS11H_SLOTEVENT_METHOD_AUTO,
898+ 0,
899+ fCertIsPrivate
900+ )) != CKR_OK
901+ ) {
902+ error ("PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv, pkcs11h_getMessage (rv));
903+ }
904+
905+ debug3 (
906+ "PKCS#11: pkcs11_addProvider - return rv=%ld-'%s'",
907+ rv,
908+ pkcs11h_getMessage (rv)
909+ );
910+
911+ return rv == CKR_OK;
912+}
913+
914+pkcs11_identity *
915+pkcs11_identity_new () {
916+ pkcs11_identity *id = xmalloc (sizeof (struct pkcs11_identity_s));
917+ if (id != NULL) {
918+ memset (id, 0, sizeof (struct pkcs11_identity_s));
919+ }
920+ return id;
921+}
922+
923+void
924+pkcs11_identity_free (
925+ const pkcs11_identity * const id
926+) {
927+ if (id != NULL) {
928+ xfree ((void *)id);
929+ }
930+}
931+
932+void
933+pkcs11_getKey (
934+ IN const pkcs11_identity * const id,
935+ OUT Key ** const sshkey,
936+ OUT char * const szComment,
937+ IN const int nCommentMax
938+) {
939+ X509 *x509 = NULL;
940+ RSA *rsa = NULL;
941+ pkcs11h_certificate_id_t certificate_id = NULL;
942+ pkcs11h_certificate_t certificate = NULL;
943+ pkcs11h_openssl_session_t openssl_session = NULL;
944+ size_t temp;
945+ CK_RV rv = CKR_OK;
946+
947+ int fOK = TRUE;
948+
949+ debug3 (
950+ "PKCS#11: pkcs11_getKey - entered - id=%p, sshkey=%p, szComment=%p, nCommentMax=%d",
951+ (void *)id,
952+ (void *)sshkey,
953+ (void *)szComment,
954+ nCommentMax
955+ );
956+
957+ PKCS11H_ASSERT (id != NULL);
958+ PKCS11H_ASSERT (sshkey!=NULL);
959+ PKCS11H_ASSERT (szComment!=NULL);
960+
961+ debug3 (
962+ "PKCS#11: pkcs11_getKey - id - id=%s, pin_cache_period=%d, cert_file=%s",
963+ id->id,
964+ id->pin_cache_period,
965+ id->cert_file
966+ );
967+
968+ PKCS11H_ASSERT (id->id);
969+
970+ if (
971+ fOK &&
972+ pkcs11h_certificate_deserializeCertificateId (&certificate_id, id->id)
973+ ) {
974+ fOK = FALSE;
975+ error ("PKCS#11: Cannot deserialize id %ld-'%s'", rv, pkcs11h_getMessage (rv));
976+ }
977+
978+ if (
979+ fOK &&
980+ id->cert_file != NULL &&
981+ id->cert_file[0] != '\x0'
982+ ) {
983+ X509 *x509 = NULL;
984+ unsigned char *p = NULL;
985+ unsigned char *certificate_blob = NULL;
986+ size_t certificate_blob_size = 0;
987+ FILE *fp = NULL;
988+
989+ if (
990+ fOK &&
991+ (fp = fopen (id->cert_file, "r")) == NULL
992+ ) {
993+ fOK = FALSE;
994+ error ("PKCS#11: Cannot open file '%s'", id->cert_file);
995+ }
996+
997+ if (
998+ fOK &&
999+ !PEM_read_X509 (
1000+ fp,
1001+ &x509,
1002+ NULL,
1003+ 0
1004+ )
1005+ ) {
1006+ x509 = NULL;
1007+ fOK = FALSE;
1008+ error ("PKCS#11: Cannot read PEM from file '%s'", id->cert_file);
1009+ }
1010+
1011+ if (
1012+ fOK &&
1013+ (certificate_blob_size = i2d_X509 (x509, NULL)) < 0
1014+ ) {
1015+ fOK = FALSE;
1016+ error ("PKCS#11: Cannot read decode certificate");
1017+ }
1018+
1019+ if (
1020+ fOK &&
1021+ (certificate_blob = (unsigned char *)xmalloc (certificate_blob_size)) == NULL
1022+ ) {
1023+ fOK = FALSE;
1024+ error ("PKCS#11: Cannot allocate memory");
1025+ }
1026+
1027+ /*
1028+ * i2d_X509 increments p!!!
1029+ */
1030+ p = certificate_blob;
1031+
1032+ if (
1033+ fOK &&
1034+ (certificate_blob_size = i2d_X509 (x509, &p)) < 0
1035+ ) {
1036+ fOK = FALSE;
1037+ error ("PKCS#11: Cannot read decode certificate");
1038+ }
1039+
1040+ if (
1041+ fOK &&
1042+ pkcs11h_certificate_setCertificateIdCertificateBlob (
1043+ certificate_id,
1044+ certificate_blob,
1045+ certificate_blob_size
1046+ ) != CKR_OK
1047+ ) {
1048+ fOK = FALSE;
1049+ error ("PKCS#11: Cannot set certificate blob %ld-'%s'", rv, pkcs11h_getMessage (rv));
1050+ }
1051+
1052+ if (x509 != NULL) {
1053+ X509_free (x509);
1054+ x509 = NULL;
1055+ }
1056+
1057+ if (certificate_blob != NULL) {
1058+ xfree (certificate_blob);
1059+ certificate_blob = NULL;
1060+ }
1061+
1062+ if (fp != NULL) {
1063+ fclose (fp);
1064+ fp = NULL;
1065+ }
1066+ }
1067+
1068+ if (
1069+ fOK &&
1070+ (rv = pkcs11h_certificate_create (
1071+ certificate_id,
1072+ NULL,
1073+ PKCS11H_PROMPT_MASK_ALLOW_ALL,
1074+ id->pin_cache_period,
1075+ &certificate
1076+ )) != CKR_OK
1077+ ) {
1078+ fOK = FALSE;
1079+ error ("PKCS#11: Cannot get certificate %ld-'%s'", rv, pkcs11h_getMessage (rv));
1080+ }
1081+
1082+ if (certificate_id != NULL){
1083+ pkcs11h_certificate_freeCertificateId (certificate_id);
1084+ certificate_id = NULL;
1085+ }
1086+
1087+ /*
1088+ * Is called so next certificate_id will
1089+ * contain a proper description
1090+ */
1091+ if (
1092+ fOK &&
1093+ (rv = pkcs11h_certificate_getCertificateBlob (
1094+ certificate,
1095+ NULL,
1096+ &temp
1097+ )) != CKR_OK
1098+ ) {
1099+ fOK = FALSE;
1100+ error ("PKCS#11: Cannot get certificate blob %ld-'%s'", rv, pkcs11h_getMessage (rv));
1101+ }
1102+
1103+ if (
1104+ fOK &&
1105+ (rv = pkcs11h_certificate_getCertificateId (
1106+ certificate,
1107+ &certificate_id
1108+ )) != CKR_OK
1109+ ) {
1110+ fOK = FALSE;
1111+ error ("PKCS#11: Cannot get certificate_id %ld-'%s'", rv, pkcs11h_getMessage (rv));
1112+ }
1113+
1114+ if (fOK) {
1115+ strncpy (szComment, certificate_id->displayName, nCommentMax);
1116+ szComment[nCommentMax - 1] = '\0';
1117+ }
1118+
1119+ if (
1120+ fOK &&
1121+ (openssl_session = pkcs11h_openssl_createSession (certificate)) == NULL
1122+ ) {
1123+ fOK = FALSE;
1124+ error ("PKCS#11: Cannot initialize openssl session");
1125+ }
1126+
1127+ if (fOK) {
1128+ /*
1129+ * will be release by openssl_session
1130+ */
1131+ certificate = NULL;
1132+ }
1133+
1134+ if (
1135+ fOK &&
1136+ (rsa = pkcs11h_openssl_session_getRSA (openssl_session)) == NULL
1137+ ) {
1138+ fOK = FALSE;
1139+ error ("PKCS#11: Unable get rsa object");
1140+ }
1141+
1142+ if (
1143+ fOK &&
1144+ (x509 = pkcs11h_openssl_session_getX509 (openssl_session)) == NULL
1145+ ) {
1146+ fOK = FALSE;
1147+ error ("PKCS#11: Unable get certificate object");
1148+ }
1149+
1150+ if (fOK) {
1151+ *sshkey = key_new_private (KEY_UNSPEC);
1152+ (*sshkey)->rsa = rsa;
1153+ rsa = NULL;
1154+#if defined(SSH_PKCS11_X509_DISABLED)
1155+ (*sshkey)->type = KEY_RSA;
1156+#else
1157+ (*sshkey)->type = KEY_X509_RSA;
1158+ (*sshkey)->x509 = x509;
1159+ x509 = NULL;
1160+#endif
1161+ }
1162+
1163+ if (x509 != NULL) {
1164+ X509_free (x509);
1165+ x509 = NULL;
1166+ }
1167+
1168+ if (openssl_session != NULL) {
1169+ pkcs11h_openssl_freeSession (openssl_session);
1170+ openssl_session = NULL;
1171+ }
1172+
1173+ if (certificate != NULL) {
1174+ pkcs11h_certificate_freeCertificate (certificate);
1175+ certificate = NULL;
1176+ }
1177+
1178+ if (certificate_id != NULL) {
1179+ pkcs11h_certificate_freeCertificateId (certificate_id);
1180+ certificate_id = NULL;
1181+ }
1182+
1183+ debug3 (
1184+ "PKCS#11: pkcs11_getKey - return fOK=%d, rv=%ld",
1185+ fOK ? 1 : 0,
1186+ rv
1187+ );
1188+}
1189+
1190+void
1191+pkcs11_show_ids (
1192+ const char * const provider,
1193+ int allow_protected_auth,
1194+ int cert_is_private
1195+) {
1196+ pkcs11h_certificate_id_list_t user_certificates = NULL;
1197+ pkcs11h_certificate_id_list_t current = NULL;
1198+ CK_RV rv = CKR_OK;
1199+
1200+ if (rv == CKR_OK) {
1201+ rv = pkcs11h_initialize ();
1202+ }
1203+
1204+ if (rv == CKR_OK) {
1205+ rv = pkcs11h_setLogHook (_pkcs11_openssh_log, NULL);
1206+ }
1207+
1208+ if (rv == CKR_OK) {
1209+ pkcs11h_setLogLevel (_pkcs11_msg_openssh2pkcs11 (SYSLOG_LEVEL_DEBUG3));
1210+ }
1211+
1212+ if (rv == CKR_OK) {
1213+ rv = pkcs11h_setPINPromptHook (_pkcs11_ssh_pin_prompt_cli, NULL);
1214+ }
1215+
1216+ if (rv == CKR_OK) {
1217+ rv = pkcs11h_setProtectedAuthentication (TRUE);
1218+ }
1219+
1220+ if (rv == CKR_OK) {
1221+ rv = pkcs11h_addProvider (
1222+ provider,
1223+ provider,
1224+ allow_protected_auth ? TRUE : FALSE,
1225+ 0,
1226+ FALSE,
1227+ 0,
1228+ cert_is_private ? TRUE : FALSE
1229+ );
1230+ }
1231+
1232+ if (rv == CKR_OK) {
1233+ rv = pkcs11h_certificate_enumCertificateIds (
1234+ PKCS11H_ENUM_METHOD_CACHE_EXIST,
1235+ NULL,
1236+ PKCS11H_PROMPT_MASK_ALLOW_ALL,
1237+ NULL,
1238+ &user_certificates
1239+ );
1240+ }
1241+
1242+ for (current = user_certificates; rv == CKR_OK && current != NULL; current = current->next) {
1243+ pkcs11h_certificate_t certificate = NULL;
1244+ X509 *x509 = NULL;
1245+ char dn[1024] = {0};
1246+ char *ser = NULL;
1247+ char *ssh_key = NULL;
1248+ size_t ser_len = 0;
1249+
1250+ if (rv == CKR_OK) {
1251+ rv = pkcs11h_certificate_serializeCertificateId (NULL, &ser_len, current->certificate_id);
1252+ }
1253+
1254+ if (
1255+ rv == CKR_OK &&
1256+ (ser = (char *)xmalloc (ser_len)) == NULL
1257+ ) {
1258+ rv = CKR_HOST_MEMORY;
1259+ }
1260+
1261+ if (rv == CKR_OK) {
1262+ rv = pkcs11h_certificate_serializeCertificateId (ser, &ser_len, current->certificate_id);
1263+ }
1264+
1265+ if (rv == CKR_OK) {
1266+ rv = pkcs11h_certificate_create (
1267+ current->certificate_id,
1268+ NULL,
1269+ PKCS11H_PROMPT_MASK_ALLOW_ALL,
1270+ PKCS11H_PIN_CACHE_INFINITE,
1271+ &certificate
1272+ );
1273+ }
1274+
1275+ if (
1276+ rv == CKR_OK &&
1277+ (x509 = pkcs11h_openssl_getX509 (certificate)) == NULL
1278+ ) {
1279+ rv = CKR_FUNCTION_FAILED;
1280+ }
1281+
1282+ if (rv == CKR_OK) {
1283+ X509_NAME_oneline (
1284+ X509_get_subject_name (x509),
1285+ dn,
1286+ sizeof (dn)
1287+ );
1288+ printf (
1289+ (
1290+ "\n"
1291+ "********************************************\n"
1292+ "IDENTITY:\n"
1293+ " DN: %s\n"
1294+ " Serialized id: %s\n"
1295+ "\n"
1296+ " Certificate:\n"
1297+ ),
1298+ dn,
1299+ ser
1300+ );
1301+ PEM_write_X509 (stdout, x509);
1302+ }
1303+
1304+ if (
1305+ rv == CKR_OK &&
1306+ (ssh_key = ssh_from_x509 (x509)) != NULL
1307+ ) {
1308+ printf (
1309+ (
1310+ "\n"
1311+ " SSH:\n"
1312+ "%s\n"
1313+ ),
1314+ ssh_key
1315+ );
1316+
1317+ xfree (ssh_key);
1318+ }
1319+
1320+ if (x509 != NULL) {
1321+ X509_free (x509);
1322+ x509 = NULL;
1323+ }
1324+
1325+ if (certificate != NULL) {
1326+ pkcs11h_certificate_freeCertificate (certificate);
1327+ certificate = NULL;
1328+ }
1329+
1330+ if (ser != NULL) {
1331+ xfree (ser);
1332+ ser = NULL;
1333+ }
1334+
1335+ /*
1336+ * Ignore error
1337+ */
1338+ if (rv != CKR_OK) {
1339+ error ("PKCS#11: Failed to get id %ld-'%s'", rv, pkcs11h_getMessage (rv));
1340+ rv = CKR_OK;
1341+ }
1342+ }
1343+
1344+ if (user_certificates != NULL) {
1345+ pkcs11h_certificate_freeCertificateIdList (user_certificates);
1346+ user_certificates = NULL;
1347+ }
1348+
1349+ pkcs11h_terminate ();
1350+}
1351+
1352+void
1353+pkcs11_dump_slots (
1354+ const char * const provider
1355+) {
1356+ pkcs11h_standalone_dump_slots (
1357+ _pkcs11_ssh_print,
1358+ NULL,
1359+ provider
1360+ );
1361+}
1362+
1363+void
1364+pkcs11_dump_objects (
1365+ const char * const provider,
1366+ const char * const slot,
1367+ const char * const pin
1368+) {
1369+ pkcs11h_standalone_dump_objects (
1370+ _pkcs11_ssh_print,
1371+ NULL,
1372+ provider,
1373+ slot,
1374+ pin
1375+ );
1376+}
1377+
1378+/*
1379+ * The ssh_from_x509 is dirived of Tatu and Markus work.
1380+ *
1381+ * Copyright (c) 2006 Alon bar-Lev <alon.barlev@gmail.com>. All rights reserved.
1382+ * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
1383+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
1384+ */
1385+
1386+#define PUT_32BIT(cp, value) ( \
1387+ (cp)[0] = (value) >> 24, \
1388+ (cp)[1] = (value) >> 16, \
1389+ (cp)[2] = (value) >> 8, \
1390+ (cp)[3] = (value) )
1391+
1392+static
1393+char *
1394+ssh_from_x509 (X509 *x509) {
1395+
1396+ EVP_PKEY *pubkey = NULL;
1397+ BIO *bio = NULL, *bio2 = NULL, *bio64 = NULL;
1398+ unsigned char *blob = NULL, *buffer = NULL;
1399+ char *ret = NULL;
1400+ int blobsize = 0, retsize = 0;
1401+ int bytes_name = 0, bytes_exponent = 0, bytes_modulus = 0;
1402+ unsigned char *bp;
1403+ char *p;
1404+ int n;
1405+ const char *keyname = NULL;
1406+ int ok = 1;
1407+
1408+ if (ok && (pubkey = X509_get_pubkey (x509)) == NULL) {
1409+ ok = 0;
1410+ }
1411+
1412+ if (ok && (bio64 = BIO_new (BIO_f_base64 ())) == NULL) {
1413+ ok = 0;
1414+ }
1415+
1416+ if (ok && (bio = BIO_new (BIO_s_mem ())) == NULL) {
1417+ ok = 0;
1418+ }
1419+
1420+ if (ok && (bio2 = BIO_push (bio64, bio)) == NULL) {
1421+ ok = 0;
1422+ }
1423+
1424+ if (ok && pubkey->type != EVP_PKEY_RSA) {
1425+ ok = 0;
1426+ }
1427+
1428+ if (ok) {
1429+ keyname = "ssh-rsa";
1430+ }
1431+
1432+ if (ok) {
1433+ bytes_name = strlen (keyname);
1434+ bytes_exponent = BN_num_bytes (pubkey->pkey.rsa->e);
1435+ bytes_modulus = BN_num_bytes (pubkey->pkey.rsa->n);
1436+
1437+ blobsize = (
1438+ 4 + bytes_name +
1439+ 4 + (bytes_exponent + 1) +
1440+ 4 + (bytes_modulus + 1) +
1441+ 1
1442+ );
1443+ }
1444+
1445+ if (ok && (blob = (unsigned char *)xmalloc (blobsize)) == NULL) {
1446+ ok = 0;
1447+ }
1448+
1449+ if (ok && (buffer = (unsigned char *)xmalloc (blobsize)) == NULL) {
1450+ ok = 0;
1451+ }
1452+
1453+ if (ok) {
1454+ bp = blob;
1455+
1456+ PUT_32BIT (bp, bytes_name), bp += 4;
1457+ memcpy (bp, keyname, bytes_name), bp += bytes_name;
1458+
1459+ BN_bn2bin (pubkey->pkey.rsa->e, buffer);
1460+ if (buffer[0] & 0x80) {
1461+ // highest bit set would indicate a negative number.
1462+ // to avoid this, we have to spend an extra byte:
1463+ PUT_32BIT (bp, bytes_exponent+1), bp += 4;
1464+ *(bp++) = 0;
1465+ } else {
1466+ PUT_32BIT (bp, bytes_exponent), bp += 4;
1467+ }
1468+ memcpy (bp, buffer, bytes_exponent), bp += bytes_exponent;
1469+
1470+ BN_bn2bin (pubkey->pkey.rsa->n, buffer);
1471+ if (buffer[0] & 0x80) {
1472+ PUT_32BIT (bp, bytes_modulus+1), bp += 4;
1473+ *(bp++) = 0;
1474+ } else {
1475+ PUT_32BIT( bp, bytes_modulus ), bp += 4;
1476+ }
1477+ memcpy (bp, buffer, bytes_modulus), bp += bytes_modulus;
1478+ }
1479+
1480+
1481+ if (ok && BIO_write (bio2, blob, bp-blob) == -1) {
1482+ ok = 0;
1483+ }
1484+
1485+ if (ok && BIO_flush (bio2) == -1) {
1486+ ok = 0;
1487+ }
1488+
1489+ /*
1490+ * Allocate the newline too... We will remove them later
1491+ * For MS, allocate return as well.
1492+ */
1493+ if (ok) {
1494+ retsize = strlen (keyname) + 1 + (blobsize * 4 / 3) + (blobsize * 2 / 50) + 10 + 1;
1495+ }
1496+
1497+ if (ok && (ret = xmalloc (retsize)) == NULL) {
1498+ ok = 0;
1499+ }
1500+
1501+ if (ok) {
1502+ strcpy (ret, keyname);
1503+ strcat (ret, " ");
1504+ }
1505+
1506+ if (ok && (n = BIO_read (bio, ret + strlen (ret), retsize - strlen (ret) - 1)) == -1) {
1507+ ok = 0;
1508+ }
1509+
1510+ if (ok) {
1511+ ret[strlen (keyname) + 1 + n] = '\x0';
1512+ }
1513+
1514+ if (ok) {
1515+ while ((p = strchr (ret, '\n')) != NULL) {
1516+ memmove (p, p+1, strlen (p)+1);
1517+ }
1518+ while ((p = strchr (ret, '\r')) != NULL) {
1519+ memmove (p, p+1, strlen (p)+1);
1520+ }
1521+
1522+ }
1523+
1524+ if (bio != NULL) {
1525+ BIO_free_all (bio);
1526+ bio = NULL;
1527+ }
1528+
1529+ if (pubkey != NULL) {
1530+ EVP_PKEY_free (pubkey);
1531+ pubkey = NULL;
1532+ }
1533+
1534+ if (buffer != NULL) {
1535+ xfree (buffer);
1536+ buffer = NULL;
1537+ }
1538+
1539+ if (blob != NULL) {
1540+ xfree (blob);
1541+ blob = NULL;
1542+ }
1543+
1544+ if (!ok) {
1545+ if (ret != NULL) {
1546+ xfree (ret);
1547+ ret = NULL;
1548+ }
1549+ }
1550+
1551+ return ret;
1552+}
1553+
1554+#else
1555+static void dummy (void) {}
1556+#endif /* SSH_PKCS11_DISABLED */
1557diff -urNp openssh-4.4p1/pkcs11.h openssh-4.4p1+pkcs11-0.17/pkcs11.h
1558--- openssh-4.4p1/pkcs11.h 1970-01-01 02:00:00.000000000 +0200
1559+++ openssh-4.4p1+pkcs11-0.17/pkcs11.h 2006-10-12 13:55:28.000000000 +0200
1560@@ -0,0 +1,100 @@
1561+/*
1562+ * Copyright (c) 2005-2006 Alon Bar-Lev. All rights reserved.
1563+ *
1564+ * Redistribution and use in source and binary forms, with or without
1565+ * modification, are permitted provided that the following conditions
1566+ * are met:
1567+ * 1. Redistributions of source code must retain the above copyright
1568+ * notice, this list of conditions and the following disclaimer.
1569+ * 2. Redistributions in binary form must reproduce the above copyright
1570+ * notice, this list of conditions and the following disclaimer in the
1571+ * documentation and/or other materials provided with the distribution.
1572+ *
1573+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1574+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1575+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1576+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1577+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1578+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1579+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1580+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1581+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
1582+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1583+ */
1584+
1585+#ifndef SSH_PKCS11_H
1586+#define SSH_PKCS11_H
1587+
1588+#if !defined(SSH_PKCS11_DISABLED)
1589+
1590+#include "key.h"
1591+
1592+typedef struct pkcs11_identity_s {
1593+ char *id;
1594+ int pin_cache_period;
1595+ char *cert_file;
1596+} pkcs11_identity;
1597+
1598+int
1599+pkcs11_initialize (
1600+ const int fProtectedAuthentication,
1601+ const int nPINCachePeriod
1602+);
1603+
1604+void
1605+pkcs11_terminate ();
1606+
1607+void
1608+pkcs11_forkFix ();
1609+
1610+int
1611+pkcs11_setAskPIN (
1612+ const char * const pin_prog
1613+);
1614+
1615+int
1616+pkcs11_addProvider (
1617+ const char * const provider,
1618+ const int fProtectedAuthentication,
1619+ const char * const sign_mode,
1620+ const int fCertIsPrivate
1621+);
1622+
1623+pkcs11_identity *
1624+pkcs11_identity_new ();
1625+
1626+void
1627+pkcs11_identity_free (
1628+ const pkcs11_identity * const id
1629+);
1630+
1631+void
1632+pkcs11_getKey (
1633+ const pkcs11_identity * const id,
1634+ Key ** const sshkey,
1635+ char * const szComment,
1636+ const int nCommentMax
1637+);
1638+
1639+void
1640+pkcs11_show_ids (
1641+ const char * const provider,
1642+ int allow_protected_auth,
1643+ int cert_is_private
1644+);
1645+
1646+void
1647+pkcs11_dump_slots (
1648+ const char * const provider
1649+);
1650+
1651+void
1652+pkcs11_dump_objects (
1653+ const char * const provider,
1654+ const char * const slot,
1655+ const char * const pin
1656+);
1657+
1658+#endif /* SSH_PKCS11_DISABLED */
1659+
1660+#endif /* OPENSSH_PKCS11_H */
1661diff -urNp openssh-4.4p1/pkcs11-headers/pkcs11f.h openssh-4.4p1+pkcs11-0.17/pkcs11-headers/pkcs11f.h
1662--- openssh-4.4p1/pkcs11-headers/pkcs11f.h 1970-01-01 02:00:00.000000000 +0200
1663+++ openssh-4.4p1+pkcs11-0.17/pkcs11-headers/pkcs11f.h 2006-09-28 08:05:35.000000000 +0300
1664@@ -0,0 +1,912 @@
1665+/* pkcs11f.h include file for PKCS #11. */
1666+/* $Revision: 1.4 $ */
1667+
1668+/* License to copy and use this software is granted provided that it is
1669+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
1670+ * (Cryptoki)" in all material mentioning or referencing this software.
1671+
1672+ * License is also granted to make and use derivative works provided that
1673+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
1674+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
1675+ * referencing the derived work.
1676+
1677+ * RSA Security Inc. makes no representations concerning either the
1678+ * merchantability of this software or the suitability of this software for
1679+ * any particular purpose. It is provided "as is" without express or implied
1680+ * warranty of any kind.
1681+ */
1682+
1683+/* This header file contains pretty much everything about all the */
1684+/* Cryptoki function prototypes. Because this information is */
1685+/* used for more than just declaring function prototypes, the */
1686+/* order of the functions appearing herein is important, and */
1687+/* should not be altered. */
1688+
1689+/* General-purpose */
1690+
1691+/* C_Initialize initializes the Cryptoki library. */
1692+CK_PKCS11_FUNCTION_INFO(C_Initialize)
1693+#ifdef CK_NEED_ARG_LIST
1694+(
1695+ CK_VOID_PTR pInitArgs /* if this is not NULL_PTR, it gets
1696+ * cast to CK_C_INITIALIZE_ARGS_PTR
1697+ * and dereferenced */
1698+);
1699+#endif
1700+
1701+
1702+/* C_Finalize indicates that an application is done with the
1703+ * Cryptoki library. */
1704+CK_PKCS11_FUNCTION_INFO(C_Finalize)
1705+#ifdef CK_NEED_ARG_LIST
1706+(
1707+ CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */
1708+);
1709+#endif
1710+
1711+
1712+/* C_GetInfo returns general information about Cryptoki. */
1713+CK_PKCS11_FUNCTION_INFO(C_GetInfo)
1714+#ifdef CK_NEED_ARG_LIST
1715+(
1716+ CK_INFO_PTR pInfo /* location that receives information */
1717+);
1718+#endif
1719+
1720+
1721+/* C_GetFunctionList returns the function list. */
1722+CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
1723+#ifdef CK_NEED_ARG_LIST
1724+(
1725+ CK_FUNCTION_LIST_PTR_PTR ppFunctionList /* receives pointer to
1726+ * function list */
1727+);
1728+#endif
1729+
1730+
1731+
1732+/* Slot and token management */
1733+
1734+/* C_GetSlotList obtains a list of slots in the system. */
1735+CK_PKCS11_FUNCTION_INFO(C_GetSlotList)
1736+#ifdef CK_NEED_ARG_LIST
1737+(
1738+ CK_BBOOL tokenPresent, /* only slots with tokens? */
1739+ CK_SLOT_ID_PTR pSlotList, /* receives array of slot IDs */
1740+ CK_ULONG_PTR pulCount /* receives number of slots */
1741+);
1742+#endif
1743+
1744+
1745+/* C_GetSlotInfo obtains information about a particular slot in
1746+ * the system. */
1747+CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
1748+#ifdef CK_NEED_ARG_LIST
1749+(
1750+ CK_SLOT_ID slotID, /* the ID of the slot */
1751+ CK_SLOT_INFO_PTR pInfo /* receives the slot information */
1752+);
1753+#endif
1754+
1755+
1756+/* C_GetTokenInfo obtains information about a particular token
1757+ * in the system. */
1758+CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo)
1759+#ifdef CK_NEED_ARG_LIST
1760+(
1761+ CK_SLOT_ID slotID, /* ID of the token's slot */
1762+ CK_TOKEN_INFO_PTR pInfo /* receives the token information */
1763+);
1764+#endif
1765+
1766+
1767+/* C_GetMechanismList obtains a list of mechanism types
1768+ * supported by a token. */
1769+CK_PKCS11_FUNCTION_INFO(C_GetMechanismList)
1770+#ifdef CK_NEED_ARG_LIST
1771+(
1772+ CK_SLOT_ID slotID, /* ID of token's slot */
1773+ CK_MECHANISM_TYPE_PTR pMechanismList, /* gets mech. array */
1774+ CK_ULONG_PTR pulCount /* gets # of mechs. */
1775+);
1776+#endif
1777+
1778+
1779+/* C_GetMechanismInfo obtains information about a particular
1780+ * mechanism possibly supported by a token. */
1781+CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
1782+#ifdef CK_NEED_ARG_LIST
1783+(
1784+ CK_SLOT_ID slotID, /* ID of the token's slot */
1785+ CK_MECHANISM_TYPE type, /* type of mechanism */
1786+ CK_MECHANISM_INFO_PTR pInfo /* receives mechanism info */
1787+);
1788+#endif
1789+
1790+
1791+/* C_InitToken initializes a token. */
1792+CK_PKCS11_FUNCTION_INFO(C_InitToken)
1793+#ifdef CK_NEED_ARG_LIST
1794+/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */
1795+(
1796+ CK_SLOT_ID slotID, /* ID of the token's slot */
1797+ CK_UTF8CHAR_PTR pPin, /* the SO's initial PIN */
1798+ CK_ULONG ulPinLen, /* length in bytes of the PIN */
1799+ CK_UTF8CHAR_PTR pLabel /* 32-byte token label (blank padded) */
1800+);
1801+#endif
1802+
1803+
1804+/* C_InitPIN initializes the normal user's PIN. */
1805+CK_PKCS11_FUNCTION_INFO(C_InitPIN)
1806+#ifdef CK_NEED_ARG_LIST
1807+(
1808+ CK_SESSION_HANDLE hSession, /* the session's handle */
1809+ CK_UTF8CHAR_PTR pPin, /* the normal user's PIN */
1810+ CK_ULONG ulPinLen /* length in bytes of the PIN */
1811+);
1812+#endif
1813+
1814+
1815+/* C_SetPIN modifies the PIN of the user who is logged in. */
1816+CK_PKCS11_FUNCTION_INFO(C_SetPIN)
1817+#ifdef CK_NEED_ARG_LIST
1818+(
1819+ CK_SESSION_HANDLE hSession, /* the session's handle */
1820+ CK_UTF8CHAR_PTR pOldPin, /* the old PIN */
1821+ CK_ULONG ulOldLen, /* length of the old PIN */
1822+ CK_UTF8CHAR_PTR pNewPin, /* the new PIN */
1823+ CK_ULONG ulNewLen /* length of the new PIN */
1824+);
1825+#endif
1826+
1827+
1828+
1829+/* Session management */
1830+
1831+/* C_OpenSession opens a session between an application and a
1832+ * token. */
1833+CK_PKCS11_FUNCTION_INFO(C_OpenSession)
1834+#ifdef CK_NEED_ARG_LIST
1835+(
1836+ CK_SLOT_ID slotID, /* the slot's ID */
1837+ CK_FLAGS flags, /* from CK_SESSION_INFO */
1838+ CK_VOID_PTR pApplication, /* passed to callback */
1839+ CK_NOTIFY Notify, /* callback function */
1840+ CK_SESSION_HANDLE_PTR phSession /* gets session handle */
1841+);
1842+#endif
1843+
1844+
1845+/* C_CloseSession closes a session between an application and a
1846+ * token. */
1847+CK_PKCS11_FUNCTION_INFO(C_CloseSession)
1848+#ifdef CK_NEED_ARG_LIST
1849+(
1850+ CK_SESSION_HANDLE hSession /* the session's handle */
1851+);
1852+#endif
1853+
1854+
1855+/* C_CloseAllSessions closes all sessions with a token. */
1856+CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions)
1857+#ifdef CK_NEED_ARG_LIST
1858+(
1859+ CK_SLOT_ID slotID /* the token's slot */
1860+);
1861+#endif
1862+
1863+
1864+/* C_GetSessionInfo obtains information about the session. */
1865+CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo)
1866+#ifdef CK_NEED_ARG_LIST
1867+(
1868+ CK_SESSION_HANDLE hSession, /* the session's handle */
1869+ CK_SESSION_INFO_PTR pInfo /* receives session info */
1870+);
1871+#endif
1872+
1873+
1874+/* C_GetOperationState obtains the state of the cryptographic operation
1875+ * in a session. */
1876+CK_PKCS11_FUNCTION_INFO(C_GetOperationState)
1877+#ifdef CK_NEED_ARG_LIST
1878+(
1879+ CK_SESSION_HANDLE hSession, /* session's handle */
1880+ CK_BYTE_PTR pOperationState, /* gets state */
1881+ CK_ULONG_PTR pulOperationStateLen /* gets state length */
1882+);
1883+#endif
1884+
1885+
1886+/* C_SetOperationState restores the state of the cryptographic
1887+ * operation in a session. */
1888+CK_PKCS11_FUNCTION_INFO(C_SetOperationState)
1889+#ifdef CK_NEED_ARG_LIST
1890+(
1891+ CK_SESSION_HANDLE hSession, /* session's handle */
1892+ CK_BYTE_PTR pOperationState, /* holds state */
1893+ CK_ULONG ulOperationStateLen, /* holds state length */
1894+ CK_OBJECT_HANDLE hEncryptionKey, /* en/decryption key */
1895+ CK_OBJECT_HANDLE hAuthenticationKey /* sign/verify key */
1896+);
1897+#endif
1898+
1899+
1900+/* C_Login logs a user into a token. */
1901+CK_PKCS11_FUNCTION_INFO(C_Login)
1902+#ifdef CK_NEED_ARG_LIST
1903+(
1904+ CK_SESSION_HANDLE hSession, /* the session's handle */
1905+ CK_USER_TYPE userType, /* the user type */
1906+ CK_UTF8CHAR_PTR pPin, /* the user's PIN */
1907+ CK_ULONG ulPinLen /* the length of the PIN */
1908+);
1909+#endif
1910+
1911+
1912+/* C_Logout logs a user out from a token. */
1913+CK_PKCS11_FUNCTION_INFO(C_Logout)
1914+#ifdef CK_NEED_ARG_LIST
1915+(
1916+ CK_SESSION_HANDLE hSession /* the session's handle */
1917+);
1918+#endif
1919+
1920+
1921+
1922+/* Object management */
1923+
1924+/* C_CreateObject creates a new object. */
1925+CK_PKCS11_FUNCTION_INFO(C_CreateObject)
1926+#ifdef CK_NEED_ARG_LIST
1927+(
1928+ CK_SESSION_HANDLE hSession, /* the session's handle */
1929+ CK_ATTRIBUTE_PTR pTemplate, /* the object's template */
1930+ CK_ULONG ulCount, /* attributes in template */
1931+ CK_OBJECT_HANDLE_PTR phObject /* gets new object's handle. */
1932+);
1933+#endif
1934+
1935+
1936+/* C_CopyObject copies an object, creating a new object for the
1937+ * copy. */
1938+CK_PKCS11_FUNCTION_INFO(C_CopyObject)
1939+#ifdef CK_NEED_ARG_LIST
1940+(
1941+ CK_SESSION_HANDLE hSession, /* the session's handle */
1942+ CK_OBJECT_HANDLE hObject, /* the object's handle */
1943+ CK_ATTRIBUTE_PTR pTemplate, /* template for new object */
1944+ CK_ULONG ulCount, /* attributes in template */
1945+ CK_OBJECT_HANDLE_PTR phNewObject /* receives handle of copy */
1946+);
1947+#endif
1948+
1949+
1950+/* C_DestroyObject destroys an object. */
1951+CK_PKCS11_FUNCTION_INFO(C_DestroyObject)
1952+#ifdef CK_NEED_ARG_LIST
1953+(
1954+ CK_SESSION_HANDLE hSession, /* the session's handle */
1955+ CK_OBJECT_HANDLE hObject /* the object's handle */
1956+);
1957+#endif
1958+
1959+
1960+/* C_GetObjectSize gets the size of an object in bytes. */
1961+CK_PKCS11_FUNCTION_INFO(C_GetObjectSize)
1962+#ifdef CK_NEED_ARG_LIST
1963+(
1964+ CK_SESSION_HANDLE hSession, /* the session's handle */
1965+ CK_OBJECT_HANDLE hObject, /* the object's handle */
1966+ CK_ULONG_PTR pulSize /* receives size of object */
1967+);
1968+#endif
1969+
1970+
1971+/* C_GetAttributeValue obtains the value of one or more object
1972+ * attributes. */
1973+CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
1974+#ifdef CK_NEED_ARG_LIST
1975+(
1976+ CK_SESSION_HANDLE hSession, /* the session's handle */
1977+ CK_OBJECT_HANDLE hObject, /* the object's handle */
1978+ CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs; gets vals */
1979+ CK_ULONG ulCount /* attributes in template */
1980+);
1981+#endif
1982+
1983+
1984+/* C_SetAttributeValue modifies the value of one or more object
1985+ * attributes */
1986+CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue)
1987+#ifdef CK_NEED_ARG_LIST
1988+(
1989+ CK_SESSION_HANDLE hSession, /* the session's handle */
1990+ CK_OBJECT_HANDLE hObject, /* the object's handle */
1991+ CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs and values */
1992+ CK_ULONG ulCount /* attributes in template */
1993+);
1994+#endif
1995+
1996+
1997+/* C_FindObjectsInit initializes a search for token and session
1998+ * objects that match a template. */
1999+CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit)
2000+#ifdef CK_NEED_ARG_LIST
2001+(
2002+ CK_SESSION_HANDLE hSession, /* the session's handle */
2003+ CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */
2004+ CK_ULONG ulCount /* attrs in search template */
2005+);
2006+#endif
2007+
2008+
2009+/* C_FindObjects continues a search for token and session
2010+ * objects that match a template, obtaining additional object
2011+ * handles. */
2012+CK_PKCS11_FUNCTION_INFO(C_FindObjects)
2013+#ifdef CK_NEED_ARG_LIST
2014+(
2015+ CK_SESSION_HANDLE hSession, /* session's handle */
2016+ CK_OBJECT_HANDLE_PTR phObject, /* gets obj. handles */
2017+ CK_ULONG ulMaxObjectCount, /* max handles to get */
2018+ CK_ULONG_PTR pulObjectCount /* actual # returned */
2019+);
2020+#endif
2021+
2022+
2023+/* C_FindObjectsFinal finishes a search for token and session
2024+ * objects. */
2025+CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal)
2026+#ifdef CK_NEED_ARG_LIST
2027+(
2028+ CK_SESSION_HANDLE hSession /* the session's handle */
2029+);
2030+#endif
2031+
2032+
2033+
2034+/* Encryption and decryption */
2035+
2036+/* C_EncryptInit initializes an encryption operation. */
2037+CK_PKCS11_FUNCTION_INFO(C_EncryptInit)
2038+#ifdef CK_NEED_ARG_LIST
2039+(
2040+ CK_SESSION_HANDLE hSession, /* the session's handle */
2041+ CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */
2042+ CK_OBJECT_HANDLE hKey /* handle of encryption key */
2043+);
2044+#endif
2045+
2046+
2047+/* C_Encrypt encrypts single-part data. */
2048+CK_PKCS11_FUNCTION_INFO(C_Encrypt)
2049+#ifdef CK_NEED_ARG_LIST
2050+(
2051+ CK_SESSION_HANDLE hSession, /* session's handle */
2052+ CK_BYTE_PTR pData, /* the plaintext data */
2053+ CK_ULONG ulDataLen, /* bytes of plaintext */
2054+ CK_BYTE_PTR pEncryptedData, /* gets ciphertext */
2055+ CK_ULONG_PTR pulEncryptedDataLen /* gets c-text size */
2056+);
2057+#endif
2058+
2059+
2060+/* C_EncryptUpdate continues a multiple-part encryption
2061+ * operation. */
2062+CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate)
2063+#ifdef CK_NEED_ARG_LIST
2064+(
2065+ CK_SESSION_HANDLE hSession, /* session's handle */
2066+ CK_BYTE_PTR pPart, /* the plaintext data */
2067+ CK_ULONG ulPartLen, /* plaintext data len */
2068+ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
2069+ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text size */
2070+);
2071+#endif
2072+
2073+
2074+/* C_EncryptFinal finishes a multiple-part encryption
2075+ * operation. */
2076+CK_PKCS11_FUNCTION_INFO(C_EncryptFinal)
2077+#ifdef CK_NEED_ARG_LIST
2078+(
2079+ CK_SESSION_HANDLE hSession, /* session handle */
2080+ CK_BYTE_PTR pLastEncryptedPart, /* last c-text */
2081+ CK_ULONG_PTR pulLastEncryptedPartLen /* gets last size */
2082+);
2083+#endif
2084+
2085+
2086+/* C_DecryptInit initializes a decryption operation. */
2087+CK_PKCS11_FUNCTION_INFO(C_DecryptInit)
2088+#ifdef CK_NEED_ARG_LIST
2089+(
2090+ CK_SESSION_HANDLE hSession, /* the session's handle */
2091+ CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */
2092+ CK_OBJECT_HANDLE hKey /* handle of decryption key */
2093+);
2094+#endif
2095+
2096+
2097+/* C_Decrypt decrypts encrypted data in a single part. */
2098+CK_PKCS11_FUNCTION_INFO(C_Decrypt)
2099+#ifdef CK_NEED_ARG_LIST
2100+(
2101+ CK_SESSION_HANDLE hSession, /* session's handle */
2102+ CK_BYTE_PTR pEncryptedData, /* ciphertext */
2103+ CK_ULONG ulEncryptedDataLen, /* ciphertext length */
2104+ CK_BYTE_PTR pData, /* gets plaintext */
2105+ CK_ULONG_PTR pulDataLen /* gets p-text size */
2106+);
2107+#endif
2108+
2109+
2110+/* C_DecryptUpdate continues a multiple-part decryption
2111+ * operation. */
2112+CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate)
2113+#ifdef CK_NEED_ARG_LIST
2114+(
2115+ CK_SESSION_HANDLE hSession, /* session's handle */
2116+ CK_BYTE_PTR pEncryptedPart, /* encrypted data */
2117+ CK_ULONG ulEncryptedPartLen, /* input length */
2118+ CK_BYTE_PTR pPart, /* gets plaintext */
2119+ CK_ULONG_PTR pulPartLen /* p-text size */
2120+);
2121+#endif
2122+
2123+
2124+/* C_DecryptFinal finishes a multiple-part decryption
2125+ * operation. */
2126+CK_PKCS11_FUNCTION_INFO(C_DecryptFinal)
2127+#ifdef CK_NEED_ARG_LIST
2128+(
2129+ CK_SESSION_HANDLE hSession, /* the session's handle */
2130+ CK_BYTE_PTR pLastPart, /* gets plaintext */
2131+ CK_ULONG_PTR pulLastPartLen /* p-text size */
2132+);
2133+#endif
2134+
2135+
2136+
2137+/* Message digesting */
2138+
2139+/* C_DigestInit initializes a message-digesting operation. */
2140+CK_PKCS11_FUNCTION_INFO(C_DigestInit)
2141+#ifdef CK_NEED_ARG_LIST
2142+(
2143+ CK_SESSION_HANDLE hSession, /* the session's handle */
2144+ CK_MECHANISM_PTR pMechanism /* the digesting mechanism */
2145+);
2146+#endif
2147+
2148+
2149+/* C_Digest digests data in a single part. */
2150+CK_PKCS11_FUNCTION_INFO(C_Digest)
2151+#ifdef CK_NEED_ARG_LIST
2152+(
2153+ CK_SESSION_HANDLE hSession, /* the session's handle */
2154+ CK_BYTE_PTR pData, /* data to be digested */
2155+ CK_ULONG ulDataLen, /* bytes of data to digest */
2156+ CK_BYTE_PTR pDigest, /* gets the message digest */
2157+ CK_ULONG_PTR pulDigestLen /* gets digest length */
2158+);
2159+#endif
2160+
2161+
2162+/* C_DigestUpdate continues a multiple-part message-digesting
2163+ * operation. */
2164+CK_PKCS11_FUNCTION_INFO(C_DigestUpdate)
2165+#ifdef CK_NEED_ARG_LIST
2166+(
2167+ CK_SESSION_HANDLE hSession, /* the session's handle */
2168+ CK_BYTE_PTR pPart, /* data to be digested */
2169+ CK_ULONG ulPartLen /* bytes of data to be digested */
2170+);
2171+#endif
2172+
2173+
2174+/* C_DigestKey continues a multi-part message-digesting
2175+ * operation, by digesting the value of a secret key as part of
2176+ * the data already digested. */
2177+CK_PKCS11_FUNCTION_INFO(C_DigestKey)
2178+#ifdef CK_NEED_ARG_LIST
2179+(
2180+ CK_SESSION_HANDLE hSession, /* the session's handle */
2181+ CK_OBJECT_HANDLE hKey /* secret key to digest */
2182+);
2183+#endif
2184+
2185+
2186+/* C_DigestFinal finishes a multiple-part message-digesting
2187+ * operation. */
2188+CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
2189+#ifdef CK_NEED_ARG_LIST
2190+(
2191+ CK_SESSION_HANDLE hSession, /* the session's handle */
2192+ CK_BYTE_PTR pDigest, /* gets the message digest */
2193+ CK_ULONG_PTR pulDigestLen /* gets byte count of digest */
2194+);
2195+#endif
2196+
2197+
2198+
2199+/* Signing and MACing */
2200+
2201+/* C_SignInit initializes a signature (private key encryption)
2202+ * operation, where the signature is (will be) an appendix to
2203+ * the data, and plaintext cannot be recovered from the
2204+ *signature. */
2205+CK_PKCS11_FUNCTION_INFO(C_SignInit)
2206+#ifdef CK_NEED_ARG_LIST
2207+(
2208+ CK_SESSION_HANDLE hSession, /* the session's handle */
2209+ CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
2210+ CK_OBJECT_HANDLE hKey /* handle of signature key */
2211+);
2212+#endif
2213+
2214+
2215+/* C_Sign signs (encrypts with private key) data in a single
2216+ * part, where the signature is (will be) an appendix to the
2217+ * data, and plaintext cannot be recovered from the signature. */
2218+CK_PKCS11_FUNCTION_INFO(C_Sign)
2219+#ifdef CK_NEED_ARG_LIST
2220+(
2221+ CK_SESSION_HANDLE hSession, /* the session's handle */
2222+ CK_BYTE_PTR pData, /* the data to sign */
2223+ CK_ULONG ulDataLen, /* count of bytes to sign */
2224+ CK_BYTE_PTR pSignature, /* gets the signature */
2225+ CK_ULONG_PTR pulSignatureLen /* gets signature length */
2226+);
2227+#endif
2228+
2229+
2230+/* C_SignUpdate continues a multiple-part signature operation,
2231+ * where the signature is (will be) an appendix to the data,
2232+ * and plaintext cannot be recovered from the signature. */
2233+CK_PKCS11_FUNCTION_INFO(C_SignUpdate)
2234+#ifdef CK_NEED_ARG_LIST
2235+(
2236+ CK_SESSION_HANDLE hSession, /* the session's handle */
2237+ CK_BYTE_PTR pPart, /* the data to sign */
2238+ CK_ULONG ulPartLen /* count of bytes to sign */
2239+);
2240+#endif
2241+
2242+
2243+/* C_SignFinal finishes a multiple-part signature operation,
2244+ * returning the signature. */
2245+CK_PKCS11_FUNCTION_INFO(C_SignFinal)
2246+#ifdef CK_NEED_ARG_LIST
2247+(
2248+ CK_SESSION_HANDLE hSession, /* the session's handle */
2249+ CK_BYTE_PTR pSignature, /* gets the signature */
2250+ CK_ULONG_PTR pulSignatureLen /* gets signature length */
2251+);
2252+#endif
2253+
2254+
2255+/* C_SignRecoverInit initializes a signature operation, where
2256+ * the data can be recovered from the signature. */
2257+CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit)
2258+#ifdef CK_NEED_ARG_LIST
2259+(
2260+ CK_SESSION_HANDLE hSession, /* the session's handle */
2261+ CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
2262+ CK_OBJECT_HANDLE hKey /* handle of the signature key */
2263+);
2264+#endif
2265+
2266+
2267+/* C_SignRecover signs data in a single operation, where the
2268+ * data can be recovered from the signature. */
2269+CK_PKCS11_FUNCTION_INFO(C_SignRecover)
2270+#ifdef CK_NEED_ARG_LIST
2271+(
2272+ CK_SESSION_HANDLE hSession, /* the session's handle */
2273+ CK_BYTE_PTR pData, /* the data to sign */
2274+ CK_ULONG ulDataLen, /* count of bytes to sign */
2275+ CK_BYTE_PTR pSignature, /* gets the signature */
2276+ CK_ULONG_PTR pulSignatureLen /* gets signature length */
2277+);
2278+#endif
2279+
2280+
2281+
2282+/* Verifying signatures and MACs */
2283+
2284+/* C_VerifyInit initializes a verification operation, where the
2285+ * signature is an appendix to the data, and plaintext cannot
2286+ * cannot be recovered from the signature (e.g. DSA). */
2287+CK_PKCS11_FUNCTION_INFO(C_VerifyInit)
2288+#ifdef CK_NEED_ARG_LIST
2289+(
2290+ CK_SESSION_HANDLE hSession, /* the session's handle */
2291+ CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
2292+ CK_OBJECT_HANDLE hKey /* verification key */
2293+);
2294+#endif
2295+
2296+
2297+/* C_Verify verifies a signature in a single-part operation,
2298+ * where the signature is an appendix to the data, and plaintext
2299+ * cannot be recovered from the signature. */
2300+CK_PKCS11_FUNCTION_INFO(C_Verify)
2301+#ifdef CK_NEED_ARG_LIST
2302+(
2303+ CK_SESSION_HANDLE hSession, /* the session's handle */
2304+ CK_BYTE_PTR pData, /* signed data */
2305+ CK_ULONG ulDataLen, /* length of signed data */
2306+ CK_BYTE_PTR pSignature, /* signature */
2307+ CK_ULONG ulSignatureLen /* signature length*/
2308+);
2309+#endif
2310+
2311+
2312+/* C_VerifyUpdate continues a multiple-part verification
2313+ * operation, where the signature is an appendix to the data,
2314+ * and plaintext cannot be recovered from the signature. */
2315+CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate)
2316+#ifdef CK_NEED_ARG_LIST
2317+(
2318+ CK_SESSION_HANDLE hSession, /* the session's handle */
2319+ CK_BYTE_PTR pPart, /* signed data */
2320+ CK_ULONG ulPartLen /* length of signed data */
2321+);
2322+#endif
2323+
2324+
2325+/* C_VerifyFinal finishes a multiple-part verification
2326+ * operation, checking the signature. */
2327+CK_PKCS11_FUNCTION_INFO(C_VerifyFinal)
2328+#ifdef CK_NEED_ARG_LIST
2329+(
2330+ CK_SESSION_HANDLE hSession, /* the session's handle */
2331+ CK_BYTE_PTR pSignature, /* signature to verify */
2332+ CK_ULONG ulSignatureLen /* signature length */
2333+);
2334+#endif
2335+
2336+
2337+/* C_VerifyRecoverInit initializes a signature verification
2338+ * operation, where the data is recovered from the signature. */
2339+CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit)
2340+#ifdef CK_NEED_ARG_LIST
2341+(
2342+ CK_SESSION_HANDLE hSession, /* the session's handle */
2343+ CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
2344+ CK_OBJECT_HANDLE hKey /* verification key */
2345+);
2346+#endif
2347+
2348+
2349+/* C_VerifyRecover verifies a signature in a single-part
2350+ * operation, where the data is recovered from the signature. */
2351+CK_PKCS11_FUNCTION_INFO(C_VerifyRecover)
2352+#ifdef CK_NEED_ARG_LIST
2353+(
2354+ CK_SESSION_HANDLE hSession, /* the session's handle */
2355+ CK_BYTE_PTR pSignature, /* signature to verify */
2356+ CK_ULONG ulSignatureLen, /* signature length */
2357+ CK_BYTE_PTR pData, /* gets signed data */
2358+ CK_ULONG_PTR pulDataLen /* gets signed data len */
2359+);
2360+#endif
2361+
2362+
2363+
2364+/* Dual-function cryptographic operations */
2365+
2366+/* C_DigestEncryptUpdate continues a multiple-part digesting
2367+ * and encryption operation. */
2368+CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate)
2369+#ifdef CK_NEED_ARG_LIST
2370+(
2371+ CK_SESSION_HANDLE hSession, /* session's handle */
2372+ CK_BYTE_PTR pPart, /* the plaintext data */
2373+ CK_ULONG ulPartLen, /* plaintext length */
2374+ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
2375+ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
2376+);
2377+#endif
2378+
2379+
2380+/* C_DecryptDigestUpdate continues a multiple-part decryption and
2381+ * digesting operation. */
2382+CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate)
2383+#ifdef CK_NEED_ARG_LIST
2384+(
2385+ CK_SESSION_HANDLE hSession, /* session's handle */
2386+ CK_BYTE_PTR pEncryptedPart, /* ciphertext */
2387+ CK_ULONG ulEncryptedPartLen, /* ciphertext length */
2388+ CK_BYTE_PTR pPart, /* gets plaintext */
2389+ CK_ULONG_PTR pulPartLen /* gets plaintext len */
2390+);
2391+#endif
2392+
2393+
2394+/* C_SignEncryptUpdate continues a multiple-part signing and
2395+ * encryption operation. */
2396+CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate)
2397+#ifdef CK_NEED_ARG_LIST
2398+(
2399+ CK_SESSION_HANDLE hSession, /* session's handle */
2400+ CK_BYTE_PTR pPart, /* the plaintext data */
2401+ CK_ULONG ulPartLen, /* plaintext length */
2402+ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
2403+ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
2404+);
2405+#endif
2406+
2407+
2408+/* C_DecryptVerifyUpdate continues a multiple-part decryption and
2409+ * verify operation. */
2410+CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate)
2411+#ifdef CK_NEED_ARG_LIST
2412+(
2413+ CK_SESSION_HANDLE hSession, /* session's handle */
2414+ CK_BYTE_PTR pEncryptedPart, /* ciphertext */
2415+ CK_ULONG ulEncryptedPartLen, /* ciphertext length */
2416+ CK_BYTE_PTR pPart, /* gets plaintext */
2417+ CK_ULONG_PTR pulPartLen /* gets p-text length */
2418+);
2419+#endif
2420+
2421+
2422+
2423+/* Key management */
2424+
2425+/* C_GenerateKey generates a secret key, creating a new key
2426+ * object. */
2427+CK_PKCS11_FUNCTION_INFO(C_GenerateKey)
2428+#ifdef CK_NEED_ARG_LIST
2429+(
2430+ CK_SESSION_HANDLE hSession, /* the session's handle */
2431+ CK_MECHANISM_PTR pMechanism, /* key generation mech. */
2432+ CK_ATTRIBUTE_PTR pTemplate, /* template for new key */
2433+ CK_ULONG ulCount, /* # of attrs in template */
2434+ CK_OBJECT_HANDLE_PTR phKey /* gets handle of new key */
2435+);
2436+#endif
2437+
2438+
2439+/* C_GenerateKeyPair generates a public-key/private-key pair,
2440+ * creating new key objects. */
2441+CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair)
2442+#ifdef CK_NEED_ARG_LIST
2443+(
2444+ CK_SESSION_HANDLE hSession, /* session
2445+ * handle */
2446+ CK_MECHANISM_PTR pMechanism, /* key-gen
2447+ * mech. */
2448+ CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* template
2449+ * for pub.
2450+ * key */
2451+ CK_ULONG ulPublicKeyAttributeCount, /* # pub.
2452+ * attrs. */
2453+ CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* template
2454+ * for priv.
2455+ * key */
2456+ CK_ULONG ulPrivateKeyAttributeCount, /* # priv.
2457+ * attrs. */
2458+ CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub.
2459+ * key
2460+ * handle */
2461+ CK_OBJECT_HANDLE_PTR phPrivateKey /* gets
2462+ * priv. key
2463+ * handle */
2464+);
2465+#endif
2466+
2467+
2468+/* C_WrapKey wraps (i.e., encrypts) a key. */
2469+CK_PKCS11_FUNCTION_INFO(C_WrapKey)
2470+#ifdef CK_NEED_ARG_LIST
2471+(
2472+ CK_SESSION_HANDLE hSession, /* the session's handle */
2473+ CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */
2474+ CK_OBJECT_HANDLE hWrappingKey, /* wrapping key */
2475+ CK_OBJECT_HANDLE hKey, /* key to be wrapped */
2476+ CK_BYTE_PTR pWrappedKey, /* gets wrapped key */
2477+ CK_ULONG_PTR pulWrappedKeyLen /* gets wrapped key size */
2478+);
2479+#endif
2480+
2481+
2482+/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
2483+ * key object. */
2484+CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
2485+#ifdef CK_NEED_ARG_LIST
2486+(
2487+ CK_SESSION_HANDLE hSession, /* session's handle */
2488+ CK_MECHANISM_PTR pMechanism, /* unwrapping mech. */
2489+ CK_OBJECT_HANDLE hUnwrappingKey, /* unwrapping key */
2490+ CK_BYTE_PTR pWrappedKey, /* the wrapped key */
2491+ CK_ULONG ulWrappedKeyLen, /* wrapped key len */
2492+ CK_ATTRIBUTE_PTR pTemplate, /* new key template */
2493+ CK_ULONG ulAttributeCount, /* template length */
2494+ CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
2495+);
2496+#endif
2497+
2498+
2499+/* C_DeriveKey derives a key from a base key, creating a new key
2500+ * object. */
2501+CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
2502+#ifdef CK_NEED_ARG_LIST
2503+(
2504+ CK_SESSION_HANDLE hSession, /* session's handle */
2505+ CK_MECHANISM_PTR pMechanism, /* key deriv. mech. */
2506+ CK_OBJECT_HANDLE hBaseKey, /* base key */
2507+ CK_ATTRIBUTE_PTR pTemplate, /* new key template */
2508+ CK_ULONG ulAttributeCount, /* template length */
2509+ CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
2510+);
2511+#endif
2512+
2513+
2514+
2515+/* Random number generation */
2516+
2517+/* C_SeedRandom mixes additional seed material into the token's
2518+ * random number generator. */
2519+CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
2520+#ifdef CK_NEED_ARG_LIST
2521+(
2522+ CK_SESSION_HANDLE hSession, /* the session's handle */
2523+ CK_BYTE_PTR pSeed, /* the seed material */
2524+ CK_ULONG ulSeedLen /* length of seed material */
2525+);
2526+#endif
2527+
2528+
2529+/* C_GenerateRandom generates random data. */
2530+CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
2531+#ifdef CK_NEED_ARG_LIST
2532+(
2533+ CK_SESSION_HANDLE hSession, /* the session's handle */
2534+ CK_BYTE_PTR RandomData, /* receives the random data */
2535+ CK_ULONG ulRandomLen /* # of bytes to generate */
2536+);
2537+#endif
2538+
2539+
2540+
2541+/* Parallel function management */
2542+
2543+/* C_GetFunctionStatus is a legacy function; it obtains an
2544+ * updated status of a function running in parallel with an
2545+ * application. */
2546+CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
2547+#ifdef CK_NEED_ARG_LIST
2548+(
2549+ CK_SESSION_HANDLE hSession /* the session's handle */
2550+);
2551+#endif
2552+
2553+
2554+/* C_CancelFunction is a legacy function; it cancels a function
2555+ * running in parallel. */
2556+CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
2557+#ifdef CK_NEED_ARG_LIST
2558+(
2559+ CK_SESSION_HANDLE hSession /* the session's handle */
2560+);
2561+#endif
2562+
2563+
2564+
2565+/* Functions added in for Cryptoki Version 2.01 or later */
2566+
2567+/* C_WaitForSlotEvent waits for a slot event (token insertion,
2568+ * removal, etc.) to occur. */
2569+CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
2570+#ifdef CK_NEED_ARG_LIST
2571+(
2572+ CK_FLAGS flags, /* blocking/nonblocking flag */
2573+ CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */
2574+ CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */
2575+);
2576+#endif
2577diff -urNp openssh-4.4p1/pkcs11-headers/pkcs11.h openssh-4.4p1+pkcs11-0.17/pkcs11-headers/pkcs11.h
2578--- openssh-4.4p1/pkcs11-headers/pkcs11.h 1970-01-01 02:00:00.000000000 +0200
2579+++ openssh-4.4p1+pkcs11-0.17/pkcs11-headers/pkcs11.h 2006-09-28 08:05:35.000000000 +0300
2580@@ -0,0 +1,299 @@
2581+/* pkcs11.h include file for PKCS #11. */
2582+/* $Revision: 1.4 $ */
2583+
2584+/* License to copy and use this software is granted provided that it is
2585+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
2586+ * (Cryptoki)" in all material mentioning or referencing this software.
2587+
2588+ * License is also granted to make and use derivative works provided that
2589+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
2590+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
2591+ * referencing the derived work.
2592+
2593+ * RSA Security Inc. makes no representations concerning either the
2594+ * merchantability of this software or the suitability of this software for
2595+ * any particular purpose. It is provided "as is" without express or implied
2596+ * warranty of any kind.
2597+ */
2598+
2599+#ifndef _PKCS11_H_
2600+#define _PKCS11_H_ 1
2601+
2602+#ifdef __cplusplus
2603+extern "C" {
2604+#endif
2605+
2606+/* Before including this file (pkcs11.h) (or pkcs11t.h by
2607+ * itself), 6 platform-specific macros must be defined. These
2608+ * macros are described below, and typical definitions for them
2609+ * are also given. Be advised that these definitions can depend
2610+ * on both the platform and the compiler used (and possibly also
2611+ * on whether a Cryptoki library is linked statically or
2612+ * dynamically).
2613+ *
2614+ * In addition to defining these 6 macros, the packing convention
2615+ * for Cryptoki structures should be set. The Cryptoki
2616+ * convention on packing is that structures should be 1-byte
2617+ * aligned.
2618+ *
2619+ * If you're using Microsoft Developer Studio 5.0 to produce
2620+ * Win32 stuff, this might be done by using the following
2621+ * preprocessor directive before including pkcs11.h or pkcs11t.h:
2622+ *
2623+ * #pragma pack(push, cryptoki, 1)
2624+ *
2625+ * and using the following preprocessor directive after including
2626+ * pkcs11.h or pkcs11t.h:
2627+ *
2628+ * #pragma pack(pop, cryptoki)
2629+ *
2630+ * If you're using an earlier version of Microsoft Developer
2631+ * Studio to produce Win16 stuff, this might be done by using
2632+ * the following preprocessor directive before including
2633+ * pkcs11.h or pkcs11t.h:
2634+ *
2635+ * #pragma pack(1)
2636+ *
2637+ * In a UNIX environment, you're on your own for this. You might
2638+ * not need to do (or be able to do!) anything.
2639+ *
2640+ *
2641+ * Now for the macros:
2642+ *
2643+ *
2644+ * 1. CK_PTR: The indirection string for making a pointer to an
2645+ * object. It can be used like this:
2646+ *
2647+ * typedef CK_BYTE CK_PTR CK_BYTE_PTR;
2648+ *
2649+ * If you're using Microsoft Developer Studio 5.0 to produce
2650+ * Win32 stuff, it might be defined by:
2651+ *
2652+ * #define CK_PTR *
2653+ *
2654+ * If you're using an earlier version of Microsoft Developer
2655+ * Studio to produce Win16 stuff, it might be defined by:
2656+ *
2657+ * #define CK_PTR far *
2658+ *
2659+ * In a typical UNIX environment, it might be defined by:
2660+ *
2661+ * #define CK_PTR *
2662+ *
2663+ *
2664+ * 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes
2665+ * an exportable Cryptoki library function definition out of a
2666+ * return type and a function name. It should be used in the
2667+ * following fashion to define the exposed Cryptoki functions in
2668+ * a Cryptoki library:
2669+ *
2670+ * CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
2671+ * CK_VOID_PTR pReserved
2672+ * )
2673+ * {
2674+ * ...
2675+ * }
2676+ *
2677+ * If you're using Microsoft Developer Studio 5.0 to define a
2678+ * function in a Win32 Cryptoki .dll, it might be defined by:
2679+ *
2680+ * #define CK_DEFINE_FUNCTION(returnType, name) \
2681+ * returnType __declspec(dllexport) name
2682+ *
2683+ * If you're using an earlier version of Microsoft Developer
2684+ * Studio to define a function in a Win16 Cryptoki .dll, it
2685+ * might be defined by:
2686+ *
2687+ * #define CK_DEFINE_FUNCTION(returnType, name) \
2688+ * returnType __export _far _pascal name
2689+ *
2690+ * In a UNIX environment, it might be defined by:
2691+ *
2692+ * #define CK_DEFINE_FUNCTION(returnType, name) \
2693+ * returnType name
2694+ *
2695+ *
2696+ * 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
2697+ * an importable Cryptoki library function declaration out of a
2698+ * return type and a function name. It should be used in the
2699+ * following fashion:
2700+ *
2701+ * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
2702+ * CK_VOID_PTR pReserved
2703+ * );
2704+ *
2705+ * If you're using Microsoft Developer Studio 5.0 to declare a
2706+ * function in a Win32 Cryptoki .dll, it might be defined by:
2707+ *
2708+ * #define CK_DECLARE_FUNCTION(returnType, name) \
2709+ * returnType __declspec(dllimport) name
2710+ *
2711+ * If you're using an earlier version of Microsoft Developer
2712+ * Studio to declare a function in a Win16 Cryptoki .dll, it
2713+ * might be defined by:
2714+ *
2715+ * #define CK_DECLARE_FUNCTION(returnType, name) \
2716+ * returnType __export _far _pascal name
2717+ *
2718+ * In a UNIX environment, it might be defined by:
2719+ *
2720+ * #define CK_DECLARE_FUNCTION(returnType, name) \
2721+ * returnType name
2722+ *
2723+ *
2724+ * 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
2725+ * which makes a Cryptoki API function pointer declaration or
2726+ * function pointer type declaration out of a return type and a
2727+ * function name. It should be used in the following fashion:
2728+ *
2729+ * // Define funcPtr to be a pointer to a Cryptoki API function
2730+ * // taking arguments args and returning CK_RV.
2731+ * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
2732+ *
2733+ * or
2734+ *
2735+ * // Define funcPtrType to be the type of a pointer to a
2736+ * // Cryptoki API function taking arguments args and returning
2737+ * // CK_RV, and then define funcPtr to be a variable of type
2738+ * // funcPtrType.
2739+ * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
2740+ * funcPtrType funcPtr;
2741+ *
2742+ * If you're using Microsoft Developer Studio 5.0 to access
2743+ * functions in a Win32 Cryptoki .dll, in might be defined by:
2744+ *
2745+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
2746+ * returnType __declspec(dllimport) (* name)
2747+ *
2748+ * If you're using an earlier version of Microsoft Developer
2749+ * Studio to access functions in a Win16 Cryptoki .dll, it might
2750+ * be defined by:
2751+ *
2752+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
2753+ * returnType __export _far _pascal (* name)
2754+ *
2755+ * In a UNIX environment, it might be defined by:
2756+ *
2757+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
2758+ * returnType (* name)
2759+ *
2760+ *
2761+ * 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
2762+ * a function pointer type for an application callback out of
2763+ * a return type for the callback and a name for the callback.
2764+ * It should be used in the following fashion:
2765+ *
2766+ * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
2767+ *
2768+ * to declare a function pointer, myCallback, to a callback
2769+ * which takes arguments args and returns a CK_RV. It can also
2770+ * be used like this:
2771+ *
2772+ * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
2773+ * myCallbackType myCallback;
2774+ *
2775+ * If you're using Microsoft Developer Studio 5.0 to do Win32
2776+ * Cryptoki development, it might be defined by:
2777+ *
2778+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
2779+ * returnType (* name)
2780+ *
2781+ * If you're using an earlier version of Microsoft Developer
2782+ * Studio to do Win16 development, it might be defined by:
2783+ *
2784+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
2785+ * returnType _far _pascal (* name)
2786+ *
2787+ * In a UNIX environment, it might be defined by:
2788+ *
2789+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
2790+ * returnType (* name)
2791+ *
2792+ *
2793+ * 6. NULL_PTR: This macro is the value of a NULL pointer.
2794+ *
2795+ * In any ANSI/ISO C environment (and in many others as well),
2796+ * this should best be defined by
2797+ *
2798+ * #ifndef NULL_PTR
2799+ * #define NULL_PTR 0
2800+ * #endif
2801+ */
2802+
2803+
2804+/* All the various Cryptoki types and #define'd values are in the
2805+ * file pkcs11t.h. */
2806+#include "pkcs11t.h"
2807+
2808+#define __PASTE(x,y) x##y
2809+
2810+
2811+/* ==============================================================
2812+ * Define the "extern" form of all the entry points.
2813+ * ==============================================================
2814+ */
2815+
2816+#define CK_NEED_ARG_LIST 1
2817+#define CK_PKCS11_FUNCTION_INFO(name) \
2818+ extern CK_DECLARE_FUNCTION(CK_RV, name)
2819+
2820+/* pkcs11f.h has all the information about the Cryptoki
2821+ * function prototypes. */
2822+#include "pkcs11f.h"
2823+
2824+#undef CK_NEED_ARG_LIST
2825+#undef CK_PKCS11_FUNCTION_INFO
2826+
2827+
2828+/* ==============================================================
2829+ * Define the typedef form of all the entry points. That is, for
2830+ * each Cryptoki function C_XXX, define a type CK_C_XXX which is
2831+ * a pointer to that kind of function.
2832+ * ==============================================================
2833+ */
2834+
2835+#define CK_NEED_ARG_LIST 1
2836+#define CK_PKCS11_FUNCTION_INFO(name) \
2837+ typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
2838+
2839+/* pkcs11f.h has all the information about the Cryptoki
2840+ * function prototypes. */
2841+#include "pkcs11f.h"
2842+
2843+#undef CK_NEED_ARG_LIST
2844+#undef CK_PKCS11_FUNCTION_INFO
2845+
2846+
2847+/* ==============================================================
2848+ * Define structed vector of entry points. A CK_FUNCTION_LIST
2849+ * contains a CK_VERSION indicating a library's Cryptoki version
2850+ * and then a whole slew of function pointers to the routines in
2851+ * the library. This type was declared, but not defined, in
2852+ * pkcs11t.h.
2853+ * ==============================================================
2854+ */
2855+
2856+#define CK_PKCS11_FUNCTION_INFO(name) \
2857+ __PASTE(CK_,name) name;
2858+
2859+struct CK_FUNCTION_LIST {
2860+
2861+ CK_VERSION version; /* Cryptoki version */
2862+
2863+/* Pile all the function pointers into the CK_FUNCTION_LIST. */
2864+/* pkcs11f.h has all the information about the Cryptoki
2865+ * function prototypes. */
2866+#include "pkcs11f.h"
2867+
2868+};
2869+
2870+#undef CK_PKCS11_FUNCTION_INFO
2871+
2872+
2873+#undef __PASTE
2874+
2875+#ifdef __cplusplus
2876+}
2877+#endif
2878+
2879+#endif
2880diff -urNp openssh-4.4p1/pkcs11-headers/pkcs11t.h openssh-4.4p1+pkcs11-0.17/pkcs11-headers/pkcs11t.h
2881--- openssh-4.4p1/pkcs11-headers/pkcs11t.h 1970-01-01 02:00:00.000000000 +0200
2882+++ openssh-4.4p1+pkcs11-0.17/pkcs11-headers/pkcs11t.h 2006-09-28 08:05:35.000000000 +0300
2883@@ -0,0 +1,1685 @@
2884+/* pkcs11t.h include file for PKCS #11. */
2885+/* $Revision: 1.6 $ */
2886+
2887+/* License to copy and use this software is granted provided that it is
2888+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
2889+ * (Cryptoki)" in all material mentioning or referencing this software.
2890+
2891+ * License is also granted to make and use derivative works provided that
2892+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
2893+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
2894+ * referencing the derived work.
2895+
2896+ * RSA Security Inc. makes no representations concerning either the
2897+ * merchantability of this software or the suitability of this software for
2898+ * any particular purpose. It is provided "as is" without express or implied
2899+ * warranty of any kind.
2900+ */
2901+
2902+/* See top of pkcs11.h for information about the macros that
2903+ * must be defined and the structure-packing conventions that
2904+ * must be set before including this file. */
2905+
2906+#ifndef _PKCS11T_H_
2907+#define _PKCS11T_H_ 1
2908+
2909+#define CK_TRUE 1
2910+#define CK_FALSE 0
2911+
2912+#ifndef CK_DISABLE_TRUE_FALSE
2913+#ifndef FALSE
2914+#define FALSE CK_FALSE
2915+#endif
2916+
2917+#ifndef TRUE
2918+#define TRUE CK_TRUE
2919+#endif
2920+#endif
2921+
2922+/* an unsigned 8-bit value */
2923+typedef unsigned char CK_BYTE;
2924+
2925+/* an unsigned 8-bit character */
2926+typedef CK_BYTE CK_CHAR;
2927+
2928+/* an 8-bit UTF-8 character */
2929+typedef CK_BYTE CK_UTF8CHAR;
2930+
2931+/* a BYTE-sized Boolean flag */
2932+typedef CK_BYTE CK_BBOOL;
2933+
2934+/* an unsigned value, at least 32 bits long */
2935+typedef unsigned long int CK_ULONG;
2936+
2937+/* a signed value, the same size as a CK_ULONG */
2938+/* CK_LONG is new for v2.0 */
2939+typedef long int CK_LONG;
2940+
2941+/* at least 32 bits; each bit is a Boolean flag */
2942+typedef CK_ULONG CK_FLAGS;
2943+
2944+
2945+/* some special values for certain CK_ULONG variables */
2946+#define CK_UNAVAILABLE_INFORMATION (~0UL)
2947+#define CK_EFFECTIVELY_INFINITE 0
2948+
2949+
2950+typedef CK_BYTE CK_PTR CK_BYTE_PTR;
2951+typedef CK_CHAR CK_PTR CK_CHAR_PTR;
2952+typedef CK_UTF8CHAR CK_PTR CK_UTF8CHAR_PTR;
2953+typedef CK_ULONG CK_PTR CK_ULONG_PTR;
2954+typedef void CK_PTR CK_VOID_PTR;
2955+
2956+/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */
2957+typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR;
2958+
2959+
2960+/* The following value is always invalid if used as a session */
2961+/* handle or object handle */
2962+#define CK_INVALID_HANDLE 0
2963+
2964+
2965+typedef struct CK_VERSION {
2966+ CK_BYTE major; /* integer portion of version number */
2967+ CK_BYTE minor; /* 1/100ths portion of version number */
2968+} CK_VERSION;
2969+
2970+typedef CK_VERSION CK_PTR CK_VERSION_PTR;
2971+
2972+
2973+typedef struct CK_INFO {
2974+ /* manufacturerID and libraryDecription have been changed from
2975+ * CK_CHAR to CK_UTF8CHAR for v2.10 */
2976+ CK_VERSION cryptokiVersion; /* Cryptoki interface ver */
2977+ CK_UTF8CHAR manufacturerID[32]; /* blank padded */
2978+ CK_FLAGS flags; /* must be zero */
2979+
2980+ /* libraryDescription and libraryVersion are new for v2.0 */
2981+ CK_UTF8CHAR libraryDescription[32]; /* blank padded */
2982+ CK_VERSION libraryVersion; /* version of library */
2983+} CK_INFO;
2984+
2985+typedef CK_INFO CK_PTR CK_INFO_PTR;
2986+
2987+
2988+/* CK_NOTIFICATION enumerates the types of notifications that
2989+ * Cryptoki provides to an application */
2990+/* CK_NOTIFICATION has been changed from an enum to a CK_ULONG
2991+ * for v2.0 */
2992+typedef CK_ULONG CK_NOTIFICATION;
2993+#define CKN_SURRENDER 0
2994+
2995+
2996+typedef CK_ULONG CK_SLOT_ID;
2997+
2998+typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
2999+
3000+
3001+/* CK_SLOT_INFO provides information about a slot */
3002+typedef struct CK_SLOT_INFO {
3003+ /* slotDescription and manufacturerID have been changed from
3004+ * CK_CHAR to CK_UTF8CHAR for v2.10 */
3005+ CK_UTF8CHAR slotDescription[64]; /* blank padded */
3006+ CK_UTF8CHAR manufacturerID[32]; /* blank padded */
3007+ CK_FLAGS flags;
3008+
3009+ /* hardwareVersion and firmwareVersion are new for v2.0 */
3010+ CK_VERSION hardwareVersion; /* version of hardware */
3011+ CK_VERSION firmwareVersion; /* version of firmware */
3012+} CK_SLOT_INFO;
3013+
3014+/* flags: bit flags that provide capabilities of the slot
3015+ * Bit Flag Mask Meaning
3016+ */
3017+#define CKF_TOKEN_PRESENT 0x00000001 /* a token is there */
3018+#define CKF_REMOVABLE_DEVICE 0x00000002 /* removable devices*/
3019+#define CKF_HW_SLOT 0x00000004 /* hardware slot */
3020+
3021+typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
3022+
3023+
3024+/* CK_TOKEN_INFO provides information about a token */
3025+typedef struct CK_TOKEN_INFO {
3026+ /* label, manufacturerID, and model have been changed from
3027+ * CK_CHAR to CK_UTF8CHAR for v2.10 */
3028+ CK_UTF8CHAR label[32]; /* blank padded */
3029+ CK_UTF8CHAR manufacturerID[32]; /* blank padded */
3030+ CK_UTF8CHAR model[16]; /* blank padded */
3031+ CK_CHAR serialNumber[16]; /* blank padded */
3032+ CK_FLAGS flags; /* see below */
3033+
3034+ /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount,
3035+ * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been
3036+ * changed from CK_USHORT to CK_ULONG for v2.0 */
3037+ CK_ULONG ulMaxSessionCount; /* max open sessions */
3038+ CK_ULONG ulSessionCount; /* sess. now open */
3039+ CK_ULONG ulMaxRwSessionCount; /* max R/W sessions */
3040+ CK_ULONG ulRwSessionCount; /* R/W sess. now open */
3041+ CK_ULONG ulMaxPinLen; /* in bytes */
3042+ CK_ULONG ulMinPinLen; /* in bytes */
3043+ CK_ULONG ulTotalPublicMemory; /* in bytes */
3044+ CK_ULONG ulFreePublicMemory; /* in bytes */
3045+ CK_ULONG ulTotalPrivateMemory; /* in bytes */
3046+ CK_ULONG ulFreePrivateMemory; /* in bytes */
3047+
3048+ /* hardwareVersion, firmwareVersion, and time are new for
3049+ * v2.0 */
3050+ CK_VERSION hardwareVersion; /* version of hardware */
3051+ CK_VERSION firmwareVersion; /* version of firmware */
3052+ CK_CHAR utcTime[16]; /* time */
3053+} CK_TOKEN_INFO;
3054+
3055+/* The flags parameter is defined as follows:
3056+ * Bit Flag Mask Meaning
3057+ */
3058+#define CKF_RNG 0x00000001 /* has random #
3059+ * generator */
3060+#define CKF_WRITE_PROTECTED 0x00000002 /* token is
3061+ * write-
3062+ * protected */
3063+#define CKF_LOGIN_REQUIRED 0x00000004 /* user must
3064+ * login */
3065+#define CKF_USER_PIN_INITIALIZED 0x00000008 /* normal user's
3066+ * PIN is set */
3067+
3068+/* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0. If it is set,
3069+ * that means that *every* time the state of cryptographic
3070+ * operations of a session is successfully saved, all keys
3071+ * needed to continue those operations are stored in the state */
3072+#define CKF_RESTORE_KEY_NOT_NEEDED 0x00000020
3073+
3074+/* CKF_CLOCK_ON_TOKEN is new for v2.0. If it is set, that means
3075+ * that the token has some sort of clock. The time on that
3076+ * clock is returned in the token info structure */
3077+#define CKF_CLOCK_ON_TOKEN 0x00000040
3078+
3079+/* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0. If it is
3080+ * set, that means that there is some way for the user to login
3081+ * without sending a PIN through the Cryptoki library itself */
3082+#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100
3083+
3084+/* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0. If it is true,
3085+ * that means that a single session with the token can perform
3086+ * dual simultaneous cryptographic operations (digest and
3087+ * encrypt; decrypt and digest; sign and encrypt; and decrypt
3088+ * and sign) */
3089+#define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200
3090+
3091+/* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the
3092+ * token has been initialized using C_InitializeToken or an
3093+ * equivalent mechanism outside the scope of PKCS #11.
3094+ * Calling C_InitializeToken when this flag is set will cause
3095+ * the token to be reinitialized. */
3096+#define CKF_TOKEN_INITIALIZED 0x00000400
3097+
3098+/* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is
3099+ * true, the token supports secondary authentication for
3100+ * private key objects. This flag is deprecated in v2.11 and
3101+ onwards. */
3102+#define CKF_SECONDARY_AUTHENTICATION 0x00000800
3103+
3104+/* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an
3105+ * incorrect user login PIN has been entered at least once
3106+ * since the last successful authentication. */
3107+#define CKF_USER_PIN_COUNT_LOW 0x00010000
3108+
3109+/* CKF_USER_PIN_FINAL_TRY if new for v2.10. If it is true,
3110+ * supplying an incorrect user PIN will it to become locked. */
3111+#define CKF_USER_PIN_FINAL_TRY 0x00020000
3112+
3113+/* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the
3114+ * user PIN has been locked. User login to the token is not
3115+ * possible. */
3116+#define CKF_USER_PIN_LOCKED 0x00040000
3117+
3118+/* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
3119+ * the user PIN value is the default value set by token
3120+ * initialization or manufacturing, or the PIN has been
3121+ * expired by the card. */
3122+#define CKF_USER_PIN_TO_BE_CHANGED 0x00080000
3123+
3124+/* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an
3125+ * incorrect SO login PIN has been entered at least once since
3126+ * the last successful authentication. */
3127+#define CKF_SO_PIN_COUNT_LOW 0x00100000
3128+
3129+/* CKF_SO_PIN_FINAL_TRY if new for v2.10. If it is true,
3130+ * supplying an incorrect SO PIN will it to become locked. */
3131+#define CKF_SO_PIN_FINAL_TRY 0x00200000
3132+
3133+/* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO
3134+ * PIN has been locked. SO login to the token is not possible.
3135+ */
3136+#define CKF_SO_PIN_LOCKED 0x00400000
3137+
3138+/* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
3139+ * the SO PIN value is the default value set by token
3140+ * initialization or manufacturing, or the PIN has been
3141+ * expired by the card. */
3142+#define CKF_SO_PIN_TO_BE_CHANGED 0x00800000
3143+
3144+typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
3145+
3146+
3147+/* CK_SESSION_HANDLE is a Cryptoki-assigned value that
3148+ * identifies a session */
3149+typedef CK_ULONG CK_SESSION_HANDLE;
3150+
3151+typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR;
3152+
3153+
3154+/* CK_USER_TYPE enumerates the types of Cryptoki users */
3155+/* CK_USER_TYPE has been changed from an enum to a CK_ULONG for
3156+ * v2.0 */
3157+typedef CK_ULONG CK_USER_TYPE;
3158+/* Security Officer */
3159+#define CKU_SO 0
3160+/* Normal user */
3161+#define CKU_USER 1
3162+/* Context specific (added in v2.20) */
3163+#define CKU_CONTEXT_SPECIFIC 2
3164+
3165+/* CK_STATE enumerates the session states */
3166+/* CK_STATE has been changed from an enum to a CK_ULONG for
3167+ * v2.0 */
3168+typedef CK_ULONG CK_STATE;
3169+#define CKS_RO_PUBLIC_SESSION 0
3170+#define CKS_RO_USER_FUNCTIONS 1
3171+#define CKS_RW_PUBLIC_SESSION 2
3172+#define CKS_RW_USER_FUNCTIONS 3
3173+#define CKS_RW_SO_FUNCTIONS 4
3174+
3175+
3176+/* CK_SESSION_INFO provides information about a session */
3177+typedef struct CK_SESSION_INFO {
3178+ CK_SLOT_ID slotID;
3179+ CK_STATE state;
3180+ CK_FLAGS flags; /* see below */
3181+
3182+ /* ulDeviceError was changed from CK_USHORT to CK_ULONG for
3183+ * v2.0 */
3184+ CK_ULONG ulDeviceError; /* device-dependent error code */
3185+} CK_SESSION_INFO;
3186+
3187+/* The flags are defined in the following table:
3188+ * Bit Flag Mask Meaning
3189+ */
3190+#define CKF_RW_SESSION 0x00000002 /* session is r/w */
3191+#define CKF_SERIAL_SESSION 0x00000004 /* no parallel */
3192+
3193+typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR;
3194+
3195+
3196+/* CK_OBJECT_HANDLE is a token-specific identifier for an
3197+ * object */
3198+typedef CK_ULONG CK_OBJECT_HANDLE;
3199+
3200+typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR;
3201+
3202+
3203+/* CK_OBJECT_CLASS is a value that identifies the classes (or
3204+ * types) of objects that Cryptoki recognizes. It is defined
3205+ * as follows: */
3206+/* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for
3207+ * v2.0 */
3208+typedef CK_ULONG CK_OBJECT_CLASS;
3209+
3210+/* The following classes of objects are defined: */
3211+/* CKO_HW_FEATURE is new for v2.10 */
3212+/* CKO_DOMAIN_PARAMETERS is new for v2.11 */
3213+/* CKO_MECHANISM is new for v2.20 */
3214+#define CKO_DATA 0x00000000
3215+#define CKO_CERTIFICATE 0x00000001
3216+#define CKO_PUBLIC_KEY 0x00000002
3217+#define CKO_PRIVATE_KEY 0x00000003
3218+#define CKO_SECRET_KEY 0x00000004
3219+#define CKO_HW_FEATURE 0x00000005
3220+#define CKO_DOMAIN_PARAMETERS 0x00000006
3221+#define CKO_MECHANISM 0x00000007
3222+#define CKO_VENDOR_DEFINED 0x80000000
3223+
3224+typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
3225+
3226+/* CK_HW_FEATURE_TYPE is new for v2.10. CK_HW_FEATURE_TYPE is a
3227+ * value that identifies the hardware feature type of an object
3228+ * with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. */
3229+typedef CK_ULONG CK_HW_FEATURE_TYPE;
3230+
3231+/* The following hardware feature types are defined */
3232+/* CKH_USER_INTERFACE is new for v2.20 */
3233+#define CKH_MONOTONIC_COUNTER 0x00000001
3234+#define CKH_CLOCK 0x00000002
3235+#define CKH_USER_INTERFACE 0x00000003
3236+#define CKH_VENDOR_DEFINED 0x80000000
3237+
3238+/* CK_KEY_TYPE is a value that identifies a key type */
3239+/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */
3240+typedef CK_ULONG CK_KEY_TYPE;
3241+
3242+/* the following key types are defined: */
3243+#define CKK_RSA 0x00000000
3244+#define CKK_DSA 0x00000001
3245+#define CKK_DH 0x00000002
3246+
3247+/* CKK_ECDSA and CKK_KEA are new for v2.0 */
3248+/* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred. */
3249+#define CKK_ECDSA 0x00000003
3250+#define CKK_EC 0x00000003
3251+#define CKK_X9_42_DH 0x00000004
3252+#define CKK_KEA 0x00000005
3253+
3254+#define CKK_GENERIC_SECRET 0x00000010
3255+#define CKK_RC2 0x00000011
3256+#define CKK_RC4 0x00000012
3257+#define CKK_DES 0x00000013
3258+#define CKK_DES2 0x00000014
3259+#define CKK_DES3 0x00000015
3260+
3261+/* all these key types are new for v2.0 */
3262+#define CKK_CAST 0x00000016
3263+#define CKK_CAST3 0x00000017
3264+/* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred. */
3265+#define CKK_CAST5 0x00000018
3266+#define CKK_CAST128 0x00000018
3267+#define CKK_RC5 0x00000019
3268+#define CKK_IDEA 0x0000001A
3269+#define CKK_SKIPJACK 0x0000001B
3270+#define CKK_BATON 0x0000001C
3271+#define CKK_JUNIPER 0x0000001D
3272+#define CKK_CDMF 0x0000001E
3273+#define CKK_AES 0x0000001F
3274+
3275+/* BlowFish and TwoFish are new for v2.20 */
3276+#define CKK_BLOWFISH 0x00000020
3277+#define CKK_TWOFISH 0x00000021
3278+
3279+#define CKK_VENDOR_DEFINED 0x80000000
3280+
3281+
3282+/* CK_CERTIFICATE_TYPE is a value that identifies a certificate
3283+ * type */
3284+/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG
3285+ * for v2.0 */
3286+typedef CK_ULONG CK_CERTIFICATE_TYPE;
3287+
3288+/* The following certificate types are defined: */
3289+/* CKC_X_509_ATTR_CERT is new for v2.10 */
3290+/* CKC_WTLS is new for v2.20 */
3291+#define CKC_X_509 0x00000000
3292+#define CKC_X_509_ATTR_CERT 0x00000001
3293+#define CKC_WTLS 0x00000002
3294+#define CKC_VENDOR_DEFINED 0x80000000
3295+
3296+
3297+/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute
3298+ * type */
3299+/* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for
3300+ * v2.0 */
3301+typedef CK_ULONG CK_ATTRIBUTE_TYPE;
3302+
3303+/* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which
3304+ consists of an array of values. */
3305+#define CKF_ARRAY_ATTRIBUTE 0x40000000
3306+
3307+/* The following attribute types are defined: */
3308+#define CKA_CLASS 0x00000000
3309+#define CKA_TOKEN 0x00000001
3310+#define CKA_PRIVATE 0x00000002
3311+#define CKA_LABEL 0x00000003
3312+#define CKA_APPLICATION 0x00000010
3313+#define CKA_VALUE 0x00000011
3314+
3315+/* CKA_OBJECT_ID is new for v2.10 */
3316+#define CKA_OBJECT_ID 0x00000012
3317+
3318+#define CKA_CERTIFICATE_TYPE 0x00000080
3319+#define CKA_ISSUER 0x00000081
3320+#define CKA_SERIAL_NUMBER 0x00000082
3321+
3322+/* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new
3323+ * for v2.10 */
3324+#define CKA_AC_ISSUER 0x00000083
3325+#define CKA_OWNER 0x00000084
3326+#define CKA_ATTR_TYPES 0x00000085
3327+
3328+/* CKA_TRUSTED is new for v2.11 */
3329+#define CKA_TRUSTED 0x00000086
3330+
3331+/* CKA_CERTIFICATE_CATEGORY ...
3332+ * CKA_CHECK_VALUE are new for v2.20 */
3333+#define CKA_CERTIFICATE_CATEGORY 0x00000087
3334+#define CKA_JAVA_MIDP_SECURITY_DOMAIN 0x00000088
3335+#define CKA_URL 0x00000089
3336+#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY 0x0000008A
3337+#define CKA_HASH_OF_ISSUER_PUBLIC_KEY 0x0000008B
3338+#define CKA_CHECK_VALUE 0x00000090
3339+
3340+#define CKA_KEY_TYPE 0x00000100
3341+#define CKA_SUBJECT 0x00000101
3342+#define CKA_ID 0x00000102
3343+#define CKA_SENSITIVE 0x00000103
3344+#define CKA_ENCRYPT 0x00000104
3345+#define CKA_DECRYPT 0x00000105
3346+#define CKA_WRAP 0x00000106
3347+#define CKA_UNWRAP 0x00000107
3348+#define CKA_SIGN 0x00000108
3349+#define CKA_SIGN_RECOVER 0x00000109
3350+#define CKA_VERIFY 0x0000010A
3351+#define CKA_VERIFY_RECOVER 0x0000010B
3352+#define CKA_DERIVE 0x0000010C
3353+#define CKA_START_DATE 0x00000110
3354+#define CKA_END_DATE 0x00000111
3355+#define CKA_MODULUS 0x00000120
3356+#define CKA_MODULUS_BITS 0x00000121
3357+#define CKA_PUBLIC_EXPONENT 0x00000122
3358+#define CKA_PRIVATE_EXPONENT 0x00000123
3359+#define CKA_PRIME_1 0x00000124
3360+#define CKA_PRIME_2 0x00000125
3361+#define CKA_EXPONENT_1 0x00000126
3362+#define CKA_EXPONENT_2 0x00000127
3363+#define CKA_COEFFICIENT 0x00000128
3364+#define CKA_PRIME 0x00000130
3365+#define CKA_SUBPRIME 0x00000131
3366+#define CKA_BASE 0x00000132
3367+
3368+/* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */
3369+#define CKA_PRIME_BITS 0x00000133
3370+#define CKA_SUBPRIME_BITS 0x00000134
3371+#define CKA_SUB_PRIME_BITS CKA_SUBPRIME_BITS
3372+/* (To retain backwards-compatibility) */
3373+
3374+#define CKA_VALUE_BITS 0x00000160
3375+#define CKA_VALUE_LEN 0x00000161
3376+
3377+/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
3378+ * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS,
3379+ * and CKA_EC_POINT are new for v2.0 */
3380+#define CKA_EXTRACTABLE 0x00000162
3381+#define CKA_LOCAL 0x00000163
3382+#define CKA_NEVER_EXTRACTABLE 0x00000164
3383+#define CKA_ALWAYS_SENSITIVE 0x00000165
3384+
3385+/* CKA_KEY_GEN_MECHANISM is new for v2.11 */
3386+#define CKA_KEY_GEN_MECHANISM 0x00000166
3387+
3388+#define CKA_MODIFIABLE 0x00000170
3389+
3390+/* CKA_ECDSA_PARAMS is deprecated in v2.11,
3391+ * CKA_EC_PARAMS is preferred. */
3392+#define CKA_ECDSA_PARAMS 0x00000180
3393+#define CKA_EC_PARAMS 0x00000180
3394+
3395+#define CKA_EC_POINT 0x00000181
3396+
3397+/* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
3398+ * are new for v2.10. Deprecated in v2.11 and onwards. */
3399+#define CKA_SECONDARY_AUTH 0x00000200
3400+#define CKA_AUTH_PIN_FLAGS 0x00000201
3401+
3402+/* CKA_ALWAYS_AUTHENTICATE ...
3403+ * CKA_UNWRAP_TEMPLATE are new for v2.20 */
3404+#define CKA_ALWAYS_AUTHENTICATE 0x00000202
3405+
3406+#define CKA_WRAP_WITH_TRUSTED 0x00000210
3407+#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000211)
3408+#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000212)
3409+
3410+/* CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET
3411+ * are new for v2.10 */
3412+#define CKA_HW_FEATURE_TYPE 0x00000300
3413+#define CKA_RESET_ON_INIT 0x00000301
3414+#define CKA_HAS_RESET 0x00000302
3415+
3416+/* The following attributes are new for v2.20 */
3417+#define CKA_PIXEL_X 0x00000400
3418+#define CKA_PIXEL_Y 0x00000401
3419+#define CKA_RESOLUTION 0x00000402
3420+#define CKA_CHAR_ROWS 0x00000403
3421+#define CKA_CHAR_COLUMNS 0x00000404
3422+#define CKA_COLOR 0x00000405
3423+#define CKA_BITS_PER_PIXEL 0x00000406
3424+#define CKA_CHAR_SETS 0x00000480
3425+#define CKA_ENCODING_METHODS 0x00000481
3426+#define CKA_MIME_TYPES 0x00000482
3427+#define CKA_MECHANISM_TYPE 0x00000500
3428+#define CKA_REQUIRED_CMS_ATTRIBUTES 0x00000501
3429+#define CKA_DEFAULT_CMS_ATTRIBUTES 0x00000502
3430+#define CKA_SUPPORTED_CMS_ATTRIBUTES 0x00000503
3431+#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE|0x00000600)
3432+
3433+#define CKA_VENDOR_DEFINED 0x80000000
3434+
3435+
3436+/* CK_ATTRIBUTE is a structure that includes the type, length
3437+ * and value of an attribute */
3438+typedef struct CK_ATTRIBUTE {
3439+ CK_ATTRIBUTE_TYPE type;
3440+ CK_VOID_PTR pValue;
3441+
3442+ /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */
3443+ CK_ULONG ulValueLen; /* in bytes */
3444+} CK_ATTRIBUTE;
3445+
3446+typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR;
3447+
3448+
3449+/* CK_DATE is a structure that defines a date */
3450+typedef struct CK_DATE{
3451+ CK_CHAR year[4]; /* the year ("1900" - "9999") */
3452+ CK_CHAR month[2]; /* the month ("01" - "12") */
3453+ CK_CHAR day[2]; /* the day ("01" - "31") */
3454+} CK_DATE;
3455+
3456+
3457+/* CK_MECHANISM_TYPE is a value that identifies a mechanism
3458+ * type */
3459+/* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for
3460+ * v2.0 */
3461+typedef CK_ULONG CK_MECHANISM_TYPE;
3462+
3463+/* the following mechanism types are defined: */
3464+#define CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000
3465+#define CKM_RSA_PKCS 0x00000001
3466+#define CKM_RSA_9796 0x00000002
3467+#define CKM_RSA_X_509 0x00000003
3468+
3469+/* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS
3470+ * are new for v2.0. They are mechanisms which hash and sign */
3471+#define CKM_MD2_RSA_PKCS 0x00000004
3472+#define CKM_MD5_RSA_PKCS 0x00000005
3473+#define CKM_SHA1_RSA_PKCS 0x00000006
3474+
3475+/* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, and
3476+ * CKM_RSA_PKCS_OAEP are new for v2.10 */
3477+#define CKM_RIPEMD128_RSA_PKCS 0x00000007
3478+#define CKM_RIPEMD160_RSA_PKCS 0x00000008
3479+#define CKM_RSA_PKCS_OAEP 0x00000009
3480+
3481+/* CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31,
3482+ * CKM_RSA_PKCS_PSS, and CKM_SHA1_RSA_PKCS_PSS are new for v2.11 */
3483+#define CKM_RSA_X9_31_KEY_PAIR_GEN 0x0000000A
3484+#define CKM_RSA_X9_31 0x0000000B
3485+#define CKM_SHA1_RSA_X9_31 0x0000000C
3486+#define CKM_RSA_PKCS_PSS 0x0000000D
3487+#define CKM_SHA1_RSA_PKCS_PSS 0x0000000E
3488+
3489+#define CKM_DSA_KEY_PAIR_GEN 0x00000010
3490+#define CKM_DSA 0x00000011
3491+#define CKM_DSA_SHA1 0x00000012
3492+#define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020
3493+#define CKM_DH_PKCS_DERIVE 0x00000021
3494+
3495+/* CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE,
3496+ * CKM_X9_42_DH_HYBRID_DERIVE, and CKM_X9_42_MQV_DERIVE are new for
3497+ * v2.11 */
3498+#define CKM_X9_42_DH_KEY_PAIR_GEN 0x00000030
3499+#define CKM_X9_42_DH_DERIVE 0x00000031
3500+#define CKM_X9_42_DH_HYBRID_DERIVE 0x00000032
3501+#define CKM_X9_42_MQV_DERIVE 0x00000033
3502+
3503+/* CKM_SHA256/384/512 are new for v2.20 */
3504+#define CKM_SHA256_RSA_PKCS 0x00000040
3505+#define CKM_SHA384_RSA_PKCS 0x00000041
3506+#define CKM_SHA512_RSA_PKCS 0x00000042
3507+#define CKM_SHA256_RSA_PKCS_PSS 0x00000043
3508+#define CKM_SHA384_RSA_PKCS_PSS 0x00000044
3509+#define CKM_SHA512_RSA_PKCS_PSS 0x00000045
3510+
3511+#define CKM_RC2_KEY_GEN 0x00000100
3512+#define CKM_RC2_ECB 0x00000101
3513+#define CKM_RC2_CBC 0x00000102
3514+#define CKM_RC2_MAC 0x00000103
3515+
3516+/* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */
3517+#define CKM_RC2_MAC_GENERAL 0x00000104
3518+#define CKM_RC2_CBC_PAD 0x00000105
3519+
3520+#define CKM_RC4_KEY_GEN 0x00000110
3521+#define CKM_RC4 0x00000111
3522+#define CKM_DES_KEY_GEN 0x00000120
3523+#define CKM_DES_ECB 0x00000121
3524+#define CKM_DES_CBC 0x00000122
3525+#define CKM_DES_MAC 0x00000123
3526+
3527+/* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */
3528+#define CKM_DES_MAC_GENERAL 0x00000124
3529+#define CKM_DES_CBC_PAD 0x00000125
3530+
3531+#define CKM_DES2_KEY_GEN 0x00000130
3532+#define CKM_DES3_KEY_GEN 0x00000131
3533+#define CKM_DES3_ECB 0x00000132
3534+#define CKM_DES3_CBC 0x00000133
3535+#define CKM_DES3_MAC 0x00000134
3536+
3537+/* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN,
3538+ * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC,
3539+ * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */
3540+#define CKM_DES3_MAC_GENERAL 0x00000135
3541+#define CKM_DES3_CBC_PAD 0x00000136
3542+#define CKM_CDMF_KEY_GEN 0x00000140
3543+#define CKM_CDMF_ECB 0x00000141
3544+#define CKM_CDMF_CBC 0x00000142
3545+#define CKM_CDMF_MAC 0x00000143
3546+#define CKM_CDMF_MAC_GENERAL 0x00000144
3547+#define CKM_CDMF_CBC_PAD 0x00000145
3548+
3549+/* the following four DES mechanisms are new for v2.20 */
3550+#define CKM_DES_OFB64 0x00000150
3551+#define CKM_DES_OFB8 0x00000151
3552+#define CKM_DES_CFB64 0x00000152
3553+#define CKM_DES_CFB8 0x00000153
3554+
3555+#define CKM_MD2 0x00000200
3556+
3557+/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */
3558+#define CKM_MD2_HMAC 0x00000201
3559+#define CKM_MD2_HMAC_GENERAL 0x00000202
3560+
3561+#define CKM_MD5 0x00000210
3562+
3563+/* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */
3564+#define CKM_MD5_HMAC 0x00000211
3565+#define CKM_MD5_HMAC_GENERAL 0x00000212
3566+
3567+#define CKM_SHA_1 0x00000220
3568+
3569+/* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */
3570+#define CKM_SHA_1_HMAC 0x00000221
3571+#define CKM_SHA_1_HMAC_GENERAL 0x00000222
3572+
3573+/* CKM_RIPEMD128, CKM_RIPEMD128_HMAC,
3574+ * CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC,
3575+ * and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */
3576+#define CKM_RIPEMD128 0x00000230
3577+#define CKM_RIPEMD128_HMAC 0x00000231
3578+#define CKM_RIPEMD128_HMAC_GENERAL 0x00000232
3579+#define CKM_RIPEMD160 0x00000240
3580+#define CKM_RIPEMD160_HMAC 0x00000241
3581+#define CKM_RIPEMD160_HMAC_GENERAL 0x00000242
3582+
3583+/* CKM_SHA256/384/512 are new for v2.20 */
3584+#define CKM_SHA256 0x00000250
3585+#define CKM_SHA256_HMAC 0x00000251
3586+#define CKM_SHA256_HMAC_GENERAL 0x00000252
3587+#define CKM_SHA384 0x00000260
3588+#define CKM_SHA384_HMAC 0x00000261
3589+#define CKM_SHA384_HMAC_GENERAL 0x00000262
3590+#define CKM_SHA512 0x00000270
3591+#define CKM_SHA512_HMAC 0x00000271
3592+#define CKM_SHA512_HMAC_GENERAL 0x00000272
3593+
3594+/* All of the following mechanisms are new for v2.0 */
3595+/* Note that CAST128 and CAST5 are the same algorithm */
3596+#define CKM_CAST_KEY_GEN 0x00000300
3597+#define CKM_CAST_ECB 0x00000301
3598+#define CKM_CAST_CBC 0x00000302
3599+#define CKM_CAST_MAC 0x00000303
3600+#define CKM_CAST_MAC_GENERAL 0x00000304
3601+#define CKM_CAST_CBC_PAD 0x00000305
3602+#define CKM_CAST3_KEY_GEN 0x00000310
3603+#define CKM_CAST3_ECB 0x00000311
3604+#define CKM_CAST3_CBC 0x00000312
3605+#define CKM_CAST3_MAC 0x00000313
3606+#define CKM_CAST3_MAC_GENERAL 0x00000314
3607+#define CKM_CAST3_CBC_PAD 0x00000315
3608+#define CKM_CAST5_KEY_GEN 0x00000320
3609+#define CKM_CAST128_KEY_GEN 0x00000320
3610+#define CKM_CAST5_ECB 0x00000321
3611+#define CKM_CAST128_ECB 0x00000321
3612+#define CKM_CAST5_CBC 0x00000322
3613+#define CKM_CAST128_CBC 0x00000322
3614+#define CKM_CAST5_MAC 0x00000323
3615+#define CKM_CAST128_MAC 0x00000323
3616+#define CKM_CAST5_MAC_GENERAL 0x00000324
3617+#define CKM_CAST128_MAC_GENERAL 0x00000324
3618+#define CKM_CAST5_CBC_PAD 0x00000325
3619+#define CKM_CAST128_CBC_PAD 0x00000325
3620+#define CKM_RC5_KEY_GEN 0x00000330
3621+#define CKM_RC5_ECB 0x00000331
3622+#define CKM_RC5_CBC 0x00000332
3623+#define CKM_RC5_MAC 0x00000333
3624+#define CKM_RC5_MAC_GENERAL 0x00000334
3625+#define CKM_RC5_CBC_PAD 0x00000335
3626+#define CKM_IDEA_KEY_GEN 0x00000340
3627+#define CKM_IDEA_ECB 0x00000341
3628+#define CKM_IDEA_CBC 0x00000342
3629+#define CKM_IDEA_MAC 0x00000343
3630+#define CKM_IDEA_MAC_GENERAL 0x00000344
3631+#define CKM_IDEA_CBC_PAD 0x00000345
3632+#define CKM_GENERIC_SECRET_KEY_GEN 0x00000350
3633+#define CKM_CONCATENATE_BASE_AND_KEY 0x00000360
3634+#define CKM_CONCATENATE_BASE_AND_DATA 0x00000362
3635+#define CKM_CONCATENATE_DATA_AND_BASE 0x00000363
3636+#define CKM_XOR_BASE_AND_DATA 0x00000364
3637+#define CKM_EXTRACT_KEY_FROM_KEY 0x00000365
3638+#define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370
3639+#define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371
3640+#define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372
3641+
3642+/* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN,
3643+ * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE, and
3644+ * CKM_TLS_MASTER_KEY_DERIVE_DH are new for v2.11 */
3645+#define CKM_SSL3_MASTER_KEY_DERIVE_DH 0x00000373
3646+#define CKM_TLS_PRE_MASTER_KEY_GEN 0x00000374
3647+#define CKM_TLS_MASTER_KEY_DERIVE 0x00000375
3648+#define CKM_TLS_KEY_AND_MAC_DERIVE 0x00000376
3649+#define CKM_TLS_MASTER_KEY_DERIVE_DH 0x00000377
3650+
3651+/* CKM_TLS_PRF is new for v2.20 */
3652+#define CKM_TLS_PRF 0x00000378
3653+
3654+#define CKM_SSL3_MD5_MAC 0x00000380
3655+#define CKM_SSL3_SHA1_MAC 0x00000381
3656+#define CKM_MD5_KEY_DERIVATION 0x00000390
3657+#define CKM_MD2_KEY_DERIVATION 0x00000391
3658+#define CKM_SHA1_KEY_DERIVATION 0x00000392
3659+
3660+/* CKM_SHA256/384/512 are new for v2.20 */
3661+#define CKM_SHA256_KEY_DERIVATION 0x00000393
3662+#define CKM_SHA384_KEY_DERIVATION 0x00000394
3663+#define CKM_SHA512_KEY_DERIVATION 0x00000395
3664+
3665+#define CKM_PBE_MD2_DES_CBC 0x000003A0
3666+#define CKM_PBE_MD5_DES_CBC 0x000003A1
3667+#define CKM_PBE_MD5_CAST_CBC 0x000003A2
3668+#define CKM_PBE_MD5_CAST3_CBC 0x000003A3
3669+#define CKM_PBE_MD5_CAST5_CBC 0x000003A4
3670+#define CKM_PBE_MD5_CAST128_CBC 0x000003A4
3671+#define CKM_PBE_SHA1_CAST5_CBC 0x000003A5
3672+#define CKM_PBE_SHA1_CAST128_CBC 0x000003A5
3673+#define CKM_PBE_SHA1_RC4_128 0x000003A6
3674+#define CKM_PBE_SHA1_RC4_40 0x000003A7
3675+#define CKM_PBE_SHA1_DES3_EDE_CBC 0x000003A8
3676+#define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9
3677+#define CKM_PBE_SHA1_RC2_128_CBC 0x000003AA
3678+#define CKM_PBE_SHA1_RC2_40_CBC 0x000003AB
3679+
3680+/* CKM_PKCS5_PBKD2 is new for v2.10 */
3681+#define CKM_PKCS5_PBKD2 0x000003B0
3682+
3683+#define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0
3684+
3685+/* WTLS mechanisms are new for v2.20 */
3686+#define CKM_WTLS_PRE_MASTER_KEY_GEN 0x000003D0
3687+#define CKM_WTLS_MASTER_KEY_DERIVE 0x000003D1
3688+#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC 0x000003D2
3689+#define CKM_WTLS_PRF 0x000003D3
3690+#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE 0x000003D4
3691+#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE 0x000003D5
3692+
3693+#define CKM_KEY_WRAP_LYNKS 0x00000400
3694+#define CKM_KEY_WRAP_SET_OAEP 0x00000401
3695+
3696+/* CKM_CMS_SIG is new for v2.20 */
3697+#define CKM_CMS_SIG 0x00000500
3698+
3699+/* Fortezza mechanisms */
3700+#define CKM_SKIPJACK_KEY_GEN 0x00001000
3701+#define CKM_SKIPJACK_ECB64 0x00001001
3702+#define CKM_SKIPJACK_CBC64 0x00001002
3703+#define CKM_SKIPJACK_OFB64 0x00001003
3704+#define CKM_SKIPJACK_CFB64 0x00001004
3705+#define CKM_SKIPJACK_CFB32 0x00001005
3706+#define CKM_SKIPJACK_CFB16 0x00001006
3707+#define CKM_SKIPJACK_CFB8 0x00001007
3708+#define CKM_SKIPJACK_WRAP 0x00001008
3709+#define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009
3710+#define CKM_SKIPJACK_RELAYX 0x0000100a
3711+#define CKM_KEA_KEY_PAIR_GEN 0x00001010
3712+#define CKM_KEA_KEY_DERIVE 0x00001011
3713+#define CKM_FORTEZZA_TIMESTAMP 0x00001020
3714+#define CKM_BATON_KEY_GEN 0x00001030
3715+#define CKM_BATON_ECB128 0x00001031
3716+#define CKM_BATON_ECB96 0x00001032
3717+#define CKM_BATON_CBC128 0x00001033
3718+#define CKM_BATON_COUNTER 0x00001034
3719+#define CKM_BATON_SHUFFLE 0x00001035
3720+#define CKM_BATON_WRAP 0x00001036
3721+
3722+/* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11,
3723+ * CKM_EC_KEY_PAIR_GEN is preferred */
3724+#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040
3725+#define CKM_EC_KEY_PAIR_GEN 0x00001040
3726+
3727+#define CKM_ECDSA 0x00001041
3728+#define CKM_ECDSA_SHA1 0x00001042
3729+
3730+/* CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE, and CKM_ECMQV_DERIVE
3731+ * are new for v2.11 */
3732+#define CKM_ECDH1_DERIVE 0x00001050
3733+#define CKM_ECDH1_COFACTOR_DERIVE 0x00001051
3734+#define CKM_ECMQV_DERIVE 0x00001052
3735+
3736+#define CKM_JUNIPER_KEY_GEN 0x00001060
3737+#define CKM_JUNIPER_ECB128 0x00001061
3738+#define CKM_JUNIPER_CBC128 0x00001062
3739+#define CKM_JUNIPER_COUNTER 0x00001063
3740+#define CKM_JUNIPER_SHUFFLE 0x00001064
3741+#define CKM_JUNIPER_WRAP 0x00001065
3742+#define CKM_FASTHASH 0x00001070
3743+
3744+/* CKM_AES_KEY_GEN, CKM_AES_ECB, CKM_AES_CBC, CKM_AES_MAC,
3745+ * CKM_AES_MAC_GENERAL, CKM_AES_CBC_PAD, CKM_DSA_PARAMETER_GEN,
3746+ * CKM_DH_PKCS_PARAMETER_GEN, and CKM_X9_42_DH_PARAMETER_GEN are
3747+ * new for v2.11 */
3748+#define CKM_AES_KEY_GEN 0x00001080
3749+#define CKM_AES_ECB 0x00001081
3750+#define CKM_AES_CBC 0x00001082
3751+#define CKM_AES_MAC 0x00001083
3752+#define CKM_AES_MAC_GENERAL 0x00001084
3753+#define CKM_AES_CBC_PAD 0x00001085
3754+
3755+/* BlowFish and TwoFish are new for v2.20 */
3756+#define CKM_BLOWFISH_KEY_GEN 0x00001090
3757+#define CKM_BLOWFISH_CBC 0x00001091
3758+#define CKM_TWOFISH_KEY_GEN 0x00001092
3759+#define CKM_TWOFISH_CBC 0x00001093
3760+
3761+
3762+/* CKM_xxx_ENCRYPT_DATA mechanisms are new for v2.20 */
3763+#define CKM_DES_ECB_ENCRYPT_DATA 0x00001100
3764+#define CKM_DES_CBC_ENCRYPT_DATA 0x00001101
3765+#define CKM_DES3_ECB_ENCRYPT_DATA 0x00001102
3766+#define CKM_DES3_CBC_ENCRYPT_DATA 0x00001103
3767+#define CKM_AES_ECB_ENCRYPT_DATA 0x00001104
3768+#define CKM_AES_CBC_ENCRYPT_DATA 0x00001105
3769+
3770+#define CKM_DSA_PARAMETER_GEN 0x00002000
3771+#define CKM_DH_PKCS_PARAMETER_GEN 0x00002001
3772+#define CKM_X9_42_DH_PARAMETER_GEN 0x00002002
3773+
3774+#define CKM_VENDOR_DEFINED 0x80000000
3775+
3776+typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR;
3777+
3778+
3779+/* CK_MECHANISM is a structure that specifies a particular
3780+ * mechanism */
3781+typedef struct CK_MECHANISM {
3782+ CK_MECHANISM_TYPE mechanism;
3783+ CK_VOID_PTR pParameter;
3784+
3785+ /* ulParameterLen was changed from CK_USHORT to CK_ULONG for
3786+ * v2.0 */
3787+ CK_ULONG ulParameterLen; /* in bytes */
3788+} CK_MECHANISM;
3789+
3790+typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR;
3791+
3792+
3793+/* CK_MECHANISM_INFO provides information about a particular
3794+ * mechanism */
3795+typedef struct CK_MECHANISM_INFO {
3796+ CK_ULONG ulMinKeySize;
3797+ CK_ULONG ulMaxKeySize;
3798+ CK_FLAGS flags;
3799+} CK_MECHANISM_INFO;
3800+
3801+/* The flags are defined as follows:
3802+ * Bit Flag Mask Meaning */
3803+#define CKF_HW 0x00000001 /* performed by HW */
3804+
3805+/* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN,
3806+ * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER,
3807+ * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP,
3808+ * and CKF_DERIVE are new for v2.0. They specify whether or not
3809+ * a mechanism can be used for a particular task */
3810+#define CKF_ENCRYPT 0x00000100
3811+#define CKF_DECRYPT 0x00000200
3812+#define CKF_DIGEST 0x00000400
3813+#define CKF_SIGN 0x00000800
3814+#define CKF_SIGN_RECOVER 0x00001000
3815+#define CKF_VERIFY 0x00002000
3816+#define CKF_VERIFY_RECOVER 0x00004000
3817+#define CKF_GENERATE 0x00008000
3818+#define CKF_GENERATE_KEY_PAIR 0x00010000
3819+#define CKF_WRAP 0x00020000
3820+#define CKF_UNWRAP 0x00040000
3821+#define CKF_DERIVE 0x00080000
3822+
3823+/* CKF_EC_F_P, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE,
3824+ * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11. They
3825+ * describe a token's EC capabilities not available in mechanism
3826+ * information. */
3827+#define CKF_EC_F_P 0x00100000
3828+#define CKF_EC_F_2M 0x00200000
3829+#define CKF_EC_ECPARAMETERS 0x00400000
3830+#define CKF_EC_NAMEDCURVE 0x00800000
3831+#define CKF_EC_UNCOMPRESS 0x01000000
3832+#define CKF_EC_COMPRESS 0x02000000
3833+
3834+#define CKF_EXTENSION 0x80000000 /* FALSE for this version */
3835+
3836+typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR;
3837+
3838+
3839+/* CK_RV is a value that identifies the return value of a
3840+ * Cryptoki function */
3841+/* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */
3842+typedef CK_ULONG CK_RV;
3843+
3844+#define CKR_OK 0x00000000
3845+#define CKR_CANCEL 0x00000001
3846+#define CKR_HOST_MEMORY 0x00000002
3847+#define CKR_SLOT_ID_INVALID 0x00000003
3848+
3849+/* CKR_FLAGS_INVALID was removed for v2.0 */
3850+
3851+/* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */
3852+#define CKR_GENERAL_ERROR 0x00000005
3853+#define CKR_FUNCTION_FAILED 0x00000006
3854+
3855+/* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS,
3856+ * and CKR_CANT_LOCK are new for v2.01 */
3857+#define CKR_ARGUMENTS_BAD 0x00000007
3858+#define CKR_NO_EVENT 0x00000008
3859+#define CKR_NEED_TO_CREATE_THREADS 0x00000009
3860+#define CKR_CANT_LOCK 0x0000000A
3861+
3862+#define CKR_ATTRIBUTE_READ_ONLY 0x00000010
3863+#define CKR_ATTRIBUTE_SENSITIVE 0x00000011
3864+#define CKR_ATTRIBUTE_TYPE_INVALID 0x00000012
3865+#define CKR_ATTRIBUTE_VALUE_INVALID 0x00000013
3866+#define CKR_DATA_INVALID 0x00000020
3867+#define CKR_DATA_LEN_RANGE 0x00000021
3868+#define CKR_DEVICE_ERROR 0x00000030
3869+#define CKR_DEVICE_MEMORY 0x00000031
3870+#define CKR_DEVICE_REMOVED 0x00000032
3871+#define CKR_ENCRYPTED_DATA_INVALID 0x00000040
3872+#define CKR_ENCRYPTED_DATA_LEN_RANGE 0x00000041
3873+#define CKR_FUNCTION_CANCELED 0x00000050
3874+#define CKR_FUNCTION_NOT_PARALLEL 0x00000051
3875+
3876+/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */
3877+#define CKR_FUNCTION_NOT_SUPPORTED 0x00000054
3878+
3879+#define CKR_KEY_HANDLE_INVALID 0x00000060
3880+
3881+/* CKR_KEY_SENSITIVE was removed for v2.0 */
3882+
3883+#define CKR_KEY_SIZE_RANGE 0x00000062
3884+#define CKR_KEY_TYPE_INCONSISTENT 0x00000063
3885+
3886+/* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED,
3887+ * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED,
3888+ * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for
3889+ * v2.0 */
3890+#define CKR_KEY_NOT_NEEDED 0x00000064
3891+#define CKR_KEY_CHANGED 0x00000065
3892+#define CKR_KEY_NEEDED 0x00000066
3893+#define CKR_KEY_INDIGESTIBLE 0x00000067
3894+#define CKR_KEY_FUNCTION_NOT_PERMITTED 0x00000068
3895+#define CKR_KEY_NOT_WRAPPABLE 0x00000069
3896+#define CKR_KEY_UNEXTRACTABLE 0x0000006A
3897+
3898+#define CKR_MECHANISM_INVALID 0x00000070
3899+#define CKR_MECHANISM_PARAM_INVALID 0x00000071
3900+
3901+/* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID
3902+ * were removed for v2.0 */
3903+#define CKR_OBJECT_HANDLE_INVALID 0x00000082
3904+#define CKR_OPERATION_ACTIVE 0x00000090
3905+#define CKR_OPERATION_NOT_INITIALIZED 0x00000091
3906+#define CKR_PIN_INCORRECT 0x000000A0
3907+#define CKR_PIN_INVALID 0x000000A1
3908+#define CKR_PIN_LEN_RANGE 0x000000A2
3909+
3910+/* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */
3911+#define CKR_PIN_EXPIRED 0x000000A3
3912+#define CKR_PIN_LOCKED 0x000000A4
3913+
3914+#define CKR_SESSION_CLOSED 0x000000B0
3915+#define CKR_SESSION_COUNT 0x000000B1
3916+#define CKR_SESSION_HANDLE_INVALID 0x000000B3
3917+#define CKR_SESSION_PARALLEL_NOT_SUPPORTED 0x000000B4
3918+#define CKR_SESSION_READ_ONLY 0x000000B5
3919+#define CKR_SESSION_EXISTS 0x000000B6
3920+
3921+/* CKR_SESSION_READ_ONLY_EXISTS and
3922+ * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */
3923+#define CKR_SESSION_READ_ONLY_EXISTS 0x000000B7
3924+#define CKR_SESSION_READ_WRITE_SO_EXISTS 0x000000B8
3925+
3926+#define CKR_SIGNATURE_INVALID 0x000000C0
3927+#define CKR_SIGNATURE_LEN_RANGE 0x000000C1
3928+#define CKR_TEMPLATE_INCOMPLETE 0x000000D0
3929+#define CKR_TEMPLATE_INCONSISTENT 0x000000D1
3930+#define CKR_TOKEN_NOT_PRESENT 0x000000E0
3931+#define CKR_TOKEN_NOT_RECOGNIZED 0x000000E1
3932+#define CKR_TOKEN_WRITE_PROTECTED 0x000000E2
3933+#define CKR_UNWRAPPING_KEY_HANDLE_INVALID 0x000000F0
3934+#define CKR_UNWRAPPING_KEY_SIZE_RANGE 0x000000F1
3935+#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT 0x000000F2
3936+#define CKR_USER_ALREADY_LOGGED_IN 0x00000100
3937+#define CKR_USER_NOT_LOGGED_IN 0x00000101
3938+#define CKR_USER_PIN_NOT_INITIALIZED 0x00000102
3939+#define CKR_USER_TYPE_INVALID 0x00000103
3940+
3941+/* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES
3942+ * are new to v2.01 */
3943+#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN 0x00000104
3944+#define CKR_USER_TOO_MANY_TYPES 0x00000105
3945+
3946+#define CKR_WRAPPED_KEY_INVALID 0x00000110
3947+#define CKR_WRAPPED_KEY_LEN_RANGE 0x00000112
3948+#define CKR_WRAPPING_KEY_HANDLE_INVALID 0x00000113
3949+#define CKR_WRAPPING_KEY_SIZE_RANGE 0x00000114
3950+#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115
3951+#define CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120
3952+
3953+/* These are new to v2.0 */
3954+#define CKR_RANDOM_NO_RNG 0x00000121
3955+
3956+/* These are new to v2.11 */
3957+#define CKR_DOMAIN_PARAMS_INVALID 0x00000130
3958+
3959+/* These are new to v2.0 */
3960+#define CKR_BUFFER_TOO_SMALL 0x00000150
3961+#define CKR_SAVED_STATE_INVALID 0x00000160
3962+#define CKR_INFORMATION_SENSITIVE 0x00000170
3963+#define CKR_STATE_UNSAVEABLE 0x00000180
3964+
3965+/* These are new to v2.01 */
3966+#define CKR_CRYPTOKI_NOT_INITIALIZED 0x00000190
3967+#define CKR_CRYPTOKI_ALREADY_INITIALIZED 0x00000191
3968+#define CKR_MUTEX_BAD 0x000001A0
3969+#define CKR_MUTEX_NOT_LOCKED 0x000001A1
3970+
3971+/* This is new to v2.20 */
3972+#define CKR_FUNCTION_REJECTED 0x00000200
3973+
3974+#define CKR_VENDOR_DEFINED 0x80000000
3975+
3976+
3977+/* CK_NOTIFY is an application callback that processes events */
3978+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)(
3979+ CK_SESSION_HANDLE hSession, /* the session's handle */
3980+ CK_NOTIFICATION event,
3981+ CK_VOID_PTR pApplication /* passed to C_OpenSession */
3982+);
3983+
3984+
3985+/* CK_FUNCTION_LIST is a structure holding a Cryptoki spec
3986+ * version and pointers of appropriate types to all the
3987+ * Cryptoki functions */
3988+/* CK_FUNCTION_LIST is new for v2.0 */
3989+typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST;
3990+
3991+typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR;
3992+
3993+typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR;
3994+
3995+
3996+/* CK_CREATEMUTEX is an application callback for creating a
3997+ * mutex object */
3998+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)(
3999+ CK_VOID_PTR_PTR ppMutex /* location to receive ptr to mutex */
4000+);
4001+
4002+
4003+/* CK_DESTROYMUTEX is an application callback for destroying a
4004+ * mutex object */
4005+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)(
4006+ CK_VOID_PTR pMutex /* pointer to mutex */
4007+);
4008+
4009+
4010+/* CK_LOCKMUTEX is an application callback for locking a mutex */
4011+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)(
4012+ CK_VOID_PTR pMutex /* pointer to mutex */
4013+);
4014+
4015+
4016+/* CK_UNLOCKMUTEX is an application callback for unlocking a
4017+ * mutex */
4018+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)(
4019+ CK_VOID_PTR pMutex /* pointer to mutex */
4020+);
4021+
4022+
4023+/* CK_C_INITIALIZE_ARGS provides the optional arguments to
4024+ * C_Initialize */
4025+typedef struct CK_C_INITIALIZE_ARGS {
4026+ CK_CREATEMUTEX CreateMutex;
4027+ CK_DESTROYMUTEX DestroyMutex;
4028+ CK_LOCKMUTEX LockMutex;
4029+ CK_UNLOCKMUTEX UnlockMutex;
4030+ CK_FLAGS flags;
4031+ CK_VOID_PTR pReserved;
4032+} CK_C_INITIALIZE_ARGS;
4033+
4034+/* flags: bit flags that provide capabilities of the slot
4035+ * Bit Flag Mask Meaning
4036+ */
4037+#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001
4038+#define CKF_OS_LOCKING_OK 0x00000002
4039+
4040+typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
4041+
4042+
4043+/* additional flags for parameters to functions */
4044+
4045+/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
4046+#define CKF_DONT_BLOCK 1
4047+
4048+/* CK_RSA_PKCS_OAEP_MGF_TYPE is new for v2.10.
4049+ * CK_RSA_PKCS_OAEP_MGF_TYPE is used to indicate the Message
4050+ * Generation Function (MGF) applied to a message block when
4051+ * formatting a message block for the PKCS #1 OAEP encryption
4052+ * scheme. */
4053+typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE;
4054+
4055+typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR;
4056+
4057+/* The following MGFs are defined */
4058+/* CKG_MGF1_SHA256, CKG_MGF1_SHA384, and CKG_MGF1_SHA512
4059+ * are new for v2.20 */
4060+#define CKG_MGF1_SHA1 0x00000001
4061+#define CKG_MGF1_SHA256 0x00000002
4062+#define CKG_MGF1_SHA384 0x00000003
4063+#define CKG_MGF1_SHA512 0x00000004
4064+
4065+/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is new for v2.10.
4066+ * CK_RSA_PKCS_OAEP_SOURCE_TYPE is used to indicate the source
4067+ * of the encoding parameter when formatting a message block
4068+ * for the PKCS #1 OAEP encryption scheme. */
4069+typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE;
4070+
4071+typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR;
4072+
4073+/* The following encoding parameter sources are defined */
4074+#define CKZ_DATA_SPECIFIED 0x00000001
4075+
4076+/* CK_RSA_PKCS_OAEP_PARAMS is new for v2.10.
4077+ * CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the
4078+ * CKM_RSA_PKCS_OAEP mechanism. */
4079+typedef struct CK_RSA_PKCS_OAEP_PARAMS {
4080+ CK_MECHANISM_TYPE hashAlg;
4081+ CK_RSA_PKCS_MGF_TYPE mgf;
4082+ CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
4083+ CK_VOID_PTR pSourceData;
4084+ CK_ULONG ulSourceDataLen;
4085+} CK_RSA_PKCS_OAEP_PARAMS;
4086+
4087+typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR;
4088+
4089+/* CK_RSA_PKCS_PSS_PARAMS is new for v2.11.
4090+ * CK_RSA_PKCS_PSS_PARAMS provides the parameters to the
4091+ * CKM_RSA_PKCS_PSS mechanism(s). */
4092+typedef struct CK_RSA_PKCS_PSS_PARAMS {
4093+ CK_MECHANISM_TYPE hashAlg;
4094+ CK_RSA_PKCS_MGF_TYPE mgf;
4095+ CK_ULONG sLen;
4096+} CK_RSA_PKCS_PSS_PARAMS;
4097+
4098+typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR;
4099+
4100+/* CK_EC_KDF_TYPE is new for v2.11. */
4101+typedef CK_ULONG CK_EC_KDF_TYPE;
4102+
4103+/* The following EC Key Derivation Functions are defined */
4104+#define CKD_NULL 0x00000001
4105+#define CKD_SHA1_KDF 0x00000002
4106+
4107+/* CK_ECDH1_DERIVE_PARAMS is new for v2.11.
4108+ * CK_ECDH1_DERIVE_PARAMS provides the parameters to the
4109+ * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms,
4110+ * where each party contributes one key pair.
4111+ */
4112+typedef struct CK_ECDH1_DERIVE_PARAMS {
4113+ CK_EC_KDF_TYPE kdf;
4114+ CK_ULONG ulSharedDataLen;
4115+ CK_BYTE_PTR pSharedData;
4116+ CK_ULONG ulPublicDataLen;
4117+ CK_BYTE_PTR pPublicData;
4118+} CK_ECDH1_DERIVE_PARAMS;
4119+
4120+typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR;
4121+
4122+
4123+/* CK_ECDH2_DERIVE_PARAMS is new for v2.11.
4124+ * CK_ECDH2_DERIVE_PARAMS provides the parameters to the
4125+ * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs. */
4126+typedef struct CK_ECDH2_DERIVE_PARAMS {
4127+ CK_EC_KDF_TYPE kdf;
4128+ CK_ULONG ulSharedDataLen;
4129+ CK_BYTE_PTR pSharedData;
4130+ CK_ULONG ulPublicDataLen;
4131+ CK_BYTE_PTR pPublicData;
4132+ CK_ULONG ulPrivateDataLen;
4133+ CK_OBJECT_HANDLE hPrivateData;
4134+ CK_ULONG ulPublicDataLen2;
4135+ CK_BYTE_PTR pPublicData2;
4136+} CK_ECDH2_DERIVE_PARAMS;
4137+
4138+typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR;
4139+
4140+typedef struct CK_ECMQV_DERIVE_PARAMS {
4141+ CK_EC_KDF_TYPE kdf;
4142+ CK_ULONG ulSharedDataLen;
4143+ CK_BYTE_PTR pSharedData;
4144+ CK_ULONG ulPublicDataLen;
4145+ CK_BYTE_PTR pPublicData;
4146+ CK_ULONG ulPrivateDataLen;
4147+ CK_OBJECT_HANDLE hPrivateData;
4148+ CK_ULONG ulPublicDataLen2;
4149+ CK_BYTE_PTR pPublicData2;
4150+ CK_OBJECT_HANDLE publicKey;
4151+} CK_ECMQV_DERIVE_PARAMS;
4152+
4153+typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR;
4154+
4155+/* Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the
4156+ * CKM_X9_42_DH_PARAMETER_GEN mechanisms (new for PKCS #11 v2.11) */
4157+typedef CK_ULONG CK_X9_42_DH_KDF_TYPE;
4158+typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR;
4159+
4160+/* The following X9.42 DH key derivation functions are defined
4161+ (besides CKD_NULL already defined : */
4162+#define CKD_SHA1_KDF_ASN1 0x00000003
4163+#define CKD_SHA1_KDF_CONCATENATE 0x00000004
4164+
4165+/* CK_X9_42_DH1_DERIVE_PARAMS is new for v2.11.
4166+ * CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the
4167+ * CKM_X9_42_DH_DERIVE key derivation mechanism, where each party
4168+ * contributes one key pair */
4169+typedef struct CK_X9_42_DH1_DERIVE_PARAMS {
4170+ CK_X9_42_DH_KDF_TYPE kdf;
4171+ CK_ULONG ulOtherInfoLen;
4172+ CK_BYTE_PTR pOtherInfo;
4173+ CK_ULONG ulPublicDataLen;
4174+ CK_BYTE_PTR pPublicData;
4175+} CK_X9_42_DH1_DERIVE_PARAMS;
4176+
4177+typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR;
4178+
4179+/* CK_X9_42_DH2_DERIVE_PARAMS is new for v2.11.
4180+ * CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the
4181+ * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation
4182+ * mechanisms, where each party contributes two key pairs */
4183+typedef struct CK_X9_42_DH2_DERIVE_PARAMS {
4184+ CK_X9_42_DH_KDF_TYPE kdf;
4185+ CK_ULONG ulOtherInfoLen;
4186+ CK_BYTE_PTR pOtherInfo;
4187+ CK_ULONG ulPublicDataLen;
4188+ CK_BYTE_PTR pPublicData;
4189+ CK_ULONG ulPrivateDataLen;
4190+ CK_OBJECT_HANDLE hPrivateData;
4191+ CK_ULONG ulPublicDataLen2;
4192+ CK_BYTE_PTR pPublicData2;
4193+} CK_X9_42_DH2_DERIVE_PARAMS;
4194+
4195+typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR;
4196+
4197+typedef struct CK_X9_42_MQV_DERIVE_PARAMS {
4198+ CK_X9_42_DH_KDF_TYPE kdf;
4199+ CK_ULONG ulOtherInfoLen;
4200+ CK_BYTE_PTR pOtherInfo;
4201+ CK_ULONG ulPublicDataLen;
4202+ CK_BYTE_PTR pPublicData;
4203+ CK_ULONG ulPrivateDataLen;
4204+ CK_OBJECT_HANDLE hPrivateData;
4205+ CK_ULONG ulPublicDataLen2;
4206+ CK_BYTE_PTR pPublicData2;
4207+ CK_OBJECT_HANDLE publicKey;
4208+} CK_X9_42_MQV_DERIVE_PARAMS;
4209+
4210+typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR;
4211+
4212+/* CK_KEA_DERIVE_PARAMS provides the parameters to the
4213+ * CKM_KEA_DERIVE mechanism */
4214+/* CK_KEA_DERIVE_PARAMS is new for v2.0 */
4215+typedef struct CK_KEA_DERIVE_PARAMS {
4216+ CK_BBOOL isSender;
4217+ CK_ULONG ulRandomLen;
4218+ CK_BYTE_PTR pRandomA;
4219+ CK_BYTE_PTR pRandomB;
4220+ CK_ULONG ulPublicDataLen;
4221+ CK_BYTE_PTR pPublicData;
4222+} CK_KEA_DERIVE_PARAMS;
4223+
4224+typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR;
4225+
4226+
4227+/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and
4228+ * CKM_RC2_MAC mechanisms. An instance of CK_RC2_PARAMS just
4229+ * holds the effective keysize */
4230+typedef CK_ULONG CK_RC2_PARAMS;
4231+
4232+typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR;
4233+
4234+
4235+/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC
4236+ * mechanism */
4237+typedef struct CK_RC2_CBC_PARAMS {
4238+ /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for
4239+ * v2.0 */
4240+ CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
4241+
4242+ CK_BYTE iv[8]; /* IV for CBC mode */
4243+} CK_RC2_CBC_PARAMS;
4244+
4245+typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR;
4246+
4247+
4248+/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the
4249+ * CKM_RC2_MAC_GENERAL mechanism */
4250+/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */
4251+typedef struct CK_RC2_MAC_GENERAL_PARAMS {
4252+ CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
4253+ CK_ULONG ulMacLength; /* Length of MAC in bytes */
4254+} CK_RC2_MAC_GENERAL_PARAMS;
4255+
4256+typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \
4257+ CK_RC2_MAC_GENERAL_PARAMS_PTR;
4258+
4259+
4260+/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and
4261+ * CKM_RC5_MAC mechanisms */
4262+/* CK_RC5_PARAMS is new for v2.0 */
4263+typedef struct CK_RC5_PARAMS {
4264+ CK_ULONG ulWordsize; /* wordsize in bits */
4265+ CK_ULONG ulRounds; /* number of rounds */
4266+} CK_RC5_PARAMS;
4267+
4268+typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR;
4269+
4270+
4271+/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC
4272+ * mechanism */
4273+/* CK_RC5_CBC_PARAMS is new for v2.0 */
4274+typedef struct CK_RC5_CBC_PARAMS {
4275+ CK_ULONG ulWordsize; /* wordsize in bits */
4276+ CK_ULONG ulRounds; /* number of rounds */
4277+ CK_BYTE_PTR pIv; /* pointer to IV */
4278+ CK_ULONG ulIvLen; /* length of IV in bytes */
4279+} CK_RC5_CBC_PARAMS;
4280+
4281+typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR;
4282+
4283+
4284+/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the
4285+ * CKM_RC5_MAC_GENERAL mechanism */
4286+/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */
4287+typedef struct CK_RC5_MAC_GENERAL_PARAMS {
4288+ CK_ULONG ulWordsize; /* wordsize in bits */
4289+ CK_ULONG ulRounds; /* number of rounds */
4290+ CK_ULONG ulMacLength; /* Length of MAC in bytes */
4291+} CK_RC5_MAC_GENERAL_PARAMS;
4292+
4293+typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \
4294+ CK_RC5_MAC_GENERAL_PARAMS_PTR;
4295+
4296+
4297+/* CK_MAC_GENERAL_PARAMS provides the parameters to most block
4298+ * ciphers' MAC_GENERAL mechanisms. Its value is the length of
4299+ * the MAC */
4300+/* CK_MAC_GENERAL_PARAMS is new for v2.0 */
4301+typedef CK_ULONG CK_MAC_GENERAL_PARAMS;
4302+
4303+typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
4304+
4305+/* CK_DES/AES_ECB/CBC_ENCRYPT_DATA_PARAMS are new for v2.20 */
4306+typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS {
4307+ CK_BYTE iv[8];
4308+ CK_BYTE_PTR pData;
4309+ CK_ULONG length;
4310+} CK_DES_CBC_ENCRYPT_DATA_PARAMS;
4311+
4312+typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR;
4313+
4314+typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS {
4315+ CK_BYTE iv[16];
4316+ CK_BYTE_PTR pData;
4317+ CK_ULONG length;
4318+} CK_AES_CBC_ENCRYPT_DATA_PARAMS;
4319+
4320+typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR;
4321+
4322+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
4323+ * CKM_SKIPJACK_PRIVATE_WRAP mechanism */
4324+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */
4325+typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS {
4326+ CK_ULONG ulPasswordLen;
4327+ CK_BYTE_PTR pPassword;
4328+ CK_ULONG ulPublicDataLen;
4329+ CK_BYTE_PTR pPublicData;
4330+ CK_ULONG ulPAndGLen;
4331+ CK_ULONG ulQLen;
4332+ CK_ULONG ulRandomLen;
4333+ CK_BYTE_PTR pRandomA;
4334+ CK_BYTE_PTR pPrimeP;
4335+ CK_BYTE_PTR pBaseG;
4336+ CK_BYTE_PTR pSubprimeQ;
4337+} CK_SKIPJACK_PRIVATE_WRAP_PARAMS;
4338+
4339+typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \
4340+ CK_SKIPJACK_PRIVATE_WRAP_PTR;
4341+
4342+
4343+/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the
4344+ * CKM_SKIPJACK_RELAYX mechanism */
4345+/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */
4346+typedef struct CK_SKIPJACK_RELAYX_PARAMS {
4347+ CK_ULONG ulOldWrappedXLen;
4348+ CK_BYTE_PTR pOldWrappedX;
4349+ CK_ULONG ulOldPasswordLen;
4350+ CK_BYTE_PTR pOldPassword;
4351+ CK_ULONG ulOldPublicDataLen;
4352+ CK_BYTE_PTR pOldPublicData;
4353+ CK_ULONG ulOldRandomLen;
4354+ CK_BYTE_PTR pOldRandomA;
4355+ CK_ULONG ulNewPasswordLen;
4356+ CK_BYTE_PTR pNewPassword;
4357+ CK_ULONG ulNewPublicDataLen;
4358+ CK_BYTE_PTR pNewPublicData;
4359+ CK_ULONG ulNewRandomLen;
4360+ CK_BYTE_PTR pNewRandomA;
4361+} CK_SKIPJACK_RELAYX_PARAMS;
4362+
4363+typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \
4364+ CK_SKIPJACK_RELAYX_PARAMS_PTR;
4365+
4366+
4367+typedef struct CK_PBE_PARAMS {
4368+ CK_BYTE_PTR pInitVector;
4369+ CK_UTF8CHAR_PTR pPassword;
4370+ CK_ULONG ulPasswordLen;
4371+ CK_BYTE_PTR pSalt;
4372+ CK_ULONG ulSaltLen;
4373+ CK_ULONG ulIteration;
4374+} CK_PBE_PARAMS;
4375+
4376+typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
4377+
4378+
4379+/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the
4380+ * CKM_KEY_WRAP_SET_OAEP mechanism */
4381+/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */
4382+typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS {
4383+ CK_BYTE bBC; /* block contents byte */
4384+ CK_BYTE_PTR pX; /* extra data */
4385+ CK_ULONG ulXLen; /* length of extra data in bytes */
4386+} CK_KEY_WRAP_SET_OAEP_PARAMS;
4387+
4388+typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \
4389+ CK_KEY_WRAP_SET_OAEP_PARAMS_PTR;
4390+
4391+
4392+typedef struct CK_SSL3_RANDOM_DATA {
4393+ CK_BYTE_PTR pClientRandom;
4394+ CK_ULONG ulClientRandomLen;
4395+ CK_BYTE_PTR pServerRandom;
4396+ CK_ULONG ulServerRandomLen;
4397+} CK_SSL3_RANDOM_DATA;
4398+
4399+
4400+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
4401+ CK_SSL3_RANDOM_DATA RandomInfo;
4402+ CK_VERSION_PTR pVersion;
4403+} CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
4404+
4405+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \
4406+ CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR;
4407+
4408+
4409+typedef struct CK_SSL3_KEY_MAT_OUT {
4410+ CK_OBJECT_HANDLE hClientMacSecret;
4411+ CK_OBJECT_HANDLE hServerMacSecret;
4412+ CK_OBJECT_HANDLE hClientKey;
4413+ CK_OBJECT_HANDLE hServerKey;
4414+ CK_BYTE_PTR pIVClient;
4415+ CK_BYTE_PTR pIVServer;
4416+} CK_SSL3_KEY_MAT_OUT;
4417+
4418+typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR;
4419+
4420+
4421+typedef struct CK_SSL3_KEY_MAT_PARAMS {
4422+ CK_ULONG ulMacSizeInBits;
4423+ CK_ULONG ulKeySizeInBits;
4424+ CK_ULONG ulIVSizeInBits;
4425+ CK_BBOOL bIsExport;
4426+ CK_SSL3_RANDOM_DATA RandomInfo;
4427+ CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
4428+} CK_SSL3_KEY_MAT_PARAMS;
4429+
4430+typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
4431+
4432+/* CK_TLS_PRF_PARAMS is new for version 2.20 */
4433+typedef struct CK_TLS_PRF_PARAMS {
4434+ CK_BYTE_PTR pSeed;
4435+ CK_ULONG ulSeedLen;
4436+ CK_BYTE_PTR pLabel;
4437+ CK_ULONG ulLabelLen;
4438+ CK_BYTE_PTR pOutput;
4439+ CK_ULONG_PTR pulOutputLen;
4440+} CK_TLS_PRF_PARAMS;
4441+
4442+typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR;
4443+
4444+/* WTLS is new for version 2.20 */
4445+typedef struct CK_WTLS_RANDOM_DATA {
4446+ CK_BYTE_PTR pClientRandom;
4447+ CK_ULONG ulClientRandomLen;
4448+ CK_BYTE_PTR pServerRandom;
4449+ CK_ULONG ulServerRandomLen;
4450+} CK_WTLS_RANDOM_DATA;
4451+
4452+typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR;
4453+
4454+typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS {
4455+ CK_MECHANISM_TYPE DigestMechanism;
4456+ CK_WTLS_RANDOM_DATA RandomInfo;
4457+ CK_BYTE_PTR pVersion;
4458+} CK_WTLS_MASTER_KEY_DERIVE_PARAMS;
4459+
4460+typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \
4461+ CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR;
4462+
4463+typedef struct CK_WTLS_PRF_PARAMS {
4464+ CK_MECHANISM_TYPE DigestMechanism;
4465+ CK_BYTE_PTR pSeed;
4466+ CK_ULONG ulSeedLen;
4467+ CK_BYTE_PTR pLabel;
4468+ CK_ULONG ulLabelLen;
4469+ CK_BYTE_PTR pOutput;
4470+ CK_ULONG_PTR pulOutputLen;
4471+} CK_WTLS_PRF_PARAMS;
4472+
4473+typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR;
4474+
4475+typedef struct CK_WTLS_KEY_MAT_OUT {
4476+ CK_OBJECT_HANDLE hMacSecret;
4477+ CK_OBJECT_HANDLE hKey;
4478+ CK_BYTE_PTR pIV;
4479+} CK_WTLS_KEY_MAT_OUT;
4480+
4481+typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR;
4482+
4483+typedef struct CK_WTLS_KEY_MAT_PARAMS {
4484+ CK_MECHANISM_TYPE DigestMechanism;
4485+ CK_ULONG ulMacSizeInBits;
4486+ CK_ULONG ulKeySizeInBits;
4487+ CK_ULONG ulIVSizeInBits;
4488+ CK_ULONG ulSequenceNumber;
4489+ CK_BBOOL bIsExport;
4490+ CK_WTLS_RANDOM_DATA RandomInfo;
4491+ CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
4492+} CK_WTLS_KEY_MAT_PARAMS;
4493+
4494+typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR;
4495+
4496+/* CMS is new for version 2.20 */
4497+typedef struct CK_CMS_SIG_PARAMS {
4498+ CK_OBJECT_HANDLE certificateHandle;
4499+ CK_MECHANISM_PTR pSigningMechanism;
4500+ CK_MECHANISM_PTR pDigestMechanism;
4501+ CK_UTF8CHAR_PTR pContentType;
4502+ CK_BYTE_PTR pRequestedAttributes;
4503+ CK_ULONG ulRequestedAttributesLen;
4504+ CK_BYTE_PTR pRequiredAttributes;
4505+ CK_ULONG ulRequiredAttributesLen;
4506+} CK_CMS_SIG_PARAMS;
4507+
4508+typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR;
4509+
4510+typedef struct CK_KEY_DERIVATION_STRING_DATA {
4511+ CK_BYTE_PTR pData;
4512+ CK_ULONG ulLen;
4513+} CK_KEY_DERIVATION_STRING_DATA;
4514+
4515+typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \
4516+ CK_KEY_DERIVATION_STRING_DATA_PTR;
4517+
4518+
4519+/* The CK_EXTRACT_PARAMS is used for the
4520+ * CKM_EXTRACT_KEY_FROM_KEY mechanism. It specifies which bit
4521+ * of the base key should be used as the first bit of the
4522+ * derived key */
4523+/* CK_EXTRACT_PARAMS is new for v2.0 */
4524+typedef CK_ULONG CK_EXTRACT_PARAMS;
4525+
4526+typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
4527+
4528+/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is new for v2.10.
4529+ * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to
4530+ * indicate the Pseudo-Random Function (PRF) used to generate
4531+ * key bits using PKCS #5 PBKDF2. */
4532+typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE;
4533+
4534+typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR;
4535+
4536+/* The following PRFs are defined in PKCS #5 v2.0. */
4537+#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001
4538+
4539+
4540+/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is new for v2.10.
4541+ * CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the
4542+ * source of the salt value when deriving a key using PKCS #5
4543+ * PBKDF2. */
4544+typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE;
4545+
4546+typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR;
4547+
4548+/* The following salt value sources are defined in PKCS #5 v2.0. */
4549+#define CKZ_SALT_SPECIFIED 0x00000001
4550+
4551+/* CK_PKCS5_PBKD2_PARAMS is new for v2.10.
4552+ * CK_PKCS5_PBKD2_PARAMS is a structure that provides the
4553+ * parameters to the CKM_PKCS5_PBKD2 mechanism. */
4554+typedef struct CK_PKCS5_PBKD2_PARAMS {
4555+ CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource;
4556+ CK_VOID_PTR pSaltSourceData;
4557+ CK_ULONG ulSaltSourceDataLen;
4558+ CK_ULONG iterations;
4559+ CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
4560+ CK_VOID_PTR pPrfData;
4561+ CK_ULONG ulPrfDataLen;
4562+ CK_UTF8CHAR_PTR pPassword;
4563+ CK_ULONG_PTR ulPasswordLen;
4564+} CK_PKCS5_PBKD2_PARAMS;
4565+
4566+typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
4567+
4568+#endif
4569diff -urNp openssh-4.4p1/pkcs11-helper.c openssh-4.4p1+pkcs11-0.17/pkcs11-helper.c
4570--- openssh-4.4p1/pkcs11-helper.c 1970-01-01 02:00:00.000000000 +0200
4571+++ openssh-4.4p1+pkcs11-0.17/pkcs11-helper.c 2006-10-22 17:11:50.000000000 +0200
4572@@ -0,0 +1,11337 @@
4573+/*
4574+ * Copyright (c) 2005-2006 Alon Bar-Lev <alon.barlev@gmail.com>
4575+ * All rights reserved.
4576+ *
4577+ * This software is available to you under a choice of one of two
4578+ * licenses. You may choose to be licensed under the terms of the GNU
4579+ * General Public License (GPL) Version 2, or the OpenIB.org BSD license.
4580+ *
4581+ * GNU General Public License (GPL) Version 2
4582+ * ===========================================
4583+ * This program is free software; you can redistribute it and/or modify
4584+ * it under the terms of the GNU General Public License version 2
4585+ * as published by the Free Software Foundation.
4586+ *
4587+ * This program is distributed in the hope that it will be useful,
4588+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4589+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4590+ * GNU General Public License for more details.
4591+ *
4592+ * You should have received a copy of the GNU General Public License
4593+ * along with this program (see the file COPYING[.GPL2] included with this
4594+ * distribution); if not, write to the Free Software Foundation, Inc.,
4595+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4596+ *
4597+ * OpenIB.org BSD license
4598+ * =======================
4599+ * Redistribution and use in source and binary forms, with or without modifi-
4600+ * cation, are permitted provided that the following conditions are met:
4601+ *
4602+ * o Redistributions of source code must retain the above copyright notice,
4603+ * this list of conditions and the following disclaimer.
4604+ *
4605+ * o Redistributions in binary form must reproduce the above copyright no-
4606+ * tice, this list of conditions and the following disclaimer in the do-
4607+ * cumentation and/or other materials provided with the distribution.
4608+ *
4609+ * o The names of the contributors may not be used to endorse or promote
4610+ * products derived from this software without specific prior written
4611+ * permission.
4612+ *
4613+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4614+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
4615+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
4616+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LI-
4617+ * ABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUEN-
4618+ * TIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4619+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEV-
4620+ * ER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABI-
4621+ * LITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
4622+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4623+ */
4624+
4625+/*
4626+ * The routines in this file deal with providing private key cryptography
4627+ * using RSA Security Inc. PKCS #11 Cryptographic Token Interface (Cryptoki).
4628+ *
4629+ */
4630+
4631+/*
4632+ * Changelog
4633+ *
4634+ * 2006.09.24
4635+ * - (alonbl) Fix invalid certificate max size handling (Zeljko Vrba).
4636+ * - (alonbl) Added object serialization.
4637+ * - (alonbl) Added user data to hooks.
4638+ * - (alonbl) Added a force login method.
4639+ * - (alonbl) Added support for gnutls in addition to openssl.
4640+ * - (alonbl) Fixup threading lock issues.
4641+ * - (alonbl) Added support for duplicate serial tokens, based on label.
4642+ * - (alonbl) Added workaround for OpenSC cards, OpenSC bug#108, thanks to Kaupo Arulo.
4643+ * - (alonbl) Added a methods to lock session between two sign/decrypt operations.
4644+ * - (alonbl) Modified openssl interface.
4645+ * - (alonbl) Release 01.02.
4646+ *
4647+ * 2006.06.26
4648+ * - (alonbl) Fix handling mutiple providers.
4649+ * - (alonbl) Release 01.01.
4650+ *
4651+ * 2006.05.14
4652+ * - (alonbl) First stable release.
4653+ * - (alonbl) Release 01.00.
4654+ *
4655+ */
4656+
4657+#include "pkcs11-helper-config.h"
4658+
4659+#if defined(ENABLE_PKCS11H_HELPER)
4660+
4661+#include "pkcs11-helper.h"
4662+
4663+/*===========================================
4664+ * Constants
4665+ */
4666+
4667+#if defined(USE_PKCS11H_OPENSSL)
4668+
4669+#if OPENSSL_VERSION_NUMBER < 0x00907000L && defined(CRYPTO_LOCK_ENGINE)
4670+# define RSA_get_default_method RSA_get_default_openssl_method
4671+#else
4672+# ifdef HAVE_ENGINE_GET_DEFAULT_RSA
4673+# include <openssl/engine.h>
4674+# if OPENSSL_VERSION_NUMBER < 0x0090704fL
4675+# define BROKEN_OPENSSL_ENGINE
4676+# endif
4677+# endif
4678+#endif
4679+
4680+#if OPENSSL_VERSION_NUMBER < 0x00907000L
4681+#if !defined(RSA_PKCS1_PADDING_SIZE)
4682+#define RSA_PKCS1_PADDING_SIZE 11
4683+#endif
4684+#endif
4685+
4686+#endif
4687+
4688+#define PKCS11H_INVALID_SLOT_ID ((CK_SLOT_ID)-1)
4689+#define PKCS11H_INVALID_SESSION_HANDLE ((CK_SESSION_HANDLE)-1)
4690+#define PKCS11H_INVALID_OBJECT_HANDLE ((CK_OBJECT_HANDLE)-1)
4691+
4692+#define PKCS11H_DEFAULT_SLOTEVENT_POLL 5000
4693+#define PKCS11H_DEFAULT_MAX_LOGIN_RETRY 3
4694+#define PKCS11H_DEFAULT_PIN_CACHE_PERIOD PKCS11H_PIN_CACHE_INFINITE
4695+
4696+#define PKCS11H_SERIALIZE_INVALID_CHARS "\\/\"'%&#@!?$* <>{}[]()`|"
4697+
4698+enum _pkcs11h_private_op_e {
4699+ _pkcs11h_private_op_sign=0,
4700+ _pkcs11h_private_op_sign_recover,
4701+ _pkcs11h_private_op_decrypt
4702+};
4703+
4704+/*===========================================
4705+ * Macros
4706+ */
4707+
4708+#define PKCS11H_MSG_LEVEL_TEST(flags) (((unsigned int)flags) <= s_pkcs11h_loglevel)
4709+
4710+#if defined(HAVE_CPP_VARARG_MACRO_ISO) && !defined(__LCLINT__)
4711+# define PKCS11H_LOG(flags, ...) do { if (PKCS11H_MSG_LEVEL_TEST(flags)) _pkcs11h_log((flags), __VA_ARGS__); } while (FALSE)
4712+# ifdef ENABLE_PKCS11H_DEBUG
4713+# define PKCS11H_DEBUG(flags, ...) do { if (PKCS11H_MSG_LEVEL_TEST(flags)) _pkcs11h_log((flags), __VA_ARGS__); } while (FALSE)
4714+# else
4715+# define PKCS11H_DEBUG(flags, ...)
4716+# endif
4717+#elif defined(HAVE_CPP_VARARG_MACRO_GCC) && !defined(__LCLINT__)
4718+# define PKCS11H_LOG(flags, args...) do { if (PKCS11H_MSG_LEVEL_TEST(flags)) _pkcs11h_log((flags), args); } while (FALSE)
4719+# ifdef ENABLE_PKCS11H_DEBUG
4720+# define PKCS11H_DEBUG(flags, args...) do { if (PKCS11H_MSG_LEVEL_TEST(flags)) _pkcs11h_log((flags), args); } while (FALSE)
4721+# else
4722+# define PKCS11H_DEBUG(flags, args...)
4723+# endif
4724+#else
4725+# define PKCS11H_LOG _pkcs11h_log
4726+# define PKCS11H_DEBUG _pkcs11h_log
4727+#endif
4728+
4729+/*===========================================
4730+ * Types
4731+ */
4732+
4733+struct pkcs11h_provider_s;
4734+struct pkcs11h_session_s;
4735+struct pkcs11h_data_s;
4736+typedef struct pkcs11h_provider_s *pkcs11h_provider_t;
4737+typedef struct pkcs11h_session_s *pkcs11h_session_t;
4738+typedef struct pkcs11h_data_s *pkcs11h_data_t;
4739+
4740+#if defined(USE_PKCS11H_OPENSSL)
4741+
4742+#if OPENSSL_VERSION_NUMBER < 0x00908000L
4743+typedef unsigned char *pkcs11_openssl_d2i_t;
4744+#else
4745+typedef const unsigned char *pkcs11_openssl_d2i_t;
4746+#endif
4747+
4748+#endif
4749+
4750+#if defined(ENABLE_PKCS11H_THREADING)
4751+
4752+#define PKCS11H_COND_INFINITE 0xffffffff
4753+
4754+#if defined(WIN32)
4755+#define PKCS11H_THREAD_NULL NULL
4756+typedef HANDLE pkcs11h_cond_t;
4757+typedef HANDLE pkcs11h_mutex_t;
4758+typedef HANDLE pkcs11h_thread_t;
4759+#else
4760+#define PKCS11H_THREAD_NULL 0l
4761+typedef pthread_mutex_t pkcs11h_mutex_t;
4762+typedef pthread_t pkcs11h_thread_t;
4763+
4764+typedef struct {
4765+ pthread_cond_t cond;
4766+ pthread_mutex_t mut;
4767+} pkcs11h_cond_t;
4768+
4769+typedef struct __pkcs11h_threading_mutex_entry_s {
4770+ struct __pkcs11h_threading_mutex_entry_s *next;
4771+ pkcs11h_mutex_t *p_mutex;
4772+ PKCS11H_BOOL locked;
4773+} *__pkcs11h_threading_mutex_entry_t;
4774+#endif
4775+
4776+typedef void * (*pkcs11h_thread_start_t)(void *);
4777+
4778+typedef struct {
4779+ pkcs11h_thread_start_t start;
4780+ void *data;
4781+} __pkcs11h_thread_data_t;
4782+
4783+#endif /* ENABLE_PKCS11H_THREADING */
4784+
4785+struct pkcs11h_provider_s {
4786+ pkcs11h_provider_t next;
4787+
4788+ PKCS11H_BOOL enabled;
4789+ char reference[1024];
4790+ char manufacturerID[sizeof (((CK_TOKEN_INFO *)NULL)->manufacturerID)+1];
4791+
4792+#if defined(WIN32)
4793+ HANDLE handle;
4794+#else
4795+ void *handle;
4796+#endif
4797+
4798+ CK_FUNCTION_LIST_PTR f;
4799+ PKCS11H_BOOL should_finalize;
4800+ PKCS11H_BOOL allow_protected_auth;
4801+ PKCS11H_BOOL cert_is_private;
4802+ unsigned mask_sign_mode;
4803+ int slot_event_method;
4804+ int slot_poll_interval;
4805+
4806+#if defined(ENABLE_PKCS11H_SLOTEVENT)
4807+ pkcs11h_thread_t slotevent_thread;
4808+#endif
4809+};
4810+
4811+struct pkcs11h_session_s {
4812+ pkcs11h_session_t next;
4813+
4814+ int reference_count;
4815+ PKCS11H_BOOL valid;
4816+
4817+ pkcs11h_provider_t provider;
4818+
4819+ pkcs11h_token_id_t token_id;
4820+
4821+ CK_SESSION_HANDLE session_handle;
4822+
4823+ PKCS11H_BOOL allow_protected_auth_supported;
4824+ int pin_cache_period;
4825+ time_t pin_expire_time;
4826+
4827+#if defined(ENABLE_PKCS11H_ENUM)
4828+#if defined(ENABLE_PKCS11H_CERTIFICATE)
4829+ pkcs11h_certificate_id_list_t cached_certs;
4830+ PKCS11H_BOOL touch;
4831+#endif
4832+#endif
4833+
4834+#if defined(ENABLE_PKCS11H_THREADING)
4835+ pkcs11h_mutex_t mutex;
4836+#endif
4837+};
4838+
4839+#if defined (ENABLE_PKCS11H_CERTIFICATE)
4840+
4841+struct pkcs11h_certificate_s {
4842+
4843+ pkcs11h_certificate_id_t id;
4844+ int pin_cache_period;
4845+ PKCS11H_BOOL pin_cache_populated_to_session;
4846+
4847+ unsigned mask_sign_mode;
4848+
4849+ pkcs11h_session_t session;
4850+ CK_OBJECT_HANDLE key_handle;
4851+
4852+ PKCS11H_BOOL operation_active;
4853+
4854+#if defined(ENABLE_PKCS11H_THREADING)
4855+ pkcs11h_mutex_t mutex;
4856+#endif
4857+
4858+ unsigned mask_prompt;
4859+ void * user_data;
4860+};
4861+
4862+#endif /* ENABLE_PKCS11H_CERTIFICATE */
4863+
4864+struct pkcs11h_data_s {
4865+ PKCS11H_BOOL initialized;
4866+ int pin_cache_period;
4867+
4868+ pkcs11h_provider_t providers;
4869+ pkcs11h_session_t sessions;
4870+
4871+ struct {
4872+ void * log_data;
4873+ void * slotevent_data;
4874+ void * token_prompt_data;
4875+ void * pin_prompt_data;
4876+ pkcs11h_hook_log_t log;
4877+ pkcs11h_hook_slotevent_t slotevent;
4878+ pkcs11h_hook_token_prompt_t token_prompt;
4879+ pkcs11h_hook_pin_prompt_t pin_prompt;
4880+ } hooks;
4881+
4882+ PKCS11H_BOOL allow_protected_auth;
4883+ unsigned max_retries;
4884+
4885+#if defined(ENABLE_PKCS11H_THREADING)
4886+ struct {
4887+ pkcs11h_mutex_t global;
4888+ pkcs11h_mutex_t session;
4889+ pkcs11h_mutex_t cache;
4890+ } mutexes;
4891+#endif
4892+
4893+#if defined(ENABLE_PKCS11H_SLOTEVENT)
4894+ struct {
4895+ PKCS11H_BOOL initialized;
4896+ PKCS11H_BOOL should_terminate;
4897+ PKCS11H_BOOL skip_event;
4898+ pkcs11h_cond_t cond_event;
4899+ pkcs11h_thread_t thread;
4900+ } slotevent;
4901+#endif
4902+};
4903+
4904+#if defined(ENABLE_PKCS11H_OPENSSL)
4905+struct pkcs11h_openssl_session_s {
4906+ int reference_count;
4907+ PKCS11H_BOOL initialized;
4908+ X509 *x509;
4909+ RSA_METHOD smart_rsa;
4910+ int (*orig_finish)(RSA *rsa);
4911+ pkcs11h_certificate_t certificate;
4912+ pkcs11h_hook_openssl_cleanup_t cleanup_hook;
4913+};
4914+#endif
4915+
4916+/*======================================================================*
4917+ * MEMORY INTERFACE
4918+ *======================================================================*/
4919+
4920+static
4921+CK_RV
4922+_pkcs11h_mem_malloc (
4923+ OUT const void * * const p,
4924+ IN const size_t s
4925+);
4926+static
4927+CK_RV
4928+_pkcs11h_mem_free (
4929+ IN const void * * const p
4930+);
4931+static
4932+CK_RV
4933+_pkcs11h_mem_strdup (
4934+ OUT const char * * const dest,
4935+ IN const char * const src
4936+);
4937+static
4938+CK_RV
4939+_pkcs11h_mem_duplicate (
4940+ OUT const void * * const dest,
4941+ OUT size_t * const dest_size,
4942+ IN const void * const src,
4943+ IN const size_t mem_size
4944+);
4945+
4946+#if defined(ENABLE_PKCS11H_THREADING)
4947+/*======================================================================*
4948+ * THREADING INTERFACE
4949+ *======================================================================*/
4950+
4951+static
4952+void
4953+_pkcs11h_threading_sleep (
4954+ IN const unsigned milli
4955+);
4956+static
4957+CK_RV
4958+_pkcs11h_threading_mutexInit (
4959+ OUT pkcs11h_mutex_t * const mutex
4960+);
4961+static
4962+CK_RV
4963+_pkcs11h_threading_mutexLock (
4964+ IN OUT pkcs11h_mutex_t *const mutex
4965+);
4966+static
4967+CK_RV
4968+_pkcs11h_threading_mutexRelease (
4969+ IN OUT pkcs11h_mutex_t *const mutex
4970+);
4971+static
4972+CK_RV
4973+_pkcs11h_threading_mutexFree (
4974+ IN OUT pkcs11h_mutex_t *const mutex
4975+);
4976+#if !defined(WIN32)
4977+static
4978+void
4979+__pkcs1h_threading_mutexLockAll ();
4980+static
4981+void
4982+__pkcs1h_threading_mutexReleaseAll ();
4983+#endif
4984+static
4985+CK_RV
4986+_pkcs11h_threading_condSignal (
4987+ IN OUT pkcs11h_cond_t *const cond
4988+);
4989+static
4990+CK_RV
4991+_pkcs11h_threading_condInit (
4992+ OUT pkcs11h_cond_t * const cond
4993+);
4994+static
4995+CK_RV
4996+_pkcs11h_threading_condWait (
4997+ IN OUT pkcs11h_cond_t *const cond,
4998+ IN const unsigned milli
4999+);
5000+static
5001+CK_RV
5002+_pkcs11h_threading_condFree (
5003+ IN OUT pkcs11h_cond_t *const cond
5004+);
5005+static
5006+CK_RV
5007+_pkcs11h_threading_threadStart (
5008+ OUT pkcs11h_thread_t * const thread,
5009+ IN pkcs11h_thread_start_t const start,
5010+ IN void * data
5011+);
5012+static
5013+CK_RV
5014+_pkcs11h_threading_threadJoin (
5015+ IN pkcs11h_thread_t * const thread
5016+);
5017+#endif /* ENABLE_PKCS11H_THREADING */
5018+
5019+/*======================================================================*
5020+ * COMMON INTERNAL INTERFACE
5021+ *======================================================================*/
5022+
5023+static
5024+void
5025+_pkcs11h_util_fixupFixedString (
5026+ OUT char * const target, /* MUST BE >= length+1 */
5027+ IN const char * const source,
5028+ IN const size_t length /* FIXED STRING LENGTH */
5029+);
5030+static
5031+CK_RV
5032+_pkcs11h_util_hexToBinary (
5033+ OUT unsigned char * const target,
5034+ IN const char * const source,
5035+ IN OUT size_t * const p_target_size
5036+);
5037+static
5038+CK_RV
5039+_pkcs11h_util_binaryToHex (
5040+ OUT char * const target,
5041+ IN const size_t target_size,
5042+ IN const unsigned char * const source,
5043+ IN const size_t source_size
5044+);
5045+CK_RV
5046+_pkcs11h_util_escapeString (
5047+ IN OUT char * const target,
5048+ IN const char * const source,
5049+ IN size_t * const max,
5050+ IN const char * const invalid_chars
5051+);
5052+static
5053+CK_RV
5054+_pkcs11h_util_unescapeString (
5055+ IN OUT char * const target,
5056+ IN const char * const source,
5057+ IN size_t * const max
5058+);
5059+static
5060+void
5061+_pkcs11h_log (
5062+ IN const unsigned flags,
5063+ IN const char * const format,
5064+ IN ...
5065+)
5066+#ifdef __GNUC__
5067+ __attribute__ ((format (printf, 2, 3)))
5068+#endif
5069+ ;
5070+
5071+static
5072+CK_RV
5073+_pkcs11h_session_getSlotList (
5074+ IN const pkcs11h_provider_t provider,
5075+ IN const CK_BBOOL token_present,
5076+ OUT CK_SLOT_ID_PTR * const pSlotList,
5077+ OUT CK_ULONG_PTR pulCount
5078+);
5079+static
5080+CK_RV
5081+_pkcs11h_session_getObjectAttributes (
5082+ IN const pkcs11h_session_t session,
5083+ IN const CK_OBJECT_HANDLE object,
5084+ IN OUT const CK_ATTRIBUTE_PTR attrs,
5085+ IN const unsigned count
5086+);
5087+static
5088+CK_RV
5089+_pkcs11h_session_freeObjectAttributes (
5090+ IN OUT const CK_ATTRIBUTE_PTR attrs,
5091+ IN const unsigned count
5092+);
5093+static
5094+CK_RV
5095+_pkcs11h_session_findObjects (
5096+ IN const pkcs11h_session_t session,
5097+ IN const CK_ATTRIBUTE * const filter,
5098+ IN const CK_ULONG filter_attrs,
5099+ OUT CK_OBJECT_HANDLE **const p_objects,
5100+ OUT CK_ULONG *p_objects_found
5101+);
5102+static
5103+CK_RV
5104+_pkcs11h_token_getTokenId (
5105+ IN const CK_TOKEN_INFO_PTR info,
5106+ OUT pkcs11h_token_id_t * const p_token_id
5107+);
5108+static
5109+CK_RV
5110+_pkcs11h_token_newTokenId (
5111+ OUT pkcs11h_token_id_t * const token_id
5112+);
5113+static
5114+CK_RV
5115+_pkcs11h_session_getSessionByTokenId (
5116+ IN const pkcs11h_token_id_t token_id,
5117+ OUT pkcs11h_session_t * const p_session
5118+);
5119+static
5120+CK_RV
5121+_pkcs11h_session_release (
5122+ IN const pkcs11h_session_t session
5123+);
5124+static
5125+CK_RV
5126+_pkcs11h_session_reset (
5127+ IN const pkcs11h_session_t session,
5128+ IN void * const user_data,
5129+ IN const unsigned mask_prompt,
5130+ OUT CK_SLOT_ID * const p_slot
5131+);
5132+static
5133+CK_RV
5134+_pkcs11h_session_getObjectById (
5135+ IN const pkcs11h_session_t session,
5136+ IN const CK_OBJECT_CLASS class,
5137+ IN const CK_BYTE_PTR id,
5138+ IN const size_t id_size,
5139+ OUT CK_OBJECT_HANDLE * const p_handle
5140+);
5141+static
5142+CK_RV
5143+_pkcs11h_session_validate (
5144+ IN const pkcs11h_session_t session
5145+);
5146+static
5147+CK_RV
5148+_pkcs11h_session_touch (
5149+ IN const pkcs11h_session_t session
5150+);
5151+static
5152+CK_RV
5153+_pkcs11h_session_login (
5154+ IN const pkcs11h_session_t session,
5155+ IN const PKCS11H_BOOL public_only,
5156+ IN const PKCS11H_BOOL readonly,
5157+ IN void * const user_data,
5158+ IN const unsigned mask_prompt
5159+);
5160+static
5161+CK_RV
5162+_pkcs11h_session_logout (
5163+ IN const pkcs11h_session_t session
5164+);
5165+
5166+static
5167+void
5168+_pkcs11h_hooks_default_log (
5169+ IN void * const global_data,
5170+ IN const unsigned flags,
5171+ IN const char * const format,
5172+ IN va_list args
5173+);
5174+
5175+static
5176+PKCS11H_BOOL
5177+_pkcs11h_hooks_default_token_prompt (
5178+ IN void * const global_data,
5179+ IN void * const user_data,
5180+ IN const pkcs11h_token_id_t token,
5181+ IN const unsigned retry
5182+);
5183+
5184+static
5185+PKCS11H_BOOL
5186+_pkcs11h_hooks_default_pin_prompt (
5187+ IN void * const global_data,
5188+ IN void * const user_data,
5189+ IN const pkcs11h_token_id_t token,
5190+ IN const unsigned retry,
5191+ OUT char * const pin,
5192+ IN const size_t pin_max
5193+);
5194+
5195+#if !defined(WIN32)
5196+#if defined(ENABLE_PKCS11H_THREADING)
5197+static
5198+void
5199+__pkcs11h_threading_atfork_prepare ();
5200+static
5201+void
5202+__pkcs11h_threading_atfork_parent ();
5203+static
5204+void
5205+__pkcs11h_threading_atfork_child ();
5206+#endif
5207+static
5208+CK_RV
5209+_pkcs11h_forkFixup ();
5210+#endif
5211+
5212+#if defined(ENABLE_PKCS11H_CERTIFICATE)
5213+/*======================================================================*
5214+ * CERTIFICATE INTERFACE
5215+ *======================================================================*/
5216+
5217+static
5218+time_t
5219+_pkcs11h_certificate_getExpiration (
5220+ IN const unsigned char * const certificate,
5221+ IN const size_t certificate_size
5222+);
5223+static
5224+PKCS11H_BOOL
5225+_pkcs11h_certificate_isBetterCertificate (
5226+ IN const unsigned char * const current,
5227+ IN const size_t current_size,
5228+ IN const unsigned char * const newone,
5229+ IN const size_t newone_size
5230+);
5231+static
5232+CK_RV
5233+_pkcs11h_certificate_newCertificateId (
5234+ OUT pkcs11h_certificate_id_t * const certificate_id
5235+);
5236+static
5237+CK_RV
5238+_pkcs11h_certificate_getDN (
5239+ IN const unsigned char * const blob,
5240+ IN const size_t blob_size,
5241+ OUT char * const dn,
5242+ IN const size_t dn_size
5243+);
5244+static
5245+CK_RV
5246+_pkcs11h_certificate_loadCertificate (
5247+ IN const pkcs11h_certificate_t certificate
5248+);
5249+static
5250+CK_RV
5251+_pkcs11h_certificate_updateCertificateIdDescription (
5252+ IN OUT pkcs11h_certificate_id_t certificate_id
5253+);
5254+static
5255+CK_RV
5256+_pkcs11h_certificate_getKeyAttributes (
5257+ IN const pkcs11h_certificate_t certificate
5258+);
5259+static
5260+CK_RV
5261+_pkcs11h_certificate_validateSession (
5262+ IN const pkcs11h_certificate_t certificate
5263+);
5264+static
5265+CK_RV
5266+_pkcs11h_certificate_resetSession (
5267+ IN const pkcs11h_certificate_t certificate,
5268+ IN const PKCS11H_BOOL public_only,
5269+ IN const PKCS11H_BOOL session_mutex_locked
5270+);
5271+static
5272+CK_RV
5273+_pkcs11h_certificate_doPrivateOperation (
5274+ IN const pkcs11h_certificate_t certificate,
5275+ IN const enum _pkcs11h_private_op_e op,
5276+ IN const CK_MECHANISM_TYPE mech_type,
5277+ IN const unsigned char * const source,
5278+ IN const size_t source_size,
5279+ OUT unsigned char * const target,
5280+ IN OUT size_t * const p_target_size
5281+);
5282+#endif /* ENABLE_PKCS11H_CERTIFICATE */
5283+
5284+#if defined(ENABLE_PKCS11H_LOCATE)
5285+/*======================================================================*
5286+ * LOCATE INTERFACE
5287+ *======================================================================*/
5288+
5289+static
5290+CK_RV
5291+_pkcs11h_locate_getTokenIdBySlotId (
5292+ IN const char * const slot,
5293+ OUT pkcs11h_token_id_t * const p_token_id
5294+);
5295+static
5296+CK_RV
5297+_pkcs11h_locate_getTokenIdBySlotName (
5298+ IN const char * const name,
5299+ OUT pkcs11h_token_id_t * const p_token_id
5300+);
5301+static
5302+CK_RV
5303+_pkcs11h_locate_getTokenIdByLabel (
5304+ IN const char * const label,
5305+ OUT pkcs11h_token_id_t * const p_token_id
5306+);
5307+
5308+#if defined(ENABLE_PKCS11H_CERTIFICATE)
5309+
5310+static
5311+CK_RV
5312+_pkcs11h_locate_getCertificateIdByLabel (
5313+ IN const pkcs11h_session_t session,
5314+ IN OUT const pkcs11h_certificate_id_t certificate_id,
5315+ IN const char * const label
5316+);
5317+static
5318+CK_RV
5319+_pkcs11h_locate_getCertificateIdBySubject (
5320+ IN const pkcs11h_session_t session,
5321+ IN OUT const pkcs11h_certificate_id_t certificate_id,
5322+ IN const char * const subject
5323+);
5324+
5325+#endif /* ENABLE_PKCS11H_CERTIFICATE */
5326+#endif /* ENABLE_PKCS11H_LOCATE */
5327+
5328+#if defined(ENABLE_PKCS11H_ENUM)
5329+/*======================================================================*
5330+ * ENUM INTERFACE
5331+ *======================================================================*/
5332+
5333+#if defined(ENABLE_PKCS11H_CERTIFICATE)
5334+
5335+static
5336+CK_RV
5337+_pkcs11h_certificate_enumSessionCertificates (
5338+ IN const pkcs11h_session_t session,
5339+ IN void * const user_data,
5340+ IN const unsigned mask_prompt
5341+);
5342+static
5343+CK_RV
5344+_pkcs11h_certificate_splitCertificateIdList (
5345+ IN const pkcs11h_certificate_id_list_t cert_id_all,
5346+ OUT pkcs11h_certificate_id_list_t * const p_cert_id_issuers_list,
5347+ OUT pkcs11h_certificate_id_list_t * const p_cert_id_end_list
5348+);
5349+
5350+#endif /* ENABLE_PKCS11H_CERTIFICATE */
5351+
5352+#endif /* ENABLE_PKCS11H_ENUM */
5353+
5354+#if defined(ENABLE_PKCS11H_SLOTEVENT)
5355+/*======================================================================*
5356+ * SLOTEVENT INTERFACE
5357+ *======================================================================*/
5358+
5359+static
5360+unsigned long
5361+_pkcs11h_slotevent_checksum (
5362+ IN const unsigned char * const p,
5363+ IN const size_t s
5364+);
5365+static
5366+void *
5367+_pkcs11h_slotevent_provider (
5368+ IN void *p
5369+);
5370+static
5371+void *
5372+_pkcs11h_slotevent_manager (
5373+ IN void *p
5374+);
5375+static
5376+CK_RV
5377+_pkcs11h_slotevent_init ();
5378+static
5379+CK_RV
5380+_pkcs11h_slotevent_notify ();
5381+static
5382+CK_RV
5383+_pkcs11h_slotevent_terminate ();
5384+
5385+#endif /* ENABLE_PKCS11H_SLOTEVENT */
5386+
5387+#if defined(ENABLE_PKCS11H_OPENSSL)
5388+/*======================================================================*
5389+ * OPENSSL INTERFACE
5390+ *======================================================================*/
5391+
5392+static
5393+int
5394+_pkcs11h_openssl_finish (
5395+ IN OUT RSA *rsa
5396+);
5397+#if OPENSSL_VERSION_NUMBER < 0x00907000L
5398+static
5399+int
5400+_pkcs11h_openssl_dec (
5401+ IN int flen,
5402+ IN unsigned char *from,
5403+ OUT unsigned char *to,
5404+ IN OUT RSA *rsa,
5405+ IN int padding
5406+);
5407+static
5408+int
5409+_pkcs11h_openssl_sign (
5410+ IN int type,
5411+ IN unsigned char *m,
5412+ IN unsigned int m_len,
5413+ OUT unsigned char *sigret,
5414+ OUT unsigned int *siglen,
5415+ IN OUT RSA *rsa
5416+);
5417+#else
5418+static
5419+int
5420+_pkcs11h_openssl_dec (
5421+ IN int flen,
5422+ IN const unsigned char *from,
5423+ OUT unsigned char *to,
5424+ IN OUT RSA *rsa,
5425+ IN int padding
5426+);
5427+static
5428+int
5429+_pkcs11h_openssl_sign (
5430+ IN int type,
5431+ IN const unsigned char *m,
5432+ IN unsigned int m_len,
5433+ OUT unsigned char *sigret,
5434+ OUT unsigned int *siglen,
5435+ IN OUT const RSA *rsa
5436+);
5437+#endif
5438+static
5439+pkcs11h_openssl_session_t
5440+_pkcs11h_openssl_get_openssl_session (
5441+ IN OUT const RSA *rsa
5442+);
5443+static
5444+pkcs11h_certificate_t
5445+_pkcs11h_openssl_get_pkcs11h_certificate (
5446+ IN OUT const RSA *rsa
5447+);
5448+#endif /* ENABLE_PKCS11H_OPENSSL */
5449+
5450+/*==========================================
5451+ * Static data
5452+ */
5453+
5454+#if defined(ENABLE_PKCS11H_THREADING)
5455+#if !defined(WIN32)
5456+static struct {
5457+ pkcs11h_mutex_t mutex;
5458+ __pkcs11h_threading_mutex_entry_t head;
5459+} __s_pkcs11h_threading_mutex_list = {
5460+ PTHREAD_MUTEX_INITIALIZER,
5461+ NULL
5462+};
5463+#endif
5464+#endif
5465+
5466+pkcs11h_data_t s_pkcs11h_data = NULL;
5467+unsigned int s_pkcs11h_loglevel = PKCS11H_LOG_INFO;
5468+
5469+/*======================================================================*
5470+ * PUBLIC INTERFACE
5471+ *======================================================================*/
5472+
5473+const char *
5474+pkcs11h_getMessage (
5475+ IN const CK_RV rv
5476+) {
5477+ switch (rv) {
5478+ case CKR_OK: return "CKR_OK";
5479+ case CKR_CANCEL: return "CKR_CANCEL";
5480+ case CKR_HOST_MEMORY: return "CKR_HOST_MEMORY";
5481+ case CKR_SLOT_ID_INVALID: return "CKR_SLOT_ID_INVALID";
5482+ case CKR_GENERAL_ERROR: return "CKR_GENERAL_ERROR";
5483+ case CKR_FUNCTION_FAILED: return "CKR_FUNCTION_FAILED";
5484+ case CKR_ARGUMENTS_BAD: return "CKR_ARGUMENTS_BAD";
5485+ case CKR_NO_EVENT: return "CKR_NO_EVENT";
5486+ case CKR_NEED_TO_CREATE_THREADS: return "CKR_NEED_TO_CREATE_THREADS";
5487+ case CKR_CANT_LOCK: return "CKR_CANT_LOCK";
5488+ case CKR_ATTRIBUTE_READ_ONLY: return "CKR_ATTRIBUTE_READ_ONLY";
5489+ case CKR_ATTRIBUTE_SENSITIVE: return "CKR_ATTRIBUTE_SENSITIVE";
5490+ case CKR_ATTRIBUTE_TYPE_INVALID: return "CKR_ATTRIBUTE_TYPE_INVALID";
5491+ case CKR_ATTRIBUTE_VALUE_INVALID: return "CKR_ATTRIBUTE_VALUE_INVALID";
5492+ case CKR_DATA_INVALID: return "CKR_DATA_INVALID";
5493+ case CKR_DATA_LEN_RANGE: return "CKR_DATA_LEN_RANGE";
5494+ case CKR_DEVICE_ERROR: return "CKR_DEVICE_ERROR";
5495+ case CKR_DEVICE_MEMORY: return "CKR_DEVICE_MEMORY";
5496+ case CKR_DEVICE_REMOVED: return "CKR_DEVICE_REMOVED";
5497+ case CKR_ENCRYPTED_DATA_INVALID: return "CKR_ENCRYPTED_DATA_INVALID";
5498+ case CKR_ENCRYPTED_DATA_LEN_RANGE: return "CKR_ENCRYPTED_DATA_LEN_RANGE";
5499+ case CKR_FUNCTION_CANCELED: return "CKR_FUNCTION_CANCELED";
5500+ case CKR_FUNCTION_NOT_PARALLEL: return "CKR_FUNCTION_NOT_PARALLEL";
5501+ case CKR_FUNCTION_NOT_SUPPORTED: return "CKR_FUNCTION_NOT_SUPPORTED";
5502+ case CKR_KEY_HANDLE_INVALID: return "CKR_KEY_HANDLE_INVALID";
5503+ case CKR_KEY_SIZE_RANGE: return "CKR_KEY_SIZE_RANGE";
5504+ case CKR_KEY_TYPE_INCONSISTENT: return "CKR_KEY_TYPE_INCONSISTENT";
5505+ case CKR_KEY_NOT_NEEDED: return "CKR_KEY_NOT_NEEDED";
5506+ case CKR_KEY_CHANGED: return "CKR_KEY_CHANGED";
5507+ case CKR_KEY_NEEDED: return "CKR_KEY_NEEDED";
5508+ case CKR_KEY_INDIGESTIBLE: return "CKR_KEY_INDIGESTIBLE";
5509+ case CKR_KEY_FUNCTION_NOT_PERMITTED: return "CKR_KEY_FUNCTION_NOT_PERMITTED";
5510+ case CKR_KEY_NOT_WRAPPABLE: return "CKR_KEY_NOT_WRAPPABLE";
5511+ case CKR_KEY_UNEXTRACTABLE: return "CKR_KEY_UNEXTRACTABLE";
5512+ case CKR_MECHANISM_INVALID: return "CKR_MECHANISM_INVALID";
5513+ case CKR_MECHANISM_PARAM_INVALID: return "CKR_MECHANISM_PARAM_INVALID";
5514+ case CKR_OBJECT_HANDLE_INVALID: return "CKR_OBJECT_HANDLE_INVALID";
5515+ case CKR_OPERATION_ACTIVE: return "CKR_OPERATION_ACTIVE";
5516+ case CKR_OPERATION_NOT_INITIALIZED: return "CKR_OPERATION_NOT_INITIALIZED";
5517+ case CKR_PIN_INCORRECT: return "CKR_PIN_INCORRECT";
5518+ case CKR_PIN_INVALID: return "CKR_PIN_INVALID";
5519+ case CKR_PIN_LEN_RANGE: return "CKR_PIN_LEN_RANGE";
5520+ case CKR_PIN_EXPIRED: return "CKR_PIN_EXPIRED";
5521+ case CKR_PIN_LOCKED: return "CKR_PIN_LOCKED";
5522+ case CKR_SESSION_CLOSED: return "CKR_SESSION_CLOSED";
5523+ case CKR_SESSION_COUNT: return "CKR_SESSION_COUNT";
5524+ case CKR_SESSION_HANDLE_INVALID: return "CKR_SESSION_HANDLE_INVALID";
5525+ case CKR_SESSION_PARALLEL_NOT_SUPPORTED: return "CKR_SESSION_PARALLEL_NOT_SUPPORTED";
5526+ case CKR_SESSION_READ_ONLY: return "CKR_SESSION_READ_ONLY";
5527+ case CKR_SESSION_EXISTS: return "CKR_SESSION_EXISTS";
5528+ case CKR_SESSION_READ_ONLY_EXISTS: return "CKR_SESSION_READ_ONLY_EXISTS";
5529+ case CKR_SESSION_READ_WRITE_SO_EXISTS: return "CKR_SESSION_READ_WRITE_SO_EXISTS";
5530+ case CKR_SIGNATURE_INVALID: return "CKR_SIGNATURE_INVALID";
5531+ case CKR_SIGNATURE_LEN_RANGE: return "CKR_SIGNATURE_LEN_RANGE";
5532+ case CKR_TEMPLATE_INCOMPLETE: return "CKR_TEMPLATE_INCOMPLETE";
5533+ case CKR_TEMPLATE_INCONSISTENT: return "CKR_TEMPLATE_INCONSISTENT";
5534+ case CKR_TOKEN_NOT_PRESENT: return "CKR_TOKEN_NOT_PRESENT";
5535+ case CKR_TOKEN_NOT_RECOGNIZED: return "CKR_TOKEN_NOT_RECOGNIZED";
5536+ case CKR_TOKEN_WRITE_PROTECTED: return "CKR_TOKEN_WRITE_PROTECTED";
5537+ case CKR_UNWRAPPING_KEY_HANDLE_INVALID: return "CKR_UNWRAPPING_KEY_HANDLE_INVALID";
5538+ case CKR_UNWRAPPING_KEY_SIZE_RANGE: return "CKR_UNWRAPPING_KEY_SIZE_RANGE";
5539+ case CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT: return "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT";
5540+ case CKR_USER_ALREADY_LOGGED_IN: return "CKR_USER_ALREADY_LOGGED_IN";
5541+ case CKR_USER_NOT_LOGGED_IN: return "CKR_USER_NOT_LOGGED_IN";
5542+ case CKR_USER_PIN_NOT_INITIALIZED: return "CKR_USER_PIN_NOT_INITIALIZED";
5543+ case CKR_USER_TYPE_INVALID: return "CKR_USER_TYPE_INVALID";
5544+ case CKR_USER_ANOTHER_ALREADY_LOGGED_IN: return "CKR_USER_ANOTHER_ALREADY_LOGGED_IN";
5545+ case CKR_USER_TOO_MANY_TYPES: return "CKR_USER_TOO_MANY_TYPES";
5546+ case CKR_WRAPPED_KEY_INVALID: return "CKR_WRAPPED_KEY_INVALID";
5547+ case CKR_WRAPPED_KEY_LEN_RANGE: return "CKR_WRAPPED_KEY_LEN_RANGE";
5548+ case CKR_WRAPPING_KEY_HANDLE_INVALID: return "CKR_WRAPPING_KEY_HANDLE_INVALID";
5549+ case CKR_WRAPPING_KEY_SIZE_RANGE: return "CKR_WRAPPING_KEY_SIZE_RANGE";
5550+ case CKR_WRAPPING_KEY_TYPE_INCONSISTENT: return "CKR_WRAPPING_KEY_TYPE_INCONSISTENT";
5551+ case CKR_RANDOM_SEED_NOT_SUPPORTED: return "CKR_RANDOM_SEED_NOT_SUPPORTED";
5552+ case CKR_RANDOM_NO_RNG: return "CKR_RANDOM_NO_RNG";
5553+ case CKR_DOMAIN_PARAMS_INVALID: return "CKR_DOMAIN_PARAMS_INVALID";
5554+ case CKR_BUFFER_TOO_SMALL: return "CKR_BUFFER_TOO_SMALL";
5555+ case CKR_SAVED_STATE_INVALID: return "CKR_SAVED_STATE_INVALID";
5556+ case CKR_INFORMATION_SENSITIVE: return "CKR_INFORMATION_SENSITIVE";
5557+ case CKR_STATE_UNSAVEABLE: return "CKR_STATE_UNSAVEABLE";
5558+ case CKR_CRYPTOKI_NOT_INITIALIZED: return "CKR_CRYPTOKI_NOT_INITIALIZED";
5559+ case CKR_CRYPTOKI_ALREADY_INITIALIZED: return "CKR_CRYPTOKI_ALREADY_INITIALIZED";
5560+ case CKR_MUTEX_BAD: return "CKR_MUTEX_BAD";
5561+ case CKR_MUTEX_NOT_LOCKED: return "CKR_MUTEX_NOT_LOCKED";
5562+ case CKR_FUNCTION_REJECTED: return "CKR_FUNCTION_REJECTED";
5563+ case CKR_VENDOR_DEFINED: return "CKR_VENDOR_DEFINED";
5564+ default: return "Unknown PKCS#11 error";
5565+ }
5566+}
5567+
5568+CK_RV
5569+pkcs11h_initialize () {
5570+
5571+#if defined(ENABLE_PKCS11H_THREADING)
5572+ PKCS11H_BOOL mutex_locked = FALSE;
5573+#endif
5574+ CK_RV rv = CKR_OK;
5575+
5576+ PKCS11H_DEBUG (
5577+ PKCS11H_LOG_DEBUG2,
5578+ "PKCS#11: pkcs11h_initialize entry"
5579+ );
5580+
5581+ pkcs11h_terminate ();
5582+
5583+ if (rv == CKR_OK) {
5584+ rv = _pkcs11h_mem_malloc ((void*)&s_pkcs11h_data, sizeof (struct pkcs11h_data_s));
5585+ }
5586+
5587+#if defined(USE_PKCS11H_OPENSSL) || defined(ENABLE_PKCS11H_OPENSSL)
5588+ OpenSSL_add_all_digests ();
5589+#endif
5590+#if defined(USE_PKCS11H_GNUTLS)
5591+ if (
5592+ rv == CKR_OK &&
5593+ gnutls_global_init () != GNUTLS_E_SUCCESS
5594+ ) {
5595+ rv = CKR_FUNCTION_FAILED;
5596+ }
5597+#endif
5598+
5599+#if defined(ENABLE_PKCS11H_THREADING)
5600+ if (rv == CKR_OK) {
5601+ rv = _pkcs11h_threading_mutexInit (&s_pkcs11h_data->mutexes.global);
5602+ }
5603+ if (rv == CKR_OK) {
5604+ rv = _pkcs11h_threading_mutexInit (&s_pkcs11h_data->mutexes.session);
5605+ }
5606+ if (rv == CKR_OK) {
5607+ rv = _pkcs11h_threading_mutexInit (&s_pkcs11h_data->mutexes.cache);
5608+ }
5609+#if !defined(WIN32)
5610+ if (
5611+ rv == CKR_OK &&
5612+ pthread_atfork (
5613+ __pkcs11h_threading_atfork_prepare,
5614+ __pkcs11h_threading_atfork_parent,
5615+ __pkcs11h_threading_atfork_child
5616+ )
5617+ ) {
5618+ rv = CKR_FUNCTION_FAILED;
5619+ }
5620+#endif
5621+ if (
5622+ rv == CKR_OK &&
5623+ (rv = _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.global)) == CKR_OK
5624+ ) {
5625+ mutex_locked = TRUE;
5626+ }
5627+#endif
5628+
5629+ if (rv == CKR_OK) {
5630+ s_pkcs11h_data->max_retries = PKCS11H_DEFAULT_MAX_LOGIN_RETRY;
5631+ s_pkcs11h_data->allow_protected_auth = TRUE;
5632+ s_pkcs11h_data->pin_cache_period = PKCS11H_DEFAULT_PIN_CACHE_PERIOD;
5633+ s_pkcs11h_data->initialized = TRUE;
5634+ }
5635+
5636+ if (rv == CKR_OK) {
5637+ pkcs11h_setLogHook (_pkcs11h_hooks_default_log, NULL);
5638+ pkcs11h_setTokenPromptHook (_pkcs11h_hooks_default_token_prompt, NULL);
5639+ pkcs11h_setPINPromptHook (_pkcs11h_hooks_default_pin_prompt, NULL);
5640+ }
5641+
5642+#if defined(ENABLE_PKCS11H_THREADING)
5643+ if (mutex_locked) {
5644+ _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.global);
5645+ mutex_locked = FALSE;
5646+ }
5647+#endif
5648+
5649+ PKCS11H_DEBUG (
5650+ PKCS11H_LOG_DEBUG2,
5651+ "PKCS#11: pkcs11h_initialize return rv=%ld-'%s'",
5652+ rv,
5653+ pkcs11h_getMessage (rv)
5654+ );
5655+
5656+ return rv;
5657+}
5658+
5659+CK_RV
5660+pkcs11h_terminate () {
5661+
5662+ PKCS11H_DEBUG (
5663+ PKCS11H_LOG_DEBUG2,
5664+ "PKCS#11: pkcs11h_terminate entry"
5665+ );
5666+
5667+ if (s_pkcs11h_data != NULL) {
5668+ pkcs11h_provider_t current_provider = NULL;
5669+
5670+ PKCS11H_DEBUG (
5671+ PKCS11H_LOG_DEBUG1,
5672+ "PKCS#11: Removing providers"
5673+ );
5674+
5675+ for (
5676+ current_provider = s_pkcs11h_data->providers;
5677+ current_provider != NULL;
5678+ current_provider = current_provider->next
5679+ ) {
5680+ pkcs11h_removeProvider (current_provider->reference);
5681+ }
5682+
5683+#if defined(ENABLE_PKCS11H_THREADING)
5684+ _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.cache);
5685+ _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.session);
5686+ _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.global);
5687+#endif
5688+
5689+ PKCS11H_DEBUG (
5690+ PKCS11H_LOG_DEBUG1,
5691+ "PKCS#11: Releasing sessions"
5692+ );
5693+
5694+ while (s_pkcs11h_data->sessions != NULL) {
5695+ pkcs11h_session_t current = s_pkcs11h_data->sessions;
5696+ s_pkcs11h_data->sessions = s_pkcs11h_data->sessions->next;
5697+
5698+#if defined(ENABLE_PKCS11H_THREADING)
5699+ _pkcs11h_threading_mutexLock (&current->mutex);
5700+#endif
5701+
5702+ current->valid = FALSE;
5703+
5704+ if (current->reference_count != 0) {
5705+ PKCS11H_DEBUG (
5706+ PKCS11H_LOG_DEBUG1,
5707+ "PKCS#11: Warning: Found session with references"
5708+ );
5709+ }
5710+
5711+ if (current->token_id != NULL) {
5712+ pkcs11h_token_freeTokenId (current->token_id);
5713+ current->token_id = NULL;
5714+ }
5715+
5716+#if defined(ENABLE_PKCS11H_ENUM)
5717+#if defined(ENABLE_PKCS11H_CERTIFICATE)
5718+ pkcs11h_certificate_freeCertificateIdList (current->cached_certs);
5719+#endif
5720+#endif
5721+
5722+ current->provider = NULL;
5723+
5724+#if defined(ENABLE_PKCS11H_THREADING)
5725+ _pkcs11h_threading_mutexFree (&current->mutex);
5726+#endif
5727+
5728+ _pkcs11h_mem_free ((void *)&current);
5729+ }
5730+
5731+#if defined(ENABLE_PKCS11H_SLOTEVENT)
5732+ PKCS11H_DEBUG (
5733+ PKCS11H_LOG_DEBUG1,
5734+ "PKCS#11: Terminating slotevent"
5735+ );
5736+
5737+ _pkcs11h_slotevent_terminate ();
5738+#endif
5739+ PKCS11H_DEBUG (
5740+ PKCS11H_LOG_DEBUG1,
5741+ "PKCS#11: Marking as uninitialized"
5742+ );
5743+
5744+ s_pkcs11h_data->initialized = FALSE;
5745+
5746+ while (s_pkcs11h_data->providers != NULL) {
5747+ pkcs11h_provider_t current = s_pkcs11h_data->providers;
5748+ s_pkcs11h_data->providers = s_pkcs11h_data->providers->next;
5749+
5750+ _pkcs11h_mem_free ((void *)&current);
5751+ }
5752+
5753+#if defined(ENABLE_PKCS11H_THREADING)
5754+ _pkcs11h_threading_mutexFree (&s_pkcs11h_data->mutexes.cache);
5755+ _pkcs11h_threading_mutexFree (&s_pkcs11h_data->mutexes.global);
5756+ _pkcs11h_threading_mutexFree (&s_pkcs11h_data->mutexes.session);
5757+#endif
5758+
5759+#if defined(USE_PKCS11H_GNUTLS)
5760+ gnutls_global_deinit ();
5761+#endif
5762+
5763+ _pkcs11h_mem_free ((void *)&s_pkcs11h_data);
5764+ }
5765+
5766+ PKCS11H_DEBUG (
5767+ PKCS11H_LOG_DEBUG2,
5768+ "PKCS#11: pkcs11h_terminate return"
5769+ );
5770+
5771+ return CKR_OK;
5772+}
5773+
5774+void
5775+pkcs11h_setLogLevel (
5776+ IN const unsigned flags
5777+) {
5778+ s_pkcs11h_loglevel = flags;
5779+}
5780+
5781+unsigned
5782+pkcs11h_getLogLevel () {
5783+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
5784+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
5785+
5786+ return s_pkcs11h_loglevel;
5787+}
5788+
5789+CK_RV
5790+pkcs11h_setLogHook (
5791+ IN const pkcs11h_hook_log_t hook,
5792+ IN void * const global_data
5793+) {
5794+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
5795+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
5796+ PKCS11H_ASSERT (hook!=NULL);
5797+
5798+ s_pkcs11h_data->hooks.log = hook;
5799+ s_pkcs11h_data->hooks.log_data = global_data;
5800+
5801+ return CKR_OK;
5802+}
5803+
5804+CK_RV
5805+pkcs11h_setSlotEventHook (
5806+ IN const pkcs11h_hook_slotevent_t hook,
5807+ IN void * const global_data
5808+) {
5809+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
5810+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
5811+ PKCS11H_ASSERT (hook!=NULL);
5812+
5813+#if defined(ENABLE_PKCS11H_SLOTEVENT)
5814+ s_pkcs11h_data->hooks.slotevent = hook;
5815+ s_pkcs11h_data->hooks.slotevent_data = global_data;
5816+
5817+ return _pkcs11h_slotevent_init ();
5818+#else
5819+ (void)global_data;
5820+
5821+ return CKR_FUNCTION_NOT_SUPPORTED;
5822+#endif
5823+}
5824+
5825+CK_RV
5826+pkcs11h_setPINPromptHook (
5827+ IN const pkcs11h_hook_pin_prompt_t hook,
5828+ IN void * const global_data
5829+) {
5830+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
5831+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
5832+ PKCS11H_ASSERT (hook!=NULL);
5833+
5834+ s_pkcs11h_data->hooks.pin_prompt = hook;
5835+ s_pkcs11h_data->hooks.pin_prompt_data = global_data;
5836+
5837+ return CKR_OK;
5838+}
5839+
5840+CK_RV
5841+pkcs11h_setTokenPromptHook (
5842+ IN const pkcs11h_hook_token_prompt_t hook,
5843+ IN void * const global_data
5844+) {
5845+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
5846+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
5847+ PKCS11H_ASSERT (hook!=NULL);
5848+
5849+ s_pkcs11h_data->hooks.token_prompt = hook;
5850+ s_pkcs11h_data->hooks.token_prompt_data = global_data;
5851+
5852+ return CKR_OK;
5853+}
5854+
5855+CK_RV
5856+pkcs11h_setPINCachePeriod (
5857+ IN const int pin_cache_period
5858+) {
5859+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
5860+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
5861+
5862+ s_pkcs11h_data->pin_cache_period = pin_cache_period;
5863+
5864+ return CKR_OK;
5865+}
5866+
5867+CK_RV
5868+pkcs11h_setMaxLoginRetries (
5869+ IN const unsigned max_retries
5870+) {
5871+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
5872+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
5873+
5874+ s_pkcs11h_data->max_retries = max_retries;
5875+
5876+ return CKR_OK;
5877+}
5878+
5879+CK_RV
5880+pkcs11h_setProtectedAuthentication (
5881+ IN const PKCS11H_BOOL allow_protected_auth
5882+) {
5883+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
5884+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
5885+
5886+ s_pkcs11h_data->allow_protected_auth = allow_protected_auth;
5887+
5888+ return CKR_OK;
5889+}
5890+
5891+CK_RV
5892+pkcs11h_addProvider (
5893+ IN const char * const reference,
5894+ IN const char * const provider_location,
5895+ IN const PKCS11H_BOOL allow_protected_auth,
5896+ IN const unsigned mask_sign_mode,
5897+ IN const int slot_event_method,
5898+ IN const int slot_poll_interval,
5899+ IN const PKCS11H_BOOL cert_is_private
5900+) {
5901+#if defined(ENABLE_PKCS11H_THREADING)
5902+ PKCS11H_BOOL mutex_locked = FALSE;
5903+#endif
5904+#if defined(WIN32)
5905+ int mypid = 0;
5906+#else
5907+ pid_t mypid = getpid ();
5908+#endif
5909+ pkcs11h_provider_t provider = NULL;
5910+ CK_C_GetFunctionList gfl = NULL;
5911+ CK_INFO info;
5912+ CK_RV rv = CKR_OK;
5913+
5914+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
5915+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
5916+ PKCS11H_ASSERT (provider_location!=NULL);
5917+ /*PKCS11H_ASSERT (szSignMode!=NULL); NOT NEEDED*/
5918+
5919+ PKCS11H_DEBUG (
5920+ PKCS11H_LOG_DEBUG2,
5921+ "PKCS#11: pkcs11h_addProvider entry pid=%d, reference='%s', provider_location='%s', allow_protected_auth=%d, mask_sign_mode=%08x, cert_is_private=%d",
5922+ mypid,
5923+ reference,
5924+ provider_location,
5925+ allow_protected_auth ? 1 : 0,
5926+ mask_sign_mode,
5927+ cert_is_private ? 1 : 0
5928+ );
5929+
5930+ PKCS11H_DEBUG (
5931+ PKCS11H_LOG_DEBUG1,
5932+ "PKCS#11: Adding provider '%s'-'%s'",
5933+ reference,
5934+ provider_location
5935+ );
5936+
5937+#if defined(ENABLE_PKCS11H_THREADING)
5938+ if (
5939+ rv == CKR_OK &&
5940+ (rv = _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.global)) == CKR_OK
5941+ ) {
5942+ mutex_locked = TRUE;
5943+ }
5944+#endif
5945+
5946+ if (
5947+ rv == CKR_OK &&
5948+ (rv = _pkcs11h_mem_malloc ((void *)&provider, sizeof (struct pkcs11h_provider_s))) == CKR_OK
5949+ ) {
5950+ strncpy (
5951+ provider->reference,
5952+ reference,
5953+ sizeof (provider->reference)-1
5954+ );
5955+ provider->reference[sizeof (provider->reference)-1] = '\x0';
5956+ strncpy (
5957+ provider->manufacturerID,
5958+ (
5959+ strlen (provider_location) < sizeof (provider->manufacturerID) ?
5960+ provider_location :
5961+ provider_location+strlen (provider_location)-sizeof (provider->manufacturerID)+1
5962+ ),
5963+ sizeof (provider->manufacturerID)-1
5964+ );
5965+ provider->manufacturerID[sizeof (provider->manufacturerID)-1] = '\x0';
5966+ provider->allow_protected_auth = allow_protected_auth;
5967+ provider->mask_sign_mode = mask_sign_mode;
5968+ provider->slot_event_method = slot_event_method;
5969+ provider->slot_poll_interval = slot_poll_interval;
5970+ provider->cert_is_private = cert_is_private;
5971+ }
5972+
5973+ if (rv == CKR_OK) {
5974+#if defined(WIN32)
5975+ provider->handle = LoadLibraryA (provider_location);
5976+#else
5977+ provider->handle = dlopen (provider_location, RTLD_NOW);
5978+#endif
5979+ if (provider->handle == NULL) {
5980+ rv = CKR_FUNCTION_FAILED;
5981+ }
5982+ }
5983+
5984+ if (rv == CKR_OK) {
5985+#if defined(WIN32)
5986+ gfl = (CK_C_GetFunctionList)GetProcAddress (
5987+ provider->handle,
5988+ "C_GetFunctionList"
5989+ );
5990+#else
5991+ /*
5992+ * Make compiler happy!
5993+ */
5994+ void *p = dlsym (
5995+ provider->handle,
5996+ "C_GetFunctionList"
5997+ );
5998+ memmove (
5999+ &gfl,
6000+ &p,
6001+ sizeof (void *)
6002+ );
6003+#endif
6004+ if (gfl == NULL) {
6005+ rv = CKR_FUNCTION_FAILED;
6006+ }
6007+ }
6008+
6009+ if (rv == CKR_OK) {
6010+ rv = gfl (&provider->f);
6011+ }
6012+
6013+ if (rv == CKR_OK) {
6014+ if ((rv = provider->f->C_Initialize (NULL)) != CKR_OK) {
6015+ if (rv == CKR_CRYPTOKI_ALREADY_INITIALIZED) {
6016+ rv = CKR_OK;
6017+ }
6018+ }
6019+ else {
6020+ provider->should_finalize = TRUE;
6021+ }
6022+ }
6023+
6024+ if (
6025+ rv == CKR_OK &&
6026+ (rv = provider->f->C_GetInfo (&info)) == CKR_OK
6027+ ) {
6028+ _pkcs11h_util_fixupFixedString (
6029+ provider->manufacturerID,
6030+ (char *)info.manufacturerID,
6031+ sizeof (info.manufacturerID)
6032+ );
6033+ }
6034+
6035+ if (rv == CKR_OK) {
6036+ provider->enabled = TRUE;
6037+ }
6038+
6039+ if (provider != NULL) {
6040+ if (s_pkcs11h_data->providers == NULL) {
6041+ s_pkcs11h_data->providers = provider;
6042+ }
6043+ else {
6044+ pkcs11h_provider_t last = NULL;
6045+
6046+ for (
6047+ last = s_pkcs11h_data->providers;
6048+ last->next != NULL;
6049+ last = last->next
6050+ );
6051+ last->next = provider;
6052+ }
6053+ }
6054+
6055+#if defined(ENABLE_PKCS11H_THREADING)
6056+ if (mutex_locked) {
6057+ _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.global);
6058+ mutex_locked = FALSE;
6059+ }
6060+#endif
6061+
6062+#if defined(ENABLE_PKCS11H_SLOTEVENT)
6063+ _pkcs11h_slotevent_notify ();
6064+#endif
6065+
6066+ PKCS11H_DEBUG (
6067+ PKCS11H_LOG_DEBUG1,
6068+ "PKCS#11: Provider '%s' added rv=%ld-'%s'",
6069+ reference,
6070+ rv,
6071+ pkcs11h_getMessage (rv)
6072+ );
6073+
6074+ PKCS11H_DEBUG (
6075+ PKCS11H_LOG_DEBUG2,
6076+ "PKCS#11: pkcs11h_addProvider return rv=%ld-'%s'",
6077+ rv,
6078+ pkcs11h_getMessage (rv)
6079+ );
6080+
6081+ return rv;
6082+}
6083+
6084+CK_RV
6085+pkcs11h_removeProvider (
6086+ IN const char * const reference
6087+) {
6088+#if defined(ENABLE_PKCS11H_THREADING)
6089+ pkcs11h_session_t current_session = NULL;
6090+#endif
6091+ pkcs11h_provider_t provider = NULL;
6092+ CK_RV rv = CKR_OK;
6093+
6094+ PKCS11H_ASSERT (reference!=NULL);
6095+
6096+ PKCS11H_DEBUG (
6097+ PKCS11H_LOG_DEBUG2,
6098+ "PKCS#11: pkcs11h_removeProvider entry reference='%s'",
6099+ reference
6100+ );
6101+
6102+ PKCS11H_DEBUG (
6103+ PKCS11H_LOG_DEBUG1,
6104+ "PKCS#11: Removing provider '%s'",
6105+ reference
6106+ );
6107+
6108+#if defined(ENABLE_PKCS11H_THREADING)
6109+ _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.cache);
6110+ _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.session);
6111+ _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.global);
6112+
6113+ for (
6114+ current_session = s_pkcs11h_data->sessions;
6115+ current_session != NULL;
6116+ current_session = current_session->next
6117+ ) {
6118+ _pkcs11h_threading_mutexLock (&current_session->mutex);
6119+ }
6120+#endif
6121+
6122+ provider = s_pkcs11h_data->providers;
6123+ while (
6124+ rv == CKR_OK &&
6125+ provider != NULL &&
6126+ strcmp (reference, provider->reference)
6127+ ) {
6128+ provider = provider->next;
6129+ }
6130+
6131+ if (rv == CKR_OK && provider == NULL) {
6132+ rv = CKR_OBJECT_HANDLE_INVALID;
6133+ }
6134+
6135+ if (rv == CKR_OK) {
6136+ provider->enabled = FALSE;
6137+ provider->reference[0] = '\0';
6138+
6139+ if (provider->should_finalize) {
6140+ provider->f->C_Finalize (NULL);
6141+ provider->should_finalize = FALSE;
6142+ }
6143+
6144+#if defined(ENABLE_PKCS11H_SLOTEVENT)
6145+ _pkcs11h_slotevent_notify ();
6146+
6147+ /*
6148+ * Wait until manager join this thread
6149+ * this happens saldom so I can poll
6150+ */
6151+ while (provider->slotevent_thread != PKCS11H_THREAD_NULL) {
6152+ _pkcs11h_threading_sleep (500);
6153+ }
6154+#endif
6155+
6156+ if (provider->f != NULL) {
6157+ provider->f = NULL;
6158+ }
6159+
6160+ if (provider->handle != NULL) {
6161+#if defined(WIN32)
6162+ FreeLibrary (provider->handle);
6163+#else
6164+ dlclose (provider->handle);
6165+#endif
6166+ provider->handle = NULL;
6167+ }
6168+ }
6169+
6170+#if defined(ENABLE_PKCS11H_THREADING)
6171+ for (
6172+ current_session = s_pkcs11h_data->sessions;
6173+ current_session != NULL;
6174+ current_session = current_session->next
6175+ ) {
6176+ _pkcs11h_threading_mutexRelease (&current_session->mutex);
6177+ }
6178+
6179+ _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.cache);
6180+ _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.session);
6181+ _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.global);
6182+#endif
6183+
6184+ PKCS11H_DEBUG (
6185+ PKCS11H_LOG_DEBUG2,
6186+ "PKCS#11: pkcs11h_removeProvider return rv=%ld-'%s'",
6187+ rv,
6188+ pkcs11h_getMessage (rv)
6189+ );
6190+
6191+ return rv;
6192+}
6193+
6194+CK_RV
6195+pkcs11h_forkFixup () {
6196+#if defined(WIN32)
6197+ return CKR_OK;
6198+#else
6199+#if defined(ENABLE_PKCS11H_THREADING)
6200+ return CKR_OK;
6201+#else
6202+ return _pkcs11h_forkFixup ();
6203+#endif
6204+#endif
6205+}
6206+
6207+CK_RV
6208+pkcs11h_plugAndPlay () {
6209+#if defined(WIN32)
6210+ int mypid = 0;
6211+#else
6212+ pid_t mypid = getpid ();
6213+#endif
6214+
6215+ PKCS11H_DEBUG (
6216+ PKCS11H_LOG_DEBUG2,
6217+ "PKCS#11: pkcs11h_forkFixup entry pid=%d",
6218+ mypid
6219+ );
6220+
6221+ if (s_pkcs11h_data != NULL && s_pkcs11h_data->initialized) {
6222+ pkcs11h_provider_t current;
6223+#if defined(ENABLE_PKCS11H_SLOTEVENT)
6224+ PKCS11H_BOOL slot_event_active = FALSE;
6225+#endif
6226+
6227+#if defined(ENABLE_PKCS11H_THREADING)
6228+ _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.global);
6229+#endif
6230+ for (
6231+ current = s_pkcs11h_data->providers;
6232+ current != NULL;
6233+ current = current->next
6234+ ) {
6235+ if (current->enabled) {
6236+ current->f->C_Finalize (NULL);
6237+ }
6238+ }
6239+
6240+#if defined(ENABLE_PKCS11H_SLOTEVENT)
6241+ if (s_pkcs11h_data->slotevent.initialized) {
6242+ slot_event_active = TRUE;
6243+ _pkcs11h_slotevent_terminate ();
6244+ }
6245+#endif
6246+
6247+ for (
6248+ current = s_pkcs11h_data->providers;
6249+ current != NULL;
6250+ current = current->next
6251+ ) {
6252+ if (current->enabled) {
6253+ current->f->C_Initialize (NULL);
6254+ }
6255+ }
6256+
6257+#if defined(ENABLE_PKCS11H_SLOTEVENT)
6258+ if (slot_event_active) {
6259+ _pkcs11h_slotevent_init ();
6260+ }
6261+#endif
6262+
6263+#if defined(ENABLE_PKCS11H_THREADING)
6264+ _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.global);
6265+#endif
6266+ }
6267+
6268+ PKCS11H_DEBUG (
6269+ PKCS11H_LOG_DEBUG2,
6270+ "PKCS#11: pkcs11h_forkFixup return"
6271+ );
6272+
6273+ return CKR_OK;
6274+}
6275+
6276+CK_RV
6277+pkcs11h_token_freeTokenId (
6278+ IN pkcs11h_token_id_t token_id
6279+) {
6280+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
6281+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
6282+ PKCS11H_ASSERT (token_id!=NULL);
6283+
6284+ PKCS11H_DEBUG (
6285+ PKCS11H_LOG_DEBUG2,
6286+ "PKCS#11: pkcs11h_token_freeTokenId entry certificate_id=%p",
6287+ (void *)token_id
6288+ );
6289+
6290+ _pkcs11h_mem_free ((void *)&token_id);
6291+
6292+ PKCS11H_DEBUG (
6293+ PKCS11H_LOG_DEBUG2,
6294+ "PKCS#11: pkcs11h_token_freeTokenId return"
6295+ );
6296+
6297+ return CKR_OK;
6298+}
6299+
6300+CK_RV
6301+pkcs11h_token_duplicateTokenId (
6302+ OUT pkcs11h_token_id_t * const to,
6303+ IN const pkcs11h_token_id_t from
6304+) {
6305+ CK_RV rv = CKR_OK;
6306+
6307+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
6308+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
6309+ PKCS11H_ASSERT (to!=NULL);
6310+ PKCS11H_ASSERT (from!=NULL);
6311+
6312+ PKCS11H_DEBUG (
6313+ PKCS11H_LOG_DEBUG2,
6314+ "PKCS#11: pkcs11h_token_duplicateTokenId entry to=%p form=%p",
6315+ (void *)to,
6316+ (void *)from
6317+ );
6318+
6319+ *to = NULL;
6320+
6321+ if (rv == CKR_OK) {
6322+ rv = _pkcs11h_mem_duplicate (
6323+ (void*)to,
6324+ NULL,
6325+ from,
6326+ sizeof (struct pkcs11h_token_id_s)
6327+ );
6328+ }
6329+
6330+ PKCS11H_DEBUG (
6331+ PKCS11H_LOG_DEBUG2,
6332+ "PKCS#11: pkcs11h_token_duplicateTokenId return rv=%ld-'%s', *to=%p",
6333+ rv,
6334+ pkcs11h_getMessage (rv),
6335+ (void *)*to
6336+ );
6337+
6338+ return rv;
6339+}
6340+
6341+PKCS11H_BOOL
6342+pkcs11h_token_sameTokenId (
6343+ IN const pkcs11h_token_id_t a,
6344+ IN const pkcs11h_token_id_t b
6345+) {
6346+ PKCS11H_ASSERT (a!=NULL);
6347+ PKCS11H_ASSERT (b!=NULL);
6348+
6349+ return (
6350+ !strcmp (a->manufacturerID, b->manufacturerID) &&
6351+ !strcmp (a->model, b->model) &&
6352+ !strcmp (a->serialNumber, b->serialNumber) &&
6353+ !strcmp (a->label, b->label)
6354+ );
6355+}
6356+
6357+#if defined(ENABLE_PKCS11H_SERIALIZATION)
6358+
6359+CK_RV
6360+pkcs11h_token_serializeTokenId (
6361+ OUT char * const sz,
6362+ IN OUT size_t *max,
6363+ IN const pkcs11h_token_id_t token_id
6364+) {
6365+ const char *sources[5];
6366+ CK_RV rv = CKR_OK;
6367+ size_t n;
6368+ int e;
6369+
6370+ /*PKCS11H_ASSERT (sz!=NULL); Not required*/
6371+ PKCS11H_ASSERT (max!=NULL);
6372+ PKCS11H_ASSERT (token_id!=NULL);
6373+
6374+ { /* Must be after assert */
6375+ sources[0] = token_id->manufacturerID;
6376+ sources[1] = token_id->model;
6377+ sources[2] = token_id->serialNumber;
6378+ sources[3] = token_id->label;
6379+ sources[4] = NULL;
6380+ }
6381+
6382+ PKCS11H_DEBUG (
6383+ PKCS11H_LOG_DEBUG2,
6384+ "PKCS#11: pkcs11h_token_serializeTokenId entry sz=%p, *max=%u, token_id=%p",
6385+ sz,
6386+ sz != NULL ? *max : 0,
6387+ (void *)token_id
6388+ );
6389+
6390+ n = 0;
6391+ for (e=0;rv == CKR_OK && sources[e] != NULL;e++) {
6392+ size_t t;
6393+ rv = _pkcs11h_util_escapeString (NULL, sources[e], &t, PKCS11H_SERIALIZE_INVALID_CHARS);
6394+ n+=t;
6395+ }
6396+
6397+ if (sz != NULL) {
6398+ if (*max < n) {
6399+ rv = CKR_ATTRIBUTE_VALUE_INVALID;
6400+ }
6401+ else {
6402+ n = 0;
6403+ for (e=0;sources[e] != NULL;e++) {
6404+ size_t t = *max-n;
6405+ _pkcs11h_util_escapeString (sz+n, sources[e], &t, PKCS11H_SERIALIZE_INVALID_CHARS);
6406+ n+=t;
6407+ sz[n-1] = '/';
6408+ }
6409+ sz[n-1] = '\x0';
6410+ }
6411+ }
6412+
6413+ *max = n;
6414+
6415+ PKCS11H_DEBUG (
6416+ PKCS11H_LOG_DEBUG2,
6417+ "PKCS#11: pkcs11h_token_serializeTokenId return rv=%ld-'%s', *max=%u, sz='%s'",
6418+ rv,
6419+ pkcs11h_getMessage (rv),
6420+ *max,
6421+ sz
6422+ );
6423+
6424+ return rv;
6425+}
6426+
6427+CK_RV
6428+pkcs11h_token_deserializeTokenId (
6429+ OUT pkcs11h_token_id_t *p_token_id,
6430+ IN const char * const sz
6431+) {
6432+#define __PKCS11H_TARGETS_NUMBER 4
6433+ struct {
6434+ char *p;
6435+ size_t s;
6436+ } targets[__PKCS11H_TARGETS_NUMBER];
6437+
6438+ pkcs11h_token_id_t token_id = NULL;
6439+ char *p1 = NULL;
6440+ char *_sz = NULL;
6441+ int e;
6442+ CK_RV rv = CKR_OK;
6443+
6444+ PKCS11H_ASSERT (p_token_id!=NULL);
6445+ PKCS11H_ASSERT (sz!=NULL);
6446+
6447+ PKCS11H_DEBUG (
6448+ PKCS11H_LOG_DEBUG2,
6449+ "PKCS#11: pkcs11h_token_deserializeTokenId entry p_token_id=%p, sz='%s'",
6450+ (void *)p_token_id,
6451+ sz
6452+ );
6453+
6454+ *p_token_id = NULL;
6455+
6456+ if (rv == CKR_OK) {
6457+ rv = _pkcs11h_mem_strdup (
6458+ (void *)&_sz,
6459+ sz
6460+ );
6461+ }
6462+
6463+ if (rv == CKR_OK) {
6464+ p1 = _sz;
6465+ }
6466+
6467+ if (
6468+ rv == CKR_OK &&
6469+ (rv = _pkcs11h_token_newTokenId (&token_id)) == CKR_OK
6470+ ) {
6471+ targets[0].p = token_id->manufacturerID;
6472+ targets[0].s = sizeof (token_id->manufacturerID);
6473+ targets[1].p = token_id->model;
6474+ targets[1].s = sizeof (token_id->model);
6475+ targets[2].p = token_id->serialNumber;
6476+ targets[2].s = sizeof (token_id->serialNumber);
6477+ targets[3].p = token_id->label;
6478+ targets[3].s = sizeof (token_id->label);
6479+ }
6480+
6481+ for (e=0;rv == CKR_OK && e < __PKCS11H_TARGETS_NUMBER;e++) {
6482+ size_t l;
6483+ char *p2 = NULL;
6484+
6485+ /*
6486+ * Don't search for last
6487+ * separator
6488+ */
6489+ if (rv == CKR_OK) {
6490+ if (e != __PKCS11H_TARGETS_NUMBER-1) {
6491+ p2 = strchr (p1, '/');
6492+ if (p2 == NULL) {
6493+ rv = CKR_ATTRIBUTE_VALUE_INVALID;
6494+ }
6495+ else {
6496+ *p2 = '\x0';
6497+ }
6498+ }
6499+ }
6500+
6501+ if (rv == CKR_OK) {
6502+ _pkcs11h_util_unescapeString (
6503+ NULL,
6504+ p1,
6505+ &l
6506+ );
6507+ }
6508+
6509+ if (rv == CKR_OK) {
6510+ if (l > targets[e].s) {
6511+ rv = CKR_ATTRIBUTE_VALUE_INVALID;
6512+ }
6513+ }
6514+
6515+ if (rv == CKR_OK) {
6516+ l = targets[e].s;
6517+ _pkcs11h_util_unescapeString (
6518+ targets[e].p,
6519+ p1,
6520+ &l
6521+ );
6522+ }
6523+
6524+ if (rv == CKR_OK) {
6525+ p1 = p2+1;
6526+ }
6527+ }
6528+
6529+ if (rv == CKR_OK) {
6530+ strncpy (
6531+ token_id->display,
6532+ token_id->label,
6533+ sizeof (token_id->display)
6534+ );
6535+ }
6536+
6537+ if (rv == CKR_OK) {
6538+ *p_token_id = token_id;
6539+ token_id = NULL;
6540+ }
6541+
6542+ if (_sz != NULL) {
6543+ _pkcs11h_mem_free ((void *)&_sz);
6544+ }
6545+
6546+ if (token_id != NULL) {
6547+ pkcs11h_token_freeTokenId (token_id);
6548+ }
6549+
6550+ return rv;
6551+#undef __PKCS11H_TARGETS_NUMBER
6552+}
6553+
6554+#endif /* ENABLE_PKCS11H_SERIALIZATION */
6555+
6556+/*======================================================================*
6557+ * MEMORY INTERFACE
6558+ *======================================================================*/
6559+
6560+static
6561+CK_RV
6562+_pkcs11h_mem_malloc (
6563+ OUT const void * * const p,
6564+ IN const size_t s
6565+) {
6566+ CK_RV rv = CKR_OK;
6567+
6568+ PKCS11H_ASSERT (p!=NULL);
6569+ PKCS11H_ASSERT (s!=0);
6570+
6571+ *p = NULL;
6572+
6573+ if (s > 0) {
6574+ if (
6575+ (*p = (void *)PKCS11H_MALLOC (s)) == NULL
6576+ ) {
6577+ rv = CKR_HOST_MEMORY;
6578+ }
6579+ else {
6580+ memset ((void *)*p, 0, s);
6581+ }
6582+ }
6583+
6584+ return rv;
6585+}
6586+
6587+static
6588+CK_RV
6589+_pkcs11h_mem_free (
6590+ IN const void * * const p
6591+) {
6592+ PKCS11H_ASSERT (p!=NULL);
6593+
6594+ PKCS11H_FREE ((void *)*p);
6595+ *p = NULL;
6596+
6597+ return CKR_OK;
6598+}
6599+
6600+static
6601+CK_RV
6602+_pkcs11h_mem_strdup (
6603+ OUT const char * * const dest,
6604+ IN const char * const src
6605+) {
6606+ return _pkcs11h_mem_duplicate (
6607+ (void *)dest,
6608+ NULL,
6609+ src,
6610+ strlen (src)+1
6611+ );
6612+}
6613+
6614+static
6615+CK_RV
6616+_pkcs11h_mem_duplicate (
6617+ OUT const void * * const dest,
6618+ OUT size_t * const p_dest_size,
6619+ IN const void * const src,
6620+ IN const size_t mem_size
6621+) {
6622+ CK_RV rv = CKR_OK;
6623+
6624+ PKCS11H_ASSERT (dest!=NULL);
6625+ /*PKCS11H_ASSERT (dest_size!=NULL); NOT NEEDED*/
6626+ PKCS11H_ASSERT (!(mem_size!=0&&src==NULL));
6627+
6628+ *dest = NULL;
6629+ if (p_dest_size != NULL) {
6630+ *p_dest_size = 0;
6631+ }
6632+
6633+ if (src != NULL) {
6634+ if (
6635+ rv == CKR_OK &&
6636+ (rv = _pkcs11h_mem_malloc (dest, mem_size)) == CKR_OK
6637+ ) {
6638+ if (p_dest_size != NULL) {
6639+ *p_dest_size = mem_size;
6640+ }
6641+ memmove ((void*)*dest, src, mem_size);
6642+ }
6643+ }
6644+
6645+ return rv;
6646+}
6647+
6648+#if defined(ENABLE_PKCS11H_THREADING)
6649+/*======================================================================*
6650+ * THREADING INTERFACE
6651+ *======================================================================*/
6652+
6653+static
6654+void
6655+_pkcs11h_threading_sleep (
6656+ IN const unsigned milli
6657+) {
6658+#if defined(WIN32)
6659+ Sleep (milli);
6660+#else
6661+ usleep (milli*1000);
6662+#endif
6663+}
6664+
6665+static
6666+CK_RV
6667+_pkcs11h_threading_mutexInit (
6668+ OUT pkcs11h_mutex_t * const mutex
6669+) {
6670+ CK_RV rv = CKR_OK;
6671+#if defined(WIN32)
6672+ if (
6673+ rv == CKR_OK &&
6674+ (*mutex = CreateMutex (NULL, FALSE, NULL)) == NULL
6675+ ) {
6676+ rv = CKR_FUNCTION_FAILED;
6677+ }
6678+#else
6679+ {
6680+ __pkcs11h_threading_mutex_entry_t entry = NULL;
6681+ PKCS11H_BOOL mutex_locked = FALSE;
6682+
6683+ if (
6684+ rv == CKR_OK &&
6685+ (rv = _pkcs11h_threading_mutexLock (&__s_pkcs11h_threading_mutex_list.mutex)) == CKR_OK
6686+ ) {
6687+ mutex_locked = TRUE;
6688+ }
6689+
6690+ if (rv == CKR_OK) {
6691+ rv = _pkcs11h_mem_malloc (
6692+ (void *)&entry,
6693+ sizeof (struct __pkcs11h_threading_mutex_entry_s)
6694+ );
6695+ }
6696+
6697+ if (
6698+ rv == CKR_OK &&
6699+ pthread_mutex_init (mutex, NULL)
6700+ ) {
6701+ rv = CKR_FUNCTION_FAILED;
6702+ }
6703+
6704+ if (rv == CKR_OK) {
6705+ entry->p_mutex = mutex;
6706+ entry->next = __s_pkcs11h_threading_mutex_list.head;
6707+ __s_pkcs11h_threading_mutex_list.head = entry;
6708+ entry = NULL;
6709+ }
6710+
6711+ if (entry != NULL) {
6712+ _pkcs11h_mem_free ((void *)&entry);
6713+ }
6714+
6715+ if (mutex_locked) {
6716+ _pkcs11h_threading_mutexRelease (&__s_pkcs11h_threading_mutex_list.mutex);
6717+ mutex_locked = FALSE;
6718+ }
6719+ }
6720+#endif
6721+ return rv;
6722+}
6723+
6724+static
6725+CK_RV
6726+_pkcs11h_threading_mutexLock (
6727+ IN OUT pkcs11h_mutex_t *const mutex
6728+) {
6729+ CK_RV rv = CKR_OK;
6730+#if defined(WIN32)
6731+ if (
6732+ rv == CKR_OK &&
6733+ WaitForSingleObject (*mutex, INFINITE) == WAIT_FAILED
6734+ ) {
6735+ rv = CKR_FUNCTION_FAILED;
6736+ }
6737+#else
6738+ if (
6739+ rv == CKR_OK &&
6740+ pthread_mutex_lock (mutex)
6741+ ) {
6742+ rv = CKR_FUNCTION_FAILED;
6743+ }
6744+#endif
6745+ return rv;
6746+}
6747+
6748+static
6749+CK_RV
6750+_pkcs11h_threading_mutexRelease (
6751+ IN OUT pkcs11h_mutex_t *const mutex
6752+) {
6753+ CK_RV rv = CKR_OK;
6754+#if defined(WIN32)
6755+ if (
6756+ rv == CKR_OK &&
6757+ !ReleaseMutex (*mutex)
6758+ ) {
6759+ rv = CKR_FUNCTION_FAILED;
6760+ }
6761+#else
6762+ if (
6763+ rv == CKR_OK &&
6764+ pthread_mutex_unlock (mutex)
6765+ ) {
6766+ rv = CKR_FUNCTION_FAILED;
6767+ }
6768+#endif
6769+ return rv;
6770+}
6771+
6772+static
6773+CK_RV
6774+_pkcs11h_threading_mutexFree (
6775+ IN OUT pkcs11h_mutex_t *const mutex
6776+) {
6777+#if defined(WIN32)
6778+ if (*mutex != NULL) {
6779+ CloseHandle (*mutex);
6780+ *mutex = NULL;
6781+ }
6782+#else
6783+ {
6784+ __pkcs11h_threading_mutex_entry_t last = NULL;
6785+ __pkcs11h_threading_mutex_entry_t entry = NULL;
6786+ PKCS11H_BOOL mutex_locked = FALSE;
6787+
6788+ if (_pkcs11h_threading_mutexLock (&__s_pkcs11h_threading_mutex_list.mutex) == CKR_OK) {
6789+ mutex_locked = TRUE;
6790+ }
6791+
6792+ entry = __s_pkcs11h_threading_mutex_list.head;
6793+ while (
6794+ entry != NULL &&
6795+ entry->p_mutex != mutex
6796+ ) {
6797+ last = entry;
6798+ entry = entry->next;
6799+ }
6800+
6801+ if (entry != NULL) {
6802+ if (last == NULL) {
6803+ __s_pkcs11h_threading_mutex_list.head = entry->next;
6804+ }
6805+ else {
6806+ last->next = entry->next;
6807+ }
6808+ _pkcs11h_mem_free ((void *)&entry);
6809+ }
6810+
6811+ pthread_mutex_destroy (mutex);
6812+
6813+ if (mutex_locked) {
6814+ _pkcs11h_threading_mutexRelease (&__s_pkcs11h_threading_mutex_list.mutex);
6815+ mutex_locked = FALSE;
6816+ }
6817+ }
6818+#endif
6819+ return CKR_OK;
6820+}
6821+
6822+#if !defined(WIN32)
6823+/*
6824+ * This function is required in order
6825+ * to lock all mutexes before fork is called,
6826+ * and to avoid dedlocks.
6827+ * The loop is required because there is no
6828+ * way to lock all mutex in one system call...
6829+ */
6830+static
6831+void
6832+__pkcs1h_threading_mutexLockAll () {
6833+ __pkcs11h_threading_mutex_entry_t entry = NULL;
6834+ PKCS11H_BOOL mutex_locked = FALSE;
6835+ PKCS11H_BOOL all_mutexes_locked = FALSE;
6836+
6837+ if (_pkcs11h_threading_mutexLock (&__s_pkcs11h_threading_mutex_list.mutex) == CKR_OK) {
6838+ mutex_locked = TRUE;
6839+ }
6840+
6841+ for (
6842+ entry = __s_pkcs11h_threading_mutex_list.head;
6843+ entry != NULL;
6844+ entry = entry->next
6845+ ) {
6846+ entry->locked = FALSE;
6847+ }
6848+
6849+ while (!all_mutexes_locked) {
6850+ PKCS11H_BOOL ok = TRUE;
6851+
6852+ for (
6853+ entry = __s_pkcs11h_threading_mutex_list.head;
6854+ entry != NULL && ok;
6855+ entry = entry->next
6856+ ) {
6857+ if (!pthread_mutex_trylock (entry->p_mutex)) {
6858+ entry->locked = TRUE;
6859+ }
6860+ else {
6861+ ok = FALSE;
6862+ }
6863+ }
6864+
6865+ if (!ok) {
6866+ for (
6867+ entry = __s_pkcs11h_threading_mutex_list.head;
6868+ entry != NULL;
6869+ entry = entry->next
6870+ ) {
6871+ if (entry->locked == TRUE) {
6872+ pthread_mutex_unlock (entry->p_mutex);
6873+ entry->locked = FALSE;
6874+ }
6875+ }
6876+
6877+ _pkcs11h_threading_mutexRelease (&__s_pkcs11h_threading_mutex_list.mutex);
6878+ _pkcs11h_threading_sleep (1000);
6879+ _pkcs11h_threading_mutexLock (&__s_pkcs11h_threading_mutex_list.mutex);
6880+ }
6881+ else {
6882+ all_mutexes_locked = TRUE;
6883+ }
6884+ }
6885+
6886+ if (mutex_locked) {
6887+ _pkcs11h_threading_mutexRelease (&__s_pkcs11h_threading_mutex_list.mutex);
6888+ mutex_locked = FALSE;
6889+ }
6890+}
6891+
6892+static
6893+void
6894+__pkcs1h_threading_mutexReleaseAll () {
6895+ __pkcs11h_threading_mutex_entry_t entry = NULL;
6896+ PKCS11H_BOOL mutex_locked = FALSE;
6897+
6898+ if (_pkcs11h_threading_mutexLock (&__s_pkcs11h_threading_mutex_list.mutex) == CKR_OK) {
6899+ mutex_locked = TRUE;
6900+ }
6901+
6902+ for (
6903+ entry = __s_pkcs11h_threading_mutex_list.head;
6904+ entry != NULL;
6905+ entry = entry->next
6906+ ) {
6907+ pthread_mutex_unlock (entry->p_mutex);
6908+ entry->locked = FALSE;
6909+ }
6910+
6911+ if (mutex_locked) {
6912+ _pkcs11h_threading_mutexRelease (&__s_pkcs11h_threading_mutex_list.mutex);
6913+ mutex_locked = FALSE;
6914+ }
6915+}
6916+#endif
6917+
6918+CK_RV
6919+_pkcs11h_threading_condSignal (
6920+ IN OUT pkcs11h_cond_t *const cond
6921+) {
6922+ CK_RV rv = CKR_OK;
6923+#if defined(WIN32)
6924+ if (
6925+ rv == CKR_OK &&
6926+ !SetEvent (*cond)
6927+ ) {
6928+ rv = CKR_FUNCTION_FAILED;
6929+ }
6930+#else
6931+ if (
6932+ rv == CKR_OK &&
6933+ (
6934+ pthread_mutex_lock (&cond->mut) ||
6935+ pthread_cond_signal (&cond->cond) ||
6936+ pthread_mutex_unlock (&cond->mut)
6937+ )
6938+ ) {
6939+ rv = CKR_FUNCTION_FAILED;
6940+ }
6941+#endif
6942+
6943+ return rv;
6944+}
6945+
6946+static
6947+CK_RV
6948+_pkcs11h_threading_condInit (
6949+ OUT pkcs11h_cond_t * const cond
6950+) {
6951+ CK_RV rv = CKR_OK;
6952+#if defined(WIN32)
6953+ if (
6954+ rv == CKR_OK &&
6955+ (*cond = CreateEvent (NULL, FALSE, FALSE, NULL)) == NULL
6956+ ) {
6957+ rv = CKR_FUNCTION_FAILED;
6958+ }
6959+#else
6960+ if (
6961+ rv == CKR_OK &&
6962+ (
6963+ pthread_mutex_init (&cond->mut, NULL) ||
6964+ pthread_cond_init (&cond->cond, NULL) ||
6965+ pthread_mutex_lock (&cond->mut)
6966+ )
6967+ ) {
6968+ rv = CKR_FUNCTION_FAILED;
6969+ }
6970+#endif
6971+ return rv;
6972+}
6973+
6974+static
6975+CK_RV
6976+_pkcs11h_threading_condWait (
6977+ IN OUT pkcs11h_cond_t *const cond,
6978+ IN const unsigned milli
6979+) {
6980+ CK_RV rv = CKR_OK;
6981+
6982+#if defined(WIN32)
6983+ DWORD dwMilli;
6984+
6985+ if (milli == PKCS11H_COND_INFINITE) {
6986+ dwMilli = INFINITE;
6987+ }
6988+ else {
6989+ dwMilli = milli;
6990+ }
6991+
6992+ if (
6993+ rv == CKR_OK &&
6994+ WaitForSingleObject (*cond, dwMilli) == WAIT_FAILED
6995+ ) {
6996+ rv = CKR_FUNCTION_FAILED;
6997+ }
6998+#else
6999+ if (milli == PKCS11H_COND_INFINITE) {
7000+ if (
7001+ rv == CKR_OK &&
7002+ pthread_cond_wait (&cond->cond, &cond->mut)
7003+ ) {
7004+ rv = CKR_FUNCTION_FAILED;
7005+ }
7006+ }
7007+ else {
7008+ struct timeval now;
7009+ struct timespec timeout;
7010+
7011+ if (
7012+ rv == CKR_OK &&
7013+ gettimeofday (&now, NULL)
7014+ ) {
7015+ rv = CKR_FUNCTION_FAILED;
7016+ }
7017+
7018+ if (rv == CKR_OK) {
7019+ timeout.tv_sec = now.tv_sec + milli/1000;
7020+ timeout.tv_nsec = now.tv_usec*1000 + milli%1000;
7021+ }
7022+
7023+ if (
7024+ rv == CKR_OK &&
7025+ pthread_cond_timedwait (&cond->cond, &cond->mut, &timeout)
7026+ ) {
7027+ rv = CKR_FUNCTION_FAILED;
7028+ }
7029+ }
7030+#endif
7031+ return rv;
7032+}
7033+
7034+static
7035+CK_RV
7036+_pkcs11h_threading_condFree (
7037+ IN OUT pkcs11h_cond_t *const cond
7038+) {
7039+#if defined(WIN32)
7040+ CloseHandle (*cond);
7041+ *cond = NULL;
7042+#else
7043+ pthread_mutex_unlock (&cond->mut);
7044+#endif
7045+ return CKR_OK;
7046+}
7047+
7048+#if defined(WIN32)
7049+static
7050+unsigned
7051+__stdcall
7052+__pkcs11h_thread_start (void *p) {
7053+ __pkcs11h_thread_data_t *_data = (__pkcs11h_thread_data_t *)p;
7054+ unsigned ret;
7055+
7056+ ret = (unsigned)_data->start (_data->data);
7057+
7058+ _pkcs11h_mem_free ((void *)&_data);
7059+
7060+ return ret;
7061+}
7062+#else
7063+static
7064+void *
7065+__pkcs11h_thread_start (void *p) {
7066+ __pkcs11h_thread_data_t *_data = (__pkcs11h_thread_data_t *)p;
7067+ void *ret;
7068+ int i;
7069+
7070+ /*
7071+ * Ignore any signal in
7072+ * this thread
7073+ */
7074+ for (i=1;i<16;i++) {
7075+ signal (i, SIG_IGN);
7076+ }
7077+
7078+ ret = _data->start (_data->data);
7079+
7080+ _pkcs11h_mem_free ((void *)&_data);
7081+
7082+ return ret;
7083+}
7084+#endif
7085+
7086+static
7087+CK_RV
7088+_pkcs11h_threading_threadStart (
7089+ OUT pkcs11h_thread_t * const thread,
7090+ IN pkcs11h_thread_start_t const start,
7091+ IN void * data
7092+) {
7093+ __pkcs11h_thread_data_t *_data = NULL;
7094+ CK_RV rv = CKR_OK;
7095+
7096+ if (rv == CKR_OK) {
7097+ rv = _pkcs11h_mem_malloc (
7098+ (void *)&_data,
7099+ sizeof (__pkcs11h_thread_data_t)
7100+ );
7101+ }
7102+
7103+ if (rv == CKR_OK) {
7104+ _data->start = start;
7105+ _data->data = data;
7106+ }
7107+
7108+#if defined(WIN32)
7109+ {
7110+ unsigned tmp;
7111+
7112+ if (
7113+ rv == CKR_OK &&
7114+ (*thread = (HANDLE)_beginthreadex (
7115+ NULL,
7116+ 0,
7117+ __pkcs11h_thread_start,
7118+ _data,
7119+ 0,
7120+ &tmp
7121+ )) == NULL
7122+ ) {
7123+ rv = CKR_FUNCTION_FAILED;
7124+ }
7125+ }
7126+#else
7127+ if (
7128+ rv == CKR_OK &&
7129+ pthread_create (thread, NULL, __pkcs11h_thread_start, _data)
7130+ ) {
7131+ rv = CKR_FUNCTION_FAILED;
7132+ }
7133+#endif
7134+ return rv;
7135+}
7136+
7137+static
7138+CK_RV
7139+_pkcs11h_threading_threadJoin (
7140+ IN pkcs11h_thread_t * const thread
7141+) {
7142+#if defined(WIN32)
7143+ WaitForSingleObject (*thread, INFINITE);
7144+ CloseHandle (*thread);
7145+ *thread = NULL;
7146+#else
7147+ pthread_join (*thread, NULL);
7148+ *thread = 0l;
7149+#endif
7150+ return CKR_OK;
7151+}
7152+
7153+#endif /* ENABLE_PKCS11H_THREADING */
7154+
7155+/*======================================================================*
7156+ * COMMON INTERNAL INTERFACE
7157+ *======================================================================*/
7158+
7159+static
7160+void
7161+_pkcs11h_util_fixupFixedString (
7162+ OUT char * const target, /* MUST BE >= length+1 */
7163+ IN const char * const source,
7164+ IN const size_t length /* FIXED STRING LENGTH */
7165+) {
7166+ char *p;
7167+
7168+ PKCS11H_ASSERT (source!=NULL);
7169+ PKCS11H_ASSERT (target!=NULL);
7170+
7171+ p = target+length;
7172+ memmove (target, source, length);
7173+ *p = '\0';
7174+ p--;
7175+ while (p >= target && *p == ' ') {
7176+ *p = '\0';
7177+ p--;
7178+ }
7179+}
7180+
7181+static
7182+CK_RV
7183+_pkcs11h_util_hexToBinary (
7184+ OUT unsigned char * const target,
7185+ IN const char * const source,
7186+ IN OUT size_t * const p_target_size
7187+) {
7188+ size_t target_max_size;
7189+ const char *p;
7190+ char buf[3] = {'\0', '\0', '\0'};
7191+ int i = 0;
7192+
7193+ PKCS11H_ASSERT (source!=NULL);
7194+ PKCS11H_ASSERT (target!=NULL);
7195+ PKCS11H_ASSERT (p_target_size!=NULL);
7196+
7197+ target_max_size = *p_target_size;
7198+ p = source;
7199+ *p_target_size = 0;
7200+
7201+ while (*p != '\x0' && *p_target_size < target_max_size) {
7202+ if (isxdigit ((unsigned char)*p)) {
7203+ buf[i%2] = *p;
7204+
7205+ if ((i%2) == 1) {
7206+ unsigned v;
7207+ if (sscanf (buf, "%x", &v) != 1) {
7208+ v = 0;
7209+ }
7210+ target[*p_target_size] = v & 0xff;
7211+ (*p_target_size)++;
7212+ }
7213+
7214+ i++;
7215+ }
7216+ p++;
7217+ }
7218+
7219+ if (*p != '\x0') {
7220+ return CKR_ATTRIBUTE_VALUE_INVALID;
7221+ }
7222+ else {
7223+ return CKR_OK;
7224+ }
7225+}
7226+
7227+static
7228+CK_RV
7229+_pkcs11h_util_binaryToHex (
7230+ OUT char * const target,
7231+ IN const size_t target_size,
7232+ IN const unsigned char * const source,
7233+ IN const size_t source_size
7234+) {
7235+ static const char *x = "0123456789ABCDEF";
7236+ size_t i;
7237+
7238+ PKCS11H_ASSERT (target!=NULL);
7239+ PKCS11H_ASSERT (source!=NULL);
7240+
7241+ if (target_size < source_size * 2 + 1) {
7242+ return CKR_ATTRIBUTE_VALUE_INVALID;
7243+ }
7244+
7245+ for (i=0;i<source_size;i++) {
7246+ target[i*2] = x[(source[i]&0xf0)>>4];
7247+ target[i*2+1] = x[(source[i]&0x0f)>>0];
7248+ }
7249+ target[source_size*2] = '\x0';
7250+
7251+ return CKR_OK;
7252+}
7253+
7254+CK_RV
7255+_pkcs11h_util_escapeString (
7256+ IN OUT char * const target,
7257+ IN const char * const source,
7258+ IN size_t * const max,
7259+ IN const char * const invalid_chars
7260+) {
7261+ static const char *x = "0123456789ABCDEF";
7262+ CK_RV rv = CKR_OK;
7263+ const char *s = source;
7264+ char *t = target;
7265+ size_t n = 0;
7266+
7267+ /*PKCS11H_ASSERT (target!=NULL); Not required*/
7268+ PKCS11H_ASSERT (source!=NULL);
7269+ PKCS11H_ASSERT (max!=NULL);
7270+
7271+ while (rv == CKR_OK && *s != '\x0') {
7272+
7273+ if (*s == '\\' || strchr (invalid_chars, *s) || !isgraph (*s)) {
7274+ if (t != NULL) {
7275+ if (n+4 > *max) {
7276+ rv = CKR_ATTRIBUTE_VALUE_INVALID;
7277+ }
7278+ else {
7279+ t[0] = '\\';
7280+ t[1] = 'x';
7281+ t[2] = x[(*s&0xf0)>>4];
7282+ t[3] = x[(*s&0x0f)>>0];
7283+ t+=4;
7284+ }
7285+ }
7286+ n+=4;
7287+ }
7288+ else {
7289+ if (t != NULL) {
7290+ if (n+1 > *max) {
7291+ rv = CKR_ATTRIBUTE_VALUE_INVALID;
7292+ }
7293+ else {
7294+ *t = *s;
7295+ t++;
7296+ }
7297+ }
7298+ n+=1;
7299+ }
7300+
7301+ s++;
7302+ }
7303+
7304+ if (t != NULL) {
7305+ if (n+1 > *max) {
7306+ rv = CKR_ATTRIBUTE_VALUE_INVALID;
7307+ }
7308+ else {
7309+ *t = '\x0';
7310+ t++;
7311+ }
7312+ }
7313+ n++;
7314+
7315+ *max = n;
7316+
7317+ return rv;
7318+}
7319+
7320+static
7321+CK_RV
7322+_pkcs11h_util_unescapeString (
7323+ IN OUT char * const target,
7324+ IN const char * const source,
7325+ IN size_t * const max
7326+) {
7327+ CK_RV rv = CKR_OK;
7328+ const char *s = source;
7329+ char *t = target;
7330+ size_t n = 0;
7331+
7332+ /*PKCS11H_ASSERT (target!=NULL); Not required*/
7333+ PKCS11H_ASSERT (source!=NULL);
7334+ PKCS11H_ASSERT (max!=NULL);
7335+
7336+ while (rv == CKR_OK && *s != '\x0') {
7337+ if (*s == '\\') {
7338+ if (t != NULL) {
7339+ if (n+1 > *max) {
7340+ rv = CKR_ATTRIBUTE_VALUE_INVALID;
7341+ }
7342+ else {
7343+ char b[3];
7344+ unsigned u;
7345+ b[0] = s[2];
7346+ b[1] = s[3];
7347+ b[2] = '\x0';
7348+ sscanf (b, "%08x", &u);
7349+ *t = u&0xff;
7350+ t++;
7351+ }
7352+ }
7353+ s+=4;
7354+ }
7355+ else {
7356+ if (t != NULL) {
7357+ if (n+1 > *max) {
7358+ rv = CKR_ATTRIBUTE_VALUE_INVALID;
7359+ }
7360+ else {
7361+ *t = *s;
7362+ t++;
7363+ }
7364+ }
7365+ s++;
7366+ }
7367+
7368+ n+=1;
7369+ }
7370+
7371+ if (t != NULL) {
7372+ if (n+1 > *max) {
7373+ rv = CKR_ATTRIBUTE_VALUE_INVALID;
7374+ }
7375+ else {
7376+ *t = '\x0';
7377+ t++;
7378+ }
7379+ }
7380+ n++;
7381+
7382+ *max = n;
7383+
7384+ return rv;
7385+}
7386+
7387+static
7388+void
7389+_pkcs11h_log (
7390+ IN const unsigned flags,
7391+ IN const char * const format,
7392+ IN ...
7393+) {
7394+ va_list args;
7395+
7396+ PKCS11H_ASSERT (format!=NULL);
7397+
7398+ va_start (args, format);
7399+
7400+ if (
7401+ s_pkcs11h_data != NULL &&
7402+ s_pkcs11h_data->initialized
7403+ ) {
7404+ if (PKCS11H_MSG_LEVEL_TEST (flags)) {
7405+ if (s_pkcs11h_data->hooks.log == NULL) {
7406+ _pkcs11h_hooks_default_log (
7407+ NULL,
7408+ flags,
7409+ format,
7410+ args
7411+ );
7412+ }
7413+ else {
7414+ s_pkcs11h_data->hooks.log (
7415+ s_pkcs11h_data->hooks.log_data,
7416+ flags,
7417+ format,
7418+ args
7419+ );
7420+ }
7421+ }
7422+ }
7423+
7424+ va_end (args);
7425+}
7426+
7427+static
7428+CK_RV
7429+_pkcs11h_session_getSlotList (
7430+ IN const pkcs11h_provider_t provider,
7431+ IN const CK_BBOOL token_present,
7432+ OUT CK_SLOT_ID_PTR * const pSlotList,
7433+ OUT CK_ULONG_PTR pulCount
7434+) {
7435+ CK_SLOT_ID_PTR _slots = NULL;
7436+ CK_ULONG _slotnum = 0;
7437+ CK_RV rv = CKR_OK;
7438+
7439+ PKCS11H_ASSERT (provider!=NULL);
7440+ PKCS11H_ASSERT (pSlotList!=NULL);
7441+ PKCS11H_ASSERT (pulCount!=NULL);
7442+
7443+ PKCS11H_DEBUG (
7444+ PKCS11H_LOG_DEBUG2,
7445+ "PKCS#11: _pkcs11h_session_getSlotList entry provider=%p, token_present=%d, pSlotList=%p, pulCount=%p",
7446+ (void *)provider,
7447+ token_present,
7448+ (void *)pSlotList,
7449+ (void *)pulCount
7450+ );
7451+
7452+ *pSlotList = NULL;
7453+ *pulCount = 0;
7454+
7455+ if (
7456+ rv == CKR_OK &&
7457+ !provider->enabled
7458+ ) {
7459+ rv = CKR_CRYPTOKI_NOT_INITIALIZED;
7460+ }
7461+
7462+ if (rv == CKR_OK) {
7463+ rv = provider->f->C_GetSlotList (
7464+ token_present,
7465+ NULL_PTR,
7466+ &_slotnum
7467+ );
7468+ }
7469+
7470+ if (rv == CKR_OK && _slotnum > 0) {
7471+ rv = _pkcs11h_mem_malloc ((void *)&_slots, _slotnum * sizeof (CK_SLOT_ID));
7472+ }
7473+
7474+ if (rv == CKR_OK && _slotnum > 0) {
7475+ rv = provider->f->C_GetSlotList (
7476+ token_present,
7477+ _slots,
7478+ &_slotnum
7479+ );
7480+ }
7481+
7482+ if (rv == CKR_OK) {
7483+ *pSlotList = _slots;
7484+ _slots = NULL;
7485+ *pulCount = _slotnum;
7486+ }
7487+
7488+ if (_slots != NULL) {
7489+ _pkcs11h_mem_free ((void *)&_slots);
7490+ }
7491+
7492+ PKCS11H_DEBUG (
7493+ PKCS11H_LOG_DEBUG2,
7494+ "PKCS#11: _pkcs11h_session_getSlotList return rv=%ld-'%s' *pulCount=%ld",
7495+ rv,
7496+ pkcs11h_getMessage (rv),
7497+ *pulCount
7498+ );
7499+
7500+ return rv;
7501+}
7502+
7503+static
7504+CK_RV
7505+_pkcs11h_session_getObjectAttributes (
7506+ IN const pkcs11h_session_t session,
7507+ IN const CK_OBJECT_HANDLE object,
7508+ IN OUT const CK_ATTRIBUTE_PTR attrs,
7509+ IN const unsigned count
7510+) {
7511+ /*
7512+ * THREADING:
7513+ * session->mutex must be locked
7514+ */
7515+ CK_RV rv = CKR_OK;
7516+
7517+ PKCS11H_ASSERT (session!=NULL);
7518+ PKCS11H_ASSERT (attrs!=NULL);
7519+
7520+ PKCS11H_DEBUG (
7521+ PKCS11H_LOG_DEBUG2,
7522+ "PKCS#11: _pkcs11h_session_getObjectAttributes entry session=%p, object=%ld, attrs=%p, count=%u",
7523+ (void *)session,
7524+ object,
7525+ (void *)attrs,
7526+ count
7527+ );
7528+
7529+ if (
7530+ rv == CKR_OK &&
7531+ (rv = session->provider->f->C_GetAttributeValue (
7532+ session->session_handle,
7533+ object,
7534+ attrs,
7535+ count
7536+ )) == CKR_OK
7537+ ) {
7538+ unsigned i;
7539+ for (i=0;rv == CKR_OK && i<count;i++) {
7540+ if (attrs[i].ulValueLen == (CK_ULONG)-1) {
7541+ rv = CKR_ATTRIBUTE_VALUE_INVALID;
7542+ }
7543+ else if (attrs[i].ulValueLen == 0) {
7544+ attrs[i].pValue = NULL;
7545+ }
7546+ else {
7547+ rv = _pkcs11h_mem_malloc (
7548+ (void *)&attrs[i].pValue,
7549+ attrs[i].ulValueLen
7550+ );
7551+ }
7552+ }
7553+ }
7554+
7555+ if (rv == CKR_OK) {
7556+ rv = session->provider->f->C_GetAttributeValue (
7557+ session->session_handle,
7558+ object,
7559+ attrs,
7560+ count
7561+ );
7562+ }
7563+
7564+ PKCS11H_DEBUG (
7565+ PKCS11H_LOG_DEBUG2,
7566+ "PKCS#11: _pkcs11h_session_getObjectAttributes return rv=%ld-'%s'",
7567+ rv,
7568+ pkcs11h_getMessage (rv)
7569+ );
7570+
7571+ return rv;
7572+}
7573+
7574+static
7575+CK_RV
7576+_pkcs11h_session_freeObjectAttributes (
7577+ IN OUT const CK_ATTRIBUTE_PTR attrs,
7578+ IN const unsigned count
7579+) {
7580+ unsigned i;
7581+
7582+ CK_RV rv = CKR_OK;
7583+
7584+ PKCS11H_ASSERT (attrs!=NULL);
7585+
7586+ PKCS11H_DEBUG (
7587+ PKCS11H_LOG_DEBUG2,
7588+ "PKCS#11: _pkcs11h_session_freeObjectAttributes entry attrs=%p, count=%u",
7589+ (void *)attrs,
7590+ count
7591+ );
7592+
7593+ for (i=0;i<count;i++) {
7594+ if (attrs[i].pValue != NULL) {
7595+ _pkcs11h_mem_free ((void *)&attrs[i].pValue);
7596+ attrs[i].pValue = NULL;
7597+ }
7598+ }
7599+
7600+ PKCS11H_DEBUG (
7601+ PKCS11H_LOG_DEBUG2,
7602+ "PKCS#11: _pkcs11h_session_freeObjectAttributes return rv=%ld-'%s'",
7603+ rv,
7604+ pkcs11h_getMessage (rv)
7605+ );
7606+
7607+ return rv;
7608+}
7609+
7610+static
7611+CK_RV
7612+_pkcs11h_session_findObjects (
7613+ IN const pkcs11h_session_t session,
7614+ IN const CK_ATTRIBUTE * const filter,
7615+ IN const CK_ULONG filter_attrs,
7616+ OUT CK_OBJECT_HANDLE **const p_objects,
7617+ OUT CK_ULONG *p_objects_found
7618+) {
7619+ /*
7620+ * THREADING:
7621+ * session->mutex must be locked
7622+ */
7623+ PKCS11H_BOOL should_FindObjectsFinal = FALSE;
7624+
7625+ CK_OBJECT_HANDLE *objects = NULL;
7626+ CK_ULONG objects_size = 0;
7627+ CK_OBJECT_HANDLE objects_buffer[100];
7628+ CK_ULONG objects_found;
7629+ CK_OBJECT_HANDLE oLast = PKCS11H_INVALID_OBJECT_HANDLE;
7630+ CK_RV rv = CKR_OK;
7631+
7632+ PKCS11H_ASSERT (session!=NULL);
7633+ PKCS11H_ASSERT (!(filter==NULL && filter_attrs!=0) || filter!=NULL);
7634+ PKCS11H_ASSERT (p_objects!=NULL);
7635+ PKCS11H_ASSERT (p_objects_found!=NULL);
7636+
7637+ PKCS11H_DEBUG (
7638+ PKCS11H_LOG_DEBUG2,
7639+ "PKCS#11: _pkcs11h_session_findObjects entry session=%p, filter=%p, filter_attrs=%ld, p_objects=%p, p_objects_found=%p",
7640+ (void *)session,
7641+ (void *)filter,
7642+ filter_attrs,
7643+ (void *)p_objects,
7644+ (void *)p_objects_found
7645+ );
7646+
7647+ *p_objects = NULL;
7648+ *p_objects_found = 0;
7649+
7650+ if (
7651+ rv == CKR_OK &&
7652+ (rv = session->provider->f->C_FindObjectsInit (
7653+ session->session_handle,
7654+ (CK_ATTRIBUTE *)filter,
7655+ filter_attrs
7656+ )) == CKR_OK
7657+ ) {
7658+ should_FindObjectsFinal = TRUE;
7659+ }
7660+
7661+ while (
7662+ rv == CKR_OK &&
7663+ (rv = session->provider->f->C_FindObjects (
7664+ session->session_handle,
7665+ objects_buffer,
7666+ sizeof (objects_buffer) / sizeof (CK_OBJECT_HANDLE),
7667+ &objects_found
7668+ )) == CKR_OK &&
7669+ objects_found > 0
7670+ ) {
7671+ CK_OBJECT_HANDLE *temp = NULL;
7672+
7673+ /*
7674+ * Begin workaround
7675+ *
7676+ * Workaround iKey bug
7677+ * It returns the same objects over and over
7678+ */
7679+ if (oLast == objects_buffer[0]) {
7680+ PKCS11H_LOG (
7681+ PKCS11H_LOG_WARN,
7682+ "PKCS#11: Bad PKCS#11 C_FindObjects implementation detected, workaround applied"
7683+ );
7684+ break;
7685+ }
7686+ oLast = objects_buffer[0];
7687+ /* End workaround */
7688+
7689+ if (
7690+ (rv = _pkcs11h_mem_malloc (
7691+ (void *)&temp,
7692+ (objects_size+objects_found) * sizeof (CK_OBJECT_HANDLE)
7693+ )) == CKR_OK
7694+ ) {
7695+ if (objects != NULL) {
7696+ memmove (
7697+ temp,
7698+ objects,
7699+ objects_size * sizeof (CK_OBJECT_HANDLE)
7700+ );
7701+ }
7702+ memmove (
7703+ temp + objects_size,
7704+ objects_buffer,
7705+ objects_found * sizeof (CK_OBJECT_HANDLE)
7706+ );
7707+ }
7708+
7709+ if (objects != NULL) {
7710+ _pkcs11h_mem_free ((void *)&objects);
7711+ objects = NULL;
7712+ }
7713+
7714+ if (rv == CKR_OK) {
7715+ objects = temp;
7716+ objects_size += objects_found;
7717+ temp = NULL;
7718+ }
7719+
7720+ if (temp != NULL) {
7721+ _pkcs11h_mem_free ((void *)&temp);
7722+ temp = NULL;
7723+ }
7724+ }
7725+
7726+ if (should_FindObjectsFinal) {
7727+ session->provider->f->C_FindObjectsFinal (
7728+ session->session_handle
7729+ );
7730+ should_FindObjectsFinal = FALSE;
7731+ }
7732+
7733+ if (rv == CKR_OK) {
7734+ *p_objects = objects;
7735+ *p_objects_found = objects_size;
7736+ objects = NULL;
7737+ objects_size = 0;
7738+ }
7739+
7740+ if (objects != NULL) {
7741+ _pkcs11h_mem_free ((void *)&objects);
7742+ objects = NULL;
7743+ objects_size = 0;
7744+ }
7745+
7746+ PKCS11H_DEBUG (
7747+ PKCS11H_LOG_DEBUG2,
7748+ "PKCS#11: _pkcs11h_session_findObjects return rv=%ld-'%s', *p_objects_found=%ld",
7749+ rv,
7750+ pkcs11h_getMessage (rv),
7751+ *p_objects_found
7752+ );
7753+
7754+ return rv;
7755+}
7756+
7757+static
7758+CK_RV
7759+_pkcs11h_token_getTokenId (
7760+ IN const CK_TOKEN_INFO_PTR info,
7761+ OUT pkcs11h_token_id_t * const p_token_id
7762+) {
7763+ pkcs11h_token_id_t token_id;
7764+ CK_RV rv = CKR_OK;
7765+
7766+ PKCS11H_ASSERT (info!=NULL);
7767+ PKCS11H_ASSERT (p_token_id!=NULL);
7768+
7769+ PKCS11H_DEBUG (
7770+ PKCS11H_LOG_DEBUG2,
7771+ "PKCS#11: _pkcs11h_token_getTokenId entry p_token_id=%p",
7772+ (void *)p_token_id
7773+ );
7774+
7775+ *p_token_id = NULL;
7776+
7777+ if (
7778+ rv == CKR_OK &&
7779+ (rv = _pkcs11h_token_newTokenId (&token_id)) == CKR_OK
7780+ ) {
7781+ _pkcs11h_util_fixupFixedString (
7782+ token_id->label,
7783+ (char *)info->label,
7784+ sizeof (info->label)
7785+ );
7786+ _pkcs11h_util_fixupFixedString (
7787+ token_id->manufacturerID,
7788+ (char *)info->manufacturerID,
7789+ sizeof (info->manufacturerID)
7790+ );
7791+ _pkcs11h_util_fixupFixedString (
7792+ token_id->model,
7793+ (char *)info->model,
7794+ sizeof (info->model)
7795+ );
7796+ _pkcs11h_util_fixupFixedString (
7797+ token_id->serialNumber,
7798+ (char *)info->serialNumber,
7799+ sizeof (info->serialNumber)
7800+ );
7801+ strncpy (
7802+ token_id->display,
7803+ token_id->label,
7804+ sizeof (token_id->display)
7805+ );
7806+ }
7807+
7808+ if (rv == CKR_OK) {
7809+ *p_token_id = token_id;
7810+ token_id = NULL;
7811+ }
7812+
7813+ if (token_id != NULL) {
7814+ _pkcs11h_mem_free ((void *)&token_id);
7815+ }
7816+
7817+ PKCS11H_DEBUG (
7818+ PKCS11H_LOG_DEBUG2,
7819+ "PKCS#11: _pkcs11h_token_getTokenId return rv=%ld-'%s', *p_token_id=%p",
7820+ rv,
7821+ pkcs11h_getMessage (rv),
7822+ (void *)*p_token_id
7823+ );
7824+
7825+ return rv;
7826+}
7827+
7828+static
7829+CK_RV
7830+_pkcs11h_token_newTokenId (
7831+ OUT pkcs11h_token_id_t * const p_token_id
7832+) {
7833+ CK_RV rv = CKR_OK;
7834+
7835+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
7836+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
7837+ PKCS11H_ASSERT (p_token_id!=NULL);
7838+
7839+ PKCS11H_DEBUG (
7840+ PKCS11H_LOG_DEBUG2,
7841+ "PKCS#11: _pkcs11h_token_newTokenId entry p_token_id=%p",
7842+ (void *)p_token_id
7843+ );
7844+
7845+ *p_token_id = NULL;
7846+
7847+ if (rv == CKR_OK) {
7848+ rv = _pkcs11h_mem_malloc ((void *)p_token_id, sizeof (struct pkcs11h_token_id_s));
7849+ }
7850+
7851+ PKCS11H_DEBUG (
7852+ PKCS11H_LOG_DEBUG2,
7853+ "PKCS#11: _pkcs11h_token_newTokenId return rv=%ld-'%s', *p_token_id=%p",
7854+ rv,
7855+ pkcs11h_getMessage (rv),
7856+ (void *)*p_token_id
7857+ );
7858+
7859+ return rv;
7860+}
7861+
7862+static
7863+CK_RV
7864+_pkcs11h_session_getSessionByTokenId (
7865+ IN const pkcs11h_token_id_t token_id,
7866+ OUT pkcs11h_session_t * const p_session
7867+) {
7868+#if defined(ENABLE_PKCS11H_THREADING)
7869+ PKCS11H_BOOL mutex_locked = FALSE;
7870+#endif
7871+ pkcs11h_session_t session = NULL;
7872+ PKCS11H_BOOL is_new_session = FALSE;
7873+ CK_RV rv = CKR_OK;
7874+
7875+ PKCS11H_ASSERT (token_id!=NULL);
7876+ PKCS11H_ASSERT (p_session!=NULL);
7877+
7878+ PKCS11H_DEBUG (
7879+ PKCS11H_LOG_DEBUG2,
7880+ "PKCS#11: _pkcs11h_session_getSessionByTokenId entry token_id=%p, p_session=%p",
7881+ (void *)token_id,
7882+ (void *)p_session
7883+ );
7884+
7885+ *p_session = NULL;
7886+
7887+#if defined(ENABLE_PKCS11H_THREADING)
7888+ if (
7889+ rv == CKR_OK &&
7890+ (rv = _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.session)) == CKR_OK
7891+ ) {
7892+ mutex_locked = TRUE;
7893+ }
7894+#endif
7895+
7896+ if (rv == CKR_OK) {
7897+ pkcs11h_session_t current_session;
7898+
7899+ for (
7900+ current_session = s_pkcs11h_data->sessions;
7901+ current_session != NULL && session == NULL;
7902+ current_session = current_session->next
7903+ ) {
7904+ if (
7905+ pkcs11h_token_sameTokenId (
7906+ current_session->token_id,
7907+ token_id
7908+ )
7909+ ) {
7910+ PKCS11H_DEBUG (
7911+ PKCS11H_LOG_DEBUG1,
7912+ "PKCS#11: Using cached session"
7913+ );
7914+ session = current_session;
7915+ session->reference_count++;
7916+ }
7917+ }
7918+ }
7919+
7920+ if (
7921+ rv == CKR_OK &&
7922+ session == NULL
7923+ ) {
7924+ is_new_session = TRUE;
7925+ }
7926+
7927+ if (is_new_session) {
7928+ PKCS11H_DEBUG (
7929+ PKCS11H_LOG_DEBUG1,
7930+ "PKCS#11: Creating a new session"
7931+ );
7932+
7933+ if (
7934+ rv == CKR_OK &&
7935+ (rv = _pkcs11h_mem_malloc ((void *)&session, sizeof (struct pkcs11h_session_s))) == CKR_OK
7936+ ) {
7937+ session->reference_count = 1;
7938+ session->session_handle = PKCS11H_INVALID_SESSION_HANDLE;
7939+
7940+ session->pin_cache_period = s_pkcs11h_data->pin_cache_period;
7941+
7942+ }
7943+
7944+ if (rv == CKR_OK) {
7945+ rv = pkcs11h_token_duplicateTokenId (
7946+ &session->token_id,
7947+ token_id
7948+ );
7949+ }
7950+
7951+#if defined(ENABLE_PKCS11H_THREADING)
7952+ if (rv == CKR_OK) {
7953+ rv = _pkcs11h_threading_mutexInit (&session->mutex);
7954+ }
7955+#endif
7956+
7957+ if (rv == CKR_OK) {
7958+ session->valid = TRUE;
7959+ session->next = s_pkcs11h_data->sessions;
7960+ s_pkcs11h_data->sessions = session;
7961+ }
7962+ else {
7963+#if defined(ENABLE_PKCS11H_THREADING)
7964+ _pkcs11h_threading_mutexFree (&session->mutex);
7965+#endif
7966+ _pkcs11h_mem_free ((void *)&session);
7967+ }
7968+ }
7969+
7970+ if (rv == CKR_OK) {
7971+ *p_session = session;
7972+ session = NULL;
7973+ }
7974+
7975+#if defined(ENABLE_PKCS11H_THREADING)
7976+ if (mutex_locked) {
7977+ _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.session);
7978+ mutex_locked = FALSE;
7979+ }
7980+#endif
7981+
7982+ PKCS11H_DEBUG (
7983+ PKCS11H_LOG_DEBUG2,
7984+ "PKCS#11: _pkcs11h_session_getSessionByTokenId return rv=%ld-'%s', *p_session=%p",
7985+ rv,
7986+ pkcs11h_getMessage (rv),
7987+ (void *)*p_session
7988+ );
7989+
7990+ return rv;
7991+}
7992+
7993+static
7994+CK_RV
7995+_pkcs11h_session_release (
7996+ IN const pkcs11h_session_t session
7997+) {
7998+#if defined(ENABLE_PKCS11H_THREADING)
7999+ PKCS11H_BOOL mutex_locked = FALSE;
8000+#endif
8001+ CK_RV rv = CKR_OK;
8002+
8003+ PKCS11H_ASSERT (session!=NULL);
8004+ PKCS11H_ASSERT (session->reference_count>=0);
8005+
8006+ PKCS11H_DEBUG (
8007+ PKCS11H_LOG_DEBUG2,
8008+ "PKCS#11: _pkcs11h_session_release entry session=%p",
8009+ (void *)session
8010+ );
8011+
8012+#if defined(ENABLE_PKCS11H_THREADING)
8013+ if (
8014+ rv == CKR_OK &&
8015+ (rv = _pkcs11h_threading_mutexLock (&session->mutex)) == CKR_OK
8016+ ) {
8017+ mutex_locked = TRUE;
8018+ }
8019+#endif
8020+
8021+ /*
8022+ * Never logout for now
8023+ */
8024+ if (rv == CKR_OK) {
8025+ if (session->reference_count > 0) {
8026+ session->reference_count--;
8027+ }
8028+ }
8029+
8030+#if defined(ENABLE_PKCS11H_THREADING)
8031+ if (mutex_locked) {
8032+ _pkcs11h_threading_mutexRelease (&session->mutex);
8033+ mutex_locked = FALSE;
8034+ }
8035+#endif
8036+
8037+ PKCS11H_DEBUG (
8038+ PKCS11H_LOG_DEBUG2,
8039+ "PKCS#11: _pkcs11h_session_release return rv=%ld-'%s'",
8040+ rv,
8041+ pkcs11h_getMessage (rv)
8042+ );
8043+
8044+ return rv;
8045+}
8046+
8047+static
8048+CK_RV
8049+_pkcs11h_session_reset (
8050+ IN const pkcs11h_session_t session,
8051+ IN void * const user_data,
8052+ IN const unsigned mask_prompt,
8053+ OUT CK_SLOT_ID * const p_slot
8054+) {
8055+ PKCS11H_BOOL found = FALSE;
8056+
8057+ CK_RV rv = CKR_OK;
8058+
8059+ unsigned nRetry = 0;
8060+
8061+ PKCS11H_ASSERT (session!=NULL);
8062+ /*PKCS11H_ASSERT (user_data) NOT NEEDED */
8063+ PKCS11H_ASSERT (p_slot!=NULL);
8064+
8065+ PKCS11H_DEBUG (
8066+ PKCS11H_LOG_DEBUG2,
8067+ "PKCS#11: _pkcs11h_session_reset entry session=%p, user_data=%p, mask_prompt=%08x, p_slot=%p",
8068+ (void *)session,
8069+ user_data,
8070+ mask_prompt,
8071+ (void *)p_slot
8072+ );
8073+
8074+ *p_slot = PKCS11H_INVALID_SLOT_ID;
8075+
8076+ while (
8077+ rv == CKR_OK &&
8078+ !found
8079+ ) {
8080+ pkcs11h_provider_t current_provider = NULL;
8081+
8082+ for (
8083+ current_provider = s_pkcs11h_data->providers;
8084+ (
8085+ rv == CKR_OK &&
8086+ current_provider != NULL &&
8087+ !found
8088+ );
8089+ current_provider = current_provider->next
8090+ ) {
8091+ CK_SLOT_ID_PTR slots = NULL;
8092+ CK_ULONG slotnum;
8093+ CK_SLOT_ID slot_index;
8094+
8095+ /*
8096+ * Skip all other providers,
8097+ * if one was set in the past
8098+ */
8099+ if (
8100+ session->provider != NULL &&
8101+ session->provider != current_provider
8102+ ) {
8103+ rv = CKR_CANCEL;
8104+ }
8105+
8106+ if (rv == CKR_OK) {
8107+ rv = _pkcs11h_session_getSlotList (
8108+ current_provider,
8109+ CK_TRUE,
8110+ &slots,
8111+ &slotnum
8112+ );
8113+ }
8114+
8115+ for (
8116+ slot_index=0;
8117+ (
8118+ slot_index < slotnum &&
8119+ rv == CKR_OK &&
8120+ !found
8121+ );
8122+ slot_index++
8123+ ) {
8124+ pkcs11h_token_id_t token_id = NULL;
8125+ CK_TOKEN_INFO info;
8126+
8127+ if (rv == CKR_OK) {
8128+ rv = current_provider->f->C_GetTokenInfo (
8129+ slots[slot_index],
8130+ &info
8131+ );
8132+ }
8133+
8134+ if (
8135+ rv == CKR_OK &&
8136+ (rv = _pkcs11h_token_getTokenId (
8137+ &info,
8138+ &token_id
8139+ )) == CKR_OK &&
8140+ pkcs11h_token_sameTokenId (
8141+ session->token_id,
8142+ token_id
8143+ )
8144+ ) {
8145+ found = TRUE;
8146+ *p_slot = slots[slot_index];
8147+ if (session->provider == NULL) {
8148+ session->provider = current_provider;
8149+ session->allow_protected_auth_supported = (info.flags & CKF_PROTECTED_AUTHENTICATION_PATH) != 0;
8150+ }
8151+ }
8152+
8153+ if (rv != CKR_OK) {
8154+ PKCS11H_DEBUG (
8155+ PKCS11H_LOG_DEBUG1,
8156+ "PKCS#11: Cannot get token information for provider '%s' slot %ld rv=%ld-'%s'",
8157+ current_provider->manufacturerID,
8158+ slots[slot_index],
8159+ rv,
8160+ pkcs11h_getMessage (rv)
8161+ );
8162+
8163+ /*
8164+ * Ignore error
8165+ */
8166+ rv = CKR_OK;
8167+ }
8168+
8169+ if (token_id != NULL) {
8170+ pkcs11h_token_freeTokenId (token_id);
8171+ }
8172+ }
8173+
8174+ if (rv != CKR_OK) {
8175+ PKCS11H_DEBUG (
8176+ PKCS11H_LOG_DEBUG1,
8177+ "PKCS#11: Cannot get slot list for provider '%s' rv=%ld-'%s'",
8178+ current_provider->manufacturerID,
8179+ rv,
8180+ pkcs11h_getMessage (rv)
8181+ );
8182+
8183+ /*
8184+ * Ignore error
8185+ */
8186+ rv = CKR_OK;
8187+ }
8188+
8189+ if (slots != NULL) {
8190+ _pkcs11h_mem_free ((void *)&slots);
8191+ slots = NULL;
8192+ }
8193+ }
8194+
8195+ if (rv == CKR_OK && !found && (mask_prompt & PKCS11H_PROMPT_MAST_ALLOW_CARD_PROMPT) == 0) {
8196+ rv = CKR_TOKEN_NOT_PRESENT;
8197+ }
8198+
8199+ if (
8200+ rv == CKR_OK &&
8201+ !found
8202+ ) {
8203+ PKCS11H_DEBUG (
8204+ PKCS11H_LOG_DEBUG1,
8205+ "PKCS#11: Calling token_prompt hook for '%s'",
8206+ session->token_id->display
8207+ );
8208+
8209+ if (
8210+ !s_pkcs11h_data->hooks.token_prompt (
8211+ s_pkcs11h_data->hooks.token_prompt_data,
8212+ user_data,
8213+ session->token_id,
8214+ nRetry++
8215+ )
8216+ ) {
8217+ rv = CKR_CANCEL;
8218+ }
8219+
8220+ PKCS11H_DEBUG (
8221+ PKCS11H_LOG_DEBUG1,
8222+ "PKCS#11: token_prompt returned %ld",
8223+ rv
8224+ );
8225+ }
8226+ }
8227+
8228+ PKCS11H_DEBUG (
8229+ PKCS11H_LOG_DEBUG2,
8230+ "PKCS#11: _pkcs11h_session_reset return rv=%ld-'%s', *p_slot=%ld",
8231+ rv,
8232+ pkcs11h_getMessage (rv),
8233+ *p_slot
8234+ );
8235+
8236+ return rv;
8237+}
8238+
8239+static
8240+CK_RV
8241+_pkcs11h_session_getObjectById (
8242+ IN const pkcs11h_session_t session,
8243+ IN const CK_OBJECT_CLASS class,
8244+ IN const CK_BYTE_PTR id,
8245+ IN const size_t id_size,
8246+ OUT CK_OBJECT_HANDLE * const p_handle
8247+) {
8248+ /*
8249+ * THREADING:
8250+ * session->mutex must be locked
8251+ */
8252+ CK_ATTRIBUTE filter[] = {
8253+ {CKA_CLASS, (void *)&class, sizeof (class)},
8254+ {CKA_ID, (void *)id, id_size}
8255+ };
8256+ CK_OBJECT_HANDLE *objects = NULL;
8257+ CK_ULONG objects_found = 0;
8258+ CK_RV rv = CKR_OK;
8259+
8260+ /*PKCS11H_ASSERT (session!=NULL); NOT NEEDED*/
8261+ PKCS11H_ASSERT (id!=NULL);
8262+ PKCS11H_ASSERT (p_handle!=NULL);
8263+
8264+ PKCS11H_DEBUG (
8265+ PKCS11H_LOG_DEBUG2,
8266+ "PKCS#11: _pkcs11h_session_getObjectById entry session=%p, class=%ld, id=%p, id_size=%u, p_handle=%p",
8267+ (void *)session,
8268+ class,
8269+ id,
8270+ id_size,
8271+ (void *)p_handle
8272+ );
8273+
8274+ *p_handle = PKCS11H_INVALID_OBJECT_HANDLE;
8275+
8276+ if (rv == CKR_OK) {
8277+ rv = _pkcs11h_session_validate (session);
8278+ }
8279+
8280+ if (rv == CKR_OK) {
8281+ rv = _pkcs11h_session_findObjects (
8282+ session,
8283+ filter,
8284+ sizeof (filter) / sizeof (CK_ATTRIBUTE),
8285+ &objects,
8286+ &objects_found
8287+ );
8288+ }
8289+
8290+ if (
8291+ rv == CKR_OK &&
8292+ objects_found == 0
8293+ ) {
8294+ rv = CKR_FUNCTION_REJECTED;
8295+ }
8296+
8297+ if (rv == CKR_OK) {
8298+ *p_handle = objects[0];
8299+ }
8300+
8301+ if (objects != NULL) {
8302+ _pkcs11h_mem_free ((void *)&objects);
8303+ }
8304+
8305+ PKCS11H_DEBUG (
8306+ PKCS11H_LOG_DEBUG2,
8307+ "PKCS#11: _pkcs11h_session_getObjectById return rv=%ld-'%s', *p_handle=%p",
8308+ rv,
8309+ pkcs11h_getMessage (rv),
8310+ (void *)*p_handle
8311+ );
8312+
8313+ return rv;
8314+}
8315+
8316+static
8317+CK_RV
8318+_pkcs11h_session_validate (
8319+ IN const pkcs11h_session_t session
8320+) {
8321+ CK_RV rv = CKR_OK;
8322+
8323+ /*PKCS11H_ASSERT (session!=NULL); NOT NEEDED*/
8324+
8325+ PKCS11H_DEBUG (
8326+ PKCS11H_LOG_DEBUG2,
8327+ "PKCS#11: _pkcs11h_session_validate entry session=%p",
8328+ (void *)session
8329+ );
8330+
8331+ if (
8332+ rv == CKR_OK &&
8333+ session == NULL
8334+ ) {
8335+ rv = CKR_SESSION_HANDLE_INVALID;
8336+ }
8337+
8338+ if (
8339+ rv == CKR_OK &&
8340+ (
8341+ session->provider == NULL ||
8342+ !session->provider->enabled ||
8343+ session->session_handle == PKCS11H_INVALID_SESSION_HANDLE
8344+ )
8345+ ) {
8346+ rv = CKR_SESSION_HANDLE_INVALID;
8347+ }
8348+
8349+ if (
8350+ rv == CKR_OK &&
8351+ session->pin_expire_time != (time_t)0 &&
8352+ session->pin_expire_time < PKCS11H_TIME (NULL)
8353+ ) {
8354+ PKCS11H_DEBUG (
8355+ PKCS11H_LOG_DEBUG1,
8356+ "PKCS#11: Forcing logout due to pin timeout"
8357+ );
8358+ _pkcs11h_session_logout (session);
8359+ rv = CKR_SESSION_HANDLE_INVALID;
8360+ }
8361+
8362+ PKCS11H_DEBUG (
8363+ PKCS11H_LOG_DEBUG2,
8364+ "PKCS#11: _pkcs11h_session_validate return rv=%ld-'%s'",
8365+ rv,
8366+ pkcs11h_getMessage (rv)
8367+ );
8368+
8369+ return rv;
8370+}
8371+
8372+static
8373+CK_RV
8374+_pkcs11h_session_touch (
8375+ IN const pkcs11h_session_t session
8376+) {
8377+ /*
8378+ * THREADING:
8379+ * session->mutex must be locked
8380+ */
8381+ PKCS11H_ASSERT (session!=NULL);
8382+
8383+ if (session->pin_cache_period == PKCS11H_PIN_CACHE_INFINITE) {
8384+ session->pin_expire_time = 0;
8385+ }
8386+ else {
8387+ session->pin_expire_time = (
8388+ PKCS11H_TIME (NULL) +
8389+ (time_t)session->pin_cache_period
8390+ );
8391+ }
8392+
8393+ return CKR_OK;
8394+}
8395+
8396+CK_RV
8397+pkcs11h_token_login (
8398+ IN const pkcs11h_token_id_t token_id,
8399+ IN const PKCS11H_BOOL readonly,
8400+ IN const char * const pin
8401+) {
8402+#if defined(ENABLE_PKCS11H_THREADING)
8403+ PKCS11H_BOOL mutex_locked = FALSE;
8404+#endif
8405+ CK_SLOT_ID slot = PKCS11H_INVALID_SLOT_ID;
8406+ CK_ULONG pin_size = 0;
8407+ CK_RV rv = CKR_OK;
8408+
8409+ pkcs11h_session_t session = NULL;
8410+
8411+ PKCS11H_ASSERT (token_id!=NULL);
8412+ /*PKCS11H_ASSERT (pin!=NULL); NOT NEEDED*/
8413+
8414+ PKCS11H_DEBUG (
8415+ PKCS11H_LOG_DEBUG2,
8416+ "PKCS#11: pkcs11h_token_login entry token_id=%p, readonly=%d\n",
8417+ (void *)token_id,
8418+ readonly ? 1 : 0
8419+ );
8420+
8421+ if (pin != NULL) {
8422+ pin_size = strlen (pin);
8423+ }
8424+
8425+ if (rv == CKR_OK) {
8426+ rv = _pkcs11h_session_getSessionByTokenId (
8427+ token_id,
8428+ &session
8429+ );
8430+ }
8431+
8432+#if defined(ENABLE_PKCS11H_THREADING)
8433+ if (
8434+ rv == CKR_OK &&
8435+ (rv = _pkcs11h_threading_mutexLock (&session->mutex)) == CKR_OK
8436+ ) {
8437+ mutex_locked = TRUE;
8438+ }
8439+#endif
8440+
8441+ if (rv == CKR_OK) {
8442+ rv = _pkcs11h_session_logout (session);
8443+ }
8444+
8445+ if (rv == CKR_OK) {
8446+ rv = _pkcs11h_session_reset (session, NULL, 0, &slot);
8447+ }
8448+
8449+ if (rv == CKR_OK) {
8450+ rv = _pkcs11h_session_touch (session);
8451+ }
8452+
8453+ if (rv == CKR_OK) {
8454+ rv = session->provider->f->C_OpenSession (
8455+ slot,
8456+ (
8457+ CKF_SERIAL_SESSION |
8458+ (readonly ? 0 : CKF_RW_SESSION)
8459+ ),
8460+ NULL_PTR,
8461+ NULL_PTR,
8462+ &session->session_handle
8463+ );
8464+ }
8465+
8466+ if (
8467+ rv == CKR_OK &&
8468+ (rv = session->provider->f->C_Login (
8469+ session->session_handle,
8470+ CKU_USER,
8471+ (CK_UTF8CHAR_PTR)pin,
8472+ pin_size
8473+ )) != CKR_OK
8474+ ) {
8475+ if (rv == CKR_USER_ALREADY_LOGGED_IN) {
8476+ rv = CKR_OK;
8477+ }
8478+ }
8479+
8480+#if defined(ENABLE_PKCS11H_THREADING)
8481+ if (mutex_locked) {
8482+ _pkcs11h_threading_mutexRelease (&session->mutex);
8483+ mutex_locked = FALSE;
8484+ }
8485+#endif
8486+
8487+ if (session != NULL) {
8488+ _pkcs11h_session_release (session);
8489+ session = NULL;
8490+ }
8491+
8492+ PKCS11H_DEBUG (
8493+ PKCS11H_LOG_DEBUG2,
8494+ "PKCS#11: pkcs11h_token_login return rv=%ld-'%s'",
8495+ rv,
8496+ pkcs11h_getMessage (rv)
8497+ );
8498+
8499+ return rv;
8500+}
8501+
8502+static
8503+CK_RV
8504+_pkcs11h_session_login (
8505+ IN const pkcs11h_session_t session,
8506+ IN const PKCS11H_BOOL is_publicOnly,
8507+ IN const PKCS11H_BOOL readonly,
8508+ IN void * const user_data,
8509+ IN const unsigned mask_prompt
8510+) {
8511+ /*
8512+ * THREADING:
8513+ * session->mutex must be locked
8514+ */
8515+ CK_SLOT_ID slot = PKCS11H_INVALID_SLOT_ID;
8516+ CK_RV rv = CKR_OK;
8517+
8518+ PKCS11H_ASSERT (session!=NULL);
8519+ /*PKCS11H_ASSERT (user_data) NOT NEEDED */
8520+
8521+ PKCS11H_DEBUG (
8522+ PKCS11H_LOG_DEBUG2,
8523+ "PKCS#11: _pkcs11h_session_login entry session=%p, is_publicOnly=%d, readonly=%d, user_data=%p, mask_prompt=%08x",
8524+ (void *)session,
8525+ is_publicOnly ? 1 : 0,
8526+ readonly ? 1 : 0,
8527+ user_data,
8528+ mask_prompt
8529+ );
8530+
8531+ if (rv == CKR_OK) {
8532+ rv = _pkcs11h_session_logout (session);
8533+ }
8534+
8535+ if (rv == CKR_OK) {
8536+ rv = _pkcs11h_session_reset (session, user_data, mask_prompt, &slot);
8537+ }
8538+
8539+ if (rv == CKR_OK) {
8540+ rv = session->provider->f->C_OpenSession (
8541+ slot,
8542+ (
8543+ CKF_SERIAL_SESSION |
8544+ (readonly ? 0 : CKF_RW_SESSION)
8545+ ),
8546+ NULL_PTR,
8547+ NULL_PTR,
8548+ &session->session_handle
8549+ );
8550+ }
8551+
8552+ if (
8553+ rv == CKR_OK &&
8554+ (
8555+ !is_publicOnly ||
8556+ session->provider->cert_is_private
8557+ )
8558+ ) {
8559+ PKCS11H_BOOL login_succeeded = FALSE;
8560+ unsigned nRetryCount = 0;
8561+
8562+ if ((mask_prompt & PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT) == 0) {
8563+ rv = CKR_USER_NOT_LOGGED_IN;
8564+
8565+ PKCS11H_DEBUG (
8566+ PKCS11H_LOG_DEBUG1,
8567+ "PKCS#11: Calling pin_prompt hook denied because of prompt mask"
8568+ );
8569+ }
8570+
8571+ while (
8572+ rv == CKR_OK &&
8573+ !login_succeeded &&
8574+ nRetryCount < s_pkcs11h_data->max_retries
8575+ ) {
8576+ CK_UTF8CHAR_PTR utfPIN = NULL;
8577+ CK_ULONG lPINLength = 0;
8578+ char pin[1024];
8579+
8580+ if (
8581+ rv == CKR_OK &&
8582+ !(
8583+ s_pkcs11h_data->allow_protected_auth &&
8584+ session->provider->allow_protected_auth &&
8585+ session->allow_protected_auth_supported
8586+ )
8587+ ) {
8588+ PKCS11H_DEBUG (
8589+ PKCS11H_LOG_DEBUG1,
8590+ "PKCS#11: Calling pin_prompt hook for '%s'",
8591+ session->token_id->display
8592+ );
8593+
8594+ if (
8595+ !s_pkcs11h_data->hooks.pin_prompt (
8596+ s_pkcs11h_data->hooks.pin_prompt_data,
8597+ user_data,
8598+ session->token_id,
8599+ nRetryCount,
8600+ pin,
8601+ sizeof (pin)
8602+ )
8603+ ) {
8604+ rv = CKR_CANCEL;
8605+ }
8606+ else {
8607+ utfPIN = (CK_UTF8CHAR_PTR)pin;
8608+ lPINLength = strlen (pin);
8609+ }
8610+
8611+ PKCS11H_DEBUG (
8612+ PKCS11H_LOG_DEBUG1,
8613+ "PKCS#11: pin_prompt hook return rv=%ld",
8614+ rv
8615+ );
8616+ }
8617+
8618+ if (rv == CKR_OK) {
8619+ rv = _pkcs11h_session_touch (session);
8620+ }
8621+
8622+ if (
8623+ rv == CKR_OK &&
8624+ (rv = session->provider->f->C_Login (
8625+ session->session_handle,
8626+ CKU_USER,
8627+ utfPIN,
8628+ lPINLength
8629+ )) != CKR_OK
8630+ ) {
8631+ if (rv == CKR_USER_ALREADY_LOGGED_IN) {
8632+ rv = CKR_OK;
8633+ }
8634+ }
8635+
8636+ /*
8637+ * Clean PIN buffer
8638+ */
8639+ memset (pin, 0, sizeof (pin));
8640+
8641+ if (rv == CKR_OK) {
8642+ login_succeeded = TRUE;
8643+ }
8644+ else if (
8645+ rv == CKR_PIN_INCORRECT ||
8646+ rv == CKR_PIN_INVALID
8647+ ) {
8648+ /*
8649+ * Ignore these errors
8650+ * so retry can be performed
8651+ */
8652+ rv = CKR_OK;
8653+ }
8654+
8655+ nRetryCount++;
8656+ }
8657+
8658+ /*
8659+ * Retry limit
8660+ */
8661+ if (!login_succeeded && rv == CKR_OK) {
8662+ rv = CKR_PIN_INCORRECT;
8663+ }
8664+ }
8665+
8666+ PKCS11H_DEBUG (
8667+ PKCS11H_LOG_DEBUG2,
8668+ "PKCS#11: _pkcs11h_session_login return rv=%ld-'%s'",
8669+ rv,
8670+ pkcs11h_getMessage (rv)
8671+ );
8672+
8673+ return rv;
8674+}
8675+
8676+static
8677+CK_RV
8678+_pkcs11h_session_logout (
8679+ IN const pkcs11h_session_t session
8680+) {
8681+ /*
8682+ * THREADING:
8683+ * session->mutex must be locked
8684+ */
8685+ /*PKCS11H_ASSERT (session!=NULL); NOT NEEDED*/
8686+
8687+ PKCS11H_DEBUG (
8688+ PKCS11H_LOG_DEBUG2,
8689+ "PKCS#11: _pkcs11h_session_logout entry session=%p",
8690+ (void *)session
8691+ );
8692+
8693+ if (
8694+ session != NULL &&
8695+ session->session_handle != PKCS11H_INVALID_SESSION_HANDLE
8696+ ) {
8697+ CK_RV rv = CKR_OK;
8698+
8699+ if (rv == CKR_OK) {
8700+ if (session->provider != NULL) {
8701+ session->provider->f->C_Logout (session->session_handle);
8702+ session->provider->f->C_CloseSession (session->session_handle);
8703+ }
8704+ session->session_handle = PKCS11H_INVALID_SESSION_HANDLE;
8705+ }
8706+ }
8707+
8708+ PKCS11H_DEBUG (
8709+ PKCS11H_LOG_DEBUG2,
8710+ "PKCS#11: _pkcs11h_session_logout return"
8711+ );
8712+
8713+ return CKR_OK;
8714+}
8715+
8716+static
8717+void
8718+_pkcs11h_hooks_default_log (
8719+ IN void * const global_data,
8720+ IN const unsigned flags,
8721+ IN const char * const format,
8722+ IN va_list args
8723+) {
8724+ (void)global_data;
8725+ (void)flags;
8726+ (void)format;
8727+ (void)args;
8728+}
8729+
8730+static
8731+PKCS11H_BOOL
8732+_pkcs11h_hooks_default_token_prompt (
8733+ IN void * const global_data,
8734+ IN void * const user_data,
8735+ IN const pkcs11h_token_id_t token,
8736+ IN const unsigned retry
8737+) {
8738+ /*PKCS11H_ASSERT (global_data) NOT NEEDED */
8739+ /*PKCS11H_ASSERT (user_data) NOT NEEDED */
8740+ PKCS11H_ASSERT (token!=NULL);
8741+
8742+ (void)global_data;
8743+ (void)user_data;
8744+ (void)retry;
8745+
8746+ PKCS11H_DEBUG (
8747+ PKCS11H_LOG_DEBUG2,
8748+ "PKCS#11: _pkcs11h_hooks_default_token_prompt global_data=%p, user_data=%p, display='%s'",
8749+ global_data,
8750+ user_data,
8751+ token->display
8752+ );
8753+
8754+ return FALSE;
8755+}
8756+
8757+static
8758+PKCS11H_BOOL
8759+_pkcs11h_hooks_default_pin_prompt (
8760+ IN void * const global_data,
8761+ IN void * const user_data,
8762+ IN const pkcs11h_token_id_t token,
8763+ IN const unsigned retry,
8764+ OUT char * const pin,
8765+ IN const size_t pin_max
8766+) {
8767+ /*PKCS11H_ASSERT (global_data) NOT NEEDED */
8768+ /*PKCS11H_ASSERT (user_data) NOT NEEDED */
8769+ PKCS11H_ASSERT (token!=NULL);
8770+
8771+ (void)global_data;
8772+ (void)user_data;
8773+ (void)retry;
8774+ (void)pin;
8775+ (void)pin_max;
8776+
8777+ PKCS11H_DEBUG (
8778+ PKCS11H_LOG_DEBUG2,
8779+ "PKCS#11: _pkcs11h_hooks_default_pin_prompt global_data=%p, user_data=%p, display='%s'",
8780+ global_data,
8781+ user_data,
8782+ token->display
8783+ );
8784+
8785+ return FALSE;
8786+}
8787+
8788+#if !defined(WIN32)
8789+#if defined(ENABLE_PKCS11H_THREADING)
8790+
8791+static
8792+void
8793+__pkcs11h_threading_atfork_prepare () {
8794+ __pkcs1h_threading_mutexLockAll ();
8795+}
8796+static
8797+void
8798+__pkcs11h_threading_atfork_parent () {
8799+ __pkcs1h_threading_mutexReleaseAll ();
8800+}
8801+static
8802+void
8803+__pkcs11h_threading_atfork_child () {
8804+ __pkcs1h_threading_mutexReleaseAll ();
8805+ _pkcs11h_forkFixup ();
8806+}
8807+
8808+#endif /* ENABLE_PKCS11H_THREADING */
8809+
8810+static
8811+CK_RV
8812+_pkcs11h_forkFixup () {
8813+#if defined(ENABLE_PKCS11H_THREADING)
8814+ PKCS11H_BOOL mutex_locked = FALSE;
8815+#endif
8816+ pid_t mypid = getpid ();
8817+
8818+ PKCS11H_DEBUG (
8819+ PKCS11H_LOG_DEBUG2,
8820+ "PKCS#11: pkcs11h_forkFixup entry pid=%d",
8821+ mypid
8822+ );
8823+
8824+ if (s_pkcs11h_data != NULL && s_pkcs11h_data->initialized) {
8825+ pkcs11h_provider_t current;
8826+
8827+#if defined(ENABLE_PKCS11H_THREADING)
8828+ if (_pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.global) == CKR_OK) {
8829+ mutex_locked = TRUE;
8830+ }
8831+#endif
8832+
8833+ for (
8834+ current = s_pkcs11h_data->providers;
8835+ current != NULL;
8836+ current = current->next
8837+ ) {
8838+ if (current->enabled) {
8839+ current->f->C_Initialize (NULL);
8840+ }
8841+
8842+#if defined(ENABLE_PKCS11H_SLOTEVENT)
8843+ /*
8844+ * After fork we have no threads...
8845+ * So just initialized.
8846+ */
8847+ if (s_pkcs11h_data->slotevent.initialized) {
8848+ s_pkcs11h_data->slotevent.initialized = FALSE;
8849+ _pkcs11h_slotevent_init ();
8850+ }
8851+#endif
8852+ }
8853+ }
8854+
8855+#if defined(ENABLE_PKCS11H_THREADING)
8856+ if (mutex_locked) {
8857+ _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.global);
8858+ mutex_locked = FALSE;
8859+ }
8860+#endif
8861+
8862+ PKCS11H_DEBUG (
8863+ PKCS11H_LOG_DEBUG2,
8864+ "PKCS#11: pkcs11h_forkFixup return"
8865+ );
8866+
8867+ return CKR_OK;
8868+}
8869+
8870+#endif /* !WIN32 */
8871+
8872+#if defined(ENABLE_PKCS11H_TOKEN)
8873+/*======================================================================*
8874+ * TOKEN INTERFACE
8875+ *======================================================================*/
8876+
8877+CK_RV
8878+pkcs11h_token_ensureAccess (
8879+ IN const pkcs11h_token_id_t token_id,
8880+ IN void * const user_data,
8881+ IN const unsigned mask_prompt
8882+) {
8883+#if defined(ENABLE_PKCS11H_THREADING)
8884+ PKCS11H_BOOL mutex_locked = FALSE;
8885+#endif
8886+ pkcs11h_session_t session = NULL;
8887+ CK_RV rv = CKR_OK;
8888+
8889+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
8890+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
8891+ PKCS11H_ASSERT (token_id!=NULL);
8892+ /*PKCS11H_ASSERT (user_data) NOT NEEDED */
8893+
8894+ PKCS11H_DEBUG (
8895+ PKCS11H_LOG_DEBUG2,
8896+ "PKCS#11: pkcs11h_token_ensureAccess entry token_id=%p, user_data=%p, mask_prompt=%08x",
8897+ (void *)token_id,
8898+ user_data,
8899+ mask_prompt
8900+ );
8901+
8902+ if (rv == CKR_OK) {
8903+ rv = _pkcs11h_session_getSessionByTokenId (
8904+ token_id,
8905+ &session
8906+ );
8907+ }
8908+
8909+#if defined(ENABLE_PKCS11H_THREADING)
8910+ if (
8911+ rv == CKR_OK &&
8912+ (rv = _pkcs11h_threading_mutexLock (&session->mutex)) == CKR_OK
8913+ ) {
8914+ mutex_locked = TRUE;
8915+ }
8916+#endif
8917+
8918+ if (rv == CKR_OK) {
8919+ CK_SLOT_ID slot;
8920+
8921+ rv = _pkcs11h_session_reset (
8922+ session,
8923+ user_data,
8924+ mask_prompt,
8925+ &slot
8926+ );
8927+ }
8928+
8929+#if defined(ENABLE_PKCS11H_THREADING)
8930+ if (mutex_locked) {
8931+ _pkcs11h_threading_mutexRelease (&session->mutex);
8932+ mutex_locked = FALSE;
8933+ }
8934+#endif
8935+
8936+ if (session != NULL) {
8937+ _pkcs11h_session_release (session);
8938+ session = NULL;
8939+ }
8940+
8941+ PKCS11H_DEBUG (
8942+ PKCS11H_LOG_DEBUG2,
8943+ "PKCS#11: pkcs11h_token_ensureAccess return rv=%ld-'%s'",
8944+ rv,
8945+ pkcs11h_getMessage (rv)
8946+ );
8947+
8948+ return rv;
8949+}
8950+
8951+#endif /* ENABLE_PKCS11H_TOKEN */
8952+
8953+#if defined(ENABLE_PKCS11H_DATA)
8954+/*======================================================================*
8955+ * DATA INTERFACE
8956+ *======================================================================*/
8957+
8958+static
8959+CK_RV
8960+_pkcs11h_data_getObject (
8961+ IN const pkcs11h_session_t session,
8962+ IN const char * const application,
8963+ IN const char * const label,
8964+ OUT CK_OBJECT_HANDLE * const p_handle
8965+) {
8966+ CK_OBJECT_CLASS class = CKO_DATA;
8967+ CK_ATTRIBUTE filter[] = {
8968+ {CKA_CLASS, (void *)&class, sizeof (class)},
8969+ {CKA_APPLICATION, (void *)application, application == NULL ? 0 : strlen (application)},
8970+ {CKA_LABEL, (void *)label, label == NULL ? 0 : strlen (label)}
8971+ };
8972+ CK_OBJECT_HANDLE *objects = NULL;
8973+ CK_ULONG objects_found = 0;
8974+ CK_RV rv = CKR_OK;
8975+
8976+ PKCS11H_ASSERT (session!=NULL);
8977+ PKCS11H_ASSERT (application!=NULL);
8978+ PKCS11H_ASSERT (label!=NULL);
8979+
8980+ PKCS11H_DEBUG (
8981+ PKCS11H_LOG_DEBUG2,
8982+ "PKCS#11: _pkcs11h_data_getObject entry session=%p, application='%s', label='%s', p_handle=%p",
8983+ (void *)session,
8984+ application,
8985+ label,
8986+ (void *)p_handle
8987+ );
8988+
8989+ *p_handle = PKCS11H_INVALID_OBJECT_HANDLE;
8990+
8991+ if (rv == CKR_OK) {
8992+ rv = _pkcs11h_session_validate (session);
8993+ }
8994+
8995+ if (rv == CKR_OK) {
8996+ rv = _pkcs11h_session_findObjects (
8997+ session,
8998+ filter,
8999+ sizeof (filter) / sizeof (CK_ATTRIBUTE),
9000+ &objects,
9001+ &objects_found
9002+ );
9003+ }
9004+
9005+ if (
9006+ rv == CKR_OK &&
9007+ objects_found == 0
9008+ ) {
9009+ rv = CKR_FUNCTION_REJECTED;
9010+ }
9011+
9012+ if (rv == CKR_OK) {
9013+ *p_handle = objects[0];
9014+ }
9015+
9016+ if (objects != NULL) {
9017+ _pkcs11h_mem_free ((void *)&objects);
9018+ }
9019+
9020+ PKCS11H_DEBUG (
9021+ PKCS11H_LOG_DEBUG2,
9022+ "PKCS#11: _pkcs11h_data_getObject return rv=%ld-'%s', *p_handle=%p",
9023+ rv,
9024+ pkcs11h_getMessage (rv),
9025+ (void *)*p_handle
9026+ );
9027+
9028+ return rv;
9029+}
9030+
9031+CK_RV
9032+pkcs11h_data_get (
9033+ IN const pkcs11h_token_id_t token_id,
9034+ IN const PKCS11H_BOOL is_public,
9035+ IN const char * const application,
9036+ IN const char * const label,
9037+ IN void * const user_data,
9038+ IN const unsigned mask_prompt,
9039+ OUT unsigned char * const blob,
9040+ IN OUT size_t * const p_blob_size
9041+) {
9042+ CK_ATTRIBUTE attrs[] = {
9043+ {CKA_VALUE, NULL, 0}
9044+ };
9045+ CK_OBJECT_HANDLE handle = PKCS11H_INVALID_OBJECT_HANDLE;
9046+ CK_RV rv = CKR_OK;
9047+
9048+#if defined(ENABLE_PKCS11H_THREADING)
9049+ PKCS11H_BOOL mutex_locked = FALSE;
9050+#endif
9051+ pkcs11h_session_t session = NULL;
9052+ PKCS11H_BOOL op_succeed = FALSE;
9053+ PKCS11H_BOOL login_retry = FALSE;
9054+ size_t blob_size_max = 0;
9055+
9056+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
9057+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
9058+ PKCS11H_ASSERT (token_id!=NULL);
9059+ PKCS11H_ASSERT (application!=NULL);
9060+ PKCS11H_ASSERT (label!=NULL);
9061+ /*PKCS11H_ASSERT (user_data) NOT NEEDED */
9062+ /*PKCS11H_ASSERT (blob!=NULL); NOT NEEDED*/
9063+ PKCS11H_ASSERT (p_blob_size!=NULL);
9064+
9065+ PKCS11H_DEBUG (
9066+ PKCS11H_LOG_DEBUG2,
9067+ "PKCS#11: pkcs11h_data_get entry token_id=%p, application='%s', label='%s', user_data=%p, mask_prompt=%08x, blob=%p, *p_blob_size=%u",
9068+ (void *)token_id,
9069+ application,
9070+ label,
9071+ user_data,
9072+ mask_prompt,
9073+ blob,
9074+ blob != NULL ? *p_blob_size : 0
9075+ );
9076+
9077+ if (blob != NULL) {
9078+ blob_size_max = *p_blob_size;
9079+ }
9080+ *p_blob_size = 0;
9081+
9082+ if (rv == CKR_OK) {
9083+ rv = _pkcs11h_session_getSessionByTokenId (
9084+ token_id,
9085+ &session
9086+ );
9087+ }
9088+
9089+#if defined(ENABLE_PKCS11H_THREADING)
9090+ if (
9091+ rv == CKR_OK &&
9092+ (rv = _pkcs11h_threading_mutexLock (&session->mutex)) == CKR_OK
9093+ ) {
9094+ mutex_locked = TRUE;
9095+ }
9096+#endif
9097+
9098+ while (rv == CKR_OK && !op_succeed) {
9099+
9100+ if (rv == CKR_OK) {
9101+ rv = _pkcs11h_session_validate (session);
9102+ }
9103+
9104+ if (rv == CKR_OK) {
9105+ rv = _pkcs11h_data_getObject (
9106+ session,
9107+ application,
9108+ label,
9109+ &handle
9110+ );
9111+ }
9112+
9113+ if (rv == CKR_OK) {
9114+ rv = _pkcs11h_session_getObjectAttributes (
9115+ session,
9116+ handle,
9117+ attrs,
9118+ sizeof (attrs)/sizeof (CK_ATTRIBUTE)
9119+ );
9120+ }
9121+
9122+ if (rv == CKR_OK) {
9123+ op_succeed = TRUE;
9124+ }
9125+ else {
9126+ if (!login_retry) {
9127+ PKCS11H_DEBUG (
9128+ PKCS11H_LOG_DEBUG1,
9129+ "PKCS#11: Read data object failed rv=%ld-'%s'",
9130+ rv,
9131+ pkcs11h_getMessage (rv)
9132+ );
9133+ login_retry = TRUE;
9134+ rv = _pkcs11h_session_login (
9135+ session,
9136+ is_public,
9137+ TRUE,
9138+ user_data,
9139+ mask_prompt
9140+ );
9141+ }
9142+ }
9143+ }
9144+
9145+#if defined(ENABLE_PKCS11H_THREADING)
9146+ if (mutex_locked) {
9147+ _pkcs11h_threading_mutexRelease (&session->mutex);
9148+ mutex_locked = FALSE;
9149+ }
9150+#endif
9151+
9152+ if (rv == CKR_OK) {
9153+ *p_blob_size = attrs[0].ulValueLen;
9154+ }
9155+
9156+ if (rv == CKR_OK) {
9157+ if (blob != NULL) {
9158+ if (*p_blob_size > blob_size_max) {
9159+ rv = CKR_BUFFER_TOO_SMALL;
9160+ }
9161+ else {
9162+ memmove (blob, attrs[0].pValue, *p_blob_size);
9163+ }
9164+ }
9165+ }
9166+
9167+ _pkcs11h_session_freeObjectAttributes (
9168+ attrs,
9169+ sizeof (attrs)/sizeof (CK_ATTRIBUTE)
9170+ );
9171+
9172+ if (session != NULL) {
9173+ _pkcs11h_session_release (session);
9174+ session = NULL;
9175+ }
9176+
9177+ PKCS11H_DEBUG (
9178+ PKCS11H_LOG_DEBUG2,
9179+ "PKCS#11: pkcs11h_data_get return rv=%ld-'%s', *p_blob_size=%u",
9180+ rv,
9181+ pkcs11h_getMessage (rv),
9182+ *p_blob_size
9183+ );
9184+
9185+ return rv;
9186+}
9187+
9188+CK_RV
9189+pkcs11h_data_put (
9190+ IN const pkcs11h_token_id_t token_id,
9191+ IN const PKCS11H_BOOL is_public,
9192+ IN const char * const application,
9193+ IN const char * const label,
9194+ IN void * const user_data,
9195+ IN const unsigned mask_prompt,
9196+ OUT unsigned char * const blob,
9197+ IN const size_t blob_size
9198+) {
9199+ CK_OBJECT_CLASS class = CKO_DATA;
9200+ CK_BBOOL ck_true = CK_TRUE;
9201+ CK_BBOOL ck_false = CK_FALSE;
9202+
9203+ CK_ATTRIBUTE attrs[] = {
9204+ {CKA_CLASS, &class, sizeof (class)},
9205+ {CKA_TOKEN, &ck_true, sizeof (ck_true)},
9206+ {CKA_PRIVATE, is_public ? &ck_false : &ck_true, sizeof (CK_BBOOL)},
9207+ {CKA_APPLICATION, (void *)application, strlen (application)},
9208+ {CKA_LABEL, (void *)label, strlen (label)},
9209+ {CKA_VALUE, blob, blob_size}
9210+ };
9211+
9212+ CK_OBJECT_HANDLE handle = PKCS11H_INVALID_OBJECT_HANDLE;
9213+ CK_RV rv = CKR_OK;
9214+
9215+#if defined(ENABLE_PKCS11H_THREADING)
9216+ PKCS11H_BOOL mutex_locked = FALSE;
9217+#endif
9218+ pkcs11h_session_t session = NULL;
9219+ PKCS11H_BOOL op_succeed = FALSE;
9220+ PKCS11H_BOOL login_retry = FALSE;
9221+
9222+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
9223+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
9224+ PKCS11H_ASSERT (token_id!=NULL);
9225+ PKCS11H_ASSERT (application!=NULL);
9226+ PKCS11H_ASSERT (label!=NULL);
9227+ /*PKCS11H_ASSERT (user_data) NOT NEEDED */
9228+ PKCS11H_ASSERT (blob!=NULL);
9229+
9230+ PKCS11H_DEBUG (
9231+ PKCS11H_LOG_DEBUG2,
9232+ "PKCS#11: pkcs11h_data_put entry token_id=%p, application='%s', label='%s', user_data=%p, mask_prompt=%08x, blob=%p, blob_size=%u",
9233+ (void *)token_id,
9234+ application,
9235+ label,
9236+ user_data,
9237+ mask_prompt,
9238+ blob,
9239+ blob != NULL ? blob_size : 0
9240+ );
9241+
9242+ if (rv == CKR_OK) {
9243+ rv = _pkcs11h_session_getSessionByTokenId (
9244+ token_id,
9245+ &session
9246+ );
9247+ }
9248+
9249+#if defined(ENABLE_PKCS11H_THREADING)
9250+ if (
9251+ rv == CKR_OK &&
9252+ (rv = _pkcs11h_threading_mutexLock (&session->mutex)) == CKR_OK
9253+ ) {
9254+ mutex_locked = TRUE;
9255+ }
9256+#endif
9257+
9258+ while (rv == CKR_OK && !op_succeed) {
9259+
9260+ if (rv == CKR_OK) {
9261+ rv = _pkcs11h_session_validate (session);
9262+ }
9263+
9264+ if (rv == CKR_OK) {
9265+ rv = session->provider->f->C_CreateObject (
9266+ session->session_handle,
9267+ attrs,
9268+ sizeof (attrs)/sizeof (CK_ATTRIBUTE),
9269+ &handle
9270+ );
9271+ }
9272+
9273+ if (rv == CKR_OK) {
9274+ op_succeed = TRUE;
9275+ }
9276+ else {
9277+ if (!login_retry) {
9278+ PKCS11H_DEBUG (
9279+ PKCS11H_LOG_DEBUG1,
9280+ "PKCS#11: Write data object failed rv=%ld-'%s'",
9281+ rv,
9282+ pkcs11h_getMessage (rv)
9283+ );
9284+ login_retry = TRUE;
9285+ rv = _pkcs11h_session_login (
9286+ session,
9287+ is_public,
9288+ FALSE,
9289+ user_data,
9290+ mask_prompt
9291+ );
9292+ }
9293+ }
9294+ }
9295+
9296+#if defined(ENABLE_PKCS11H_THREADING)
9297+ if (mutex_locked) {
9298+ _pkcs11h_threading_mutexRelease (&session->mutex);
9299+ mutex_locked = FALSE;
9300+ }
9301+#endif
9302+
9303+ if (session != NULL) {
9304+ _pkcs11h_session_release (session);
9305+ session = NULL;
9306+ }
9307+
9308+ PKCS11H_DEBUG (
9309+ PKCS11H_LOG_DEBUG2,
9310+ "PKCS#11: pkcs11h_data_put return rv=%ld-'%s'",
9311+ rv,
9312+ pkcs11h_getMessage (rv)
9313+ );
9314+
9315+ return rv;
9316+}
9317+
9318+CK_RV
9319+pkcs11h_data_del (
9320+ IN const pkcs11h_token_id_t token_id,
9321+ IN const PKCS11H_BOOL is_public,
9322+ IN const char * const application,
9323+ IN const char * const label,
9324+ IN void * const user_data,
9325+ IN const unsigned mask_prompt
9326+) {
9327+#if defined(ENABLE_PKCS11H_THREADING)
9328+ PKCS11H_BOOL mutex_locked = FALSE;
9329+#endif
9330+ pkcs11h_session_t session = NULL;
9331+ PKCS11H_BOOL op_succeed = FALSE;
9332+ PKCS11H_BOOL login_retry = FALSE;
9333+ CK_OBJECT_HANDLE handle = PKCS11H_INVALID_OBJECT_HANDLE;
9334+ CK_RV rv = CKR_OK;
9335+
9336+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
9337+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
9338+ PKCS11H_ASSERT (token_id!=NULL);
9339+ PKCS11H_ASSERT (application!=NULL);
9340+ PKCS11H_ASSERT (label!=NULL);
9341+ /*PKCS11H_ASSERT (user_data) NOT NEEDED */
9342+
9343+ PKCS11H_DEBUG (
9344+ PKCS11H_LOG_DEBUG2,
9345+ "PKCS#11: pkcs11h_data_del entry token_id=%p, application='%s', label='%s', user_data=%p, mask_prompt=%08x",
9346+ (void *)token_id,
9347+ application,
9348+ label,
9349+ user_data,
9350+ mask_prompt
9351+ );
9352+
9353+ if (rv == CKR_OK) {
9354+ rv = _pkcs11h_session_getSessionByTokenId (
9355+ token_id,
9356+ &session
9357+ );
9358+ }
9359+
9360+#if defined(ENABLE_PKCS11H_THREADING)
9361+ if (
9362+ rv == CKR_OK &&
9363+ (rv = _pkcs11h_threading_mutexLock (&session->mutex)) == CKR_OK
9364+ ) {
9365+ mutex_locked = TRUE;
9366+ }
9367+#endif
9368+
9369+ while (rv == CKR_OK && !op_succeed) {
9370+
9371+ if (rv == CKR_OK) {
9372+ rv = _pkcs11h_session_validate (session);
9373+ }
9374+
9375+ if (rv == CKR_OK) {
9376+ rv = _pkcs11h_data_getObject (
9377+ session,
9378+ application,
9379+ label,
9380+ &handle
9381+ );
9382+ }
9383+
9384+ if (rv == CKR_OK) {
9385+ rv = session->provider->f->C_DestroyObject (
9386+ session->session_handle,
9387+ handle
9388+ );
9389+ }
9390+
9391+ if (rv == CKR_OK) {
9392+ op_succeed = TRUE;
9393+ }
9394+ else {
9395+ if (!login_retry) {
9396+ PKCS11H_DEBUG (
9397+ PKCS11H_LOG_DEBUG1,
9398+ "PKCS#11: Remove data object failed rv=%ld-'%s'",
9399+ rv,
9400+ pkcs11h_getMessage (rv)
9401+ );
9402+ login_retry = TRUE;
9403+ rv = _pkcs11h_session_login (
9404+ session,
9405+ is_public,
9406+ FALSE,
9407+ user_data,
9408+ mask_prompt
9409+ );
9410+ }
9411+ }
9412+ }
9413+
9414+#if defined(ENABLE_PKCS11H_THREADING)
9415+ if (mutex_locked) {
9416+ _pkcs11h_threading_mutexRelease (&session->mutex);
9417+ mutex_locked = FALSE;
9418+ }
9419+#endif
9420+
9421+ if (session != NULL) {
9422+ _pkcs11h_session_release (session);
9423+ session = NULL;
9424+ }
9425+
9426+ PKCS11H_DEBUG (
9427+ PKCS11H_LOG_DEBUG2,
9428+ "PKCS#11: pkcs11h_data_del return rv=%ld-'%s'",
9429+ rv,
9430+ pkcs11h_getMessage (rv)
9431+ );
9432+
9433+ return rv;
9434+}
9435+
9436+#endif /* ENABLE_PKCS11H_DATA */
9437+
9438+#if defined(ENABLE_PKCS11H_CERTIFICATE)
9439+/*======================================================================*
9440+ * CERTIFICATE INTERFACE
9441+ *======================================================================*/
9442+
9443+static
9444+time_t
9445+_pkcs11h_certificate_getExpiration (
9446+ IN const unsigned char * const certificate,
9447+ IN const size_t certificate_size
9448+) {
9449+ /*
9450+ * This function compare the notAfter
9451+ * and select the most recent certificate
9452+ */
9453+
9454+#if defined(USE_PKCS11H_OPENSSL)
9455+ X509 *x509 = NULL;
9456+#elif defined(USE_PKCS11H_GNUTLS)
9457+ gnutls_x509_crt_t cert = NULL;
9458+#endif
9459+ time_t expire = (time_t)0;
9460+
9461+ PKCS11H_ASSERT (certificate!=NULL);
9462+
9463+#if defined(USE_PKCS11H_OPENSSL)
9464+ x509 = X509_new ();
9465+
9466+ if (x509 != NULL) {
9467+ pkcs11_openssl_d2i_t d2i = (pkcs11_openssl_d2i_t)certificate;
9468+
9469+ if (
9470+ d2i_X509 (&x509, &d2i, certificate_size)
9471+ ) {
9472+ ASN1_TIME *notBefore = X509_get_notBefore (x509);
9473+ ASN1_TIME *notAfter = X509_get_notAfter (x509);
9474+
9475+ if (
9476+ notBefore != NULL &&
9477+ notAfter != NULL &&
9478+ X509_cmp_current_time (notBefore) <= 0 &&
9479+ X509_cmp_current_time (notAfter) >= 0 &&
9480+ notAfter->length >= 12
9481+ ) {
9482+ struct tm tm1;
9483+ time_t now = time (NULL);
9484+
9485+ memset (&tm1, 0, sizeof (tm1));
9486+ tm1.tm_year = (notAfter->data[ 0] - '0') * 10 + (notAfter->data[ 1] - '0') + 100;
9487+ tm1.tm_mon = (notAfter->data[ 2] - '0') * 10 + (notAfter->data[ 3] - '0') - 1;
9488+ tm1.tm_mday = (notAfter->data[ 4] - '0') * 10 + (notAfter->data[ 5] - '0');
9489+ tm1.tm_hour = (notAfter->data[ 6] - '0') * 10 + (notAfter->data[ 7] - '0');
9490+ tm1.tm_min = (notAfter->data[ 8] - '0') * 10 + (notAfter->data[ 9] - '0');
9491+ tm1.tm_sec = (notAfter->data[10] - '0') * 10 + (notAfter->data[11] - '0');
9492+
9493+ tm1.tm_sec += (int)(mktime (localtime (&now)) - mktime (gmtime (&now)));
9494+
9495+ expire = mktime (&tm1);
9496+ }
9497+ }
9498+ }
9499+
9500+ if (x509 != NULL) {
9501+ X509_free (x509);
9502+ x509 = NULL;
9503+ }
9504+#elif defined(USE_PKCS11H_GNUTLS)
9505+ if (gnutls_x509_crt_init (&cert) == GNUTLS_E_SUCCESS) {
9506+ gnutls_datum_t datum = {(unsigned char *)certificate, certificate_size};
9507+
9508+ if (gnutls_x509_crt_import (cert, &datum, GNUTLS_X509_FMT_DER) == GNUTLS_E_SUCCESS) {
9509+
9510+ time_t activation_time = gnutls_x509_crt_get_activation_time (cert);
9511+ time_t expiration_time = gnutls_x509_crt_get_expiration_time (cert);
9512+ time_t now = time (NULL);
9513+
9514+ if (
9515+ now >= activation_time &&
9516+ now <= expiration_time
9517+ ) {
9518+ expire = expiration_time;
9519+ }
9520+ }
9521+ gnutls_x509_crt_deinit (cert);
9522+ }
9523+#else
9524+#error Invalid configuration
9525+#endif
9526+
9527+ return expire;
9528+}
9529+
9530+static
9531+PKCS11H_BOOL
9532+_pkcs11h_certificate_isBetterCertificate (
9533+ IN const unsigned char * const current,
9534+ IN const size_t current_size,
9535+ IN const unsigned char * const newone,
9536+ IN const size_t newone_size
9537+) {
9538+ PKCS11H_BOOL is_better = FALSE;
9539+
9540+ /*PKCS11H_ASSERT (current!=NULL); NOT NEEDED */
9541+ PKCS11H_ASSERT (newone!=NULL);
9542+
9543+ PKCS11H_DEBUG (
9544+ PKCS11H_LOG_DEBUG2,
9545+ "PKCS#11: _pkcs11h_certificate_isBetterCertificate entry current=%p, current_size=%u, newone=%p, newone_size=%u",
9546+ current,
9547+ current_size,
9548+ newone,
9549+ newone_size
9550+ );
9551+
9552+ /*
9553+ * First certificae
9554+ * always select
9555+ */
9556+ if (current_size == 0 || current == NULL) {
9557+ is_better = TRUE;
9558+ }
9559+ else {
9560+ time_t notAfterCurrent, notAfterNew;
9561+
9562+ notAfterCurrent = _pkcs11h_certificate_getExpiration (
9563+ current,
9564+ current_size
9565+ );
9566+ notAfterNew = _pkcs11h_certificate_getExpiration (
9567+ newone,
9568+ newone_size
9569+ );
9570+
9571+ PKCS11H_DEBUG (
9572+ PKCS11H_LOG_DEBUG2,
9573+ "PKCS#11: _pkcs11h_certificate_isBetterCertificate notAfterCurrent='%s', notAfterNew='%s'",
9574+ asctime (localtime (&notAfterCurrent)),
9575+ asctime (localtime (&notAfterNew))
9576+ );
9577+
9578+ is_better = notAfterNew > notAfterCurrent;
9579+ }
9580+
9581+ PKCS11H_DEBUG (
9582+ PKCS11H_LOG_DEBUG2,
9583+ "PKCS#11: _pkcs11h_certificate_isBetterCertificate return is_better=%d",
9584+ is_better ? 1 : 0
9585+ );
9586+
9587+ return is_better;
9588+}
9589+
9590+static
9591+CK_RV
9592+_pkcs11h_certificate_newCertificateId (
9593+ OUT pkcs11h_certificate_id_t * const p_certificate_id
9594+) {
9595+ CK_RV rv = CKR_OK;
9596+
9597+ PKCS11H_ASSERT (p_certificate_id!=NULL);
9598+
9599+ PKCS11H_DEBUG (
9600+ PKCS11H_LOG_DEBUG2,
9601+ "PKCS#11: _pkcs11h_certificate_newCertificateId entry p_certificate_id=%p",
9602+ (void *)p_certificate_id
9603+ );
9604+
9605+ *p_certificate_id = NULL;
9606+
9607+ if (rv == CKR_OK) {
9608+ rv = _pkcs11h_mem_malloc ((void *)p_certificate_id, sizeof (struct pkcs11h_certificate_id_s));
9609+ }
9610+
9611+ PKCS11H_DEBUG (
9612+ PKCS11H_LOG_DEBUG2,
9613+ "PKCS#11: _pkcs11h_certificate_newCertificateId return rv=%ld-'%s', *p_certificate_id=%p",
9614+ rv,
9615+ pkcs11h_getMessage (rv),
9616+ (void *)*p_certificate_id
9617+ );
9618+
9619+ return rv;
9620+}
9621+
9622+static
9623+CK_RV
9624+_pkcs11h_certificate_getDN (
9625+ IN const unsigned char * const blob,
9626+ IN const size_t blob_size,
9627+ OUT char * const dn,
9628+ IN const size_t dn_size
9629+) {
9630+#if defined(USE_PKCS11H_OPENSSL)
9631+ X509 *x509 = NULL;
9632+ pkcs11_openssl_d2i_t d2i1;
9633+#elif defined(USE_PKCS11H_GNUTLS)
9634+ gnutls_x509_crt_t cert = NULL;
9635+#endif
9636+
9637+ PKCS11H_ASSERT (blob_size==0||blob!=NULL);
9638+ PKCS11H_ASSERT (dn!=NULL);
9639+
9640+ dn[0] = '\x0';
9641+
9642+#if defined(USE_PKCS11H_OPENSSL)
9643+
9644+ if (blob_size > 0) {
9645+ x509 = X509_new ();
9646+
9647+ d2i1 = (pkcs11_openssl_d2i_t)blob;
9648+ if (d2i_X509 (&x509, &d2i1, blob_size)) {
9649+ X509_NAME_oneline (
9650+ X509_get_subject_name (x509),
9651+ dn,
9652+ dn_size
9653+ );
9654+ }
9655+
9656+ if (x509 != NULL) {
9657+ X509_free (x509);
9658+ x509 = NULL;
9659+ }
9660+ }
9661+
9662+#elif defined(USE_PKCS11H_GNUTLS)
9663+
9664+ if (blob_size > 0) {
9665+ if (gnutls_x509_crt_init (&cert) == GNUTLS_E_SUCCESS) {
9666+ gnutls_datum_t datum = {(unsigned char *)blob, blob_size};
9667+
9668+ if (gnutls_x509_crt_import (cert, &datum, GNUTLS_X509_FMT_DER) == GNUTLS_E_SUCCESS) {
9669+ size_t s = dn_size;
9670+ if (
9671+ gnutls_x509_crt_get_dn (
9672+ cert,
9673+ dn,
9674+ &s
9675+ ) != GNUTLS_E_SUCCESS
9676+ ) {
9677+ /* gnutls sets output parameters */
9678+ dn[0] = '\x0';
9679+ }
9680+ }
9681+ gnutls_x509_crt_deinit (cert);
9682+ }
9683+ }
9684+
9685+#else
9686+#error Invalid configuration
9687+#endif
9688+
9689+ return CKR_OK;
9690+}
9691+
9692+static
9693+CK_RV
9694+_pkcs11h_certificate_loadCertificate (
9695+ IN const pkcs11h_certificate_t certificate
9696+) {
9697+ /*
9698+ * THREADING:
9699+ * certificate->mutex must be locked
9700+ */
9701+#if defined(ENABLE_PKCS11H_THREADING)
9702+ PKCS11H_BOOL mutex_locked = FALSE;
9703+#endif
9704+ CK_OBJECT_CLASS cert_filter_class = CKO_CERTIFICATE;
9705+ CK_ATTRIBUTE cert_filter[] = {
9706+ {CKA_CLASS, &cert_filter_class, sizeof (cert_filter_class)},
9707+ {CKA_ID, NULL, 0}
9708+ };
9709+
9710+ CK_OBJECT_HANDLE *objects = NULL;
9711+ CK_ULONG objects_found = 0;
9712+ CK_RV rv = CKR_OK;
9713+
9714+ CK_ULONG i;
9715+
9716+ PKCS11H_ASSERT (certificate!=NULL);
9717+ PKCS11H_ASSERT (certificate->id!=NULL);
9718+
9719+ /* Must be after assert */
9720+ cert_filter[1].pValue = certificate->id->attrCKA_ID;
9721+ cert_filter[1].ulValueLen = certificate->id->attrCKA_ID_size;
9722+
9723+ PKCS11H_DEBUG (
9724+ PKCS11H_LOG_DEBUG2,
9725+ "PKCS#11: _pkcs11h_certificate_loadCertificate entry certificate=%p",
9726+ (void *)certificate
9727+ );
9728+
9729+#if defined(ENABLE_PKCS11H_THREADING)
9730+ if (
9731+ rv == CKR_OK &&
9732+ (rv = _pkcs11h_threading_mutexLock (&certificate->session->mutex)) == CKR_OK
9733+ ) {
9734+ mutex_locked = TRUE;
9735+ }
9736+#endif
9737+
9738+ if (rv == CKR_OK) {
9739+ rv = _pkcs11h_session_validate (certificate->session);
9740+ }
9741+
9742+ if (rv == CKR_OK) {
9743+ rv = _pkcs11h_session_findObjects (
9744+ certificate->session,
9745+ cert_filter,
9746+ sizeof (cert_filter) / sizeof (CK_ATTRIBUTE),
9747+ &objects,
9748+ &objects_found
9749+ );
9750+ }
9751+
9752+ for (i=0;rv == CKR_OK && i < objects_found;i++) {
9753+ CK_ATTRIBUTE attrs[] = {
9754+ {CKA_VALUE, NULL, 0}
9755+ };
9756+
9757+ if (
9758+ rv == CKR_OK &&
9759+ (rv = _pkcs11h_session_getObjectAttributes (
9760+ certificate->session,
9761+ objects[i],
9762+ attrs,
9763+ sizeof (attrs) / sizeof (CK_ATTRIBUTE)
9764+ )) == CKR_OK
9765+ ) {
9766+ if (
9767+ _pkcs11h_certificate_isBetterCertificate (
9768+ certificate->id->certificate_blob,
9769+ certificate->id->certificate_blob_size,
9770+ attrs[0].pValue,
9771+ attrs[0].ulValueLen
9772+ )
9773+ ) {
9774+ if (certificate->id->certificate_blob != NULL) {
9775+ _pkcs11h_mem_free ((void *)&certificate->id->certificate_blob);
9776+ }
9777+
9778+ rv = _pkcs11h_mem_duplicate (
9779+ (void*)&certificate->id->certificate_blob,
9780+ &certificate->id->certificate_blob_size,
9781+ attrs[0].pValue,
9782+ attrs[0].ulValueLen
9783+ );
9784+ }
9785+ }
9786+
9787+ if (rv != CKR_OK) {
9788+ PKCS11H_DEBUG (
9789+ PKCS11H_LOG_DEBUG1,
9790+ "PKCS#11: Cannot get object attribute for provider '%s' object %ld rv=%ld-'%s'",
9791+ certificate->session->provider->manufacturerID,
9792+ objects[i],
9793+ rv,
9794+ pkcs11h_getMessage (rv)
9795+ );
9796+
9797+ /*
9798+ * Ignore error
9799+ */
9800+ rv = CKR_OK;
9801+ }
9802+
9803+ _pkcs11h_session_freeObjectAttributes (
9804+ attrs,
9805+ sizeof (attrs) / sizeof (CK_ATTRIBUTE)
9806+ );
9807+ }
9808+
9809+#if defined(ENABLE_PKCS11H_THREADING)
9810+ if (mutex_locked) {
9811+ _pkcs11h_threading_mutexRelease (&certificate->session->mutex);
9812+ mutex_locked = FALSE;
9813+ }
9814+#endif
9815+
9816+ if (
9817+ rv == CKR_OK &&
9818+ certificate->id->certificate_blob == NULL
9819+ ) {
9820+ rv = CKR_ATTRIBUTE_VALUE_INVALID;
9821+ }
9822+
9823+ if (objects != NULL) {
9824+ _pkcs11h_mem_free ((void *)&objects);
9825+ }
9826+
9827+ /*
9828+ * No need to free allocated objects
9829+ * on error, since the certificate_id
9830+ * should be free by caller.
9831+ */
9832+
9833+ PKCS11H_DEBUG (
9834+ PKCS11H_LOG_DEBUG2,
9835+ "PKCS#11: _pkcs11h_certificate_loadCertificate return rv=%ld-'%s'",
9836+ rv,
9837+ pkcs11h_getMessage (rv)
9838+ );
9839+
9840+ return rv;
9841+}
9842+
9843+static
9844+CK_RV
9845+_pkcs11h_certificate_updateCertificateIdDescription (
9846+ IN OUT pkcs11h_certificate_id_t certificate_id
9847+) {
9848+ static const char * separator = " on ";
9849+ static const char * unknown = "UNKNOWN";
9850+
9851+ PKCS11H_ASSERT (certificate_id!=NULL);
9852+
9853+ PKCS11H_DEBUG (
9854+ PKCS11H_LOG_DEBUG2,
9855+ "PKCS#11: _pkcs11h_certificate_updateCertificateIdDescription entry certificate_id=%p",
9856+ (void *)certificate_id
9857+ );
9858+
9859+ certificate_id->displayName[0] = '\x0';
9860+
9861+ _pkcs11h_certificate_getDN (
9862+ certificate_id->certificate_blob,
9863+ certificate_id->certificate_blob_size,
9864+ certificate_id->displayName,
9865+ sizeof (certificate_id->displayName)
9866+ );
9867+
9868+ if (strlen (certificate_id->displayName) == 0) {
9869+ strncpy (
9870+ certificate_id->displayName,
9871+ unknown,
9872+ sizeof (certificate_id->displayName)-1
9873+ );
9874+ }
9875+
9876+ /*
9877+ * Try to avoid using snprintf,
9878+ * may be unavailable
9879+ */
9880+ strncat (
9881+ certificate_id->displayName,
9882+ separator,
9883+ sizeof (certificate_id->displayName)-1-strlen (certificate_id->displayName)
9884+ );
9885+ strncat (
9886+ certificate_id->displayName,
9887+ certificate_id->token_id->display,
9888+ sizeof (certificate_id->displayName)-1-strlen (certificate_id->displayName)
9889+ );
9890+ certificate_id->displayName[sizeof (certificate_id->displayName) - 1] = '\0';
9891+
9892+ PKCS11H_DEBUG (
9893+ PKCS11H_LOG_DEBUG2,
9894+ "PKCS#11: _pkcs11h_certificate_updateCertificateIdDescription return displayName='%s'",
9895+ certificate_id->displayName
9896+ );
9897+
9898+ return CKR_OK;
9899+}
9900+
9901+static
9902+CK_RV
9903+_pkcs11h_certificate_getKeyAttributes (
9904+ IN const pkcs11h_certificate_t certificate
9905+) {
9906+#if defined(ENABLE_PKCS11H_THREADING)
9907+ PKCS11H_BOOL mutex_locked = FALSE;
9908+#endif
9909+ CK_RV rv = CKR_OK;
9910+
9911+ PKCS11H_BOOL op_succeed = FALSE;
9912+ PKCS11H_BOOL login_retry = FALSE;
9913+
9914+ PKCS11H_ASSERT (certificate!=NULL);
9915+
9916+ PKCS11H_DEBUG (
9917+ PKCS11H_LOG_DEBUG2,
9918+ "PKCS#11: _pkcs11h_certificate_getKeyAttributes entry certificate=%p",
9919+ (void *)certificate
9920+ );
9921+
9922+#if defined(ENABLE_PKCS11H_THREADING)
9923+ if (
9924+ rv == CKR_OK &&
9925+ (rv = _pkcs11h_threading_mutexLock (&certificate->mutex)) == CKR_OK
9926+ ) {
9927+ mutex_locked = TRUE;
9928+ }
9929+#endif
9930+
9931+ certificate->mask_sign_mode = 0;
9932+
9933+ while (rv == CKR_OK && !op_succeed) {
9934+ CK_ATTRIBUTE key_attrs[] = {
9935+ {CKA_SIGN, NULL, 0},
9936+ {CKA_SIGN_RECOVER, NULL, 0}
9937+ };
9938+
9939+ /*
9940+ * Don't try invalid object
9941+ */
9942+ if (
9943+ rv == CKR_OK &&
9944+ certificate->key_handle == PKCS11H_INVALID_OBJECT_HANDLE
9945+ ) {
9946+ rv = CKR_OBJECT_HANDLE_INVALID;
9947+ }
9948+
9949+ if (rv == CKR_OK) {
9950+ if (certificate->session->provider->mask_sign_mode != 0) {
9951+ certificate->mask_sign_mode = certificate->session->provider->mask_sign_mode;
9952+ op_succeed = TRUE;
9953+ PKCS11H_DEBUG (
9954+ PKCS11H_LOG_DEBUG1,
9955+ "PKCS#11: Key attributes enforced by provider (%08x)",
9956+ certificate->mask_sign_mode
9957+ );
9958+ }
9959+ }
9960+
9961+ if (rv == CKR_OK && !op_succeed) {
9962+ rv = _pkcs11h_session_getObjectAttributes (
9963+ certificate->session,
9964+ certificate->key_handle,
9965+ key_attrs,
9966+ sizeof (key_attrs) / sizeof (CK_ATTRIBUTE)
9967+ );
9968+ }
9969+
9970+ if (rv == CKR_OK && !op_succeed) {
9971+ CK_BBOOL *key_attrs_sign = (CK_BBOOL *)key_attrs[0].pValue;
9972+ CK_BBOOL *key_attrs_sign_recover = (CK_BBOOL *)key_attrs[1].pValue;
9973+
9974+ if (key_attrs_sign != NULL && *key_attrs_sign != CK_FALSE) {
9975+ certificate->mask_sign_mode |= PKCS11H_SIGNMODE_MASK_SIGN;
9976+ }
9977+ if (key_attrs_sign_recover != NULL && *key_attrs_sign_recover != CK_FALSE) {
9978+ certificate->mask_sign_mode |= PKCS11H_SIGNMODE_MASK_RECOVER;
9979+ }
9980+ if (certificate->mask_sign_mode == 0) {
9981+ rv = CKR_KEY_TYPE_INCONSISTENT;
9982+ }
9983+ PKCS11H_DEBUG (
9984+ PKCS11H_LOG_DEBUG1,
9985+ "PKCS#11: Key attributes loaded (%08x)",
9986+ certificate->mask_sign_mode
9987+ );
9988+ }
9989+
9990+ _pkcs11h_session_freeObjectAttributes (
9991+ key_attrs,
9992+ sizeof (key_attrs) / sizeof (CK_ATTRIBUTE)
9993+ );
9994+
9995+ if (rv == CKR_OK) {
9996+ op_succeed = TRUE;
9997+ }
9998+ else {
9999+ if (!login_retry) {
10000+ PKCS11H_DEBUG (
10001+ PKCS11H_LOG_DEBUG1,
10002+ "PKCS#11: Get private key attributes failed: %ld:'%s'",
10003+ rv,
10004+ pkcs11h_getMessage (rv)
10005+ );
10006+
10007+ rv = _pkcs11h_certificate_resetSession (
10008+ certificate,
10009+ FALSE,
10010+ TRUE
10011+ );
10012+
10013+ login_retry = TRUE;
10014+ }
10015+ }
10016+ }
10017+
10018+#if defined(ENABLE_PKCS11H_THREADING)
10019+ if (mutex_locked) {
10020+ _pkcs11h_threading_mutexRelease (&certificate->mutex);
10021+ mutex_locked = FALSE;
10022+ }
10023+#endif
10024+
10025+ PKCS11H_DEBUG (
10026+ PKCS11H_LOG_DEBUG2,
10027+ "PKCS#11: _pkcs11h_certificate_getKeyAttributes return rv=%ld-'%s'",
10028+ rv,
10029+ pkcs11h_getMessage (rv)
10030+ );
10031+
10032+ return rv;
10033+}
10034+
10035+static
10036+CK_RV
10037+_pkcs11h_certificate_validateSession (
10038+ IN const pkcs11h_certificate_t certificate
10039+) {
10040+ /*
10041+ * THREADING:
10042+ * certificate->mutex must be locked
10043+ * certificate->session->mutex must be locked
10044+ */
10045+ CK_RV rv = CKR_OK;
10046+
10047+ PKCS11H_ASSERT (certificate!=NULL);
10048+
10049+ PKCS11H_DEBUG (
10050+ PKCS11H_LOG_DEBUG2,
10051+ "PKCS#11: _pkcs11h_certificate_validateSession entry certificate=%p",
10052+ (void *)certificate
10053+ );
10054+
10055+ if (certificate->session == NULL) {
10056+ rv = CKR_SESSION_HANDLE_INVALID;
10057+ }
10058+
10059+ if (rv == CKR_OK) {
10060+ rv = _pkcs11h_session_validate (certificate->session);
10061+ }
10062+
10063+ if (rv == CKR_OK) {
10064+ if (certificate->key_handle == PKCS11H_INVALID_OBJECT_HANDLE) {
10065+ rv = CKR_OBJECT_HANDLE_INVALID;
10066+ }
10067+ }
10068+
10069+ PKCS11H_DEBUG (
10070+ PKCS11H_LOG_DEBUG2,
10071+ "PKCS#11: _pkcs11h_certificate_validateSession return rv=%ld-'%s'",
10072+ rv,
10073+ pkcs11h_getMessage (rv)
10074+ );
10075+
10076+ return rv;
10077+}
10078+
10079+CK_RV
10080+_pkcs11h_certificate_resetSession (
10081+ IN const pkcs11h_certificate_t certificate,
10082+ IN const PKCS11H_BOOL public_only,
10083+ IN const PKCS11H_BOOL session_mutex_locked
10084+) {
10085+ /*
10086+ * THREADING:
10087+ * certificate->mutex must be locked
10088+ */
10089+#if defined(ENABLE_PKCS11H_THREADING)
10090+ PKCS11H_BOOL mutex_locked = FALSE;
10091+#endif
10092+ PKCS11H_BOOL is_key_valid = FALSE;
10093+ CK_RV rv = CKR_OK;
10094+
10095+ PKCS11H_ASSERT (certificate!=NULL);
10096+
10097+ PKCS11H_DEBUG (
10098+ PKCS11H_LOG_DEBUG2,
10099+ "PKCS#11: _pkcs11h_certificate_resetSession entry certificate=%p, public_only=%d, session_mutex_locked=%d",
10100+ (void *)certificate,
10101+ public_only ? 1 : 0,
10102+ session_mutex_locked ? 1 : 0
10103+ );
10104+
10105+ if (rv == CKR_OK && certificate->session == NULL) {
10106+ rv = _pkcs11h_session_getSessionByTokenId (certificate->id->token_id, &certificate->session);
10107+ }
10108+
10109+#if defined(ENABLE_PKCS11H_THREADING)
10110+ if (
10111+ rv == CKR_OK &&
10112+ !session_mutex_locked &&
10113+ (rv = _pkcs11h_threading_mutexLock (&certificate->session->mutex)) == CKR_OK
10114+ ) {
10115+ mutex_locked = TRUE;
10116+ }
10117+#endif
10118+
10119+ if (
10120+ rv == CKR_OK &&
10121+ !certificate->pin_cache_populated_to_session
10122+ ) {
10123+ certificate->pin_cache_populated_to_session = TRUE;
10124+
10125+ if (certificate->pin_cache_period != PKCS11H_PIN_CACHE_INFINITE) {
10126+ if (certificate->session->pin_cache_period != PKCS11H_PIN_CACHE_INFINITE) {
10127+ if (certificate->session->pin_cache_period > certificate->pin_cache_period) {
10128+ certificate->session->pin_expire_time = (
10129+ certificate->session->pin_expire_time -
10130+ (time_t)certificate->session->pin_cache_period +
10131+ (time_t)certificate->pin_cache_period
10132+ );
10133+ certificate->session->pin_cache_period = certificate->pin_cache_period;
10134+ }
10135+ }
10136+ else {
10137+ certificate->session->pin_expire_time = (
10138+ PKCS11H_TIME (NULL) +
10139+ (time_t)certificate->pin_cache_period
10140+ );
10141+ certificate->session->pin_cache_period = certificate->pin_cache_period;
10142+ }
10143+ }
10144+ }
10145+
10146+ /*
10147+ * First, if session seems to be valid
10148+ * and key handle is invalid (hard-set),
10149+ * try to fetch key handle,
10150+ * maybe the token is already logged in
10151+ */
10152+ if (rv == CKR_OK) {
10153+ if (
10154+ certificate->session->session_handle != PKCS11H_INVALID_SESSION_HANDLE &&
10155+ certificate->key_handle == PKCS11H_INVALID_OBJECT_HANDLE
10156+ ) {
10157+ if (!public_only || certificate->session->provider->cert_is_private) {
10158+ if (
10159+ (rv = _pkcs11h_session_getObjectById (
10160+ certificate->session,
10161+ CKO_PRIVATE_KEY,
10162+ certificate->id->attrCKA_ID,
10163+ certificate->id->attrCKA_ID_size,
10164+ &certificate->key_handle
10165+ )) == CKR_OK
10166+ ) {
10167+ is_key_valid = TRUE;
10168+ }
10169+ else {
10170+ /*
10171+ * Ignore error
10172+ */
10173+ rv = CKR_OK;
10174+ certificate->key_handle = PKCS11H_INVALID_OBJECT_HANDLE;
10175+ }
10176+ }
10177+ }
10178+ }
10179+
10180+ if (
10181+ !is_key_valid &&
10182+ rv == CKR_OK &&
10183+ (rv = _pkcs11h_session_login (
10184+ certificate->session,
10185+ public_only,
10186+ TRUE,
10187+ certificate->user_data,
10188+ certificate->mask_prompt
10189+ )) == CKR_OK
10190+ ) {
10191+ rv = _pkcs11h_certificate_updateCertificateIdDescription (certificate->id);
10192+ }
10193+
10194+ if (
10195+ !is_key_valid &&
10196+ rv == CKR_OK &&
10197+ !public_only &&
10198+ (rv = _pkcs11h_session_getObjectById (
10199+ certificate->session,
10200+ CKO_PRIVATE_KEY,
10201+ certificate->id->attrCKA_ID,
10202+ certificate->id->attrCKA_ID_size,
10203+ &certificate->key_handle
10204+ )) == CKR_OK
10205+ ) {
10206+ is_key_valid = TRUE;
10207+ }
10208+
10209+ if (
10210+ rv == CKR_OK &&
10211+ !public_only &&
10212+ !is_key_valid
10213+ ) {
10214+ rv = CKR_FUNCTION_REJECTED;
10215+ }
10216+
10217+#if defined(ENABLE_PKCS11H_THREADING)
10218+ if (mutex_locked) {
10219+ _pkcs11h_threading_mutexRelease (&certificate->session->mutex);
10220+ mutex_locked = FALSE;
10221+ }
10222+#endif
10223+
10224+ PKCS11H_DEBUG (
10225+ PKCS11H_LOG_DEBUG2,
10226+ "PKCS#11: _pkcs11h_certificate_resetSession return rv=%ld-'%s'",
10227+ rv,
10228+ pkcs11h_getMessage (rv)
10229+ );
10230+
10231+ return rv;
10232+}
10233+
10234+static
10235+CK_RV
10236+_pkcs11h_certificate_doPrivateOperation (
10237+ IN const pkcs11h_certificate_t certificate,
10238+ IN const enum _pkcs11h_private_op_e op,
10239+ IN const CK_MECHANISM_TYPE mech_type,
10240+ IN const unsigned char * const source,
10241+ IN const size_t source_size,
10242+ OUT unsigned char * const target,
10243+ IN OUT size_t * const p_target_size
10244+) {
10245+#if defined(ENABLE_PKCS11H_THREADING)
10246+ PKCS11H_BOOL mutex_locked = FALSE;
10247+#endif
10248+ CK_MECHANISM mech = {
10249+ mech_type, NULL, 0
10250+ };
10251+
10252+ CK_RV rv = CKR_OK;
10253+ PKCS11H_BOOL login_retry = FALSE;
10254+ PKCS11H_BOOL op_succeed = FALSE;
10255+
10256+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
10257+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
10258+ PKCS11H_ASSERT (certificate!=NULL);
10259+ PKCS11H_ASSERT (source!=NULL);
10260+ /*PKCS11H_ASSERT (target); NOT NEEDED*/
10261+ PKCS11H_ASSERT (p_target_size!=NULL);
10262+
10263+ PKCS11H_DEBUG (
10264+ PKCS11H_LOG_DEBUG2,
10265+ "PKCS#11: _pkcs11h_certificate_doPrivateOperation entry certificate=%p, op=%d, mech_type=%ld, source=%p, source_size=%u, target=%p, *p_target_size=%u",
10266+ (void *)certificate,
10267+ op,
10268+ mech_type,
10269+ source,
10270+ source_size,
10271+ target,
10272+ target != NULL ? *p_target_size : 0
10273+ );
10274+
10275+ if (target == NULL) {
10276+ *p_target_size = 0;
10277+ }
10278+
10279+#if defined(ENABLE_PKCS11H_THREADING)
10280+ if (
10281+ rv == CKR_OK &&
10282+ (rv = _pkcs11h_threading_mutexLock (&certificate->mutex)) == CKR_OK
10283+ ) {
10284+ mutex_locked = TRUE;
10285+ }
10286+#endif
10287+
10288+ while (rv == CKR_OK && !op_succeed) {
10289+ if (rv == CKR_OK && !certificate->operation_active) {
10290+ rv = _pkcs11h_certificate_validateSession (certificate);
10291+ }
10292+
10293+ if (rv == CKR_OK && !certificate->operation_active) {
10294+ switch (op) {
10295+ case _pkcs11h_private_op_sign:
10296+ rv = certificate->session->provider->f->C_SignInit (
10297+ certificate->session->session_handle,
10298+ &mech,
10299+ certificate->key_handle
10300+ );
10301+ break;
10302+ case _pkcs11h_private_op_sign_recover:
10303+ rv = certificate->session->provider->f->C_SignRecoverInit (
10304+ certificate->session->session_handle,
10305+ &mech,
10306+ certificate->key_handle
10307+ );
10308+ break;
10309+ case _pkcs11h_private_op_decrypt:
10310+ rv = certificate->session->provider->f->C_DecryptInit (
10311+ certificate->session->session_handle,
10312+ &mech,
10313+ certificate->key_handle
10314+ );
10315+ break;
10316+ default:
10317+ rv = CKR_ARGUMENTS_BAD;
10318+ break;
10319+ }
10320+
10321+ PKCS11H_DEBUG (
10322+ PKCS11H_LOG_DEBUG2,
10323+ "PKCS#11: _pkcs11h_certificate_doPrivateOperation init rv=%ld",
10324+ rv
10325+ );
10326+ }
10327+
10328+ if (rv == CKR_OK) {
10329+ CK_ULONG size = *p_target_size;
10330+
10331+ switch (op) {
10332+ case _pkcs11h_private_op_sign:
10333+ rv = certificate->session->provider->f->C_Sign (
10334+ certificate->session->session_handle,
10335+ (CK_BYTE_PTR)source,
10336+ source_size,
10337+ (CK_BYTE_PTR)target,
10338+ &size
10339+ );
10340+ break;
10341+ case _pkcs11h_private_op_sign_recover:
10342+ rv = certificate->session->provider->f->C_SignRecover (
10343+ certificate->session->session_handle,
10344+ (CK_BYTE_PTR)source,
10345+ source_size,
10346+ (CK_BYTE_PTR)target,
10347+ &size
10348+ );
10349+ break;
10350+ case _pkcs11h_private_op_decrypt:
10351+ rv = certificate->session->provider->f->C_Decrypt (
10352+ certificate->session->session_handle,
10353+ (CK_BYTE_PTR)source,
10354+ source_size,
10355+ (CK_BYTE_PTR)target,
10356+ &size
10357+ );
10358+ break;
10359+ default:
10360+ rv = CKR_ARGUMENTS_BAD;
10361+ break;
10362+ }
10363+
10364+ *p_target_size = size;
10365+
10366+ PKCS11H_DEBUG (
10367+ PKCS11H_LOG_DEBUG2,
10368+ "PKCS#11: _pkcs11h_certificate_doPrivateOperation op rv=%ld",
10369+ rv
10370+ );
10371+ }
10372+
10373+ if (
10374+ target == NULL &&
10375+ (
10376+ rv == CKR_BUFFER_TOO_SMALL ||
10377+ rv == CKR_OK
10378+ )
10379+ ) {
10380+ certificate->operation_active = TRUE;
10381+ rv = CKR_OK;
10382+ }
10383+ else {
10384+ certificate->operation_active = FALSE;
10385+ }
10386+
10387+ if (rv == CKR_OK) {
10388+ op_succeed = TRUE;
10389+ }
10390+ else {
10391+ /*
10392+ * OpenSC workaround
10393+ * It still allows C_FindObjectsInit when
10394+ * token is removed/inserted but fails
10395+ * private key operation.
10396+ * So we force logout.
10397+ * bug#108 at OpenSC trac
10398+ */
10399+ if (login_retry && rv == CKR_DEVICE_REMOVED) {
10400+ login_retry = FALSE;
10401+ _pkcs11h_session_logout (certificate->session);
10402+ }
10403+
10404+ if (!login_retry) {
10405+ PKCS11H_DEBUG (
10406+ PKCS11H_LOG_DEBUG1,
10407+ "PKCS#11: Private key operation failed rv=%ld-'%s'",
10408+ rv,
10409+ pkcs11h_getMessage (rv)
10410+ );
10411+ login_retry = TRUE;
10412+ rv = _pkcs11h_certificate_resetSession (
10413+ certificate,
10414+ FALSE,
10415+ TRUE
10416+ );
10417+ }
10418+ }
10419+
10420+ }
10421+
10422+#if defined(ENABLE_PKCS11H_THREADING)
10423+ if (mutex_locked) {
10424+ _pkcs11h_threading_mutexRelease (&certificate->mutex);
10425+ mutex_locked = FALSE;
10426+ }
10427+#endif
10428+
10429+ PKCS11H_DEBUG (
10430+ PKCS11H_LOG_DEBUG2,
10431+ "PKCS#11: _pkcs11h_certificate_doPrivateOperation return rv=%ld-'%s', *p_target_size=%u",
10432+ rv,
10433+ pkcs11h_getMessage (rv),
10434+ *p_target_size
10435+ );
10436+
10437+ return rv;
10438+}
10439+
10440+CK_RV
10441+pkcs11h_certificate_freeCertificateId (
10442+ IN pkcs11h_certificate_id_t certificate_id
10443+) {
10444+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
10445+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
10446+ PKCS11H_ASSERT (certificate_id!=NULL);
10447+
10448+ PKCS11H_DEBUG (
10449+ PKCS11H_LOG_DEBUG2,
10450+ "PKCS#11: pkcs11h_certificate_freeCertificateId entry certificate_id=%p",
10451+ (void *)certificate_id
10452+ );
10453+
10454+ if (certificate_id->attrCKA_ID != NULL) {
10455+ _pkcs11h_mem_free ((void *)&certificate_id->attrCKA_ID);
10456+ }
10457+ if (certificate_id->certificate_blob != NULL) {
10458+ _pkcs11h_mem_free ((void *)&certificate_id->certificate_blob);
10459+ }
10460+ if (certificate_id->token_id != NULL) {
10461+ pkcs11h_token_freeTokenId (certificate_id->token_id);
10462+ certificate_id->token_id = NULL;
10463+ }
10464+ _pkcs11h_mem_free ((void *)&certificate_id);
10465+
10466+ PKCS11H_DEBUG (
10467+ PKCS11H_LOG_DEBUG2,
10468+ "PKCS#11: pkcs11h_certificate_freeCertificateId return"
10469+ );
10470+
10471+ return CKR_OK;
10472+}
10473+
10474+CK_RV
10475+pkcs11h_certificate_duplicateCertificateId (
10476+ OUT pkcs11h_certificate_id_t * const to,
10477+ IN const pkcs11h_certificate_id_t from
10478+) {
10479+ CK_RV rv = CKR_OK;
10480+
10481+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
10482+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
10483+ PKCS11H_ASSERT (to!=NULL);
10484+ PKCS11H_ASSERT (from!=NULL);
10485+
10486+ PKCS11H_DEBUG (
10487+ PKCS11H_LOG_DEBUG2,
10488+ "PKCS#11: pkcs11h_certificate_duplicateCertificateId entry to=%p form=%p",
10489+ (void *)to,
10490+ (void *)from
10491+ );
10492+
10493+ *to = NULL;
10494+
10495+ if (rv == CKR_OK) {
10496+ rv = _pkcs11h_mem_duplicate (
10497+ (void*)to,
10498+ NULL,
10499+ from,
10500+ sizeof (struct pkcs11h_certificate_id_s)
10501+ );
10502+ }
10503+
10504+ if (rv == CKR_OK) {
10505+ rv = _pkcs11h_mem_duplicate (
10506+ (void*)&(*to)->token_id,
10507+ NULL,
10508+ from->token_id,
10509+ sizeof (struct pkcs11h_token_id_s)
10510+ );
10511+ }
10512+
10513+ if (rv == CKR_OK) {
10514+ rv = _pkcs11h_mem_duplicate (
10515+ (void*)&(*to)->attrCKA_ID,
10516+ &(*to)->attrCKA_ID_size,
10517+ from->attrCKA_ID,
10518+ from->attrCKA_ID_size
10519+ );
10520+ }
10521+
10522+ if (rv == CKR_OK) {
10523+ rv = _pkcs11h_mem_duplicate (
10524+ (void*)&(*to)->certificate_blob,
10525+ &(*to)->certificate_blob_size,
10526+ from->certificate_blob,
10527+ from->certificate_blob_size
10528+ );
10529+ }
10530+
10531+ PKCS11H_DEBUG (
10532+ PKCS11H_LOG_DEBUG2,
10533+ "PKCS#11: pkcs11h_certificate_duplicateCertificateId return rv=%ld-'%s', *to=%p",
10534+ rv,
10535+ pkcs11h_getMessage (rv),
10536+ (void *)*to
10537+ );
10538+
10539+ return rv;
10540+}
10541+
10542+CK_RV
10543+pkcs11h_certificate_setCertificateIdCertificateBlob (
10544+ IN const pkcs11h_certificate_id_t certificate_id,
10545+ IN const unsigned char * const blob,
10546+ IN const size_t blob_size
10547+) {
10548+ CK_RV rv = CKR_OK;
10549+
10550+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
10551+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
10552+ PKCS11H_ASSERT (certificate_id!=NULL);
10553+ PKCS11H_ASSERT (blob!=NULL);
10554+
10555+ PKCS11H_DEBUG (
10556+ PKCS11H_LOG_DEBUG2,
10557+ "PKCS#11: pkcs11h_certificate_setCertificateIdCertificateBlob entry certificate_id=%p",
10558+ (void *)certificate_id
10559+ );
10560+
10561+ if (rv == CKR_OK && certificate_id->certificate_blob != NULL) {
10562+ rv = _pkcs11h_mem_free ((void *)&certificate_id->certificate_blob);
10563+ }
10564+
10565+ if (rv == CKR_OK) {
10566+ rv = _pkcs11h_mem_duplicate (
10567+ (void *)&certificate_id->certificate_blob,
10568+ &certificate_id->certificate_blob_size,
10569+ blob,
10570+ blob_size
10571+ );
10572+ }
10573+
10574+ PKCS11H_DEBUG (
10575+ PKCS11H_LOG_DEBUG2,
10576+ "PKCS#11: pkcs11h_certificate_setCertificateIdCertificateBlob return rv=%ld-'%s'",
10577+ rv,
10578+ pkcs11h_getMessage (rv)
10579+ );
10580+
10581+ return rv;
10582+}
10583+
10584+CK_RV
10585+pkcs11h_certificate_freeCertificate (
10586+ IN pkcs11h_certificate_t certificate
10587+) {
10588+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
10589+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
10590+
10591+ PKCS11H_DEBUG (
10592+ PKCS11H_LOG_DEBUG2,
10593+ "PKCS#11: pkcs11h_certificate_freeCertificate entry certificate=%p",
10594+ (void *)certificate
10595+ );
10596+
10597+ if (certificate != NULL) {
10598+ if (certificate->session != NULL) {
10599+ _pkcs11h_session_release (certificate->session);
10600+ }
10601+ pkcs11h_certificate_freeCertificateId (certificate->id);
10602+ certificate->id = NULL;
10603+
10604+#if defined(ENABLE_PKCS11H_THREADING)
10605+ _pkcs11h_threading_mutexFree (&certificate->mutex);
10606+#endif
10607+
10608+ _pkcs11h_mem_free ((void *)&certificate);
10609+ }
10610+
10611+ PKCS11H_DEBUG (
10612+ PKCS11H_LOG_DEBUG2,
10613+ "PKCS#11: pkcs11h_certificate_freeCertificate return"
10614+ );
10615+
10616+ return CKR_OK;
10617+}
10618+
10619+CK_RV
10620+pkcs11h_certificate_lockSession (
10621+ IN const pkcs11h_certificate_t certificate
10622+) {
10623+#if defined(ENABLE_PKCS11H_THREADING)
10624+ CK_RV rv = CKR_OK;
10625+
10626+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
10627+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
10628+ PKCS11H_ASSERT (certificate!=NULL);
10629+
10630+ if (rv == CKR_OK && certificate->session == NULL) {
10631+ rv = _pkcs11h_session_getSessionByTokenId (certificate->id->token_id, &certificate->session);
10632+ }
10633+
10634+ if (rv == CKR_OK) {
10635+ rv = _pkcs11h_threading_mutexLock (&certificate->session->mutex);
10636+ }
10637+
10638+ return rv;
10639+#else
10640+ return CKR_OK;
10641+#endif
10642+}
10643+
10644+CK_RV
10645+pkcs11h_certificate_releaseSession (
10646+ IN const pkcs11h_certificate_t certificate
10647+) {
10648+#if defined(ENABLE_PKCS11H_THREADING)
10649+ CK_RV rv = CKR_OK;
10650+
10651+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
10652+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
10653+ PKCS11H_ASSERT (certificate!=NULL);
10654+
10655+ if (certificate->session != NULL) {
10656+ rv = _pkcs11h_threading_mutexRelease (&certificate->session->mutex);
10657+ }
10658+
10659+ return rv;
10660+#else
10661+ return CKR_OK;
10662+#endif
10663+}
10664+
10665+CK_RV
10666+pkcs11h_certificate_sign (
10667+ IN const pkcs11h_certificate_t certificate,
10668+ IN const CK_MECHANISM_TYPE mech_type,
10669+ IN const unsigned char * const source,
10670+ IN const size_t source_size,
10671+ OUT unsigned char * const target,
10672+ IN OUT size_t * const p_target_size
10673+) {
10674+ CK_RV rv = CKR_OK;
10675+
10676+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
10677+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
10678+ PKCS11H_ASSERT (certificate!=NULL);
10679+ PKCS11H_ASSERT (source!=NULL);
10680+ /*PKCS11H_ASSERT (target); NOT NEEDED*/
10681+ PKCS11H_ASSERT (p_target_size!=NULL);
10682+
10683+ PKCS11H_DEBUG (
10684+ PKCS11H_LOG_DEBUG2,
10685+ "PKCS#11: pkcs11h_certificate_sign entry certificate=%p, mech_type=%ld, source=%p, source_size=%u, target=%p, *p_target_size=%u",
10686+ (void *)certificate,
10687+ mech_type,
10688+ source,
10689+ source_size,
10690+ target,
10691+ target != NULL ? *p_target_size : 0
10692+ );
10693+
10694+ if (target == NULL) {
10695+ *p_target_size = 0;
10696+ }
10697+
10698+ if (rv == CKR_OK) {
10699+ rv = _pkcs11h_certificate_doPrivateOperation (
10700+ certificate,
10701+ _pkcs11h_private_op_sign,
10702+ mech_type,
10703+ source,
10704+ source_size,
10705+ target,
10706+ p_target_size
10707+ );
10708+ }
10709+
10710+ PKCS11H_DEBUG (
10711+ PKCS11H_LOG_DEBUG2,
10712+ "PKCS#11: pkcs11h_certificate_sign return rv=%ld-'%s', *p_target_size=%u",
10713+ rv,
10714+ pkcs11h_getMessage (rv),
10715+ *p_target_size
10716+ );
10717+
10718+ return rv;
10719+}
10720+
10721+CK_RV
10722+pkcs11h_certificate_signRecover (
10723+ IN const pkcs11h_certificate_t certificate,
10724+ IN const CK_MECHANISM_TYPE mech_type,
10725+ IN const unsigned char * const source,
10726+ IN const size_t source_size,
10727+ OUT unsigned char * const target,
10728+ IN OUT size_t * const p_target_size
10729+) {
10730+ CK_RV rv = CKR_OK;
10731+
10732+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
10733+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
10734+ PKCS11H_ASSERT (certificate!=NULL);
10735+ PKCS11H_ASSERT (source!=NULL);
10736+ /*PKCS11H_ASSERT (target); NOT NEEDED*/
10737+ PKCS11H_ASSERT (p_target_size!=NULL);
10738+
10739+ PKCS11H_DEBUG (
10740+ PKCS11H_LOG_DEBUG2,
10741+ "PKCS#11: pkcs11h_certificate_signRecover entry certificate=%p, mech_type=%ld, source=%p, source_size=%u, target=%p, *p_target_size=%u",
10742+ (void *)certificate,
10743+ mech_type,
10744+ source,
10745+ source_size,
10746+ target,
10747+ target != NULL ? *p_target_size : 0
10748+ );
10749+
10750+ if (target == NULL) {
10751+ *p_target_size = 0;
10752+ }
10753+
10754+ if (rv == CKR_OK) {
10755+ rv = _pkcs11h_certificate_doPrivateOperation (
10756+ certificate,
10757+ _pkcs11h_private_op_sign_recover,
10758+ mech_type,
10759+ source,
10760+ source_size,
10761+ target,
10762+ p_target_size
10763+ );
10764+ }
10765+
10766+ PKCS11H_DEBUG (
10767+ PKCS11H_LOG_DEBUG2,
10768+ "PKCS#11: pkcs11h_certificate_signRecover return rv=%ld-'%s', *p_target_size=%u",
10769+ rv,
10770+ pkcs11h_getMessage (rv),
10771+ *p_target_size
10772+ );
10773+
10774+ return rv;
10775+}
10776+
10777+CK_RV
10778+pkcs11h_certificate_signAny (
10779+ IN const pkcs11h_certificate_t certificate,
10780+ IN const CK_MECHANISM_TYPE mech_type,
10781+ IN const unsigned char * const source,
10782+ IN const size_t source_size,
10783+ OUT unsigned char * const target,
10784+ IN OUT size_t * const p_target_size
10785+) {
10786+ CK_RV rv = CKR_OK;
10787+ PKCS11H_BOOL fSigned = FALSE;
10788+
10789+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
10790+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
10791+ PKCS11H_ASSERT (certificate!=NULL);
10792+ PKCS11H_ASSERT (source!=NULL);
10793+ /*PKCS11H_ASSERT (target); NOT NEEDED*/
10794+ PKCS11H_ASSERT (p_target_size!=NULL);
10795+
10796+ PKCS11H_DEBUG (
10797+ PKCS11H_LOG_DEBUG2,
10798+ "PKCS#11: pkcs11h_certificate_signAny entry certificate=%p, mech_type=%ld, source=%p, source_size=%u, target=%p, *p_target_size=%u",
10799+ (void *)certificate,
10800+ mech_type,
10801+ source,
10802+ source_size,
10803+ target,
10804+ target != NULL ? *p_target_size : 0
10805+ );
10806+
10807+ if (
10808+ rv == CKR_OK &&
10809+ certificate->mask_sign_mode == 0
10810+ ) {
10811+ PKCS11H_DEBUG (
10812+ PKCS11H_LOG_DEBUG1,
10813+ "PKCS#11: Getting key attributes"
10814+ );
10815+ rv = _pkcs11h_certificate_getKeyAttributes (certificate);
10816+ }
10817+
10818+ if (
10819+ rv == CKR_OK &&
10820+ !fSigned &&
10821+ (certificate->mask_sign_mode & PKCS11H_SIGNMODE_MASK_SIGN) != 0
10822+ ) {
10823+ rv = pkcs11h_certificate_sign (
10824+ certificate,
10825+ mech_type,
10826+ source,
10827+ source_size,
10828+ target,
10829+ p_target_size
10830+ );
10831+
10832+ if (rv == CKR_OK) {
10833+ fSigned = TRUE;
10834+ }
10835+ else if (
10836+ rv == CKR_FUNCTION_NOT_SUPPORTED ||
10837+ rv == CKR_KEY_FUNCTION_NOT_PERMITTED
10838+ ) {
10839+ certificate->mask_sign_mode &= ~PKCS11H_SIGNMODE_MASK_SIGN;
10840+ rv = CKR_OK;
10841+ }
10842+ }
10843+
10844+ if (
10845+ rv == CKR_OK &&
10846+ !fSigned &&
10847+ (certificate->mask_sign_mode & PKCS11H_SIGNMODE_MASK_RECOVER) != 0
10848+ ) {
10849+ rv = pkcs11h_certificate_signRecover (
10850+ certificate,
10851+ mech_type,
10852+ source,
10853+ source_size,
10854+ target,
10855+ p_target_size
10856+ );
10857+
10858+ if (rv == CKR_OK) {
10859+ fSigned = TRUE;
10860+ }
10861+ else if (
10862+ rv == CKR_FUNCTION_NOT_SUPPORTED ||
10863+ rv == CKR_KEY_FUNCTION_NOT_PERMITTED
10864+ ) {
10865+ certificate->mask_sign_mode &= ~PKCS11H_SIGNMODE_MASK_RECOVER;
10866+ rv = CKR_OK;
10867+ }
10868+ }
10869+
10870+ if (rv == CKR_OK && !fSigned) {
10871+ rv = CKR_FUNCTION_FAILED;
10872+ }
10873+
10874+ PKCS11H_DEBUG (
10875+ PKCS11H_LOG_DEBUG2,
10876+ "PKCS#11: pkcs11h_certificate_signAny return rv=%ld-'%s', *p_target_size=%p",
10877+ rv,
10878+ pkcs11h_getMessage (rv),
10879+ (void *)*p_target_size
10880+ );
10881+
10882+ return rv;
10883+}
10884+
10885+CK_RV
10886+pkcs11h_certificate_decrypt (
10887+ IN const pkcs11h_certificate_t certificate,
10888+ IN const CK_MECHANISM_TYPE mech_type,
10889+ IN const unsigned char * const source,
10890+ IN const size_t source_size,
10891+ OUT unsigned char * const target,
10892+ IN OUT size_t * const p_target_size
10893+) {
10894+ CK_RV rv = CKR_OK;
10895+
10896+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
10897+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
10898+ PKCS11H_ASSERT (certificate!=NULL);
10899+ PKCS11H_ASSERT (source!=NULL);
10900+ /*PKCS11H_ASSERT (target); NOT NEEDED*/
10901+ PKCS11H_ASSERT (p_target_size!=NULL);
10902+
10903+ PKCS11H_DEBUG (
10904+ PKCS11H_LOG_DEBUG2,
10905+ "PKCS#11: pkcs11h_decrypt entry certificate=%p, mech_type=%ld, source=%p, source_size=%u, target=%p, *p_target_size=%u",
10906+ (void *)certificate,
10907+ mech_type,
10908+ source,
10909+ source_size,
10910+ target,
10911+ target != NULL ? *p_target_size : 0
10912+ );
10913+
10914+ if (target == NULL) {
10915+ *p_target_size = 0;
10916+ }
10917+
10918+ if (rv == CKR_OK) {
10919+ rv = _pkcs11h_certificate_doPrivateOperation (
10920+ certificate,
10921+ _pkcs11h_private_op_decrypt,
10922+ mech_type,
10923+ source,
10924+ source_size,
10925+ target,
10926+ p_target_size
10927+ );
10928+ }
10929+
10930+ PKCS11H_DEBUG (
10931+ PKCS11H_LOG_DEBUG2,
10932+ "PKCS#11: pkcs11h_decrypt return rv=%ld-'%s', *p_target_size=%u",
10933+ rv,
10934+ pkcs11h_getMessage (rv),
10935+ *p_target_size
10936+ );
10937+
10938+ return rv;
10939+}
10940+
10941+CK_RV
10942+pkcs11h_certificate_create (
10943+ IN const pkcs11h_certificate_id_t certificate_id,
10944+ IN void * const user_data,
10945+ IN const unsigned mask_prompt,
10946+ IN const int pin_cache_period,
10947+ OUT pkcs11h_certificate_t * const p_certificate
10948+) {
10949+ pkcs11h_certificate_t certificate = NULL;
10950+ CK_RV rv = CKR_OK;
10951+
10952+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
10953+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
10954+ /*PKCS11H_ASSERT (user_data!=NULL); NOT NEEDED */
10955+ PKCS11H_ASSERT (p_certificate!=NULL);
10956+
10957+ PKCS11H_DEBUG (
10958+ PKCS11H_LOG_DEBUG2,
10959+ "PKCS#11: pkcs11h_certificate_create entry certificate_id=%p, user_data=%p, mask_prompt=%08x, pin_cache_period=%d, p_certificate=%p",
10960+ (void *)certificate_id,
10961+ user_data,
10962+ mask_prompt,
10963+ pin_cache_period,
10964+ (void *)p_certificate
10965+ );
10966+
10967+ *p_certificate = NULL;
10968+
10969+ if (
10970+ rv == CKR_OK &&
10971+ (rv = _pkcs11h_mem_malloc ((void*)&certificate, sizeof (struct pkcs11h_certificate_s))) == CKR_OK
10972+ ) {
10973+ certificate->user_data = user_data;
10974+ certificate->mask_prompt = mask_prompt;
10975+ certificate->key_handle = PKCS11H_INVALID_OBJECT_HANDLE;
10976+ certificate->pin_cache_period = pin_cache_period;
10977+ }
10978+
10979+#if defined(ENABLE_PKCS11H_THREADING)
10980+ if (rv == CKR_OK) {
10981+ rv = _pkcs11h_threading_mutexInit (&certificate->mutex);
10982+ }
10983+#endif
10984+
10985+ if (rv == CKR_OK) {
10986+ rv = pkcs11h_certificate_duplicateCertificateId (&certificate->id, certificate_id);
10987+ }
10988+
10989+ if (rv == CKR_OK) {
10990+ *p_certificate = certificate;
10991+ certificate = NULL;
10992+ }
10993+
10994+ if (certificate != NULL) {
10995+#if defined(ENABLE_PKCS11H_THREADING)
10996+ _pkcs11h_threading_mutexFree (&certificate->mutex);
10997+#endif
10998+ _pkcs11h_mem_free ((void *)&certificate);
10999+ }
11000+
11001+ PKCS11H_DEBUG (
11002+ PKCS11H_LOG_DEBUG2,
11003+ "PKCS#11: pkcs11h_certificate_create return rv=%ld-'%s' *p_certificate=%p",
11004+ rv,
11005+ pkcs11h_getMessage (rv),
11006+ (void *)*p_certificate
11007+ );
11008+
11009+ return rv;
11010+}
11011+
11012+unsigned
11013+pkcs11h_certificate_getPromptMask (
11014+ IN const pkcs11h_certificate_t certificate
11015+) {
11016+ PKCS11H_ASSERT (certificate!=NULL);
11017+
11018+ return certificate->mask_prompt;
11019+}
11020+
11021+void
11022+pkcs11h_certificate_setPromptMask (
11023+ IN const pkcs11h_certificate_t certificate,
11024+ IN const unsigned mask_prompt
11025+) {
11026+ PKCS11H_ASSERT (certificate!=NULL);
11027+
11028+ certificate->mask_prompt = mask_prompt;
11029+}
11030+
11031+void *
11032+pkcs11h_certificate_getUserData (
11033+ IN const pkcs11h_certificate_t certificate
11034+) {
11035+ PKCS11H_ASSERT (certificate!=NULL);
11036+
11037+ return certificate->user_data;
11038+}
11039+
11040+void
11041+pkcs11h_certificate_setUserData (
11042+ IN const pkcs11h_certificate_t certificate,
11043+ IN void * const user_data
11044+) {
11045+ PKCS11H_ASSERT (certificate!=NULL);
11046+
11047+ certificate->user_data = user_data;
11048+}
11049+
11050+CK_RV
11051+pkcs11h_certificate_getCertificateId (
11052+ IN const pkcs11h_certificate_t certificate,
11053+ OUT pkcs11h_certificate_id_t * const p_certificate_id
11054+) {
11055+ CK_RV rv = CKR_OK;
11056+
11057+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
11058+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
11059+ PKCS11H_ASSERT (certificate!=NULL);
11060+ PKCS11H_ASSERT (p_certificate_id!=NULL);
11061+
11062+ PKCS11H_DEBUG (
11063+ PKCS11H_LOG_DEBUG2,
11064+ "PKCS#11: pkcs11h_certificate_getCertificateId entry certificate=%p, certificate_id=%p",
11065+ (void *)certificate,
11066+ (void *)p_certificate_id
11067+ );
11068+
11069+ if (rv == CKR_OK) {
11070+ rv = pkcs11h_certificate_duplicateCertificateId (
11071+ p_certificate_id,
11072+ certificate->id
11073+ );
11074+ }
11075+
11076+ PKCS11H_DEBUG (
11077+ PKCS11H_LOG_DEBUG2,
11078+ "PKCS#11: pkcs11h_certificate_getCertificateId return rv=%ld-'%s'",
11079+ rv,
11080+ pkcs11h_getMessage (rv)
11081+ );
11082+
11083+ return rv;
11084+}
11085+
11086+CK_RV
11087+pkcs11h_certificate_getCertificateBlob (
11088+ IN const pkcs11h_certificate_t certificate,
11089+ OUT unsigned char * const certificate_blob,
11090+ IN OUT size_t * const p_certificate_blob_size
11091+) {
11092+#if defined(ENABLE_PKCS11H_THREADING)
11093+ PKCS11H_BOOL mutex_locked = FALSE;
11094+#endif
11095+ CK_RV rv = CKR_OK;
11096+ size_t certifiate_blob_size_max = 0;
11097+
11098+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
11099+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
11100+ PKCS11H_ASSERT (certificate!=NULL);
11101+ /*PKCS11H_ASSERT (certificate_blob!=NULL); NOT NEEDED */
11102+ PKCS11H_ASSERT (p_certificate_blob_size!=NULL);
11103+
11104+ PKCS11H_DEBUG (
11105+ PKCS11H_LOG_DEBUG2,
11106+ "PKCS#11: pkcs11h_certificate_getCertificateBlob entry certificate=%p, certificate_blob=%p, *p_certificate_blob_size=%u",
11107+ (void *)certificate,
11108+ certificate_blob,
11109+ certificate_blob != NULL ? *p_certificate_blob_size : 0
11110+ );
11111+
11112+ if (certificate_blob != NULL) {
11113+ certifiate_blob_size_max = *p_certificate_blob_size;
11114+ }
11115+ *p_certificate_blob_size = 0;
11116+
11117+#if defined(ENABLE_PKCS11H_THREADING)
11118+ if (
11119+ rv == CKR_OK &&
11120+ (rv = _pkcs11h_threading_mutexLock (&certificate->mutex)) == CKR_OK
11121+ ) {
11122+ mutex_locked = TRUE;
11123+ }
11124+#endif
11125+
11126+ if (rv == CKR_OK && certificate->id->certificate_blob == NULL) {
11127+ PKCS11H_BOOL op_succeed = FALSE;
11128+ PKCS11H_BOOL login_retry = FALSE;
11129+ while (rv == CKR_OK && !op_succeed) {
11130+ if (certificate->session == NULL) {
11131+ rv = CKR_SESSION_HANDLE_INVALID;
11132+ }
11133+
11134+ if (rv == CKR_OK) {
11135+ rv = _pkcs11h_certificate_loadCertificate (certificate);
11136+ }
11137+
11138+ if (rv == CKR_OK) {
11139+ op_succeed = TRUE;
11140+ }
11141+ else {
11142+ if (!login_retry) {
11143+ login_retry = TRUE;
11144+ rv = _pkcs11h_certificate_resetSession (
11145+ certificate,
11146+ TRUE,
11147+ FALSE
11148+ );
11149+ }
11150+ }
11151+ }
11152+ }
11153+
11154+ if (
11155+ rv == CKR_OK &&
11156+ certificate->id->certificate_blob == NULL
11157+ ) {
11158+ rv = CKR_FUNCTION_REJECTED;
11159+ }
11160+
11161+ if (rv == CKR_OK) {
11162+ _pkcs11h_certificate_updateCertificateIdDescription (certificate->id);
11163+ }
11164+
11165+ if (rv == CKR_OK) {
11166+ *p_certificate_blob_size = certificate->id->certificate_blob_size;
11167+ }
11168+
11169+ if (certificate_blob != NULL) {
11170+ if (
11171+ rv == CKR_OK &&
11172+ certificate->id->certificate_blob_size > certifiate_blob_size_max
11173+ ) {
11174+ rv = CKR_BUFFER_TOO_SMALL;
11175+ }
11176+
11177+ if (rv == CKR_OK) {
11178+ memmove (
11179+ certificate_blob,
11180+ certificate->id->certificate_blob,
11181+ *p_certificate_blob_size
11182+ );
11183+ }
11184+ }
11185+
11186+#if defined(ENABLE_PKCS11H_THREADING)
11187+ if (mutex_locked) {
11188+ _pkcs11h_threading_mutexRelease (&certificate->mutex);
11189+ mutex_locked = FALSE;
11190+ }
11191+#endif
11192+
11193+ PKCS11H_DEBUG (
11194+ PKCS11H_LOG_DEBUG2,
11195+ "PKCS#11: pkcs11h_certificate_getCertificateBlob return rv=%ld-'%s'",
11196+ rv,
11197+ pkcs11h_getMessage (rv)
11198+ );
11199+
11200+ return rv;
11201+}
11202+
11203+#if defined(ENABLE_PKCS11H_SERIALIZATION)
11204+
11205+CK_RV
11206+pkcs11h_certificate_serializeCertificateId (
11207+ OUT char * const sz,
11208+ IN OUT size_t *max,
11209+ IN const pkcs11h_certificate_id_t certificate_id
11210+) {
11211+ CK_RV rv = CKR_OK;
11212+ size_t saved_max = 0;
11213+ size_t n = 0;
11214+ size_t _max = 0;
11215+
11216+ /*PKCS11H_ASSERT (sz!=NULL); Not required */
11217+ PKCS11H_ASSERT (max!=NULL);
11218+ PKCS11H_ASSERT (certificate_id!=NULL);
11219+
11220+ PKCS11H_DEBUG (
11221+ PKCS11H_LOG_DEBUG2,
11222+ "PKCS#11: pkcs11h_certificate_serializeCertificateId entry sz=%p, *max=%u, certificate_id=%p",
11223+ sz,
11224+ sz != NULL ? *max : 0,
11225+ (void *)certificate_id
11226+ );
11227+
11228+ if (sz != NULL) {
11229+ saved_max = n = *max;
11230+ }
11231+ *max = 0;
11232+
11233+ if (rv == CKR_OK) {
11234+ rv = pkcs11h_token_serializeTokenId (
11235+ sz,
11236+ &n,
11237+ certificate_id->token_id
11238+ );
11239+ }
11240+
11241+ if (rv == CKR_OK) {
11242+ _max = n + certificate_id->attrCKA_ID_size*2 + 1;
11243+ }
11244+
11245+ if (sz != NULL) {
11246+ if (saved_max < _max) {
11247+ rv = CKR_ATTRIBUTE_VALUE_INVALID;
11248+ }
11249+
11250+ if (rv == CKR_OK) {
11251+ sz[n-1] = '/';
11252+ rv = _pkcs11h_util_binaryToHex (
11253+ sz+n,
11254+ saved_max-n,
11255+ certificate_id->attrCKA_ID,
11256+ certificate_id->attrCKA_ID_size
11257+ );
11258+
11259+ }
11260+ }
11261+
11262+ *max = _max;
11263+
11264+ PKCS11H_DEBUG (
11265+ PKCS11H_LOG_DEBUG2,
11266+ "PKCS#11: pkcs11h_certificate_serializeCertificateId return rv=%ld-'%s', *max=%u, sz='%s'",
11267+ rv,
11268+ pkcs11h_getMessage (rv),
11269+ *max,
11270+ sz
11271+ );
11272+
11273+ return rv;
11274+}
11275+
11276+CK_RV
11277+pkcs11h_certificate_deserializeCertificateId (
11278+ OUT pkcs11h_certificate_id_t * const p_certificate_id,
11279+ IN const char * const sz
11280+) {
11281+ pkcs11h_certificate_id_t certificate_id = NULL;
11282+ CK_RV rv = CKR_OK;
11283+ char *p = NULL;
11284+ char *_sz = NULL;
11285+
11286+ PKCS11H_ASSERT (p_certificate_id!=NULL);
11287+ PKCS11H_ASSERT (sz!=NULL);
11288+
11289+ *p_certificate_id = NULL;
11290+
11291+ PKCS11H_DEBUG (
11292+ PKCS11H_LOG_DEBUG2,
11293+ "PKCS#11: pkcs11h_certificate_deserializeCertificateId entry p_certificate_id=%p, sz='%s'",
11294+ (void *)p_certificate_id,
11295+ sz
11296+ );
11297+
11298+ if (rv == CKR_OK) {
11299+ rv = _pkcs11h_mem_strdup (
11300+ (void *)&_sz,
11301+ sz
11302+ );
11303+ }
11304+
11305+ if (rv == CKR_OK) {
11306+ p = _sz;
11307+ }
11308+
11309+ if (rv == CKR_OK) {
11310+ rv = _pkcs11h_certificate_newCertificateId (&certificate_id);
11311+ }
11312+
11313+ if (
11314+ rv == CKR_OK &&
11315+ (p = strrchr (_sz, '/')) == NULL
11316+ ) {
11317+ rv = CKR_ATTRIBUTE_VALUE_INVALID;
11318+ }
11319+
11320+ if (rv == CKR_OK) {
11321+ *p = '\x0';
11322+ p++;
11323+ }
11324+
11325+ if (rv == CKR_OK) {
11326+ rv = pkcs11h_token_deserializeTokenId (
11327+ &certificate_id->token_id,
11328+ _sz
11329+ );
11330+ }
11331+
11332+ if (rv == CKR_OK) {
11333+ certificate_id->attrCKA_ID_size = strlen (p)/2;
11334+ }
11335+
11336+ if (
11337+ rv == CKR_OK &&
11338+ (rv = _pkcs11h_mem_malloc (
11339+ (void *)&certificate_id->attrCKA_ID,
11340+ certificate_id->attrCKA_ID_size)
11341+ ) == CKR_OK
11342+ ) {
11343+ rv = _pkcs11h_util_hexToBinary (
11344+ certificate_id->attrCKA_ID,
11345+ p,
11346+ &certificate_id->attrCKA_ID_size
11347+ );
11348+ }
11349+
11350+ if (rv == CKR_OK) {
11351+ *p_certificate_id = certificate_id;
11352+ certificate_id = NULL;
11353+ }
11354+
11355+ if (certificate_id != NULL) {
11356+ pkcs11h_certificate_freeCertificateId (certificate_id);
11357+ certificate_id = NULL;
11358+ }
11359+
11360+ if (_sz != NULL) {
11361+ _pkcs11h_mem_free ((void *)&_sz);
11362+ }
11363+
11364+ PKCS11H_DEBUG (
11365+ PKCS11H_LOG_DEBUG2,
11366+ "PKCS#11: pkcs11h_certificate_deserializeCertificateId return rv=%ld-'%s'",
11367+ rv,
11368+ pkcs11h_getMessage (rv)
11369+ );
11370+
11371+ return rv;
11372+
11373+}
11374+
11375+#endif /* ENABLE_PKCS11H_SERIALIZATION */
11376+
11377+CK_RV
11378+pkcs11h_certificate_ensureCertificateAccess (
11379+ IN const pkcs11h_certificate_t certificate
11380+) {
11381+#if defined(ENABLE_PKCS11H_THREADING)
11382+ PKCS11H_BOOL mutex_locked_cert = FALSE;
11383+ PKCS11H_BOOL mutex_locked_sess = FALSE;
11384+#endif
11385+ PKCS11H_BOOL validCert = FALSE;
11386+ CK_RV rv = CKR_OK;
11387+
11388+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
11389+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
11390+ PKCS11H_ASSERT (certificate!=NULL);
11391+
11392+ PKCS11H_DEBUG (
11393+ PKCS11H_LOG_DEBUG2,
11394+ "PKCS#11: pkcs11h_certificate_ensureCertificateAccess entry certificate=%p",
11395+ (void *)certificate
11396+ );
11397+
11398+#if defined(ENABLE_PKCS11H_THREADING)
11399+ if (
11400+ rv == CKR_OK &&
11401+ (rv = _pkcs11h_threading_mutexLock (&certificate->mutex)) == CKR_OK
11402+ ) {
11403+ mutex_locked_cert = TRUE;
11404+ }
11405+#endif
11406+
11407+ if (!validCert && rv == CKR_OK) {
11408+ CK_OBJECT_HANDLE h = PKCS11H_INVALID_OBJECT_HANDLE;
11409+
11410+ if (certificate->session == NULL) {
11411+ rv = CKR_SESSION_HANDLE_INVALID;
11412+ }
11413+
11414+#if defined(ENABLE_PKCS11H_THREADING)
11415+ if (
11416+ rv == CKR_OK &&
11417+ (rv = _pkcs11h_threading_mutexLock (&certificate->session->mutex)) == CKR_OK
11418+ ) {
11419+ mutex_locked_sess = TRUE;
11420+ }
11421+#endif
11422+
11423+ if (
11424+ (rv = _pkcs11h_session_getObjectById (
11425+ certificate->session,
11426+ CKO_CERTIFICATE,
11427+ certificate->id->attrCKA_ID,
11428+ certificate->id->attrCKA_ID_size,
11429+ &h
11430+ )) == CKR_OK
11431+ ) {
11432+ validCert = TRUE;
11433+ }
11434+
11435+#if defined(ENABLE_PKCS11H_THREADING)
11436+ if (mutex_locked_sess) {
11437+ _pkcs11h_threading_mutexRelease (&certificate->session->mutex);
11438+ mutex_locked_sess = FALSE;
11439+ }
11440+#endif
11441+
11442+ if (rv != CKR_OK) {
11443+ PKCS11H_DEBUG (
11444+ PKCS11H_LOG_DEBUG1,
11445+ "PKCS#11: Cannot access existing object rv=%ld-'%s'",
11446+ rv,
11447+ pkcs11h_getMessage (rv)
11448+ );
11449+
11450+ /*
11451+ * Ignore error
11452+ */
11453+ rv = CKR_OK;
11454+ }
11455+ }
11456+
11457+ if (!validCert && rv == CKR_OK) {
11458+ if (
11459+ (rv = _pkcs11h_certificate_resetSession (
11460+ certificate,
11461+ TRUE,
11462+ FALSE
11463+ )) == CKR_OK
11464+ ) {
11465+ validCert = TRUE;
11466+ }
11467+ }
11468+
11469+#if defined(ENABLE_PKCS11H_THREADING)
11470+ if (mutex_locked_cert) {
11471+ _pkcs11h_threading_mutexRelease (&certificate->mutex);
11472+ mutex_locked_cert = FALSE;
11473+ }
11474+#endif
11475+
11476+ PKCS11H_DEBUG (
11477+ PKCS11H_LOG_DEBUG2,
11478+ "PKCS#11: pkcs11h_certificate_ensureCertificateAccess return rv=%ld-'%s'",
11479+ rv,
11480+ pkcs11h_getMessage (rv)
11481+ );
11482+
11483+ return rv;
11484+}
11485+
11486+CK_RV
11487+pkcs11h_certificate_ensureKeyAccess (
11488+ IN const pkcs11h_certificate_t certificate
11489+) {
11490+#if defined(ENABLE_PKCS11H_THREADING)
11491+ PKCS11H_BOOL mutex_locked_cert = FALSE;
11492+ PKCS11H_BOOL mutex_locked_sess = FALSE;
11493+#endif
11494+ CK_RV rv = CKR_OK;
11495+ PKCS11H_BOOL valid_key = FALSE;
11496+
11497+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
11498+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
11499+ PKCS11H_ASSERT (certificate!=NULL);
11500+
11501+ PKCS11H_DEBUG (
11502+ PKCS11H_LOG_DEBUG2,
11503+ "PKCS#11: pkcs11h_certificate_ensureKeyAccess entry certificate=%p",
11504+ (void *)certificate
11505+ );
11506+
11507+#if defined(ENABLE_PKCS11H_THREADING)
11508+ if (
11509+ rv == CKR_OK &&
11510+ (rv = _pkcs11h_threading_mutexLock (&certificate->mutex)) == CKR_OK
11511+ ) {
11512+ mutex_locked_cert = TRUE;
11513+ }
11514+#endif
11515+
11516+ if (!valid_key && rv == CKR_OK) {
11517+
11518+ if (certificate->session == NULL) {
11519+ rv = CKR_SESSION_HANDLE_INVALID;
11520+ }
11521+
11522+#if defined(ENABLE_PKCS11H_THREADING)
11523+ if (
11524+ rv == CKR_OK &&
11525+ (rv = _pkcs11h_threading_mutexLock (&certificate->session->mutex)) == CKR_OK
11526+ ) {
11527+ mutex_locked_sess = TRUE;
11528+ }
11529+#endif
11530+
11531+ if (
11532+ (rv = _pkcs11h_session_getObjectById (
11533+ certificate->session,
11534+ CKO_PRIVATE_KEY,
11535+ certificate->id->attrCKA_ID,
11536+ certificate->id->attrCKA_ID_size,
11537+ &certificate->key_handle
11538+ )) == CKR_OK
11539+ ) {
11540+ valid_key = TRUE;
11541+ }
11542+
11543+#if defined(ENABLE_PKCS11H_THREADING)
11544+ if (mutex_locked_sess) {
11545+ _pkcs11h_threading_mutexRelease (&certificate->session->mutex);
11546+ mutex_locked_sess = FALSE;
11547+ }
11548+#endif
11549+
11550+ if (rv != CKR_OK) {
11551+ PKCS11H_DEBUG (
11552+ PKCS11H_LOG_DEBUG1,
11553+ "PKCS#11: Cannot access existing object rv=%ld-'%s'",
11554+ rv,
11555+ pkcs11h_getMessage (rv)
11556+ );
11557+
11558+ /*
11559+ * Ignore error
11560+ */
11561+ rv = CKR_OK;
11562+ certificate->key_handle = PKCS11H_INVALID_OBJECT_HANDLE;
11563+ }
11564+ }
11565+
11566+ if (!valid_key && rv == CKR_OK) {
11567+ if (
11568+ (rv = _pkcs11h_certificate_resetSession (
11569+ certificate,
11570+ FALSE,
11571+ FALSE
11572+ )) == CKR_OK
11573+ ) {
11574+ valid_key = TRUE;
11575+ }
11576+ }
11577+
11578+#if defined(ENABLE_PKCS11H_THREADING)
11579+ if (mutex_locked_sess) {
11580+ _pkcs11h_threading_mutexRelease (&certificate->session->mutex);
11581+ mutex_locked_sess = FALSE;
11582+ }
11583+#endif
11584+
11585+ PKCS11H_DEBUG (
11586+ PKCS11H_LOG_DEBUG2,
11587+ "PKCS#11: pkcs11h_certificate_ensureKeyAccess return rv=%ld-'%s'",
11588+ rv,
11589+ pkcs11h_getMessage (rv)
11590+ );
11591+
11592+ return rv;
11593+}
11594+
11595+#endif /* ENABLE_PKCS11H_CERTIFICATE */
11596+
11597+#if defined(ENABLE_PKCS11H_LOCATE)
11598+/*======================================================================*
11599+ * LOCATE INTERFACE
11600+ *======================================================================*/
11601+
11602+#if defined(ENABLE_PKCS11H_TOKEN) || defined(ENABLE_PKCS11H_CERTIFICATE)
11603+
11604+static
11605+CK_RV
11606+_pkcs11h_locate_getTokenIdBySlotId (
11607+ IN const char * const slot,
11608+ OUT pkcs11h_token_id_t * const p_token_id
11609+) {
11610+ pkcs11h_provider_t current_provider = NULL;
11611+ char reference[sizeof (((pkcs11h_provider_t)NULL)->reference)];
11612+
11613+ CK_SLOT_ID selected_slot = PKCS11H_INVALID_SLOT_ID;
11614+ CK_TOKEN_INFO info;
11615+ CK_RV rv = CKR_OK;
11616+
11617+ PKCS11H_ASSERT (slot!=NULL);
11618+ PKCS11H_ASSERT (p_token_id!=NULL);
11619+
11620+ PKCS11H_DEBUG (
11621+ PKCS11H_LOG_DEBUG2,
11622+ "PKCS#11: _pkcs11h_locate_getTokenIdBySlotId entry slot='%s', p_token_id=%p",
11623+ slot,
11624+ (void *)p_token_id
11625+ );
11626+
11627+ *p_token_id = NULL;
11628+
11629+ if (rv == CKR_OK) {
11630+ if (strchr (slot, ':') == NULL) {
11631+ reference[0] = '\0';
11632+ selected_slot = atol (slot);
11633+ }
11634+ else {
11635+ char *p;
11636+
11637+ strncpy (reference, slot, sizeof (reference));
11638+ reference[sizeof (reference)-1] = '\0';
11639+
11640+ p = strchr (reference, ':');
11641+
11642+ *p = '\0';
11643+ p++;
11644+ selected_slot = atol (p);
11645+ }
11646+ }
11647+
11648+ if (rv == CKR_OK) {
11649+ current_provider=s_pkcs11h_data->providers;
11650+ while (
11651+ current_provider != NULL &&
11652+ reference[0] != '\0' && /* So first provider will be selected */
11653+ strcmp (current_provider->reference, reference)
11654+ ) {
11655+ current_provider = current_provider->next;
11656+ }
11657+
11658+ if (
11659+ current_provider == NULL ||
11660+ (
11661+ current_provider != NULL &&
11662+ !current_provider->enabled
11663+ )
11664+ ) {
11665+ rv = CKR_SLOT_ID_INVALID;
11666+ }
11667+ }
11668+
11669+ if (
11670+ rv == CKR_OK &&
11671+ (rv = current_provider->f->C_GetTokenInfo (selected_slot, &info)) == CKR_OK
11672+ ) {
11673+ rv = _pkcs11h_token_getTokenId (
11674+ &info,
11675+ p_token_id
11676+ );
11677+ }
11678+
11679+ PKCS11H_DEBUG (
11680+ PKCS11H_LOG_DEBUG2,
11681+ "PKCS#11: _pkcs11h_locate_getTokenIdBySlotId return rv=%ld-'%s', *p_token_id=%p",
11682+ rv,
11683+ pkcs11h_getMessage (rv),
11684+ (void *)*p_token_id
11685+ );
11686+
11687+ return rv;
11688+}
11689+
11690+static
11691+CK_RV
11692+_pkcs11h_locate_getTokenIdBySlotName (
11693+ IN const char * const name,
11694+ OUT pkcs11h_token_id_t * const p_token_id
11695+) {
11696+ pkcs11h_provider_t current_provider = NULL;
11697+
11698+ CK_SLOT_ID selected_slot = PKCS11H_INVALID_SLOT_ID;
11699+ CK_TOKEN_INFO info;
11700+ CK_RV rv = CKR_OK;
11701+
11702+ PKCS11H_BOOL found = FALSE;
11703+
11704+ PKCS11H_ASSERT (name!=NULL);
11705+ PKCS11H_ASSERT (p_token_id!=NULL);
11706+
11707+ PKCS11H_DEBUG (
11708+ PKCS11H_LOG_DEBUG2,
11709+ "PKCS#11: _pkcs11h_locate_getTokenIdBySlotName entry name='%s', p_token_id=%p",
11710+ name,
11711+ (void *)p_token_id
11712+ );
11713+
11714+ *p_token_id = NULL;
11715+
11716+ current_provider = s_pkcs11h_data->providers;
11717+ while (
11718+ current_provider != NULL &&
11719+ rv == CKR_OK &&
11720+ !found
11721+ ) {
11722+ CK_SLOT_ID_PTR slots = NULL;
11723+ CK_ULONG slotnum;
11724+ CK_SLOT_ID slot_index;
11725+
11726+ if (!current_provider->enabled) {
11727+ rv = CKR_CRYPTOKI_NOT_INITIALIZED;
11728+ }
11729+
11730+ if (rv == CKR_OK) {
11731+ rv = _pkcs11h_session_getSlotList (
11732+ current_provider,
11733+ CK_TRUE,
11734+ &slots,
11735+ &slotnum
11736+ );
11737+ }
11738+
11739+ for (
11740+ slot_index=0;
11741+ (
11742+ slot_index < slotnum &&
11743+ rv == CKR_OK &&
11744+ !found
11745+ );
11746+ slot_index++
11747+ ) {
11748+ CK_SLOT_INFO info;
11749+
11750+ if (
11751+ (rv = current_provider->f->C_GetSlotInfo (
11752+ slots[slot_index],
11753+ &info
11754+ )) == CKR_OK
11755+ ) {
11756+ char current_name[sizeof (info.slotDescription)+1];
11757+
11758+ _pkcs11h_util_fixupFixedString (
11759+ current_name,
11760+ (char *)info.slotDescription,
11761+ sizeof (info.slotDescription)
11762+ );
11763+
11764+ if (!strcmp (current_name, name)) {
11765+ found = TRUE;
11766+ selected_slot = slots[slot_index];
11767+ }
11768+ }
11769+
11770+ if (rv != CKR_OK) {
11771+ PKCS11H_DEBUG (
11772+ PKCS11H_LOG_DEBUG1,
11773+ "PKCS#11: Cannot get slot information for provider '%s' slot %ld rv=%ld-'%s'",
11774+ current_provider->manufacturerID,
11775+ slots[slot_index],
11776+ rv,
11777+ pkcs11h_getMessage (rv)
11778+ );
11779+
11780+ /*
11781+ * Ignore error
11782+ */
11783+ rv = CKR_OK;
11784+ }
11785+ }
11786+
11787+ if (rv != CKR_OK) {
11788+ PKCS11H_DEBUG (
11789+ PKCS11H_LOG_DEBUG1,
11790+ "PKCS#11: Cannot get slot list for provider '%s' rv=%ld-'%s'",
11791+ current_provider->manufacturerID,
11792+ rv,
11793+ pkcs11h_getMessage (rv)
11794+ );
11795+
11796+ /*
11797+ * Ignore error
11798+ */
11799+ rv = CKR_OK;
11800+ }
11801+
11802+ if (slots != NULL) {
11803+ _pkcs11h_mem_free ((void *)&slots);
11804+ slots = NULL;
11805+ }
11806+
11807+ if (!found) {
11808+ current_provider = current_provider->next;
11809+ }
11810+ }
11811+
11812+ if (rv == CKR_OK && !found) {
11813+ rv = CKR_SLOT_ID_INVALID;
11814+ }
11815+
11816+ if (
11817+ rv == CKR_OK &&
11818+ (rv = current_provider->f->C_GetTokenInfo (selected_slot, &info)) == CKR_OK
11819+ ) {
11820+ rv = _pkcs11h_token_getTokenId (
11821+ &info,
11822+ p_token_id
11823+ );
11824+ }
11825+
11826+ PKCS11H_DEBUG (
11827+ PKCS11H_LOG_DEBUG2,
11828+ "PKCS#11: _pkcs11h_locate_getTokenIdBySlotName return rv=%ld-'%s' *p_token_id=%p",
11829+ rv,
11830+ pkcs11h_getMessage (rv),
11831+ (void *)*p_token_id
11832+ );
11833+
11834+ return rv;
11835+}
11836+
11837+static
11838+CK_RV
11839+_pkcs11h_locate_getTokenIdByLabel (
11840+ IN const char * const label,
11841+ OUT pkcs11h_token_id_t * const p_token_id
11842+) {
11843+ pkcs11h_provider_t current_provider = NULL;
11844+
11845+ CK_SLOT_ID selected_slot = PKCS11H_INVALID_SLOT_ID;
11846+ CK_TOKEN_INFO info;
11847+ CK_RV rv = CKR_OK;
11848+
11849+ PKCS11H_BOOL found = FALSE;
11850+
11851+ PKCS11H_ASSERT (label!=NULL);
11852+ PKCS11H_ASSERT (p_token_id!=NULL);
11853+
11854+ PKCS11H_DEBUG (
11855+ PKCS11H_LOG_DEBUG2,
11856+ "PKCS#11: _pkcs11h_locate_getTokenIdByLabel entry label='%s', p_token_id=%p",
11857+ label,
11858+ (void *)p_token_id
11859+ );
11860+
11861+ *p_token_id = NULL;
11862+
11863+ current_provider = s_pkcs11h_data->providers;
11864+ while (
11865+ current_provider != NULL &&
11866+ rv == CKR_OK &&
11867+ !found
11868+ ) {
11869+ CK_SLOT_ID_PTR slots = NULL;
11870+ CK_ULONG slotnum;
11871+ CK_SLOT_ID slot_index;
11872+
11873+ if (!current_provider->enabled) {
11874+ rv = CKR_CRYPTOKI_NOT_INITIALIZED;
11875+ }
11876+
11877+ if (rv == CKR_OK) {
11878+ rv = _pkcs11h_session_getSlotList (
11879+ current_provider,
11880+ CK_TRUE,
11881+ &slots,
11882+ &slotnum
11883+ );
11884+ }
11885+
11886+ for (
11887+ slot_index=0;
11888+ (
11889+ slot_index < slotnum &&
11890+ rv == CKR_OK &&
11891+ !found
11892+ );
11893+ slot_index++
11894+ ) {
11895+ CK_TOKEN_INFO info;
11896+
11897+ if (rv == CKR_OK) {
11898+ rv = current_provider->f->C_GetTokenInfo (
11899+ slots[slot_index],
11900+ &info
11901+ );
11902+ }
11903+
11904+ if (rv == CKR_OK) {
11905+ char current_label[sizeof (info.label)+1];
11906+
11907+ _pkcs11h_util_fixupFixedString (
11908+ current_label,
11909+ (char *)info.label,
11910+ sizeof (info.label)
11911+ );
11912+
11913+ if (!strcmp (current_label, label)) {
11914+ found = TRUE;
11915+ selected_slot = slots[slot_index];
11916+ }
11917+ }
11918+
11919+ if (rv != CKR_OK) {
11920+ PKCS11H_DEBUG (
11921+ PKCS11H_LOG_DEBUG1,
11922+ "PKCS#11: Cannot get token information for provider '%s' slot %ld rv=%ld-'%s'",
11923+ current_provider->manufacturerID,
11924+ slots[slot_index],
11925+ rv,
11926+ pkcs11h_getMessage (rv)
11927+ );
11928+
11929+ /*
11930+ * Ignore error
11931+ */
11932+ rv = CKR_OK;
11933+ }
11934+ }
11935+
11936+ if (rv != CKR_OK) {
11937+ PKCS11H_DEBUG (
11938+ PKCS11H_LOG_DEBUG1,
11939+ "PKCS#11: Cannot get slot list for provider '%s' rv=%ld-'%s'",
11940+ current_provider->manufacturerID,
11941+ rv,
11942+ pkcs11h_getMessage (rv)
11943+ );
11944+
11945+ /*
11946+ * Ignore error
11947+ */
11948+ rv = CKR_OK;
11949+ }
11950+
11951+ if (slots != NULL) {
11952+ _pkcs11h_mem_free ((void *)&slots);
11953+ slots = NULL;
11954+ }
11955+
11956+ if (!found) {
11957+ current_provider = current_provider->next;
11958+ }
11959+ }
11960+
11961+ if (rv == CKR_OK && !found) {
11962+ rv = CKR_SLOT_ID_INVALID;
11963+ }
11964+
11965+ if (
11966+ rv == CKR_OK &&
11967+ (rv = current_provider->f->C_GetTokenInfo (selected_slot, &info)) == CKR_OK
11968+ ) {
11969+ rv = _pkcs11h_token_getTokenId (
11970+ &info,
11971+ p_token_id
11972+ );
11973+ }
11974+
11975+ PKCS11H_DEBUG (
11976+ PKCS11H_LOG_DEBUG2,
11977+ "PKCS#11: _pkcs11h_locate_getTokenIdByLabel return rv=%ld-'%s', *p_token_id=%p",
11978+ rv,
11979+ pkcs11h_getMessage (rv),
11980+ (void *)*p_token_id
11981+ );
11982+
11983+ return rv;
11984+}
11985+
11986+CK_RV
11987+pkcs11h_locate_token (
11988+ IN const char * const slot_type,
11989+ IN const char * const slot,
11990+ IN void * const user_data,
11991+ IN const unsigned mask_prompt,
11992+ OUT pkcs11h_token_id_t * const p_token_id
11993+) {
11994+#if defined(ENABLE_PKCS11H_THREADING)
11995+ PKCS11H_BOOL mutex_locked = FALSE;
11996+#endif
11997+
11998+ pkcs11h_token_id_t dummy_token_id = NULL;
11999+ pkcs11h_token_id_t token_id = NULL;
12000+ PKCS11H_BOOL found = FALSE;
12001+
12002+ CK_RV rv = CKR_OK;
12003+
12004+ unsigned nRetry = 0;
12005+
12006+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
12007+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
12008+ PKCS11H_ASSERT (slot_type!=NULL);
12009+ PKCS11H_ASSERT (slot!=NULL);
12010+ /*PKCS11H_ASSERT (user_data) NOT NEEDED */
12011+ PKCS11H_ASSERT (p_token_id!=NULL);
12012+
12013+ PKCS11H_DEBUG (
12014+ PKCS11H_LOG_DEBUG2,
12015+ "PKCS#11: pkcs11h_locate_token entry slot_type='%s', slot='%s', user_data=%p, p_token_id=%p",
12016+ slot_type,
12017+ slot,
12018+ user_data,
12019+ (void *)p_token_id
12020+ );
12021+
12022+ *p_token_id = NULL;
12023+
12024+#if defined(ENABLE_PKCS11H_THREADING)
12025+ if (
12026+ rv == CKR_OK &&
12027+ (rv = _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.global)) == CKR_OK
12028+ ) {
12029+ mutex_locked = TRUE;
12030+ }
12031+#endif
12032+
12033+ if (
12034+ rv == CKR_OK &&
12035+ (rv = _pkcs11h_token_newTokenId (&dummy_token_id)) == CKR_OK
12036+ ) {
12037+ /*
12038+ * Temperary slot id
12039+ */
12040+ strcpy (dummy_token_id->display, "SLOT(");
12041+ strncat (dummy_token_id->display, slot_type, sizeof (dummy_token_id->display)-1-strlen (dummy_token_id->display));
12042+ strncat (dummy_token_id->display, "=", sizeof (dummy_token_id->display)-1-strlen (dummy_token_id->display));
12043+ strncat (dummy_token_id->display, slot, sizeof (dummy_token_id->display)-1-strlen (dummy_token_id->display));
12044+ strncat (dummy_token_id->display, ")", sizeof (dummy_token_id->display)-1-strlen (dummy_token_id->display));
12045+ dummy_token_id->display[sizeof (dummy_token_id->display)-1] = 0;
12046+ }
12047+
12048+ while (rv == CKR_OK && !found) {
12049+ if (!strcmp (slot_type, "id")) {
12050+ rv = _pkcs11h_locate_getTokenIdBySlotId (
12051+ slot,
12052+ &token_id
12053+ );
12054+ }
12055+ else if (!strcmp (slot_type, "name")) {
12056+ rv = _pkcs11h_locate_getTokenIdBySlotName (
12057+ slot,
12058+ &token_id
12059+ );
12060+ }
12061+ else if (!strcmp (slot_type, "label")) {
12062+ rv = _pkcs11h_locate_getTokenIdByLabel (
12063+ slot,
12064+ &token_id
12065+ );
12066+ }
12067+ else {
12068+ rv = CKR_ARGUMENTS_BAD;
12069+ }
12070+
12071+ if (rv == CKR_OK) {
12072+ found = TRUE;
12073+ }
12074+
12075+ /*
12076+ * Ignore error, since we have what we
12077+ * want in found.
12078+ */
12079+ if (rv != CKR_OK && rv != CKR_ARGUMENTS_BAD) {
12080+ PKCS11H_DEBUG (
12081+ PKCS11H_LOG_DEBUG1,
12082+ "PKCS#11: pkcs11h_locate_token failed rv=%ld-'%s'",
12083+ rv,
12084+ pkcs11h_getMessage (rv)
12085+ );
12086+
12087+ rv = CKR_OK;
12088+ }
12089+
12090+ if (rv == CKR_OK && !found && (mask_prompt & PKCS11H_PROMPT_MAST_ALLOW_CARD_PROMPT) == 0) {
12091+ rv = CKR_TOKEN_NOT_PRESENT;
12092+ }
12093+
12094+ if (rv == CKR_OK && !found) {
12095+
12096+ PKCS11H_DEBUG (
12097+ PKCS11H_LOG_DEBUG1,
12098+ "PKCS#11: Calling token_prompt hook for '%s'",
12099+ dummy_token_id->display
12100+ );
12101+
12102+ if (
12103+ !s_pkcs11h_data->hooks.token_prompt (
12104+ s_pkcs11h_data->hooks.token_prompt_data,
12105+ user_data,
12106+ dummy_token_id,
12107+ nRetry++
12108+ )
12109+ ) {
12110+ rv = CKR_CANCEL;
12111+ }
12112+
12113+ PKCS11H_DEBUG (
12114+ PKCS11H_LOG_DEBUG1,
12115+ "PKCS#11: token_prompt returned %ld",
12116+ rv
12117+ );
12118+ }
12119+ }
12120+
12121+ if (rv == CKR_OK && !found) {
12122+ rv = CKR_SLOT_ID_INVALID;
12123+ }
12124+
12125+ if (rv == CKR_OK) {
12126+ *p_token_id = token_id;
12127+ token_id = NULL;
12128+ }
12129+
12130+ if (dummy_token_id != NULL) {
12131+ pkcs11h_token_freeTokenId (dummy_token_id);
12132+ dummy_token_id = NULL;
12133+ }
12134+
12135+#if defined(ENABLE_PKCS11H_THREADING)
12136+ if (mutex_locked) {
12137+ _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.global);
12138+ mutex_locked = FALSE;
12139+ }
12140+#endif
12141+
12142+ PKCS11H_DEBUG (
12143+ PKCS11H_LOG_DEBUG2,
12144+ "PKCS#11: pkcs11h_locate_token return rv=%ld-'%s', *p_token_id=%p",
12145+ rv,
12146+ pkcs11h_getMessage (rv),
12147+ (void *)*p_token_id
12148+ );
12149+
12150+ return rv;
12151+}
12152+
12153+#endif /* ENABLE_PKCS11H_TOKEN || ENABLE_PKCS11H_CERTIFICATE */
12154+
12155+#if defined(ENABLE_PKCS11H_CERTIFICATE)
12156+
12157+static
12158+CK_RV
12159+_pkcs11h_locate_getCertificateIdByLabel (
12160+ IN const pkcs11h_session_t session,
12161+ IN OUT const pkcs11h_certificate_id_t certificate_id,
12162+ IN const char * const label
12163+) {
12164+#if defined(ENABLE_PKCS11H_THREADING)
12165+ PKCS11H_BOOL mutex_locked = FALSE;
12166+#endif
12167+ CK_OBJECT_CLASS cert_filter_class = CKO_CERTIFICATE;
12168+ CK_ATTRIBUTE cert_filter[] = {
12169+ {CKA_CLASS, &cert_filter_class, sizeof (cert_filter_class)},
12170+ {CKA_LABEL, (CK_BYTE_PTR)label, strlen (label)}
12171+ };
12172+
12173+ CK_OBJECT_HANDLE *objects = NULL;
12174+ CK_ULONG objects_found = 0;
12175+ CK_RV rv = CKR_OK;
12176+
12177+ CK_ULONG i;
12178+
12179+ PKCS11H_ASSERT (session!=NULL);
12180+ PKCS11H_ASSERT (certificate_id!=NULL);
12181+ PKCS11H_ASSERT (label!=NULL);
12182+
12183+ PKCS11H_DEBUG (
12184+ PKCS11H_LOG_DEBUG2,
12185+ "PKCS#11: _pkcs11h_locate_getCertificateIdByLabel entry session=%p, certificate_id=%p, label='%s'",
12186+ (void *)session,
12187+ (void *)certificate_id,
12188+ label
12189+ );
12190+
12191+#if defined(ENABLE_PKCS11H_THREADING)
12192+ if (
12193+ rv == CKR_OK &&
12194+ (rv = _pkcs11h_threading_mutexLock (&session->mutex)) == CKR_OK
12195+ ) {
12196+ mutex_locked = TRUE;
12197+ }
12198+#endif
12199+
12200+ if (rv == CKR_OK) {
12201+ rv = _pkcs11h_session_validate (session);
12202+ }
12203+
12204+ if (rv == CKR_OK) {
12205+ rv = _pkcs11h_session_findObjects (
12206+ session,
12207+ cert_filter,
12208+ sizeof (cert_filter) / sizeof (CK_ATTRIBUTE),
12209+ &objects,
12210+ &objects_found
12211+ );
12212+ }
12213+
12214+ for (i=0;rv == CKR_OK && i < objects_found;i++) {
12215+ CK_ATTRIBUTE attrs[] = {
12216+ {CKA_ID, NULL, 0},
12217+ {CKA_VALUE, NULL, 0}
12218+ };
12219+
12220+ if (rv == CKR_OK) {
12221+ rv = _pkcs11h_session_getObjectAttributes (
12222+ session,
12223+ objects[i],
12224+ attrs,
12225+ sizeof (attrs) / sizeof (CK_ATTRIBUTE)
12226+ );
12227+ }
12228+
12229+ if (
12230+ rv == CKR_OK &&
12231+ _pkcs11h_certificate_isBetterCertificate (
12232+ certificate_id->certificate_blob,
12233+ certificate_id->certificate_blob_size,
12234+ attrs[1].pValue,
12235+ attrs[1].ulValueLen
12236+ )
12237+ ) {
12238+ if (certificate_id->attrCKA_ID != NULL) {
12239+ _pkcs11h_mem_free ((void *)&certificate_id->attrCKA_ID);
12240+ }
12241+ if (certificate_id->certificate_blob != NULL) {
12242+ _pkcs11h_mem_free ((void *)&certificate_id->certificate_blob);
12243+ }
12244+ rv = _pkcs11h_mem_duplicate (
12245+ (void *)&certificate_id->attrCKA_ID,
12246+ &certificate_id->attrCKA_ID_size,
12247+ attrs[0].pValue,
12248+ attrs[0].ulValueLen
12249+ );
12250+ rv = _pkcs11h_mem_duplicate (
12251+ (void *)&certificate_id->certificate_blob,
12252+ &certificate_id->certificate_blob_size,
12253+ attrs[1].pValue,
12254+ attrs[1].ulValueLen
12255+ );
12256+ }
12257+
12258+ if (rv != CKR_OK) {
12259+ PKCS11H_DEBUG (
12260+ PKCS11H_LOG_DEBUG1,
12261+ "PKCS#11: Cannot get object attribute for provider '%s' object %ld rv=%ld-'%s'",
12262+ session->provider->manufacturerID,
12263+ objects[i],
12264+ rv,
12265+ pkcs11h_getMessage (rv)
12266+ );
12267+
12268+ /*
12269+ * Ignore error
12270+ */
12271+ rv = CKR_OK;
12272+ }
12273+
12274+ _pkcs11h_session_freeObjectAttributes (
12275+ attrs,
12276+ sizeof (attrs) / sizeof (CK_ATTRIBUTE)
12277+ );
12278+ }
12279+
12280+ if (
12281+ rv == CKR_OK &&
12282+ certificate_id->certificate_blob == NULL
12283+ ) {
12284+ rv = CKR_ATTRIBUTE_VALUE_INVALID;
12285+ }
12286+
12287+ if (objects != NULL) {
12288+ _pkcs11h_mem_free ((void *)&objects);
12289+ }
12290+
12291+#if defined(ENABLE_PKCS11H_THREADING)
12292+ if (mutex_locked) {
12293+ _pkcs11h_threading_mutexRelease (&session->mutex);
12294+ mutex_locked = FALSE;
12295+ }
12296+#endif
12297+
12298+ /*
12299+ * No need to free allocated objects
12300+ * on error, since the certificate_id
12301+ * should be free by caller.
12302+ */
12303+
12304+ PKCS11H_DEBUG (
12305+ PKCS11H_LOG_DEBUG2,
12306+ "PKCS#11: _pkcs11h_locate_getCertificateIdByLabel return rv=%ld-'%s'",
12307+ rv,
12308+ pkcs11h_getMessage (rv)
12309+ );
12310+
12311+ return rv;
12312+}
12313+
12314+static
12315+CK_RV
12316+_pkcs11h_locate_getCertificateIdBySubject (
12317+ IN const pkcs11h_session_t session,
12318+ IN OUT const pkcs11h_certificate_id_t certificate_id,
12319+ IN const char * const subject
12320+) {
12321+#if defined(ENABLE_PKCS11H_THREADING)
12322+ PKCS11H_BOOL mutex_locked = FALSE;
12323+#endif
12324+ CK_OBJECT_CLASS cert_filter_class = CKO_CERTIFICATE;
12325+ CK_ATTRIBUTE cert_filter[] = {
12326+ {CKA_CLASS, &cert_filter_class, sizeof (cert_filter_class)}
12327+ };
12328+
12329+ CK_OBJECT_HANDLE *objects = NULL;
12330+ CK_ULONG objects_found = 0;
12331+ CK_RV rv = CKR_OK;
12332+
12333+ CK_ULONG i;
12334+
12335+ PKCS11H_ASSERT (session!=NULL);
12336+ PKCS11H_ASSERT (certificate_id!=NULL);
12337+ PKCS11H_ASSERT (subject!=NULL);
12338+
12339+ PKCS11H_DEBUG (
12340+ PKCS11H_LOG_DEBUG2,
12341+ "PKCS#11: _pkcs11h_locate_getCertificateIdBySubject entry session=%p, certificate_id=%p, subject='%s'",
12342+ (void *)session,
12343+ (void *)certificate_id,
12344+ subject
12345+ );
12346+
12347+#if defined(ENABLE_PKCS11H_THREADING)
12348+ if (
12349+ rv == CKR_OK &&
12350+ (rv = _pkcs11h_threading_mutexLock (&session->mutex)) == CKR_OK
12351+ ) {
12352+ mutex_locked = TRUE;
12353+ }
12354+#endif
12355+
12356+ if (rv == CKR_OK) {
12357+ rv = _pkcs11h_session_validate (session);
12358+ }
12359+
12360+ if (rv == CKR_OK) {
12361+ rv = _pkcs11h_session_findObjects (
12362+ session,
12363+ cert_filter,
12364+ sizeof (cert_filter) / sizeof (CK_ATTRIBUTE),
12365+ &objects,
12366+ &objects_found
12367+ );
12368+ }
12369+
12370+#if defined(ENABLE_PKCS11H_THREADING)
12371+ if (mutex_locked) {
12372+ _pkcs11h_threading_mutexRelease (&session->mutex);
12373+ mutex_locked = FALSE;
12374+ }
12375+#endif
12376+
12377+ for (i=0;rv == CKR_OK && i < objects_found;i++) {
12378+ CK_ATTRIBUTE attrs[] = {
12379+ {CKA_ID, NULL, 0},
12380+ {CKA_VALUE, NULL, 0}
12381+ };
12382+ char current_subject[1024];
12383+ current_subject[0] = '\0';
12384+
12385+ if (rv == CKR_OK) {
12386+ rv = _pkcs11h_session_getObjectAttributes (
12387+ session,
12388+ objects[i],
12389+ attrs,
12390+ sizeof (attrs) / sizeof (CK_ATTRIBUTE)
12391+ );
12392+ }
12393+
12394+ if (rv == CKR_OK) {
12395+ rv = _pkcs11h_certificate_getDN (
12396+ attrs[1].pValue,
12397+ attrs[1].ulValueLen,
12398+ current_subject,
12399+ sizeof (current_subject)
12400+ );
12401+ }
12402+
12403+ if (
12404+ rv == CKR_OK &&
12405+ !strcmp (subject, current_subject) &&
12406+ _pkcs11h_certificate_isBetterCertificate (
12407+ certificate_id->certificate_blob,
12408+ certificate_id->certificate_blob_size,
12409+ attrs[1].pValue,
12410+ attrs[1].ulValueLen
12411+ )
12412+ ) {
12413+ if (certificate_id->attrCKA_ID != NULL) {
12414+ _pkcs11h_mem_free ((void *)&certificate_id->attrCKA_ID);
12415+ }
12416+ if (certificate_id->certificate_blob != NULL) {
12417+ _pkcs11h_mem_free ((void *)&certificate_id->certificate_blob);
12418+ }
12419+ rv = _pkcs11h_mem_duplicate (
12420+ (void *)&certificate_id->attrCKA_ID,
12421+ &certificate_id->attrCKA_ID_size,
12422+ attrs[0].pValue,
12423+ attrs[0].ulValueLen
12424+ );
12425+ rv = _pkcs11h_mem_duplicate (
12426+ (void *)&certificate_id->certificate_blob,
12427+ &certificate_id->certificate_blob_size,
12428+ attrs[1].pValue,
12429+ attrs[1].ulValueLen
12430+ );
12431+ }
12432+
12433+ if (rv != CKR_OK) {
12434+ PKCS11H_DEBUG (
12435+ PKCS11H_LOG_DEBUG1,
12436+ "PKCS#11: Cannot get object attribute for provider '%s' object %ld rv=%ld-'%s'",
12437+ session->provider->manufacturerID,
12438+ objects[i],
12439+ rv,
12440+ pkcs11h_getMessage (rv)
12441+ );
12442+
12443+ /*
12444+ * Ignore error
12445+ */
12446+ rv = CKR_OK;
12447+ }
12448+
12449+ _pkcs11h_session_freeObjectAttributes (
12450+ attrs,
12451+ sizeof (attrs) / sizeof (CK_ATTRIBUTE)
12452+ );
12453+ }
12454+
12455+ if (
12456+ rv == CKR_OK &&
12457+ certificate_id->certificate_blob == NULL
12458+ ) {
12459+ rv = CKR_ATTRIBUTE_VALUE_INVALID;
12460+ }
12461+
12462+ if (objects != NULL) {
12463+ _pkcs11h_mem_free ((void *)&objects);
12464+ }
12465+
12466+ /*
12467+ * No need to free allocated objects
12468+ * on error, since the certificate_id
12469+ * should be free by caller.
12470+ */
12471+
12472+ PKCS11H_DEBUG (
12473+ PKCS11H_LOG_DEBUG2,
12474+ "PKCS#11: _pkcs11h_locate_getCertificateIdBySubject return rv=%ld-'%s'",
12475+ rv,
12476+ pkcs11h_getMessage (rv)
12477+ );
12478+
12479+ return rv;
12480+}
12481+
12482+CK_RV
12483+pkcs11h_locate_certificate (
12484+ IN const char * const slot_type,
12485+ IN const char * const slot,
12486+ IN const char * const id_type,
12487+ IN const char * const id,
12488+ IN void * const user_data,
12489+ IN const unsigned mask_prompt,
12490+ OUT pkcs11h_certificate_id_t * const p_certificate_id
12491+) {
12492+#if defined(ENABLE_PKCS11H_THREADING)
12493+ PKCS11H_BOOL mutex_locked = FALSE;
12494+#endif
12495+ pkcs11h_certificate_id_t certificate_id = NULL;
12496+ pkcs11h_session_t session = NULL;
12497+ PKCS11H_BOOL op_succeed = FALSE;
12498+ PKCS11H_BOOL login_retry = FALSE;
12499+
12500+ CK_RV rv = CKR_OK;
12501+
12502+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
12503+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
12504+ PKCS11H_ASSERT (slot_type!=NULL);
12505+ PKCS11H_ASSERT (slot!=NULL);
12506+ PKCS11H_ASSERT (id_type!=NULL);
12507+ PKCS11H_ASSERT (id!=NULL);
12508+ /*PKCS11H_ASSERT (user_data) NOT NEEDED */
12509+ PKCS11H_ASSERT (p_certificate_id!=NULL);
12510+
12511+ PKCS11H_DEBUG (
12512+ PKCS11H_LOG_DEBUG2,
12513+ "PKCS#11: pkcs11h_locateCertificate entry slot_type='%s', slot='%s', id_type='%s', id='%s', user_data=%p, mask_prompt=%08x, p_certificate_id=%p",
12514+ slot_type,
12515+ slot,
12516+ id_type,
12517+ id,
12518+ user_data,
12519+ mask_prompt,
12520+ (void *)p_certificate_id
12521+ );
12522+
12523+ *p_certificate_id = NULL;
12524+
12525+ if (rv == CKR_OK) {
12526+ rv = _pkcs11h_certificate_newCertificateId (&certificate_id);
12527+ }
12528+
12529+ if (rv == CKR_OK) {
12530+ rv = pkcs11h_locate_token (
12531+ slot_type,
12532+ slot,
12533+ user_data,
12534+ mask_prompt,
12535+ &certificate_id->token_id
12536+ );
12537+ }
12538+
12539+ if (rv == CKR_OK) {
12540+ rv = _pkcs11h_session_getSessionByTokenId (
12541+ certificate_id->token_id,
12542+ &session
12543+ );
12544+ }
12545+
12546+#if defined(ENABLE_PKCS11H_THREADING)
12547+ if (
12548+ rv == CKR_OK &&
12549+ (rv = _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.global)) == CKR_OK
12550+ ) {
12551+ mutex_locked = TRUE;
12552+ }
12553+#endif
12554+
12555+ while (rv == CKR_OK && !op_succeed) {
12556+ if (!strcmp (id_type, "id")) {
12557+ certificate_id->attrCKA_ID_size = strlen (id)/2;
12558+
12559+ if (certificate_id->attrCKA_ID_size == 0) {
12560+ rv = CKR_FUNCTION_FAILED;
12561+ }
12562+
12563+ if (
12564+ rv == CKR_OK &&
12565+ (rv = _pkcs11h_mem_malloc (
12566+ (void*)&certificate_id->attrCKA_ID,
12567+ certificate_id->attrCKA_ID_size
12568+ )) == CKR_OK
12569+ ) {
12570+ _pkcs11h_util_hexToBinary (
12571+ certificate_id->attrCKA_ID,
12572+ id,
12573+ &certificate_id->attrCKA_ID_size
12574+ );
12575+ }
12576+ }
12577+ else if (!strcmp (id_type, "label")) {
12578+ rv = _pkcs11h_locate_getCertificateIdByLabel (
12579+ session,
12580+ certificate_id,
12581+ id
12582+ );
12583+ }
12584+ else if (!strcmp (id_type, "subject")) {
12585+ rv = _pkcs11h_locate_getCertificateIdBySubject (
12586+ session,
12587+ certificate_id,
12588+ id
12589+ );
12590+ }
12591+ else {
12592+ rv = CKR_ARGUMENTS_BAD;
12593+ }
12594+
12595+ if (rv == CKR_OK) {
12596+ op_succeed = TRUE;
12597+ }
12598+ else {
12599+ if (!login_retry) {
12600+ PKCS11H_DEBUG (
12601+ PKCS11H_LOG_DEBUG1,
12602+ "PKCS#11: Get certificate failed: %ld:'%s'",
12603+ rv,
12604+ pkcs11h_getMessage (rv)
12605+ );
12606+
12607+ rv = _pkcs11h_session_login (
12608+ session,
12609+ TRUE,
12610+ TRUE,
12611+ user_data,
12612+ mask_prompt
12613+ );
12614+
12615+ login_retry = TRUE;
12616+ }
12617+ }
12618+ }
12619+
12620+#if defined(ENABLE_PKCS11H_THREADING)
12621+ if (mutex_locked) {
12622+ _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.global);
12623+ mutex_locked = FALSE;
12624+ }
12625+#endif
12626+
12627+ if (rv == CKR_OK) {
12628+ *p_certificate_id = certificate_id;
12629+ certificate_id = NULL;
12630+ }
12631+
12632+ if (certificate_id != NULL) {
12633+ pkcs11h_certificate_freeCertificateId (certificate_id);
12634+ certificate_id = NULL;
12635+ }
12636+
12637+ if (session != NULL) {
12638+ _pkcs11h_session_release (session);
12639+ session = NULL;
12640+ }
12641+
12642+ PKCS11H_DEBUG (
12643+ PKCS11H_LOG_DEBUG2,
12644+ "PKCS#11: pkcs11h_locateCertificate return rv=%ld-'%s' *p_certificate_id=%p",
12645+ rv,
12646+ pkcs11h_getMessage (rv),
12647+ (void *)*p_certificate_id
12648+ );
12649+
12650+ return rv;
12651+}
12652+
12653+#endif /* ENABLE_PKCS11H_CERTIFICATE */
12654+
12655+#endif /* ENABLE_PKCS11H_LOCATE */
12656+
12657+#if defined(ENABLE_PKCS11H_ENUM)
12658+/*======================================================================*
12659+ * ENUM INTERFACE
12660+ *======================================================================*/
12661+
12662+#if defined(ENABLE_PKCS11H_TOKEN)
12663+
12664+CK_RV
12665+pkcs11h_token_freeTokenIdList (
12666+ IN const pkcs11h_token_id_list_t token_id_list
12667+) {
12668+ pkcs11h_token_id_list_t _id = token_id_list;
12669+
12670+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
12671+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
12672+ /*PKCS11H_ASSERT (token_id_list!=NULL); NOT NEEDED*/
12673+
12674+ PKCS11H_DEBUG (
12675+ PKCS11H_LOG_DEBUG2,
12676+ "PKCS#11: pkcs11h_token_freeTokenIdList entry token_id_list=%p",
12677+ (void *)token_id_list
12678+ );
12679+
12680+ while (_id != NULL) {
12681+ pkcs11h_token_id_list_t x = _id;
12682+ _id = _id->next;
12683+ if (x->token_id != NULL) {
12684+ pkcs11h_token_freeTokenId (x->token_id);
12685+ }
12686+ x->next = NULL;
12687+ _pkcs11h_mem_free ((void *)&x);
12688+ }
12689+
12690+ PKCS11H_DEBUG (
12691+ PKCS11H_LOG_DEBUG2,
12692+ "PKCS#11: pkcs11h_token_freeTokenIdList return"
12693+ );
12694+
12695+ return CKR_OK;
12696+}
12697+
12698+CK_RV
12699+pkcs11h_token_enumTokenIds (
12700+ IN const int method,
12701+ OUT pkcs11h_token_id_list_t * const p_token_id_list
12702+) {
12703+#if defined(ENABLE_PKCS11H_THREADING)
12704+ PKCS11H_BOOL mutex_locked = FALSE;
12705+#endif
12706+
12707+ pkcs11h_token_id_list_t token_id_list = NULL;
12708+ pkcs11h_provider_t current_provider;
12709+ CK_RV rv = CKR_OK;
12710+
12711+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
12712+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
12713+ PKCS11H_ASSERT (p_token_id_list!=NULL);
12714+
12715+ PKCS11H_DEBUG (
12716+ PKCS11H_LOG_DEBUG2,
12717+ "PKCS#11: pkcs11h_token_enumTokenIds entry p_token_id_list=%p",
12718+ (void *)p_token_id_list
12719+ );
12720+
12721+ *p_token_id_list = NULL;
12722+
12723+#if defined(ENABLE_PKCS11H_THREADING)
12724+ if (
12725+ rv == CKR_OK &&
12726+ (rv = _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.global)) == CKR_OK
12727+ ) {
12728+ mutex_locked = TRUE;
12729+ }
12730+#endif
12731+
12732+ for (
12733+ current_provider = s_pkcs11h_data->providers;
12734+ (
12735+ current_provider != NULL &&
12736+ rv == CKR_OK
12737+ );
12738+ current_provider = current_provider->next
12739+ ) {
12740+ CK_SLOT_ID_PTR slots = NULL;
12741+ CK_ULONG slotnum;
12742+ CK_SLOT_ID slot_index;
12743+
12744+ if (!current_provider->enabled) {
12745+ rv = CKR_CRYPTOKI_NOT_INITIALIZED;
12746+ }
12747+
12748+ if (rv == CKR_OK) {
12749+ rv = _pkcs11h_session_getSlotList (
12750+ current_provider,
12751+ CK_TRUE,
12752+ &slots,
12753+ &slotnum
12754+ );
12755+ }
12756+
12757+ for (
12758+ slot_index=0;
12759+ (
12760+ slot_index < slotnum &&
12761+ rv == CKR_OK
12762+ );
12763+ slot_index++
12764+ ) {
12765+ pkcs11h_token_id_list_t entry = NULL;
12766+ CK_TOKEN_INFO info;
12767+
12768+ if (rv == CKR_OK) {
12769+ rv = _pkcs11h_mem_malloc ((void *)&entry, sizeof (struct pkcs11h_token_id_list_s));
12770+ }
12771+
12772+ if (rv == CKR_OK) {
12773+ rv = current_provider->f->C_GetTokenInfo (
12774+ slots[slot_index],
12775+ &info
12776+ );
12777+ }
12778+
12779+ if (rv == CKR_OK) {
12780+ rv = _pkcs11h_token_getTokenId (
12781+ &info,
12782+ &entry->token_id
12783+ );
12784+ }
12785+
12786+ if (rv == CKR_OK) {
12787+ entry->next = token_id_list;
12788+ token_id_list = entry;
12789+ entry = NULL;
12790+ }
12791+
12792+ if (entry != NULL) {
12793+ pkcs11h_token_freeTokenIdList (entry);
12794+ entry = NULL;
12795+ }
12796+ }
12797+
12798+ if (rv != CKR_OK) {
12799+ PKCS11H_DEBUG (
12800+ PKCS11H_LOG_DEBUG1,
12801+ "PKCS#11: Cannot get slot list for provider '%s' rv=%ld-'%s'",
12802+ current_provider->manufacturerID,
12803+ rv,
12804+ pkcs11h_getMessage (rv)
12805+ );
12806+
12807+ /*
12808+ * Ignore error
12809+ */
12810+ rv = CKR_OK;
12811+ }
12812+
12813+ if (slots != NULL) {
12814+ _pkcs11h_mem_free ((void *)&slots);
12815+ slots = NULL;
12816+ }
12817+ }
12818+
12819+ if (rv == CKR_OK && method == PKCS11H_ENUM_METHOD_CACHE) {
12820+ pkcs11h_session_t session = NULL;
12821+
12822+ for (
12823+ session = s_pkcs11h_data->sessions;
12824+ session != NULL && rv == CKR_OK;
12825+ session = session->next
12826+ ) {
12827+ pkcs11h_token_id_list_t entry = NULL;
12828+ PKCS11H_BOOL found = FALSE;
12829+
12830+ for (
12831+ entry = token_id_list;
12832+ entry != NULL && !found;
12833+ entry = entry->next
12834+ ) {
12835+ if (
12836+ pkcs11h_token_sameTokenId (
12837+ session->token_id,
12838+ entry->token_id
12839+ )
12840+ ) {
12841+ found = TRUE;
12842+ }
12843+ }
12844+
12845+ if (!found) {
12846+ entry = NULL;
12847+
12848+ if (rv == CKR_OK) {
12849+ rv = _pkcs11h_mem_malloc (
12850+ (void *)&entry,
12851+ sizeof (struct pkcs11h_token_id_list_s)
12852+ );
12853+ }
12854+
12855+ if (rv == CKR_OK) {
12856+ rv = pkcs11h_token_duplicateTokenId (
12857+ &entry->token_id,
12858+ session->token_id
12859+ );
12860+ }
12861+
12862+ if (rv == CKR_OK) {
12863+ entry->next = token_id_list;
12864+ token_id_list = entry;
12865+ entry = NULL;
12866+ }
12867+
12868+ if (entry != NULL) {
12869+ if (entry->token_id != NULL) {
12870+ pkcs11h_token_freeTokenId (entry->token_id);
12871+ }
12872+ _pkcs11h_mem_free ((void *)&entry);
12873+ }
12874+ }
12875+ }
12876+ }
12877+
12878+ if (rv == CKR_OK) {
12879+ *p_token_id_list = token_id_list;
12880+ token_id_list = NULL;
12881+ }
12882+
12883+ if (token_id_list != NULL) {
12884+ pkcs11h_token_freeTokenIdList (token_id_list);
12885+ token_id_list = NULL;
12886+ }
12887+
12888+#if defined(ENABLE_PKCS11H_THREADING)
12889+ if (mutex_locked) {
12890+ rv = _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.global);
12891+ mutex_locked = FALSE;
12892+ }
12893+#endif
12894+
12895+ PKCS11H_DEBUG (
12896+ PKCS11H_LOG_DEBUG2,
12897+ "PKCS#11: pkcs11h_token_enumTokenIds return rv=%ld-'%s', *p_token_id_list=%p",
12898+ rv,
12899+ pkcs11h_getMessage (rv),
12900+ (void *)p_token_id_list
12901+ );
12902+
12903+ return rv;
12904+}
12905+
12906+#endif
12907+
12908+#if defined(ENABLE_PKCS11H_DATA)
12909+
12910+CK_RV
12911+pkcs11h_data_freeDataIdList (
12912+ IN const pkcs11h_data_id_list_t data_id_list
12913+) {
12914+ pkcs11h_data_id_list_t _id = data_id_list;
12915+
12916+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
12917+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
12918+ /*PKCS11H_ASSERT (data_id_list!=NULL); NOT NEEDED*/
12919+
12920+ PKCS11H_DEBUG (
12921+ PKCS11H_LOG_DEBUG2,
12922+ "PKCS#11: pkcs11h_freeDataIdList entry token_id_list=%p",
12923+ (void *)data_id_list
12924+ );
12925+
12926+ while (_id != NULL) {
12927+ pkcs11h_data_id_list_t x = _id;
12928+ _id = _id->next;
12929+
12930+ if (x->application != NULL) {
12931+ _pkcs11h_mem_free ((void *)&x->application);
12932+ }
12933+ if (x->label != NULL) {
12934+ _pkcs11h_mem_free ((void *)&x->label);
12935+ }
12936+ _pkcs11h_mem_free ((void *)&x);
12937+ }
12938+
12939+ PKCS11H_DEBUG (
12940+ PKCS11H_LOG_DEBUG2,
12941+ "PKCS#11: pkcs11h_token_freeDataIdList return"
12942+ );
12943+
12944+ return CKR_OK;
12945+}
12946+
12947+CK_RV
12948+pkcs11h_data_enumDataObjects (
12949+ IN const pkcs11h_token_id_t token_id,
12950+ IN const PKCS11H_BOOL is_public,
12951+ IN void * const user_data,
12952+ IN const unsigned mask_prompt,
12953+ OUT pkcs11h_data_id_list_t * const p_data_id_list
12954+) {
12955+#if defined(ENABLE_PKCS11H_THREADING)
12956+ PKCS11H_BOOL mutex_locked = FALSE;
12957+#endif
12958+ pkcs11h_session_t session = NULL;
12959+ pkcs11h_data_id_list_t data_id_list = NULL;
12960+ CK_RV rv = CKR_OK;
12961+
12962+ PKCS11H_BOOL op_succeed = FALSE;
12963+ PKCS11H_BOOL login_retry = FALSE;
12964+
12965+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
12966+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
12967+ PKCS11H_ASSERT (p_data_id_list!=NULL);
12968+
12969+ PKCS11H_DEBUG (
12970+ PKCS11H_LOG_DEBUG2,
12971+ "PKCS#11: pkcs11h_data_enumDataObjects entry token_id=%p, is_public=%d, user_data=%p, mask_prompt=%08x, p_data_id_list=%p",
12972+ (void *)token_id,
12973+ is_public ? 1 : 0,
12974+ user_data,
12975+ mask_prompt,
12976+ (void *)p_data_id_list
12977+ );
12978+
12979+ *p_data_id_list = NULL;
12980+
12981+ if (rv == CKR_OK) {
12982+ rv = _pkcs11h_session_getSessionByTokenId (
12983+ token_id,
12984+ &session
12985+ );
12986+ }
12987+
12988+#if defined(ENABLE_PKCS11H_THREADING)
12989+ if (
12990+ rv == CKR_OK &&
12991+ (rv = _pkcs11h_threading_mutexLock (&session->mutex)) == CKR_OK
12992+ ) {
12993+ mutex_locked = TRUE;
12994+ }
12995+#endif
12996+
12997+ while (rv == CKR_OK && !op_succeed) {
12998+
12999+ CK_OBJECT_CLASS class = CKO_DATA;
13000+ CK_ATTRIBUTE filter[] = {
13001+ {CKA_CLASS, (void *)&class, sizeof (class)}
13002+ };
13003+ CK_OBJECT_HANDLE *objects = NULL;
13004+ CK_ULONG objects_found = 0;
13005+
13006+ CK_ULONG i;
13007+
13008+ if (rv == CKR_OK) {
13009+ rv = _pkcs11h_session_validate (session);
13010+ }
13011+
13012+ if (rv == CKR_OK) {
13013+ rv = _pkcs11h_session_findObjects (
13014+ session,
13015+ filter,
13016+ sizeof (filter) / sizeof (CK_ATTRIBUTE),
13017+ &objects,
13018+ &objects_found
13019+ );
13020+ }
13021+
13022+ for (i = 0;rv == CKR_OK && i < objects_found;i++) {
13023+ pkcs11h_data_id_list_t entry = NULL;
13024+
13025+ CK_ATTRIBUTE attrs[] = {
13026+ {CKA_APPLICATION, NULL, 0},
13027+ {CKA_LABEL, NULL, 0}
13028+ };
13029+
13030+ if (rv == CKR_OK) {
13031+ rv = _pkcs11h_session_getObjectAttributes (
13032+ session,
13033+ objects[i],
13034+ attrs,
13035+ sizeof (attrs) / sizeof (CK_ATTRIBUTE)
13036+ );
13037+ }
13038+
13039+ if (rv == CKR_OK) {
13040+ rv = _pkcs11h_mem_malloc (
13041+ (void *)&entry,
13042+ sizeof (struct pkcs11h_data_id_list_s)
13043+ );
13044+ }
13045+
13046+ if (
13047+ rv == CKR_OK &&
13048+ (rv = _pkcs11h_mem_malloc (
13049+ (void *)&entry->application,
13050+ attrs[0].ulValueLen+1
13051+ )) == CKR_OK
13052+ ) {
13053+ memmove (entry->application, attrs[0].pValue, attrs[0].ulValueLen);
13054+ entry->application[attrs[0].ulValueLen] = '\0';
13055+ }
13056+
13057+ if (
13058+ rv == CKR_OK &&
13059+ (rv = _pkcs11h_mem_malloc (
13060+ (void *)&entry->label,
13061+ attrs[1].ulValueLen+1
13062+ )) == CKR_OK
13063+ ) {
13064+ memmove (entry->label, attrs[1].pValue, attrs[1].ulValueLen);
13065+ entry->label[attrs[1].ulValueLen] = '\0';
13066+ }
13067+
13068+ if (rv == CKR_OK) {
13069+ entry->next = data_id_list;
13070+ data_id_list = entry;
13071+ entry = NULL;
13072+ }
13073+
13074+ _pkcs11h_session_freeObjectAttributes (
13075+ attrs,
13076+ sizeof (attrs) / sizeof (CK_ATTRIBUTE)
13077+ );
13078+
13079+ if (entry != NULL) {
13080+ if (entry->application != NULL) {
13081+ _pkcs11h_mem_free ((void *)&entry->application);
13082+ }
13083+ if (entry->label != NULL) {
13084+ _pkcs11h_mem_free ((void *)&entry->label);
13085+ }
13086+ _pkcs11h_mem_free ((void *)&entry);
13087+ }
13088+ }
13089+
13090+ if (objects != NULL) {
13091+ _pkcs11h_mem_free ((void *)&objects);
13092+ }
13093+
13094+ if (rv == CKR_OK) {
13095+ op_succeed = TRUE;
13096+ }
13097+ else {
13098+ if (!login_retry) {
13099+ PKCS11H_DEBUG (
13100+ PKCS11H_LOG_DEBUG1,
13101+ "PKCS#11: Enumerate data objects failed rv=%ld-'%s'",
13102+ rv,
13103+ pkcs11h_getMessage (rv)
13104+ );
13105+ login_retry = TRUE;
13106+ rv = _pkcs11h_session_login (
13107+ session,
13108+ is_public,
13109+ TRUE,
13110+ user_data,
13111+ mask_prompt
13112+ );
13113+ }
13114+ }
13115+ }
13116+
13117+#if defined(ENABLE_PKCS11H_THREADING)
13118+ if (mutex_locked) {
13119+ _pkcs11h_threading_mutexRelease (&session->mutex);
13120+ mutex_locked = FALSE;
13121+ }
13122+#endif
13123+
13124+ if (rv == CKR_OK) {
13125+ *p_data_id_list = data_id_list;
13126+ data_id_list = NULL;
13127+ }
13128+
13129+ if (session != NULL) {
13130+ _pkcs11h_session_release (session);
13131+ session = NULL;
13132+ }
13133+
13134+ if (data_id_list != NULL) {
13135+ pkcs11h_data_freeDataIdList (data_id_list);
13136+ data_id_list = NULL;
13137+ }
13138+
13139+ PKCS11H_DEBUG (
13140+ PKCS11H_LOG_DEBUG2,
13141+ "PKCS#11: pkcs11h_data_enumDataObjects return rv=%ld-'%s', *p_data_id_list=%p",
13142+ rv,
13143+ pkcs11h_getMessage (rv),
13144+ (void *)*p_data_id_list
13145+ );
13146+
13147+ return rv;
13148+}
13149+
13150+#endif /* ENABLE_PKCS11H_DATA */
13151+
13152+#if defined(ENABLE_PKCS11H_CERTIFICATE)
13153+
13154+static
13155+CK_RV
13156+_pkcs11h_certificate_enumSessionCertificates (
13157+ IN const pkcs11h_session_t session,
13158+ IN void * const user_data,
13159+ IN const unsigned mask_prompt
13160+) {
13161+#if defined(ENABLE_PKCS11H_THREADING)
13162+ PKCS11H_BOOL mutex_locked = FALSE;
13163+#endif
13164+ PKCS11H_BOOL op_succeed = FALSE;
13165+ PKCS11H_BOOL login_retry = FALSE;
13166+
13167+ CK_RV rv = CKR_OK;
13168+
13169+ PKCS11H_ASSERT (session!=NULL);
13170+ /*PKCS11H_ASSERT (user_data) NOT NEEDED */
13171+
13172+ PKCS11H_DEBUG (
13173+ PKCS11H_LOG_DEBUG2,
13174+ "PKCS#11: _pkcs11h_certificate_enumSessionCertificates entry session=%p, user_data=%p, mask_prompt=%08x",
13175+ (void *)session,
13176+ user_data,
13177+ mask_prompt
13178+ );
13179+
13180+ /* THREADS: NO NEED TO LOCK, GLOBAL CACHE IS LOCKED */
13181+#if defined(ENABLE_PKCS11H_THREADING)
13182+ if (
13183+ rv == CKR_OK &&
13184+ (rv = _pkcs11h_threading_mutexLock (&session->mutex)) == CKR_OK
13185+ ) {
13186+ mutex_locked = TRUE;
13187+ }
13188+#endif
13189+
13190+ while (rv == CKR_OK && !op_succeed) {
13191+ CK_OBJECT_CLASS cert_filter_class = CKO_CERTIFICATE;
13192+ CK_ATTRIBUTE cert_filter[] = {
13193+ {CKA_CLASS, &cert_filter_class, sizeof (cert_filter_class)}
13194+ };
13195+
13196+ CK_OBJECT_HANDLE *objects = NULL;
13197+ CK_ULONG objects_found = 0;
13198+
13199+ CK_ULONG i;
13200+
13201+ if (rv == CKR_OK) {
13202+ rv = _pkcs11h_session_validate (session);
13203+ }
13204+
13205+ if (rv == CKR_OK) {
13206+ rv = _pkcs11h_session_findObjects (
13207+ session,
13208+ cert_filter,
13209+ sizeof (cert_filter) / sizeof (CK_ATTRIBUTE),
13210+ &objects,
13211+ &objects_found
13212+ );
13213+ }
13214+
13215+ for (i=0;rv == CKR_OK && i < objects_found;i++) {
13216+ pkcs11h_certificate_id_t certificate_id = NULL;
13217+ pkcs11h_certificate_id_list_t new_element = NULL;
13218+
13219+ CK_ATTRIBUTE attrs[] = {
13220+ {CKA_ID, NULL, 0},
13221+ {CKA_VALUE, NULL, 0}
13222+ };
13223+
13224+ if (rv == CKR_OK) {
13225+ rv = _pkcs11h_session_getObjectAttributes (
13226+ session,
13227+ objects[i],
13228+ attrs,
13229+ sizeof (attrs) / sizeof (CK_ATTRIBUTE)
13230+ );
13231+ }
13232+
13233+ if (
13234+ rv == CKR_OK &&
13235+ (rv = _pkcs11h_certificate_newCertificateId (&certificate_id)) == CKR_OK
13236+ ) {
13237+ rv = pkcs11h_token_duplicateTokenId (
13238+ &certificate_id->token_id,
13239+ session->token_id
13240+ );
13241+ }
13242+
13243+ if (rv == CKR_OK) {
13244+ rv = _pkcs11h_mem_duplicate (
13245+ (void*)&certificate_id->attrCKA_ID,
13246+ &certificate_id->attrCKA_ID_size,
13247+ attrs[0].pValue,
13248+ attrs[0].ulValueLen
13249+ );
13250+ }
13251+
13252+ if (rv == CKR_OK) {
13253+ rv = _pkcs11h_mem_duplicate (
13254+ (void*)&certificate_id->certificate_blob,
13255+ &certificate_id->certificate_blob_size,
13256+ attrs[1].pValue,
13257+ attrs[1].ulValueLen
13258+ );
13259+ }
13260+
13261+ if (rv == CKR_OK) {
13262+ rv = _pkcs11h_certificate_updateCertificateIdDescription (certificate_id);
13263+ }
13264+
13265+ if (
13266+ rv == CKR_OK &&
13267+ (rv = _pkcs11h_mem_malloc (
13268+ (void *)&new_element,
13269+ sizeof (struct pkcs11h_certificate_id_list_s)
13270+ )) == CKR_OK
13271+ ) {
13272+ new_element->next = session->cached_certs;
13273+ new_element->certificate_id = certificate_id;
13274+ certificate_id = NULL;
13275+
13276+ session->cached_certs = new_element;
13277+ new_element = NULL;
13278+ }
13279+
13280+ if (certificate_id != NULL) {
13281+ pkcs11h_certificate_freeCertificateId (certificate_id);
13282+ certificate_id = NULL;
13283+ }
13284+
13285+ if (new_element != NULL) {
13286+ _pkcs11h_mem_free ((void *)&new_element);
13287+ new_element = NULL;
13288+ }
13289+
13290+ _pkcs11h_session_freeObjectAttributes (
13291+ attrs,
13292+ sizeof (attrs) / sizeof (CK_ATTRIBUTE)
13293+ );
13294+
13295+ if (rv != CKR_OK) {
13296+ PKCS11H_DEBUG (
13297+ PKCS11H_LOG_DEBUG1,
13298+ "PKCS#11: Cannot get object attribute for provider '%s' object %ld rv=%ld-'%s'",
13299+ session->provider->manufacturerID,
13300+ objects[i],
13301+ rv,
13302+ pkcs11h_getMessage (rv)
13303+ );
13304+
13305+ /*
13306+ * Ignore error
13307+ */
13308+ rv = CKR_OK;
13309+ }
13310+ }
13311+
13312+ if (objects != NULL) {
13313+ _pkcs11h_mem_free ((void *)&objects);
13314+ }
13315+
13316+ if (rv == CKR_OK) {
13317+ op_succeed = TRUE;
13318+ }
13319+ else {
13320+ if (!login_retry) {
13321+ PKCS11H_DEBUG (
13322+ PKCS11H_LOG_DEBUG1,
13323+ "PKCS#11: Get certificate attributes failed: %ld:'%s'",
13324+ rv,
13325+ pkcs11h_getMessage (rv)
13326+ );
13327+
13328+ rv = _pkcs11h_session_login (
13329+ session,
13330+ TRUE,
13331+ TRUE,
13332+ user_data,
13333+ (mask_prompt & PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT)
13334+ );
13335+
13336+ login_retry = TRUE;
13337+ }
13338+ }
13339+ }
13340+
13341+#if defined(ENABLE_PKCS11H_THREADING)
13342+ if (mutex_locked) {
13343+ _pkcs11h_threading_mutexRelease (&session->mutex);
13344+ mutex_locked = FALSE;
13345+ }
13346+#endif
13347+
13348+ PKCS11H_DEBUG (
13349+ PKCS11H_LOG_DEBUG2,
13350+ "PKCS#11: _pkcs11h_certificate_enumSessionCertificates return rv=%ld-'%s'",
13351+ rv,
13352+ pkcs11h_getMessage (rv)
13353+ );
13354+
13355+ return rv;
13356+}
13357+
13358+static
13359+CK_RV
13360+_pkcs11h_certificate_splitCertificateIdList (
13361+ IN const pkcs11h_certificate_id_list_t cert_id_all,
13362+ OUT pkcs11h_certificate_id_list_t * const p_cert_id_issuers_list,
13363+ OUT pkcs11h_certificate_id_list_t * const p_cert_id_end_list
13364+) {
13365+ typedef struct info_s {
13366+ struct info_s *next;
13367+ pkcs11h_certificate_id_t e;
13368+#if defined(USE_PKCS11H_OPENSSL)
13369+ X509 *x509;
13370+#elif defined(USE_PKCS11H_GNUTLS)
13371+ gnutls_x509_crt_t cert;
13372+#endif
13373+ PKCS11H_BOOL is_issuer;
13374+ } *info_t;
13375+
13376+ pkcs11h_certificate_id_list_t cert_id_issuers_list = NULL;
13377+ pkcs11h_certificate_id_list_t cert_id_end_list = NULL;
13378+
13379+ info_t head = NULL;
13380+ info_t info = NULL;
13381+
13382+ CK_RV rv = CKR_OK;
13383+
13384+ /*PKCS11H_ASSERT (cert_id_all!=NULL); NOT NEEDED */
13385+ /*PKCS11H_ASSERT (p_cert_id_issuers_list!=NULL); NOT NEEDED*/
13386+ PKCS11H_ASSERT (p_cert_id_end_list!=NULL);
13387+
13388+ PKCS11H_DEBUG (
13389+ PKCS11H_LOG_DEBUG2,
13390+ "PKCS#11: _pkcs11h_certificate_splitCertificateIdList entry cert_id_all=%p, p_cert_id_issuers_list=%p, p_cert_id_end_list=%p",
13391+ (void *)cert_id_all,
13392+ (void *)p_cert_id_issuers_list,
13393+ (void *)p_cert_id_end_list
13394+ );
13395+
13396+ if (p_cert_id_issuers_list != NULL) {
13397+ *p_cert_id_issuers_list = NULL;
13398+ }
13399+ *p_cert_id_end_list = NULL;
13400+
13401+ if (rv == CKR_OK) {
13402+ pkcs11h_certificate_id_list_t entry = NULL;
13403+
13404+ for (
13405+ entry = cert_id_all;
13406+ entry != NULL && rv == CKR_OK;
13407+ entry = entry->next
13408+ ) {
13409+ info_t new_info = NULL;
13410+
13411+ if (
13412+ rv == CKR_OK &&
13413+ (rv = _pkcs11h_mem_malloc ((void *)&new_info, sizeof (struct info_s))) == CKR_OK &&
13414+ entry->certificate_id->certificate_blob != NULL
13415+ ) {
13416+#if defined(USE_PKCS11H_OPENSSL)
13417+ pkcs11_openssl_d2i_t d2i = (pkcs11_openssl_d2i_t)entry->certificate_id->certificate_blob;
13418+#endif
13419+
13420+ new_info->next = head;
13421+ new_info->e = entry->certificate_id;
13422+#if defined(USE_PKCS11H_OPENSSL)
13423+ new_info->x509 = X509_new ();
13424+ if (
13425+ new_info->x509 != NULL &&
13426+ !d2i_X509 (
13427+ &new_info->x509,
13428+ &d2i,
13429+ entry->certificate_id->certificate_blob_size
13430+ )
13431+ ) {
13432+ X509_free (new_info->x509);
13433+ new_info->x509 = NULL;
13434+ }
13435+#elif defined(USE_PKCS11H_GNUTLS)
13436+ if (gnutls_x509_crt_init (&new_info->cert) != GNUTLS_E_SUCCESS) {
13437+ /* gnutls sets output */
13438+ new_info->cert = NULL;
13439+ }
13440+ else {
13441+ gnutls_datum_t datum = {
13442+ entry->certificate_id->certificate_blob,
13443+ entry->certificate_id->certificate_blob_size
13444+ };
13445+
13446+ if (
13447+ gnutls_x509_crt_import (
13448+ new_info->cert,
13449+ &datum,
13450+ GNUTLS_X509_FMT_DER
13451+ ) != GNUTLS_E_SUCCESS
13452+ ) {
13453+ gnutls_x509_crt_deinit (new_info->cert);
13454+ new_info->cert = NULL;
13455+ }
13456+ }
13457+#else
13458+#error Invalid configuration.
13459+#endif
13460+ head = new_info;
13461+ new_info = NULL;
13462+ }
13463+ }
13464+
13465+ }
13466+
13467+ if (rv == CKR_OK) {
13468+ for (
13469+ info = head;
13470+ info != NULL;
13471+ info = info->next
13472+ ) {
13473+ info_t info2 = NULL;
13474+#if defined(USE_PKCS11H_OPENSSL)
13475+ EVP_PKEY *pub = X509_get_pubkey (info->x509);
13476+#endif
13477+
13478+ for (
13479+ info2 = head;
13480+ info2 != NULL && !info->is_issuer;
13481+ info2 = info2->next
13482+ ) {
13483+ if (info != info2) {
13484+#if defined(USE_PKCS11H_OPENSSL)
13485+ if (
13486+ info->x509 != NULL &&
13487+ info2->x509 != NULL &&
13488+ !X509_NAME_cmp (
13489+ X509_get_subject_name (info->x509),
13490+ X509_get_issuer_name (info2->x509)
13491+ ) &&
13492+ X509_verify (info2->x509, pub) == 1
13493+ ) {
13494+ info->is_issuer = TRUE;
13495+ }
13496+#elif defined(USE_PKCS11H_GNUTLS)
13497+ unsigned result;
13498+
13499+ if (
13500+ info->cert != NULL &&
13501+ info2->cert != NULL &&
13502+ gnutls_x509_crt_verify (
13503+ info2->cert,
13504+ &info->cert,
13505+ 1,
13506+ 0,
13507+ &result
13508+ ) &&
13509+ (result & GNUTLS_CERT_INVALID) == 0
13510+ ) {
13511+ info->is_issuer = TRUE;
13512+ }
13513+#else
13514+#error Invalid configuration.
13515+#endif
13516+ }
13517+
13518+ }
13519+
13520+#if defined(USE_PKCS11H_OPENSSL)
13521+ if (pub != NULL) {
13522+ EVP_PKEY_free (pub);
13523+ pub = NULL;
13524+ }
13525+#endif
13526+ }
13527+ }
13528+
13529+ if (rv == CKR_OK) {
13530+ for (
13531+ info = head;
13532+ info != NULL && rv == CKR_OK;
13533+ info = info->next
13534+ ) {
13535+ pkcs11h_certificate_id_list_t new_entry = NULL;
13536+
13537+ if (rv == CKR_OK) {
13538+ rv = _pkcs11h_mem_malloc (
13539+ (void *)&new_entry,
13540+ sizeof (struct pkcs11h_certificate_id_list_s)
13541+ );
13542+ }
13543+
13544+ if (
13545+ rv == CKR_OK &&
13546+ (rv = pkcs11h_certificate_duplicateCertificateId (
13547+ &new_entry->certificate_id,
13548+ info->e
13549+ )) == CKR_OK
13550+ ) {
13551+ /*
13552+ * Should not free base list
13553+ */
13554+ info->e = NULL;
13555+ }
13556+
13557+ if (rv == CKR_OK) {
13558+ if (info->is_issuer) {
13559+ new_entry->next = cert_id_issuers_list;
13560+ cert_id_issuers_list = new_entry;
13561+ new_entry = NULL;
13562+ }
13563+ else {
13564+ new_entry->next = cert_id_end_list;
13565+ cert_id_end_list = new_entry;
13566+ new_entry = NULL;
13567+ }
13568+ }
13569+
13570+ if (new_entry != NULL) {
13571+ if (new_entry->certificate_id != NULL) {
13572+ pkcs11h_certificate_freeCertificateId (new_entry->certificate_id);
13573+ }
13574+ _pkcs11h_mem_free ((void *)&new_entry);
13575+ }
13576+ }
13577+ }
13578+
13579+ if (rv == CKR_OK) {
13580+ while (head != NULL) {
13581+ info_t entry = head;
13582+ head = head->next;
13583+
13584+#if defined(USE_PKCS11H_OPENSSL)
13585+ if (entry->x509 != NULL) {
13586+ X509_free (entry->x509);
13587+ entry->x509 = NULL;
13588+ }
13589+#elif defined(USE_PKCS11H_GNUTLS)
13590+ if (entry->cert != NULL) {
13591+ gnutls_x509_crt_deinit (entry->cert);
13592+ entry->cert = NULL;
13593+ }
13594+#else
13595+#error Invalid configuration.
13596+#endif
13597+
13598+ _pkcs11h_mem_free ((void *)&entry);
13599+ }
13600+ }
13601+
13602+ if (rv == CKR_OK && p_cert_id_issuers_list != NULL ) {
13603+ *p_cert_id_issuers_list = cert_id_issuers_list;
13604+ cert_id_issuers_list = NULL;
13605+ }
13606+
13607+ if (rv == CKR_OK) {
13608+ *p_cert_id_end_list = cert_id_end_list;
13609+ cert_id_end_list = NULL;
13610+ }
13611+
13612+ if (cert_id_issuers_list != NULL) {
13613+ pkcs11h_certificate_freeCertificateIdList (cert_id_issuers_list);
13614+ }
13615+
13616+ if (cert_id_end_list != NULL) {
13617+ pkcs11h_certificate_freeCertificateIdList (cert_id_end_list);
13618+ }
13619+
13620+ PKCS11H_DEBUG (
13621+ PKCS11H_LOG_DEBUG2,
13622+ "PKCS#11: _pkcs11h_certificate_splitCertificateIdList return rv=%ld-'%s'",
13623+ rv,
13624+ pkcs11h_getMessage (rv)
13625+ );
13626+
13627+ return rv;
13628+}
13629+
13630+CK_RV
13631+pkcs11h_certificate_freeCertificateIdList (
13632+ IN const pkcs11h_certificate_id_list_t cert_id_list
13633+) {
13634+ pkcs11h_certificate_id_list_t _id = cert_id_list;
13635+
13636+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
13637+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
13638+ /*PKCS11H_ASSERT (cert_id_list!=NULL); NOT NEEDED*/
13639+
13640+ PKCS11H_DEBUG (
13641+ PKCS11H_LOG_DEBUG2,
13642+ "PKCS#11: pkcs11h_certificate_freeCertificateIdList entry cert_id_list=%p",
13643+ (void *)cert_id_list
13644+ );
13645+
13646+ while (_id != NULL) {
13647+ pkcs11h_certificate_id_list_t x = _id;
13648+ _id = _id->next;
13649+ if (x->certificate_id != NULL) {
13650+ pkcs11h_certificate_freeCertificateId (x->certificate_id);
13651+ }
13652+ x->next = NULL;
13653+ _pkcs11h_mem_free ((void *)&x);
13654+ }
13655+
13656+ PKCS11H_DEBUG (
13657+ PKCS11H_LOG_DEBUG2,
13658+ "PKCS#11: pkcs11h_certificate_freeCertificateIdList return"
13659+ );
13660+
13661+ return CKR_OK;
13662+}
13663+
13664+CK_RV
13665+pkcs11h_certificate_enumTokenCertificateIds (
13666+ IN const pkcs11h_token_id_t token_id,
13667+ IN const int method,
13668+ IN void * const user_data,
13669+ IN const unsigned mask_prompt,
13670+ OUT pkcs11h_certificate_id_list_t * const p_cert_id_issuers_list,
13671+ OUT pkcs11h_certificate_id_list_t * const p_cert_id_end_list
13672+) {
13673+#if defined(ENABLE_PKCS11H_THREADING)
13674+ PKCS11H_BOOL mutex_locked = FALSE;
13675+#endif
13676+ pkcs11h_session_t session = NULL;
13677+ CK_RV rv = CKR_OK;
13678+
13679+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
13680+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
13681+ PKCS11H_ASSERT (token_id!=NULL);
13682+ /*PKCS11H_ASSERT (user_data) NOT NEEDED */
13683+ /*PKCS11H_ASSERT (p_cert_id_issuers_list!=NULL); NOT NEEDED*/
13684+ PKCS11H_ASSERT (p_cert_id_end_list!=NULL);
13685+
13686+ PKCS11H_DEBUG (
13687+ PKCS11H_LOG_DEBUG2,
13688+ "PKCS#11: pkcs11h_certificate_enumTokenCertificateIds entry token_id=%p, method=%d, user_data=%p, mask_prompt=%08x, p_cert_id_issuers_list=%p, p_cert_id_end_list=%p",
13689+ (void *)token_id,
13690+ method,
13691+ user_data,
13692+ mask_prompt,
13693+ (void *)p_cert_id_issuers_list,
13694+ (void *)p_cert_id_end_list
13695+ );
13696+
13697+ if (p_cert_id_issuers_list != NULL) {
13698+ *p_cert_id_issuers_list = NULL;
13699+ }
13700+ *p_cert_id_end_list = NULL;
13701+
13702+#if defined(ENABLE_PKCS11H_THREADING)
13703+ if (
13704+ rv == CKR_OK &&
13705+ (rv = _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.cache)) == CKR_OK
13706+ ) {
13707+ mutex_locked = TRUE;
13708+ }
13709+#endif
13710+
13711+ if (
13712+ rv == CKR_OK &&
13713+ (rv = _pkcs11h_session_getSessionByTokenId (
13714+ token_id,
13715+ &session
13716+ )) == CKR_OK
13717+ ) {
13718+ if (method == PKCS11H_ENUM_METHOD_RELOAD) {
13719+ pkcs11h_certificate_freeCertificateIdList (session->cached_certs);
13720+ session->cached_certs = NULL;
13721+ }
13722+
13723+ if (session->cached_certs == NULL) {
13724+ rv = _pkcs11h_certificate_enumSessionCertificates (session, user_data, mask_prompt);
13725+ }
13726+ }
13727+
13728+ if (rv == CKR_OK) {
13729+ rv = _pkcs11h_certificate_splitCertificateIdList (
13730+ session->cached_certs,
13731+ p_cert_id_issuers_list,
13732+ p_cert_id_end_list
13733+ );
13734+ }
13735+
13736+ if (session != NULL) {
13737+ _pkcs11h_session_release (session);
13738+ }
13739+
13740+#if defined(ENABLE_PKCS11H_THREADING)
13741+ if (mutex_locked) {
13742+ _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.cache);
13743+ mutex_locked = FALSE;
13744+ }
13745+#endif
13746+
13747+ PKCS11H_DEBUG (
13748+ PKCS11H_LOG_DEBUG2,
13749+ "PKCS#11: pkcs11h_certificate_enumTokenCertificateIds return rv=%ld-'%s'",
13750+ rv,
13751+ pkcs11h_getMessage (rv)
13752+ );
13753+
13754+ return rv;
13755+}
13756+
13757+CK_RV
13758+pkcs11h_certificate_enumCertificateIds (
13759+ IN const int method,
13760+ IN void * const user_data,
13761+ IN const unsigned mask_prompt,
13762+ OUT pkcs11h_certificate_id_list_t * const p_cert_id_issuers_list,
13763+ OUT pkcs11h_certificate_id_list_t * const p_cert_id_end_list
13764+) {
13765+#if defined(ENABLE_PKCS11H_THREADING)
13766+ PKCS11H_BOOL mutex_locked = FALSE;
13767+#endif
13768+ pkcs11h_certificate_id_list_t cert_id_list = NULL;
13769+ pkcs11h_provider_t current_provider;
13770+ pkcs11h_session_t current_session;
13771+ CK_RV rv = CKR_OK;
13772+
13773+ PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
13774+ PKCS11H_ASSERT (s_pkcs11h_data->initialized);
13775+ /*PKCS11H_ASSERT (user_data!=NULL); NOT NEEDED*/
13776+ /*PKCS11H_ASSERT (p_cert_id_issuers_list!=NULL); NOT NEEDED*/
13777+ PKCS11H_ASSERT (p_cert_id_end_list!=NULL);
13778+
13779+ PKCS11H_DEBUG (
13780+ PKCS11H_LOG_DEBUG2,
13781+ "PKCS#11: pkcs11h_certificate_enumCertificateIds entry method=%d, mask_prompt=%08x, p_cert_id_issuers_list=%p, p_cert_id_end_list=%p",
13782+ method,
13783+ mask_prompt,
13784+ (void *)p_cert_id_issuers_list,
13785+ (void *)p_cert_id_end_list
13786+ );
13787+
13788+ if (p_cert_id_issuers_list != NULL) {
13789+ *p_cert_id_issuers_list = NULL;
13790+ }
13791+ *p_cert_id_end_list = NULL;
13792+
13793+#if defined(ENABLE_PKCS11H_THREADING)
13794+ if (
13795+ rv == CKR_OK &&
13796+ (rv = _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.cache)) == CKR_OK
13797+ ) {
13798+ mutex_locked = TRUE;
13799+ }
13800+#endif
13801+
13802+ for (
13803+ current_session = s_pkcs11h_data->sessions;
13804+ current_session != NULL;
13805+ current_session = current_session->next
13806+ ) {
13807+ current_session->touch = FALSE;
13808+ if (method == PKCS11H_ENUM_METHOD_RELOAD) {
13809+ pkcs11h_certificate_freeCertificateIdList (current_session->cached_certs);
13810+ current_session->cached_certs = NULL;
13811+ }
13812+ }
13813+
13814+ for (
13815+ current_provider = s_pkcs11h_data->providers;
13816+ (
13817+ current_provider != NULL &&
13818+ rv == CKR_OK
13819+ );
13820+ current_provider = current_provider->next
13821+ ) {
13822+ CK_SLOT_ID_PTR slots = NULL;
13823+ CK_ULONG slotnum;
13824+ CK_SLOT_ID slot_index;
13825+
13826+ if (!current_provider->enabled) {
13827+ rv = CKR_CRYPTOKI_NOT_INITIALIZED;
13828+ }
13829+
13830+ if (rv == CKR_OK) {
13831+ rv = _pkcs11h_session_getSlotList (
13832+ current_provider,
13833+ CK_TRUE,
13834+ &slots,
13835+ &slotnum
13836+ );
13837+ }
13838+
13839+ for (
13840+ slot_index=0;
13841+ (
13842+ slot_index < slotnum &&
13843+ rv == CKR_OK
13844+ );
13845+ slot_index++
13846+ ) {
13847+ pkcs11h_session_t session = NULL;
13848+ pkcs11h_token_id_t token_id = NULL;
13849+ CK_TOKEN_INFO info;
13850+
13851+ if (rv == CKR_OK) {
13852+ rv = current_provider->f->C_GetTokenInfo (
13853+ slots[slot_index],
13854+ &info
13855+ );
13856+ }
13857+
13858+ if (
13859+ rv == CKR_OK &&
13860+ (rv = _pkcs11h_token_getTokenId (
13861+ &info,
13862+ &token_id
13863+ )) == CKR_OK &&
13864+ (rv = _pkcs11h_session_getSessionByTokenId (
13865+ token_id,
13866+ &session
13867+ )) == CKR_OK
13868+ ) {
13869+ session->touch = TRUE;
13870+
13871+ if (session->cached_certs == NULL) {
13872+ rv = _pkcs11h_certificate_enumSessionCertificates (session, user_data, mask_prompt);
13873+ }
13874+ }
13875+
13876+ if (rv != CKR_OK) {
13877+ PKCS11H_DEBUG (
13878+ PKCS11H_LOG_DEBUG1,
13879+ "PKCS#11: Cannot get token information for provider '%s' slot %ld rv=%ld-'%s'",
13880+ current_provider->manufacturerID,
13881+ slots[slot_index],
13882+ rv,
13883+ pkcs11h_getMessage (rv)
13884+ );
13885+
13886+ /*
13887+ * Ignore error
13888+ */
13889+ rv = CKR_OK;
13890+ }
13891+
13892+ if (session != NULL) {
13893+ _pkcs11h_session_release (session);
13894+ session = NULL;
13895+ }
13896+
13897+ if (token_id != NULL) {
13898+ pkcs11h_token_freeTokenId (token_id);
13899+ token_id = NULL;
13900+ }
13901+ }
13902+
13903+ if (rv != CKR_OK) {
13904+ PKCS11H_DEBUG (
13905+ PKCS11H_LOG_DEBUG1,
13906+ "PKCS#11: Cannot get slot list for provider '%s' rv=%ld-'%s'",
13907+ current_provider->manufacturerID,
13908+ rv,
13909+ pkcs11h_getMessage (rv)
13910+ );
13911+
13912+ /*
13913+ * Ignore error
13914+ */
13915+ rv = CKR_OK;
13916+ }
13917+
13918+ if (slots != NULL) {
13919+ _pkcs11h_mem_free ((void *)&slots);
13920+ slots = NULL;
13921+ }
13922+ }
13923+
13924+ for (
13925+ current_session = s_pkcs11h_data->sessions;
13926+ (
13927+ current_session != NULL &&
13928+ rv == CKR_OK
13929+ );
13930+ current_session = current_session->next
13931+ ) {
13932+ if (
13933+ method == PKCS11H_ENUM_METHOD_CACHE ||
13934+ (
13935+ (
13936+ method == PKCS11H_ENUM_METHOD_RELOAD ||
13937+ method == PKCS11H_ENUM_METHOD_CACHE_EXIST
13938+ ) &&
13939+ current_session->touch
13940+ )
13941+ ) {
13942+ pkcs11h_certificate_id_list_t entry = NULL;
13943+
13944+ for (
13945+ entry = current_session->cached_certs;
13946+ (
13947+ entry != NULL &&
13948+ rv == CKR_OK
13949+ );
13950+ entry = entry->next
13951+ ) {
13952+ pkcs11h_certificate_id_list_t new_entry = NULL;
13953+
13954+ if (
13955+ rv == CKR_OK &&
13956+ (rv = _pkcs11h_mem_malloc (
13957+ (void *)&new_entry,
13958+ sizeof (struct pkcs11h_certificate_id_list_s)
13959+ )) == CKR_OK &&
13960+ (rv = pkcs11h_certificate_duplicateCertificateId (
13961+ &new_entry->certificate_id,
13962+ entry->certificate_id
13963+ )) == CKR_OK
13964+ ) {
13965+ new_entry->next = cert_id_list;
13966+ cert_id_list = new_entry;
13967+ new_entry = NULL;
13968+ }
13969+
13970+ if (new_entry != NULL) {
13971+ new_entry->next = NULL;
13972+ pkcs11h_certificate_freeCertificateIdList (new_entry);
13973+ new_entry = NULL;
13974+ }
13975+ }
13976+ }
13977+ }
13978+
13979+ if (rv == CKR_OK) {
13980+ rv = _pkcs11h_certificate_splitCertificateIdList (
13981+ cert_id_list,
13982+ p_cert_id_issuers_list,
13983+ p_cert_id_end_list
13984+ );
13985+ }
13986+
13987+ if (cert_id_list != NULL) {
13988+ pkcs11h_certificate_freeCertificateIdList (cert_id_list);
13989+ cert_id_list = NULL;
13990+ }
13991+
13992+
13993+#if defined(ENABLE_PKCS11H_THREADING)
13994+ if (mutex_locked) {
13995+ _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.cache);
13996+ mutex_locked = FALSE;
13997+ }
13998+#endif
13999+
14000+ PKCS11H_DEBUG (
14001+ PKCS11H_LOG_DEBUG2,
14002+ "PKCS#11: pkcs11h_certificate_enumCertificateIds return rv=%ld-'%s'",
14003+ rv,
14004+ pkcs11h_getMessage (rv)
14005+ );
14006+
14007+ return rv;
14008+}
14009+
14010+#endif /* ENABLE_PKCS11H_CERTIFICATE */
14011+
14012+#endif /* ENABLE_PKCS11H_ENUM */
14013+
14014+#if defined(ENABLE_PKCS11H_SLOTEVENT)
14015+/*======================================================================*
14016+ * SLOTEVENT INTERFACE
14017+ *======================================================================*/
14018+
14019+static
14020+unsigned long
14021+_pkcs11h_slotevent_checksum (
14022+ IN const unsigned char * const p,
14023+ IN const size_t s
14024+) {
14025+ unsigned long r = 0;
14026+ size_t i;
14027+ for (i=0;i<s;i++) {
14028+ r += p[i];
14029+ }
14030+ return r;
14031+}
14032+
14033+static
14034+void *
14035+_pkcs11h_slotevent_provider (
14036+ IN void *p
14037+) {
14038+ pkcs11h_provider_t provider = (pkcs11h_provider_t)p;
14039+ CK_SLOT_ID slot;
14040+ CK_RV rv = CKR_OK;
14041+
14042+ PKCS11H_DEBUG (
14043+ PKCS11H_LOG_DEBUG2,
14044+ "PKCS#11: _pkcs11h_slotevent_provider provider='%s' entry",
14045+ provider->manufacturerID
14046+ );
14047+
14048+ if (rv == CKR_OK && !provider->enabled) {
14049+ rv = CKR_OPERATION_NOT_INITIALIZED;
14050+ }
14051+
14052+ if (rv == CKR_OK) {
14053+
14054+ if (provider->slot_poll_interval == 0) {
14055+ provider->slot_poll_interval = PKCS11H_DEFAULT_SLOTEVENT_POLL;
14056+ }
14057+
14058+ /*
14059+ * If we cannot finalize, we cannot cause
14060+ * WaitForSlotEvent to terminate
14061+ */
14062+ if (!provider->should_finalize) {
14063+ PKCS11H_DEBUG (
14064+ PKCS11H_LOG_DEBUG1,
14065+ "PKCS#11: Setup slotevent provider='%s' mode hardset to poll",
14066+ provider->manufacturerID
14067+ );
14068+ provider->slot_event_method = PKCS11H_SLOTEVENT_METHOD_POLL;
14069+ }
14070+
14071+ if (
14072+ provider->slot_event_method == PKCS11H_SLOTEVENT_METHOD_AUTO ||
14073+ provider->slot_event_method == PKCS11H_SLOTEVENT_METHOD_TRIGGER
14074+ ) {
14075+ if (
14076+ provider->f->C_WaitForSlotEvent (
14077+ CKF_DONT_BLOCK,
14078+ &slot,
14079+ NULL_PTR
14080+ ) == CKR_FUNCTION_NOT_SUPPORTED
14081+ ) {
14082+ PKCS11H_DEBUG (
14083+ PKCS11H_LOG_DEBUG1,
14084+ "PKCS#11: Setup slotevent provider='%s' mode is poll",
14085+ provider->manufacturerID
14086+ );
14087+
14088+ provider->slot_event_method = PKCS11H_SLOTEVENT_METHOD_POLL;
14089+ }
14090+ else {
14091+ PKCS11H_DEBUG (
14092+ PKCS11H_LOG_DEBUG1,
14093+ "PKCS#11: Setup slotevent provider='%s' mode is trigger",
14094+ provider->manufacturerID
14095+ );
14096+
14097+ provider->slot_event_method = PKCS11H_SLOTEVENT_METHOD_TRIGGER;
14098+ }
14099+ }
14100+ }
14101+
14102+ if (provider->slot_event_method == PKCS11H_SLOTEVENT_METHOD_TRIGGER) {
14103+ while (
14104+ !s_pkcs11h_data->slotevent.should_terminate &&
14105+ provider->enabled &&
14106+ rv == CKR_OK &&
14107+ (rv = provider->f->C_WaitForSlotEvent (
14108+ 0,
14109+ &slot,
14110+ NULL_PTR
14111+ )) == CKR_OK
14112+ ) {
14113+ PKCS11H_DEBUG (
14114+ PKCS11H_LOG_DEBUG1,
14115+ "PKCS#11: Slotevent provider='%s' event",
14116+ provider->manufacturerID
14117+ );
14118+
14119+ _pkcs11h_threading_condSignal (&s_pkcs11h_data->slotevent.cond_event);
14120+ }
14121+ }
14122+ else {
14123+ unsigned long ulLastChecksum = 0;
14124+ PKCS11H_BOOL is_first_time = TRUE;
14125+
14126+ while (
14127+ !s_pkcs11h_data->slotevent.should_terminate &&
14128+ provider->enabled &&
14129+ rv == CKR_OK
14130+ ) {
14131+ unsigned long ulCurrentChecksum = 0;
14132+
14133+ CK_SLOT_ID_PTR slots = NULL;
14134+ CK_ULONG slotnum;
14135+
14136+ PKCS11H_DEBUG (
14137+ PKCS11H_LOG_DEBUG1,
14138+ "PKCS#11: Slotevent provider='%s' poll",
14139+ provider->manufacturerID
14140+ );
14141+
14142+ if (
14143+ rv == CKR_OK &&
14144+ (rv = _pkcs11h_session_getSlotList (
14145+ provider,
14146+ TRUE,
14147+ &slots,
14148+ &slotnum
14149+ )) == CKR_OK
14150+ ) {
14151+ CK_ULONG i;
14152+
14153+ for (i=0;i<slotnum;i++) {
14154+ CK_TOKEN_INFO info;
14155+
14156+ if (provider->f->C_GetTokenInfo (slots[i], &info) == CKR_OK) {
14157+ ulCurrentChecksum += (
14158+ _pkcs11h_slotevent_checksum (
14159+ info.label,
14160+ sizeof (info.label)
14161+ ) +
14162+ _pkcs11h_slotevent_checksum (
14163+ info.manufacturerID,
14164+ sizeof (info.manufacturerID)
14165+ ) +
14166+ _pkcs11h_slotevent_checksum (
14167+ info.model,
14168+ sizeof (info.model)
14169+ ) +
14170+ _pkcs11h_slotevent_checksum (
14171+ info.serialNumber,
14172+ sizeof (info.serialNumber)
14173+ )
14174+ );
14175+ }
14176+ }
14177+ }
14178+
14179+ if (rv == CKR_OK) {
14180+ if (is_first_time) {
14181+ is_first_time = FALSE;
14182+ }
14183+ else {
14184+ if (ulLastChecksum != ulCurrentChecksum) {
14185+ PKCS11H_DEBUG (
14186+ PKCS11H_LOG_DEBUG1,
14187+ "PKCS#11: Slotevent provider='%s' event",
14188+ provider->manufacturerID
14189+ );
14190+
14191+ _pkcs11h_threading_condSignal (&s_pkcs11h_data->slotevent.cond_event);
14192+ }
14193+ }
14194+ ulLastChecksum = ulCurrentChecksum;
14195+ }
14196+
14197+ if (slots != NULL) {
14198+ _pkcs11h_mem_free ((void *)&slots);
14199+ }
14200+
14201+ if (!s_pkcs11h_data->slotevent.should_terminate) {
14202+ _pkcs11h_threading_sleep (provider->slot_poll_interval);
14203+ }
14204+ }
14205+ }
14206+
14207+ PKCS11H_DEBUG (
14208+ PKCS11H_LOG_DEBUG2,
14209+ "PKCS#11: _pkcs11h_slotevent_provider provider='%s' return",
14210+ provider->manufacturerID
14211+ );
14212+
14213+ return NULL;
14214+}
14215+
14216+static
14217+void *
14218+_pkcs11h_slotevent_manager (
14219+ IN void *p
14220+) {
14221+ PKCS11H_BOOL first_time = TRUE;
14222+
14223+ (void)p;
14224+
14225+ PKCS11H_DEBUG (
14226+ PKCS11H_LOG_DEBUG2,
14227+ "PKCS#11: _pkcs11h_slotevent_manager entry"
14228+ );
14229+
14230+ /*
14231+ * Trigger hook, so application may
14232+ * depend on initial slot change
14233+ */
14234+ PKCS11H_DEBUG (
14235+ PKCS11H_LOG_DEBUG1,
14236+ "PKCS#11: Calling slotevent hook"
14237+ );
14238+ s_pkcs11h_data->hooks.slotevent (s_pkcs11h_data->hooks.slotevent_data);
14239+
14240+ while (
14241+ first_time || /* Must enter wait or mutex will never be free */
14242+ !s_pkcs11h_data->slotevent.should_terminate
14243+ ) {
14244+ pkcs11h_provider_t current_provider;
14245+
14246+ first_time = FALSE;
14247+
14248+ /*
14249+ * Start each provider thread
14250+ * if not already started.
14251+ * This is required in order to allow
14252+ * adding new providers.
14253+ */
14254+ for (
14255+ current_provider = s_pkcs11h_data->providers;
14256+ current_provider != NULL;
14257+ current_provider = current_provider->next
14258+ ) {
14259+ if (!current_provider->enabled) {
14260+ if (current_provider->slotevent_thread == PKCS11H_THREAD_NULL) {
14261+ _pkcs11h_threading_threadStart (
14262+ &current_provider->slotevent_thread,
14263+ _pkcs11h_slotevent_provider,
14264+ current_provider
14265+ );
14266+ }
14267+ }
14268+ else {
14269+ if (current_provider->slotevent_thread != PKCS11H_THREAD_NULL) {
14270+ _pkcs11h_threading_threadJoin (&current_provider->slotevent_thread);
14271+ }
14272+ }
14273+ }
14274+
14275+ PKCS11H_DEBUG (
14276+ PKCS11H_LOG_DEBUG2,
14277+ "PKCS#11: _pkcs11h_slotevent_manager waiting for slotevent"
14278+ );
14279+ _pkcs11h_threading_condWait (&s_pkcs11h_data->slotevent.cond_event, PKCS11H_COND_INFINITE);
14280+
14281+ if (s_pkcs11h_data->slotevent.skip_event) {
14282+ PKCS11H_DEBUG (
14283+ PKCS11H_LOG_DEBUG1,
14284+ "PKCS#11: Slotevent skipping event"
14285+ );
14286+ s_pkcs11h_data->slotevent.skip_event = FALSE;
14287+ }
14288+ else {
14289+ PKCS11H_DEBUG (
14290+ PKCS11H_LOG_DEBUG1,
14291+ "PKCS#11: Calling slotevent hook"
14292+ );
14293+ s_pkcs11h_data->hooks.slotevent (s_pkcs11h_data->hooks.slotevent_data);
14294+ }
14295+ }
14296+
14297+ {
14298+ pkcs11h_provider_t current_provider;
14299+
14300+ PKCS11H_DEBUG (
14301+ PKCS11H_LOG_DEBUG2,
14302+ "PKCS#11: _pkcs11h_slotevent_manager joining threads"
14303+ );
14304+
14305+
14306+ for (
14307+ current_provider = s_pkcs11h_data->providers;
14308+ current_provider != NULL;
14309+ current_provider = current_provider->next
14310+ ) {
14311+ if (current_provider->slotevent_thread != PKCS11H_THREAD_NULL) {
14312+ _pkcs11h_threading_threadJoin (&current_provider->slotevent_thread);
14313+ }
14314+ }
14315+ }
14316+
14317+ PKCS11H_DEBUG (
14318+ PKCS11H_LOG_DEBUG2,
14319+ "PKCS#11: _pkcs11h_slotevent_manager return"
14320+ );
14321+
14322+ return NULL;
14323+}
14324+
14325+static
14326+CK_RV
14327+_pkcs11h_slotevent_init () {
14328+ CK_RV rv = CKR_OK;
14329+
14330+ PKCS11H_DEBUG (
14331+ PKCS11H_LOG_DEBUG2,
14332+ "PKCS#11: _pkcs11h_slotevent_init entry"
14333+ );
14334+
14335+ if (!s_pkcs11h_data->slotevent.initialized) {
14336+ if (rv == CKR_OK) {
14337+ rv = _pkcs11h_threading_condInit (&s_pkcs11h_data->slotevent.cond_event);
14338+ }
14339+
14340+ if (rv == CKR_OK) {
14341+ rv = _pkcs11h_threading_threadStart (
14342+ &s_pkcs11h_data->slotevent.thread,
14343+ _pkcs11h_slotevent_manager,
14344+ NULL
14345+ );
14346+ }
14347+
14348+ if (rv == CKR_OK) {
14349+ s_pkcs11h_data->slotevent.initialized = TRUE;
14350+ }
14351+ }
14352+
14353+ PKCS11H_DEBUG (
14354+ PKCS11H_LOG_DEBUG2,
14355+ "PKCS#11: _pkcs11h_slotevent_init return rv=%ld-'%s'",
14356+ rv,
14357+ pkcs11h_getMessage (rv)
14358+ );
14359+
14360+ return rv;
14361+}
14362+
14363+static
14364+CK_RV
14365+_pkcs11h_slotevent_notify () {
14366+
14367+ PKCS11H_DEBUG (
14368+ PKCS11H_LOG_DEBUG2,
14369+ "PKCS#11: _pkcs11h_slotevent_notify entry"
14370+ );
14371+
14372+ if (s_pkcs11h_data->slotevent.initialized) {
14373+ s_pkcs11h_data->slotevent.skip_event = TRUE;
14374+ _pkcs11h_threading_condSignal (&s_pkcs11h_data->slotevent.cond_event);
14375+ }
14376+
14377+ PKCS11H_DEBUG (
14378+ PKCS11H_LOG_DEBUG2,
14379+ "PKCS#11: _pkcs11h_slotevent_notify return"
14380+ );
14381+
14382+ return CKR_OK;
14383+}
14384+
14385+static
14386+CK_RV
14387+_pkcs11h_slotevent_terminate () {
14388+
14389+ PKCS11H_DEBUG (
14390+ PKCS11H_LOG_DEBUG2,
14391+ "PKCS#11: _pkcs11h_slotevent_terminate entry"
14392+ );
14393+
14394+ if (s_pkcs11h_data->slotevent.initialized) {
14395+ s_pkcs11h_data->slotevent.should_terminate = TRUE;
14396+
14397+ _pkcs11h_slotevent_notify ();
14398+
14399+ if (s_pkcs11h_data->slotevent.thread != PKCS11H_THREAD_NULL) {
14400+ _pkcs11h_threading_threadJoin (&s_pkcs11h_data->slotevent.thread);
14401+ }
14402+
14403+ _pkcs11h_threading_condFree (&s_pkcs11h_data->slotevent.cond_event);
14404+ s_pkcs11h_data->slotevent.initialized = FALSE;
14405+ }
14406+
14407+ PKCS11H_DEBUG (
14408+ PKCS11H_LOG_DEBUG2,
14409+ "PKCS#11: _pkcs11h_slotevent_terminate return"
14410+ );
14411+
14412+ return CKR_OK;
14413+}
14414+
14415+#endif
14416+
14417+#if defined(ENABLE_PKCS11H_OPENSSL)
14418+/*======================================================================*
14419+ * OPENSSL INTERFACE
14420+ *======================================================================*/
14421+
14422+static
14423+pkcs11h_openssl_session_t
14424+_pkcs11h_openssl_get_openssl_session (
14425+ IN OUT const RSA *rsa
14426+) {
14427+ pkcs11h_openssl_session_t session;
14428+
14429+ PKCS11H_ASSERT (rsa!=NULL);
14430+#if OPENSSL_VERSION_NUMBER < 0x00907000L
14431+ session = (pkcs11h_openssl_session_t)RSA_get_app_data ((RSA *)rsa);
14432+#else
14433+ session = (pkcs11h_openssl_session_t)RSA_get_app_data (rsa);
14434+#endif
14435+ PKCS11H_ASSERT (session!=NULL);
14436+
14437+ return session;
14438+}
14439+
14440+static
14441+pkcs11h_certificate_t
14442+_pkcs11h_openssl_get_pkcs11h_certificate (
14443+ IN OUT const RSA *rsa
14444+) {
14445+ pkcs11h_openssl_session_t session = _pkcs11h_openssl_get_openssl_session (rsa);
14446+
14447+ PKCS11H_ASSERT (session!=NULL);
14448+ PKCS11H_ASSERT (session->certificate!=NULL);
14449+
14450+ return session->certificate;
14451+}
14452+
14453+#if OPENSSL_VERSION_NUMBER < 0x00907000L
14454+static
14455+int
14456+_pkcs11h_openssl_dec (
14457+ IN int flen,
14458+ IN unsigned char *from,
14459+ OUT unsigned char *to,
14460+ IN OUT RSA *rsa,
14461+ IN int padding
14462+) {
14463+#else
14464+static
14465+int
14466+_pkcs11h_openssl_dec (
14467+ IN int flen,
14468+ IN const unsigned char *from,
14469+ OUT unsigned char *to,
14470+ IN OUT RSA *rsa,
14471+ IN int padding
14472+) {
14473+#endif
14474+ PKCS11H_ASSERT (from!=NULL);
14475+ PKCS11H_ASSERT (to!=NULL);
14476+ PKCS11H_ASSERT (rsa!=NULL);
14477+
14478+ PKCS11H_DEBUG (
14479+ PKCS11H_LOG_DEBUG2,
14480+ "PKCS#11: _pkcs11h_openssl_dec entered - flen=%d, from=%p, to=%p, rsa=%p, padding=%d",
14481+ flen,
14482+ from,
14483+ to,
14484+ (void *)rsa,
14485+ padding
14486+ );
14487+
14488+ PKCS11H_LOG (
14489+ PKCS11H_LOG_ERROR,
14490+ "PKCS#11: Private key decryption is not supported"
14491+ );
14492+
14493+ PKCS11H_DEBUG (
14494+ PKCS11H_LOG_DEBUG2,
14495+ "PKCS#11: _pkcs11h_openssl_dec return"
14496+ );
14497+
14498+ return -1;
14499+}
14500+
14501+#if OPENSSL_VERSION_NUMBER < 0x00907000L
14502+static
14503+int
14504+_pkcs11h_openssl_sign (
14505+ IN int type,
14506+ IN unsigned char *m,
14507+ IN unsigned int m_len,
14508+ OUT unsigned char *sigret,
14509+ OUT unsigned int *siglen,
14510+ IN OUT RSA *rsa
14511+) {
14512+#else
14513+static
14514+int
14515+_pkcs11h_openssl_sign (
14516+ IN int type,
14517+ IN const unsigned char *m,
14518+ IN unsigned int m_len,
14519+ OUT unsigned char *sigret,
14520+ OUT unsigned int *siglen,
14521+ IN OUT const RSA *rsa
14522+) {
14523+#endif
14524+ pkcs11h_certificate_t certificate = _pkcs11h_openssl_get_pkcs11h_certificate (rsa);
14525+ PKCS11H_BOOL session_locked = FALSE;
14526+ CK_RV rv = CKR_OK;
14527+
14528+ int myrsa_size = 0;
14529+
14530+ unsigned char *enc_alloc = NULL;
14531+ unsigned char *enc = NULL;
14532+ int enc_len = 0;
14533+
14534+ PKCS11H_ASSERT (m!=NULL);
14535+ PKCS11H_ASSERT (sigret!=NULL);
14536+ PKCS11H_ASSERT (siglen!=NULL);
14537+
14538+ PKCS11H_DEBUG (
14539+ PKCS11H_LOG_DEBUG2,
14540+ "PKCS#11: _pkcs11h_openssl_sign entered - type=%d, m=%p, m_len=%u, signret=%p, *signlen=%u, rsa=%p",
14541+ type,
14542+ m,
14543+ m_len,
14544+ sigret,
14545+ sigret != NULL ? *siglen : 0,
14546+ (void *)rsa
14547+ );
14548+
14549+ if (rv == CKR_OK) {
14550+ myrsa_size=RSA_size(rsa);
14551+ }
14552+
14553+ if (type == NID_md5_sha1) {
14554+ if (rv == CKR_OK) {
14555+ enc = (unsigned char *)m;
14556+ enc_len = m_len;
14557+ }
14558+ }
14559+ else {
14560+ X509_SIG sig;
14561+ ASN1_TYPE parameter;
14562+ X509_ALGOR algor;
14563+ ASN1_OCTET_STRING digest;
14564+ unsigned char *p = NULL;
14565+
14566+ if (
14567+ rv == CKR_OK &&
14568+ (rv = _pkcs11h_mem_malloc ((void*)&enc, myrsa_size+1)) == CKR_OK
14569+ ) {
14570+ enc_alloc = enc;
14571+ }
14572+
14573+ if (rv == CKR_OK) {
14574+ sig.algor = &algor;
14575+ }
14576+
14577+ if (
14578+ rv == CKR_OK &&
14579+ (sig.algor->algorithm = OBJ_nid2obj (type)) == NULL
14580+ ) {
14581+ rv = CKR_FUNCTION_FAILED;
14582+ }
14583+
14584+ if (
14585+ rv == CKR_OK &&
14586+ sig.algor->algorithm->length == 0
14587+ ) {
14588+ rv = CKR_KEY_SIZE_RANGE;
14589+ }
14590+
14591+ if (rv == CKR_OK) {
14592+ parameter.type = V_ASN1_NULL;
14593+ parameter.value.ptr = NULL;
14594+
14595+ sig.algor->parameter = &parameter;
14596+
14597+ sig.digest = &digest;
14598+ sig.digest->data = (unsigned char *)m;
14599+ sig.digest->length = m_len;
14600+ }
14601+
14602+ if (
14603+ rv == CKR_OK &&
14604+ (enc_len=i2d_X509_SIG (&sig, NULL)) < 0
14605+ ) {
14606+ rv = CKR_FUNCTION_FAILED;
14607+ }
14608+
14609+ /*
14610+ * d_X509_SIG increments pointer!
14611+ */
14612+ p = enc;
14613+
14614+ if (
14615+ rv == CKR_OK &&
14616+ (enc_len=i2d_X509_SIG (&sig, &p)) < 0
14617+ ) {
14618+ rv = CKR_FUNCTION_FAILED;
14619+ }
14620+ }
14621+
14622+ if (
14623+ rv == CKR_OK &&
14624+ enc_len > (myrsa_size-RSA_PKCS1_PADDING_SIZE)
14625+ ) {
14626+ rv = CKR_KEY_SIZE_RANGE;
14627+ }
14628+
14629+ if (
14630+ rv == CKR_OK &&
14631+ (rv = pkcs11h_certificate_lockSession (certificate)) == CKR_OK
14632+ ) {
14633+ session_locked = TRUE;
14634+ }
14635+
14636+ if (rv == CKR_OK) {
14637+ PKCS11H_DEBUG (
14638+ PKCS11H_LOG_DEBUG1,
14639+ "PKCS#11: Performing signature"
14640+ );
14641+
14642+ *siglen = myrsa_size;
14643+
14644+ if (
14645+ (rv = pkcs11h_certificate_signAny (
14646+ certificate,
14647+ CKM_RSA_PKCS,
14648+ enc,
14649+ enc_len,
14650+ sigret,
14651+ siglen
14652+ )) != CKR_OK
14653+ ) {
14654+ PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11h_getMessage (rv));
14655+ }
14656+ }
14657+
14658+ if (session_locked) {
14659+ pkcs11h_certificate_releaseSession (certificate);
14660+ session_locked = FALSE;
14661+ }
14662+
14663+ if (enc_alloc != NULL) {
14664+ _pkcs11h_mem_free ((void *)&enc_alloc);
14665+ }
14666+
14667+ PKCS11H_DEBUG (
14668+ PKCS11H_LOG_DEBUG2,
14669+ "PKCS#11: _pkcs11h_openssl_sign - return rv=%ld-'%s'",
14670+ rv,
14671+ pkcs11h_getMessage (rv)
14672+ );
14673+
14674+ return rv == CKR_OK ? 1 : -1;
14675+}
14676+
14677+static
14678+int
14679+_pkcs11h_openssl_finish (
14680+ IN OUT RSA *rsa
14681+) {
14682+ pkcs11h_openssl_session_t openssl_session = _pkcs11h_openssl_get_openssl_session (rsa);
14683+
14684+ PKCS11H_DEBUG (
14685+ PKCS11H_LOG_DEBUG2,
14686+ "PKCS#11: _pkcs11h_openssl_finish - entered rsa=%p",
14687+ (void *)rsa
14688+ );
14689+
14690+ RSA_set_app_data (rsa, NULL);
14691+
14692+ if (openssl_session->orig_finish != NULL) {
14693+ openssl_session->orig_finish (rsa);
14694+
14695+#ifdef BROKEN_OPENSSL_ENGINE
14696+ {
14697+ /* We get called TWICE here, once for
14698+ * releasing the key and also for
14699+ * releasing the engine.
14700+ * To prevent endless recursion, FIRST
14701+ * clear rsa->engine, THEN call engine->finish
14702+ */
14703+ ENGINE *e = rsa->engine;
14704+ rsa->engine = NULL;
14705+ if (e) {
14706+ ENGINE_finish(e);
14707+ }
14708+ }
14709+#endif
14710+ }
14711+
14712+ pkcs11h_openssl_freeSession (openssl_session);
14713+
14714+ PKCS11H_DEBUG (
14715+ PKCS11H_LOG_DEBUG2,
14716+ "PKCS#11: _pkcs11h_openssl_finish - return"
14717+ );
14718+
14719+ return 1;
14720+}
14721+
14722+X509 *
14723+pkcs11h_openssl_getX509 (
14724+ IN const pkcs11h_certificate_t certificate
14725+) {
14726+ unsigned char *certificate_blob = NULL;
14727+ size_t certificate_blob_size = 0;
14728+ X509 *x509 = NULL;
14729+ CK_RV rv = CKR_OK;
14730+
14731+ pkcs11_openssl_d2i_t d2i1 = NULL;
14732+ PKCS11H_BOOL ok = TRUE;
14733+
14734+ PKCS11H_ASSERT (certificate!=NULL);
14735+
14736+ PKCS11H_DEBUG (
14737+ PKCS11H_LOG_DEBUG2,
14738+ "PKCS#11: pkcs11h_openssl_getX509 - entry certificate=%p",
14739+ (void *)certificate
14740+ );
14741+
14742+ if (
14743+ ok &&
14744+ (x509 = X509_new ()) == NULL
14745+ ) {
14746+ ok = FALSE;
14747+ PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Unable to allocate certificate object");
14748+ }
14749+
14750+ if (
14751+ ok &&
14752+ pkcs11h_certificate_getCertificateBlob (
14753+ certificate,
14754+ NULL,
14755+ &certificate_blob_size
14756+ ) != CKR_OK
14757+ ) {
14758+ ok = FALSE;
14759+ PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot read X.509 certificate from token %ld-'%s'", rv, pkcs11h_getMessage (rv));
14760+ }
14761+
14762+ if (
14763+ ok &&
14764+ (rv = _pkcs11h_mem_malloc ((void *)&certificate_blob, certificate_blob_size)) != CKR_OK
14765+ ) {
14766+ ok = FALSE;
14767+ PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot allocate X.509 memory %ld-'%s'", rv, pkcs11h_getMessage (rv));
14768+ }
14769+
14770+ if (
14771+ ok &&
14772+ pkcs11h_certificate_getCertificateBlob (
14773+ certificate,
14774+ certificate_blob,
14775+ &certificate_blob_size
14776+ ) != CKR_OK
14777+ ) {
14778+ ok = FALSE;
14779+ PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot read X.509 certificate from token %ld-'%s'", rv, pkcs11h_getMessage (rv));
14780+ }
14781+
14782+ d2i1 = (pkcs11_openssl_d2i_t)certificate_blob;
14783+ if (
14784+ ok &&
14785+ !d2i_X509 (&x509, &d2i1, certificate_blob_size)
14786+ ) {
14787+ ok = FALSE;
14788+ PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Unable to parse X.509 certificate");
14789+ }
14790+
14791+ if (!ok) {
14792+ X509_free (x509);
14793+ x509 = NULL;
14794+ }
14795+
14796+ PKCS11H_DEBUG (
14797+ PKCS11H_LOG_DEBUG2,
14798+ "PKCS#11: pkcs11h_openssl_getX509 - return x509=%p",
14799+ (void *)x509
14800+ );
14801+
14802+ return x509;
14803+}
14804+
14805+pkcs11h_openssl_session_t
14806+pkcs11h_openssl_createSession (
14807+ IN const pkcs11h_certificate_t certificate
14808+) {
14809+ pkcs11h_openssl_session_t openssl_session = NULL;
14810+ PKCS11H_BOOL ok = TRUE;
14811+
14812+ PKCS11H_DEBUG (
14813+ PKCS11H_LOG_DEBUG2,
14814+ "PKCS#11: pkcs11h_openssl_createSession - entry"
14815+ );
14816+
14817+ if (
14818+ ok &&
14819+ _pkcs11h_mem_malloc (
14820+ (void*)&openssl_session,
14821+ sizeof (struct pkcs11h_openssl_session_s)) != CKR_OK
14822+ ) {
14823+ ok = FALSE;
14824+ PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot allocate memory");
14825+ }
14826+
14827+ if (ok) {
14828+ const RSA_METHOD *def = RSA_get_default_method();
14829+
14830+ memmove (&openssl_session->smart_rsa, def, sizeof(RSA_METHOD));
14831+
14832+ openssl_session->orig_finish = def->finish;
14833+
14834+ openssl_session->smart_rsa.name = "pkcs11";
14835+ openssl_session->smart_rsa.rsa_priv_dec = _pkcs11h_openssl_dec;
14836+ openssl_session->smart_rsa.rsa_sign = _pkcs11h_openssl_sign;
14837+ openssl_session->smart_rsa.finish = _pkcs11h_openssl_finish;
14838+ openssl_session->smart_rsa.flags = RSA_METHOD_FLAG_NO_CHECK | RSA_FLAG_EXT_PKEY;
14839+ openssl_session->certificate = certificate;
14840+ openssl_session->reference_count = 1;
14841+ }
14842+
14843+ if (!ok) {
14844+ _pkcs11h_mem_free ((void *)&openssl_session);
14845+ }
14846+
14847+ PKCS11H_DEBUG (
14848+ PKCS11H_LOG_DEBUG2,
14849+ "PKCS#11: pkcs11h_openssl_createSession - return openssl_session=%p",
14850+ (void *)openssl_session
14851+ );
14852+
14853+ return openssl_session;
14854+}
14855+
14856+pkcs11h_hook_openssl_cleanup_t
14857+pkcs11h_openssl_getCleanupHook (
14858+ IN const pkcs11h_openssl_session_t openssl_session
14859+) {
14860+ PKCS11H_ASSERT (openssl_session!=NULL);
14861+
14862+ return openssl_session->cleanup_hook;
14863+}
14864+
14865+void
14866+pkcs11h_openssl_setCleanupHook (
14867+ IN const pkcs11h_openssl_session_t openssl_session,
14868+ IN const pkcs11h_hook_openssl_cleanup_t cleanup
14869+) {
14870+ PKCS11H_ASSERT (openssl_session!=NULL);
14871+
14872+ openssl_session->cleanup_hook = cleanup;
14873+}
14874+
14875+void
14876+pkcs11h_openssl_freeSession (
14877+ IN const pkcs11h_openssl_session_t openssl_session
14878+) {
14879+ PKCS11H_ASSERT (openssl_session!=NULL);
14880+ PKCS11H_ASSERT (openssl_session->reference_count>0);
14881+
14882+ PKCS11H_DEBUG (
14883+ PKCS11H_LOG_DEBUG2,
14884+ "PKCS#11: pkcs11h_openssl_freeSession - entry openssl_session=%p, count=%d",
14885+ (void *)openssl_session,
14886+ openssl_session->reference_count
14887+ );
14888+
14889+ openssl_session->reference_count--;
14890+
14891+ if (openssl_session->reference_count == 0) {
14892+ if (openssl_session->cleanup_hook != NULL) {
14893+ openssl_session->cleanup_hook (openssl_session->certificate);
14894+ }
14895+
14896+ if (openssl_session->x509 != NULL) {
14897+ X509_free (openssl_session->x509);
14898+ openssl_session->x509 = NULL;
14899+ }
14900+ if (openssl_session->certificate != NULL) {
14901+ pkcs11h_certificate_freeCertificate (openssl_session->certificate);
14902+ openssl_session->certificate = NULL;
14903+ }
14904+
14905+ _pkcs11h_mem_free ((void *)&openssl_session);
14906+ }
14907+
14908+ PKCS11H_DEBUG (
14909+ PKCS11H_LOG_DEBUG2,
14910+ "PKCS#11: pkcs11h_openssl_freeSession - return"
14911+ );
14912+}
14913+
14914+RSA *
14915+pkcs11h_openssl_session_getRSA (
14916+ IN const pkcs11h_openssl_session_t openssl_session
14917+) {
14918+ X509 *x509 = NULL;
14919+ RSA *rsa = NULL;
14920+ EVP_PKEY *pubkey = NULL;
14921+ PKCS11H_BOOL ok = TRUE;
14922+
14923+ PKCS11H_ASSERT (openssl_session!=NULL);
14924+ PKCS11H_ASSERT (!openssl_session->initialized);
14925+ PKCS11H_ASSERT (openssl_session!=NULL);
14926+
14927+ PKCS11H_DEBUG (
14928+ PKCS11H_LOG_DEBUG2,
14929+ "PKCS#11: pkcs11h_openssl_session_getRSA - entry openssl_session=%p",
14930+ (void *)openssl_session
14931+ );
14932+
14933+ /*
14934+ * Dup x509 so RSA will not hold session x509
14935+ */
14936+ if (
14937+ ok &&
14938+ (x509 = pkcs11h_openssl_session_getX509 (openssl_session)) == NULL
14939+ ) {
14940+ ok = FALSE;
14941+ PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get certificate object");
14942+ }
14943+
14944+ if (
14945+ ok &&
14946+ (pubkey = X509_get_pubkey (x509)) == NULL
14947+ ) {
14948+ ok = FALSE;
14949+ PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get public key");
14950+ }
14951+
14952+ if (
14953+ ok &&
14954+ pubkey->type != EVP_PKEY_RSA
14955+ ) {
14956+ ok = FALSE;
14957+ PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Invalid public key algorithm");
14958+ }
14959+
14960+ if (
14961+ ok &&
14962+ (rsa = EVP_PKEY_get1_RSA (pubkey)) == NULL
14963+ ) {
14964+ ok = FALSE;
14965+ PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get RSA key");
14966+ }
14967+
14968+ if (ok) {
14969+ RSA_set_method (rsa, &openssl_session->smart_rsa);
14970+ RSA_set_app_data (rsa, openssl_session);
14971+ openssl_session->reference_count++;
14972+ }
14973+
14974+#ifdef BROKEN_OPENSSL_ENGINE
14975+ if (ok) {
14976+ if (!rsa->engine) {
14977+ rsa->engine = ENGINE_get_default_RSA();
14978+ }
14979+
14980+ ENGINE_set_RSA(ENGINE_get_default_RSA(), &openssl_session->smart_rsa);
14981+ PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: OpenSSL engine support is broken! Workaround enabled");
14982+ }
14983+#endif
14984+
14985+ if (ok) {
14986+ rsa->flags |= RSA_FLAG_SIGN_VER;
14987+ openssl_session->initialized = TRUE;
14988+ }
14989+ else {
14990+ if (rsa != NULL) {
14991+ RSA_free (rsa);
14992+ rsa = NULL;
14993+ }
14994+ }
14995+
14996+ /*
14997+ * openssl objects have reference
14998+ * count, so release them
14999+ */
15000+ if (pubkey != NULL) {
15001+ EVP_PKEY_free (pubkey);
15002+ pubkey = NULL;
15003+ }
15004+
15005+ if (x509 != NULL) {
15006+ X509_free (x509);
15007+ x509 = NULL;
15008+ }
15009+
15010+ PKCS11H_DEBUG (
15011+ PKCS11H_LOG_DEBUG2,
15012+ "PKCS#11: pkcs11h_openssl_session_getRSA - return rsa=%p",
15013+ (void *)rsa
15014+ );
15015+
15016+ return rsa;
15017+}
15018+
15019+X509 *
15020+pkcs11h_openssl_session_getX509 (
15021+ IN const pkcs11h_openssl_session_t openssl_session
15022+) {
15023+ X509 *x509 = NULL;
15024+ PKCS11H_BOOL ok = TRUE;
15025+
15026+ PKCS11H_ASSERT (openssl_session!=NULL);
15027+
15028+ PKCS11H_DEBUG (
15029+ PKCS11H_LOG_DEBUG2,
15030+ "PKCS#11: pkcs11h_openssl_session_getX509 - entry openssl_session=%p",
15031+ (void *)openssl_session
15032+ );
15033+
15034+ if (
15035+ ok &&
15036+ openssl_session->x509 == NULL &&
15037+ (openssl_session->x509 = pkcs11h_openssl_getX509 (openssl_session->certificate)) == NULL
15038+ ) {
15039+ ok = FALSE;
15040+ PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get certificate object");
15041+ }
15042+
15043+ if (
15044+ ok &&
15045+ (x509 = X509_dup (openssl_session->x509)) == NULL
15046+ ) {
15047+ ok = FALSE;
15048+ PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot duplicate certificate object");
15049+ }
15050+
15051+ PKCS11H_DEBUG (
15052+ PKCS11H_LOG_DEBUG2,
15053+ "PKCS#11: pkcs11h_openssl_session_getX509 - return x509=%p",
15054+ (void *)x509
15055+ );
15056+
15057+ return x509;
15058+}
15059+
15060+#endif /* ENABLE_PKCS11H_OPENSSL */
15061+
15062+#if defined(ENABLE_PKCS11H_STANDALONE)
15063+/*======================================================================*
15064+ * STANDALONE INTERFACE
15065+ *======================================================================*/
15066+
15067+void
15068+pkcs11h_standalone_dump_slots (
15069+ IN const pkcs11h_output_print_t my_output,
15070+ IN void * const global_data,
15071+ IN const char * const provider
15072+) {
15073+ CK_RV rv = CKR_OK;
15074+
15075+ pkcs11h_provider_t pkcs11h_provider;
15076+
15077+ PKCS11H_ASSERT (my_output!=NULL);
15078+ /*PKCS11H_ASSERT (global_data) NOT NEEDED */
15079+ PKCS11H_ASSERT (provider!=NULL);
15080+
15081+ if (
15082+ rv == CKR_OK &&
15083+ (rv = pkcs11h_initialize ()) != CKR_OK
15084+ ) {
15085+ my_output (global_data, "PKCS#11: Cannot initialize interface %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
15086+ }
15087+
15088+ if (
15089+ rv == CKR_OK &&
15090+ (rv = pkcs11h_addProvider (
15091+ provider,
15092+ provider,
15093+ FALSE,
15094+ (
15095+ PKCS11H_SIGNMODE_MASK_SIGN |
15096+ PKCS11H_SIGNMODE_MASK_RECOVER
15097+ ),
15098+ PKCS11H_SLOTEVENT_METHOD_AUTO,
15099+ 0,
15100+ FALSE
15101+ )) != CKR_OK
15102+ ) {
15103+ my_output (global_data, "PKCS#11: Cannot initialize provider %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
15104+ }
15105+
15106+ /*
15107+ * our provider is head
15108+ */
15109+ if (rv == CKR_OK) {
15110+ pkcs11h_provider = s_pkcs11h_data->providers;
15111+ if (pkcs11h_provider == NULL || !pkcs11h_provider->enabled) {
15112+ my_output (global_data, "PKCS#11: Cannot get provider %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
15113+ rv = CKR_GENERAL_ERROR;
15114+ }
15115+ }
15116+
15117+ if (rv == CKR_OK) {
15118+ CK_INFO info;
15119+
15120+ if ((rv = pkcs11h_provider->f->C_GetInfo (&info)) != CKR_OK) {
15121+ my_output (global_data, "PKCS#11: Cannot get PKCS#11 provider information %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
15122+ rv = CKR_OK;
15123+ }
15124+ else {
15125+ char manufacturerID[sizeof (info.manufacturerID)+1];
15126+
15127+ _pkcs11h_util_fixupFixedString (
15128+ manufacturerID,
15129+ (char *)info.manufacturerID,
15130+ sizeof (info.manufacturerID)
15131+ );
15132+
15133+ my_output (
15134+ global_data,
15135+ (
15136+ "Provider Information:\n"
15137+ "\tcryptokiVersion:\t%u.%u\n"
15138+ "\tmanufacturerID:\t\t%s\n"
15139+ "\tflags:\t\t\t%08x\n"
15140+ "\n"
15141+ ),
15142+ info.cryptokiVersion.major,
15143+ info.cryptokiVersion.minor,
15144+ manufacturerID,
15145+ (unsigned)info.flags
15146+ );
15147+ }
15148+ }
15149+
15150+ if (rv == CKR_OK) {
15151+ CK_SLOT_ID_PTR slots = NULL;
15152+ CK_ULONG slotnum;
15153+ CK_SLOT_ID slot_index;
15154+
15155+ if (
15156+ _pkcs11h_session_getSlotList (
15157+ pkcs11h_provider,
15158+ CK_FALSE,
15159+ &slots,
15160+ &slotnum
15161+ ) != CKR_OK
15162+ ) {
15163+ my_output (global_data, "PKCS#11: Cannot get slot list %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
15164+ }
15165+ else {
15166+ my_output (
15167+ global_data,
15168+ "The following slots are available for use with this provider.\n"
15169+ );
15170+
15171+#if defined(PKCS11H_PRM_SLOT_TYPE)
15172+ my_output (
15173+ global_data,
15174+ (
15175+ "Each slot shown below may be used as a parameter to a\n"
15176+ "%s and %s options.\n"
15177+ ),
15178+ PKCS11H_PRM_SLOT_TYPE,
15179+ PKCS11H_PRM_SLOT_ID
15180+ );
15181+#endif
15182+
15183+ my_output (
15184+ global_data,
15185+ (
15186+ "\n"
15187+ "Slots: (id - name)\n"
15188+ )
15189+ );
15190+
15191+ for (slot_index=0;slot_index < slotnum;slot_index++) {
15192+ CK_SLOT_INFO info;
15193+
15194+ if (
15195+ (rv = pkcs11h_provider->f->C_GetSlotInfo (
15196+ slots[slot_index],
15197+ &info
15198+ )) == CKR_OK
15199+ ) {
15200+ char current_name[sizeof (info.slotDescription)+1];
15201+
15202+ _pkcs11h_util_fixupFixedString (
15203+ current_name,
15204+ (char *)info.slotDescription,
15205+ sizeof (info.slotDescription)
15206+ );
15207+
15208+ my_output (global_data, "\t%lu - %s\n", slots[slot_index], current_name);
15209+ }
15210+ }
15211+ }
15212+
15213+ if (slots != NULL) {
15214+ _pkcs11h_mem_free ((void *)&slots);
15215+ }
15216+ }
15217+
15218+ pkcs11h_terminate ();
15219+}
15220+
15221+static
15222+PKCS11H_BOOL
15223+_pkcs11h_standalone_dump_objects_pin_prompt (
15224+ IN void * const global_data,
15225+ IN void * const user_data,
15226+ IN const pkcs11h_token_id_t token,
15227+ IN const unsigned retry,
15228+ OUT char * const pin,
15229+ IN const size_t pin_max
15230+) {
15231+ (void)user_data;
15232+ (void)token;
15233+
15234+ /*
15235+ * Don't lock card
15236+ */
15237+ if (retry == 0) {
15238+ strncpy (pin, (char *)global_data, pin_max);
15239+ return TRUE;
15240+ }
15241+ else {
15242+ return FALSE;
15243+ }
15244+}
15245+
15246+void
15247+_pkcs11h_standalone_dump_objects_hex (
15248+ IN const unsigned char * const p,
15249+ IN const size_t p_size,
15250+ OUT char * const sz,
15251+ IN const size_t max,
15252+ IN const char * const prefix
15253+) {
15254+ size_t j;
15255+
15256+ sz[0] = '\0';
15257+
15258+ for (j=0;j<p_size;j+=16) {
15259+ char line[3*16+1];
15260+ size_t k;
15261+
15262+ line[0] = '\0';
15263+ for (k=0;k<16 && j+k<p_size;k++) {
15264+ sprintf (line+strlen (line), "%02x ", p[j+k]);
15265+ }
15266+
15267+ strncat (
15268+ sz,
15269+ prefix,
15270+ max-1-strlen (sz)
15271+ );
15272+ strncat (
15273+ sz,
15274+ line,
15275+ max-1-strlen (sz)
15276+ );
15277+ strncat (
15278+ sz,
15279+ "\n",
15280+ max-1-strlen (sz)
15281+ );
15282+ }
15283+
15284+ sz[max-1] = '\0';
15285+}
15286+
15287+void
15288+pkcs11h_standalone_dump_objects (
15289+ IN const pkcs11h_output_print_t my_output,
15290+ IN void * const global_data,
15291+ IN const char * const provider,
15292+ IN const char * const slot,
15293+ IN const char * const pin
15294+) {
15295+ CK_SLOT_ID s;
15296+ CK_RV rv = CKR_OK;
15297+
15298+ pkcs11h_provider_t pkcs11h_provider = NULL;
15299+ pkcs11h_token_id_t token_id = NULL;
15300+ pkcs11h_session_t session = NULL;
15301+
15302+ PKCS11H_ASSERT (my_output!=NULL);
15303+ /*PKCS11H_ASSERT (global_data) NOT NEEDED */
15304+ PKCS11H_ASSERT (provider!=NULL);
15305+ PKCS11H_ASSERT (slot!=NULL);
15306+ PKCS11H_ASSERT (pin!=NULL);
15307+
15308+ s = atoi (slot);
15309+
15310+ if (
15311+ rv == CKR_OK &&
15312+ (rv = pkcs11h_initialize ()) != CKR_OK
15313+ ) {
15314+ my_output (global_data, "PKCS#11: Cannot initialize interface %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
15315+ }
15316+
15317+ if (
15318+ rv == CKR_OK &&
15319+ (rv = pkcs11h_setPINPromptHook (_pkcs11h_standalone_dump_objects_pin_prompt, (void *)pin)) != CKR_OK
15320+ ) {
15321+ my_output (global_data, "PKCS#11: Cannot set hooks %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
15322+ }
15323+
15324+ if (
15325+ rv == CKR_OK &&
15326+ (rv = pkcs11h_addProvider (
15327+ provider,
15328+ provider,
15329+ FALSE,
15330+ (
15331+ PKCS11H_SIGNMODE_MASK_SIGN |
15332+ PKCS11H_SIGNMODE_MASK_RECOVER
15333+ ),
15334+ PKCS11H_SLOTEVENT_METHOD_AUTO,
15335+ 0,
15336+ FALSE
15337+ )) != CKR_OK
15338+ ) {
15339+ my_output (global_data, "PKCS#11: Cannot initialize provider %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
15340+ }
15341+
15342+ /*
15343+ * our provider is head
15344+ */
15345+ if (rv == CKR_OK) {
15346+ pkcs11h_provider = s_pkcs11h_data->providers;
15347+ if (pkcs11h_provider == NULL || !pkcs11h_provider->enabled) {
15348+ my_output (global_data, "PKCS#11: Cannot get provider %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
15349+ rv = CKR_GENERAL_ERROR;
15350+ }
15351+ }
15352+
15353+ if (rv == CKR_OK) {
15354+ CK_TOKEN_INFO info;
15355+
15356+ if (
15357+ (rv = pkcs11h_provider->f->C_GetTokenInfo (
15358+ s,
15359+ &info
15360+ )) != CKR_OK
15361+ ) {
15362+ my_output (global_data, "PKCS#11: Cannot get token information for slot %ld %ld-'%s'\n", s, rv, pkcs11h_getMessage (rv));
15363+ /* Ignore this error */
15364+ rv = CKR_OK;
15365+ }
15366+ else {
15367+ char label[sizeof (info.label)+1];
15368+ char manufacturerID[sizeof (info.manufacturerID)+1];
15369+ char model[sizeof (info.model)+1];
15370+ char serialNumberNumber[sizeof (info.serialNumber)+1];
15371+
15372+ _pkcs11h_util_fixupFixedString (
15373+ label,
15374+ (char *)info.label,
15375+ sizeof (info.label)
15376+ );
15377+ _pkcs11h_util_fixupFixedString (
15378+ manufacturerID,
15379+ (char *)info.manufacturerID,
15380+ sizeof (info.manufacturerID)
15381+ );
15382+ _pkcs11h_util_fixupFixedString (
15383+ model,
15384+ (char *)info.model,
15385+ sizeof (info.model)
15386+ );
15387+ _pkcs11h_util_fixupFixedString (
15388+ serialNumberNumber,
15389+ (char *)info.serialNumber,
15390+ sizeof (info.serialNumber)
15391+ );
15392+
15393+ my_output (
15394+ global_data,
15395+ (
15396+ "Token Information:\n"
15397+ "\tlabel:\t\t%s\n"
15398+ "\tmanufacturerID:\t%s\n"
15399+ "\tmodel:\t\t%s\n"
15400+ "\tserialNumber:\t%s\n"
15401+ "\tflags:\t\t%08x\n"
15402+ "\n"
15403+ ),
15404+ label,
15405+ manufacturerID,
15406+ model,
15407+ serialNumberNumber,
15408+ (unsigned)info.flags
15409+ );
15410+
15411+#if defined(PKCS11H_PRM_SLOT_TYPE)
15412+ my_output (
15413+ global_data,
15414+ (
15415+ "You can access this token using\n"
15416+ "%s \"label\" %s \"%s\" options.\n"
15417+ "\n"
15418+ ),
15419+ PKCS11H_PRM_SLOT_TYPE,
15420+ PKCS11H_PRM_SLOT_ID,
15421+ label
15422+ );
15423+#endif
15424+
15425+ if (
15426+ rv == CKR_OK &&
15427+ (rv = _pkcs11h_token_getTokenId (
15428+ &info,
15429+ &token_id
15430+ )) != CKR_OK
15431+ ) {
15432+ my_output (global_data, "PKCS#11: Cannot get token id for slot %ld %ld-'%s'\n", s, rv, pkcs11h_getMessage (rv));
15433+ rv = CKR_OK;
15434+ }
15435+ }
15436+ }
15437+
15438+ if (token_id != NULL) {
15439+ if (
15440+ (rv = _pkcs11h_session_getSessionByTokenId (
15441+ token_id,
15442+ &session
15443+ )) != CKR_OK
15444+ ) {
15445+ my_output (global_data, "PKCS#11: Cannot session for token '%s' %ld-'%s'\n", token_id->display, rv, pkcs11h_getMessage (rv));
15446+ rv = CKR_OK;
15447+ }
15448+ }
15449+
15450+ if (session != NULL) {
15451+ CK_OBJECT_HANDLE *objects = NULL;
15452+ CK_ULONG objects_found = 0;
15453+ CK_ULONG i;
15454+
15455+ if (
15456+ (rv = _pkcs11h_session_login (
15457+ session,
15458+ FALSE,
15459+ TRUE,
15460+ NULL,
15461+ PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT
15462+ )) != CKR_OK
15463+ ) {
15464+ my_output (global_data, "PKCS#11: Cannot open session to token '%s' %ld-'%s'\n", session->token_id->display, rv, pkcs11h_getMessage (rv));
15465+ }
15466+
15467+ my_output (
15468+ global_data,
15469+ "The following objects are available for use with this token.\n"
15470+ );
15471+
15472+#if defined(PKCS11H_PRM_OBJ_TYPE)
15473+ my_output (
15474+ global_data,
15475+ (
15476+ "Each object shown below may be used as a parameter to\n"
15477+ "%s and %s options.\n"
15478+ ),
15479+ PKCS11H_PRM_OBJ_TYPE,
15480+ PKCS11H_PRM_OBJ_ID
15481+ );
15482+#endif
15483+
15484+ my_output (
15485+ global_data,
15486+ "\n"
15487+ );
15488+
15489+ if (
15490+ rv == CKR_OK &&
15491+ (rv = _pkcs11h_session_findObjects (
15492+ session,
15493+ NULL,
15494+ 0,
15495+ &objects,
15496+ &objects_found
15497+ )) != CKR_OK
15498+ ) {
15499+ my_output (global_data, "PKCS#11: Cannot query objects for token '%s' %ld-'%s'\n", session->token_id->display, rv, pkcs11h_getMessage (rv));
15500+ }
15501+
15502+ for (i=0;rv == CKR_OK && i < objects_found;i++) {
15503+ CK_OBJECT_CLASS attrs_class = 0;
15504+ CK_ATTRIBUTE attrs[] = {
15505+ {CKA_CLASS, &attrs_class, sizeof (attrs_class)}
15506+ };
15507+
15508+ if (
15509+ _pkcs11h_session_getObjectAttributes (
15510+ session,
15511+ objects[i],
15512+ attrs,
15513+ sizeof (attrs) / sizeof (CK_ATTRIBUTE)
15514+ ) == CKR_OK
15515+ ) {
15516+ if (attrs_class == CKO_CERTIFICATE) {
15517+ CK_ATTRIBUTE attrs_cert[] = {
15518+ {CKA_ID, NULL, 0},
15519+ {CKA_LABEL, NULL, 0},
15520+ {CKA_VALUE, NULL, 0}
15521+ };
15522+ unsigned char *attrs_id = NULL;
15523+ int attrs_id_size = 0;
15524+ unsigned char *attrs_value = NULL;
15525+ int attrs_value_size = 0;
15526+ char *attrs_label = NULL;
15527+ char hex_id[1024];
15528+ char subject[1024];
15529+ char serialNumber[1024];
15530+ time_t notAfter = 0;
15531+
15532+ subject[0] = '\0';
15533+ serialNumber[0] = '\0';
15534+
15535+
15536+ if (
15537+ _pkcs11h_session_getObjectAttributes (
15538+ session,
15539+ objects[i],
15540+ attrs_cert,
15541+ sizeof (attrs_cert) / sizeof (CK_ATTRIBUTE)
15542+ ) == CKR_OK &&
15543+ _pkcs11h_mem_malloc (
15544+ (void *)&attrs_label,
15545+ attrs_cert[1].ulValueLen+1
15546+ ) == CKR_OK
15547+ ) {
15548+ attrs_id = (unsigned char *)attrs_cert[0].pValue;
15549+ attrs_id_size = attrs_cert[0].ulValueLen;
15550+ attrs_value = (unsigned char *)attrs_cert[2].pValue;
15551+ attrs_value_size = attrs_cert[2].ulValueLen;
15552+
15553+ memset (attrs_label, 0, attrs_cert[1].ulValueLen+1);
15554+ memmove (attrs_label, attrs_cert[1].pValue, attrs_cert[1].ulValueLen);
15555+ _pkcs11h_standalone_dump_objects_hex (
15556+ attrs_id,
15557+ attrs_id_size,
15558+ hex_id,
15559+ sizeof (hex_id),
15560+ "\t\t"
15561+ );
15562+ }
15563+
15564+ if (attrs_value != NULL) {
15565+#if defined(USE_PKCS11H_OPENSSL)
15566+ X509 *x509 = NULL;
15567+ BIO *bioSerial = NULL;
15568+#elif defined(USE_PKCS11H_GNUTLS)
15569+ gnutls_x509_crt_t cert = NULL;
15570+#endif
15571+
15572+ _pkcs11h_certificate_getDN (
15573+ attrs_value,
15574+ attrs_value_size,
15575+ subject,
15576+ sizeof (subject)
15577+ );
15578+ notAfter = _pkcs11h_certificate_getExpiration (
15579+ attrs_value,
15580+ attrs_value_size
15581+ );
15582+#if defined(USE_PKCS11H_OPENSSL)
15583+ if ((x509 = X509_new ()) == NULL) {
15584+ my_output (global_data, "Cannot create x509 context\n");
15585+ }
15586+ else {
15587+ pkcs11_openssl_d2i_t d2i1 = (pkcs11_openssl_d2i_t)attrs_value;
15588+ if (d2i_X509 (&x509, &d2i1, attrs_value_size)) {
15589+ if ((bioSerial = BIO_new (BIO_s_mem ())) == NULL) {
15590+ my_output (global_data, "Cannot create BIO context\n");
15591+ }
15592+ else {
15593+ int n;
15594+
15595+ i2a_ASN1_INTEGER(bioSerial, X509_get_serialNumber (x509));
15596+ n = BIO_read (bioSerial, serialNumber, sizeof (serialNumber)-1);
15597+ if (n<0) {
15598+ serialNumber[0] = '\0';
15599+ }
15600+ else {
15601+ serialNumber[n] = '\0';
15602+ }
15603+ }
15604+ }
15605+ }
15606+
15607+
15608+ if (bioSerial != NULL) {
15609+ BIO_free_all (bioSerial);
15610+ bioSerial = NULL;
15611+ }
15612+ if (x509 != NULL) {
15613+ X509_free (x509);
15614+ x509 = NULL;
15615+ }
15616+#elif defined(USE_PKCS11H_GNUTLS)
15617+ if (gnutls_x509_crt_init (&cert) == GNUTLS_E_SUCCESS) {
15618+ gnutls_datum_t datum = {attrs_value, attrs_value_size};
15619+
15620+ if (gnutls_x509_crt_import (cert, &datum, GNUTLS_X509_FMT_DER) == GNUTLS_E_SUCCESS) {
15621+ unsigned char ser[1024];
15622+ size_t ser_size = sizeof (ser);
15623+ if (gnutls_x509_crt_get_serial (cert, ser, &ser_size) == GNUTLS_E_SUCCESS) {
15624+ _pkcs11h_util_binaryToHex (
15625+ serialNumber,
15626+ sizeof (serialNumber),
15627+ ser,
15628+ ser_size
15629+ );
15630+ }
15631+ }
15632+ gnutls_x509_crt_deinit (cert);
15633+ }
15634+#else
15635+#error Invalid configuration.
15636+#endif
15637+ }
15638+
15639+ my_output (
15640+ global_data,
15641+ (
15642+ "Object\n"
15643+ "\tType:\t\t\tCertificate\n"
15644+ "\tCKA_ID:\n"
15645+ "%s"
15646+ "\tCKA_LABEL:\t\t%s\n"
15647+ "\tsubject:\t\t%s\n"
15648+ "\tserialNumber:\t\t%s\n"
15649+ "\tnotAfter:\t\t%s\n"
15650+ ),
15651+ hex_id,
15652+ attrs_label,
15653+ subject,
15654+ serialNumber,
15655+ asctime (localtime (&notAfter))
15656+ );
15657+
15658+ _pkcs11h_mem_free ((void *)&attrs_label);
15659+
15660+ _pkcs11h_session_freeObjectAttributes (
15661+ attrs_cert,
15662+ sizeof (attrs_cert) / sizeof (CK_ATTRIBUTE)
15663+ );
15664+ }
15665+ else if (attrs_class == CKO_PRIVATE_KEY) {
15666+ CK_BBOOL sign_recover = CK_FALSE;
15667+ CK_BBOOL sign = CK_FALSE;
15668+ CK_ATTRIBUTE attrs_key[] = {
15669+ {CKA_SIGN, &sign, sizeof (sign)},
15670+ {CKA_SIGN_RECOVER, &sign_recover, sizeof (sign_recover)}
15671+ };
15672+ CK_ATTRIBUTE attrs_key_common[] = {
15673+ {CKA_ID, NULL, 0},
15674+ {CKA_LABEL, NULL, 0}
15675+ };
15676+ unsigned char *attrs_id = NULL;
15677+ int attrs_id_size = 0;
15678+ char *attrs_label = NULL;
15679+ char hex_id[1024];
15680+
15681+ pkcs11h_provider->f->C_GetAttributeValue (
15682+ session->session_handle,
15683+ objects[i],
15684+ attrs_key,
15685+ sizeof (attrs_key) / sizeof (CK_ATTRIBUTE)
15686+ );
15687+
15688+ if (
15689+ _pkcs11h_session_getObjectAttributes (
15690+ session,
15691+ objects[i],
15692+ attrs_key_common,
15693+ sizeof (attrs_key_common) / sizeof (CK_ATTRIBUTE)
15694+ ) == CKR_OK &&
15695+ _pkcs11h_mem_malloc (
15696+ (void *)&attrs_label,
15697+ attrs_key_common[1].ulValueLen+1
15698+ ) == CKR_OK
15699+ ) {
15700+ attrs_id = (unsigned char *)attrs_key_common[0].pValue;
15701+ attrs_id_size = attrs_key_common[0].ulValueLen;
15702+
15703+ memset (attrs_label, 0, attrs_key_common[1].ulValueLen+1);
15704+ memmove (attrs_label, attrs_key_common[1].pValue, attrs_key_common[1].ulValueLen);
15705+
15706+ _pkcs11h_standalone_dump_objects_hex (
15707+ attrs_id,
15708+ attrs_id_size,
15709+ hex_id,
15710+ sizeof (hex_id),
15711+ "\t\t"
15712+ );
15713+
15714+ }
15715+
15716+ my_output (
15717+ global_data,
15718+ (
15719+ "Object\n"
15720+ "\tType:\t\t\tPrivate Key\n"
15721+ "\tCKA_ID:\n"
15722+ "%s"
15723+ "\tCKA_LABEL:\t\t%s\n"
15724+ "\tCKA_SIGN:\t\t%s\n"
15725+ "\tCKA_SIGN_RECOVER:\t%s\n"
15726+ ),
15727+ hex_id,
15728+ attrs_label,
15729+ sign ? "TRUE" : "FALSE",
15730+ sign_recover ? "TRUE" : "FALSE"
15731+ );
15732+
15733+ _pkcs11h_mem_free ((void *)&attrs_label);
15734+
15735+ _pkcs11h_session_freeObjectAttributes (
15736+ attrs_key_common,
15737+ sizeof (attrs_key_common) / sizeof (CK_ATTRIBUTE)
15738+ );
15739+ }
15740+ else if (attrs_class == CKO_PUBLIC_KEY) {
15741+ CK_ATTRIBUTE attrs_key_common[] = {
15742+ {CKA_ID, NULL, 0},
15743+ {CKA_LABEL, NULL, 0}
15744+ };
15745+ unsigned char *attrs_id = NULL;
15746+ int attrs_id_size = 0;
15747+ char *attrs_label = NULL;
15748+ char hex_id[1024];
15749+
15750+ if (
15751+ _pkcs11h_session_getObjectAttributes (
15752+ session,
15753+ objects[i],
15754+ attrs_key_common,
15755+ sizeof (attrs_key_common) / sizeof (CK_ATTRIBUTE)
15756+ ) == CKR_OK &&
15757+ _pkcs11h_mem_malloc (
15758+ (void *)&attrs_label,
15759+ attrs_key_common[1].ulValueLen+1
15760+ ) == CKR_OK
15761+ ) {
15762+ attrs_id = (unsigned char *)attrs_key_common[0].pValue;
15763+ attrs_id_size = attrs_key_common[0].ulValueLen;
15764+
15765+ memset (attrs_label, 0, attrs_key_common[1].ulValueLen+1);
15766+ memmove (attrs_label, attrs_key_common[1].pValue, attrs_key_common[1].ulValueLen);
15767+
15768+ _pkcs11h_standalone_dump_objects_hex (
15769+ attrs_id,
15770+ attrs_id_size,
15771+ hex_id,
15772+ sizeof (hex_id),
15773+ "\t\t"
15774+ );
15775+
15776+ }
15777+
15778+ my_output (
15779+ global_data,
15780+ (
15781+ "Object\n"
15782+ "\tType:\t\t\tPublic Key\n"
15783+ "\tCKA_ID:\n"
15784+ "%s"
15785+ "\tCKA_LABEL:\t\t%s\n"
15786+ ),
15787+ hex_id,
15788+ attrs_label
15789+ );
15790+
15791+ _pkcs11h_mem_free ((void *)&attrs_label);
15792+
15793+ _pkcs11h_session_freeObjectAttributes (
15794+ attrs_key_common,
15795+ sizeof (attrs_key_common) / sizeof (CK_ATTRIBUTE)
15796+ );
15797+ }
15798+ else if (attrs_class == CKO_DATA) {
15799+ CK_ATTRIBUTE attrs_key_common[] = {
15800+ {CKA_APPLICATION, NULL, 0},
15801+ {CKA_LABEL, NULL, 0}
15802+ };
15803+ char *attrs_application = NULL;
15804+ char *attrs_label = NULL;
15805+
15806+ if (
15807+ _pkcs11h_session_getObjectAttributes (
15808+ session,
15809+ objects[i],
15810+ attrs_key_common,
15811+ sizeof (attrs_key_common) / sizeof (CK_ATTRIBUTE)
15812+ ) == CKR_OK &&
15813+ _pkcs11h_mem_malloc (
15814+ (void *)&attrs_application,
15815+ attrs_key_common[0].ulValueLen+1
15816+ ) == CKR_OK &&
15817+ _pkcs11h_mem_malloc (
15818+ (void *)&attrs_label,
15819+ attrs_key_common[1].ulValueLen+1
15820+ ) == CKR_OK
15821+ ) {
15822+ memset (attrs_application, 0, attrs_key_common[0].ulValueLen+1);
15823+ memmove (attrs_application, attrs_key_common[0].pValue, attrs_key_common[0].ulValueLen);
15824+ memset (attrs_label, 0, attrs_key_common[1].ulValueLen+1);
15825+ memmove (attrs_label, attrs_key_common[1].pValue, attrs_key_common[1].ulValueLen);
15826+ }
15827+
15828+ my_output (
15829+ global_data,
15830+ (
15831+ "Object\n"
15832+ "\tType:\t\t\tData\n"
15833+ "\tCKA_APPLICATION\t\t%s\n"
15834+ "\tCKA_LABEL:\t\t%s\n"
15835+ ),
15836+ attrs_application,
15837+ attrs_label
15838+ );
15839+
15840+ _pkcs11h_mem_free ((void *)&attrs_application);
15841+ _pkcs11h_mem_free ((void *)&attrs_label);
15842+
15843+ _pkcs11h_session_freeObjectAttributes (
15844+ attrs_key_common,
15845+ sizeof (attrs_key_common) / sizeof (CK_ATTRIBUTE)
15846+ );
15847+ }
15848+ else {
15849+ my_output (
15850+ global_data,
15851+ (
15852+ "Object\n"
15853+ "\tType:\t\t\tUnsupported\n"
15854+ )
15855+ );
15856+ }
15857+ }
15858+
15859+ _pkcs11h_session_freeObjectAttributes (
15860+ attrs,
15861+ sizeof (attrs) / sizeof (CK_ATTRIBUTE)
15862+ );
15863+
15864+ /*
15865+ * Ignore any error and
15866+ * perform next iteration
15867+ */
15868+ rv = CKR_OK;
15869+ }
15870+
15871+ if (objects != NULL) {
15872+ _pkcs11h_mem_free ((void *)&objects);
15873+ }
15874+
15875+ /*
15876+ * Ignore this error
15877+ */
15878+ rv = CKR_OK;
15879+ }
15880+
15881+ if (session != NULL) {
15882+ _pkcs11h_session_release (session);
15883+ session = NULL;
15884+ }
15885+
15886+ if (token_id != NULL) {
15887+ pkcs11h_token_freeTokenId (token_id);
15888+ token_id = NULL;
15889+ }
15890+
15891+ pkcs11h_terminate ();
15892+}
15893+
15894+#endif /* ENABLE_PKCS11H_STANDALONE */
15895+
15896+#ifdef BROKEN_OPENSSL_ENGINE
15897+static void broken_openssl_init() __attribute__ ((constructor));
15898+static void broken_openssl_init()
15899+{
15900+ SSL_library_init();
15901+ ENGINE_load_openssl();
15902+ ENGINE_register_all_RSA();
15903+}
15904+#endif
15905+
15906+#else
15907+static void dummy (void) {}
15908+#endif /* PKCS11H_HELPER_ENABLE */
15909+
15910diff -urNp openssh-4.4p1/pkcs11-helper-config.h openssh-4.4p1+pkcs11-0.17/pkcs11-helper-config.h
15911--- openssh-4.4p1/pkcs11-helper-config.h 1970-01-01 02:00:00.000000000 +0200
15912+++ openssh-4.4p1+pkcs11-0.17/pkcs11-helper-config.h 2006-10-12 16:43:38.000000000 +0200
15913@@ -0,0 +1,103 @@
15914+/*
15915+ * Copyright (c) 2005-2006 Alon Bar-Lev. All rights reserved.
15916+ *
15917+ * Redistribution and use in source and binary forms, with or without
15918+ * modification, are permitted provided that the following conditions
15919+ * are met:
15920+ * 1. Redistributions of source code must retain the above copyright
15921+ * notice, this list of conditions and the following disclaimer.
15922+ * 2. Redistributions in binary form must reproduce the above copyright
15923+ * notice, this list of conditions and the following disclaimer in the
15924+ * documentation and/or other materials provided with the distribution.
15925+ *
15926+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15927+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15928+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
15929+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
15930+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
15931+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
15932+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
15933+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
15934+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
15935+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15936+ */
15937+
15938+#ifndef __PKCS11H_HELPER_CONFIG_H
15939+#define __PKCS11H_HELPER_CONFIG_H
15940+
15941+#if !defined(PKCS11H_NO_NEED_INCLUDE_CONFIG)
15942+
15943+#include "includes.h"
15944+
15945+#endif /* PKCS11H_NO_NEED_INCLUDE_CONFIG */
15946+
15947+#ifndef SSH_PKCS11H_DISABLED
15948+#define ENABLE_PKCS11H_HELPER
15949+#endif
15950+
15951+#include <assert.h>
15952+#include <string.h>
15953+#include <ctype.h>
15954+#if !defined(WIN32)
15955+#include <unistd.h>
15956+#include <dlfcn.h>
15957+#endif
15958+
15959+#include "log.h"
15960+#include "xmalloc.h"
15961+#include "openssl/x509.h"
15962+
15963+#if defined(HAVE_CYGWIN)
15964+#define PKCS11H_USE_CYGWIN
15965+#endif
15966+
15967+#if !defined(FALSE)
15968+#define FALSE 0
15969+#endif
15970+#if !defined(TRUE)
15971+#define TRUE (!FALSE)
15972+#endif
15973+
15974+typedef int PKCS11H_BOOL;
15975+
15976+#if !defined(IN)
15977+#define IN
15978+#endif
15979+#if !defined(OUT)
15980+#define OUT
15981+#endif
15982+
15983+#define USE_PKCS11H_OPENSSL
15984+#define ENABLE_PKCS11H_DEBUG
15985+#undef ENABLE_PKCS11H_THREADING
15986+#undef ENABLE_PKCS11H_TOKEN
15987+#undef ENABLE_PKCS11H_DATA
15988+#define ENABLE_PKCS11H_CERTIFICATE
15989+#undef ENABLE_PKCS11H_LOCATE
15990+#define ENABLE_PKCS11H_ENUM
15991+#define ENABLE_PKCS11H_SERIALIZATION
15992+#undef ENABLE_PKCS11H_SLOTEVENT
15993+#define ENABLE_PKCS11H_OPENSSL
15994+#define ENABLE_PKCS11H_STANDALONE
15995+
15996+/*
15997+#define PKCS11H_PRM_SLOT_TYPE "--pkcs11-slot-type"
15998+#define PKCS11H_PRM_SLOT_ID "--pkcs11-slot"
15999+#define PKCS11H_PRM_OBJ_TYPE "--pkcs11-id-type"
16000+#define PKCS11H_PRM_OBJ_ID "--pkcs11-id"
16001+*/
16002+
16003+#define PKCS11H_ASSERT assert
16004+#define PKCS11H_TIME time
16005+#define PKCS11H_MALLOC xmalloc
16006+#define PKCS11H_FREE xfree
16007+
16008+#ifdef ENABLE_PKCS11H_HELPER
16009+#if defined(WIN32) || defined(PKCS11H_USE_CYGWIN)
16010+#include "cryptoki-win32.h"
16011+#else
16012+#include "cryptoki.h"
16013+#endif
16014+
16015+#endif /* ENABLE_PKCS11H_HELPER */
16016+#endif /* __PKCS11H_HELPER_CONFIG_H */
16017diff -urNp openssh-4.4p1/pkcs11-helper.h openssh-4.4p1+pkcs11-0.17/pkcs11-helper.h
16018--- openssh-4.4p1/pkcs11-helper.h 1970-01-01 02:00:00.000000000 +0200
16019+++ openssh-4.4p1+pkcs11-0.17/pkcs11-helper.h 2006-10-22 17:11:14.000000000 +0200
16020@@ -0,0 +1,1303 @@
16021+/*
16022+ * Copyright (c) 2005-2006 Alon Bar-Lev <alon.barlev@gmail.com>
16023+ * All rights reserved.
16024+ *
16025+ * This software is available to you under a choice of one of two
16026+ * licenses. You may choose to be licensed under the terms of the GNU
16027+ * General Public License (GPL) Version 2, or the OpenIB.org BSD license.
16028+ *
16029+ * GNU General Public License (GPL) Version 2
16030+ * ===========================================
16031+ * This program is free software; you can redistribute it and/or modify
16032+ * it under the terms of the GNU General Public License version 2
16033+ * as published by the Free Software Foundation.
16034+ *
16035+ * This program is distributed in the hope that it will be useful,
16036+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16037+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16038+ * GNU General Public License for more details.
16039+ *
16040+ * You should have received a copy of the GNU General Public License
16041+ * along with this program (see the file COPYING[.GPL2] included with this
16042+ * distribution); if not, write to the Free Software Foundation, Inc.,
16043+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16044+ *
16045+ * OpenIB.org BSD license
16046+ * =======================
16047+ * Redistribution and use in source and binary forms, with or without modifi-
16048+ * cation, are permitted provided that the following conditions are met:
16049+ *
16050+ * o Redistributions of source code must retain the above copyright notice,
16051+ * this list of conditions and the following disclaimer.
16052+ *
16053+ * o Redistributions in binary form must reproduce the above copyright no-
16054+ * tice, this list of conditions and the following disclaimer in the do-
16055+ * cumentation and/or other materials provided with the distribution.
16056+ *
16057+ * o The names of the contributors may not be used to endorse or promote
16058+ * products derived from this software without specific prior written
16059+ * permission.
16060+ *
16061+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16062+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
16063+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16064+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LI-
16065+ * ABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUEN-
16066+ * TIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
16067+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEV-
16068+ * ER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABI-
16069+ * LITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
16070+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16071+ */
16072+
16073+/*
16074+ * The routines in this file deal with providing private key cryptography
16075+ * using RSA Security Inc. PKCS #11 Cryptographic Token Interface (Cryptoki).
16076+ *
16077+ */
16078+
16079+#ifndef __PKCS11H_HELPER_H
16080+#define __PKCS11H_HELPER_H
16081+
16082+#if defined(__cplusplus)
16083+extern "C" {
16084+#endif
16085+
16086+#include "pkcs11-helper-config.h"
16087+
16088+#if !defined(USE_PKCS11H_OPENSSL) && !defined(USE_PKCS11H_GNUTLS)
16089+#error PKCS#11: USE_PKCS11H_OPENSSL or USE_PKCS11H_GNUTLS must be defined
16090+#endif
16091+
16092+#if defined(ENABLE_PKCS11H_SLOTEVENT) && !defined(ENABLE_PKCS11H_THREADING)
16093+#error PKCS#11: ENABLE_PKCS11H_SLOTEVENT requires ENABLE_PKCS11H_THREADING
16094+#endif
16095+#if defined(ENABLE_PKCS11H_OPENSSL) && !defined(ENABLE_PKCS11H_CERTIFICATE)
16096+#error PKCS#11: ENABLE_PKCS11H_OPENSSL requires ENABLE_PKCS11H_CERTIFICATE
16097+#endif
16098+
16099+#define PKCS11H_LOG_DEBUG2 5
16100+#define PKCS11H_LOG_DEBUG1 4
16101+#define PKCS11H_LOG_INFO 3
16102+#define PKCS11H_LOG_WARN 2
16103+#define PKCS11H_LOG_ERROR 1
16104+#define PKCS11H_LOG_QUITE 0
16105+
16106+#define PKCS11H_PIN_CACHE_INFINITE -1
16107+
16108+#define PKCS11H_SIGNMODE_MASK_SIGN (1<<0)
16109+#define PKCS11H_SIGNMODE_MASK_RECOVER (1<<1)
16110+
16111+#define PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT (1<<0)
16112+#define PKCS11H_PROMPT_MAST_ALLOW_CARD_PROMPT (1<<1)
16113+#define PKCS11H_PROMPT_MASK_ALLOW_ALL ( \
16114+ PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT | \
16115+ PKCS11H_PROMPT_MAST_ALLOW_CARD_PROMPT \
16116+ )
16117+
16118+#define PKCS11H_SLOTEVENT_METHOD_AUTO 0
16119+#define PKCS11H_SLOTEVENT_METHOD_TRIGGER 1
16120+#define PKCS11H_SLOTEVENT_METHOD_POLL 2
16121+
16122+#define PKCS11H_ENUM_METHOD_CACHE 0
16123+#define PKCS11H_ENUM_METHOD_CACHE_EXIST 1
16124+#define PKCS11H_ENUM_METHOD_RELOAD 2
16125+
16126+typedef void (*pkcs11h_output_print_t)(
16127+ IN void * const global_data,
16128+ IN const char * const format,
16129+ IN ...
16130+)
16131+#if __GNUC__ > 2
16132+ __attribute__ ((format (printf, 2, 3)))
16133+#endif
16134+ ;
16135+
16136+struct pkcs11h_token_id_s;
16137+typedef struct pkcs11h_token_id_s *pkcs11h_token_id_t;
16138+
16139+#if defined(ENABLE_PKCS11H_CERTIFICATE)
16140+
16141+struct pkcs11h_certificate_id_s;
16142+struct pkcs11h_certificate_s;
16143+typedef struct pkcs11h_certificate_id_s *pkcs11h_certificate_id_t;
16144+typedef struct pkcs11h_certificate_s *pkcs11h_certificate_t;
16145+
16146+#endif /* ENABLE_PKCS11H_CERTIFICATE */
16147+
16148+#if defined(ENABLE_PKCS11H_ENUM)
16149+
16150+struct pkcs11h_token_id_list_s;
16151+typedef struct pkcs11h_token_id_list_s *pkcs11h_token_id_list_t;
16152+
16153+#if defined(ENABLE_PKCS11H_DATA)
16154+
16155+struct pkcs11h_data_id_list_s;
16156+typedef struct pkcs11h_data_id_list_s *pkcs11h_data_id_list_t;
16157+
16158+#endif /* ENABLE_PKCS11H_DATA */
16159+
16160+#if defined(ENABLE_PKCS11H_CERTIFICATE)
16161+
16162+struct pkcs11h_certificate_id_list_s;
16163+typedef struct pkcs11h_certificate_id_list_s *pkcs11h_certificate_id_list_t;
16164+
16165+#endif /* ENABLE_PKCS11H_CERTIFICATE */
16166+
16167+#endif /* ENABLE_PKCS11H_ENUM */
16168+
16169+typedef void (*pkcs11h_hook_log_t)(
16170+ IN void * const global_data,
16171+ IN const unsigned flags,
16172+ IN const char * const format,
16173+ IN va_list args
16174+);
16175+
16176+typedef void (*pkcs11h_hook_slotevent_t)(
16177+ IN void * const global_data
16178+);
16179+
16180+typedef PKCS11H_BOOL (*pkcs11h_hook_token_prompt_t)(
16181+ IN void * const global_data,
16182+ IN void * const user_data,
16183+ IN const pkcs11h_token_id_t token,
16184+ IN const unsigned retry
16185+);
16186+
16187+typedef PKCS11H_BOOL (*pkcs11h_hook_pin_prompt_t)(
16188+ IN void * const global_data,
16189+ IN void * const user_data,
16190+ IN const pkcs11h_token_id_t token,
16191+ IN const unsigned retry,
16192+ OUT char * const pin,
16193+ IN const size_t pin_max
16194+);
16195+
16196+struct pkcs11h_token_id_s {
16197+ char display[1024];
16198+ char manufacturerID[sizeof (((CK_TOKEN_INFO *)NULL)->manufacturerID)+1];
16199+ char model[sizeof (((CK_TOKEN_INFO *)NULL)->model)+1];
16200+ char serialNumber[sizeof (((CK_TOKEN_INFO *)NULL)->serialNumber)+1];
16201+ char label[sizeof (((CK_TOKEN_INFO *)NULL)->label)+1];
16202+};
16203+
16204+#if defined(ENABLE_PKCS11H_CERTIFICATE)
16205+
16206+struct pkcs11h_certificate_id_s {
16207+ pkcs11h_token_id_t token_id;
16208+
16209+ char displayName[1024];
16210+ CK_BYTE_PTR attrCKA_ID;
16211+ size_t attrCKA_ID_size;
16212+
16213+ unsigned char *certificate_blob;
16214+ size_t certificate_blob_size;
16215+};
16216+
16217+#endif
16218+
16219+#if defined(ENABLE_PKCS11H_ENUM)
16220+
16221+struct pkcs11h_token_id_list_s {
16222+ pkcs11h_token_id_list_t next;
16223+ pkcs11h_token_id_t token_id;
16224+};
16225+
16226+#if defined(ENABLE_PKCS11H_DATA)
16227+
16228+struct pkcs11h_data_id_list_s {
16229+ pkcs11h_data_id_list_t next;
16230+
16231+ char *application;
16232+ char *label;
16233+};
16234+
16235+#endif /* ENABLE_PKCS11H_DATA */
16236+
16237+#if defined(ENABLE_PKCS11H_CERTIFICATE)
16238+
16239+struct pkcs11h_certificate_id_list_s {
16240+ pkcs11h_certificate_id_list_t next;
16241+ pkcs11h_certificate_id_t certificate_id;
16242+};
16243+
16244+#endif /* ENABLE_PKCS11H_CERTIFICATE */
16245+
16246+#endif /* ENABLE_PKCS11H_CERTIFICATE */
16247+
16248+#if defined(ENABLE_PKCS11H_OPENSSL)
16249+
16250+typedef void (*pkcs11h_hook_openssl_cleanup_t) (
16251+ IN const pkcs11h_certificate_t certificate
16252+);
16253+
16254+struct pkcs11h_openssl_session_s;
16255+typedef struct pkcs11h_openssl_session_s *pkcs11h_openssl_session_t;
16256+
16257+#endif /* ENABLE_PKCS11H_OPENSSL */
16258+
16259+/*
16260+ * pkcs11h_getMessage - Get message by return value.
16261+ *
16262+ * Parameters:
16263+ * rv - Return value.
16264+ */
16265+const char *
16266+pkcs11h_getMessage (
16267+ IN const CK_RV rv
16268+);
16269+
16270+/*
16271+ * pkcs11h_initialize - Inititalize helper interface.
16272+ *
16273+ * Must be called once, from main thread.
16274+ * Defaults:
16275+ * Protected authentication enabled.
16276+ * PIN cached is infinite.
16277+ */
16278+CK_RV
16279+pkcs11h_initialize ();
16280+
16281+/*
16282+ * pkcs11h_terminate - Terminate helper interface.
16283+ *
16284+ * Must be called once, from main thread, after all
16285+ * related resources freed.
16286+ */
16287+CK_RV
16288+pkcs11h_terminate ();
16289+
16290+/*
16291+ * pkcs11h_setLogLevel - Set current log level of the helper.
16292+ *
16293+ * Parameters:
16294+ * flags - current log level.
16295+ *
16296+ * The log level can be set to maximum, but setting it to lower
16297+ * level will improve performance.
16298+ */
16299+void
16300+pkcs11h_setLogLevel (
16301+ IN const unsigned flags
16302+);
16303+
16304+/*
16305+ * pkcs11h_getLogLevel - Get current log level.
16306+ */
16307+unsigned
16308+pkcs11h_getLogLevel ();
16309+
16310+/*
16311+ * pkcs11h_setLogHook - Set a log callback.
16312+ *
16313+ * Parameters:
16314+ * hook - Callback.
16315+ * pData - Data to send to callback.
16316+ */
16317+CK_RV
16318+pkcs11h_setLogHook (
16319+ IN const pkcs11h_hook_log_t hook,
16320+ IN void * const global_data
16321+);
16322+
16323+/*
16324+ * pkcs11h_setSlotEventHook - Set a slot event callback.
16325+ *
16326+ * Parameters:
16327+ * hook - Callback.
16328+ * pData - Data to send to callback.
16329+ *
16330+ * Calling this function initialize slot event notifications, these
16331+ * notifications can be started, but never terminate due to PKCS#11 limitation.
16332+ *
16333+ * In order to use slot events you must have threading enabled.
16334+ */
16335+CK_RV
16336+pkcs11h_setSlotEventHook (
16337+ IN const pkcs11h_hook_slotevent_t hook,
16338+ IN void * const global_data
16339+);
16340+
16341+/*
16342+ * pkcs11h_setTokenPromptHook - Set a token prompt callback.
16343+ *
16344+ * Parameters:
16345+ * hook - Callback.
16346+ * pData - Data to send to callback.
16347+ */
16348+CK_RV
16349+pkcs11h_setTokenPromptHook (
16350+ IN const pkcs11h_hook_token_prompt_t hook,
16351+ IN void * const global_data
16352+);
16353+
16354+/*
16355+ * pkcs11h_setPINPromptHook - Set a pin prompt callback.
16356+ *
16357+ * Parameters:
16358+ * hook - Callback.
16359+ * pData - Data to send to callback.
16360+ */
16361+CK_RV
16362+pkcs11h_setPINPromptHook (
16363+ IN const pkcs11h_hook_pin_prompt_t hook,
16364+ IN void * const global_data
16365+);
16366+
16367+/*
16368+ * pkcs11h_setProtectedAuthentication - Set global protected authentication mode.
16369+ *
16370+ * Parameters:
16371+ * allow_protected_auth - Allow protected authentication if enabled by token.
16372+ */
16373+CK_RV
16374+pkcs11h_setProtectedAuthentication (
16375+ IN const PKCS11H_BOOL allow_protected_auth
16376+);
16377+
16378+/*
16379+ * pkcs11h_setPINCachePeriod - Set global PIN cache timeout.
16380+ *
16381+ * Parameters:
16382+ * pin_cache_period - Cache period in seconds, or PKCS11H_PIN_CACHE_INFINITE.
16383+ */
16384+CK_RV
16385+pkcs11h_setPINCachePeriod (
16386+ IN const int pin_cache_period
16387+);
16388+
16389+/*
16390+ * pkcs11h_setMaxLoginRetries - Set global login retries attempts.
16391+ *
16392+ * Parameters:
16393+ * max_retries - Login retries handled by the helper.
16394+ */
16395+CK_RV
16396+pkcs11h_setMaxLoginRetries (
16397+ IN const unsigned max_retries
16398+);
16399+
16400+/*
16401+ * pkcs11h_addProvider - Add a PKCS#11 provider.
16402+ *
16403+ * Parameters:
16404+ * reference - Reference name for this provider.
16405+ * provider - Provider library location.
16406+ * allow_protected_auth - Allow this provider to use protected authentication.
16407+ * mask_sign_mode - Provider signmode override.
16408+ * slot_event_method - Provider slot event method.
16409+ * slot_poll_interval - Slot event poll interval (If in polling mode).
16410+ * cert_is_private - Provider's certificate access should be done after login.
16411+ *
16412+ * This function must be called from the main thread.
16413+ *
16414+ * The global allow_protected_auth must be enabled in order to allow provider specific.
16415+ * The mask_sign_mode can be 0 in order to automatically detect key sign mode.
16416+ */
16417+CK_RV
16418+pkcs11h_addProvider (
16419+ IN const char * const reference,
16420+ IN const char * const provider_location,
16421+ IN const PKCS11H_BOOL allow_protected_auth,
16422+ IN const unsigned mask_sign_mode,
16423+ IN const int slot_event_method,
16424+ IN const int slot_poll_interval,
16425+ IN const PKCS11H_BOOL cert_is_private
16426+);
16427+
16428+/*
16429+ * pkcs11h_delProvider - Delete a PKCS#11 provider.
16430+ *
16431+ * Parameters:
16432+ * reference - Reference name for this provider.
16433+ *
16434+ * This function must be called from the main thread.
16435+ */
16436+CK_RV
16437+pkcs11h_removeProvider (
16438+ IN const char * const reference
16439+);
16440+
16441+/*
16442+ * pkcs11h_forkFixup - Handle special case of Unix fork()
16443+ *
16444+ * This function should be called after fork is called. This is required
16445+ * due to a limitation of the PKCS#11 standard.
16446+ *
16447+ * This function must be called from the main thread.
16448+ *
16449+ * The helper library handles fork automatically if ENABLE_PKCS11H_THREADING
16450+ * is set on configuration file, by use of pthread_atfork.
16451+ */
16452+CK_RV
16453+pkcs11h_forkFixup ();
16454+
16455+/*
16456+ * pkcs11h_plugAndPlay - Handle slot rescan.
16457+ *
16458+ * This function must be called from the main thread.
16459+ *
16460+ * PKCS#11 providers do not allow plug&play, plug&play can be established by
16461+ * finalizing all providers and initializing them again.
16462+ *
16463+ * The cost of this process is invalidating all sessions, and require user
16464+ * login at the next access.
16465+ */
16466+CK_RV
16467+pkcs11h_plugAndPlay ();
16468+
16469+/*
16470+ * pkcs11h_token_freeTokenId - Free token_id object.
16471+ *
16472+ * Parameters:
16473+ * token_id - token_id.
16474+ */
16475+CK_RV
16476+pkcs11h_token_freeTokenId (
16477+ IN pkcs11h_token_id_t token_id
16478+);
16479+
16480+/*
16481+ * pkcs11h_duplicateTokenId - Duplicate token_id object.
16482+ *
16483+ * Parameters:
16484+ * to - target.
16485+ * from - source.
16486+ */
16487+CK_RV
16488+pkcs11h_token_duplicateTokenId (
16489+ OUT pkcs11h_token_id_t * const to,
16490+ IN const pkcs11h_token_id_t from
16491+);
16492+
16493+/*
16494+ * pkcs11h_sameTokenId - Returns TRUE if same token id
16495+ *
16496+ * Parameters:
16497+ * a - a.
16498+ * b - b.
16499+ */
16500+PKCS11H_BOOL
16501+pkcs11h_token_sameTokenId (
16502+ IN const pkcs11h_token_id_t a,
16503+ IN const pkcs11h_token_id_t b
16504+);
16505+
16506+/*
16507+ * pkcs11h_token_login - Force login, avoid hooks.
16508+ *
16509+ * Parameters:
16510+ * token_id - Token to login into.
16511+ * readonly - Should session be readonly.
16512+ * pin - PIN to login, NULL for protected authentication
16513+ */
16514+CK_RV
16515+pkcs11h_token_login (
16516+ IN const pkcs11h_token_id_t token_id,
16517+ IN const PKCS11H_BOOL readonly,
16518+ IN const char * const pin
16519+);
16520+
16521+#if defined(ENABLE_PKCS11H_SERIALIZATION)
16522+
16523+/*
16524+ * pkcs11h_serializeTokenId - Serialize token_id into string.
16525+ *
16526+ * Parameters:
16527+ * sz - Output string.
16528+ * max - Maximum string size.
16529+ * token_id - id to serialize
16530+ *
16531+ * sz may be NULL to get size
16532+ */
16533+CK_RV
16534+pkcs11h_token_serializeTokenId (
16535+ OUT char * const sz,
16536+ IN OUT size_t *max,
16537+ IN const pkcs11h_token_id_t token_id
16538+);
16539+
16540+/*
16541+ * pkcs11h_deserializeTokenId - Deserialize token_id from string.
16542+ *
16543+ * Parameters:
16544+ * p_token_id - id.
16545+ * sz - Input string
16546+ */
16547+CK_RV
16548+pkcs11h_token_deserializeTokenId (
16549+ OUT pkcs11h_token_id_t *p_token_id,
16550+ IN const char * const sz
16551+);
16552+
16553+#endif /* ENABLE_PKCS11H_SERIALIZATION */
16554+
16555+#if defined(ENABLE_PKCS11H_TOKEN)
16556+
16557+/*
16558+ * pkcs11h_token_ensureAccess - Ensure token is accessible.
16559+ *
16560+ * Parameters:
16561+ * token_id - Token id object.
16562+ * user_data - Optional user data, to be passed to hooks.
16563+ * mask_prompt - Allow prompt.
16564+ */
16565+CK_RV
16566+pkcs11h_token_ensureAccess (
16567+ IN const pkcs11h_token_id_t token_id,
16568+ IN void * const user_data,
16569+ IN const unsigned mask_prompt
16570+);
16571+
16572+#endif /* ENABLE_PKCS11H_TOKEN */
16573+
16574+#if defined(ENABLE_PKCS11H_DATA)
16575+
16576+/*
16577+ * pkcs11h_data_get - get data object.
16578+ *
16579+ * Parameters:
16580+ * token_id - Token id object.
16581+ * is_public - Object is public.
16582+ * application - Object application attribute.
16583+ * label - Object label attribute.
16584+ * user_data - Optional user data, to be passed to hooks.
16585+ * mask_prompt - Allow prompt.
16586+ * blob - blob, set to NULL to get size.
16587+ * p_blob_size - blob size.
16588+ */
16589+CK_RV
16590+pkcs11h_data_get (
16591+ IN const pkcs11h_token_id_t token_id,
16592+ IN const PKCS11H_BOOL is_public,
16593+ IN const char * const application,
16594+ IN const char * const label,
16595+ IN void * const user_data,
16596+ IN const unsigned mask_prompt,
16597+ OUT unsigned char * const blob,
16598+ IN OUT size_t * const p_blob_size
16599+);
16600+
16601+/*
16602+ * pkcs11h_data_put - put data object.
16603+ *
16604+ * Parameters:
16605+ * token_id - Token id object.
16606+ * is_public - Object is public.
16607+ * application - Object application attribute.
16608+ * label - Object label attribute.
16609+ * user_data - Optional user data, to be passed to hooks.
16610+ * mask_prompt - Allow prompt.
16611+ * blob - blob.
16612+ * blob_size - blob size.
16613+ */
16614+CK_RV
16615+pkcs11h_data_put (
16616+ IN const pkcs11h_token_id_t token_id,
16617+ IN const PKCS11H_BOOL is_public,
16618+ IN const char * const application,
16619+ IN const char * const label,
16620+ IN void * const user_data,
16621+ IN const unsigned mask_prompt,
16622+ OUT unsigned char * const blob,
16623+ IN const size_t blob_size
16624+);
16625+
16626+/*
16627+ * pkcs11h_data_del - delete data object.
16628+ *
16629+ * Parameters:
16630+ * token_id - Token id object.
16631+ * is_public - Object is public.
16632+ * application - Object application attribute.
16633+ * label - Object label attribute.
16634+ * user_data - Optional user data, to be passed to hooks.
16635+ * mask_prompt - Allow prompt.
16636+ */
16637+CK_RV
16638+pkcs11h_data_del (
16639+ IN const pkcs11h_token_id_t token_id,
16640+ IN const PKCS11H_BOOL is_public,
16641+ IN const char * const application,
16642+ IN const char * const label,
16643+ IN void * const user_data,
16644+ IN const unsigned mask_prompt
16645+);
16646+
16647+#endif /* ENABLE_PKCS11H_DATA */
16648+
16649+#if defined(ENABLE_PKCS11H_CERTIFICATE)
16650+/*======================================================================*
16651+ * CERTIFICATE INTERFACE
16652+ *======================================================================*/
16653+
16654+/*
16655+ * pkcs11h_certificate_freeCertificateId - Free certificate_id object.
16656+ */
16657+CK_RV
16658+pkcs11h_certificate_freeCertificateId (
16659+ IN pkcs11h_certificate_id_t certificate_id
16660+);
16661+
16662+/*
16663+ * pkcs11h_duplicateCertificateId - Duplicate certificate_id object.
16664+ */
16665+CK_RV
16666+pkcs11h_certificate_duplicateCertificateId (
16667+ OUT pkcs11h_certificate_id_t * const to,
16668+ IN const pkcs11h_certificate_id_t from
16669+);
16670+
16671+/*
16672+ * pkcs11h_certificate_setCertificateIdCertificateBlob - Sets internal certificate_id blob.
16673+ *
16674+ * Parameters:
16675+ * certificate_id - Certificate id ojbect.
16676+ * blob - blob.
16677+ * blob_size - blob size.
16678+ *
16679+ * Useful to set after deserialization so certificate is available and not read from token.
16680+ */
16681+CK_RV
16682+pkcs11h_certificate_setCertificateIdCertificateBlob (
16683+ IN const pkcs11h_certificate_id_t certificate_id,
16684+ IN const unsigned char * const blob,
16685+ IN const size_t blob_size
16686+);
16687+
16688+/*
16689+ * pkcs11h_certificate_freeCertificate - Free certificate object.
16690+ *
16691+ * Parameters:
16692+ * certificate - Certificate ojbect.
16693+ */
16694+CK_RV
16695+pkcs11h_certificate_freeCertificate (
16696+ IN pkcs11h_certificate_t certificate
16697+);
16698+
16699+/*
16700+ * pkcs11h_certificate_create - Create a certificate object out of certificate_id.
16701+ *
16702+ * Parameters:
16703+ * certificate_id - Certificate id object to be based on.
16704+ * user_data - Optional user data, to be passed to hooks.
16705+ * mask_prompt - Allow prompt.
16706+ * pin_cache_period - Session specific cache period.
16707+ * p_certificate - Receives certificate object.
16708+ *
16709+ * The certificate id object may not specify the full certificate.
16710+ * The certificate object must be freed by caller.
16711+ */
16712+CK_RV
16713+pkcs11h_certificate_create (
16714+ IN const pkcs11h_certificate_id_t certificate_id,
16715+ IN void * const user_data,
16716+ IN const unsigned mask_prompt,
16717+ IN const int pin_cache_period,
16718+ OUT pkcs11h_certificate_t * const p_certificate
16719+);
16720+
16721+/*
16722+ * pkcs11h_certificate_getPromptMask - Extract user data out of certificate.
16723+ *
16724+ * Parameters:
16725+ * certificate - Certificate ojbect.
16726+ *
16727+ * Returns:
16728+ * mask_prompt - Allow prompt.
16729+ *
16730+ */
16731+unsigned
16732+pkcs11h_certificate_getPromptMask (
16733+ IN const pkcs11h_certificate_t certificate
16734+);
16735+
16736+/*
16737+ * pkcs11h_certificate_setPromptMask - Extract user data out of certificate.
16738+ *
16739+ * Parameters:
16740+ * certificate - Certificate ojbect.
16741+ * mask_prompt - Allow prompt.
16742+ */
16743+void
16744+pkcs11h_certificate_setPromptMask (
16745+ IN const pkcs11h_certificate_t certificate,
16746+ IN const unsigned ask_prompt
16747+);
16748+
16749+/*
16750+ * pkcs11h_certificate_getUserData - Extract user data out of certificate.
16751+ *
16752+ * Parameters:
16753+ * certificate - Certificate ojbect.
16754+ *
16755+ * Returns:
16756+ * user_data - Optional user data, to be passed to hooks.
16757+ */
16758+void *
16759+pkcs11h_certificate_getUserData (
16760+ IN const pkcs11h_certificate_t certificate
16761+);
16762+
16763+/*
16764+ * pkcs11h_certificate_setUserData - Extract user data out of certificate.
16765+ *
16766+ * Parameters:
16767+ * certificate - Certificate ojbect.
16768+ * user_data - Optional user data, to be passed to hooks.
16769+ */
16770+void
16771+pkcs11h_certificate_setUserData (
16772+ IN const pkcs11h_certificate_t certificate,
16773+ IN void * const user_data
16774+);
16775+
16776+/*
16777+ * pkcs11h_certificate_getCertificateId - Get certifiate id object out of a certifiate
16778+ *
16779+ * Parameters:
16780+ * certificate - Certificate object.
16781+ * p_certificate_id - Certificate id object pointer.
16782+ *
16783+ * The certificate id must be freed by caller.
16784+ */
16785+CK_RV
16786+pkcs11h_certificate_getCertificateId (
16787+ IN const pkcs11h_certificate_t certificate,
16788+ OUT pkcs11h_certificate_id_t * const p_certificate_id
16789+);
16790+
16791+/*
16792+ * pkcs11h_certificate_getCertificateBlob - Get the certificate blob out of the certificate object.
16793+ *
16794+ * Parameters:
16795+ * certificate - Certificate object.
16796+ * certificate_blob - Buffer.
16797+ * certificate_blob_size - Buffer size.
16798+ *
16799+ * Buffer may be NULL in order to get size.
16800+ */
16801+CK_RV
16802+pkcs11h_certificate_getCertificateBlob (
16803+ IN const pkcs11h_certificate_t certificate,
16804+ OUT unsigned char * const certificate_blob,
16805+ IN OUT size_t * const p_certificate_blob_size
16806+);
16807+
16808+#if defined(ENABLE_PKCS11H_SERIALIZATION)
16809+
16810+/*
16811+ * pkcs11h_certificate_serializeCertificateId - Serialize certificate_id into a string
16812+ *
16813+ * Parametrs:
16814+ * sz - Output string.
16815+ * max - Max buffer size.
16816+ * certificate_id - id to serialize
16817+ *
16818+ * sz may be NULL in order to get size.
16819+ */
16820+CK_RV
16821+pkcs11h_certificate_serializeCertificateId (
16822+ OUT char * const sz,
16823+ IN OUT size_t *max,
16824+ IN const pkcs11h_certificate_id_t certificate_id
16825+);
16826+
16827+/*
16828+ * pkcs11h_certificate_deserializeCertificateId - Deserialize certificate_id out of string.
16829+ *
16830+ * Parameters:
16831+ * p_certificate_id - id.
16832+ * sz - Inut string
16833+ */
16834+CK_RV
16835+pkcs11h_certificate_deserializeCertificateId (
16836+ OUT pkcs11h_certificate_id_t * const p_certificate_id,
16837+ IN const char * const sz
16838+);
16839+
16840+#endif /* ENABLE_PKCS11H_SERIALIZATION */
16841+
16842+/*
16843+ * pkcs11h_certificate_ensureCertificateAccess - Ensure certificate is accessible.
16844+ *
16845+ * Parameters:
16846+ * certificate - Certificate object.
16847+ */
16848+CK_RV
16849+pkcs11h_certificate_ensureCertificateAccess (
16850+ IN const pkcs11h_certificate_t certificate
16851+);
16852+
16853+/*
16854+ * pkcs11h_certificate_ensureKeyAccess - Ensure key is accessible.
16855+ *
16856+ * Parameters:
16857+ * certificate - Certificate object.
16858+ */
16859+CK_RV
16860+pkcs11h_certificate_ensureKeyAccess (
16861+ IN const pkcs11h_certificate_t certificate
16862+);
16863+
16864+/*
16865+ * pkcs11h_certificate_lockSession - Lock session for threded environment
16866+ *
16867+ * Parameters:
16868+ * certificate - Certificate object.
16869+ *
16870+ * This must be called on threaded environment, so both calls to _sign and
16871+ * _signRecover and _decrypt will be from the same source.
16872+ * Failing to lock session, will result with CKR_OPERATION_ACTIVE if
16873+ * provider is good, or unexpected behaviour for others.
16874+ *
16875+ * It is save to call this also in none threaded environment, it will do nothing.
16876+ * Call this also if you are doing one stage operation, since locking is not
16877+ * done by method.
16878+ */
16879+CK_RV
16880+pkcs11h_certificate_lockSession (
16881+ IN const pkcs11h_certificate_t certificate
16882+);
16883+
16884+/*
16885+ * pkcs11h_certificate_releaseSession - Releases session lock.
16886+ *
16887+ * Parameters:
16888+ * certificate - Certificate object.
16889+ *
16890+ * See pkcs11h_certificate_lockSession.
16891+ */
16892+CK_RV
16893+pkcs11h_certificate_releaseSession (
16894+ IN const pkcs11h_certificate_t certificate
16895+);
16896+
16897+/*
16898+ * pkcs11h_certificate_sign - Sign data.
16899+ *
16900+ * Parameters:
16901+ * certificate - Certificate object.
16902+ * mech_type - PKCS#11 mechanism.
16903+ * source - Buffer to sign.
16904+ * source_size - Buffer size.
16905+ * target - Target buffer, can be NULL to get size.
16906+ * target_size - Target buffer size.
16907+ */
16908+CK_RV
16909+pkcs11h_certificate_sign (
16910+ IN const pkcs11h_certificate_t certificate,
16911+ IN const CK_MECHANISM_TYPE mech_type,
16912+ IN const unsigned char * const source,
16913+ IN const size_t source_size,
16914+ OUT unsigned char * const target,
16915+ IN OUT size_t * const p_target_size
16916+);
16917+
16918+/*
16919+ * pkcs11h_certificate_signRecover - Sign data.
16920+ *
16921+ * Parameters:
16922+ * certificate - Certificate object.
16923+ * mech_type - PKCS#11 mechanism.
16924+ * source - Buffer to sign.
16925+ * source_size - Buffer size.
16926+ * target - Target buffer, can be NULL to get size.
16927+ * target_size - Target buffer size.
16928+ */
16929+CK_RV
16930+pkcs11h_certificate_signRecover (
16931+ IN const pkcs11h_certificate_t certificate,
16932+ IN const CK_MECHANISM_TYPE mech_type,
16933+ IN const unsigned char * const source,
16934+ IN const size_t source_size,
16935+ OUT unsigned char * const target,
16936+ IN OUT size_t * const p_target_size
16937+);
16938+
16939+/*
16940+ * pkcs11h_certificate_signAny - Sign data mechanism determined by key attributes.
16941+ *
16942+ * Parameters:
16943+ * certificate - Certificate object.
16944+ * mech_type - PKCS#11 mechanism.
16945+ * source - Buffer to sign.
16946+ * source_size - Buffer size.
16947+ * target - Target buffer, can be NULL to get size.
16948+ * target_size - Target buffer size.
16949+ */
16950+CK_RV
16951+pkcs11h_certificate_signAny (
16952+ IN const pkcs11h_certificate_t certificate,
16953+ IN const CK_MECHANISM_TYPE mech_type,
16954+ IN const unsigned char * const source,
16955+ IN const size_t source_size,
16956+ OUT unsigned char * const target,
16957+ IN OUT size_t * const p_target_size
16958+);
16959+
16960+/*
16961+ * pkcs11h_certificate_decrypt - Decrypt data.
16962+ *
16963+ * Parameters:
16964+ * certificate - Certificate object.
16965+ * mech_type - PKCS#11 mechanism.
16966+ * source - Buffer to sign.
16967+ * source_size - Buffer size.
16968+ * target - Target buffer, can be NULL to get size.
16969+ * target_size - Target buffer size.
16970+ */
16971+CK_RV
16972+pkcs11h_certificate_decrypt (
16973+ IN const pkcs11h_certificate_t certificate,
16974+ IN const CK_MECHANISM_TYPE mech_type,
16975+ IN const unsigned char * const source,
16976+ IN const size_t source_size,
16977+ OUT unsigned char * const target,
16978+ IN OUT size_t * const p_target_size
16979+);
16980+
16981+#endif /* ENABLE_PKCS11H_CERTIFICATE */
16982+
16983+#if defined(ENABLE_PKCS11H_LOCATE)
16984+/*======================================================================*
16985+ * LOCATE INTERFACE
16986+ *======================================================================*/
16987+
16988+#if defined(ENABLE_PKCS11H_TOKEN) || defined(ENABLE_PKCS11H_CERTIFICATE)
16989+
16990+/*
16991+ * pkcs11h_locate_token - Locate token based on atributes.
16992+ *
16993+ * Parameters:
16994+ * slot_type - How to locate slot.
16995+ * slot - Slot name.
16996+ * user_data - Optional user data, to be passed to hooks.
16997+ * mask_prompt - Allow prompt.
16998+ * p_token_id - Token object.
16999+ *
17000+ * Slot:
17001+ * id - Slot number.
17002+ * name - Slot name.
17003+ * label - Available token label.
17004+ *
17005+ * Caller must free token id.
17006+ */
17007+CK_RV
17008+pkcs11h_locate_token (
17009+ IN const char * const slot_type,
17010+ IN const char * const slot,
17011+ IN void * const user_data,
17012+ IN const unsigned mask_prompt,
17013+ OUT pkcs11h_token_id_t * const p_token_id
17014+);
17015+
17016+#endif /* ENABLE_PKCS11H_TOKEN || ENABLE_PKCS11H_CERTIFICATE */
17017+
17018+#if defined(ENABLE_PKCS11H_CERTIFICATE)
17019+
17020+/*
17021+ * pkcs11h_locate_certificate - Locate certificate based on atributes.
17022+ *
17023+ * Parameters:
17024+ * slot_type - How to locate slot.
17025+ * slot - Slot name.
17026+ * id_type - How to locate object.
17027+ * id - Object name.
17028+ * user_data - Optional user data, to be passed to hooks.
17029+ * mask_prompt - Allow prompt.
17030+ * p_certificate_id - Certificate object.
17031+ *
17032+ * Slot:
17033+ * Same as pkcs11h_locate_token.
17034+ *
17035+ * Object:
17036+ * id - Certificate CKA_ID (hex string) (Fastest).
17037+ * label - Certificate CKA_LABEL (string).
17038+ * subject - Certificate subject (OpenSSL or gnutls DN).
17039+ *
17040+ * Caller must free certificate id.
17041+ */
17042+CK_RV
17043+pkcs11h_locate_certificate (
17044+ IN const char * const slot_type,
17045+ IN const char * const slot,
17046+ IN const char * const id_type,
17047+ IN const char * const id,
17048+ IN void * const user_data,
17049+ IN const unsigned mask_prompt,
17050+ OUT pkcs11h_certificate_id_t * const p_certificate_id
17051+);
17052+
17053+#endif /* ENABLE_PKCS11H_CERTIFICATE */
17054+
17055+#endif /* ENABLE_PKCS11H_LOCATE */
17056+
17057+#if defined(ENABLE_PKCS11H_ENUM)
17058+/*======================================================================*
17059+ * ENUM INTERFACE
17060+ *======================================================================*/
17061+
17062+#if defined(ENABLE_PKCS11H_TOKEN)
17063+
17064+/*
17065+ * pkcs11h_freeTokenIdList - Free certificate_id list.
17066+ */
17067+CK_RV
17068+pkcs11h_token_freeTokenIdList (
17069+ IN const pkcs11h_token_id_list_t token_id_list
17070+);
17071+
17072+/*
17073+ * pkcs11h_token_enumTokenIds - Enumerate available tokens
17074+ *
17075+ * Parameters:
17076+ * p_token_id_list - A list of token ids.
17077+ *
17078+ * Caller must free the list.
17079+ */
17080+CK_RV
17081+pkcs11h_token_enumTokenIds (
17082+ IN const int method,
17083+ OUT pkcs11h_token_id_list_t * const p_token_id_list
17084+);
17085+
17086+#endif /* ENABLE_PKCS11H_TOKEN */
17087+
17088+#if defined(ENABLE_PKCS11H_DATA)
17089+
17090+/*
17091+ * pkcs11h_data_freeDataIdList - free data object list..
17092+ *
17093+ * Parameters:
17094+ * data_id_list - list to free.
17095+ */
17096+CK_RV
17097+pkcs11h_data_freeDataIdList (
17098+ IN const pkcs11h_data_id_list_t data_id_list
17099+);
17100+
17101+/*
17102+ * pkcs11h_data_enumDataObjects - get list of data objects.
17103+ *
17104+ * Parameters:
17105+ * token_id - token id.
17106+ * is_public - Get a list of public objects.
17107+ * user_data - Optional user data, to be passed to hooks.
17108+ * mask_prompt - Allow prompt.
17109+ * p_data_id_list - List location.
17110+ */
17111+CK_RV
17112+pkcs11h_data_enumDataObjects (
17113+ IN const pkcs11h_token_id_t token_id,
17114+ IN const PKCS11H_BOOL is_public,
17115+ IN void * const user_data,
17116+ IN const unsigned mask_prompt,
17117+ OUT pkcs11h_data_id_list_t * const p_data_id_list
17118+);
17119+
17120+#endif /* ENABLE_PKCS11H_DATA */
17121+
17122+#if defined(ENABLE_PKCS11H_CERTIFICATE)
17123+
17124+/*
17125+ * pkcs11h_certificate_freeCertificateIdList - Free certificate_id list.
17126+ */
17127+CK_RV
17128+pkcs11h_certificate_freeCertificateIdList (
17129+ IN const pkcs11h_certificate_id_list_t cert_id_list
17130+);
17131+
17132+/*
17133+ * pkcs11h_certificate_enumTokenCertificateIds - Enumerate available certificates on specific token
17134+ *
17135+ * Parameters:
17136+ * token_id - Token id to enum.
17137+ * method - How to fetch certificates.
17138+ * user_data - Some user specific data.
17139+ * mask_prompt - Allow prompt.
17140+ * p_cert_id_issuers_list - Receives issues list, can be NULL.
17141+ * p_cert_id_end_list - Receives end certificates list.
17142+ *
17143+ * This function will likely take long time.
17144+ *
17145+ * Method can be one of the following:
17146+ * PKCS11H_ENUM_METHOD_CACHE
17147+ * Return available certificates, even if token was once detected and
17148+ * was removed.
17149+ * PKCS11H_ENUM_METHOD_CACHE_EXIST
17150+ * Return available certificates for available tokens only, don't
17151+ * read the contents of the token if already read, even if this token
17152+ * removed and inserted.
17153+ * PKCS11H_ENUM_METHOD_RELOAD
17154+ * Clear all caches and then enum.
17155+ *
17156+ * Caller must free the lists.
17157+ */
17158+CK_RV
17159+pkcs11h_certificate_enumTokenCertificateIds (
17160+ IN const pkcs11h_token_id_t token_id,
17161+ IN const int method,
17162+ IN void * const user_data,
17163+ IN const unsigned mask_prompt,
17164+ OUT pkcs11h_certificate_id_list_t * const p_cert_id_issuers_list,
17165+ OUT pkcs11h_certificate_id_list_t * const p_cert_id_end_list
17166+);
17167+
17168+/*
17169+ * pkcs11h_enum_getCertificateIds - Enumerate available certificates.
17170+ *
17171+ * Parameters:
17172+ * method - How to fetch certificates.
17173+ * user_data - Some user specific data.
17174+ * mask_prompt - Allow prompt.
17175+ * p_cert_id_issuers_list - Receives issues list, can be NULL.
17176+ * p_cert_id_end_list - Receives end certificates list.
17177+ *
17178+ * This function will likely take long time.
17179+ *
17180+ * Method can be one of the following:
17181+ * PKCS11H_ENUM_METHOD_CACHE
17182+ * Return available certificates, even if token was once detected and
17183+ * was removed.
17184+ * PKCS11H_ENUM_METHOD_CACHE_EXIST
17185+ * Return available certificates for available tokens only, don't
17186+ * read the contents of the token if already read, even if this token
17187+ * removed and inserted.
17188+ * PKCS11H_ENUM_METHOD_RELOAD
17189+ * Clear all caches and then enum.
17190+ *
17191+ * Caller must free lists.
17192+ */
17193+CK_RV
17194+pkcs11h_certificate_enumCertificateIds (
17195+ IN const int method,
17196+ IN void * const user_data,
17197+ IN const unsigned mask_prompt,
17198+ OUT pkcs11h_certificate_id_list_t * const p_cert_id_issuers_list,
17199+ OUT pkcs11h_certificate_id_list_t * const p_cert_id_end_list
17200+);
17201+
17202+#endif /* ENABLE_PKCS11H_CERTIFICATE */
17203+
17204+#endif /* ENABLE_PKCS11H_ENUM */
17205+
17206+#if defined(ENABLE_PKCS11H_OPENSSL)
17207+/*======================================================================*
17208+ * OPENSSL INTERFACE
17209+ *======================================================================*/
17210+
17211+/*
17212+ * pkcs11h_openssl_getX509 - Returns an X509 object out of the openssl_session object.
17213+ *
17214+ * Parameters:
17215+ * certificate - Certificate object.
17216+ */
17217+X509 *
17218+pkcs11h_openssl_getX509 (
17219+ IN const pkcs11h_certificate_t certificate
17220+);
17221+
17222+/*
17223+ * pkcs11h_openssl_createSession - Create OpenSSL session based on a certificate object.
17224+ *
17225+ * Parameters:
17226+ * certificate - Certificate object.
17227+ *
17228+ * The certificate object will be freed by the OpenSSL interface on session end.
17229+ */
17230+pkcs11h_openssl_session_t
17231+pkcs11h_openssl_createSession (
17232+ IN const pkcs11h_certificate_t certificate
17233+);
17234+
17235+/*
17236+ * pkcs11h_openssl_getCleanupHook - Sets cleanup hook
17237+ *
17238+ * Parameters:
17239+ * openssl_session - session.
17240+ */
17241+pkcs11h_hook_openssl_cleanup_t
17242+pkcs11h_openssl_getCleanupHook (
17243+ IN const pkcs11h_openssl_session_t openssl_session
17244+);
17245+
17246+/*
17247+ * pkcs11h_openssl_setCleanupHook - Sets cleanup hook
17248+ *
17249+ * Parameters:
17250+ * openssl_session - session.
17251+ * cleanup - hook.
17252+ */
17253+void
17254+pkcs11h_openssl_setCleanupHook (
17255+ IN const pkcs11h_openssl_session_t openssl_session,
17256+ IN const pkcs11h_hook_openssl_cleanup_t cleanup
17257+);
17258+
17259+/*
17260+ * pkcs11h_openssl_freeSession - Free OpenSSL session.
17261+ *
17262+ * Parameters:
17263+ * openssl_session - Session to free.
17264+ *
17265+ * The openssl_session object has a reference count just like other OpenSSL objects.
17266+ */
17267+void
17268+pkcs11h_openssl_freeSession (
17269+ IN const pkcs11h_openssl_session_t openssl_session
17270+);
17271+
17272+/*
17273+ * pkcs11h_openssl_session_getRSA - Returns an RSA object out of the openssl_session object.
17274+ *
17275+ * Parameters:
17276+ * openssl_session - Session.
17277+ */
17278+RSA *
17279+pkcs11h_openssl_session_getRSA (
17280+ IN const pkcs11h_openssl_session_t openssl_session
17281+);
17282+
17283+/*
17284+ * pkcs11h_openssl_session_getX509 - Returns an X509 object out of the openssl_session object.
17285+ *
17286+ * Parameters:
17287+ * openssl_session - Session.
17288+ */
17289+X509 *
17290+pkcs11h_openssl_session_getX509 (
17291+ IN const pkcs11h_openssl_session_t openssl_session
17292+);
17293+
17294+#endif /* ENABLE_PKCS11H_OPENSSL */
17295+
17296+#if defined(ENABLE_PKCS11H_STANDALONE)
17297+/*======================================================================*
17298+ * STANDALONE INTERFACE
17299+ *======================================================================*/
17300+
17301+void
17302+pkcs11h_standalone_dump_slots (
17303+ IN const pkcs11h_output_print_t my_output,
17304+ IN void * const global_data,
17305+ IN const char * const provider
17306+);
17307+
17308+void
17309+pkcs11h_standalone_dump_objects (
17310+ IN const pkcs11h_output_print_t my_output,
17311+ IN void * const global_data,
17312+ IN const char * const provider,
17313+ IN const char * const slot,
17314+ IN const char * const pin
17315+);
17316+
17317+#endif /* ENABLE_PKCS11H_STANDALONE */
17318+
17319+#ifdef __cplusplus
17320+}
17321+#endif
17322+
17323+#endif /* __PKCS11H_HELPER_H */
17324diff -urNp openssh-4.4p1/README.pkcs11 openssh-4.4p1+pkcs11-0.17/README.pkcs11
17325--- openssh-4.4p1/README.pkcs11 1970-01-01 02:00:00.000000000 +0200
17326+++ openssh-4.4p1+pkcs11-0.17/README.pkcs11 2006-10-18 20:22:08.000000000 +0200
17327@@ -0,0 +1,49 @@
17328+The PKCS#11 patch modify ssh-add and ssh-agent to support PKCS#11 private keys
17329+and certificates (http://alon.barlev.googlepages.com/openssh-pkcs11).
17330+
17331+It allows using multiple PKCS#11 providers at the same time, selecting keys by
17332+id, label or certificate subject, handling card removal and card insert events,
17333+handling card re-insert to a different slot, supporting session expiration.
17334+
17335+A valid X.509 certificate should exist on the token, without X.509 support it is
17336+exported as regular RSA key. Self-signed certificates are treated as RSA key and
17337+not as X.509 RSA key.
17338+
17339+If you like X.509 (http://roumenpetrov.info/openssh) support apply the X.509
17340+patch AFTER the PKCS#11 patch. You can use -o PubkeyAlgorithms=ssh-rsa in order to
17341+authenticate to none X.509 servers.
17342+
17343+One significant change is that the ssh-agent prompts for passwords now... So you
17344+need to configure it with a program that asks for card insert or PIN, a program
17345+such as x11-ssh-askpass. Current implementation (ssh-add asks for passwords) is
17346+not valid for dynamic smartcard environment.
17347+
17348+Current implementation uses the askpin program also for prompting card insert...
17349+Don't be confused, it only expects ok or cancel, some simple scripts available
17350+at http://alon.barlev.googlepages.com/openssh-pkcs11 that uses KDE, Gnome and .NET
17351+in order to display these dialogs.
17352+
17353+You can view full usage by:
17354+$ ssh-agent /bin/sh
17355+$ ssh-add -h
17356+
17357+A common scenario is the following:
17358+$ ssh-agent /bin/sh
17359+$ ssh-add --pkcs11-ask-pin `which openssh-kde-dialogs.sh`
17360+$ ssh-add --pkcs11-add-provider --pkcs11-provider /usr/lib/pkcs11/MyProvider.so
17361+$ ssh-add --pkcs11-add-id --pkcs11-id "serialized id"
17362+$ ssh myhost
17363+
17364+In order to see available objects, you can use:
17365+$ ssh-add --pkcs11-show-ids --pkcs11-provider /usr/lib/pkcs11/MyProvider.so
17366+
17367+In order to add id without accessing the token, you must put the certificate in
17368+a PEM file and use:
17369+$ ssh-add --pkcs11-add-id --pkcs11-id "serialized id" --pkcs11-cert-file my.pem
17370+
17371+In order to debug open two shells:
17372+1$ rm -fr /tmp/s; ssh-agent -d -d -d -a /tmp/s
17373+
17374+2$ SSH_AUTH_SOCK=/tmp/s; export SSH_AUTH_SOCK;
17375+2$ [ssh-add]...
17376+
17377diff -urNp openssh-4.4p1/ssh-add.c openssh-4.4p1+pkcs11-0.17/ssh-add.c
17378--- openssh-4.4p1/ssh-add.c 2006-09-01 08:38:37.000000000 +0300
17379+++ openssh-4.4p1+pkcs11-0.17/ssh-add.c 2006-10-12 15:10:42.000000000 +0200
17380@@ -56,12 +56,15 @@
17381 #include "rsa.h"
17382 #include "log.h"
17383 #include "key.h"
17384+#include "pkcs11.h"
17385 #include "buffer.h"
17386 #include "authfd.h"
17387 #include "authfile.h"
17388 #include "pathnames.h"
17389 #include "misc.h"
17390
17391+static void usage (void);
17392+
17393 /* argv0 */
17394 extern char *__progname;
17395
17396@@ -306,6 +309,261 @@ do_file(AuthenticationConnection *ac, in
17397 return 0;
17398 }
17399
17400+#ifndef SSH_PKCS11_DISABLED
17401+
17402+static
17403+int
17404+do_pkcs11 (AuthenticationConnection *ac, int argc, char *argv[])
17405+{
17406+ /*
17407+ * TEMP TEMP TEMP TEMP
17408+ *
17409+ * This should be fixed if another mechanism
17410+ * will be propsed.
17411+ */
17412+ pkcs11_identity *id = NULL;
17413+ char *szPKCS11Provider = NULL;
17414+ char *szPKCS11Id = NULL;
17415+ char *szPKCS11SignMode = NULL;
17416+ char *szPKCS11AskPIN = NULL;
17417+ char *szPKCS11SlotId = NULL;
17418+ char *szPKCS11CertFile = NULL;
17419+ int fDebug = 0;
17420+ int fPKCS11AddProvider = 0;
17421+ int fPKCS11AddId = 0;
17422+ int fPKCS11RemoveId = 0;
17423+ int fPKCS11ShowIds = 0;
17424+ int fPKCS11DumpSlots = 0;
17425+ int fPKCS11DumpObjects = 0;
17426+ int fPKCS11ProtectedAuthentication = 0;
17427+ int fPKCS11CertPrivate = 0;
17428+ int nPKCS11PINCachePeriod = -1;
17429+ int fBadUsage = 0;
17430+ int ret = 0;
17431+ int nSkipPrmCount;
17432+ int i;
17433+
17434+ for (i=0,nSkipPrmCount=0;i<argc;i++) {
17435+ if (!strcmp (argv[i], "--pkcs11-provider")) {
17436+ szPKCS11Provider = argv[i+1];
17437+ i++;
17438+ }
17439+ else if (!strcmp (argv[i], "--pkcs11-id")) {
17440+ szPKCS11Id = argv[i+1];
17441+ i++;
17442+ }
17443+ else if (!strcmp (argv[i], "--pkcs11-pin-cache")) {
17444+ nPKCS11PINCachePeriod = atoi (argv[i+1]);
17445+ i++;
17446+ }
17447+ else if (!strcmp (argv[i], "--pkcs11-sign-mode")) {
17448+ szPKCS11SignMode = argv[i+1];
17449+ i++;
17450+ }
17451+ else if (!strcmp (argv[i], "--pkcs11-ask-pin")) {
17452+ szPKCS11AskPIN = argv[i+1];
17453+ i++;
17454+ }
17455+ else if (!strcmp (argv[i], "--pkcs11-slot")) {
17456+ szPKCS11SlotId = argv[i+1];
17457+ i++;
17458+ }
17459+ else if (!strcmp (argv[i], "--pkcs11-cert-file")) {
17460+ szPKCS11CertFile = argv[i+1];
17461+ i++;
17462+ }
17463+ else if (!strcmp (argv[i], "--pkcs11-add-provider")) {
17464+ fPKCS11AddProvider = 1;
17465+ }
17466+ else if (!strcmp (argv[i], "--pkcs11-remove-id")) {
17467+ fPKCS11RemoveId = 1;
17468+ }
17469+ else if (!strcmp (argv[i], "--pkcs11-add-id")) {
17470+ fPKCS11AddId = 1;
17471+ }
17472+ else if (!strcmp (argv[i], "--pkcs11-show-ids")) {
17473+ fPKCS11ShowIds = 1;
17474+ }
17475+ else if (!strcmp (argv[i], "--pkcs11-dump-slots")) {
17476+ fPKCS11DumpSlots = 1;
17477+ }
17478+ else if (!strcmp (argv[i], "--pkcs11-dump-objects")) {
17479+ fPKCS11DumpObjects = 1;
17480+ }
17481+ else if (!strcmp (argv[i], "--pkcs11-protected-authentication")) {
17482+ fPKCS11ProtectedAuthentication = 1;
17483+ }
17484+ else if (!strcmp (argv[i], "--pkcs11-cert-private")) {
17485+ fPKCS11CertPrivate = 1;
17486+ }
17487+ else if (!strcmp (argv[i], "-d")) {
17488+ fDebug = 1;
17489+ }
17490+ else {
17491+ nSkipPrmCount++;
17492+ }
17493+ }
17494+
17495+ if (nSkipPrmCount == argc) {
17496+ /* no pkcs#11 arguments */
17497+ ret = -2;
17498+ }
17499+
17500+ if (ret == 0) {
17501+ if (
17502+ !fBadUsage &&
17503+ fPKCS11AddProvider &&
17504+ szPKCS11Provider == NULL
17505+ ) {
17506+ fBadUsage = 1;
17507+ }
17508+
17509+ if (
17510+ !fBadUsage &&
17511+ fPKCS11AddId &&
17512+ (
17513+ szPKCS11Id == NULL
17514+ )
17515+ ) {
17516+ fBadUsage = 1;
17517+ }
17518+
17519+ if (
17520+ !fBadUsage &&
17521+ fPKCS11RemoveId &&
17522+ (
17523+ szPKCS11Id == NULL
17524+ )
17525+ ) {
17526+ fBadUsage = 1;
17527+ }
17528+
17529+ if (
17530+ !fBadUsage &&
17531+ fPKCS11ShowIds &&
17532+ szPKCS11Provider == NULL
17533+ ) {
17534+ fBadUsage = 1;
17535+ }
17536+
17537+ if (
17538+ !fBadUsage &&
17539+ fPKCS11DumpSlots &&
17540+ szPKCS11Provider == NULL
17541+ ) {
17542+ fBadUsage = 1;
17543+ }
17544+
17545+ if (
17546+ !fBadUsage &&
17547+ fPKCS11DumpObjects &&
17548+ (
17549+ szPKCS11Provider == NULL ||
17550+ szPKCS11SlotId == NULL
17551+ )
17552+ ) {
17553+ fBadUsage = 1;
17554+ }
17555+
17556+ if (fBadUsage) {
17557+ usage ();
17558+ ret = 1;
17559+ }
17560+ }
17561+
17562+ if (ret == 0) {
17563+ if (fPKCS11AddId || fPKCS11RemoveId) {
17564+ id = pkcs11_identity_new ();
17565+ if (id == NULL) {
17566+ ret = 1;
17567+ }
17568+ else {
17569+ id->id = strdup (szPKCS11Id);
17570+ id->pin_cache_period = nPKCS11PINCachePeriod;
17571+ id->cert_file = szPKCS11CertFile;
17572+ }
17573+ }
17574+ }
17575+
17576+ if (ret == 0) {
17577+ if (fDebug) {
17578+ log_init(__progname, SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 1);
17579+ }
17580+
17581+ if (fPKCS11ShowIds) {
17582+ pkcs11_show_ids (szPKCS11Provider, fPKCS11ProtectedAuthentication, fPKCS11CertPrivate);
17583+ ret = 0;
17584+ }
17585+ else if (fPKCS11DumpSlots) {
17586+ pkcs11_dump_slots (szPKCS11Provider);
17587+ ret = 0;
17588+ }
17589+ else if (fPKCS11DumpObjects) {
17590+ char *szPIN = read_passphrase("PIN: ", RP_ALLOW_STDIN);
17591+ if (szPIN[0] != '\0') {
17592+ pkcs11_dump_objects (szPKCS11Provider, szPKCS11SlotId, szPIN);
17593+ }
17594+ memset (szPIN, 0, strlen (szPIN));
17595+ xfree (szPIN);
17596+ ret = 0;
17597+ }
17598+ else if (szPKCS11AskPIN != NULL) {
17599+ ret = !ssh_pkcs11_set_ask_pin (ac, szPKCS11AskPIN);
17600+
17601+ if (ret) {
17602+ fprintf (stderr, "Failed\n");
17603+ }
17604+ else {
17605+ fprintf (stderr, "Success\n");
17606+ }
17607+ }
17608+ else if (fPKCS11AddProvider) {
17609+ ret = !ssh_pkcs11_add_provider (
17610+ ac,
17611+ szPKCS11Provider,
17612+ fPKCS11ProtectedAuthentication,
17613+ szPKCS11SignMode,
17614+ fPKCS11CertPrivate
17615+ );
17616+
17617+ if (ret) {
17618+ fprintf (stderr, "Cannot add provider %s\n", szPKCS11Provider);
17619+ }
17620+ else {
17621+ fprintf (stderr, "Provider %s added successfully\n", szPKCS11Provider);
17622+ }
17623+ }
17624+ else if (fPKCS11AddId) {
17625+ ret = !ssh_pkcs11_id (ac, id, 0);
17626+
17627+ if (ret) {
17628+ fprintf (stderr, "Cannot add identity\n");
17629+ }
17630+ else {
17631+ fprintf (stderr, "Identity added successfully\n");
17632+ }
17633+ }
17634+ else if (fPKCS11RemoveId) {
17635+ ret = !ssh_pkcs11_id (ac, id, 1);
17636+
17637+ if (ret) {
17638+ fprintf (stderr, "Cannot remove identity\n");
17639+ }
17640+ else {
17641+ fprintf (stderr, "Identity removed successfully\n");
17642+ }
17643+ }
17644+ }
17645+
17646+ if (id != NULL) {
17647+ pkcs11_identity_free (id);
17648+ }
17649+
17650+ return ret;
17651+}
17652+
17653+#endif /* SSH_PKCS11_DISABLED */
17654+
17655 static void
17656 usage(void)
17657 {
17658@@ -323,6 +581,50 @@ usage(void)
17659 fprintf(stderr, " -s reader Add key in smartcard reader.\n");
17660 fprintf(stderr, " -e reader Remove key in smartcard reader.\n");
17661 #endif
17662+#ifndef SSH_PKCS11_DISABLED
17663+ fprintf(
17664+ stderr,
17665+ (
17666+ "\n"
17667+ " PKCS#11 Options:\n"
17668+ " --pkcs11-ask-pin prog Set ask-pin program\n"
17669+ "\n"
17670+ " --pkcs11-add-provider Add PKCS#11 provider\n"
17671+ " --pkcs11-provider provider PKCS#11 provider library\n"
17672+ " [--pkcs11-protected-authentication] Use PKCS#11 protected authentication\n"
17673+ " [--pkcs11-sign-mode mode] Provider signature mode\n"
17674+ " auto - determine automatically\n"
17675+ " sign - perform sign\n"
17676+ " recover - perform sign recover\n"
17677+ " any - perform sign and then sign recover\n"
17678+ " [--pkcs11-cert-private] Login required in order to access certificate\n"
17679+ "\n"
17680+ " --pkcs11-show-ids Show available identities\n"
17681+ " --pkcs11-provider provider PKCS#11 provider library\n"
17682+ " [--pkcs11-protected-authentication] Use PKCS#11 protected authentication\n"
17683+ " [--pkcs11-cert-private] Login required in order to access certificate\n"
17684+ " [-d] debug\n"
17685+ "\n"
17686+ " --pkcs11-add-id Add PKCS#11 identity\n"
17687+ " --pkcs11-id id Serialized string\n"
17688+ " [--pkcs11-cert-file file] Use this PEM file, don't access token\n"
17689+ " [--pkcs11-pin-cache period] PIN cache period (seconds)\n"
17690+ "\n"
17691+ " --pkcs11-remove-id Remove PKCS#11 identity\n"
17692+ " --pkcs11-id id Serialized string\n"
17693+ " [--pkcs11-cert-file file] Use this PEM file, don't access token\n"
17694+ "\n"
17695+ " PKCS#11 Debugging Options:\n"
17696+ " --pkcs11-dump-slots Dump available PKCS#11 slots\n"
17697+ " --pkcs11-provider provider PKCS#11 provider library\n"
17698+ "\n"
17699+ " --pkcs11-dump-objects Dump available PKCS#11 objects\n"
17700+ " --pkcs11-provider provider PKCS#11 provider library\n"
17701+ " --pkcs11-slot slot Slot numeric id\n"
17702+ "\n"
17703+ )
17704+ );
17705+#endif /* SSH_PKCS11_DISABLED */
17706 }
17707
17708 int
17709@@ -350,6 +652,17 @@ main(int argc, char **argv)
17710 "Could not open a connection to your authentication agent.\n");
17711 exit(2);
17712 }
17713+
17714+#ifndef SSH_PKCS11_DISABLED
17715+ {
17716+ int r = do_pkcs11 (ac, argc, argv);
17717+ if (r != -2) {
17718+ ret = r;
17719+ goto done;
17720+ }
17721+ }
17722+#endif /* SSH_PKCS11_DISABLED */
17723+
17724 while ((ch = getopt(argc, argv, "lLcdDxXe:s:t:")) != -1) {
17725 switch (ch) {
17726 case 'l':
17727diff -urNp openssh-4.4p1/ssh-agent.c openssh-4.4p1+pkcs11-0.17/ssh-agent.c
17728--- openssh-4.4p1/ssh-agent.c 2006-09-01 08:38:37.000000000 +0300
17729+++ openssh-4.4p1+pkcs11-0.17/ssh-agent.c 2006-10-12 14:00:53.000000000 +0200
17730@@ -71,6 +71,7 @@
17731 #include "buffer.h"
17732 #include "key.h"
17733 #include "authfd.h"
17734+#include "pkcs11.h"
17735 #include "compat.h"
17736 #include "log.h"
17737 #include "misc.h"
17738@@ -690,6 +691,157 @@ send:
17739 }
17740 #endif /* SMARTCARD */
17741
17742+#ifndef SSH_PKCS11_DISABLED
17743+
17744+static
17745+void
17746+process_pkcs11_set_ask_pin (SocketEntry *e)
17747+{
17748+ char *szAskPIN = NULL;
17749+ int success = 0;
17750+
17751+ szAskPIN = buffer_get_string(&e->request, NULL);
17752+
17753+ success = pkcs11_setAskPIN (szAskPIN);
17754+
17755+ buffer_put_int(&e->output, 1);
17756+ buffer_put_char(&e->output,
17757+ success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
17758+}
17759+
17760+static void
17761+process_pkcs11_add_provider (SocketEntry *e)
17762+{
17763+ char *szProvider = NULL;
17764+ int fProtectedAuthentication = 0;
17765+ char *szSignMode = NULL;
17766+ int fCertIsPrivate = 0;
17767+ int success = 0;
17768+
17769+ szProvider = buffer_get_string(&e->request, NULL);
17770+ fProtectedAuthentication = buffer_get_int (&e->request);
17771+ szSignMode = buffer_get_string(&e->request, NULL);
17772+ fCertIsPrivate = buffer_get_int (&e->request);
17773+
17774+ success = pkcs11_addProvider (szProvider, fProtectedAuthentication, szSignMode, fCertIsPrivate);
17775+
17776+ buffer_put_int(&e->output, 1);
17777+ buffer_put_char(&e->output,
17778+ success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
17779+}
17780+
17781+static
17782+void
17783+process_pkcs11_add_id (SocketEntry *e)
17784+{
17785+ int success = 0;
17786+ int version = 2;
17787+ char szComment[1024];
17788+ Key *k = NULL;
17789+ pkcs11_identity *pkcs11_id = NULL;
17790+
17791+ pkcs11_id = pkcs11_identity_new ();
17792+ if (pkcs11_id != NULL) {
17793+ pkcs11_id->id = strdup (buffer_get_string(&e->request, NULL));
17794+ pkcs11_id->pin_cache_period = buffer_get_int(&e->request);
17795+ pkcs11_id->cert_file = strdup (buffer_get_string(&e->request, NULL));
17796+
17797+ pkcs11_getKey (
17798+ pkcs11_id,
17799+ &k,
17800+ szComment,
17801+ sizeof (szComment)
17802+ );
17803+
17804+ if (k != NULL) {
17805+ if (lookup_identity(k, version) == NULL) {
17806+ Identity *id = xmalloc(sizeof(Identity));
17807+ Idtab *tab = NULL;
17808+
17809+ id->key = k;
17810+ k = NULL;
17811+ id->comment = xstrdup (szComment);
17812+ id->death = 0; /* handled by pkcs#11 helper */
17813+ id->confirm = 0;
17814+
17815+ tab = idtab_lookup(version);
17816+ TAILQ_INSERT_TAIL(&tab->idlist, id, next);
17817+ /* Increment the number of identities. */
17818+ tab->nentries++;
17819+ success = 1;
17820+ }
17821+ }
17822+ }
17823+
17824+ if (k != NULL) {
17825+ key_free (k);
17826+ }
17827+
17828+ if (pkcs11_id != NULL) {
17829+ pkcs11_identity_free (pkcs11_id);
17830+ }
17831+
17832+ buffer_put_int(&e->output, 1);
17833+ buffer_put_char(&e->output,
17834+ success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
17835+}
17836+
17837+static
17838+void
17839+process_pkcs11_remove_id (SocketEntry *e)
17840+{
17841+ int success = 0;
17842+ Identity *id = NULL;
17843+ int version = 2;
17844+ char szComment[1024];
17845+ Key *k = NULL;
17846+
17847+ pkcs11_identity *pkcs11_id = NULL;
17848+
17849+ pkcs11_id = pkcs11_identity_new ();
17850+ if (pkcs11_id != NULL) {
17851+ pkcs11_id->id = strdup (buffer_get_string(&e->request, NULL));
17852+ pkcs11_id->pin_cache_period = buffer_get_int(&e->request);
17853+ pkcs11_id->cert_file = strdup (buffer_get_string(&e->request, NULL));
17854+
17855+ pkcs11_getKey (
17856+ pkcs11_id,
17857+ &k,
17858+ szComment,
17859+ sizeof (szComment)
17860+ );
17861+
17862+ if (k != NULL) {
17863+ id = lookup_identity (k, version);
17864+ }
17865+
17866+ if (id != NULL) {
17867+ Idtab *tab = NULL;
17868+
17869+ tab = idtab_lookup(version);
17870+ TAILQ_REMOVE(&tab->idlist, id, next);
17871+ tab->nentries--;
17872+ free_identity(id);
17873+ id = NULL;
17874+ success = 1;
17875+ }
17876+ }
17877+
17878+ if (k != NULL) {
17879+ key_free (k);
17880+ }
17881+
17882+ if (pkcs11_id != NULL) {
17883+ pkcs11_identity_free (pkcs11_id);
17884+ }
17885+
17886+ buffer_put_int(&e->output, 1);
17887+ buffer_put_char(&e->output,
17888+ success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
17889+}
17890+
17891+#endif /* SSH_PKCS11_DISABLED */
17892+
17893 /* dispatch incoming messages */
17894
17895 static void
17896@@ -785,6 +937,21 @@ process_message(SocketEntry *e)
17897 process_remove_smartcard_key(e);
17898 break;
17899 #endif /* SMARTCARD */
17900+
17901+#ifndef SSH_PKCS11_DISABLED
17902+ case SSH_AGENTC_PKCS11_SET_ASK_PIN:
17903+ process_pkcs11_set_ask_pin (e);
17904+ break;
17905+ case SSH_AGENTC_PKCS11_ADD_PROVIDER:
17906+ process_pkcs11_add_provider (e);
17907+ break;
17908+ case SSH_AGENTC_PKCS11_ADD_ID:
17909+ process_pkcs11_add_id (e);
17910+ break;
17911+ case SSH_AGENTC_PKCS11_REMOVE_ID:
17912+ process_pkcs11_remove_id (e);
17913+ break;
17914+#endif /* SSH_PKCS11_DISABLED */
17915 default:
17916 /* Unknown message. Respond with failure. */
17917 error("Unknown message %d", type);
17918@@ -1064,7 +1231,7 @@ main(int ac, char **av)
17919 s_flag++;
17920 break;
17921 case 'd':
17922- if (d_flag)
17923+ if (d_flag > 3)
17924 usage();
17925 d_flag++;
17926 break;
17927@@ -1167,7 +1334,7 @@ main(int ac, char **av)
17928 * the socket data. The child continues as the authentication agent.
17929 */
17930 if (d_flag) {
17931- log_init(__progname, SYSLOG_LEVEL_DEBUG1, SYSLOG_FACILITY_AUTH, 1);
17932+ log_init(__progname, SYSLOG_LEVEL_DEBUG1+d_flag-1, SYSLOG_FACILITY_AUTH, 1);
17933 format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n";
17934 printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name,
17935 SSH_AUTHSOCKET_ENV_NAME);
17936@@ -1228,6 +1395,11 @@ main(int ac, char **av)
17937 #endif
17938
17939 skip:
17940+
17941+#ifndef SSH_PKCS11_DISABLED
17942+ pkcs11_initialize (1, -1);
17943+#endif /* SSH_PKCS11_DISABLED */
17944+
17945 new_socket(AUTH_SOCKET, sock);
17946 if (ac > 0) {
17947 mysignal(SIGALRM, check_parent_exists);
17948@@ -1251,4 +1423,8 @@ skip:
17949 after_select(readsetp, writesetp);
17950 }
17951 /* NOTREACHED */
17952+
17953+#ifndef SSH_PKCS11_DISABLED
17954+ pkcs11_terminate ();
17955+#endif /* SSH_PKCS11_DISABLED */
17956 }