1 diff -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)
9 +#ifndef SSH_PKCS11_DISABLED
12 +ssh_pkcs11_add_provider (AuthenticationConnection *auth, const char *provider,
13 + int protected_authentication, const char *sign_mode, int cert_private)
19 + code = SSH_AGENTC_PKCS11_ADD_PROVIDER;
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);
28 + if (ssh_request_reply(auth, &msg, &msg) == 0) {
32 + type = buffer_get_char(&msg);
34 + return decode_reply(type);
38 +ssh_pkcs11_id (AuthenticationConnection *auth, const pkcs11_identity *id, int remove)
44 + code = remove ? SSH_AGENTC_PKCS11_REMOVE_ID : SSH_AGENTC_PKCS11_ADD_ID;
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);
52 + if (ssh_request_reply(auth, &msg, &msg) == 0) {
56 + type = buffer_get_char(&msg);
58 + return decode_reply(type);
62 +ssh_pkcs11_set_ask_pin (AuthenticationConnection *auth, const char *pin_prog)
68 + code = SSH_AGENTC_PKCS11_SET_ASK_PIN;
71 + buffer_put_char(&msg, code);
72 + buffer_put_cstring(&msg, pin_prog);
74 + if (ssh_request_reply(auth, &msg, &msg) == 0) {
78 + type = buffer_get_char(&msg);
80 + return decode_reply(type);
83 +#endif /* SSH_PKCS11_DISABLED */
84 diff -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
93 /* Messages for the authentication agent connection. */
94 #define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1
95 #define SSH_AGENT_RSA_IDENTITIES_ANSWER 2
97 #define SSH2_AGENTC_ADD_ID_CONSTRAINED 25
98 #define SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED 26
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
105 #define SSH_AGENT_CONSTRAIN_LIFETIME 1
106 #define SSH_AGENT_CONSTRAIN_CONFIRM 2
108 @@ -92,4 +99,11 @@ int
109 ssh_agent_sign(AuthenticationConnection *, Key *, u_char **, u_int *, u_char *,
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 */
119 #endif /* AUTHFD_H */
120 diff -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
125 + - (alonbl) Removed logit from ssh-agent, thanks to Denniston, Todd.
126 + - (alonbl) Release 0.17
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
139 + - (alonbl) OpenSC bug workaround.
140 + - (alonbl) PKCS#11 release 0.15
143 + - (alonbl) Some pkcs11-helper updates.
144 + - (alonbl) Rebase against 4.4p1.
145 + - (alonbl) PKCS#11 release 0.14
148 + - (alonbl) PKCS#11 fixed handling multiproviders.
149 + - (alonbl) PKCS#11 release 0.13
152 + - (alonbl) PKCS#11 modifed to match X.509-5.5 patch, works OK with focing
154 + - (alonbl) PKCS#11 removed --pkcs11-x509-force-ssh argument.
155 + - (alonbl) PKCS#11 release 0.12
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
166 + - (alonbl) PKCS#11 fix handling empty attributes.
167 + - (alonbl) PKCS#11 release 0.10
170 + - (alonbl) PKCS#11 code sync.
171 + - (alonbl) PKCS#11 release 0.09
173 diff -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
180 +/* Define if you don't want use PKCS#11 */
181 +#undef SSH_PKCS11_DISABLED
183 +/* Define if you don't want use X509 with PKCS#11 */
184 +#undef SSH_PKCS11_X509_DISABLED
186 /* non-privileged user for privilege separation */
187 #undef SSH_PRIVSEP_USER
189 diff -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
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;}
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
216 +if test "x$ssh_pkcs11" = "xno"; then
218 +cat >>confdefs.h <<_ACEOF
219 +#define SSH_PKCS11_DISABLED 1
223 +if test "x$ssh_x509" = "x"; then
225 +cat >>confdefs.h <<_ACEOF
226 +#define SSH_PKCS11_X509_DISABLED 1
231 CFLAGS="$CFLAGS $werror_flags"
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"
242 diff -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])
250 +ssh_pkcs11_x509="yes"
251 +AC_ARG_ENABLE(pkcs11,
252 + [ --disable-pkcs11 Disable PKCS#11 support],
254 + if test "x$enableval" = "xno"; then
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])
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])
270 dnl Adding -Werror to CFLAGS early prevents configure tests from running.
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"
281 diff -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
285 +/* cryptoki.h include file for PKCS #11. */
286 +/* $Revision: 1.4 $ */
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.
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.
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.
303 +#ifndef ___CRYPTOKI_H_INC___
304 +#define ___CRYPTOKI_H_INC___
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)
317 +#include "pkcs11-headers/pkcs11.h"
319 +#endif /* ___CRYPTOKI_H_INC___ */
320 diff -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
324 +/* cryptoki.h include file for PKCS #11. */
325 +/* $Revision: 1.4 $ */
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.
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.
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.
342 +/* This is a sample file containing the top level include directives
343 + * for building Win32 Cryptoki libraries and applications.
346 +#ifndef ___CRYPTOKI_H_INC___
347 +#define ___CRYPTOKI_H_INC___
349 +#pragma pack(push, cryptoki, 1)
351 +/* Specifies that the function is a DLL entry point. */
352 +#define CK_IMPORT_SPEC __declspec(dllimport)
354 +/* Define CRYPTOKI_EXPORTS during the build of cryptoki libraries. Do
355 + * not define it in applications.
357 +#ifdef CRYPTOKI_EXPORTS
358 +/* Specified that the function is an exported DLL entry point. */
359 +#define CK_EXPORT_SPEC __declspec(dllexport)
361 +#define CK_EXPORT_SPEC CK_IMPORT_SPEC
364 +/* Ensures the calling convention for Win32 builds */
365 +#define CK_CALL_SPEC __cdecl
369 +#define CK_DEFINE_FUNCTION(returnType, name) \
370 + returnType CK_EXPORT_SPEC CK_CALL_SPEC name
372 +#define CK_DECLARE_FUNCTION(returnType, name) \
373 + returnType CK_EXPORT_SPEC CK_CALL_SPEC name
375 +#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
376 + returnType CK_IMPORT_SPEC (CK_CALL_SPEC CK_PTR name)
378 +#define CK_CALLBACK_FUNCTION(returnType, name) \
379 + returnType (CK_CALL_SPEC CK_PTR name)
385 +#include "pkcs11-headers/pkcs11.h"
387 +#pragma pack(pop, cryptoki)
389 +#endif /* ___CRYPTOKI_H_INC___ */
390 diff -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.
395 ****************************************************************************/
397 + d) PKCS #11: Cryptographic Token Interface Standard
399 + This software uses RSA Security Inc. PKCS #11 Cryptographic Token Interface (Cryptoki).
402 $OpenBSD: LICENCE,v 1.19 2004/08/30 09:18:08 markus Exp $
403 diff -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
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 \
414 diff -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
419 + * Copyright (c) 2005-2006 Alon Bar-Lev. All rights reserved.
421 + * Redistribution and use in source and binary forms, with or without
422 + * modification, are permitted provided that the following conditions
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.
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.
443 + * The routines in this file deal with providing private key cryptography
444 + * using RSA Security Inc. PKCS #11 Cryptographic Token Interface (Cryptoki).
448 +#include "includes.h"
449 +#include <sys/wait.h>
452 +#if !defined(SSH_PKCS11_DISABLED)
454 +#include "pkcs11-helper.h"
456 +#include "openssl/pem.h"
461 +ssh_from_x509 (X509 *x509);
463 +static char *s_szSetPINProg = NULL;
467 +_pkcs11_msg_pkcs112openssh (
468 + IN const unsigned flags
470 + unsigned openssh_flags;
473 + case PKCS11H_LOG_DEBUG2:
474 + openssh_flags = SYSLOG_LEVEL_DEBUG3;
476 + case PKCS11H_LOG_DEBUG1:
477 + openssh_flags = SYSLOG_LEVEL_DEBUG2;
479 + case PKCS11H_LOG_INFO:
480 + openssh_flags = SYSLOG_LEVEL_INFO;
482 + case PKCS11H_LOG_WARN:
483 + openssh_flags = SYSLOG_LEVEL_ERROR;
485 + case PKCS11H_LOG_ERROR:
486 + openssh_flags = SYSLOG_LEVEL_FATAL;
489 + openssh_flags = SYSLOG_LEVEL_FATAL;
493 + return openssh_flags;
498 +_pkcs11_msg_openssh2pkcs11 (
499 + IN const unsigned flags
501 + unsigned pkcs11_flags;
504 + case SYSLOG_LEVEL_DEBUG3:
505 + pkcs11_flags = PKCS11H_LOG_DEBUG2;
507 + case SYSLOG_LEVEL_DEBUG2:
508 + pkcs11_flags = PKCS11H_LOG_DEBUG1;
510 + case SYSLOG_LEVEL_INFO:
511 + pkcs11_flags = PKCS11H_LOG_INFO;
513 + case SYSLOG_LEVEL_ERROR:
514 + pkcs11_flags = PKCS11H_LOG_WARN;
516 + case SYSLOG_LEVEL_FATAL:
517 + pkcs11_flags = PKCS11H_LOG_ERROR;
520 + pkcs11_flags = PKCS11H_LOG_ERROR;
524 + return pkcs11_flags;
529 +_pkcs11_openssh_log (
530 + IN void * const pData,
532 + IN const char * const szFormat,
535 + do_log (_pkcs11_msg_pkcs112openssh (flags), szFormat, args);
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
547 + int fds[2] = {-1, -1};
551 + * Make sure we don't reuse PIN
554 + memset (szInput, 0, nMaxInput);
557 + if (fOK && s_szSetPINProg == NULL) {
561 + if (fOK && pipe (fds) == -1) {
565 + if (fOK && (pid = fork ()) == -1) {
574 + if (fOK && dup2 (fds[1], 1) == -1) {
604 + (r=waitpid (pid, &status, 0)) == 0 ||
605 + (r == -1 && errno == EINTR)
613 + if (fOK && !WIFEXITED (status)) {
617 + if (fOK && WEXITSTATUS (status) != 0) {
622 + if (!strcmp (szType, "password")) {
623 + if ((r = read (fds[0], szInput, nMaxInput)) == -1) {
635 + if (strlen (szInput) > 0 && szInput[strlen (szInput)-1] == '\n') {
636 + szInput[strlen (szInput)-1] = '\0';
639 + * for DOS compatability
641 + if (strlen (szInput) > 0 && szInput[strlen (szInput)-1] == '\r') {
642 + szInput[strlen (szInput)-1] = '\0';
648 + if (fds[0] != -1) {
653 + if (fds[1] != -1) {
664 + IN void * const pData,
665 + IN const char * const szFormat,
670 + va_start (args, szFormat);
671 + vprintf (szFormat, args);
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
683 + char szPrompt[1024];
686 + snprintf (szPrompt, sizeof (szPrompt), "Please insert token '%s' or cancel", token->display);
687 + return _pkcs11_ssh_prompt ("okcancel", szPrompt, szPIN, sizeof (szPIN));
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
700 + char szPrompt[1024];
702 + snprintf (szPrompt, sizeof (szPrompt), "Please enter PIN for token '%s'", token->display);
703 + return _pkcs11_ssh_prompt ("password", szPrompt, szPIN, nMaxPIN);
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
716 + char szPrompt[1024];
717 + snprintf (szPrompt, sizeof (szPrompt), "Please enter '%s' PIN or 'cancel': ", token->display);
718 + char *p = getpass (szPrompt);
720 + strncpy (szPIN, p, nMaxPIN);
721 + szPIN[nMaxPIN-1] = '\0';
723 + return strcmp (szPIN, "cancel") != 0;
733 + va_start (args, f);
734 + do_log (l, f, args);
740 + const int fProtectedAuthentication,
741 + const int nPINCachePeriod
746 + "PKCS#11: pkcs11_initialize - entered fProtectedAuthentication=%d, nPINCachePeriod=%d",
747 + fProtectedAuthentication,
753 + (rv = pkcs11h_initialize ()) != CKR_OK
755 + error ("PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage (rv));
760 + (rv = pkcs11h_setLogHook (_pkcs11_openssh_log, NULL)) != CKR_OK
762 + error ("PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv));
767 + * There is no way to get log level,
768 + * so set to minimum.
769 + * After fix in log.c it can be fixed.
771 + if (rv == CKR_OK) {
772 + pkcs11h_setLogLevel (_pkcs11_msg_openssh2pkcs11 (SYSLOG_LEVEL_DEBUG3));
777 + (rv = pkcs11h_setTokenPromptHook (_pkcs11_ssh_token_prompt, NULL)) != CKR_OK
779 + error ("PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv));
784 + (rv = pkcs11h_setPINPromptHook (_pkcs11_ssh_pin_prompt, NULL)) != CKR_OK
786 + error ("PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv));
791 + (rv = pkcs11h_setProtectedAuthentication (fProtectedAuthentication)) != CKR_OK
793 + error ("PKCS#11: Cannot set protected authentication mode %ld-'%s'", rv, pkcs11h_getMessage (rv));
798 + (rv = pkcs11h_setPINCachePeriod (nPINCachePeriod)) != CKR_OK
800 + error ("PKCS#11: Cannot set PIN cache period %ld-'%s'", rv, pkcs11h_getMessage (rv));
804 + "PKCS#11: pkcs11_initialize - return rv=%ld-'%s'",
806 + pkcs11h_getMessage (rv)
809 + return rv == CKR_OK;
813 +pkcs11_terminate () {
814 + debug3 ("PKCS#11: pkcs11_terminate - entered");
816 + pkcs11h_terminate ();
818 + debug3 ("PKCS#11: pkcs11_terminate - return");
823 + pkcs11h_forkFixup ();
828 + const char * const pin_prog
830 + if (pin_prog != NULL) {
831 + if (s_szSetPINProg != NULL) {
832 + xfree (s_szSetPINProg);
833 + s_szSetPINProg = NULL;
836 + s_szSetPINProg = xstrdup (pin_prog);
843 +pkcs11_addProvider (
844 + const char * const provider,
845 + const int fProtectedAuthentication,
846 + const char * const sign_mode,
847 + const int fCertIsPrivate
849 + unsigned maskSignMode = 0;
852 + PKCS11H_ASSERT (provider != NULL);
853 + PKCS11H_ASSERT (sign_mode != NULL);
856 + "PKCS#11: pkcs11_addProvider - entered - provider='%s', fProtectedAuthentication=%d, sign_mode='%s', fCertIsPrivate=%d",
858 + fProtectedAuthentication ? 1 : 0,
859 + sign_mode == NULL ? "default" : sign_mode,
860 + fCertIsPrivate ? 1 : 0
864 + "PKCS#11: Adding PKCS#11 provider '%s'",
868 + if (rv == CKR_OK) {
869 + if (sign_mode == NULL || !strcmp (sign_mode, "auto")) {
872 + else if (!strcmp (sign_mode, "sign")) {
873 + maskSignMode = PKCS11H_SIGNMODE_MASK_SIGN;
875 + else if (!strcmp (sign_mode, "recover")) {
876 + maskSignMode = PKCS11H_SIGNMODE_MASK_RECOVER;
878 + else if (!strcmp (sign_mode, "any")) {
880 + PKCS11H_SIGNMODE_MASK_SIGN |
881 + PKCS11H_SIGNMODE_MASK_RECOVER
885 + error ("PKCS#11: Invalid sign mode '%s'", sign_mode);
886 + rv = CKR_ARGUMENTS_BAD;
892 + (rv = pkcs11h_addProvider (
895 + fProtectedAuthentication,
897 + PKCS11H_SLOTEVENT_METHOD_AUTO,
902 + error ("PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv, pkcs11h_getMessage (rv));
906 + "PKCS#11: pkcs11_addProvider - return rv=%ld-'%s'",
908 + pkcs11h_getMessage (rv)
911 + return rv == CKR_OK;
915 +pkcs11_identity_new () {
916 + pkcs11_identity *id = xmalloc (sizeof (struct pkcs11_identity_s));
918 + memset (id, 0, sizeof (struct pkcs11_identity_s));
924 +pkcs11_identity_free (
925 + const pkcs11_identity * const id
928 + xfree ((void *)id);
934 + IN const pkcs11_identity * const id,
935 + OUT Key ** const sshkey,
936 + OUT char * const szComment,
937 + IN const int nCommentMax
941 + pkcs11h_certificate_id_t certificate_id = NULL;
942 + pkcs11h_certificate_t certificate = NULL;
943 + pkcs11h_openssl_session_t openssl_session = NULL;
950 + "PKCS#11: pkcs11_getKey - entered - id=%p, sshkey=%p, szComment=%p, nCommentMax=%d",
957 + PKCS11H_ASSERT (id != NULL);
958 + PKCS11H_ASSERT (sshkey!=NULL);
959 + PKCS11H_ASSERT (szComment!=NULL);
962 + "PKCS#11: pkcs11_getKey - id - id=%s, pin_cache_period=%d, cert_file=%s",
964 + id->pin_cache_period,
968 + PKCS11H_ASSERT (id->id);
972 + pkcs11h_certificate_deserializeCertificateId (&certificate_id, id->id)
975 + error ("PKCS#11: Cannot deserialize id %ld-'%s'", rv, pkcs11h_getMessage (rv));
980 + id->cert_file != NULL &&
981 + id->cert_file[0] != '\x0'
984 + unsigned char *p = NULL;
985 + unsigned char *certificate_blob = NULL;
986 + size_t certificate_blob_size = 0;
991 + (fp = fopen (id->cert_file, "r")) == NULL
994 + error ("PKCS#11: Cannot open file '%s'", id->cert_file);
1008 + error ("PKCS#11: Cannot read PEM from file '%s'", id->cert_file);
1013 + (certificate_blob_size = i2d_X509 (x509, NULL)) < 0
1016 + error ("PKCS#11: Cannot read decode certificate");
1021 + (certificate_blob = (unsigned char *)xmalloc (certificate_blob_size)) == NULL
1024 + error ("PKCS#11: Cannot allocate memory");
1028 + * i2d_X509 increments p!!!
1030 + p = certificate_blob;
1034 + (certificate_blob_size = i2d_X509 (x509, &p)) < 0
1037 + error ("PKCS#11: Cannot read decode certificate");
1042 + pkcs11h_certificate_setCertificateIdCertificateBlob (
1045 + certificate_blob_size
1049 + error ("PKCS#11: Cannot set certificate blob %ld-'%s'", rv, pkcs11h_getMessage (rv));
1052 + if (x509 != NULL) {
1057 + if (certificate_blob != NULL) {
1058 + xfree (certificate_blob);
1059 + certificate_blob = NULL;
1070 + (rv = pkcs11h_certificate_create (
1073 + PKCS11H_PROMPT_MASK_ALLOW_ALL,
1074 + id->pin_cache_period,
1079 + error ("PKCS#11: Cannot get certificate %ld-'%s'", rv, pkcs11h_getMessage (rv));
1082 + if (certificate_id != NULL){
1083 + pkcs11h_certificate_freeCertificateId (certificate_id);
1084 + certificate_id = NULL;
1088 + * Is called so next certificate_id will
1089 + * contain a proper description
1093 + (rv = pkcs11h_certificate_getCertificateBlob (
1100 + error ("PKCS#11: Cannot get certificate blob %ld-'%s'", rv, pkcs11h_getMessage (rv));
1105 + (rv = pkcs11h_certificate_getCertificateId (
1111 + error ("PKCS#11: Cannot get certificate_id %ld-'%s'", rv, pkcs11h_getMessage (rv));
1115 + strncpy (szComment, certificate_id->displayName, nCommentMax);
1116 + szComment[nCommentMax - 1] = '\0';
1121 + (openssl_session = pkcs11h_openssl_createSession (certificate)) == NULL
1124 + error ("PKCS#11: Cannot initialize openssl session");
1129 + * will be release by openssl_session
1131 + certificate = NULL;
1136 + (rsa = pkcs11h_openssl_session_getRSA (openssl_session)) == NULL
1139 + error ("PKCS#11: Unable get rsa object");
1144 + (x509 = pkcs11h_openssl_session_getX509 (openssl_session)) == NULL
1147 + error ("PKCS#11: Unable get certificate object");
1151 + *sshkey = key_new_private (KEY_UNSPEC);
1152 + (*sshkey)->rsa = rsa;
1154 +#if defined(SSH_PKCS11_X509_DISABLED)
1155 + (*sshkey)->type = KEY_RSA;
1157 + (*sshkey)->type = KEY_X509_RSA;
1158 + (*sshkey)->x509 = x509;
1163 + if (x509 != NULL) {
1168 + if (openssl_session != NULL) {
1169 + pkcs11h_openssl_freeSession (openssl_session);
1170 + openssl_session = NULL;
1173 + if (certificate != NULL) {
1174 + pkcs11h_certificate_freeCertificate (certificate);
1175 + certificate = NULL;
1178 + if (certificate_id != NULL) {
1179 + pkcs11h_certificate_freeCertificateId (certificate_id);
1180 + certificate_id = NULL;
1184 + "PKCS#11: pkcs11_getKey - return fOK=%d, rv=%ld",
1192 + const char * const provider,
1193 + int allow_protected_auth,
1194 + int cert_is_private
1196 + pkcs11h_certificate_id_list_t user_certificates = NULL;
1197 + pkcs11h_certificate_id_list_t current = NULL;
1198 + CK_RV rv = CKR_OK;
1200 + if (rv == CKR_OK) {
1201 + rv = pkcs11h_initialize ();
1204 + if (rv == CKR_OK) {
1205 + rv = pkcs11h_setLogHook (_pkcs11_openssh_log, NULL);
1208 + if (rv == CKR_OK) {
1209 + pkcs11h_setLogLevel (_pkcs11_msg_openssh2pkcs11 (SYSLOG_LEVEL_DEBUG3));
1212 + if (rv == CKR_OK) {
1213 + rv = pkcs11h_setPINPromptHook (_pkcs11_ssh_pin_prompt_cli, NULL);
1216 + if (rv == CKR_OK) {
1217 + rv = pkcs11h_setProtectedAuthentication (TRUE);
1220 + if (rv == CKR_OK) {
1221 + rv = pkcs11h_addProvider (
1224 + allow_protected_auth ? TRUE : FALSE,
1228 + cert_is_private ? TRUE : FALSE
1232 + if (rv == CKR_OK) {
1233 + rv = pkcs11h_certificate_enumCertificateIds (
1234 + PKCS11H_ENUM_METHOD_CACHE_EXIST,
1236 + PKCS11H_PROMPT_MASK_ALLOW_ALL,
1238 + &user_certificates
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};
1247 + char *ssh_key = NULL;
1248 + size_t ser_len = 0;
1250 + if (rv == CKR_OK) {
1251 + rv = pkcs11h_certificate_serializeCertificateId (NULL, &ser_len, current->certificate_id);
1256 + (ser = (char *)xmalloc (ser_len)) == NULL
1258 + rv = CKR_HOST_MEMORY;
1261 + if (rv == CKR_OK) {
1262 + rv = pkcs11h_certificate_serializeCertificateId (ser, &ser_len, current->certificate_id);
1265 + if (rv == CKR_OK) {
1266 + rv = pkcs11h_certificate_create (
1267 + current->certificate_id,
1269 + PKCS11H_PROMPT_MASK_ALLOW_ALL,
1270 + PKCS11H_PIN_CACHE_INFINITE,
1277 + (x509 = pkcs11h_openssl_getX509 (certificate)) == NULL
1279 + rv = CKR_FUNCTION_FAILED;
1282 + if (rv == CKR_OK) {
1283 + X509_NAME_oneline (
1284 + X509_get_subject_name (x509),
1291 + "********************************************\n"
1294 + " Serialized id: %s\n"
1301 + PEM_write_X509 (stdout, x509);
1306 + (ssh_key = ssh_from_x509 (x509)) != NULL
1320 + if (x509 != NULL) {
1325 + if (certificate != NULL) {
1326 + pkcs11h_certificate_freeCertificate (certificate);
1327 + certificate = NULL;
1330 + if (ser != NULL) {
1338 + if (rv != CKR_OK) {
1339 + error ("PKCS#11: Failed to get id %ld-'%s'", rv, pkcs11h_getMessage (rv));
1344 + if (user_certificates != NULL) {
1345 + pkcs11h_certificate_freeCertificateIdList (user_certificates);
1346 + user_certificates = NULL;
1349 + pkcs11h_terminate ();
1353 +pkcs11_dump_slots (
1354 + const char * const provider
1356 + pkcs11h_standalone_dump_slots (
1357 + _pkcs11_ssh_print,
1364 +pkcs11_dump_objects (
1365 + const char * const provider,
1366 + const char * const slot,
1367 + const char * const pin
1369 + pkcs11h_standalone_dump_objects (
1370 + _pkcs11_ssh_print,
1379 + * The ssh_from_x509 is dirived of Tatu and Markus work.
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
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) )
1394 +ssh_from_x509 (X509 *x509) {
1396 + EVP_PKEY *pubkey = NULL;
1397 + BIO *bio = NULL, *bio2 = NULL, *bio64 = NULL;
1398 + unsigned char *blob = NULL, *buffer = NULL;
1400 + int blobsize = 0, retsize = 0;
1401 + int bytes_name = 0, bytes_exponent = 0, bytes_modulus = 0;
1402 + unsigned char *bp;
1405 + const char *keyname = NULL;
1408 + if (ok && (pubkey = X509_get_pubkey (x509)) == NULL) {
1412 + if (ok && (bio64 = BIO_new (BIO_f_base64 ())) == NULL) {
1416 + if (ok && (bio = BIO_new (BIO_s_mem ())) == NULL) {
1420 + if (ok && (bio2 = BIO_push (bio64, bio)) == NULL) {
1424 + if (ok && pubkey->type != EVP_PKEY_RSA) {
1429 + keyname = "ssh-rsa";
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);
1439 + 4 + (bytes_exponent + 1) +
1440 + 4 + (bytes_modulus + 1) +
1445 + if (ok && (blob = (unsigned char *)xmalloc (blobsize)) == NULL) {
1449 + if (ok && (buffer = (unsigned char *)xmalloc (blobsize)) == NULL) {
1456 + PUT_32BIT (bp, bytes_name), bp += 4;
1457 + memcpy (bp, keyname, bytes_name), bp += bytes_name;
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;
1466 + PUT_32BIT (bp, bytes_exponent), bp += 4;
1468 + memcpy (bp, buffer, bytes_exponent), bp += bytes_exponent;
1470 + BN_bn2bin (pubkey->pkey.rsa->n, buffer);
1471 + if (buffer[0] & 0x80) {
1472 + PUT_32BIT (bp, bytes_modulus+1), bp += 4;
1475 + PUT_32BIT( bp, bytes_modulus ), bp += 4;
1477 + memcpy (bp, buffer, bytes_modulus), bp += bytes_modulus;
1481 + if (ok && BIO_write (bio2, blob, bp-blob) == -1) {
1485 + if (ok && BIO_flush (bio2) == -1) {
1490 + * Allocate the newline too... We will remove them later
1491 + * For MS, allocate return as well.
1494 + retsize = strlen (keyname) + 1 + (blobsize * 4 / 3) + (blobsize * 2 / 50) + 10 + 1;
1497 + if (ok && (ret = xmalloc (retsize)) == NULL) {
1502 + strcpy (ret, keyname);
1503 + strcat (ret, " ");
1506 + if (ok && (n = BIO_read (bio, ret + strlen (ret), retsize - strlen (ret) - 1)) == -1) {
1511 + ret[strlen (keyname) + 1 + n] = '\x0';
1515 + while ((p = strchr (ret, '\n')) != NULL) {
1516 + memmove (p, p+1, strlen (p)+1);
1518 + while ((p = strchr (ret, '\r')) != NULL) {
1519 + memmove (p, p+1, strlen (p)+1);
1524 + if (bio != NULL) {
1525 + BIO_free_all (bio);
1529 + if (pubkey != NULL) {
1530 + EVP_PKEY_free (pubkey);
1534 + if (buffer != NULL) {
1539 + if (blob != NULL) {
1545 + if (ret != NULL) {
1555 +static void dummy (void) {}
1556 +#endif /* SSH_PKCS11_DISABLED */
1557 diff -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
1562 + * Copyright (c) 2005-2006 Alon Bar-Lev. All rights reserved.
1564 + * Redistribution and use in source and binary forms, with or without
1565 + * modification, are permitted provided that the following conditions
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.
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.
1585 +#ifndef SSH_PKCS11_H
1586 +#define SSH_PKCS11_H
1588 +#if !defined(SSH_PKCS11_DISABLED)
1592 +typedef struct pkcs11_identity_s {
1594 + int pin_cache_period;
1599 +pkcs11_initialize (
1600 + const int fProtectedAuthentication,
1601 + const int nPINCachePeriod
1605 +pkcs11_terminate ();
1612 + const char * const pin_prog
1616 +pkcs11_addProvider (
1617 + const char * const provider,
1618 + const int fProtectedAuthentication,
1619 + const char * const sign_mode,
1620 + const int fCertIsPrivate
1624 +pkcs11_identity_new ();
1627 +pkcs11_identity_free (
1628 + const pkcs11_identity * const id
1633 + const pkcs11_identity * const id,
1634 + Key ** const sshkey,
1635 + char * const szComment,
1636 + const int nCommentMax
1641 + const char * const provider,
1642 + int allow_protected_auth,
1643 + int cert_is_private
1647 +pkcs11_dump_slots (
1648 + const char * const provider
1652 +pkcs11_dump_objects (
1653 + const char * const provider,
1654 + const char * const slot,
1655 + const char * const pin
1658 +#endif /* SSH_PKCS11_DISABLED */
1660 +#endif /* OPENSSH_PKCS11_H */
1661 diff -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
1665 +/* pkcs11f.h include file for PKCS #11. */
1666 +/* $Revision: 1.4 $ */
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.
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.
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.
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. */
1689 +/* General-purpose */
1691 +/* C_Initialize initializes the Cryptoki library. */
1692 +CK_PKCS11_FUNCTION_INFO(C_Initialize)
1693 +#ifdef CK_NEED_ARG_LIST
1695 + CK_VOID_PTR pInitArgs /* if this is not NULL_PTR, it gets
1696 + * cast to CK_C_INITIALIZE_ARGS_PTR
1697 + * and dereferenced */
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
1707 + CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */
1712 +/* C_GetInfo returns general information about Cryptoki. */
1713 +CK_PKCS11_FUNCTION_INFO(C_GetInfo)
1714 +#ifdef CK_NEED_ARG_LIST
1716 + CK_INFO_PTR pInfo /* location that receives information */
1721 +/* C_GetFunctionList returns the function list. */
1722 +CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
1723 +#ifdef CK_NEED_ARG_LIST
1725 + CK_FUNCTION_LIST_PTR_PTR ppFunctionList /* receives pointer to
1726 + * function list */
1732 +/* Slot and token management */
1734 +/* C_GetSlotList obtains a list of slots in the system. */
1735 +CK_PKCS11_FUNCTION_INFO(C_GetSlotList)
1736 +#ifdef CK_NEED_ARG_LIST
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 */
1745 +/* C_GetSlotInfo obtains information about a particular slot in
1747 +CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
1748 +#ifdef CK_NEED_ARG_LIST
1750 + CK_SLOT_ID slotID, /* the ID of the slot */
1751 + CK_SLOT_INFO_PTR pInfo /* receives the slot information */
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
1761 + CK_SLOT_ID slotID, /* ID of the token's slot */
1762 + CK_TOKEN_INFO_PTR pInfo /* receives the token information */
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
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. */
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
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 */
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 */
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) */
1804 +/* C_InitPIN initializes the normal user's PIN. */
1805 +CK_PKCS11_FUNCTION_INFO(C_InitPIN)
1806 +#ifdef CK_NEED_ARG_LIST
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 */
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
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 */
1829 +/* Session management */
1831 +/* C_OpenSession opens a session between an application and a
1833 +CK_PKCS11_FUNCTION_INFO(C_OpenSession)
1834 +#ifdef CK_NEED_ARG_LIST
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 */
1845 +/* C_CloseSession closes a session between an application and a
1847 +CK_PKCS11_FUNCTION_INFO(C_CloseSession)
1848 +#ifdef CK_NEED_ARG_LIST
1850 + CK_SESSION_HANDLE hSession /* the session's handle */
1855 +/* C_CloseAllSessions closes all sessions with a token. */
1856 +CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions)
1857 +#ifdef CK_NEED_ARG_LIST
1859 + CK_SLOT_ID slotID /* the token's slot */
1864 +/* C_GetSessionInfo obtains information about the session. */
1865 +CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo)
1866 +#ifdef CK_NEED_ARG_LIST
1868 + CK_SESSION_HANDLE hSession, /* the session's handle */
1869 + CK_SESSION_INFO_PTR pInfo /* receives session info */
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
1879 + CK_SESSION_HANDLE hSession, /* session's handle */
1880 + CK_BYTE_PTR pOperationState, /* gets state */
1881 + CK_ULONG_PTR pulOperationStateLen /* gets state length */
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
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 */
1900 +/* C_Login logs a user into a token. */
1901 +CK_PKCS11_FUNCTION_INFO(C_Login)
1902 +#ifdef CK_NEED_ARG_LIST
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 */
1912 +/* C_Logout logs a user out from a token. */
1913 +CK_PKCS11_FUNCTION_INFO(C_Logout)
1914 +#ifdef CK_NEED_ARG_LIST
1916 + CK_SESSION_HANDLE hSession /* the session's handle */
1922 +/* Object management */
1924 +/* C_CreateObject creates a new object. */
1925 +CK_PKCS11_FUNCTION_INFO(C_CreateObject)
1926 +#ifdef CK_NEED_ARG_LIST
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. */
1936 +/* C_CopyObject copies an object, creating a new object for the
1938 +CK_PKCS11_FUNCTION_INFO(C_CopyObject)
1939 +#ifdef CK_NEED_ARG_LIST
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 */
1950 +/* C_DestroyObject destroys an object. */
1951 +CK_PKCS11_FUNCTION_INFO(C_DestroyObject)
1952 +#ifdef CK_NEED_ARG_LIST
1954 + CK_SESSION_HANDLE hSession, /* the session's handle */
1955 + CK_OBJECT_HANDLE hObject /* the object's handle */
1960 +/* C_GetObjectSize gets the size of an object in bytes. */
1961 +CK_PKCS11_FUNCTION_INFO(C_GetObjectSize)
1962 +#ifdef CK_NEED_ARG_LIST
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 */
1971 +/* C_GetAttributeValue obtains the value of one or more object
1973 +CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
1974 +#ifdef CK_NEED_ARG_LIST
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 */
1984 +/* C_SetAttributeValue modifies the value of one or more object
1986 +CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue)
1987 +#ifdef CK_NEED_ARG_LIST
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 */
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
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 */
2009 +/* C_FindObjects continues a search for token and session
2010 + * objects that match a template, obtaining additional object
2012 +CK_PKCS11_FUNCTION_INFO(C_FindObjects)
2013 +#ifdef CK_NEED_ARG_LIST
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 */
2023 +/* C_FindObjectsFinal finishes a search for token and session
2025 +CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal)
2026 +#ifdef CK_NEED_ARG_LIST
2028 + CK_SESSION_HANDLE hSession /* the session's handle */
2034 +/* Encryption and decryption */
2036 +/* C_EncryptInit initializes an encryption operation. */
2037 +CK_PKCS11_FUNCTION_INFO(C_EncryptInit)
2038 +#ifdef CK_NEED_ARG_LIST
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 */
2047 +/* C_Encrypt encrypts single-part data. */
2048 +CK_PKCS11_FUNCTION_INFO(C_Encrypt)
2049 +#ifdef CK_NEED_ARG_LIST
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 */
2060 +/* C_EncryptUpdate continues a multiple-part encryption
2062 +CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate)
2063 +#ifdef CK_NEED_ARG_LIST
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 */
2074 +/* C_EncryptFinal finishes a multiple-part encryption
2076 +CK_PKCS11_FUNCTION_INFO(C_EncryptFinal)
2077 +#ifdef CK_NEED_ARG_LIST
2079 + CK_SESSION_HANDLE hSession, /* session handle */
2080 + CK_BYTE_PTR pLastEncryptedPart, /* last c-text */
2081 + CK_ULONG_PTR pulLastEncryptedPartLen /* gets last size */
2086 +/* C_DecryptInit initializes a decryption operation. */
2087 +CK_PKCS11_FUNCTION_INFO(C_DecryptInit)
2088 +#ifdef CK_NEED_ARG_LIST
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 */
2097 +/* C_Decrypt decrypts encrypted data in a single part. */
2098 +CK_PKCS11_FUNCTION_INFO(C_Decrypt)
2099 +#ifdef CK_NEED_ARG_LIST
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 */
2110 +/* C_DecryptUpdate continues a multiple-part decryption
2112 +CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate)
2113 +#ifdef CK_NEED_ARG_LIST
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 */
2124 +/* C_DecryptFinal finishes a multiple-part decryption
2126 +CK_PKCS11_FUNCTION_INFO(C_DecryptFinal)
2127 +#ifdef CK_NEED_ARG_LIST
2129 + CK_SESSION_HANDLE hSession, /* the session's handle */
2130 + CK_BYTE_PTR pLastPart, /* gets plaintext */
2131 + CK_ULONG_PTR pulLastPartLen /* p-text size */
2137 +/* Message digesting */
2139 +/* C_DigestInit initializes a message-digesting operation. */
2140 +CK_PKCS11_FUNCTION_INFO(C_DigestInit)
2141 +#ifdef CK_NEED_ARG_LIST
2143 + CK_SESSION_HANDLE hSession, /* the session's handle */
2144 + CK_MECHANISM_PTR pMechanism /* the digesting mechanism */
2149 +/* C_Digest digests data in a single part. */
2150 +CK_PKCS11_FUNCTION_INFO(C_Digest)
2151 +#ifdef CK_NEED_ARG_LIST
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 */
2162 +/* C_DigestUpdate continues a multiple-part message-digesting
2164 +CK_PKCS11_FUNCTION_INFO(C_DigestUpdate)
2165 +#ifdef CK_NEED_ARG_LIST
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 */
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
2180 + CK_SESSION_HANDLE hSession, /* the session's handle */
2181 + CK_OBJECT_HANDLE hKey /* secret key to digest */
2186 +/* C_DigestFinal finishes a multiple-part message-digesting
2188 +CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
2189 +#ifdef CK_NEED_ARG_LIST
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 */
2199 +/* Signing and MACing */
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
2205 +CK_PKCS11_FUNCTION_INFO(C_SignInit)
2206 +#ifdef CK_NEED_ARG_LIST
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 */
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
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 */
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
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 */
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
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 */
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
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 */
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
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 */
2282 +/* Verifying signatures and MACs */
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
2290 + CK_SESSION_HANDLE hSession, /* the session's handle */
2291 + CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
2292 + CK_OBJECT_HANDLE hKey /* verification key */
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
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*/
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
2318 + CK_SESSION_HANDLE hSession, /* the session's handle */
2319 + CK_BYTE_PTR pPart, /* signed data */
2320 + CK_ULONG ulPartLen /* length of signed data */
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
2330 + CK_SESSION_HANDLE hSession, /* the session's handle */
2331 + CK_BYTE_PTR pSignature, /* signature to verify */
2332 + CK_ULONG ulSignatureLen /* signature length */
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
2342 + CK_SESSION_HANDLE hSession, /* the session's handle */
2343 + CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
2344 + CK_OBJECT_HANDLE hKey /* verification key */
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
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 */
2364 +/* Dual-function cryptographic operations */
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
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 */
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
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 */
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
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 */
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
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 */
2423 +/* Key management */
2425 +/* C_GenerateKey generates a secret key, creating a new key
2427 +CK_PKCS11_FUNCTION_INFO(C_GenerateKey)
2428 +#ifdef CK_NEED_ARG_LIST
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 */
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
2444 + CK_SESSION_HANDLE hSession, /* session
2446 + CK_MECHANISM_PTR pMechanism, /* key-gen
2448 + CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* template
2451 + CK_ULONG ulPublicKeyAttributeCount, /* # pub.
2453 + CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* template
2456 + CK_ULONG ulPrivateKeyAttributeCount, /* # priv.
2458 + CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub.
2461 + CK_OBJECT_HANDLE_PTR phPrivateKey /* gets
2468 +/* C_WrapKey wraps (i.e., encrypts) a key. */
2469 +CK_PKCS11_FUNCTION_INFO(C_WrapKey)
2470 +#ifdef CK_NEED_ARG_LIST
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 */
2482 +/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
2484 +CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
2485 +#ifdef CK_NEED_ARG_LIST
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 */
2499 +/* C_DeriveKey derives a key from a base key, creating a new key
2501 +CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
2502 +#ifdef CK_NEED_ARG_LIST
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 */
2515 +/* Random number generation */
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
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 */
2529 +/* C_GenerateRandom generates random data. */
2530 +CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
2531 +#ifdef CK_NEED_ARG_LIST
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 */
2541 +/* Parallel function management */
2543 +/* C_GetFunctionStatus is a legacy function; it obtains an
2544 + * updated status of a function running in parallel with an
2546 +CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
2547 +#ifdef CK_NEED_ARG_LIST
2549 + CK_SESSION_HANDLE hSession /* the session's handle */
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
2559 + CK_SESSION_HANDLE hSession /* the session's handle */
2565 +/* Functions added in for Cryptoki Version 2.01 or later */
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
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 */
2577 diff -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
2581 +/* pkcs11.h include file for PKCS #11. */
2582 +/* $Revision: 1.4 $ */
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.
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.
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.
2600 +#define _PKCS11_H_ 1
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
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
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:
2623 + * #pragma pack(push, cryptoki, 1)
2625 + * and using the following preprocessor directive after including
2626 + * pkcs11.h or pkcs11t.h:
2628 + * #pragma pack(pop, cryptoki)
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:
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.
2641 + * Now for the macros:
2644 + * 1. CK_PTR: The indirection string for making a pointer to an
2645 + * object. It can be used like this:
2647 + * typedef CK_BYTE CK_PTR CK_BYTE_PTR;
2649 + * If you're using Microsoft Developer Studio 5.0 to produce
2650 + * Win32 stuff, it might be defined by:
2652 + * #define CK_PTR *
2654 + * If you're using an earlier version of Microsoft Developer
2655 + * Studio to produce Win16 stuff, it might be defined by:
2657 + * #define CK_PTR far *
2659 + * In a typical UNIX environment, it might be defined by:
2661 + * #define CK_PTR *
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:
2670 + * CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
2671 + * CK_VOID_PTR pReserved
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:
2680 + * #define CK_DEFINE_FUNCTION(returnType, name) \
2681 + * returnType __declspec(dllexport) name
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:
2687 + * #define CK_DEFINE_FUNCTION(returnType, name) \
2688 + * returnType __export _far _pascal name
2690 + * In a UNIX environment, it might be defined by:
2692 + * #define CK_DEFINE_FUNCTION(returnType, name) \
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:
2701 + * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
2702 + * CK_VOID_PTR pReserved
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:
2708 + * #define CK_DECLARE_FUNCTION(returnType, name) \
2709 + * returnType __declspec(dllimport) name
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:
2715 + * #define CK_DECLARE_FUNCTION(returnType, name) \
2716 + * returnType __export _far _pascal name
2718 + * In a UNIX environment, it might be defined by:
2720 + * #define CK_DECLARE_FUNCTION(returnType, name) \
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:
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);
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
2739 + * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
2740 + * funcPtrType funcPtr;
2742 + * If you're using Microsoft Developer Studio 5.0 to access
2743 + * functions in a Win32 Cryptoki .dll, in might be defined by:
2745 + * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
2746 + * returnType __declspec(dllimport) (* name)
2748 + * If you're using an earlier version of Microsoft Developer
2749 + * Studio to access functions in a Win16 Cryptoki .dll, it might
2752 + * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
2753 + * returnType __export _far _pascal (* name)
2755 + * In a UNIX environment, it might be defined by:
2757 + * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
2758 + * returnType (* name)
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:
2766 + * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
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:
2772 + * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
2773 + * myCallbackType myCallback;
2775 + * If you're using Microsoft Developer Studio 5.0 to do Win32
2776 + * Cryptoki development, it might be defined by:
2778 + * #define CK_CALLBACK_FUNCTION(returnType, name) \
2779 + * returnType (* name)
2781 + * If you're using an earlier version of Microsoft Developer
2782 + * Studio to do Win16 development, it might be defined by:
2784 + * #define CK_CALLBACK_FUNCTION(returnType, name) \
2785 + * returnType _far _pascal (* name)
2787 + * In a UNIX environment, it might be defined by:
2789 + * #define CK_CALLBACK_FUNCTION(returnType, name) \
2790 + * returnType (* name)
2793 + * 6. NULL_PTR: This macro is the value of a NULL pointer.
2795 + * In any ANSI/ISO C environment (and in many others as well),
2796 + * this should best be defined by
2798 + * #ifndef NULL_PTR
2799 + * #define NULL_PTR 0
2804 +/* All the various Cryptoki types and #define'd values are in the
2805 + * file pkcs11t.h. */
2806 +#include "pkcs11t.h"
2808 +#define __PASTE(x,y) x##y
2811 +/* ==============================================================
2812 + * Define the "extern" form of all the entry points.
2813 + * ==============================================================
2816 +#define CK_NEED_ARG_LIST 1
2817 +#define CK_PKCS11_FUNCTION_INFO(name) \
2818 + extern CK_DECLARE_FUNCTION(CK_RV, name)
2820 +/* pkcs11f.h has all the information about the Cryptoki
2821 + * function prototypes. */
2822 +#include "pkcs11f.h"
2824 +#undef CK_NEED_ARG_LIST
2825 +#undef CK_PKCS11_FUNCTION_INFO
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 + * ==============================================================
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))
2839 +/* pkcs11f.h has all the information about the Cryptoki
2840 + * function prototypes. */
2841 +#include "pkcs11f.h"
2843 +#undef CK_NEED_ARG_LIST
2844 +#undef CK_PKCS11_FUNCTION_INFO
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
2853 + * ==============================================================
2856 +#define CK_PKCS11_FUNCTION_INFO(name) \
2857 + __PASTE(CK_,name) name;
2859 +struct CK_FUNCTION_LIST {
2861 + CK_VERSION version; /* Cryptoki version */
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"
2870 +#undef CK_PKCS11_FUNCTION_INFO
2880 diff -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
2884 +/* pkcs11t.h include file for PKCS #11. */
2885 +/* $Revision: 1.6 $ */
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.
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.
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.
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. */
2906 +#ifndef _PKCS11T_H_
2907 +#define _PKCS11T_H_ 1
2912 +#ifndef CK_DISABLE_TRUE_FALSE
2914 +#define FALSE CK_FALSE
2918 +#define TRUE CK_TRUE
2922 +/* an unsigned 8-bit value */
2923 +typedef unsigned char CK_BYTE;
2925 +/* an unsigned 8-bit character */
2926 +typedef CK_BYTE CK_CHAR;
2928 +/* an 8-bit UTF-8 character */
2929 +typedef CK_BYTE CK_UTF8CHAR;
2931 +/* a BYTE-sized Boolean flag */
2932 +typedef CK_BYTE CK_BBOOL;
2934 +/* an unsigned value, at least 32 bits long */
2935 +typedef unsigned long int CK_ULONG;
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;
2941 +/* at least 32 bits; each bit is a Boolean flag */
2942 +typedef CK_ULONG CK_FLAGS;
2945 +/* some special values for certain CK_ULONG variables */
2946 +#define CK_UNAVAILABLE_INFORMATION (~0UL)
2947 +#define CK_EFFECTIVELY_INFINITE 0
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;
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;
2960 +/* The following value is always invalid if used as a session */
2961 +/* handle or object handle */
2962 +#define CK_INVALID_HANDLE 0
2965 +typedef struct CK_VERSION {
2966 + CK_BYTE major; /* integer portion of version number */
2967 + CK_BYTE minor; /* 1/100ths portion of version number */
2970 +typedef CK_VERSION CK_PTR CK_VERSION_PTR;
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 */
2980 + /* libraryDescription and libraryVersion are new for v2.0 */
2981 + CK_UTF8CHAR libraryDescription[32]; /* blank padded */
2982 + CK_VERSION libraryVersion; /* version of library */
2985 +typedef CK_INFO CK_PTR CK_INFO_PTR;
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
2992 +typedef CK_ULONG CK_NOTIFICATION;
2993 +#define CKN_SURRENDER 0
2996 +typedef CK_ULONG CK_SLOT_ID;
2998 +typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
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 */
3009 + /* hardwareVersion and firmwareVersion are new for v2.0 */
3010 + CK_VERSION hardwareVersion; /* version of hardware */
3011 + CK_VERSION firmwareVersion; /* version of firmware */
3014 +/* flags: bit flags that provide capabilities of the slot
3015 + * Bit Flag Mask Meaning
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 */
3021 +typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
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 */
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 */
3048 + /* hardwareVersion, firmwareVersion, and time are new for
3050 + CK_VERSION hardwareVersion; /* version of hardware */
3051 + CK_VERSION firmwareVersion; /* version of firmware */
3052 + CK_CHAR utcTime[16]; /* time */
3055 +/* The flags parameter is defined as follows:
3056 + * Bit Flag Mask Meaning
3058 +#define CKF_RNG 0x00000001 /* has random #
3060 +#define CKF_WRITE_PROTECTED 0x00000002 /* token is
3063 +#define CKF_LOGIN_REQUIRED 0x00000004 /* user must
3065 +#define CKF_USER_PIN_INITIALIZED 0x00000008 /* normal user's
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
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
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
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
3089 +#define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200
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
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
3102 +#define CKF_SECONDARY_AUTHENTICATION 0x00000800
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
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
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
3116 +#define CKF_USER_PIN_LOCKED 0x00040000
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
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
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
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.
3136 +#define CKF_SO_PIN_LOCKED 0x00400000
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
3144 +typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
3147 +/* CK_SESSION_HANDLE is a Cryptoki-assigned value that
3148 + * identifies a session */
3149 +typedef CK_ULONG CK_SESSION_HANDLE;
3151 +typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR;
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
3157 +typedef CK_ULONG CK_USER_TYPE;
3158 +/* Security Officer */
3162 +/* Context specific (added in v2.20) */
3163 +#define CKU_CONTEXT_SPECIFIC 2
3165 +/* CK_STATE enumerates the session states */
3166 +/* CK_STATE has been changed from an enum to a CK_ULONG for
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
3176 +/* CK_SESSION_INFO provides information about a session */
3177 +typedef struct CK_SESSION_INFO {
3178 + CK_SLOT_ID slotID;
3180 + CK_FLAGS flags; /* see below */
3182 + /* ulDeviceError was changed from CK_USHORT to CK_ULONG for
3184 + CK_ULONG ulDeviceError; /* device-dependent error code */
3187 +/* The flags are defined in the following table:
3188 + * Bit Flag Mask Meaning
3190 +#define CKF_RW_SESSION 0x00000002 /* session is r/w */
3191 +#define CKF_SERIAL_SESSION 0x00000004 /* no parallel */
3193 +typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR;
3196 +/* CK_OBJECT_HANDLE is a token-specific identifier for an
3198 +typedef CK_ULONG CK_OBJECT_HANDLE;
3200 +typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR;
3203 +/* CK_OBJECT_CLASS is a value that identifies the classes (or
3204 + * types) of objects that Cryptoki recognizes. It is defined
3206 +/* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for
3208 +typedef CK_ULONG CK_OBJECT_CLASS;
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
3224 +typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
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;
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
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;
3242 +/* the following key types are defined: */
3243 +#define CKK_RSA 0x00000000
3244 +#define CKK_DSA 0x00000001
3245 +#define CKK_DH 0x00000002
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
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
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
3275 +/* BlowFish and TwoFish are new for v2.20 */
3276 +#define CKK_BLOWFISH 0x00000020
3277 +#define CKK_TWOFISH 0x00000021
3279 +#define CKK_VENDOR_DEFINED 0x80000000
3282 +/* CK_CERTIFICATE_TYPE is a value that identifies a certificate
3284 +/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG
3286 +typedef CK_ULONG CK_CERTIFICATE_TYPE;
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
3297 +/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute
3299 +/* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for
3301 +typedef CK_ULONG CK_ATTRIBUTE_TYPE;
3303 +/* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which
3304 + consists of an array of values. */
3305 +#define CKF_ARRAY_ATTRIBUTE 0x40000000
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
3315 +/* CKA_OBJECT_ID is new for v2.10 */
3316 +#define CKA_OBJECT_ID 0x00000012
3318 +#define CKA_CERTIFICATE_TYPE 0x00000080
3319 +#define CKA_ISSUER 0x00000081
3320 +#define CKA_SERIAL_NUMBER 0x00000082
3322 +/* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new
3324 +#define CKA_AC_ISSUER 0x00000083
3325 +#define CKA_OWNER 0x00000084
3326 +#define CKA_ATTR_TYPES 0x00000085
3328 +/* CKA_TRUSTED is new for v2.11 */
3329 +#define CKA_TRUSTED 0x00000086
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
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
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) */
3374 +#define CKA_VALUE_BITS 0x00000160
3375 +#define CKA_VALUE_LEN 0x00000161
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
3385 +/* CKA_KEY_GEN_MECHANISM is new for v2.11 */
3386 +#define CKA_KEY_GEN_MECHANISM 0x00000166
3388 +#define CKA_MODIFIABLE 0x00000170
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
3395 +#define CKA_EC_POINT 0x00000181
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
3402 +/* CKA_ALWAYS_AUTHENTICATE ...
3403 + * CKA_UNWRAP_TEMPLATE are new for v2.20 */
3404 +#define CKA_ALWAYS_AUTHENTICATE 0x00000202
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)
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
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)
3433 +#define CKA_VENDOR_DEFINED 0x80000000
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;
3442 + /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */
3443 + CK_ULONG ulValueLen; /* in bytes */
3446 +typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR;
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") */
3457 +/* CK_MECHANISM_TYPE is a value that identifies a mechanism
3459 +/* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for
3461 +typedef CK_ULONG CK_MECHANISM_TYPE;
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
3555 +#define CKM_MD2 0x00000200
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
3561 +#define CKM_MD5 0x00000210
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
3567 +#define CKM_SHA_1 0x00000220
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
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
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
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
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
3651 +/* CKM_TLS_PRF is new for v2.20 */
3652 +#define CKM_TLS_PRF 0x00000378
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
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
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
3680 +/* CKM_PKCS5_PBKD2 is new for v2.10 */
3681 +#define CKM_PKCS5_PBKD2 0x000003B0
3683 +#define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0
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
3693 +#define CKM_KEY_WRAP_LYNKS 0x00000400
3694 +#define CKM_KEY_WRAP_SET_OAEP 0x00000401
3696 +/* CKM_CMS_SIG is new for v2.20 */
3697 +#define CKM_CMS_SIG 0x00000500
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
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
3727 +#define CKM_ECDSA 0x00001041
3728 +#define CKM_ECDSA_SHA1 0x00001042
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
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
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
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
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
3770 +#define CKM_DSA_PARAMETER_GEN 0x00002000
3771 +#define CKM_DH_PKCS_PARAMETER_GEN 0x00002001
3772 +#define CKM_X9_42_DH_PARAMETER_GEN 0x00002002
3774 +#define CKM_VENDOR_DEFINED 0x80000000
3776 +typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR;
3779 +/* CK_MECHANISM is a structure that specifies a particular
3781 +typedef struct CK_MECHANISM {
3782 + CK_MECHANISM_TYPE mechanism;
3783 + CK_VOID_PTR pParameter;
3785 + /* ulParameterLen was changed from CK_USHORT to CK_ULONG for
3787 + CK_ULONG ulParameterLen; /* in bytes */
3790 +typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR;
3793 +/* CK_MECHANISM_INFO provides information about a particular
3795 +typedef struct CK_MECHANISM_INFO {
3796 + CK_ULONG ulMinKeySize;
3797 + CK_ULONG ulMaxKeySize;
3799 +} CK_MECHANISM_INFO;
3801 +/* The flags are defined as follows:
3802 + * Bit Flag Mask Meaning */
3803 +#define CKF_HW 0x00000001 /* performed by HW */
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
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
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
3834 +#define CKF_EXTENSION 0x80000000 /* FALSE for this version */
3836 +typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR;
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;
3844 +#define CKR_OK 0x00000000
3845 +#define CKR_CANCEL 0x00000001
3846 +#define CKR_HOST_MEMORY 0x00000002
3847 +#define CKR_SLOT_ID_INVALID 0x00000003
3849 +/* CKR_FLAGS_INVALID was removed for v2.0 */
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
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
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
3876 +/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */
3877 +#define CKR_FUNCTION_NOT_SUPPORTED 0x00000054
3879 +#define CKR_KEY_HANDLE_INVALID 0x00000060
3881 +/* CKR_KEY_SENSITIVE was removed for v2.0 */
3883 +#define CKR_KEY_SIZE_RANGE 0x00000062
3884 +#define CKR_KEY_TYPE_INCONSISTENT 0x00000063
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
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
3898 +#define CKR_MECHANISM_INVALID 0x00000070
3899 +#define CKR_MECHANISM_PARAM_INVALID 0x00000071
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
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
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
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
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
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
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
3953 +/* These are new to v2.0 */
3954 +#define CKR_RANDOM_NO_RNG 0x00000121
3956 +/* These are new to v2.11 */
3957 +#define CKR_DOMAIN_PARAMS_INVALID 0x00000130
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
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
3971 +/* This is new to v2.20 */
3972 +#define CKR_FUNCTION_REJECTED 0x00000200
3974 +#define CKR_VENDOR_DEFINED 0x80000000
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 */
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;
3991 +typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR;
3993 +typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR;
3996 +/* CK_CREATEMUTEX is an application callback for creating a
3998 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)(
3999 + CK_VOID_PTR_PTR ppMutex /* location to receive ptr to mutex */
4003 +/* CK_DESTROYMUTEX is an application callback for destroying a
4005 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)(
4006 + CK_VOID_PTR pMutex /* pointer to mutex */
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 */
4016 +/* CK_UNLOCKMUTEX is an application callback for unlocking a
4018 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)(
4019 + CK_VOID_PTR pMutex /* pointer to mutex */
4023 +/* CK_C_INITIALIZE_ARGS provides the optional arguments to
4025 +typedef struct CK_C_INITIALIZE_ARGS {
4026 + CK_CREATEMUTEX CreateMutex;
4027 + CK_DESTROYMUTEX DestroyMutex;
4028 + CK_LOCKMUTEX LockMutex;
4029 + CK_UNLOCKMUTEX UnlockMutex;
4031 + CK_VOID_PTR pReserved;
4032 +} CK_C_INITIALIZE_ARGS;
4034 +/* flags: bit flags that provide capabilities of the slot
4035 + * Bit Flag Mask Meaning
4037 +#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001
4038 +#define CKF_OS_LOCKING_OK 0x00000002
4040 +typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
4043 +/* additional flags for parameters to functions */
4045 +/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
4046 +#define CKF_DONT_BLOCK 1
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
4053 +typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE;
4055 +typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR;
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
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;
4071 +typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR;
4073 +/* The following encoding parameter sources are defined */
4074 +#define CKZ_DATA_SPECIFIED 0x00000001
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;
4087 +typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR;
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;
4096 +} CK_RSA_PKCS_PSS_PARAMS;
4098 +typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR;
4100 +/* CK_EC_KDF_TYPE is new for v2.11. */
4101 +typedef CK_ULONG CK_EC_KDF_TYPE;
4103 +/* The following EC Key Derivation Functions are defined */
4104 +#define CKD_NULL 0x00000001
4105 +#define CKD_SHA1_KDF 0x00000002
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.
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;
4120 +typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR;
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;
4138 +typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR;
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;
4153 +typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR;
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;
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
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;
4177 +typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR;
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;
4195 +typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR;
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;
4210 +typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR;
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;
4224 +typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR;
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;
4232 +typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR;
4235 +/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC
4237 +typedef struct CK_RC2_CBC_PARAMS {
4238 + /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for
4240 + CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
4242 + CK_BYTE iv[8]; /* IV for CBC mode */
4243 +} CK_RC2_CBC_PARAMS;
4245 +typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR;
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;
4256 +typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \
4257 + CK_RC2_MAC_GENERAL_PARAMS_PTR;
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 */
4268 +typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR;
4271 +/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC
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;
4281 +typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR;
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;
4293 +typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \
4294 + CK_RC5_MAC_GENERAL_PARAMS_PTR;
4297 +/* CK_MAC_GENERAL_PARAMS provides the parameters to most block
4298 + * ciphers' MAC_GENERAL mechanisms. Its value is the length of
4300 +/* CK_MAC_GENERAL_PARAMS is new for v2.0 */
4301 +typedef CK_ULONG CK_MAC_GENERAL_PARAMS;
4303 +typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
4305 +/* CK_DES/AES_ECB/CBC_ENCRYPT_DATA_PARAMS are new for v2.20 */
4306 +typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS {
4308 + CK_BYTE_PTR pData;
4310 +} CK_DES_CBC_ENCRYPT_DATA_PARAMS;
4312 +typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR;
4314 +typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS {
4316 + CK_BYTE_PTR pData;
4318 +} CK_AES_CBC_ENCRYPT_DATA_PARAMS;
4320 +typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR;
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;
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;
4339 +typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \
4340 + CK_SKIPJACK_PRIVATE_WRAP_PTR;
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;
4363 +typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \
4364 + CK_SKIPJACK_RELAYX_PARAMS_PTR;
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;
4376 +typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
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;
4388 +typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \
4389 + CK_KEY_WRAP_SET_OAEP_PARAMS_PTR;
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;
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;
4405 +typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \
4406 + CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR;
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;
4418 +typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR;
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;
4430 +typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
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;
4442 +typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR;
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;
4452 +typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR;
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;
4460 +typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \
4461 + CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR;
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;
4473 +typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR;
4475 +typedef struct CK_WTLS_KEY_MAT_OUT {
4476 + CK_OBJECT_HANDLE hMacSecret;
4477 + CK_OBJECT_HANDLE hKey;
4479 +} CK_WTLS_KEY_MAT_OUT;
4481 +typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR;
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;
4494 +typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR;
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;
4508 +typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR;
4510 +typedef struct CK_KEY_DERIVATION_STRING_DATA {
4511 + CK_BYTE_PTR pData;
4513 +} CK_KEY_DERIVATION_STRING_DATA;
4515 +typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \
4516 + CK_KEY_DERIVATION_STRING_DATA_PTR;
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
4523 +/* CK_EXTRACT_PARAMS is new for v2.0 */
4524 +typedef CK_ULONG CK_EXTRACT_PARAMS;
4526 +typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
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;
4534 +typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR;
4536 +/* The following PRFs are defined in PKCS #5 v2.0. */
4537 +#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001
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
4544 +typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE;
4546 +typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR;
4548 +/* The following salt value sources are defined in PKCS #5 v2.0. */
4549 +#define CKZ_SALT_SPECIFIED 0x00000001
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;
4566 +typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
4569 diff -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
4574 + * Copyright (c) 2005-2006 Alon Bar-Lev <alon.barlev@gmail.com>
4575 + * All rights reserved.
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.
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.
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.
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
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:
4602 + * o Redistributions of source code must retain the above copyright notice,
4603 + * this list of conditions and the following disclaimer.
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.
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
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.
4626 + * The routines in this file deal with providing private key cryptography
4627 + * using RSA Security Inc. PKCS #11 Cryptographic Token Interface (Cryptoki).
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.
4648 + * - (alonbl) Fix handling mutiple providers.
4649 + * - (alonbl) Release 01.01.
4652 + * - (alonbl) First stable release.
4653 + * - (alonbl) Release 01.00.
4657 +#include "pkcs11-helper-config.h"
4659 +#if defined(ENABLE_PKCS11H_HELPER)
4661 +#include "pkcs11-helper.h"
4663 +/*===========================================
4667 +#if defined(USE_PKCS11H_OPENSSL)
4669 +#if OPENSSL_VERSION_NUMBER < 0x00907000L && defined(CRYPTO_LOCK_ENGINE)
4670 +# define RSA_get_default_method RSA_get_default_openssl_method
4672 +# ifdef HAVE_ENGINE_GET_DEFAULT_RSA
4673 +# include <openssl/engine.h>
4674 +# if OPENSSL_VERSION_NUMBER < 0x0090704fL
4675 +# define BROKEN_OPENSSL_ENGINE
4680 +#if OPENSSL_VERSION_NUMBER < 0x00907000L
4681 +#if !defined(RSA_PKCS1_PADDING_SIZE)
4682 +#define RSA_PKCS1_PADDING_SIZE 11
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)
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
4696 +#define PKCS11H_SERIALIZE_INVALID_CHARS "\\/\"'%&#@!?$* <>{}[]()`|"
4698 +enum _pkcs11h_private_op_e {
4699 + _pkcs11h_private_op_sign=0,
4700 + _pkcs11h_private_op_sign_recover,
4701 + _pkcs11h_private_op_decrypt
4704 +/*===========================================
4708 +#define PKCS11H_MSG_LEVEL_TEST(flags) (((unsigned int)flags) <= s_pkcs11h_loglevel)
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)
4715 +# define PKCS11H_DEBUG(flags, ...)
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)
4722 +# define PKCS11H_DEBUG(flags, args...)
4725 +# define PKCS11H_LOG _pkcs11h_log
4726 +# define PKCS11H_DEBUG _pkcs11h_log
4729 +/*===========================================
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;
4740 +#if defined(USE_PKCS11H_OPENSSL)
4742 +#if OPENSSL_VERSION_NUMBER < 0x00908000L
4743 +typedef unsigned char *pkcs11_openssl_d2i_t;
4745 +typedef const unsigned char *pkcs11_openssl_d2i_t;
4750 +#if defined(ENABLE_PKCS11H_THREADING)
4752 +#define PKCS11H_COND_INFINITE 0xffffffff
4755 +#define PKCS11H_THREAD_NULL NULL
4756 +typedef HANDLE pkcs11h_cond_t;
4757 +typedef HANDLE pkcs11h_mutex_t;
4758 +typedef HANDLE pkcs11h_thread_t;
4760 +#define PKCS11H_THREAD_NULL 0l
4761 +typedef pthread_mutex_t pkcs11h_mutex_t;
4762 +typedef pthread_t pkcs11h_thread_t;
4765 + pthread_cond_t cond;
4766 + pthread_mutex_t mut;
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;
4776 +typedef void * (*pkcs11h_thread_start_t)(void *);
4779 + pkcs11h_thread_start_t start;
4781 +} __pkcs11h_thread_data_t;
4783 +#endif /* ENABLE_PKCS11H_THREADING */
4785 +struct pkcs11h_provider_s {
4786 + pkcs11h_provider_t next;
4788 + PKCS11H_BOOL enabled;
4789 + char reference[1024];
4790 + char manufacturerID[sizeof (((CK_TOKEN_INFO *)NULL)->manufacturerID)+1];
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;
4806 +#if defined(ENABLE_PKCS11H_SLOTEVENT)
4807 + pkcs11h_thread_t slotevent_thread;
4811 +struct pkcs11h_session_s {
4812 + pkcs11h_session_t next;
4814 + int reference_count;
4815 + PKCS11H_BOOL valid;
4817 + pkcs11h_provider_t provider;
4819 + pkcs11h_token_id_t token_id;
4821 + CK_SESSION_HANDLE session_handle;
4823 + PKCS11H_BOOL allow_protected_auth_supported;
4824 + int pin_cache_period;
4825 + time_t pin_expire_time;
4827 +#if defined(ENABLE_PKCS11H_ENUM)
4828 +#if defined(ENABLE_PKCS11H_CERTIFICATE)
4829 + pkcs11h_certificate_id_list_t cached_certs;
4830 + PKCS11H_BOOL touch;
4834 +#if defined(ENABLE_PKCS11H_THREADING)
4835 + pkcs11h_mutex_t mutex;
4839 +#if defined (ENABLE_PKCS11H_CERTIFICATE)
4841 +struct pkcs11h_certificate_s {
4843 + pkcs11h_certificate_id_t id;
4844 + int pin_cache_period;
4845 + PKCS11H_BOOL pin_cache_populated_to_session;
4847 + unsigned mask_sign_mode;
4849 + pkcs11h_session_t session;
4850 + CK_OBJECT_HANDLE key_handle;
4852 + PKCS11H_BOOL operation_active;
4854 +#if defined(ENABLE_PKCS11H_THREADING)
4855 + pkcs11h_mutex_t mutex;
4858 + unsigned mask_prompt;
4862 +#endif /* ENABLE_PKCS11H_CERTIFICATE */
4864 +struct pkcs11h_data_s {
4865 + PKCS11H_BOOL initialized;
4866 + int pin_cache_period;
4868 + pkcs11h_provider_t providers;
4869 + pkcs11h_session_t sessions;
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;
4882 + PKCS11H_BOOL allow_protected_auth;
4883 + unsigned max_retries;
4885 +#if defined(ENABLE_PKCS11H_THREADING)
4887 + pkcs11h_mutex_t global;
4888 + pkcs11h_mutex_t session;
4889 + pkcs11h_mutex_t cache;
4893 +#if defined(ENABLE_PKCS11H_SLOTEVENT)
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;
4904 +#if defined(ENABLE_PKCS11H_OPENSSL)
4905 +struct pkcs11h_openssl_session_s {
4906 + int reference_count;
4907 + PKCS11H_BOOL initialized;
4909 + RSA_METHOD smart_rsa;
4910 + int (*orig_finish)(RSA *rsa);
4911 + pkcs11h_certificate_t certificate;
4912 + pkcs11h_hook_openssl_cleanup_t cleanup_hook;
4916 +/*======================================================================*
4917 + * MEMORY INTERFACE
4918 + *======================================================================*/
4922 +_pkcs11h_mem_malloc (
4923 + OUT const void * * const p,
4928 +_pkcs11h_mem_free (
4929 + IN const void * * const p
4933 +_pkcs11h_mem_strdup (
4934 + OUT const char * * const dest,
4935 + IN const char * const src
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
4946 +#if defined(ENABLE_PKCS11H_THREADING)
4947 +/*======================================================================*
4948 + * THREADING INTERFACE
4949 + *======================================================================*/
4953 +_pkcs11h_threading_sleep (
4954 + IN const unsigned milli
4958 +_pkcs11h_threading_mutexInit (
4959 + OUT pkcs11h_mutex_t * const mutex
4963 +_pkcs11h_threading_mutexLock (
4964 + IN OUT pkcs11h_mutex_t *const mutex
4968 +_pkcs11h_threading_mutexRelease (
4969 + IN OUT pkcs11h_mutex_t *const mutex
4973 +_pkcs11h_threading_mutexFree (
4974 + IN OUT pkcs11h_mutex_t *const mutex
4976 +#if !defined(WIN32)
4979 +__pkcs1h_threading_mutexLockAll ();
4982 +__pkcs1h_threading_mutexReleaseAll ();
4986 +_pkcs11h_threading_condSignal (
4987 + IN OUT pkcs11h_cond_t *const cond
4991 +_pkcs11h_threading_condInit (
4992 + OUT pkcs11h_cond_t * const cond
4996 +_pkcs11h_threading_condWait (
4997 + IN OUT pkcs11h_cond_t *const cond,
4998 + IN const unsigned milli
5002 +_pkcs11h_threading_condFree (
5003 + IN OUT pkcs11h_cond_t *const cond
5007 +_pkcs11h_threading_threadStart (
5008 + OUT pkcs11h_thread_t * const thread,
5009 + IN pkcs11h_thread_start_t const start,
5014 +_pkcs11h_threading_threadJoin (
5015 + IN pkcs11h_thread_t * const thread
5017 +#endif /* ENABLE_PKCS11H_THREADING */
5019 +/*======================================================================*
5020 + * COMMON INTERNAL INTERFACE
5021 + *======================================================================*/
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 */
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
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
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
5054 +_pkcs11h_util_unescapeString (
5055 + IN OUT char * const target,
5056 + IN const char * const source,
5057 + IN size_t * const max
5062 + IN const unsigned flags,
5063 + IN const char * const format,
5067 + __attribute__ ((format (printf, 2, 3)))
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
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
5089 +_pkcs11h_session_freeObjectAttributes (
5090 + IN OUT const CK_ATTRIBUTE_PTR attrs,
5091 + IN const unsigned count
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
5104 +_pkcs11h_token_getTokenId (
5105 + IN const CK_TOKEN_INFO_PTR info,
5106 + OUT pkcs11h_token_id_t * const p_token_id
5110 +_pkcs11h_token_newTokenId (
5111 + OUT pkcs11h_token_id_t * const token_id
5115 +_pkcs11h_session_getSessionByTokenId (
5116 + IN const pkcs11h_token_id_t token_id,
5117 + OUT pkcs11h_session_t * const p_session
5121 +_pkcs11h_session_release (
5122 + IN const pkcs11h_session_t session
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
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
5143 +_pkcs11h_session_validate (
5144 + IN const pkcs11h_session_t session
5148 +_pkcs11h_session_touch (
5149 + IN const pkcs11h_session_t session
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
5162 +_pkcs11h_session_logout (
5163 + IN const pkcs11h_session_t session
5168 +_pkcs11h_hooks_default_log (
5169 + IN void * const global_data,
5170 + IN const unsigned flags,
5171 + IN const char * const format,
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
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
5195 +#if !defined(WIN32)
5196 +#if defined(ENABLE_PKCS11H_THREADING)
5199 +__pkcs11h_threading_atfork_prepare ();
5202 +__pkcs11h_threading_atfork_parent ();
5205 +__pkcs11h_threading_atfork_child ();
5209 +_pkcs11h_forkFixup ();
5212 +#if defined(ENABLE_PKCS11H_CERTIFICATE)
5213 +/*======================================================================*
5214 + * CERTIFICATE INTERFACE
5215 + *======================================================================*/
5219 +_pkcs11h_certificate_getExpiration (
5220 + IN const unsigned char * const certificate,
5221 + IN const size_t certificate_size
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
5233 +_pkcs11h_certificate_newCertificateId (
5234 + OUT pkcs11h_certificate_id_t * const certificate_id
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
5246 +_pkcs11h_certificate_loadCertificate (
5247 + IN const pkcs11h_certificate_t certificate
5251 +_pkcs11h_certificate_updateCertificateIdDescription (
5252 + IN OUT pkcs11h_certificate_id_t certificate_id
5256 +_pkcs11h_certificate_getKeyAttributes (
5257 + IN const pkcs11h_certificate_t certificate
5261 +_pkcs11h_certificate_validateSession (
5262 + IN const pkcs11h_certificate_t certificate
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
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
5282 +#endif /* ENABLE_PKCS11H_CERTIFICATE */
5284 +#if defined(ENABLE_PKCS11H_LOCATE)
5285 +/*======================================================================*
5286 + * LOCATE INTERFACE
5287 + *======================================================================*/
5291 +_pkcs11h_locate_getTokenIdBySlotId (
5292 + IN const char * const slot,
5293 + OUT pkcs11h_token_id_t * const p_token_id
5297 +_pkcs11h_locate_getTokenIdBySlotName (
5298 + IN const char * const name,
5299 + OUT pkcs11h_token_id_t * const p_token_id
5303 +_pkcs11h_locate_getTokenIdByLabel (
5304 + IN const char * const label,
5305 + OUT pkcs11h_token_id_t * const p_token_id
5308 +#if defined(ENABLE_PKCS11H_CERTIFICATE)
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
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
5325 +#endif /* ENABLE_PKCS11H_CERTIFICATE */
5326 +#endif /* ENABLE_PKCS11H_LOCATE */
5328 +#if defined(ENABLE_PKCS11H_ENUM)
5329 +/*======================================================================*
5331 + *======================================================================*/
5333 +#if defined(ENABLE_PKCS11H_CERTIFICATE)
5337 +_pkcs11h_certificate_enumSessionCertificates (
5338 + IN const pkcs11h_session_t session,
5339 + IN void * const user_data,
5340 + IN const unsigned mask_prompt
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
5350 +#endif /* ENABLE_PKCS11H_CERTIFICATE */
5352 +#endif /* ENABLE_PKCS11H_ENUM */
5354 +#if defined(ENABLE_PKCS11H_SLOTEVENT)
5355 +/*======================================================================*
5356 + * SLOTEVENT INTERFACE
5357 + *======================================================================*/
5361 +_pkcs11h_slotevent_checksum (
5362 + IN const unsigned char * const p,
5367 +_pkcs11h_slotevent_provider (
5372 +_pkcs11h_slotevent_manager (
5377 +_pkcs11h_slotevent_init ();
5380 +_pkcs11h_slotevent_notify ();
5383 +_pkcs11h_slotevent_terminate ();
5385 +#endif /* ENABLE_PKCS11H_SLOTEVENT */
5387 +#if defined(ENABLE_PKCS11H_OPENSSL)
5388 +/*======================================================================*
5389 + * OPENSSL INTERFACE
5390 + *======================================================================*/
5394 +_pkcs11h_openssl_finish (
5397 +#if OPENSSL_VERSION_NUMBER < 0x00907000L
5400 +_pkcs11h_openssl_dec (
5402 + IN unsigned char *from,
5403 + OUT unsigned char *to,
5409 +_pkcs11h_openssl_sign (
5411 + IN unsigned char *m,
5412 + IN unsigned int m_len,
5413 + OUT unsigned char *sigret,
5414 + OUT unsigned int *siglen,
5420 +_pkcs11h_openssl_dec (
5422 + IN const unsigned char *from,
5423 + OUT unsigned char *to,
5429 +_pkcs11h_openssl_sign (
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
5439 +pkcs11h_openssl_session_t
5440 +_pkcs11h_openssl_get_openssl_session (
5441 + IN OUT const RSA *rsa
5444 +pkcs11h_certificate_t
5445 +_pkcs11h_openssl_get_pkcs11h_certificate (
5446 + IN OUT const RSA *rsa
5448 +#endif /* ENABLE_PKCS11H_OPENSSL */
5450 +/*==========================================
5454 +#if defined(ENABLE_PKCS11H_THREADING)
5455 +#if !defined(WIN32)
5457 + pkcs11h_mutex_t mutex;
5458 + __pkcs11h_threading_mutex_entry_t head;
5459 +} __s_pkcs11h_threading_mutex_list = {
5460 + PTHREAD_MUTEX_INITIALIZER,
5466 +pkcs11h_data_t s_pkcs11h_data = NULL;
5467 +unsigned int s_pkcs11h_loglevel = PKCS11H_LOG_INFO;
5469 +/*======================================================================*
5470 + * PUBLIC INTERFACE
5471 + *======================================================================*/
5474 +pkcs11h_getMessage (
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";
5569 +pkcs11h_initialize () {
5571 +#if defined(ENABLE_PKCS11H_THREADING)
5572 + PKCS11H_BOOL mutex_locked = FALSE;
5574 + CK_RV rv = CKR_OK;
5577 + PKCS11H_LOG_DEBUG2,
5578 + "PKCS#11: pkcs11h_initialize entry"
5581 + pkcs11h_terminate ();
5583 + if (rv == CKR_OK) {
5584 + rv = _pkcs11h_mem_malloc ((void*)&s_pkcs11h_data, sizeof (struct pkcs11h_data_s));
5587 +#if defined(USE_PKCS11H_OPENSSL) || defined(ENABLE_PKCS11H_OPENSSL)
5588 + OpenSSL_add_all_digests ();
5590 +#if defined(USE_PKCS11H_GNUTLS)
5593 + gnutls_global_init () != GNUTLS_E_SUCCESS
5595 + rv = CKR_FUNCTION_FAILED;
5599 +#if defined(ENABLE_PKCS11H_THREADING)
5600 + if (rv == CKR_OK) {
5601 + rv = _pkcs11h_threading_mutexInit (&s_pkcs11h_data->mutexes.global);
5603 + if (rv == CKR_OK) {
5604 + rv = _pkcs11h_threading_mutexInit (&s_pkcs11h_data->mutexes.session);
5606 + if (rv == CKR_OK) {
5607 + rv = _pkcs11h_threading_mutexInit (&s_pkcs11h_data->mutexes.cache);
5609 +#if !defined(WIN32)
5613 + __pkcs11h_threading_atfork_prepare,
5614 + __pkcs11h_threading_atfork_parent,
5615 + __pkcs11h_threading_atfork_child
5618 + rv = CKR_FUNCTION_FAILED;
5623 + (rv = _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.global)) == CKR_OK
5625 + mutex_locked = TRUE;
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;
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);
5642 +#if defined(ENABLE_PKCS11H_THREADING)
5643 + if (mutex_locked) {
5644 + _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.global);
5645 + mutex_locked = FALSE;
5650 + PKCS11H_LOG_DEBUG2,
5651 + "PKCS#11: pkcs11h_initialize return rv=%ld-'%s'",
5653 + pkcs11h_getMessage (rv)
5660 +pkcs11h_terminate () {
5663 + PKCS11H_LOG_DEBUG2,
5664 + "PKCS#11: pkcs11h_terminate entry"
5667 + if (s_pkcs11h_data != NULL) {
5668 + pkcs11h_provider_t current_provider = NULL;
5671 + PKCS11H_LOG_DEBUG1,
5672 + "PKCS#11: Removing providers"
5676 + current_provider = s_pkcs11h_data->providers;
5677 + current_provider != NULL;
5678 + current_provider = current_provider->next
5680 + pkcs11h_removeProvider (current_provider->reference);
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);
5690 + PKCS11H_LOG_DEBUG1,
5691 + "PKCS#11: Releasing sessions"
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;
5698 +#if defined(ENABLE_PKCS11H_THREADING)
5699 + _pkcs11h_threading_mutexLock (¤t->mutex);
5702 + current->valid = FALSE;
5704 + if (current->reference_count != 0) {
5706 + PKCS11H_LOG_DEBUG1,
5707 + "PKCS#11: Warning: Found session with references"
5711 + if (current->token_id != NULL) {
5712 + pkcs11h_token_freeTokenId (current->token_id);
5713 + current->token_id = NULL;
5716 +#if defined(ENABLE_PKCS11H_ENUM)
5717 +#if defined(ENABLE_PKCS11H_CERTIFICATE)
5718 + pkcs11h_certificate_freeCertificateIdList (current->cached_certs);
5722 + current->provider = NULL;
5724 +#if defined(ENABLE_PKCS11H_THREADING)
5725 + _pkcs11h_threading_mutexFree (¤t->mutex);
5728 + _pkcs11h_mem_free ((void *)¤t);
5731 +#if defined(ENABLE_PKCS11H_SLOTEVENT)
5733 + PKCS11H_LOG_DEBUG1,
5734 + "PKCS#11: Terminating slotevent"
5737 + _pkcs11h_slotevent_terminate ();
5740 + PKCS11H_LOG_DEBUG1,
5741 + "PKCS#11: Marking as uninitialized"
5744 + s_pkcs11h_data->initialized = FALSE;
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;
5750 + _pkcs11h_mem_free ((void *)¤t);
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);
5759 +#if defined(USE_PKCS11H_GNUTLS)
5760 + gnutls_global_deinit ();
5763 + _pkcs11h_mem_free ((void *)&s_pkcs11h_data);
5767 + PKCS11H_LOG_DEBUG2,
5768 + "PKCS#11: pkcs11h_terminate return"
5775 +pkcs11h_setLogLevel (
5776 + IN const unsigned flags
5778 + s_pkcs11h_loglevel = flags;
5782 +pkcs11h_getLogLevel () {
5783 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
5784 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
5786 + return s_pkcs11h_loglevel;
5790 +pkcs11h_setLogHook (
5791 + IN const pkcs11h_hook_log_t hook,
5792 + IN void * const global_data
5794 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
5795 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
5796 + PKCS11H_ASSERT (hook!=NULL);
5798 + s_pkcs11h_data->hooks.log = hook;
5799 + s_pkcs11h_data->hooks.log_data = global_data;
5805 +pkcs11h_setSlotEventHook (
5806 + IN const pkcs11h_hook_slotevent_t hook,
5807 + IN void * const global_data
5809 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
5810 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
5811 + PKCS11H_ASSERT (hook!=NULL);
5813 +#if defined(ENABLE_PKCS11H_SLOTEVENT)
5814 + s_pkcs11h_data->hooks.slotevent = hook;
5815 + s_pkcs11h_data->hooks.slotevent_data = global_data;
5817 + return _pkcs11h_slotevent_init ();
5819 + (void)global_data;
5821 + return CKR_FUNCTION_NOT_SUPPORTED;
5826 +pkcs11h_setPINPromptHook (
5827 + IN const pkcs11h_hook_pin_prompt_t hook,
5828 + IN void * const global_data
5830 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
5831 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
5832 + PKCS11H_ASSERT (hook!=NULL);
5834 + s_pkcs11h_data->hooks.pin_prompt = hook;
5835 + s_pkcs11h_data->hooks.pin_prompt_data = global_data;
5841 +pkcs11h_setTokenPromptHook (
5842 + IN const pkcs11h_hook_token_prompt_t hook,
5843 + IN void * const global_data
5845 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
5846 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
5847 + PKCS11H_ASSERT (hook!=NULL);
5849 + s_pkcs11h_data->hooks.token_prompt = hook;
5850 + s_pkcs11h_data->hooks.token_prompt_data = global_data;
5856 +pkcs11h_setPINCachePeriod (
5857 + IN const int pin_cache_period
5859 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
5860 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
5862 + s_pkcs11h_data->pin_cache_period = pin_cache_period;
5868 +pkcs11h_setMaxLoginRetries (
5869 + IN const unsigned max_retries
5871 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
5872 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
5874 + s_pkcs11h_data->max_retries = max_retries;
5880 +pkcs11h_setProtectedAuthentication (
5881 + IN const PKCS11H_BOOL allow_protected_auth
5883 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
5884 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
5886 + s_pkcs11h_data->allow_protected_auth = allow_protected_auth;
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
5901 +#if defined(ENABLE_PKCS11H_THREADING)
5902 + PKCS11H_BOOL mutex_locked = FALSE;
5907 + pid_t mypid = getpid ();
5909 + pkcs11h_provider_t provider = NULL;
5910 + CK_C_GetFunctionList gfl = NULL;
5912 + CK_RV rv = CKR_OK;
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*/
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",
5924 + provider_location,
5925 + allow_protected_auth ? 1 : 0,
5927 + cert_is_private ? 1 : 0
5931 + PKCS11H_LOG_DEBUG1,
5932 + "PKCS#11: Adding provider '%s'-'%s'",
5937 +#if defined(ENABLE_PKCS11H_THREADING)
5940 + (rv = _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.global)) == CKR_OK
5942 + mutex_locked = TRUE;
5948 + (rv = _pkcs11h_mem_malloc ((void *)&provider, sizeof (struct pkcs11h_provider_s))) == CKR_OK
5951 + provider->reference,
5953 + sizeof (provider->reference)-1
5955 + provider->reference[sizeof (provider->reference)-1] = '\x0';
5957 + provider->manufacturerID,
5959 + strlen (provider_location) < sizeof (provider->manufacturerID) ?
5960 + provider_location :
5961 + provider_location+strlen (provider_location)-sizeof (provider->manufacturerID)+1
5963 + sizeof (provider->manufacturerID)-1
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;
5973 + if (rv == CKR_OK) {
5975 + provider->handle = LoadLibraryA (provider_location);
5977 + provider->handle = dlopen (provider_location, RTLD_NOW);
5979 + if (provider->handle == NULL) {
5980 + rv = CKR_FUNCTION_FAILED;
5984 + if (rv == CKR_OK) {
5986 + gfl = (CK_C_GetFunctionList)GetProcAddress (
5988 + "C_GetFunctionList"
5992 + * Make compiler happy!
5996 + "C_GetFunctionList"
6004 + if (gfl == NULL) {
6005 + rv = CKR_FUNCTION_FAILED;
6009 + if (rv == CKR_OK) {
6010 + rv = gfl (&provider->f);
6013 + if (rv == CKR_OK) {
6014 + if ((rv = provider->f->C_Initialize (NULL)) != CKR_OK) {
6015 + if (rv == CKR_CRYPTOKI_ALREADY_INITIALIZED) {
6020 + provider->should_finalize = TRUE;
6026 + (rv = provider->f->C_GetInfo (&info)) == CKR_OK
6028 + _pkcs11h_util_fixupFixedString (
6029 + provider->manufacturerID,
6030 + (char *)info.manufacturerID,
6031 + sizeof (info.manufacturerID)
6035 + if (rv == CKR_OK) {
6036 + provider->enabled = TRUE;
6039 + if (provider != NULL) {
6040 + if (s_pkcs11h_data->providers == NULL) {
6041 + s_pkcs11h_data->providers = provider;
6044 + pkcs11h_provider_t last = NULL;
6047 + last = s_pkcs11h_data->providers;
6048 + last->next != NULL;
6051 + last->next = provider;
6055 +#if defined(ENABLE_PKCS11H_THREADING)
6056 + if (mutex_locked) {
6057 + _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.global);
6058 + mutex_locked = FALSE;
6062 +#if defined(ENABLE_PKCS11H_SLOTEVENT)
6063 + _pkcs11h_slotevent_notify ();
6067 + PKCS11H_LOG_DEBUG1,
6068 + "PKCS#11: Provider '%s' added rv=%ld-'%s'",
6071 + pkcs11h_getMessage (rv)
6075 + PKCS11H_LOG_DEBUG2,
6076 + "PKCS#11: pkcs11h_addProvider return rv=%ld-'%s'",
6078 + pkcs11h_getMessage (rv)
6085 +pkcs11h_removeProvider (
6086 + IN const char * const reference
6088 +#if defined(ENABLE_PKCS11H_THREADING)
6089 + pkcs11h_session_t current_session = NULL;
6091 + pkcs11h_provider_t provider = NULL;
6092 + CK_RV rv = CKR_OK;
6094 + PKCS11H_ASSERT (reference!=NULL);
6097 + PKCS11H_LOG_DEBUG2,
6098 + "PKCS#11: pkcs11h_removeProvider entry reference='%s'",
6103 + PKCS11H_LOG_DEBUG1,
6104 + "PKCS#11: Removing provider '%s'",
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);
6114 + current_session = s_pkcs11h_data->sessions;
6115 + current_session != NULL;
6116 + current_session = current_session->next
6118 + _pkcs11h_threading_mutexLock (¤t_session->mutex);
6122 + provider = s_pkcs11h_data->providers;
6125 + provider != NULL &&
6126 + strcmp (reference, provider->reference)
6128 + provider = provider->next;
6131 + if (rv == CKR_OK && provider == NULL) {
6132 + rv = CKR_OBJECT_HANDLE_INVALID;
6135 + if (rv == CKR_OK) {
6136 + provider->enabled = FALSE;
6137 + provider->reference[0] = '\0';
6139 + if (provider->should_finalize) {
6140 + provider->f->C_Finalize (NULL);
6141 + provider->should_finalize = FALSE;
6144 +#if defined(ENABLE_PKCS11H_SLOTEVENT)
6145 + _pkcs11h_slotevent_notify ();
6148 + * Wait until manager join this thread
6149 + * this happens saldom so I can poll
6151 + while (provider->slotevent_thread != PKCS11H_THREAD_NULL) {
6152 + _pkcs11h_threading_sleep (500);
6156 + if (provider->f != NULL) {
6157 + provider->f = NULL;
6160 + if (provider->handle != NULL) {
6162 + FreeLibrary (provider->handle);
6164 + dlclose (provider->handle);
6166 + provider->handle = NULL;
6170 +#if defined(ENABLE_PKCS11H_THREADING)
6172 + current_session = s_pkcs11h_data->sessions;
6173 + current_session != NULL;
6174 + current_session = current_session->next
6176 + _pkcs11h_threading_mutexRelease (¤t_session->mutex);
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);
6185 + PKCS11H_LOG_DEBUG2,
6186 + "PKCS#11: pkcs11h_removeProvider return rv=%ld-'%s'",
6188 + pkcs11h_getMessage (rv)
6195 +pkcs11h_forkFixup () {
6199 +#if defined(ENABLE_PKCS11H_THREADING)
6202 + return _pkcs11h_forkFixup ();
6208 +pkcs11h_plugAndPlay () {
6212 + pid_t mypid = getpid ();
6216 + PKCS11H_LOG_DEBUG2,
6217 + "PKCS#11: pkcs11h_forkFixup entry pid=%d",
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;
6227 +#if defined(ENABLE_PKCS11H_THREADING)
6228 + _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.global);
6231 + current = s_pkcs11h_data->providers;
6233 + current = current->next
6235 + if (current->enabled) {
6236 + current->f->C_Finalize (NULL);
6240 +#if defined(ENABLE_PKCS11H_SLOTEVENT)
6241 + if (s_pkcs11h_data->slotevent.initialized) {
6242 + slot_event_active = TRUE;
6243 + _pkcs11h_slotevent_terminate ();
6248 + current = s_pkcs11h_data->providers;
6250 + current = current->next
6252 + if (current->enabled) {
6253 + current->f->C_Initialize (NULL);
6257 +#if defined(ENABLE_PKCS11H_SLOTEVENT)
6258 + if (slot_event_active) {
6259 + _pkcs11h_slotevent_init ();
6263 +#if defined(ENABLE_PKCS11H_THREADING)
6264 + _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.global);
6269 + PKCS11H_LOG_DEBUG2,
6270 + "PKCS#11: pkcs11h_forkFixup return"
6277 +pkcs11h_token_freeTokenId (
6278 + IN pkcs11h_token_id_t token_id
6280 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
6281 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
6282 + PKCS11H_ASSERT (token_id!=NULL);
6285 + PKCS11H_LOG_DEBUG2,
6286 + "PKCS#11: pkcs11h_token_freeTokenId entry certificate_id=%p",
6290 + _pkcs11h_mem_free ((void *)&token_id);
6293 + PKCS11H_LOG_DEBUG2,
6294 + "PKCS#11: pkcs11h_token_freeTokenId return"
6301 +pkcs11h_token_duplicateTokenId (
6302 + OUT pkcs11h_token_id_t * const to,
6303 + IN const pkcs11h_token_id_t from
6305 + CK_RV rv = CKR_OK;
6307 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
6308 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
6309 + PKCS11H_ASSERT (to!=NULL);
6310 + PKCS11H_ASSERT (from!=NULL);
6313 + PKCS11H_LOG_DEBUG2,
6314 + "PKCS#11: pkcs11h_token_duplicateTokenId entry to=%p form=%p",
6321 + if (rv == CKR_OK) {
6322 + rv = _pkcs11h_mem_duplicate (
6326 + sizeof (struct pkcs11h_token_id_s)
6331 + PKCS11H_LOG_DEBUG2,
6332 + "PKCS#11: pkcs11h_token_duplicateTokenId return rv=%ld-'%s', *to=%p",
6334 + pkcs11h_getMessage (rv),
6342 +pkcs11h_token_sameTokenId (
6343 + IN const pkcs11h_token_id_t a,
6344 + IN const pkcs11h_token_id_t b
6346 + PKCS11H_ASSERT (a!=NULL);
6347 + PKCS11H_ASSERT (b!=NULL);
6350 + !strcmp (a->manufacturerID, b->manufacturerID) &&
6351 + !strcmp (a->model, b->model) &&
6352 + !strcmp (a->serialNumber, b->serialNumber) &&
6353 + !strcmp (a->label, b->label)
6357 +#if defined(ENABLE_PKCS11H_SERIALIZATION)
6360 +pkcs11h_token_serializeTokenId (
6361 + OUT char * const sz,
6362 + IN OUT size_t *max,
6363 + IN const pkcs11h_token_id_t token_id
6365 + const char *sources[5];
6366 + CK_RV rv = CKR_OK;
6370 + /*PKCS11H_ASSERT (sz!=NULL); Not required*/
6371 + PKCS11H_ASSERT (max!=NULL);
6372 + PKCS11H_ASSERT (token_id!=NULL);
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;
6383 + PKCS11H_LOG_DEBUG2,
6384 + "PKCS#11: pkcs11h_token_serializeTokenId entry sz=%p, *max=%u, token_id=%p",
6386 + sz != NULL ? *max : 0,
6391 + for (e=0;rv == CKR_OK && sources[e] != NULL;e++) {
6393 + rv = _pkcs11h_util_escapeString (NULL, sources[e], &t, PKCS11H_SERIALIZE_INVALID_CHARS);
6399 + rv = CKR_ATTRIBUTE_VALUE_INVALID;
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);
6416 + PKCS11H_LOG_DEBUG2,
6417 + "PKCS#11: pkcs11h_token_serializeTokenId return rv=%ld-'%s', *max=%u, sz='%s'",
6419 + pkcs11h_getMessage (rv),
6428 +pkcs11h_token_deserializeTokenId (
6429 + OUT pkcs11h_token_id_t *p_token_id,
6430 + IN const char * const sz
6432 +#define __PKCS11H_TARGETS_NUMBER 4
6436 + } targets[__PKCS11H_TARGETS_NUMBER];
6438 + pkcs11h_token_id_t token_id = NULL;
6442 + CK_RV rv = CKR_OK;
6444 + PKCS11H_ASSERT (p_token_id!=NULL);
6445 + PKCS11H_ASSERT (sz!=NULL);
6448 + PKCS11H_LOG_DEBUG2,
6449 + "PKCS#11: pkcs11h_token_deserializeTokenId entry p_token_id=%p, sz='%s'",
6450 + (void *)p_token_id,
6454 + *p_token_id = NULL;
6456 + if (rv == CKR_OK) {
6457 + rv = _pkcs11h_mem_strdup (
6463 + if (rv == CKR_OK) {
6469 + (rv = _pkcs11h_token_newTokenId (&token_id)) == CKR_OK
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);
6481 + for (e=0;rv == CKR_OK && e < __PKCS11H_TARGETS_NUMBER;e++) {
6486 + * Don't search for last
6489 + if (rv == CKR_OK) {
6490 + if (e != __PKCS11H_TARGETS_NUMBER-1) {
6491 + p2 = strchr (p1, '/');
6493 + rv = CKR_ATTRIBUTE_VALUE_INVALID;
6501 + if (rv == CKR_OK) {
6502 + _pkcs11h_util_unescapeString (
6509 + if (rv == CKR_OK) {
6510 + if (l > targets[e].s) {
6511 + rv = CKR_ATTRIBUTE_VALUE_INVALID;
6515 + if (rv == CKR_OK) {
6517 + _pkcs11h_util_unescapeString (
6524 + if (rv == CKR_OK) {
6529 + if (rv == CKR_OK) {
6531 + token_id->display,
6533 + sizeof (token_id->display)
6537 + if (rv == CKR_OK) {
6538 + *p_token_id = token_id;
6542 + if (_sz != NULL) {
6543 + _pkcs11h_mem_free ((void *)&_sz);
6546 + if (token_id != NULL) {
6547 + pkcs11h_token_freeTokenId (token_id);
6551 +#undef __PKCS11H_TARGETS_NUMBER
6554 +#endif /* ENABLE_PKCS11H_SERIALIZATION */
6556 +/*======================================================================*
6557 + * MEMORY INTERFACE
6558 + *======================================================================*/
6562 +_pkcs11h_mem_malloc (
6563 + OUT const void * * const p,
6566 + CK_RV rv = CKR_OK;
6568 + PKCS11H_ASSERT (p!=NULL);
6569 + PKCS11H_ASSERT (s!=0);
6575 + (*p = (void *)PKCS11H_MALLOC (s)) == NULL
6577 + rv = CKR_HOST_MEMORY;
6580 + memset ((void *)*p, 0, s);
6589 +_pkcs11h_mem_free (
6590 + IN const void * * const p
6592 + PKCS11H_ASSERT (p!=NULL);
6594 + PKCS11H_FREE ((void *)*p);
6602 +_pkcs11h_mem_strdup (
6603 + OUT const char * * const dest,
6604 + IN const char * const src
6606 + return _pkcs11h_mem_duplicate (
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
6622 + CK_RV rv = CKR_OK;
6624 + PKCS11H_ASSERT (dest!=NULL);
6625 + /*PKCS11H_ASSERT (dest_size!=NULL); NOT NEEDED*/
6626 + PKCS11H_ASSERT (!(mem_size!=0&&src==NULL));
6629 + if (p_dest_size != NULL) {
6633 + if (src != NULL) {
6636 + (rv = _pkcs11h_mem_malloc (dest, mem_size)) == CKR_OK
6638 + if (p_dest_size != NULL) {
6639 + *p_dest_size = mem_size;
6641 + memmove ((void*)*dest, src, mem_size);
6648 +#if defined(ENABLE_PKCS11H_THREADING)
6649 +/*======================================================================*
6650 + * THREADING INTERFACE
6651 + *======================================================================*/
6655 +_pkcs11h_threading_sleep (
6656 + IN const unsigned milli
6661 + usleep (milli*1000);
6667 +_pkcs11h_threading_mutexInit (
6668 + OUT pkcs11h_mutex_t * const mutex
6670 + CK_RV rv = CKR_OK;
6674 + (*mutex = CreateMutex (NULL, FALSE, NULL)) == NULL
6676 + rv = CKR_FUNCTION_FAILED;
6680 + __pkcs11h_threading_mutex_entry_t entry = NULL;
6681 + PKCS11H_BOOL mutex_locked = FALSE;
6685 + (rv = _pkcs11h_threading_mutexLock (&__s_pkcs11h_threading_mutex_list.mutex)) == CKR_OK
6687 + mutex_locked = TRUE;
6690 + if (rv == CKR_OK) {
6691 + rv = _pkcs11h_mem_malloc (
6693 + sizeof (struct __pkcs11h_threading_mutex_entry_s)
6699 + pthread_mutex_init (mutex, NULL)
6701 + rv = CKR_FUNCTION_FAILED;
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;
6711 + if (entry != NULL) {
6712 + _pkcs11h_mem_free ((void *)&entry);
6715 + if (mutex_locked) {
6716 + _pkcs11h_threading_mutexRelease (&__s_pkcs11h_threading_mutex_list.mutex);
6717 + mutex_locked = FALSE;
6726 +_pkcs11h_threading_mutexLock (
6727 + IN OUT pkcs11h_mutex_t *const mutex
6729 + CK_RV rv = CKR_OK;
6733 + WaitForSingleObject (*mutex, INFINITE) == WAIT_FAILED
6735 + rv = CKR_FUNCTION_FAILED;
6740 + pthread_mutex_lock (mutex)
6742 + rv = CKR_FUNCTION_FAILED;
6750 +_pkcs11h_threading_mutexRelease (
6751 + IN OUT pkcs11h_mutex_t *const mutex
6753 + CK_RV rv = CKR_OK;
6757 + !ReleaseMutex (*mutex)
6759 + rv = CKR_FUNCTION_FAILED;
6764 + pthread_mutex_unlock (mutex)
6766 + rv = CKR_FUNCTION_FAILED;
6774 +_pkcs11h_threading_mutexFree (
6775 + IN OUT pkcs11h_mutex_t *const mutex
6778 + if (*mutex != NULL) {
6779 + CloseHandle (*mutex);
6784 + __pkcs11h_threading_mutex_entry_t last = NULL;
6785 + __pkcs11h_threading_mutex_entry_t entry = NULL;
6786 + PKCS11H_BOOL mutex_locked = FALSE;
6788 + if (_pkcs11h_threading_mutexLock (&__s_pkcs11h_threading_mutex_list.mutex) == CKR_OK) {
6789 + mutex_locked = TRUE;
6792 + entry = __s_pkcs11h_threading_mutex_list.head;
6795 + entry->p_mutex != mutex
6798 + entry = entry->next;
6801 + if (entry != NULL) {
6802 + if (last == NULL) {
6803 + __s_pkcs11h_threading_mutex_list.head = entry->next;
6806 + last->next = entry->next;
6808 + _pkcs11h_mem_free ((void *)&entry);
6811 + pthread_mutex_destroy (mutex);
6813 + if (mutex_locked) {
6814 + _pkcs11h_threading_mutexRelease (&__s_pkcs11h_threading_mutex_list.mutex);
6815 + mutex_locked = FALSE;
6822 +#if !defined(WIN32)
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...
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;
6837 + if (_pkcs11h_threading_mutexLock (&__s_pkcs11h_threading_mutex_list.mutex) == CKR_OK) {
6838 + mutex_locked = TRUE;
6842 + entry = __s_pkcs11h_threading_mutex_list.head;
6844 + entry = entry->next
6846 + entry->locked = FALSE;
6849 + while (!all_mutexes_locked) {
6850 + PKCS11H_BOOL ok = TRUE;
6853 + entry = __s_pkcs11h_threading_mutex_list.head;
6854 + entry != NULL && ok;
6855 + entry = entry->next
6857 + if (!pthread_mutex_trylock (entry->p_mutex)) {
6858 + entry->locked = TRUE;
6867 + entry = __s_pkcs11h_threading_mutex_list.head;
6869 + entry = entry->next
6871 + if (entry->locked == TRUE) {
6872 + pthread_mutex_unlock (entry->p_mutex);
6873 + entry->locked = FALSE;
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);
6882 + all_mutexes_locked = TRUE;
6886 + if (mutex_locked) {
6887 + _pkcs11h_threading_mutexRelease (&__s_pkcs11h_threading_mutex_list.mutex);
6888 + mutex_locked = FALSE;
6894 +__pkcs1h_threading_mutexReleaseAll () {
6895 + __pkcs11h_threading_mutex_entry_t entry = NULL;
6896 + PKCS11H_BOOL mutex_locked = FALSE;
6898 + if (_pkcs11h_threading_mutexLock (&__s_pkcs11h_threading_mutex_list.mutex) == CKR_OK) {
6899 + mutex_locked = TRUE;
6903 + entry = __s_pkcs11h_threading_mutex_list.head;
6905 + entry = entry->next
6907 + pthread_mutex_unlock (entry->p_mutex);
6908 + entry->locked = FALSE;
6911 + if (mutex_locked) {
6912 + _pkcs11h_threading_mutexRelease (&__s_pkcs11h_threading_mutex_list.mutex);
6913 + mutex_locked = FALSE;
6919 +_pkcs11h_threading_condSignal (
6920 + IN OUT pkcs11h_cond_t *const cond
6922 + CK_RV rv = CKR_OK;
6928 + rv = CKR_FUNCTION_FAILED;
6934 + pthread_mutex_lock (&cond->mut) ||
6935 + pthread_cond_signal (&cond->cond) ||
6936 + pthread_mutex_unlock (&cond->mut)
6939 + rv = CKR_FUNCTION_FAILED;
6948 +_pkcs11h_threading_condInit (
6949 + OUT pkcs11h_cond_t * const cond
6951 + CK_RV rv = CKR_OK;
6955 + (*cond = CreateEvent (NULL, FALSE, FALSE, NULL)) == NULL
6957 + rv = CKR_FUNCTION_FAILED;
6963 + pthread_mutex_init (&cond->mut, NULL) ||
6964 + pthread_cond_init (&cond->cond, NULL) ||
6965 + pthread_mutex_lock (&cond->mut)
6968 + rv = CKR_FUNCTION_FAILED;
6976 +_pkcs11h_threading_condWait (
6977 + IN OUT pkcs11h_cond_t *const cond,
6978 + IN const unsigned milli
6980 + CK_RV rv = CKR_OK;
6985 + if (milli == PKCS11H_COND_INFINITE) {
6986 + dwMilli = INFINITE;
6994 + WaitForSingleObject (*cond, dwMilli) == WAIT_FAILED
6996 + rv = CKR_FUNCTION_FAILED;
6999 + if (milli == PKCS11H_COND_INFINITE) {
7002 + pthread_cond_wait (&cond->cond, &cond->mut)
7004 + rv = CKR_FUNCTION_FAILED;
7008 + struct timeval now;
7009 + struct timespec timeout;
7013 + gettimeofday (&now, NULL)
7015 + rv = CKR_FUNCTION_FAILED;
7018 + if (rv == CKR_OK) {
7019 + timeout.tv_sec = now.tv_sec + milli/1000;
7020 + timeout.tv_nsec = now.tv_usec*1000 + milli%1000;
7025 + pthread_cond_timedwait (&cond->cond, &cond->mut, &timeout)
7027 + rv = CKR_FUNCTION_FAILED;
7036 +_pkcs11h_threading_condFree (
7037 + IN OUT pkcs11h_cond_t *const cond
7040 + CloseHandle (*cond);
7043 + pthread_mutex_unlock (&cond->mut);
7052 +__pkcs11h_thread_start (void *p) {
7053 + __pkcs11h_thread_data_t *_data = (__pkcs11h_thread_data_t *)p;
7056 + ret = (unsigned)_data->start (_data->data);
7058 + _pkcs11h_mem_free ((void *)&_data);
7065 +__pkcs11h_thread_start (void *p) {
7066 + __pkcs11h_thread_data_t *_data = (__pkcs11h_thread_data_t *)p;
7071 + * Ignore any signal in
7074 + for (i=1;i<16;i++) {
7075 + signal (i, SIG_IGN);
7078 + ret = _data->start (_data->data);
7080 + _pkcs11h_mem_free ((void *)&_data);
7088 +_pkcs11h_threading_threadStart (
7089 + OUT pkcs11h_thread_t * const thread,
7090 + IN pkcs11h_thread_start_t const start,
7093 + __pkcs11h_thread_data_t *_data = NULL;
7094 + CK_RV rv = CKR_OK;
7096 + if (rv == CKR_OK) {
7097 + rv = _pkcs11h_mem_malloc (
7099 + sizeof (__pkcs11h_thread_data_t)
7103 + if (rv == CKR_OK) {
7104 + _data->start = start;
7105 + _data->data = data;
7114 + (*thread = (HANDLE)_beginthreadex (
7117 + __pkcs11h_thread_start,
7123 + rv = CKR_FUNCTION_FAILED;
7129 + pthread_create (thread, NULL, __pkcs11h_thread_start, _data)
7131 + rv = CKR_FUNCTION_FAILED;
7139 +_pkcs11h_threading_threadJoin (
7140 + IN pkcs11h_thread_t * const thread
7143 + WaitForSingleObject (*thread, INFINITE);
7144 + CloseHandle (*thread);
7147 + pthread_join (*thread, NULL);
7153 +#endif /* ENABLE_PKCS11H_THREADING */
7155 +/*======================================================================*
7156 + * COMMON INTERNAL INTERFACE
7157 + *======================================================================*/
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 */
7168 + PKCS11H_ASSERT (source!=NULL);
7169 + PKCS11H_ASSERT (target!=NULL);
7171 + p = target+length;
7172 + memmove (target, source, length);
7175 + while (p >= target && *p == ' ') {
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
7188 + size_t target_max_size;
7190 + char buf[3] = {'\0', '\0', '\0'};
7193 + PKCS11H_ASSERT (source!=NULL);
7194 + PKCS11H_ASSERT (target!=NULL);
7195 + PKCS11H_ASSERT (p_target_size!=NULL);
7197 + target_max_size = *p_target_size;
7199 + *p_target_size = 0;
7201 + while (*p != '\x0' && *p_target_size < target_max_size) {
7202 + if (isxdigit ((unsigned char)*p)) {
7207 + if (sscanf (buf, "%x", &v) != 1) {
7210 + target[*p_target_size] = v & 0xff;
7211 + (*p_target_size)++;
7219 + if (*p != '\x0') {
7220 + return CKR_ATTRIBUTE_VALUE_INVALID;
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
7235 + static const char *x = "0123456789ABCDEF";
7238 + PKCS11H_ASSERT (target!=NULL);
7239 + PKCS11H_ASSERT (source!=NULL);
7241 + if (target_size < source_size * 2 + 1) {
7242 + return CKR_ATTRIBUTE_VALUE_INVALID;
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];
7249 + target[source_size*2] = '\x0';
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
7261 + static const char *x = "0123456789ABCDEF";
7262 + CK_RV rv = CKR_OK;
7263 + const char *s = source;
7267 + /*PKCS11H_ASSERT (target!=NULL); Not required*/
7268 + PKCS11H_ASSERT (source!=NULL);
7269 + PKCS11H_ASSERT (max!=NULL);
7271 + while (rv == CKR_OK && *s != '\x0') {
7273 + if (*s == '\\' || strchr (invalid_chars, *s) || !isgraph (*s)) {
7276 + rv = CKR_ATTRIBUTE_VALUE_INVALID;
7281 + t[2] = x[(*s&0xf0)>>4];
7282 + t[3] = x[(*s&0x0f)>>0];
7291 + rv = CKR_ATTRIBUTE_VALUE_INVALID;
7306 + rv = CKR_ATTRIBUTE_VALUE_INVALID;
7322 +_pkcs11h_util_unescapeString (
7323 + IN OUT char * const target,
7324 + IN const char * const source,
7325 + IN size_t * const max
7327 + CK_RV rv = CKR_OK;
7328 + const char *s = source;
7332 + /*PKCS11H_ASSERT (target!=NULL); Not required*/
7333 + PKCS11H_ASSERT (source!=NULL);
7334 + PKCS11H_ASSERT (max!=NULL);
7336 + while (rv == CKR_OK && *s != '\x0') {
7340 + rv = CKR_ATTRIBUTE_VALUE_INVALID;
7348 + sscanf (b, "%08x", &u);
7358 + rv = CKR_ATTRIBUTE_VALUE_INVALID;
7373 + rv = CKR_ATTRIBUTE_VALUE_INVALID;
7390 + IN const unsigned flags,
7391 + IN const char * const format,
7396 + PKCS11H_ASSERT (format!=NULL);
7398 + va_start (args, format);
7401 + s_pkcs11h_data != NULL &&
7402 + s_pkcs11h_data->initialized
7404 + if (PKCS11H_MSG_LEVEL_TEST (flags)) {
7405 + if (s_pkcs11h_data->hooks.log == NULL) {
7406 + _pkcs11h_hooks_default_log (
7414 + s_pkcs11h_data->hooks.log (
7415 + s_pkcs11h_data->hooks.log_data,
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
7435 + CK_SLOT_ID_PTR _slots = NULL;
7436 + CK_ULONG _slotnum = 0;
7437 + CK_RV rv = CKR_OK;
7439 + PKCS11H_ASSERT (provider!=NULL);
7440 + PKCS11H_ASSERT (pSlotList!=NULL);
7441 + PKCS11H_ASSERT (pulCount!=NULL);
7444 + PKCS11H_LOG_DEBUG2,
7445 + "PKCS#11: _pkcs11h_session_getSlotList entry provider=%p, token_present=%d, pSlotList=%p, pulCount=%p",
7448 + (void *)pSlotList,
7452 + *pSlotList = NULL;
7457 + !provider->enabled
7459 + rv = CKR_CRYPTOKI_NOT_INITIALIZED;
7462 + if (rv == CKR_OK) {
7463 + rv = provider->f->C_GetSlotList (
7470 + if (rv == CKR_OK && _slotnum > 0) {
7471 + rv = _pkcs11h_mem_malloc ((void *)&_slots, _slotnum * sizeof (CK_SLOT_ID));
7474 + if (rv == CKR_OK && _slotnum > 0) {
7475 + rv = provider->f->C_GetSlotList (
7482 + if (rv == CKR_OK) {
7483 + *pSlotList = _slots;
7485 + *pulCount = _slotnum;
7488 + if (_slots != NULL) {
7489 + _pkcs11h_mem_free ((void *)&_slots);
7493 + PKCS11H_LOG_DEBUG2,
7494 + "PKCS#11: _pkcs11h_session_getSlotList return rv=%ld-'%s' *pulCount=%ld",
7496 + pkcs11h_getMessage (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
7513 + * session->mutex must be locked
7515 + CK_RV rv = CKR_OK;
7517 + PKCS11H_ASSERT (session!=NULL);
7518 + PKCS11H_ASSERT (attrs!=NULL);
7521 + PKCS11H_LOG_DEBUG2,
7522 + "PKCS#11: _pkcs11h_session_getObjectAttributes entry session=%p, object=%ld, attrs=%p, count=%u",
7531 + (rv = session->provider->f->C_GetAttributeValue (
7532 + session->session_handle,
7539 + for (i=0;rv == CKR_OK && i<count;i++) {
7540 + if (attrs[i].ulValueLen == (CK_ULONG)-1) {
7541 + rv = CKR_ATTRIBUTE_VALUE_INVALID;
7543 + else if (attrs[i].ulValueLen == 0) {
7544 + attrs[i].pValue = NULL;
7547 + rv = _pkcs11h_mem_malloc (
7548 + (void *)&attrs[i].pValue,
7549 + attrs[i].ulValueLen
7555 + if (rv == CKR_OK) {
7556 + rv = session->provider->f->C_GetAttributeValue (
7557 + session->session_handle,
7565 + PKCS11H_LOG_DEBUG2,
7566 + "PKCS#11: _pkcs11h_session_getObjectAttributes return rv=%ld-'%s'",
7568 + pkcs11h_getMessage (rv)
7576 +_pkcs11h_session_freeObjectAttributes (
7577 + IN OUT const CK_ATTRIBUTE_PTR attrs,
7578 + IN const unsigned count
7582 + CK_RV rv = CKR_OK;
7584 + PKCS11H_ASSERT (attrs!=NULL);
7587 + PKCS11H_LOG_DEBUG2,
7588 + "PKCS#11: _pkcs11h_session_freeObjectAttributes entry attrs=%p, count=%u",
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;
7601 + PKCS11H_LOG_DEBUG2,
7602 + "PKCS#11: _pkcs11h_session_freeObjectAttributes return rv=%ld-'%s'",
7604 + pkcs11h_getMessage (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
7621 + * session->mutex must be locked
7623 + PKCS11H_BOOL should_FindObjectsFinal = FALSE;
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;
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);
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",
7643 + (void *)p_objects,
7644 + (void *)p_objects_found
7647 + *p_objects = NULL;
7648 + *p_objects_found = 0;
7652 + (rv = session->provider->f->C_FindObjectsInit (
7653 + session->session_handle,
7654 + (CK_ATTRIBUTE *)filter,
7658 + should_FindObjectsFinal = TRUE;
7663 + (rv = session->provider->f->C_FindObjects (
7664 + session->session_handle,
7666 + sizeof (objects_buffer) / sizeof (CK_OBJECT_HANDLE),
7671 + CK_OBJECT_HANDLE *temp = NULL;
7674 + * Begin workaround
7676 + * Workaround iKey bug
7677 + * It returns the same objects over and over
7679 + if (oLast == objects_buffer[0]) {
7682 + "PKCS#11: Bad PKCS#11 C_FindObjects implementation detected, workaround applied"
7686 + oLast = objects_buffer[0];
7687 + /* End workaround */
7690 + (rv = _pkcs11h_mem_malloc (
7692 + (objects_size+objects_found) * sizeof (CK_OBJECT_HANDLE)
7695 + if (objects != NULL) {
7699 + objects_size * sizeof (CK_OBJECT_HANDLE)
7703 + temp + objects_size,
7705 + objects_found * sizeof (CK_OBJECT_HANDLE)
7709 + if (objects != NULL) {
7710 + _pkcs11h_mem_free ((void *)&objects);
7714 + if (rv == CKR_OK) {
7716 + objects_size += objects_found;
7720 + if (temp != NULL) {
7721 + _pkcs11h_mem_free ((void *)&temp);
7726 + if (should_FindObjectsFinal) {
7727 + session->provider->f->C_FindObjectsFinal (
7728 + session->session_handle
7730 + should_FindObjectsFinal = FALSE;
7733 + if (rv == CKR_OK) {
7734 + *p_objects = objects;
7735 + *p_objects_found = objects_size;
7740 + if (objects != NULL) {
7741 + _pkcs11h_mem_free ((void *)&objects);
7747 + PKCS11H_LOG_DEBUG2,
7748 + "PKCS#11: _pkcs11h_session_findObjects return rv=%ld-'%s', *p_objects_found=%ld",
7750 + pkcs11h_getMessage (rv),
7759 +_pkcs11h_token_getTokenId (
7760 + IN const CK_TOKEN_INFO_PTR info,
7761 + OUT pkcs11h_token_id_t * const p_token_id
7763 + pkcs11h_token_id_t token_id;
7764 + CK_RV rv = CKR_OK;
7766 + PKCS11H_ASSERT (info!=NULL);
7767 + PKCS11H_ASSERT (p_token_id!=NULL);
7770 + PKCS11H_LOG_DEBUG2,
7771 + "PKCS#11: _pkcs11h_token_getTokenId entry p_token_id=%p",
7772 + (void *)p_token_id
7775 + *p_token_id = NULL;
7779 + (rv = _pkcs11h_token_newTokenId (&token_id)) == CKR_OK
7781 + _pkcs11h_util_fixupFixedString (
7783 + (char *)info->label,
7784 + sizeof (info->label)
7786 + _pkcs11h_util_fixupFixedString (
7787 + token_id->manufacturerID,
7788 + (char *)info->manufacturerID,
7789 + sizeof (info->manufacturerID)
7791 + _pkcs11h_util_fixupFixedString (
7793 + (char *)info->model,
7794 + sizeof (info->model)
7796 + _pkcs11h_util_fixupFixedString (
7797 + token_id->serialNumber,
7798 + (char *)info->serialNumber,
7799 + sizeof (info->serialNumber)
7802 + token_id->display,
7804 + sizeof (token_id->display)
7808 + if (rv == CKR_OK) {
7809 + *p_token_id = token_id;
7813 + if (token_id != NULL) {
7814 + _pkcs11h_mem_free ((void *)&token_id);
7818 + PKCS11H_LOG_DEBUG2,
7819 + "PKCS#11: _pkcs11h_token_getTokenId return rv=%ld-'%s', *p_token_id=%p",
7821 + pkcs11h_getMessage (rv),
7822 + (void *)*p_token_id
7830 +_pkcs11h_token_newTokenId (
7831 + OUT pkcs11h_token_id_t * const p_token_id
7833 + CK_RV rv = CKR_OK;
7835 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
7836 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
7837 + PKCS11H_ASSERT (p_token_id!=NULL);
7840 + PKCS11H_LOG_DEBUG2,
7841 + "PKCS#11: _pkcs11h_token_newTokenId entry p_token_id=%p",
7842 + (void *)p_token_id
7845 + *p_token_id = NULL;
7847 + if (rv == CKR_OK) {
7848 + rv = _pkcs11h_mem_malloc ((void *)p_token_id, sizeof (struct pkcs11h_token_id_s));
7852 + PKCS11H_LOG_DEBUG2,
7853 + "PKCS#11: _pkcs11h_token_newTokenId return rv=%ld-'%s', *p_token_id=%p",
7855 + pkcs11h_getMessage (rv),
7856 + (void *)*p_token_id
7864 +_pkcs11h_session_getSessionByTokenId (
7865 + IN const pkcs11h_token_id_t token_id,
7866 + OUT pkcs11h_session_t * const p_session
7868 +#if defined(ENABLE_PKCS11H_THREADING)
7869 + PKCS11H_BOOL mutex_locked = FALSE;
7871 + pkcs11h_session_t session = NULL;
7872 + PKCS11H_BOOL is_new_session = FALSE;
7873 + CK_RV rv = CKR_OK;
7875 + PKCS11H_ASSERT (token_id!=NULL);
7876 + PKCS11H_ASSERT (p_session!=NULL);
7879 + PKCS11H_LOG_DEBUG2,
7880 + "PKCS#11: _pkcs11h_session_getSessionByTokenId entry token_id=%p, p_session=%p",
7885 + *p_session = NULL;
7887 +#if defined(ENABLE_PKCS11H_THREADING)
7890 + (rv = _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.session)) == CKR_OK
7892 + mutex_locked = TRUE;
7896 + if (rv == CKR_OK) {
7897 + pkcs11h_session_t current_session;
7900 + current_session = s_pkcs11h_data->sessions;
7901 + current_session != NULL && session == NULL;
7902 + current_session = current_session->next
7905 + pkcs11h_token_sameTokenId (
7906 + current_session->token_id,
7911 + PKCS11H_LOG_DEBUG1,
7912 + "PKCS#11: Using cached session"
7914 + session = current_session;
7915 + session->reference_count++;
7924 + is_new_session = TRUE;
7927 + if (is_new_session) {
7929 + PKCS11H_LOG_DEBUG1,
7930 + "PKCS#11: Creating a new session"
7935 + (rv = _pkcs11h_mem_malloc ((void *)&session, sizeof (struct pkcs11h_session_s))) == CKR_OK
7937 + session->reference_count = 1;
7938 + session->session_handle = PKCS11H_INVALID_SESSION_HANDLE;
7940 + session->pin_cache_period = s_pkcs11h_data->pin_cache_period;
7944 + if (rv == CKR_OK) {
7945 + rv = pkcs11h_token_duplicateTokenId (
7946 + &session->token_id,
7951 +#if defined(ENABLE_PKCS11H_THREADING)
7952 + if (rv == CKR_OK) {
7953 + rv = _pkcs11h_threading_mutexInit (&session->mutex);
7957 + if (rv == CKR_OK) {
7958 + session->valid = TRUE;
7959 + session->next = s_pkcs11h_data->sessions;
7960 + s_pkcs11h_data->sessions = session;
7963 +#if defined(ENABLE_PKCS11H_THREADING)
7964 + _pkcs11h_threading_mutexFree (&session->mutex);
7966 + _pkcs11h_mem_free ((void *)&session);
7970 + if (rv == CKR_OK) {
7971 + *p_session = session;
7975 +#if defined(ENABLE_PKCS11H_THREADING)
7976 + if (mutex_locked) {
7977 + _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.session);
7978 + mutex_locked = FALSE;
7983 + PKCS11H_LOG_DEBUG2,
7984 + "PKCS#11: _pkcs11h_session_getSessionByTokenId return rv=%ld-'%s', *p_session=%p",
7986 + pkcs11h_getMessage (rv),
7987 + (void *)*p_session
7995 +_pkcs11h_session_release (
7996 + IN const pkcs11h_session_t session
7998 +#if defined(ENABLE_PKCS11H_THREADING)
7999 + PKCS11H_BOOL mutex_locked = FALSE;
8001 + CK_RV rv = CKR_OK;
8003 + PKCS11H_ASSERT (session!=NULL);
8004 + PKCS11H_ASSERT (session->reference_count>=0);
8007 + PKCS11H_LOG_DEBUG2,
8008 + "PKCS#11: _pkcs11h_session_release entry session=%p",
8012 +#if defined(ENABLE_PKCS11H_THREADING)
8015 + (rv = _pkcs11h_threading_mutexLock (&session->mutex)) == CKR_OK
8017 + mutex_locked = TRUE;
8022 + * Never logout for now
8024 + if (rv == CKR_OK) {
8025 + if (session->reference_count > 0) {
8026 + session->reference_count--;
8030 +#if defined(ENABLE_PKCS11H_THREADING)
8031 + if (mutex_locked) {
8032 + _pkcs11h_threading_mutexRelease (&session->mutex);
8033 + mutex_locked = FALSE;
8038 + PKCS11H_LOG_DEBUG2,
8039 + "PKCS#11: _pkcs11h_session_release return rv=%ld-'%s'",
8041 + pkcs11h_getMessage (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
8055 + PKCS11H_BOOL found = FALSE;
8057 + CK_RV rv = CKR_OK;
8059 + unsigned nRetry = 0;
8061 + PKCS11H_ASSERT (session!=NULL);
8062 + /*PKCS11H_ASSERT (user_data) NOT NEEDED */
8063 + PKCS11H_ASSERT (p_slot!=NULL);
8066 + PKCS11H_LOG_DEBUG2,
8067 + "PKCS#11: _pkcs11h_session_reset entry session=%p, user_data=%p, mask_prompt=%08x, p_slot=%p",
8074 + *p_slot = PKCS11H_INVALID_SLOT_ID;
8080 + pkcs11h_provider_t current_provider = NULL;
8083 + current_provider = s_pkcs11h_data->providers;
8086 + current_provider != NULL &&
8089 + current_provider = current_provider->next
8091 + CK_SLOT_ID_PTR slots = NULL;
8093 + CK_SLOT_ID slot_index;
8096 + * Skip all other providers,
8097 + * if one was set in the past
8100 + session->provider != NULL &&
8101 + session->provider != current_provider
8106 + if (rv == CKR_OK) {
8107 + rv = _pkcs11h_session_getSlotList (
8118 + slot_index < slotnum &&
8124 + pkcs11h_token_id_t token_id = NULL;
8125 + CK_TOKEN_INFO info;
8127 + if (rv == CKR_OK) {
8128 + rv = current_provider->f->C_GetTokenInfo (
8129 + slots[slot_index],
8136 + (rv = _pkcs11h_token_getTokenId (
8140 + pkcs11h_token_sameTokenId (
8141 + session->token_id,
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;
8153 + if (rv != CKR_OK) {
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],
8160 + pkcs11h_getMessage (rv)
8169 + if (token_id != NULL) {
8170 + pkcs11h_token_freeTokenId (token_id);
8174 + if (rv != CKR_OK) {
8176 + PKCS11H_LOG_DEBUG1,
8177 + "PKCS#11: Cannot get slot list for provider '%s' rv=%ld-'%s'",
8178 + current_provider->manufacturerID,
8180 + pkcs11h_getMessage (rv)
8189 + if (slots != NULL) {
8190 + _pkcs11h_mem_free ((void *)&slots);
8195 + if (rv == CKR_OK && !found && (mask_prompt & PKCS11H_PROMPT_MAST_ALLOW_CARD_PROMPT) == 0) {
8196 + rv = CKR_TOKEN_NOT_PRESENT;
8204 + PKCS11H_LOG_DEBUG1,
8205 + "PKCS#11: Calling token_prompt hook for '%s'",
8206 + session->token_id->display
8210 + !s_pkcs11h_data->hooks.token_prompt (
8211 + s_pkcs11h_data->hooks.token_prompt_data,
8213 + session->token_id,
8221 + PKCS11H_LOG_DEBUG1,
8222 + "PKCS#11: token_prompt returned %ld",
8229 + PKCS11H_LOG_DEBUG2,
8230 + "PKCS#11: _pkcs11h_session_reset return rv=%ld-'%s', *p_slot=%ld",
8232 + pkcs11h_getMessage (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
8250 + * session->mutex must be locked
8252 + CK_ATTRIBUTE filter[] = {
8253 + {CKA_CLASS, (void *)&class, sizeof (class)},
8254 + {CKA_ID, (void *)id, id_size}
8256 + CK_OBJECT_HANDLE *objects = NULL;
8257 + CK_ULONG objects_found = 0;
8258 + CK_RV rv = CKR_OK;
8260 + /*PKCS11H_ASSERT (session!=NULL); NOT NEEDED*/
8261 + PKCS11H_ASSERT (id!=NULL);
8262 + PKCS11H_ASSERT (p_handle!=NULL);
8265 + PKCS11H_LOG_DEBUG2,
8266 + "PKCS#11: _pkcs11h_session_getObjectById entry session=%p, class=%ld, id=%p, id_size=%u, p_handle=%p",
8274 + *p_handle = PKCS11H_INVALID_OBJECT_HANDLE;
8276 + if (rv == CKR_OK) {
8277 + rv = _pkcs11h_session_validate (session);
8280 + if (rv == CKR_OK) {
8281 + rv = _pkcs11h_session_findObjects (
8284 + sizeof (filter) / sizeof (CK_ATTRIBUTE),
8292 + objects_found == 0
8294 + rv = CKR_FUNCTION_REJECTED;
8297 + if (rv == CKR_OK) {
8298 + *p_handle = objects[0];
8301 + if (objects != NULL) {
8302 + _pkcs11h_mem_free ((void *)&objects);
8306 + PKCS11H_LOG_DEBUG2,
8307 + "PKCS#11: _pkcs11h_session_getObjectById return rv=%ld-'%s', *p_handle=%p",
8309 + pkcs11h_getMessage (rv),
8318 +_pkcs11h_session_validate (
8319 + IN const pkcs11h_session_t session
8321 + CK_RV rv = CKR_OK;
8323 + /*PKCS11H_ASSERT (session!=NULL); NOT NEEDED*/
8326 + PKCS11H_LOG_DEBUG2,
8327 + "PKCS#11: _pkcs11h_session_validate entry session=%p",
8335 + rv = CKR_SESSION_HANDLE_INVALID;
8341 + session->provider == NULL ||
8342 + !session->provider->enabled ||
8343 + session->session_handle == PKCS11H_INVALID_SESSION_HANDLE
8346 + rv = CKR_SESSION_HANDLE_INVALID;
8351 + session->pin_expire_time != (time_t)0 &&
8352 + session->pin_expire_time < PKCS11H_TIME (NULL)
8355 + PKCS11H_LOG_DEBUG1,
8356 + "PKCS#11: Forcing logout due to pin timeout"
8358 + _pkcs11h_session_logout (session);
8359 + rv = CKR_SESSION_HANDLE_INVALID;
8363 + PKCS11H_LOG_DEBUG2,
8364 + "PKCS#11: _pkcs11h_session_validate return rv=%ld-'%s'",
8366 + pkcs11h_getMessage (rv)
8374 +_pkcs11h_session_touch (
8375 + IN const pkcs11h_session_t session
8379 + * session->mutex must be locked
8381 + PKCS11H_ASSERT (session!=NULL);
8383 + if (session->pin_cache_period == PKCS11H_PIN_CACHE_INFINITE) {
8384 + session->pin_expire_time = 0;
8387 + session->pin_expire_time = (
8388 + PKCS11H_TIME (NULL) +
8389 + (time_t)session->pin_cache_period
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
8402 +#if defined(ENABLE_PKCS11H_THREADING)
8403 + PKCS11H_BOOL mutex_locked = FALSE;
8405 + CK_SLOT_ID slot = PKCS11H_INVALID_SLOT_ID;
8406 + CK_ULONG pin_size = 0;
8407 + CK_RV rv = CKR_OK;
8409 + pkcs11h_session_t session = NULL;
8411 + PKCS11H_ASSERT (token_id!=NULL);
8412 + /*PKCS11H_ASSERT (pin!=NULL); NOT NEEDED*/
8415 + PKCS11H_LOG_DEBUG2,
8416 + "PKCS#11: pkcs11h_token_login entry token_id=%p, readonly=%d\n",
8421 + if (pin != NULL) {
8422 + pin_size = strlen (pin);
8425 + if (rv == CKR_OK) {
8426 + rv = _pkcs11h_session_getSessionByTokenId (
8432 +#if defined(ENABLE_PKCS11H_THREADING)
8435 + (rv = _pkcs11h_threading_mutexLock (&session->mutex)) == CKR_OK
8437 + mutex_locked = TRUE;
8441 + if (rv == CKR_OK) {
8442 + rv = _pkcs11h_session_logout (session);
8445 + if (rv == CKR_OK) {
8446 + rv = _pkcs11h_session_reset (session, NULL, 0, &slot);
8449 + if (rv == CKR_OK) {
8450 + rv = _pkcs11h_session_touch (session);
8453 + if (rv == CKR_OK) {
8454 + rv = session->provider->f->C_OpenSession (
8457 + CKF_SERIAL_SESSION |
8458 + (readonly ? 0 : CKF_RW_SESSION)
8462 + &session->session_handle
8468 + (rv = session->provider->f->C_Login (
8469 + session->session_handle,
8471 + (CK_UTF8CHAR_PTR)pin,
8475 + if (rv == CKR_USER_ALREADY_LOGGED_IN) {
8480 +#if defined(ENABLE_PKCS11H_THREADING)
8481 + if (mutex_locked) {
8482 + _pkcs11h_threading_mutexRelease (&session->mutex);
8483 + mutex_locked = FALSE;
8487 + if (session != NULL) {
8488 + _pkcs11h_session_release (session);
8493 + PKCS11H_LOG_DEBUG2,
8494 + "PKCS#11: pkcs11h_token_login return rv=%ld-'%s'",
8496 + pkcs11h_getMessage (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
8513 + * session->mutex must be locked
8515 + CK_SLOT_ID slot = PKCS11H_INVALID_SLOT_ID;
8516 + CK_RV rv = CKR_OK;
8518 + PKCS11H_ASSERT (session!=NULL);
8519 + /*PKCS11H_ASSERT (user_data) NOT NEEDED */
8522 + PKCS11H_LOG_DEBUG2,
8523 + "PKCS#11: _pkcs11h_session_login entry session=%p, is_publicOnly=%d, readonly=%d, user_data=%p, mask_prompt=%08x",
8525 + is_publicOnly ? 1 : 0,
8531 + if (rv == CKR_OK) {
8532 + rv = _pkcs11h_session_logout (session);
8535 + if (rv == CKR_OK) {
8536 + rv = _pkcs11h_session_reset (session, user_data, mask_prompt, &slot);
8539 + if (rv == CKR_OK) {
8540 + rv = session->provider->f->C_OpenSession (
8543 + CKF_SERIAL_SESSION |
8544 + (readonly ? 0 : CKF_RW_SESSION)
8548 + &session->session_handle
8556 + session->provider->cert_is_private
8559 + PKCS11H_BOOL login_succeeded = FALSE;
8560 + unsigned nRetryCount = 0;
8562 + if ((mask_prompt & PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT) == 0) {
8563 + rv = CKR_USER_NOT_LOGGED_IN;
8566 + PKCS11H_LOG_DEBUG1,
8567 + "PKCS#11: Calling pin_prompt hook denied because of prompt mask"
8573 + !login_succeeded &&
8574 + nRetryCount < s_pkcs11h_data->max_retries
8576 + CK_UTF8CHAR_PTR utfPIN = NULL;
8577 + CK_ULONG lPINLength = 0;
8583 + s_pkcs11h_data->allow_protected_auth &&
8584 + session->provider->allow_protected_auth &&
8585 + session->allow_protected_auth_supported
8589 + PKCS11H_LOG_DEBUG1,
8590 + "PKCS#11: Calling pin_prompt hook for '%s'",
8591 + session->token_id->display
8595 + !s_pkcs11h_data->hooks.pin_prompt (
8596 + s_pkcs11h_data->hooks.pin_prompt_data,
8598 + session->token_id,
8607 + utfPIN = (CK_UTF8CHAR_PTR)pin;
8608 + lPINLength = strlen (pin);
8612 + PKCS11H_LOG_DEBUG1,
8613 + "PKCS#11: pin_prompt hook return rv=%ld",
8618 + if (rv == CKR_OK) {
8619 + rv = _pkcs11h_session_touch (session);
8624 + (rv = session->provider->f->C_Login (
8625 + session->session_handle,
8631 + if (rv == CKR_USER_ALREADY_LOGGED_IN) {
8637 + * Clean PIN buffer
8639 + memset (pin, 0, sizeof (pin));
8641 + if (rv == CKR_OK) {
8642 + login_succeeded = TRUE;
8645 + rv == CKR_PIN_INCORRECT ||
8646 + rv == CKR_PIN_INVALID
8649 + * Ignore these errors
8650 + * so retry can be performed
8661 + if (!login_succeeded && rv == CKR_OK) {
8662 + rv = CKR_PIN_INCORRECT;
8667 + PKCS11H_LOG_DEBUG2,
8668 + "PKCS#11: _pkcs11h_session_login return rv=%ld-'%s'",
8670 + pkcs11h_getMessage (rv)
8678 +_pkcs11h_session_logout (
8679 + IN const pkcs11h_session_t session
8683 + * session->mutex must be locked
8685 + /*PKCS11H_ASSERT (session!=NULL); NOT NEEDED*/
8688 + PKCS11H_LOG_DEBUG2,
8689 + "PKCS#11: _pkcs11h_session_logout entry session=%p",
8694 + session != NULL &&
8695 + session->session_handle != PKCS11H_INVALID_SESSION_HANDLE
8697 + CK_RV rv = CKR_OK;
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);
8704 + session->session_handle = PKCS11H_INVALID_SESSION_HANDLE;
8709 + PKCS11H_LOG_DEBUG2,
8710 + "PKCS#11: _pkcs11h_session_logout return"
8718 +_pkcs11h_hooks_default_log (
8719 + IN void * const global_data,
8720 + IN const unsigned flags,
8721 + IN const char * const format,
8724 + (void)global_data;
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
8738 + /*PKCS11H_ASSERT (global_data) NOT NEEDED */
8739 + /*PKCS11H_ASSERT (user_data) NOT NEEDED */
8740 + PKCS11H_ASSERT (token!=NULL);
8742 + (void)global_data;
8747 + PKCS11H_LOG_DEBUG2,
8748 + "PKCS#11: _pkcs11h_hooks_default_token_prompt global_data=%p, user_data=%p, display='%s'",
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
8767 + /*PKCS11H_ASSERT (global_data) NOT NEEDED */
8768 + /*PKCS11H_ASSERT (user_data) NOT NEEDED */
8769 + PKCS11H_ASSERT (token!=NULL);
8771 + (void)global_data;
8778 + PKCS11H_LOG_DEBUG2,
8779 + "PKCS#11: _pkcs11h_hooks_default_pin_prompt global_data=%p, user_data=%p, display='%s'",
8788 +#if !defined(WIN32)
8789 +#if defined(ENABLE_PKCS11H_THREADING)
8793 +__pkcs11h_threading_atfork_prepare () {
8794 + __pkcs1h_threading_mutexLockAll ();
8798 +__pkcs11h_threading_atfork_parent () {
8799 + __pkcs1h_threading_mutexReleaseAll ();
8803 +__pkcs11h_threading_atfork_child () {
8804 + __pkcs1h_threading_mutexReleaseAll ();
8805 + _pkcs11h_forkFixup ();
8808 +#endif /* ENABLE_PKCS11H_THREADING */
8812 +_pkcs11h_forkFixup () {
8813 +#if defined(ENABLE_PKCS11H_THREADING)
8814 + PKCS11H_BOOL mutex_locked = FALSE;
8816 + pid_t mypid = getpid ();
8819 + PKCS11H_LOG_DEBUG2,
8820 + "PKCS#11: pkcs11h_forkFixup entry pid=%d",
8824 + if (s_pkcs11h_data != NULL && s_pkcs11h_data->initialized) {
8825 + pkcs11h_provider_t current;
8827 +#if defined(ENABLE_PKCS11H_THREADING)
8828 + if (_pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.global) == CKR_OK) {
8829 + mutex_locked = TRUE;
8834 + current = s_pkcs11h_data->providers;
8836 + current = current->next
8838 + if (current->enabled) {
8839 + current->f->C_Initialize (NULL);
8842 +#if defined(ENABLE_PKCS11H_SLOTEVENT)
8844 + * After fork we have no threads...
8845 + * So just initialized.
8847 + if (s_pkcs11h_data->slotevent.initialized) {
8848 + s_pkcs11h_data->slotevent.initialized = FALSE;
8849 + _pkcs11h_slotevent_init ();
8855 +#if defined(ENABLE_PKCS11H_THREADING)
8856 + if (mutex_locked) {
8857 + _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.global);
8858 + mutex_locked = FALSE;
8863 + PKCS11H_LOG_DEBUG2,
8864 + "PKCS#11: pkcs11h_forkFixup return"
8870 +#endif /* !WIN32 */
8872 +#if defined(ENABLE_PKCS11H_TOKEN)
8873 +/*======================================================================*
8875 + *======================================================================*/
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
8883 +#if defined(ENABLE_PKCS11H_THREADING)
8884 + PKCS11H_BOOL mutex_locked = FALSE;
8886 + pkcs11h_session_t session = NULL;
8887 + CK_RV rv = CKR_OK;
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 */
8895 + PKCS11H_LOG_DEBUG2,
8896 + "PKCS#11: pkcs11h_token_ensureAccess entry token_id=%p, user_data=%p, mask_prompt=%08x",
8902 + if (rv == CKR_OK) {
8903 + rv = _pkcs11h_session_getSessionByTokenId (
8909 +#if defined(ENABLE_PKCS11H_THREADING)
8912 + (rv = _pkcs11h_threading_mutexLock (&session->mutex)) == CKR_OK
8914 + mutex_locked = TRUE;
8918 + if (rv == CKR_OK) {
8921 + rv = _pkcs11h_session_reset (
8929 +#if defined(ENABLE_PKCS11H_THREADING)
8930 + if (mutex_locked) {
8931 + _pkcs11h_threading_mutexRelease (&session->mutex);
8932 + mutex_locked = FALSE;
8936 + if (session != NULL) {
8937 + _pkcs11h_session_release (session);
8942 + PKCS11H_LOG_DEBUG2,
8943 + "PKCS#11: pkcs11h_token_ensureAccess return rv=%ld-'%s'",
8945 + pkcs11h_getMessage (rv)
8951 +#endif /* ENABLE_PKCS11H_TOKEN */
8953 +#if defined(ENABLE_PKCS11H_DATA)
8954 +/*======================================================================*
8956 + *======================================================================*/
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
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)}
8972 + CK_OBJECT_HANDLE *objects = NULL;
8973 + CK_ULONG objects_found = 0;
8974 + CK_RV rv = CKR_OK;
8976 + PKCS11H_ASSERT (session!=NULL);
8977 + PKCS11H_ASSERT (application!=NULL);
8978 + PKCS11H_ASSERT (label!=NULL);
8981 + PKCS11H_LOG_DEBUG2,
8982 + "PKCS#11: _pkcs11h_data_getObject entry session=%p, application='%s', label='%s', p_handle=%p",
8989 + *p_handle = PKCS11H_INVALID_OBJECT_HANDLE;
8991 + if (rv == CKR_OK) {
8992 + rv = _pkcs11h_session_validate (session);
8995 + if (rv == CKR_OK) {
8996 + rv = _pkcs11h_session_findObjects (
8999 + sizeof (filter) / sizeof (CK_ATTRIBUTE),
9007 + objects_found == 0
9009 + rv = CKR_FUNCTION_REJECTED;
9012 + if (rv == CKR_OK) {
9013 + *p_handle = objects[0];
9016 + if (objects != NULL) {
9017 + _pkcs11h_mem_free ((void *)&objects);
9021 + PKCS11H_LOG_DEBUG2,
9022 + "PKCS#11: _pkcs11h_data_getObject return rv=%ld-'%s', *p_handle=%p",
9024 + pkcs11h_getMessage (rv),
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
9042 + CK_ATTRIBUTE attrs[] = {
9043 + {CKA_VALUE, NULL, 0}
9045 + CK_OBJECT_HANDLE handle = PKCS11H_INVALID_OBJECT_HANDLE;
9046 + CK_RV rv = CKR_OK;
9048 +#if defined(ENABLE_PKCS11H_THREADING)
9049 + PKCS11H_BOOL mutex_locked = FALSE;
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;
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);
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",
9074 + blob != NULL ? *p_blob_size : 0
9077 + if (blob != NULL) {
9078 + blob_size_max = *p_blob_size;
9082 + if (rv == CKR_OK) {
9083 + rv = _pkcs11h_session_getSessionByTokenId (
9089 +#if defined(ENABLE_PKCS11H_THREADING)
9092 + (rv = _pkcs11h_threading_mutexLock (&session->mutex)) == CKR_OK
9094 + mutex_locked = TRUE;
9098 + while (rv == CKR_OK && !op_succeed) {
9100 + if (rv == CKR_OK) {
9101 + rv = _pkcs11h_session_validate (session);
9104 + if (rv == CKR_OK) {
9105 + rv = _pkcs11h_data_getObject (
9113 + if (rv == CKR_OK) {
9114 + rv = _pkcs11h_session_getObjectAttributes (
9118 + sizeof (attrs)/sizeof (CK_ATTRIBUTE)
9122 + if (rv == CKR_OK) {
9123 + op_succeed = TRUE;
9126 + if (!login_retry) {
9128 + PKCS11H_LOG_DEBUG1,
9129 + "PKCS#11: Read data object failed rv=%ld-'%s'",
9131 + pkcs11h_getMessage (rv)
9133 + login_retry = TRUE;
9134 + rv = _pkcs11h_session_login (
9145 +#if defined(ENABLE_PKCS11H_THREADING)
9146 + if (mutex_locked) {
9147 + _pkcs11h_threading_mutexRelease (&session->mutex);
9148 + mutex_locked = FALSE;
9152 + if (rv == CKR_OK) {
9153 + *p_blob_size = attrs[0].ulValueLen;
9156 + if (rv == CKR_OK) {
9157 + if (blob != NULL) {
9158 + if (*p_blob_size > blob_size_max) {
9159 + rv = CKR_BUFFER_TOO_SMALL;
9162 + memmove (blob, attrs[0].pValue, *p_blob_size);
9167 + _pkcs11h_session_freeObjectAttributes (
9169 + sizeof (attrs)/sizeof (CK_ATTRIBUTE)
9172 + if (session != NULL) {
9173 + _pkcs11h_session_release (session);
9178 + PKCS11H_LOG_DEBUG2,
9179 + "PKCS#11: pkcs11h_data_get return rv=%ld-'%s', *p_blob_size=%u",
9181 + pkcs11h_getMessage (rv),
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
9199 + CK_OBJECT_CLASS class = CKO_DATA;
9200 + CK_BBOOL ck_true = CK_TRUE;
9201 + CK_BBOOL ck_false = CK_FALSE;
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}
9212 + CK_OBJECT_HANDLE handle = PKCS11H_INVALID_OBJECT_HANDLE;
9213 + CK_RV rv = CKR_OK;
9215 +#if defined(ENABLE_PKCS11H_THREADING)
9216 + PKCS11H_BOOL mutex_locked = FALSE;
9218 + pkcs11h_session_t session = NULL;
9219 + PKCS11H_BOOL op_succeed = FALSE;
9220 + PKCS11H_BOOL login_retry = FALSE;
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);
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",
9239 + blob != NULL ? blob_size : 0
9242 + if (rv == CKR_OK) {
9243 + rv = _pkcs11h_session_getSessionByTokenId (
9249 +#if defined(ENABLE_PKCS11H_THREADING)
9252 + (rv = _pkcs11h_threading_mutexLock (&session->mutex)) == CKR_OK
9254 + mutex_locked = TRUE;
9258 + while (rv == CKR_OK && !op_succeed) {
9260 + if (rv == CKR_OK) {
9261 + rv = _pkcs11h_session_validate (session);
9264 + if (rv == CKR_OK) {
9265 + rv = session->provider->f->C_CreateObject (
9266 + session->session_handle,
9268 + sizeof (attrs)/sizeof (CK_ATTRIBUTE),
9273 + if (rv == CKR_OK) {
9274 + op_succeed = TRUE;
9277 + if (!login_retry) {
9279 + PKCS11H_LOG_DEBUG1,
9280 + "PKCS#11: Write data object failed rv=%ld-'%s'",
9282 + pkcs11h_getMessage (rv)
9284 + login_retry = TRUE;
9285 + rv = _pkcs11h_session_login (
9296 +#if defined(ENABLE_PKCS11H_THREADING)
9297 + if (mutex_locked) {
9298 + _pkcs11h_threading_mutexRelease (&session->mutex);
9299 + mutex_locked = FALSE;
9303 + if (session != NULL) {
9304 + _pkcs11h_session_release (session);
9309 + PKCS11H_LOG_DEBUG2,
9310 + "PKCS#11: pkcs11h_data_put return rv=%ld-'%s'",
9312 + pkcs11h_getMessage (rv)
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
9327 +#if defined(ENABLE_PKCS11H_THREADING)
9328 + PKCS11H_BOOL mutex_locked = FALSE;
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;
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 */
9344 + PKCS11H_LOG_DEBUG2,
9345 + "PKCS#11: pkcs11h_data_del entry token_id=%p, application='%s', label='%s', user_data=%p, mask_prompt=%08x",
9353 + if (rv == CKR_OK) {
9354 + rv = _pkcs11h_session_getSessionByTokenId (
9360 +#if defined(ENABLE_PKCS11H_THREADING)
9363 + (rv = _pkcs11h_threading_mutexLock (&session->mutex)) == CKR_OK
9365 + mutex_locked = TRUE;
9369 + while (rv == CKR_OK && !op_succeed) {
9371 + if (rv == CKR_OK) {
9372 + rv = _pkcs11h_session_validate (session);
9375 + if (rv == CKR_OK) {
9376 + rv = _pkcs11h_data_getObject (
9384 + if (rv == CKR_OK) {
9385 + rv = session->provider->f->C_DestroyObject (
9386 + session->session_handle,
9391 + if (rv == CKR_OK) {
9392 + op_succeed = TRUE;
9395 + if (!login_retry) {
9397 + PKCS11H_LOG_DEBUG1,
9398 + "PKCS#11: Remove data object failed rv=%ld-'%s'",
9400 + pkcs11h_getMessage (rv)
9402 + login_retry = TRUE;
9403 + rv = _pkcs11h_session_login (
9414 +#if defined(ENABLE_PKCS11H_THREADING)
9415 + if (mutex_locked) {
9416 + _pkcs11h_threading_mutexRelease (&session->mutex);
9417 + mutex_locked = FALSE;
9421 + if (session != NULL) {
9422 + _pkcs11h_session_release (session);
9427 + PKCS11H_LOG_DEBUG2,
9428 + "PKCS#11: pkcs11h_data_del return rv=%ld-'%s'",
9430 + pkcs11h_getMessage (rv)
9436 +#endif /* ENABLE_PKCS11H_DATA */
9438 +#if defined(ENABLE_PKCS11H_CERTIFICATE)
9439 +/*======================================================================*
9440 + * CERTIFICATE INTERFACE
9441 + *======================================================================*/
9445 +_pkcs11h_certificate_getExpiration (
9446 + IN const unsigned char * const certificate,
9447 + IN const size_t certificate_size
9450 + * This function compare the notAfter
9451 + * and select the most recent certificate
9454 +#if defined(USE_PKCS11H_OPENSSL)
9455 + X509 *x509 = NULL;
9456 +#elif defined(USE_PKCS11H_GNUTLS)
9457 + gnutls_x509_crt_t cert = NULL;
9459 + time_t expire = (time_t)0;
9461 + PKCS11H_ASSERT (certificate!=NULL);
9463 +#if defined(USE_PKCS11H_OPENSSL)
9464 + x509 = X509_new ();
9466 + if (x509 != NULL) {
9467 + pkcs11_openssl_d2i_t d2i = (pkcs11_openssl_d2i_t)certificate;
9470 + d2i_X509 (&x509, &d2i, certificate_size)
9472 + ASN1_TIME *notBefore = X509_get_notBefore (x509);
9473 + ASN1_TIME *notAfter = X509_get_notAfter (x509);
9476 + notBefore != NULL &&
9477 + notAfter != NULL &&
9478 + X509_cmp_current_time (notBefore) <= 0 &&
9479 + X509_cmp_current_time (notAfter) >= 0 &&
9480 + notAfter->length >= 12
9483 + time_t now = time (NULL);
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');
9493 + tm1.tm_sec += (int)(mktime (localtime (&now)) - mktime (gmtime (&now)));
9495 + expire = mktime (&tm1);
9500 + if (x509 != NULL) {
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};
9508 + if (gnutls_x509_crt_import (cert, &datum, GNUTLS_X509_FMT_DER) == GNUTLS_E_SUCCESS) {
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);
9515 + now >= activation_time &&
9516 + now <= expiration_time
9518 + expire = expiration_time;
9521 + gnutls_x509_crt_deinit (cert);
9524 +#error Invalid configuration
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
9538 + PKCS11H_BOOL is_better = FALSE;
9540 + /*PKCS11H_ASSERT (current!=NULL); NOT NEEDED */
9541 + PKCS11H_ASSERT (newone!=NULL);
9544 + PKCS11H_LOG_DEBUG2,
9545 + "PKCS#11: _pkcs11h_certificate_isBetterCertificate entry current=%p, current_size=%u, newone=%p, newone_size=%u",
9553 + * First certificae
9556 + if (current_size == 0 || current == NULL) {
9560 + time_t notAfterCurrent, notAfterNew;
9562 + notAfterCurrent = _pkcs11h_certificate_getExpiration (
9566 + notAfterNew = _pkcs11h_certificate_getExpiration (
9572 + PKCS11H_LOG_DEBUG2,
9573 + "PKCS#11: _pkcs11h_certificate_isBetterCertificate notAfterCurrent='%s', notAfterNew='%s'",
9574 + asctime (localtime (¬AfterCurrent)),
9575 + asctime (localtime (¬AfterNew))
9578 + is_better = notAfterNew > notAfterCurrent;
9582 + PKCS11H_LOG_DEBUG2,
9583 + "PKCS#11: _pkcs11h_certificate_isBetterCertificate return is_better=%d",
9592 +_pkcs11h_certificate_newCertificateId (
9593 + OUT pkcs11h_certificate_id_t * const p_certificate_id
9595 + CK_RV rv = CKR_OK;
9597 + PKCS11H_ASSERT (p_certificate_id!=NULL);
9600 + PKCS11H_LOG_DEBUG2,
9601 + "PKCS#11: _pkcs11h_certificate_newCertificateId entry p_certificate_id=%p",
9602 + (void *)p_certificate_id
9605 + *p_certificate_id = NULL;
9607 + if (rv == CKR_OK) {
9608 + rv = _pkcs11h_mem_malloc ((void *)p_certificate_id, sizeof (struct pkcs11h_certificate_id_s));
9612 + PKCS11H_LOG_DEBUG2,
9613 + "PKCS#11: _pkcs11h_certificate_newCertificateId return rv=%ld-'%s', *p_certificate_id=%p",
9615 + pkcs11h_getMessage (rv),
9616 + (void *)*p_certificate_id
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
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;
9637 + PKCS11H_ASSERT (blob_size==0||blob!=NULL);
9638 + PKCS11H_ASSERT (dn!=NULL);
9642 +#if defined(USE_PKCS11H_OPENSSL)
9644 + if (blob_size > 0) {
9645 + x509 = X509_new ();
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),
9656 + if (x509 != NULL) {
9662 +#elif defined(USE_PKCS11H_GNUTLS)
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};
9668 + if (gnutls_x509_crt_import (cert, &datum, GNUTLS_X509_FMT_DER) == GNUTLS_E_SUCCESS) {
9669 + size_t s = dn_size;
9671 + gnutls_x509_crt_get_dn (
9675 + ) != GNUTLS_E_SUCCESS
9677 + /* gnutls sets output parameters */
9681 + gnutls_x509_crt_deinit (cert);
9686 +#error Invalid configuration
9694 +_pkcs11h_certificate_loadCertificate (
9695 + IN const pkcs11h_certificate_t certificate
9699 + * certificate->mutex must be locked
9701 +#if defined(ENABLE_PKCS11H_THREADING)
9702 + PKCS11H_BOOL mutex_locked = FALSE;
9704 + CK_OBJECT_CLASS cert_filter_class = CKO_CERTIFICATE;
9705 + CK_ATTRIBUTE cert_filter[] = {
9706 + {CKA_CLASS, &cert_filter_class, sizeof (cert_filter_class)},
9710 + CK_OBJECT_HANDLE *objects = NULL;
9711 + CK_ULONG objects_found = 0;
9712 + CK_RV rv = CKR_OK;
9716 + PKCS11H_ASSERT (certificate!=NULL);
9717 + PKCS11H_ASSERT (certificate->id!=NULL);
9719 + /* Must be after assert */
9720 + cert_filter[1].pValue = certificate->id->attrCKA_ID;
9721 + cert_filter[1].ulValueLen = certificate->id->attrCKA_ID_size;
9724 + PKCS11H_LOG_DEBUG2,
9725 + "PKCS#11: _pkcs11h_certificate_loadCertificate entry certificate=%p",
9726 + (void *)certificate
9729 +#if defined(ENABLE_PKCS11H_THREADING)
9732 + (rv = _pkcs11h_threading_mutexLock (&certificate->session->mutex)) == CKR_OK
9734 + mutex_locked = TRUE;
9738 + if (rv == CKR_OK) {
9739 + rv = _pkcs11h_session_validate (certificate->session);
9742 + if (rv == CKR_OK) {
9743 + rv = _pkcs11h_session_findObjects (
9744 + certificate->session,
9746 + sizeof (cert_filter) / sizeof (CK_ATTRIBUTE),
9752 + for (i=0;rv == CKR_OK && i < objects_found;i++) {
9753 + CK_ATTRIBUTE attrs[] = {
9754 + {CKA_VALUE, NULL, 0}
9759 + (rv = _pkcs11h_session_getObjectAttributes (
9760 + certificate->session,
9763 + sizeof (attrs) / sizeof (CK_ATTRIBUTE)
9767 + _pkcs11h_certificate_isBetterCertificate (
9768 + certificate->id->certificate_blob,
9769 + certificate->id->certificate_blob_size,
9771 + attrs[0].ulValueLen
9774 + if (certificate->id->certificate_blob != NULL) {
9775 + _pkcs11h_mem_free ((void *)&certificate->id->certificate_blob);
9778 + rv = _pkcs11h_mem_duplicate (
9779 + (void*)&certificate->id->certificate_blob,
9780 + &certificate->id->certificate_blob_size,
9782 + attrs[0].ulValueLen
9787 + if (rv != CKR_OK) {
9789 + PKCS11H_LOG_DEBUG1,
9790 + "PKCS#11: Cannot get object attribute for provider '%s' object %ld rv=%ld-'%s'",
9791 + certificate->session->provider->manufacturerID,
9794 + pkcs11h_getMessage (rv)
9803 + _pkcs11h_session_freeObjectAttributes (
9805 + sizeof (attrs) / sizeof (CK_ATTRIBUTE)
9809 +#if defined(ENABLE_PKCS11H_THREADING)
9810 + if (mutex_locked) {
9811 + _pkcs11h_threading_mutexRelease (&certificate->session->mutex);
9812 + mutex_locked = FALSE;
9818 + certificate->id->certificate_blob == NULL
9820 + rv = CKR_ATTRIBUTE_VALUE_INVALID;
9823 + if (objects != NULL) {
9824 + _pkcs11h_mem_free ((void *)&objects);
9828 + * No need to free allocated objects
9829 + * on error, since the certificate_id
9830 + * should be free by caller.
9834 + PKCS11H_LOG_DEBUG2,
9835 + "PKCS#11: _pkcs11h_certificate_loadCertificate return rv=%ld-'%s'",
9837 + pkcs11h_getMessage (rv)
9845 +_pkcs11h_certificate_updateCertificateIdDescription (
9846 + IN OUT pkcs11h_certificate_id_t certificate_id
9848 + static const char * separator = " on ";
9849 + static const char * unknown = "UNKNOWN";
9851 + PKCS11H_ASSERT (certificate_id!=NULL);
9854 + PKCS11H_LOG_DEBUG2,
9855 + "PKCS#11: _pkcs11h_certificate_updateCertificateIdDescription entry certificate_id=%p",
9856 + (void *)certificate_id
9859 + certificate_id->displayName[0] = '\x0';
9861 + _pkcs11h_certificate_getDN (
9862 + certificate_id->certificate_blob,
9863 + certificate_id->certificate_blob_size,
9864 + certificate_id->displayName,
9865 + sizeof (certificate_id->displayName)
9868 + if (strlen (certificate_id->displayName) == 0) {
9870 + certificate_id->displayName,
9872 + sizeof (certificate_id->displayName)-1
9877 + * Try to avoid using snprintf,
9878 + * may be unavailable
9881 + certificate_id->displayName,
9883 + sizeof (certificate_id->displayName)-1-strlen (certificate_id->displayName)
9886 + certificate_id->displayName,
9887 + certificate_id->token_id->display,
9888 + sizeof (certificate_id->displayName)-1-strlen (certificate_id->displayName)
9890 + certificate_id->displayName[sizeof (certificate_id->displayName) - 1] = '\0';
9893 + PKCS11H_LOG_DEBUG2,
9894 + "PKCS#11: _pkcs11h_certificate_updateCertificateIdDescription return displayName='%s'",
9895 + certificate_id->displayName
9903 +_pkcs11h_certificate_getKeyAttributes (
9904 + IN const pkcs11h_certificate_t certificate
9906 +#if defined(ENABLE_PKCS11H_THREADING)
9907 + PKCS11H_BOOL mutex_locked = FALSE;
9909 + CK_RV rv = CKR_OK;
9911 + PKCS11H_BOOL op_succeed = FALSE;
9912 + PKCS11H_BOOL login_retry = FALSE;
9914 + PKCS11H_ASSERT (certificate!=NULL);
9917 + PKCS11H_LOG_DEBUG2,
9918 + "PKCS#11: _pkcs11h_certificate_getKeyAttributes entry certificate=%p",
9919 + (void *)certificate
9922 +#if defined(ENABLE_PKCS11H_THREADING)
9925 + (rv = _pkcs11h_threading_mutexLock (&certificate->mutex)) == CKR_OK
9927 + mutex_locked = TRUE;
9931 + certificate->mask_sign_mode = 0;
9933 + while (rv == CKR_OK && !op_succeed) {
9934 + CK_ATTRIBUTE key_attrs[] = {
9935 + {CKA_SIGN, NULL, 0},
9936 + {CKA_SIGN_RECOVER, NULL, 0}
9940 + * Don't try invalid object
9944 + certificate->key_handle == PKCS11H_INVALID_OBJECT_HANDLE
9946 + rv = CKR_OBJECT_HANDLE_INVALID;
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;
9954 + PKCS11H_LOG_DEBUG1,
9955 + "PKCS#11: Key attributes enforced by provider (%08x)",
9956 + certificate->mask_sign_mode
9961 + if (rv == CKR_OK && !op_succeed) {
9962 + rv = _pkcs11h_session_getObjectAttributes (
9963 + certificate->session,
9964 + certificate->key_handle,
9966 + sizeof (key_attrs) / sizeof (CK_ATTRIBUTE)
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;
9974 + if (key_attrs_sign != NULL && *key_attrs_sign != CK_FALSE) {
9975 + certificate->mask_sign_mode |= PKCS11H_SIGNMODE_MASK_SIGN;
9977 + if (key_attrs_sign_recover != NULL && *key_attrs_sign_recover != CK_FALSE) {
9978 + certificate->mask_sign_mode |= PKCS11H_SIGNMODE_MASK_RECOVER;
9980 + if (certificate->mask_sign_mode == 0) {
9981 + rv = CKR_KEY_TYPE_INCONSISTENT;
9984 + PKCS11H_LOG_DEBUG1,
9985 + "PKCS#11: Key attributes loaded (%08x)",
9986 + certificate->mask_sign_mode
9990 + _pkcs11h_session_freeObjectAttributes (
9992 + sizeof (key_attrs) / sizeof (CK_ATTRIBUTE)
9995 + if (rv == CKR_OK) {
9996 + op_succeed = TRUE;
9999 + if (!login_retry) {
10001 + PKCS11H_LOG_DEBUG1,
10002 + "PKCS#11: Get private key attributes failed: %ld:'%s'",
10004 + pkcs11h_getMessage (rv)
10007 + rv = _pkcs11h_certificate_resetSession (
10013 + login_retry = TRUE;
10018 +#if defined(ENABLE_PKCS11H_THREADING)
10019 + if (mutex_locked) {
10020 + _pkcs11h_threading_mutexRelease (&certificate->mutex);
10021 + mutex_locked = FALSE;
10026 + PKCS11H_LOG_DEBUG2,
10027 + "PKCS#11: _pkcs11h_certificate_getKeyAttributes return rv=%ld-'%s'",
10029 + pkcs11h_getMessage (rv)
10037 +_pkcs11h_certificate_validateSession (
10038 + IN const pkcs11h_certificate_t certificate
10042 + * certificate->mutex must be locked
10043 + * certificate->session->mutex must be locked
10045 + CK_RV rv = CKR_OK;
10047 + PKCS11H_ASSERT (certificate!=NULL);
10050 + PKCS11H_LOG_DEBUG2,
10051 + "PKCS#11: _pkcs11h_certificate_validateSession entry certificate=%p",
10052 + (void *)certificate
10055 + if (certificate->session == NULL) {
10056 + rv = CKR_SESSION_HANDLE_INVALID;
10059 + if (rv == CKR_OK) {
10060 + rv = _pkcs11h_session_validate (certificate->session);
10063 + if (rv == CKR_OK) {
10064 + if (certificate->key_handle == PKCS11H_INVALID_OBJECT_HANDLE) {
10065 + rv = CKR_OBJECT_HANDLE_INVALID;
10070 + PKCS11H_LOG_DEBUG2,
10071 + "PKCS#11: _pkcs11h_certificate_validateSession return rv=%ld-'%s'",
10073 + pkcs11h_getMessage (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
10087 + * certificate->mutex must be locked
10089 +#if defined(ENABLE_PKCS11H_THREADING)
10090 + PKCS11H_BOOL mutex_locked = FALSE;
10092 + PKCS11H_BOOL is_key_valid = FALSE;
10093 + CK_RV rv = CKR_OK;
10095 + PKCS11H_ASSERT (certificate!=NULL);
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
10105 + if (rv == CKR_OK && certificate->session == NULL) {
10106 + rv = _pkcs11h_session_getSessionByTokenId (certificate->id->token_id, &certificate->session);
10109 +#if defined(ENABLE_PKCS11H_THREADING)
10112 + !session_mutex_locked &&
10113 + (rv = _pkcs11h_threading_mutexLock (&certificate->session->mutex)) == CKR_OK
10115 + mutex_locked = TRUE;
10121 + !certificate->pin_cache_populated_to_session
10123 + certificate->pin_cache_populated_to_session = TRUE;
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
10133 + certificate->session->pin_cache_period = certificate->pin_cache_period;
10137 + certificate->session->pin_expire_time = (
10138 + PKCS11H_TIME (NULL) +
10139 + (time_t)certificate->pin_cache_period
10141 + certificate->session->pin_cache_period = certificate->pin_cache_period;
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
10152 + if (rv == CKR_OK) {
10154 + certificate->session->session_handle != PKCS11H_INVALID_SESSION_HANDLE &&
10155 + certificate->key_handle == PKCS11H_INVALID_OBJECT_HANDLE
10157 + if (!public_only || certificate->session->provider->cert_is_private) {
10159 + (rv = _pkcs11h_session_getObjectById (
10160 + certificate->session,
10162 + certificate->id->attrCKA_ID,
10163 + certificate->id->attrCKA_ID_size,
10164 + &certificate->key_handle
10167 + is_key_valid = TRUE;
10174 + certificate->key_handle = PKCS11H_INVALID_OBJECT_HANDLE;
10183 + (rv = _pkcs11h_session_login (
10184 + certificate->session,
10187 + certificate->user_data,
10188 + certificate->mask_prompt
10191 + rv = _pkcs11h_certificate_updateCertificateIdDescription (certificate->id);
10198 + (rv = _pkcs11h_session_getObjectById (
10199 + certificate->session,
10201 + certificate->id->attrCKA_ID,
10202 + certificate->id->attrCKA_ID_size,
10203 + &certificate->key_handle
10206 + is_key_valid = TRUE;
10214 + rv = CKR_FUNCTION_REJECTED;
10217 +#if defined(ENABLE_PKCS11H_THREADING)
10218 + if (mutex_locked) {
10219 + _pkcs11h_threading_mutexRelease (&certificate->session->mutex);
10220 + mutex_locked = FALSE;
10225 + PKCS11H_LOG_DEBUG2,
10226 + "PKCS#11: _pkcs11h_certificate_resetSession return rv=%ld-'%s'",
10228 + pkcs11h_getMessage (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
10245 +#if defined(ENABLE_PKCS11H_THREADING)
10246 + PKCS11H_BOOL mutex_locked = FALSE;
10248 + CK_MECHANISM mech = {
10249 + mech_type, NULL, 0
10252 + CK_RV rv = CKR_OK;
10253 + PKCS11H_BOOL login_retry = FALSE;
10254 + PKCS11H_BOOL op_succeed = FALSE;
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);
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,
10272 + target != NULL ? *p_target_size : 0
10275 + if (target == NULL) {
10276 + *p_target_size = 0;
10279 +#if defined(ENABLE_PKCS11H_THREADING)
10282 + (rv = _pkcs11h_threading_mutexLock (&certificate->mutex)) == CKR_OK
10284 + mutex_locked = TRUE;
10288 + while (rv == CKR_OK && !op_succeed) {
10289 + if (rv == CKR_OK && !certificate->operation_active) {
10290 + rv = _pkcs11h_certificate_validateSession (certificate);
10293 + if (rv == CKR_OK && !certificate->operation_active) {
10295 + case _pkcs11h_private_op_sign:
10296 + rv = certificate->session->provider->f->C_SignInit (
10297 + certificate->session->session_handle,
10299 + certificate->key_handle
10302 + case _pkcs11h_private_op_sign_recover:
10303 + rv = certificate->session->provider->f->C_SignRecoverInit (
10304 + certificate->session->session_handle,
10306 + certificate->key_handle
10309 + case _pkcs11h_private_op_decrypt:
10310 + rv = certificate->session->provider->f->C_DecryptInit (
10311 + certificate->session->session_handle,
10313 + certificate->key_handle
10317 + rv = CKR_ARGUMENTS_BAD;
10322 + PKCS11H_LOG_DEBUG2,
10323 + "PKCS#11: _pkcs11h_certificate_doPrivateOperation init rv=%ld",
10328 + if (rv == CKR_OK) {
10329 + CK_ULONG size = *p_target_size;
10332 + case _pkcs11h_private_op_sign:
10333 + rv = certificate->session->provider->f->C_Sign (
10334 + certificate->session->session_handle,
10335 + (CK_BYTE_PTR)source,
10337 + (CK_BYTE_PTR)target,
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,
10346 + (CK_BYTE_PTR)target,
10350 + case _pkcs11h_private_op_decrypt:
10351 + rv = certificate->session->provider->f->C_Decrypt (
10352 + certificate->session->session_handle,
10353 + (CK_BYTE_PTR)source,
10355 + (CK_BYTE_PTR)target,
10360 + rv = CKR_ARGUMENTS_BAD;
10364 + *p_target_size = size;
10367 + PKCS11H_LOG_DEBUG2,
10368 + "PKCS#11: _pkcs11h_certificate_doPrivateOperation op rv=%ld",
10374 + target == NULL &&
10376 + rv == CKR_BUFFER_TOO_SMALL ||
10380 + certificate->operation_active = TRUE;
10384 + certificate->operation_active = FALSE;
10387 + if (rv == CKR_OK) {
10388 + op_succeed = TRUE;
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
10399 + if (login_retry && rv == CKR_DEVICE_REMOVED) {
10400 + login_retry = FALSE;
10401 + _pkcs11h_session_logout (certificate->session);
10404 + if (!login_retry) {
10406 + PKCS11H_LOG_DEBUG1,
10407 + "PKCS#11: Private key operation failed rv=%ld-'%s'",
10409 + pkcs11h_getMessage (rv)
10411 + login_retry = TRUE;
10412 + rv = _pkcs11h_certificate_resetSession (
10422 +#if defined(ENABLE_PKCS11H_THREADING)
10423 + if (mutex_locked) {
10424 + _pkcs11h_threading_mutexRelease (&certificate->mutex);
10425 + mutex_locked = FALSE;
10430 + PKCS11H_LOG_DEBUG2,
10431 + "PKCS#11: _pkcs11h_certificate_doPrivateOperation return rv=%ld-'%s', *p_target_size=%u",
10433 + pkcs11h_getMessage (rv),
10441 +pkcs11h_certificate_freeCertificateId (
10442 + IN pkcs11h_certificate_id_t certificate_id
10444 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
10445 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
10446 + PKCS11H_ASSERT (certificate_id!=NULL);
10449 + PKCS11H_LOG_DEBUG2,
10450 + "PKCS#11: pkcs11h_certificate_freeCertificateId entry certificate_id=%p",
10451 + (void *)certificate_id
10454 + if (certificate_id->attrCKA_ID != NULL) {
10455 + _pkcs11h_mem_free ((void *)&certificate_id->attrCKA_ID);
10457 + if (certificate_id->certificate_blob != NULL) {
10458 + _pkcs11h_mem_free ((void *)&certificate_id->certificate_blob);
10460 + if (certificate_id->token_id != NULL) {
10461 + pkcs11h_token_freeTokenId (certificate_id->token_id);
10462 + certificate_id->token_id = NULL;
10464 + _pkcs11h_mem_free ((void *)&certificate_id);
10467 + PKCS11H_LOG_DEBUG2,
10468 + "PKCS#11: pkcs11h_certificate_freeCertificateId return"
10475 +pkcs11h_certificate_duplicateCertificateId (
10476 + OUT pkcs11h_certificate_id_t * const to,
10477 + IN const pkcs11h_certificate_id_t from
10479 + CK_RV rv = CKR_OK;
10481 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
10482 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
10483 + PKCS11H_ASSERT (to!=NULL);
10484 + PKCS11H_ASSERT (from!=NULL);
10487 + PKCS11H_LOG_DEBUG2,
10488 + "PKCS#11: pkcs11h_certificate_duplicateCertificateId entry to=%p form=%p",
10495 + if (rv == CKR_OK) {
10496 + rv = _pkcs11h_mem_duplicate (
10500 + sizeof (struct pkcs11h_certificate_id_s)
10504 + if (rv == CKR_OK) {
10505 + rv = _pkcs11h_mem_duplicate (
10506 + (void*)&(*to)->token_id,
10509 + sizeof (struct pkcs11h_token_id_s)
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
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
10532 + PKCS11H_LOG_DEBUG2,
10533 + "PKCS#11: pkcs11h_certificate_duplicateCertificateId return rv=%ld-'%s', *to=%p",
10535 + pkcs11h_getMessage (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
10548 + CK_RV rv = CKR_OK;
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);
10556 + PKCS11H_LOG_DEBUG2,
10557 + "PKCS#11: pkcs11h_certificate_setCertificateIdCertificateBlob entry certificate_id=%p",
10558 + (void *)certificate_id
10561 + if (rv == CKR_OK && certificate_id->certificate_blob != NULL) {
10562 + rv = _pkcs11h_mem_free ((void *)&certificate_id->certificate_blob);
10565 + if (rv == CKR_OK) {
10566 + rv = _pkcs11h_mem_duplicate (
10567 + (void *)&certificate_id->certificate_blob,
10568 + &certificate_id->certificate_blob_size,
10575 + PKCS11H_LOG_DEBUG2,
10576 + "PKCS#11: pkcs11h_certificate_setCertificateIdCertificateBlob return rv=%ld-'%s'",
10578 + pkcs11h_getMessage (rv)
10585 +pkcs11h_certificate_freeCertificate (
10586 + IN pkcs11h_certificate_t certificate
10588 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
10589 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
10592 + PKCS11H_LOG_DEBUG2,
10593 + "PKCS#11: pkcs11h_certificate_freeCertificate entry certificate=%p",
10594 + (void *)certificate
10597 + if (certificate != NULL) {
10598 + if (certificate->session != NULL) {
10599 + _pkcs11h_session_release (certificate->session);
10601 + pkcs11h_certificate_freeCertificateId (certificate->id);
10602 + certificate->id = NULL;
10604 +#if defined(ENABLE_PKCS11H_THREADING)
10605 + _pkcs11h_threading_mutexFree (&certificate->mutex);
10608 + _pkcs11h_mem_free ((void *)&certificate);
10612 + PKCS11H_LOG_DEBUG2,
10613 + "PKCS#11: pkcs11h_certificate_freeCertificate return"
10620 +pkcs11h_certificate_lockSession (
10621 + IN const pkcs11h_certificate_t certificate
10623 +#if defined(ENABLE_PKCS11H_THREADING)
10624 + CK_RV rv = CKR_OK;
10626 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
10627 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
10628 + PKCS11H_ASSERT (certificate!=NULL);
10630 + if (rv == CKR_OK && certificate->session == NULL) {
10631 + rv = _pkcs11h_session_getSessionByTokenId (certificate->id->token_id, &certificate->session);
10634 + if (rv == CKR_OK) {
10635 + rv = _pkcs11h_threading_mutexLock (&certificate->session->mutex);
10645 +pkcs11h_certificate_releaseSession (
10646 + IN const pkcs11h_certificate_t certificate
10648 +#if defined(ENABLE_PKCS11H_THREADING)
10649 + CK_RV rv = CKR_OK;
10651 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
10652 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
10653 + PKCS11H_ASSERT (certificate!=NULL);
10655 + if (certificate->session != NULL) {
10656 + rv = _pkcs11h_threading_mutexRelease (&certificate->session->mutex);
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
10674 + CK_RV rv = CKR_OK;
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);
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,
10691 + target != NULL ? *p_target_size : 0
10694 + if (target == NULL) {
10695 + *p_target_size = 0;
10698 + if (rv == CKR_OK) {
10699 + rv = _pkcs11h_certificate_doPrivateOperation (
10701 + _pkcs11h_private_op_sign,
10711 + PKCS11H_LOG_DEBUG2,
10712 + "PKCS#11: pkcs11h_certificate_sign return rv=%ld-'%s', *p_target_size=%u",
10714 + pkcs11h_getMessage (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
10730 + CK_RV rv = CKR_OK;
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);
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,
10747 + target != NULL ? *p_target_size : 0
10750 + if (target == NULL) {
10751 + *p_target_size = 0;
10754 + if (rv == CKR_OK) {
10755 + rv = _pkcs11h_certificate_doPrivateOperation (
10757 + _pkcs11h_private_op_sign_recover,
10767 + PKCS11H_LOG_DEBUG2,
10768 + "PKCS#11: pkcs11h_certificate_signRecover return rv=%ld-'%s', *p_target_size=%u",
10770 + pkcs11h_getMessage (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
10786 + CK_RV rv = CKR_OK;
10787 + PKCS11H_BOOL fSigned = FALSE;
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);
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,
10804 + target != NULL ? *p_target_size : 0
10809 + certificate->mask_sign_mode == 0
10812 + PKCS11H_LOG_DEBUG1,
10813 + "PKCS#11: Getting key attributes"
10815 + rv = _pkcs11h_certificate_getKeyAttributes (certificate);
10821 + (certificate->mask_sign_mode & PKCS11H_SIGNMODE_MASK_SIGN) != 0
10823 + rv = pkcs11h_certificate_sign (
10832 + if (rv == CKR_OK) {
10836 + rv == CKR_FUNCTION_NOT_SUPPORTED ||
10837 + rv == CKR_KEY_FUNCTION_NOT_PERMITTED
10839 + certificate->mask_sign_mode &= ~PKCS11H_SIGNMODE_MASK_SIGN;
10847 + (certificate->mask_sign_mode & PKCS11H_SIGNMODE_MASK_RECOVER) != 0
10849 + rv = pkcs11h_certificate_signRecover (
10858 + if (rv == CKR_OK) {
10862 + rv == CKR_FUNCTION_NOT_SUPPORTED ||
10863 + rv == CKR_KEY_FUNCTION_NOT_PERMITTED
10865 + certificate->mask_sign_mode &= ~PKCS11H_SIGNMODE_MASK_RECOVER;
10870 + if (rv == CKR_OK && !fSigned) {
10871 + rv = CKR_FUNCTION_FAILED;
10875 + PKCS11H_LOG_DEBUG2,
10876 + "PKCS#11: pkcs11h_certificate_signAny return rv=%ld-'%s', *p_target_size=%p",
10878 + pkcs11h_getMessage (rv),
10879 + (void *)*p_target_size
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
10894 + CK_RV rv = CKR_OK;
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);
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,
10911 + target != NULL ? *p_target_size : 0
10914 + if (target == NULL) {
10915 + *p_target_size = 0;
10918 + if (rv == CKR_OK) {
10919 + rv = _pkcs11h_certificate_doPrivateOperation (
10921 + _pkcs11h_private_op_decrypt,
10931 + PKCS11H_LOG_DEBUG2,
10932 + "PKCS#11: pkcs11h_decrypt return rv=%ld-'%s', *p_target_size=%u",
10934 + pkcs11h_getMessage (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
10949 + pkcs11h_certificate_t certificate = NULL;
10950 + CK_RV rv = CKR_OK;
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);
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,
10963 + pin_cache_period,
10964 + (void *)p_certificate
10967 + *p_certificate = NULL;
10971 + (rv = _pkcs11h_mem_malloc ((void*)&certificate, sizeof (struct pkcs11h_certificate_s))) == CKR_OK
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;
10979 +#if defined(ENABLE_PKCS11H_THREADING)
10980 + if (rv == CKR_OK) {
10981 + rv = _pkcs11h_threading_mutexInit (&certificate->mutex);
10985 + if (rv == CKR_OK) {
10986 + rv = pkcs11h_certificate_duplicateCertificateId (&certificate->id, certificate_id);
10989 + if (rv == CKR_OK) {
10990 + *p_certificate = certificate;
10991 + certificate = NULL;
10994 + if (certificate != NULL) {
10995 +#if defined(ENABLE_PKCS11H_THREADING)
10996 + _pkcs11h_threading_mutexFree (&certificate->mutex);
10998 + _pkcs11h_mem_free ((void *)&certificate);
11002 + PKCS11H_LOG_DEBUG2,
11003 + "PKCS#11: pkcs11h_certificate_create return rv=%ld-'%s' *p_certificate=%p",
11005 + pkcs11h_getMessage (rv),
11006 + (void *)*p_certificate
11013 +pkcs11h_certificate_getPromptMask (
11014 + IN const pkcs11h_certificate_t certificate
11016 + PKCS11H_ASSERT (certificate!=NULL);
11018 + return certificate->mask_prompt;
11022 +pkcs11h_certificate_setPromptMask (
11023 + IN const pkcs11h_certificate_t certificate,
11024 + IN const unsigned mask_prompt
11026 + PKCS11H_ASSERT (certificate!=NULL);
11028 + certificate->mask_prompt = mask_prompt;
11032 +pkcs11h_certificate_getUserData (
11033 + IN const pkcs11h_certificate_t certificate
11035 + PKCS11H_ASSERT (certificate!=NULL);
11037 + return certificate->user_data;
11041 +pkcs11h_certificate_setUserData (
11042 + IN const pkcs11h_certificate_t certificate,
11043 + IN void * const user_data
11045 + PKCS11H_ASSERT (certificate!=NULL);
11047 + certificate->user_data = user_data;
11051 +pkcs11h_certificate_getCertificateId (
11052 + IN const pkcs11h_certificate_t certificate,
11053 + OUT pkcs11h_certificate_id_t * const p_certificate_id
11055 + CK_RV rv = CKR_OK;
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);
11063 + PKCS11H_LOG_DEBUG2,
11064 + "PKCS#11: pkcs11h_certificate_getCertificateId entry certificate=%p, certificate_id=%p",
11065 + (void *)certificate,
11066 + (void *)p_certificate_id
11069 + if (rv == CKR_OK) {
11070 + rv = pkcs11h_certificate_duplicateCertificateId (
11071 + p_certificate_id,
11077 + PKCS11H_LOG_DEBUG2,
11078 + "PKCS#11: pkcs11h_certificate_getCertificateId return rv=%ld-'%s'",
11080 + pkcs11h_getMessage (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
11092 +#if defined(ENABLE_PKCS11H_THREADING)
11093 + PKCS11H_BOOL mutex_locked = FALSE;
11095 + CK_RV rv = CKR_OK;
11096 + size_t certifiate_blob_size_max = 0;
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);
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
11112 + if (certificate_blob != NULL) {
11113 + certifiate_blob_size_max = *p_certificate_blob_size;
11115 + *p_certificate_blob_size = 0;
11117 +#if defined(ENABLE_PKCS11H_THREADING)
11120 + (rv = _pkcs11h_threading_mutexLock (&certificate->mutex)) == CKR_OK
11122 + mutex_locked = TRUE;
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;
11134 + if (rv == CKR_OK) {
11135 + rv = _pkcs11h_certificate_loadCertificate (certificate);
11138 + if (rv == CKR_OK) {
11139 + op_succeed = TRUE;
11142 + if (!login_retry) {
11143 + login_retry = TRUE;
11144 + rv = _pkcs11h_certificate_resetSession (
11156 + certificate->id->certificate_blob == NULL
11158 + rv = CKR_FUNCTION_REJECTED;
11161 + if (rv == CKR_OK) {
11162 + _pkcs11h_certificate_updateCertificateIdDescription (certificate->id);
11165 + if (rv == CKR_OK) {
11166 + *p_certificate_blob_size = certificate->id->certificate_blob_size;
11169 + if (certificate_blob != NULL) {
11172 + certificate->id->certificate_blob_size > certifiate_blob_size_max
11174 + rv = CKR_BUFFER_TOO_SMALL;
11177 + if (rv == CKR_OK) {
11179 + certificate_blob,
11180 + certificate->id->certificate_blob,
11181 + *p_certificate_blob_size
11186 +#if defined(ENABLE_PKCS11H_THREADING)
11187 + if (mutex_locked) {
11188 + _pkcs11h_threading_mutexRelease (&certificate->mutex);
11189 + mutex_locked = FALSE;
11194 + PKCS11H_LOG_DEBUG2,
11195 + "PKCS#11: pkcs11h_certificate_getCertificateBlob return rv=%ld-'%s'",
11197 + pkcs11h_getMessage (rv)
11203 +#if defined(ENABLE_PKCS11H_SERIALIZATION)
11206 +pkcs11h_certificate_serializeCertificateId (
11207 + OUT char * const sz,
11208 + IN OUT size_t *max,
11209 + IN const pkcs11h_certificate_id_t certificate_id
11211 + CK_RV rv = CKR_OK;
11212 + size_t saved_max = 0;
11216 + /*PKCS11H_ASSERT (sz!=NULL); Not required */
11217 + PKCS11H_ASSERT (max!=NULL);
11218 + PKCS11H_ASSERT (certificate_id!=NULL);
11221 + PKCS11H_LOG_DEBUG2,
11222 + "PKCS#11: pkcs11h_certificate_serializeCertificateId entry sz=%p, *max=%u, certificate_id=%p",
11224 + sz != NULL ? *max : 0,
11225 + (void *)certificate_id
11228 + if (sz != NULL) {
11229 + saved_max = n = *max;
11233 + if (rv == CKR_OK) {
11234 + rv = pkcs11h_token_serializeTokenId (
11237 + certificate_id->token_id
11241 + if (rv == CKR_OK) {
11242 + _max = n + certificate_id->attrCKA_ID_size*2 + 1;
11245 + if (sz != NULL) {
11246 + if (saved_max < _max) {
11247 + rv = CKR_ATTRIBUTE_VALUE_INVALID;
11250 + if (rv == CKR_OK) {
11252 + rv = _pkcs11h_util_binaryToHex (
11255 + certificate_id->attrCKA_ID,
11256 + certificate_id->attrCKA_ID_size
11265 + PKCS11H_LOG_DEBUG2,
11266 + "PKCS#11: pkcs11h_certificate_serializeCertificateId return rv=%ld-'%s', *max=%u, sz='%s'",
11268 + pkcs11h_getMessage (rv),
11277 +pkcs11h_certificate_deserializeCertificateId (
11278 + OUT pkcs11h_certificate_id_t * const p_certificate_id,
11279 + IN const char * const sz
11281 + pkcs11h_certificate_id_t certificate_id = NULL;
11282 + CK_RV rv = CKR_OK;
11284 + char *_sz = NULL;
11286 + PKCS11H_ASSERT (p_certificate_id!=NULL);
11287 + PKCS11H_ASSERT (sz!=NULL);
11289 + *p_certificate_id = NULL;
11292 + PKCS11H_LOG_DEBUG2,
11293 + "PKCS#11: pkcs11h_certificate_deserializeCertificateId entry p_certificate_id=%p, sz='%s'",
11294 + (void *)p_certificate_id,
11298 + if (rv == CKR_OK) {
11299 + rv = _pkcs11h_mem_strdup (
11305 + if (rv == CKR_OK) {
11309 + if (rv == CKR_OK) {
11310 + rv = _pkcs11h_certificate_newCertificateId (&certificate_id);
11315 + (p = strrchr (_sz, '/')) == NULL
11317 + rv = CKR_ATTRIBUTE_VALUE_INVALID;
11320 + if (rv == CKR_OK) {
11325 + if (rv == CKR_OK) {
11326 + rv = pkcs11h_token_deserializeTokenId (
11327 + &certificate_id->token_id,
11332 + if (rv == CKR_OK) {
11333 + certificate_id->attrCKA_ID_size = strlen (p)/2;
11338 + (rv = _pkcs11h_mem_malloc (
11339 + (void *)&certificate_id->attrCKA_ID,
11340 + certificate_id->attrCKA_ID_size)
11343 + rv = _pkcs11h_util_hexToBinary (
11344 + certificate_id->attrCKA_ID,
11346 + &certificate_id->attrCKA_ID_size
11350 + if (rv == CKR_OK) {
11351 + *p_certificate_id = certificate_id;
11352 + certificate_id = NULL;
11355 + if (certificate_id != NULL) {
11356 + pkcs11h_certificate_freeCertificateId (certificate_id);
11357 + certificate_id = NULL;
11360 + if (_sz != NULL) {
11361 + _pkcs11h_mem_free ((void *)&_sz);
11365 + PKCS11H_LOG_DEBUG2,
11366 + "PKCS#11: pkcs11h_certificate_deserializeCertificateId return rv=%ld-'%s'",
11368 + pkcs11h_getMessage (rv)
11375 +#endif /* ENABLE_PKCS11H_SERIALIZATION */
11378 +pkcs11h_certificate_ensureCertificateAccess (
11379 + IN const pkcs11h_certificate_t certificate
11381 +#if defined(ENABLE_PKCS11H_THREADING)
11382 + PKCS11H_BOOL mutex_locked_cert = FALSE;
11383 + PKCS11H_BOOL mutex_locked_sess = FALSE;
11385 + PKCS11H_BOOL validCert = FALSE;
11386 + CK_RV rv = CKR_OK;
11388 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
11389 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
11390 + PKCS11H_ASSERT (certificate!=NULL);
11393 + PKCS11H_LOG_DEBUG2,
11394 + "PKCS#11: pkcs11h_certificate_ensureCertificateAccess entry certificate=%p",
11395 + (void *)certificate
11398 +#if defined(ENABLE_PKCS11H_THREADING)
11401 + (rv = _pkcs11h_threading_mutexLock (&certificate->mutex)) == CKR_OK
11403 + mutex_locked_cert = TRUE;
11407 + if (!validCert && rv == CKR_OK) {
11408 + CK_OBJECT_HANDLE h = PKCS11H_INVALID_OBJECT_HANDLE;
11410 + if (certificate->session == NULL) {
11411 + rv = CKR_SESSION_HANDLE_INVALID;
11414 +#if defined(ENABLE_PKCS11H_THREADING)
11417 + (rv = _pkcs11h_threading_mutexLock (&certificate->session->mutex)) == CKR_OK
11419 + mutex_locked_sess = TRUE;
11424 + (rv = _pkcs11h_session_getObjectById (
11425 + certificate->session,
11427 + certificate->id->attrCKA_ID,
11428 + certificate->id->attrCKA_ID_size,
11432 + validCert = TRUE;
11435 +#if defined(ENABLE_PKCS11H_THREADING)
11436 + if (mutex_locked_sess) {
11437 + _pkcs11h_threading_mutexRelease (&certificate->session->mutex);
11438 + mutex_locked_sess = FALSE;
11442 + if (rv != CKR_OK) {
11444 + PKCS11H_LOG_DEBUG1,
11445 + "PKCS#11: Cannot access existing object rv=%ld-'%s'",
11447 + pkcs11h_getMessage (rv)
11457 + if (!validCert && rv == CKR_OK) {
11459 + (rv = _pkcs11h_certificate_resetSession (
11465 + validCert = TRUE;
11469 +#if defined(ENABLE_PKCS11H_THREADING)
11470 + if (mutex_locked_cert) {
11471 + _pkcs11h_threading_mutexRelease (&certificate->mutex);
11472 + mutex_locked_cert = FALSE;
11477 + PKCS11H_LOG_DEBUG2,
11478 + "PKCS#11: pkcs11h_certificate_ensureCertificateAccess return rv=%ld-'%s'",
11480 + pkcs11h_getMessage (rv)
11487 +pkcs11h_certificate_ensureKeyAccess (
11488 + IN const pkcs11h_certificate_t certificate
11490 +#if defined(ENABLE_PKCS11H_THREADING)
11491 + PKCS11H_BOOL mutex_locked_cert = FALSE;
11492 + PKCS11H_BOOL mutex_locked_sess = FALSE;
11494 + CK_RV rv = CKR_OK;
11495 + PKCS11H_BOOL valid_key = FALSE;
11497 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
11498 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
11499 + PKCS11H_ASSERT (certificate!=NULL);
11502 + PKCS11H_LOG_DEBUG2,
11503 + "PKCS#11: pkcs11h_certificate_ensureKeyAccess entry certificate=%p",
11504 + (void *)certificate
11507 +#if defined(ENABLE_PKCS11H_THREADING)
11510 + (rv = _pkcs11h_threading_mutexLock (&certificate->mutex)) == CKR_OK
11512 + mutex_locked_cert = TRUE;
11516 + if (!valid_key && rv == CKR_OK) {
11518 + if (certificate->session == NULL) {
11519 + rv = CKR_SESSION_HANDLE_INVALID;
11522 +#if defined(ENABLE_PKCS11H_THREADING)
11525 + (rv = _pkcs11h_threading_mutexLock (&certificate->session->mutex)) == CKR_OK
11527 + mutex_locked_sess = TRUE;
11532 + (rv = _pkcs11h_session_getObjectById (
11533 + certificate->session,
11535 + certificate->id->attrCKA_ID,
11536 + certificate->id->attrCKA_ID_size,
11537 + &certificate->key_handle
11540 + valid_key = TRUE;
11543 +#if defined(ENABLE_PKCS11H_THREADING)
11544 + if (mutex_locked_sess) {
11545 + _pkcs11h_threading_mutexRelease (&certificate->session->mutex);
11546 + mutex_locked_sess = FALSE;
11550 + if (rv != CKR_OK) {
11552 + PKCS11H_LOG_DEBUG1,
11553 + "PKCS#11: Cannot access existing object rv=%ld-'%s'",
11555 + pkcs11h_getMessage (rv)
11562 + certificate->key_handle = PKCS11H_INVALID_OBJECT_HANDLE;
11566 + if (!valid_key && rv == CKR_OK) {
11568 + (rv = _pkcs11h_certificate_resetSession (
11574 + valid_key = TRUE;
11578 +#if defined(ENABLE_PKCS11H_THREADING)
11579 + if (mutex_locked_sess) {
11580 + _pkcs11h_threading_mutexRelease (&certificate->session->mutex);
11581 + mutex_locked_sess = FALSE;
11586 + PKCS11H_LOG_DEBUG2,
11587 + "PKCS#11: pkcs11h_certificate_ensureKeyAccess return rv=%ld-'%s'",
11589 + pkcs11h_getMessage (rv)
11595 +#endif /* ENABLE_PKCS11H_CERTIFICATE */
11597 +#if defined(ENABLE_PKCS11H_LOCATE)
11598 +/*======================================================================*
11599 + * LOCATE INTERFACE
11600 + *======================================================================*/
11602 +#if defined(ENABLE_PKCS11H_TOKEN) || defined(ENABLE_PKCS11H_CERTIFICATE)
11606 +_pkcs11h_locate_getTokenIdBySlotId (
11607 + IN const char * const slot,
11608 + OUT pkcs11h_token_id_t * const p_token_id
11610 + pkcs11h_provider_t current_provider = NULL;
11611 + char reference[sizeof (((pkcs11h_provider_t)NULL)->reference)];
11613 + CK_SLOT_ID selected_slot = PKCS11H_INVALID_SLOT_ID;
11614 + CK_TOKEN_INFO info;
11615 + CK_RV rv = CKR_OK;
11617 + PKCS11H_ASSERT (slot!=NULL);
11618 + PKCS11H_ASSERT (p_token_id!=NULL);
11621 + PKCS11H_LOG_DEBUG2,
11622 + "PKCS#11: _pkcs11h_locate_getTokenIdBySlotId entry slot='%s', p_token_id=%p",
11624 + (void *)p_token_id
11627 + *p_token_id = NULL;
11629 + if (rv == CKR_OK) {
11630 + if (strchr (slot, ':') == NULL) {
11631 + reference[0] = '\0';
11632 + selected_slot = atol (slot);
11637 + strncpy (reference, slot, sizeof (reference));
11638 + reference[sizeof (reference)-1] = '\0';
11640 + p = strchr (reference, ':');
11644 + selected_slot = atol (p);
11648 + if (rv == CKR_OK) {
11649 + current_provider=s_pkcs11h_data->providers;
11651 + current_provider != NULL &&
11652 + reference[0] != '\0' && /* So first provider will be selected */
11653 + strcmp (current_provider->reference, reference)
11655 + current_provider = current_provider->next;
11659 + current_provider == NULL ||
11661 + current_provider != NULL &&
11662 + !current_provider->enabled
11665 + rv = CKR_SLOT_ID_INVALID;
11671 + (rv = current_provider->f->C_GetTokenInfo (selected_slot, &info)) == CKR_OK
11673 + rv = _pkcs11h_token_getTokenId (
11680 + PKCS11H_LOG_DEBUG2,
11681 + "PKCS#11: _pkcs11h_locate_getTokenIdBySlotId return rv=%ld-'%s', *p_token_id=%p",
11683 + pkcs11h_getMessage (rv),
11684 + (void *)*p_token_id
11692 +_pkcs11h_locate_getTokenIdBySlotName (
11693 + IN const char * const name,
11694 + OUT pkcs11h_token_id_t * const p_token_id
11696 + pkcs11h_provider_t current_provider = NULL;
11698 + CK_SLOT_ID selected_slot = PKCS11H_INVALID_SLOT_ID;
11699 + CK_TOKEN_INFO info;
11700 + CK_RV rv = CKR_OK;
11702 + PKCS11H_BOOL found = FALSE;
11704 + PKCS11H_ASSERT (name!=NULL);
11705 + PKCS11H_ASSERT (p_token_id!=NULL);
11708 + PKCS11H_LOG_DEBUG2,
11709 + "PKCS#11: _pkcs11h_locate_getTokenIdBySlotName entry name='%s', p_token_id=%p",
11711 + (void *)p_token_id
11714 + *p_token_id = NULL;
11716 + current_provider = s_pkcs11h_data->providers;
11718 + current_provider != NULL &&
11722 + CK_SLOT_ID_PTR slots = NULL;
11723 + CK_ULONG slotnum;
11724 + CK_SLOT_ID slot_index;
11726 + if (!current_provider->enabled) {
11727 + rv = CKR_CRYPTOKI_NOT_INITIALIZED;
11730 + if (rv == CKR_OK) {
11731 + rv = _pkcs11h_session_getSlotList (
11732 + current_provider,
11742 + slot_index < slotnum &&
11748 + CK_SLOT_INFO info;
11751 + (rv = current_provider->f->C_GetSlotInfo (
11752 + slots[slot_index],
11756 + char current_name[sizeof (info.slotDescription)+1];
11758 + _pkcs11h_util_fixupFixedString (
11760 + (char *)info.slotDescription,
11761 + sizeof (info.slotDescription)
11764 + if (!strcmp (current_name, name)) {
11766 + selected_slot = slots[slot_index];
11770 + if (rv != CKR_OK) {
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],
11777 + pkcs11h_getMessage (rv)
11787 + if (rv != CKR_OK) {
11789 + PKCS11H_LOG_DEBUG1,
11790 + "PKCS#11: Cannot get slot list for provider '%s' rv=%ld-'%s'",
11791 + current_provider->manufacturerID,
11793 + pkcs11h_getMessage (rv)
11802 + if (slots != NULL) {
11803 + _pkcs11h_mem_free ((void *)&slots);
11808 + current_provider = current_provider->next;
11812 + if (rv == CKR_OK && !found) {
11813 + rv = CKR_SLOT_ID_INVALID;
11818 + (rv = current_provider->f->C_GetTokenInfo (selected_slot, &info)) == CKR_OK
11820 + rv = _pkcs11h_token_getTokenId (
11827 + PKCS11H_LOG_DEBUG2,
11828 + "PKCS#11: _pkcs11h_locate_getTokenIdBySlotName return rv=%ld-'%s' *p_token_id=%p",
11830 + pkcs11h_getMessage (rv),
11831 + (void *)*p_token_id
11839 +_pkcs11h_locate_getTokenIdByLabel (
11840 + IN const char * const label,
11841 + OUT pkcs11h_token_id_t * const p_token_id
11843 + pkcs11h_provider_t current_provider = NULL;
11845 + CK_SLOT_ID selected_slot = PKCS11H_INVALID_SLOT_ID;
11846 + CK_TOKEN_INFO info;
11847 + CK_RV rv = CKR_OK;
11849 + PKCS11H_BOOL found = FALSE;
11851 + PKCS11H_ASSERT (label!=NULL);
11852 + PKCS11H_ASSERT (p_token_id!=NULL);
11855 + PKCS11H_LOG_DEBUG2,
11856 + "PKCS#11: _pkcs11h_locate_getTokenIdByLabel entry label='%s', p_token_id=%p",
11858 + (void *)p_token_id
11861 + *p_token_id = NULL;
11863 + current_provider = s_pkcs11h_data->providers;
11865 + current_provider != NULL &&
11869 + CK_SLOT_ID_PTR slots = NULL;
11870 + CK_ULONG slotnum;
11871 + CK_SLOT_ID slot_index;
11873 + if (!current_provider->enabled) {
11874 + rv = CKR_CRYPTOKI_NOT_INITIALIZED;
11877 + if (rv == CKR_OK) {
11878 + rv = _pkcs11h_session_getSlotList (
11879 + current_provider,
11889 + slot_index < slotnum &&
11895 + CK_TOKEN_INFO info;
11897 + if (rv == CKR_OK) {
11898 + rv = current_provider->f->C_GetTokenInfo (
11899 + slots[slot_index],
11904 + if (rv == CKR_OK) {
11905 + char current_label[sizeof (info.label)+1];
11907 + _pkcs11h_util_fixupFixedString (
11909 + (char *)info.label,
11910 + sizeof (info.label)
11913 + if (!strcmp (current_label, label)) {
11915 + selected_slot = slots[slot_index];
11919 + if (rv != CKR_OK) {
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],
11926 + pkcs11h_getMessage (rv)
11936 + if (rv != CKR_OK) {
11938 + PKCS11H_LOG_DEBUG1,
11939 + "PKCS#11: Cannot get slot list for provider '%s' rv=%ld-'%s'",
11940 + current_provider->manufacturerID,
11942 + pkcs11h_getMessage (rv)
11951 + if (slots != NULL) {
11952 + _pkcs11h_mem_free ((void *)&slots);
11957 + current_provider = current_provider->next;
11961 + if (rv == CKR_OK && !found) {
11962 + rv = CKR_SLOT_ID_INVALID;
11967 + (rv = current_provider->f->C_GetTokenInfo (selected_slot, &info)) == CKR_OK
11969 + rv = _pkcs11h_token_getTokenId (
11976 + PKCS11H_LOG_DEBUG2,
11977 + "PKCS#11: _pkcs11h_locate_getTokenIdByLabel return rv=%ld-'%s', *p_token_id=%p",
11979 + pkcs11h_getMessage (rv),
11980 + (void *)*p_token_id
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
11994 +#if defined(ENABLE_PKCS11H_THREADING)
11995 + PKCS11H_BOOL mutex_locked = FALSE;
11998 + pkcs11h_token_id_t dummy_token_id = NULL;
11999 + pkcs11h_token_id_t token_id = NULL;
12000 + PKCS11H_BOOL found = FALSE;
12002 + CK_RV rv = CKR_OK;
12004 + unsigned nRetry = 0;
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);
12014 + PKCS11H_LOG_DEBUG2,
12015 + "PKCS#11: pkcs11h_locate_token entry slot_type='%s', slot='%s', user_data=%p, p_token_id=%p",
12019 + (void *)p_token_id
12022 + *p_token_id = NULL;
12024 +#if defined(ENABLE_PKCS11H_THREADING)
12027 + (rv = _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.global)) == CKR_OK
12029 + mutex_locked = TRUE;
12035 + (rv = _pkcs11h_token_newTokenId (&dummy_token_id)) == CKR_OK
12038 + * Temperary slot id
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;
12048 + while (rv == CKR_OK && !found) {
12049 + if (!strcmp (slot_type, "id")) {
12050 + rv = _pkcs11h_locate_getTokenIdBySlotId (
12055 + else if (!strcmp (slot_type, "name")) {
12056 + rv = _pkcs11h_locate_getTokenIdBySlotName (
12061 + else if (!strcmp (slot_type, "label")) {
12062 + rv = _pkcs11h_locate_getTokenIdByLabel (
12068 + rv = CKR_ARGUMENTS_BAD;
12071 + if (rv == CKR_OK) {
12076 + * Ignore error, since we have what we
12079 + if (rv != CKR_OK && rv != CKR_ARGUMENTS_BAD) {
12081 + PKCS11H_LOG_DEBUG1,
12082 + "PKCS#11: pkcs11h_locate_token failed rv=%ld-'%s'",
12084 + pkcs11h_getMessage (rv)
12090 + if (rv == CKR_OK && !found && (mask_prompt & PKCS11H_PROMPT_MAST_ALLOW_CARD_PROMPT) == 0) {
12091 + rv = CKR_TOKEN_NOT_PRESENT;
12094 + if (rv == CKR_OK && !found) {
12097 + PKCS11H_LOG_DEBUG1,
12098 + "PKCS#11: Calling token_prompt hook for '%s'",
12099 + dummy_token_id->display
12103 + !s_pkcs11h_data->hooks.token_prompt (
12104 + s_pkcs11h_data->hooks.token_prompt_data,
12114 + PKCS11H_LOG_DEBUG1,
12115 + "PKCS#11: token_prompt returned %ld",
12121 + if (rv == CKR_OK && !found) {
12122 + rv = CKR_SLOT_ID_INVALID;
12125 + if (rv == CKR_OK) {
12126 + *p_token_id = token_id;
12130 + if (dummy_token_id != NULL) {
12131 + pkcs11h_token_freeTokenId (dummy_token_id);
12132 + dummy_token_id = NULL;
12135 +#if defined(ENABLE_PKCS11H_THREADING)
12136 + if (mutex_locked) {
12137 + _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.global);
12138 + mutex_locked = FALSE;
12143 + PKCS11H_LOG_DEBUG2,
12144 + "PKCS#11: pkcs11h_locate_token return rv=%ld-'%s', *p_token_id=%p",
12146 + pkcs11h_getMessage (rv),
12147 + (void *)*p_token_id
12153 +#endif /* ENABLE_PKCS11H_TOKEN || ENABLE_PKCS11H_CERTIFICATE */
12155 +#if defined(ENABLE_PKCS11H_CERTIFICATE)
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
12164 +#if defined(ENABLE_PKCS11H_THREADING)
12165 + PKCS11H_BOOL mutex_locked = FALSE;
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)}
12173 + CK_OBJECT_HANDLE *objects = NULL;
12174 + CK_ULONG objects_found = 0;
12175 + CK_RV rv = CKR_OK;
12179 + PKCS11H_ASSERT (session!=NULL);
12180 + PKCS11H_ASSERT (certificate_id!=NULL);
12181 + PKCS11H_ASSERT (label!=NULL);
12184 + PKCS11H_LOG_DEBUG2,
12185 + "PKCS#11: _pkcs11h_locate_getCertificateIdByLabel entry session=%p, certificate_id=%p, label='%s'",
12187 + (void *)certificate_id,
12191 +#if defined(ENABLE_PKCS11H_THREADING)
12194 + (rv = _pkcs11h_threading_mutexLock (&session->mutex)) == CKR_OK
12196 + mutex_locked = TRUE;
12200 + if (rv == CKR_OK) {
12201 + rv = _pkcs11h_session_validate (session);
12204 + if (rv == CKR_OK) {
12205 + rv = _pkcs11h_session_findObjects (
12208 + sizeof (cert_filter) / sizeof (CK_ATTRIBUTE),
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}
12220 + if (rv == CKR_OK) {
12221 + rv = _pkcs11h_session_getObjectAttributes (
12225 + sizeof (attrs) / sizeof (CK_ATTRIBUTE)
12231 + _pkcs11h_certificate_isBetterCertificate (
12232 + certificate_id->certificate_blob,
12233 + certificate_id->certificate_blob_size,
12235 + attrs[1].ulValueLen
12238 + if (certificate_id->attrCKA_ID != NULL) {
12239 + _pkcs11h_mem_free ((void *)&certificate_id->attrCKA_ID);
12241 + if (certificate_id->certificate_blob != NULL) {
12242 + _pkcs11h_mem_free ((void *)&certificate_id->certificate_blob);
12244 + rv = _pkcs11h_mem_duplicate (
12245 + (void *)&certificate_id->attrCKA_ID,
12246 + &certificate_id->attrCKA_ID_size,
12248 + attrs[0].ulValueLen
12250 + rv = _pkcs11h_mem_duplicate (
12251 + (void *)&certificate_id->certificate_blob,
12252 + &certificate_id->certificate_blob_size,
12254 + attrs[1].ulValueLen
12258 + if (rv != CKR_OK) {
12260 + PKCS11H_LOG_DEBUG1,
12261 + "PKCS#11: Cannot get object attribute for provider '%s' object %ld rv=%ld-'%s'",
12262 + session->provider->manufacturerID,
12265 + pkcs11h_getMessage (rv)
12274 + _pkcs11h_session_freeObjectAttributes (
12276 + sizeof (attrs) / sizeof (CK_ATTRIBUTE)
12282 + certificate_id->certificate_blob == NULL
12284 + rv = CKR_ATTRIBUTE_VALUE_INVALID;
12287 + if (objects != NULL) {
12288 + _pkcs11h_mem_free ((void *)&objects);
12291 +#if defined(ENABLE_PKCS11H_THREADING)
12292 + if (mutex_locked) {
12293 + _pkcs11h_threading_mutexRelease (&session->mutex);
12294 + mutex_locked = FALSE;
12299 + * No need to free allocated objects
12300 + * on error, since the certificate_id
12301 + * should be free by caller.
12305 + PKCS11H_LOG_DEBUG2,
12306 + "PKCS#11: _pkcs11h_locate_getCertificateIdByLabel return rv=%ld-'%s'",
12308 + pkcs11h_getMessage (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
12321 +#if defined(ENABLE_PKCS11H_THREADING)
12322 + PKCS11H_BOOL mutex_locked = FALSE;
12324 + CK_OBJECT_CLASS cert_filter_class = CKO_CERTIFICATE;
12325 + CK_ATTRIBUTE cert_filter[] = {
12326 + {CKA_CLASS, &cert_filter_class, sizeof (cert_filter_class)}
12329 + CK_OBJECT_HANDLE *objects = NULL;
12330 + CK_ULONG objects_found = 0;
12331 + CK_RV rv = CKR_OK;
12335 + PKCS11H_ASSERT (session!=NULL);
12336 + PKCS11H_ASSERT (certificate_id!=NULL);
12337 + PKCS11H_ASSERT (subject!=NULL);
12340 + PKCS11H_LOG_DEBUG2,
12341 + "PKCS#11: _pkcs11h_locate_getCertificateIdBySubject entry session=%p, certificate_id=%p, subject='%s'",
12343 + (void *)certificate_id,
12347 +#if defined(ENABLE_PKCS11H_THREADING)
12350 + (rv = _pkcs11h_threading_mutexLock (&session->mutex)) == CKR_OK
12352 + mutex_locked = TRUE;
12356 + if (rv == CKR_OK) {
12357 + rv = _pkcs11h_session_validate (session);
12360 + if (rv == CKR_OK) {
12361 + rv = _pkcs11h_session_findObjects (
12364 + sizeof (cert_filter) / sizeof (CK_ATTRIBUTE),
12370 +#if defined(ENABLE_PKCS11H_THREADING)
12371 + if (mutex_locked) {
12372 + _pkcs11h_threading_mutexRelease (&session->mutex);
12373 + mutex_locked = FALSE;
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}
12382 + char current_subject[1024];
12383 + current_subject[0] = '\0';
12385 + if (rv == CKR_OK) {
12386 + rv = _pkcs11h_session_getObjectAttributes (
12390 + sizeof (attrs) / sizeof (CK_ATTRIBUTE)
12394 + if (rv == CKR_OK) {
12395 + rv = _pkcs11h_certificate_getDN (
12397 + attrs[1].ulValueLen,
12399 + sizeof (current_subject)
12405 + !strcmp (subject, current_subject) &&
12406 + _pkcs11h_certificate_isBetterCertificate (
12407 + certificate_id->certificate_blob,
12408 + certificate_id->certificate_blob_size,
12410 + attrs[1].ulValueLen
12413 + if (certificate_id->attrCKA_ID != NULL) {
12414 + _pkcs11h_mem_free ((void *)&certificate_id->attrCKA_ID);
12416 + if (certificate_id->certificate_blob != NULL) {
12417 + _pkcs11h_mem_free ((void *)&certificate_id->certificate_blob);
12419 + rv = _pkcs11h_mem_duplicate (
12420 + (void *)&certificate_id->attrCKA_ID,
12421 + &certificate_id->attrCKA_ID_size,
12423 + attrs[0].ulValueLen
12425 + rv = _pkcs11h_mem_duplicate (
12426 + (void *)&certificate_id->certificate_blob,
12427 + &certificate_id->certificate_blob_size,
12429 + attrs[1].ulValueLen
12433 + if (rv != CKR_OK) {
12435 + PKCS11H_LOG_DEBUG1,
12436 + "PKCS#11: Cannot get object attribute for provider '%s' object %ld rv=%ld-'%s'",
12437 + session->provider->manufacturerID,
12440 + pkcs11h_getMessage (rv)
12449 + _pkcs11h_session_freeObjectAttributes (
12451 + sizeof (attrs) / sizeof (CK_ATTRIBUTE)
12457 + certificate_id->certificate_blob == NULL
12459 + rv = CKR_ATTRIBUTE_VALUE_INVALID;
12462 + if (objects != NULL) {
12463 + _pkcs11h_mem_free ((void *)&objects);
12467 + * No need to free allocated objects
12468 + * on error, since the certificate_id
12469 + * should be free by caller.
12473 + PKCS11H_LOG_DEBUG2,
12474 + "PKCS#11: _pkcs11h_locate_getCertificateIdBySubject return rv=%ld-'%s'",
12476 + pkcs11h_getMessage (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
12492 +#if defined(ENABLE_PKCS11H_THREADING)
12493 + PKCS11H_BOOL mutex_locked = FALSE;
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;
12500 + CK_RV rv = CKR_OK;
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);
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",
12520 + (void *)p_certificate_id
12523 + *p_certificate_id = NULL;
12525 + if (rv == CKR_OK) {
12526 + rv = _pkcs11h_certificate_newCertificateId (&certificate_id);
12529 + if (rv == CKR_OK) {
12530 + rv = pkcs11h_locate_token (
12535 + &certificate_id->token_id
12539 + if (rv == CKR_OK) {
12540 + rv = _pkcs11h_session_getSessionByTokenId (
12541 + certificate_id->token_id,
12546 +#if defined(ENABLE_PKCS11H_THREADING)
12549 + (rv = _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.global)) == CKR_OK
12551 + mutex_locked = TRUE;
12555 + while (rv == CKR_OK && !op_succeed) {
12556 + if (!strcmp (id_type, "id")) {
12557 + certificate_id->attrCKA_ID_size = strlen (id)/2;
12559 + if (certificate_id->attrCKA_ID_size == 0) {
12560 + rv = CKR_FUNCTION_FAILED;
12565 + (rv = _pkcs11h_mem_malloc (
12566 + (void*)&certificate_id->attrCKA_ID,
12567 + certificate_id->attrCKA_ID_size
12570 + _pkcs11h_util_hexToBinary (
12571 + certificate_id->attrCKA_ID,
12573 + &certificate_id->attrCKA_ID_size
12577 + else if (!strcmp (id_type, "label")) {
12578 + rv = _pkcs11h_locate_getCertificateIdByLabel (
12584 + else if (!strcmp (id_type, "subject")) {
12585 + rv = _pkcs11h_locate_getCertificateIdBySubject (
12592 + rv = CKR_ARGUMENTS_BAD;
12595 + if (rv == CKR_OK) {
12596 + op_succeed = TRUE;
12599 + if (!login_retry) {
12601 + PKCS11H_LOG_DEBUG1,
12602 + "PKCS#11: Get certificate failed: %ld:'%s'",
12604 + pkcs11h_getMessage (rv)
12607 + rv = _pkcs11h_session_login (
12615 + login_retry = TRUE;
12620 +#if defined(ENABLE_PKCS11H_THREADING)
12621 + if (mutex_locked) {
12622 + _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.global);
12623 + mutex_locked = FALSE;
12627 + if (rv == CKR_OK) {
12628 + *p_certificate_id = certificate_id;
12629 + certificate_id = NULL;
12632 + if (certificate_id != NULL) {
12633 + pkcs11h_certificate_freeCertificateId (certificate_id);
12634 + certificate_id = NULL;
12637 + if (session != NULL) {
12638 + _pkcs11h_session_release (session);
12643 + PKCS11H_LOG_DEBUG2,
12644 + "PKCS#11: pkcs11h_locateCertificate return rv=%ld-'%s' *p_certificate_id=%p",
12646 + pkcs11h_getMessage (rv),
12647 + (void *)*p_certificate_id
12653 +#endif /* ENABLE_PKCS11H_CERTIFICATE */
12655 +#endif /* ENABLE_PKCS11H_LOCATE */
12657 +#if defined(ENABLE_PKCS11H_ENUM)
12658 +/*======================================================================*
12660 + *======================================================================*/
12662 +#if defined(ENABLE_PKCS11H_TOKEN)
12665 +pkcs11h_token_freeTokenIdList (
12666 + IN const pkcs11h_token_id_list_t token_id_list
12668 + pkcs11h_token_id_list_t _id = token_id_list;
12670 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
12671 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
12672 + /*PKCS11H_ASSERT (token_id_list!=NULL); NOT NEEDED*/
12675 + PKCS11H_LOG_DEBUG2,
12676 + "PKCS#11: pkcs11h_token_freeTokenIdList entry token_id_list=%p",
12677 + (void *)token_id_list
12680 + while (_id != NULL) {
12681 + pkcs11h_token_id_list_t x = _id;
12683 + if (x->token_id != NULL) {
12684 + pkcs11h_token_freeTokenId (x->token_id);
12687 + _pkcs11h_mem_free ((void *)&x);
12691 + PKCS11H_LOG_DEBUG2,
12692 + "PKCS#11: pkcs11h_token_freeTokenIdList return"
12699 +pkcs11h_token_enumTokenIds (
12700 + IN const int method,
12701 + OUT pkcs11h_token_id_list_t * const p_token_id_list
12703 +#if defined(ENABLE_PKCS11H_THREADING)
12704 + PKCS11H_BOOL mutex_locked = FALSE;
12707 + pkcs11h_token_id_list_t token_id_list = NULL;
12708 + pkcs11h_provider_t current_provider;
12709 + CK_RV rv = CKR_OK;
12711 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
12712 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
12713 + PKCS11H_ASSERT (p_token_id_list!=NULL);
12716 + PKCS11H_LOG_DEBUG2,
12717 + "PKCS#11: pkcs11h_token_enumTokenIds entry p_token_id_list=%p",
12718 + (void *)p_token_id_list
12721 + *p_token_id_list = NULL;
12723 +#if defined(ENABLE_PKCS11H_THREADING)
12726 + (rv = _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.global)) == CKR_OK
12728 + mutex_locked = TRUE;
12733 + current_provider = s_pkcs11h_data->providers;
12735 + current_provider != NULL &&
12738 + current_provider = current_provider->next
12740 + CK_SLOT_ID_PTR slots = NULL;
12741 + CK_ULONG slotnum;
12742 + CK_SLOT_ID slot_index;
12744 + if (!current_provider->enabled) {
12745 + rv = CKR_CRYPTOKI_NOT_INITIALIZED;
12748 + if (rv == CKR_OK) {
12749 + rv = _pkcs11h_session_getSlotList (
12750 + current_provider,
12760 + slot_index < slotnum &&
12765 + pkcs11h_token_id_list_t entry = NULL;
12766 + CK_TOKEN_INFO info;
12768 + if (rv == CKR_OK) {
12769 + rv = _pkcs11h_mem_malloc ((void *)&entry, sizeof (struct pkcs11h_token_id_list_s));
12772 + if (rv == CKR_OK) {
12773 + rv = current_provider->f->C_GetTokenInfo (
12774 + slots[slot_index],
12779 + if (rv == CKR_OK) {
12780 + rv = _pkcs11h_token_getTokenId (
12786 + if (rv == CKR_OK) {
12787 + entry->next = token_id_list;
12788 + token_id_list = entry;
12792 + if (entry != NULL) {
12793 + pkcs11h_token_freeTokenIdList (entry);
12798 + if (rv != CKR_OK) {
12800 + PKCS11H_LOG_DEBUG1,
12801 + "PKCS#11: Cannot get slot list for provider '%s' rv=%ld-'%s'",
12802 + current_provider->manufacturerID,
12804 + pkcs11h_getMessage (rv)
12813 + if (slots != NULL) {
12814 + _pkcs11h_mem_free ((void *)&slots);
12819 + if (rv == CKR_OK && method == PKCS11H_ENUM_METHOD_CACHE) {
12820 + pkcs11h_session_t session = NULL;
12823 + session = s_pkcs11h_data->sessions;
12824 + session != NULL && rv == CKR_OK;
12825 + session = session->next
12827 + pkcs11h_token_id_list_t entry = NULL;
12828 + PKCS11H_BOOL found = FALSE;
12831 + entry = token_id_list;
12832 + entry != NULL && !found;
12833 + entry = entry->next
12836 + pkcs11h_token_sameTokenId (
12837 + session->token_id,
12848 + if (rv == CKR_OK) {
12849 + rv = _pkcs11h_mem_malloc (
12851 + sizeof (struct pkcs11h_token_id_list_s)
12855 + if (rv == CKR_OK) {
12856 + rv = pkcs11h_token_duplicateTokenId (
12857 + &entry->token_id,
12858 + session->token_id
12862 + if (rv == CKR_OK) {
12863 + entry->next = token_id_list;
12864 + token_id_list = entry;
12868 + if (entry != NULL) {
12869 + if (entry->token_id != NULL) {
12870 + pkcs11h_token_freeTokenId (entry->token_id);
12872 + _pkcs11h_mem_free ((void *)&entry);
12878 + if (rv == CKR_OK) {
12879 + *p_token_id_list = token_id_list;
12880 + token_id_list = NULL;
12883 + if (token_id_list != NULL) {
12884 + pkcs11h_token_freeTokenIdList (token_id_list);
12885 + token_id_list = NULL;
12888 +#if defined(ENABLE_PKCS11H_THREADING)
12889 + if (mutex_locked) {
12890 + rv = _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.global);
12891 + mutex_locked = FALSE;
12896 + PKCS11H_LOG_DEBUG2,
12897 + "PKCS#11: pkcs11h_token_enumTokenIds return rv=%ld-'%s', *p_token_id_list=%p",
12899 + pkcs11h_getMessage (rv),
12900 + (void *)p_token_id_list
12908 +#if defined(ENABLE_PKCS11H_DATA)
12911 +pkcs11h_data_freeDataIdList (
12912 + IN const pkcs11h_data_id_list_t data_id_list
12914 + pkcs11h_data_id_list_t _id = data_id_list;
12916 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
12917 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
12918 + /*PKCS11H_ASSERT (data_id_list!=NULL); NOT NEEDED*/
12921 + PKCS11H_LOG_DEBUG2,
12922 + "PKCS#11: pkcs11h_freeDataIdList entry token_id_list=%p",
12923 + (void *)data_id_list
12926 + while (_id != NULL) {
12927 + pkcs11h_data_id_list_t x = _id;
12930 + if (x->application != NULL) {
12931 + _pkcs11h_mem_free ((void *)&x->application);
12933 + if (x->label != NULL) {
12934 + _pkcs11h_mem_free ((void *)&x->label);
12936 + _pkcs11h_mem_free ((void *)&x);
12940 + PKCS11H_LOG_DEBUG2,
12941 + "PKCS#11: pkcs11h_token_freeDataIdList return"
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
12955 +#if defined(ENABLE_PKCS11H_THREADING)
12956 + PKCS11H_BOOL mutex_locked = FALSE;
12958 + pkcs11h_session_t session = NULL;
12959 + pkcs11h_data_id_list_t data_id_list = NULL;
12960 + CK_RV rv = CKR_OK;
12962 + PKCS11H_BOOL op_succeed = FALSE;
12963 + PKCS11H_BOOL login_retry = FALSE;
12965 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
12966 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
12967 + PKCS11H_ASSERT (p_data_id_list!=NULL);
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,
12976 + (void *)p_data_id_list
12979 + *p_data_id_list = NULL;
12981 + if (rv == CKR_OK) {
12982 + rv = _pkcs11h_session_getSessionByTokenId (
12988 +#if defined(ENABLE_PKCS11H_THREADING)
12991 + (rv = _pkcs11h_threading_mutexLock (&session->mutex)) == CKR_OK
12993 + mutex_locked = TRUE;
12997 + while (rv == CKR_OK && !op_succeed) {
12999 + CK_OBJECT_CLASS class = CKO_DATA;
13000 + CK_ATTRIBUTE filter[] = {
13001 + {CKA_CLASS, (void *)&class, sizeof (class)}
13003 + CK_OBJECT_HANDLE *objects = NULL;
13004 + CK_ULONG objects_found = 0;
13008 + if (rv == CKR_OK) {
13009 + rv = _pkcs11h_session_validate (session);
13012 + if (rv == CKR_OK) {
13013 + rv = _pkcs11h_session_findObjects (
13016 + sizeof (filter) / sizeof (CK_ATTRIBUTE),
13022 + for (i = 0;rv == CKR_OK && i < objects_found;i++) {
13023 + pkcs11h_data_id_list_t entry = NULL;
13025 + CK_ATTRIBUTE attrs[] = {
13026 + {CKA_APPLICATION, NULL, 0},
13027 + {CKA_LABEL, NULL, 0}
13030 + if (rv == CKR_OK) {
13031 + rv = _pkcs11h_session_getObjectAttributes (
13035 + sizeof (attrs) / sizeof (CK_ATTRIBUTE)
13039 + if (rv == CKR_OK) {
13040 + rv = _pkcs11h_mem_malloc (
13042 + sizeof (struct pkcs11h_data_id_list_s)
13048 + (rv = _pkcs11h_mem_malloc (
13049 + (void *)&entry->application,
13050 + attrs[0].ulValueLen+1
13053 + memmove (entry->application, attrs[0].pValue, attrs[0].ulValueLen);
13054 + entry->application[attrs[0].ulValueLen] = '\0';
13059 + (rv = _pkcs11h_mem_malloc (
13060 + (void *)&entry->label,
13061 + attrs[1].ulValueLen+1
13064 + memmove (entry->label, attrs[1].pValue, attrs[1].ulValueLen);
13065 + entry->label[attrs[1].ulValueLen] = '\0';
13068 + if (rv == CKR_OK) {
13069 + entry->next = data_id_list;
13070 + data_id_list = entry;
13074 + _pkcs11h_session_freeObjectAttributes (
13076 + sizeof (attrs) / sizeof (CK_ATTRIBUTE)
13079 + if (entry != NULL) {
13080 + if (entry->application != NULL) {
13081 + _pkcs11h_mem_free ((void *)&entry->application);
13083 + if (entry->label != NULL) {
13084 + _pkcs11h_mem_free ((void *)&entry->label);
13086 + _pkcs11h_mem_free ((void *)&entry);
13090 + if (objects != NULL) {
13091 + _pkcs11h_mem_free ((void *)&objects);
13094 + if (rv == CKR_OK) {
13095 + op_succeed = TRUE;
13098 + if (!login_retry) {
13100 + PKCS11H_LOG_DEBUG1,
13101 + "PKCS#11: Enumerate data objects failed rv=%ld-'%s'",
13103 + pkcs11h_getMessage (rv)
13105 + login_retry = TRUE;
13106 + rv = _pkcs11h_session_login (
13117 +#if defined(ENABLE_PKCS11H_THREADING)
13118 + if (mutex_locked) {
13119 + _pkcs11h_threading_mutexRelease (&session->mutex);
13120 + mutex_locked = FALSE;
13124 + if (rv == CKR_OK) {
13125 + *p_data_id_list = data_id_list;
13126 + data_id_list = NULL;
13129 + if (session != NULL) {
13130 + _pkcs11h_session_release (session);
13134 + if (data_id_list != NULL) {
13135 + pkcs11h_data_freeDataIdList (data_id_list);
13136 + data_id_list = NULL;
13140 + PKCS11H_LOG_DEBUG2,
13141 + "PKCS#11: pkcs11h_data_enumDataObjects return rv=%ld-'%s', *p_data_id_list=%p",
13143 + pkcs11h_getMessage (rv),
13144 + (void *)*p_data_id_list
13150 +#endif /* ENABLE_PKCS11H_DATA */
13152 +#if defined(ENABLE_PKCS11H_CERTIFICATE)
13156 +_pkcs11h_certificate_enumSessionCertificates (
13157 + IN const pkcs11h_session_t session,
13158 + IN void * const user_data,
13159 + IN const unsigned mask_prompt
13161 +#if defined(ENABLE_PKCS11H_THREADING)
13162 + PKCS11H_BOOL mutex_locked = FALSE;
13164 + PKCS11H_BOOL op_succeed = FALSE;
13165 + PKCS11H_BOOL login_retry = FALSE;
13167 + CK_RV rv = CKR_OK;
13169 + PKCS11H_ASSERT (session!=NULL);
13170 + /*PKCS11H_ASSERT (user_data) NOT NEEDED */
13173 + PKCS11H_LOG_DEBUG2,
13174 + "PKCS#11: _pkcs11h_certificate_enumSessionCertificates entry session=%p, user_data=%p, mask_prompt=%08x",
13180 + /* THREADS: NO NEED TO LOCK, GLOBAL CACHE IS LOCKED */
13181 +#if defined(ENABLE_PKCS11H_THREADING)
13184 + (rv = _pkcs11h_threading_mutexLock (&session->mutex)) == CKR_OK
13186 + mutex_locked = TRUE;
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)}
13196 + CK_OBJECT_HANDLE *objects = NULL;
13197 + CK_ULONG objects_found = 0;
13201 + if (rv == CKR_OK) {
13202 + rv = _pkcs11h_session_validate (session);
13205 + if (rv == CKR_OK) {
13206 + rv = _pkcs11h_session_findObjects (
13209 + sizeof (cert_filter) / sizeof (CK_ATTRIBUTE),
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;
13219 + CK_ATTRIBUTE attrs[] = {
13220 + {CKA_ID, NULL, 0},
13221 + {CKA_VALUE, NULL, 0}
13224 + if (rv == CKR_OK) {
13225 + rv = _pkcs11h_session_getObjectAttributes (
13229 + sizeof (attrs) / sizeof (CK_ATTRIBUTE)
13235 + (rv = _pkcs11h_certificate_newCertificateId (&certificate_id)) == CKR_OK
13237 + rv = pkcs11h_token_duplicateTokenId (
13238 + &certificate_id->token_id,
13239 + session->token_id
13243 + if (rv == CKR_OK) {
13244 + rv = _pkcs11h_mem_duplicate (
13245 + (void*)&certificate_id->attrCKA_ID,
13246 + &certificate_id->attrCKA_ID_size,
13248 + attrs[0].ulValueLen
13252 + if (rv == CKR_OK) {
13253 + rv = _pkcs11h_mem_duplicate (
13254 + (void*)&certificate_id->certificate_blob,
13255 + &certificate_id->certificate_blob_size,
13257 + attrs[1].ulValueLen
13261 + if (rv == CKR_OK) {
13262 + rv = _pkcs11h_certificate_updateCertificateIdDescription (certificate_id);
13267 + (rv = _pkcs11h_mem_malloc (
13268 + (void *)&new_element,
13269 + sizeof (struct pkcs11h_certificate_id_list_s)
13272 + new_element->next = session->cached_certs;
13273 + new_element->certificate_id = certificate_id;
13274 + certificate_id = NULL;
13276 + session->cached_certs = new_element;
13277 + new_element = NULL;
13280 + if (certificate_id != NULL) {
13281 + pkcs11h_certificate_freeCertificateId (certificate_id);
13282 + certificate_id = NULL;
13285 + if (new_element != NULL) {
13286 + _pkcs11h_mem_free ((void *)&new_element);
13287 + new_element = NULL;
13290 + _pkcs11h_session_freeObjectAttributes (
13292 + sizeof (attrs) / sizeof (CK_ATTRIBUTE)
13295 + if (rv != CKR_OK) {
13297 + PKCS11H_LOG_DEBUG1,
13298 + "PKCS#11: Cannot get object attribute for provider '%s' object %ld rv=%ld-'%s'",
13299 + session->provider->manufacturerID,
13302 + pkcs11h_getMessage (rv)
13312 + if (objects != NULL) {
13313 + _pkcs11h_mem_free ((void *)&objects);
13316 + if (rv == CKR_OK) {
13317 + op_succeed = TRUE;
13320 + if (!login_retry) {
13322 + PKCS11H_LOG_DEBUG1,
13323 + "PKCS#11: Get certificate attributes failed: %ld:'%s'",
13325 + pkcs11h_getMessage (rv)
13328 + rv = _pkcs11h_session_login (
13333 + (mask_prompt & PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT)
13336 + login_retry = TRUE;
13341 +#if defined(ENABLE_PKCS11H_THREADING)
13342 + if (mutex_locked) {
13343 + _pkcs11h_threading_mutexRelease (&session->mutex);
13344 + mutex_locked = FALSE;
13349 + PKCS11H_LOG_DEBUG2,
13350 + "PKCS#11: _pkcs11h_certificate_enumSessionCertificates return rv=%ld-'%s'",
13352 + pkcs11h_getMessage (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
13365 + typedef struct info_s {
13366 + struct info_s *next;
13367 + pkcs11h_certificate_id_t e;
13368 +#if defined(USE_PKCS11H_OPENSSL)
13370 +#elif defined(USE_PKCS11H_GNUTLS)
13371 + gnutls_x509_crt_t cert;
13373 + PKCS11H_BOOL is_issuer;
13376 + pkcs11h_certificate_id_list_t cert_id_issuers_list = NULL;
13377 + pkcs11h_certificate_id_list_t cert_id_end_list = NULL;
13379 + info_t head = NULL;
13380 + info_t info = NULL;
13382 + CK_RV rv = CKR_OK;
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);
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
13396 + if (p_cert_id_issuers_list != NULL) {
13397 + *p_cert_id_issuers_list = NULL;
13399 + *p_cert_id_end_list = NULL;
13401 + if (rv == CKR_OK) {
13402 + pkcs11h_certificate_id_list_t entry = NULL;
13405 + entry = cert_id_all;
13406 + entry != NULL && rv == CKR_OK;
13407 + entry = entry->next
13409 + info_t new_info = NULL;
13413 + (rv = _pkcs11h_mem_malloc ((void *)&new_info, sizeof (struct info_s))) == CKR_OK &&
13414 + entry->certificate_id->certificate_blob != NULL
13416 +#if defined(USE_PKCS11H_OPENSSL)
13417 + pkcs11_openssl_d2i_t d2i = (pkcs11_openssl_d2i_t)entry->certificate_id->certificate_blob;
13420 + new_info->next = head;
13421 + new_info->e = entry->certificate_id;
13422 +#if defined(USE_PKCS11H_OPENSSL)
13423 + new_info->x509 = X509_new ();
13425 + new_info->x509 != NULL &&
13429 + entry->certificate_id->certificate_blob_size
13432 + X509_free (new_info->x509);
13433 + new_info->x509 = NULL;
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;
13441 + gnutls_datum_t datum = {
13442 + entry->certificate_id->certificate_blob,
13443 + entry->certificate_id->certificate_blob_size
13447 + gnutls_x509_crt_import (
13450 + GNUTLS_X509_FMT_DER
13451 + ) != GNUTLS_E_SUCCESS
13453 + gnutls_x509_crt_deinit (new_info->cert);
13454 + new_info->cert = NULL;
13458 +#error Invalid configuration.
13467 + if (rv == CKR_OK) {
13471 + info = info->next
13473 + info_t info2 = NULL;
13474 +#if defined(USE_PKCS11H_OPENSSL)
13475 + EVP_PKEY *pub = X509_get_pubkey (info->x509);
13480 + info2 != NULL && !info->is_issuer;
13481 + info2 = info2->next
13483 + if (info != info2) {
13484 +#if defined(USE_PKCS11H_OPENSSL)
13486 + info->x509 != NULL &&
13487 + info2->x509 != NULL &&
13489 + X509_get_subject_name (info->x509),
13490 + X509_get_issuer_name (info2->x509)
13492 + X509_verify (info2->x509, pub) == 1
13494 + info->is_issuer = TRUE;
13496 +#elif defined(USE_PKCS11H_GNUTLS)
13500 + info->cert != NULL &&
13501 + info2->cert != NULL &&
13502 + gnutls_x509_crt_verify (
13509 + (result & GNUTLS_CERT_INVALID) == 0
13511 + info->is_issuer = TRUE;
13514 +#error Invalid configuration.
13520 +#if defined(USE_PKCS11H_OPENSSL)
13521 + if (pub != NULL) {
13522 + EVP_PKEY_free (pub);
13529 + if (rv == CKR_OK) {
13532 + info != NULL && rv == CKR_OK;
13533 + info = info->next
13535 + pkcs11h_certificate_id_list_t new_entry = NULL;
13537 + if (rv == CKR_OK) {
13538 + rv = _pkcs11h_mem_malloc (
13539 + (void *)&new_entry,
13540 + sizeof (struct pkcs11h_certificate_id_list_s)
13546 + (rv = pkcs11h_certificate_duplicateCertificateId (
13547 + &new_entry->certificate_id,
13552 + * Should not free base list
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;
13564 + new_entry->next = cert_id_end_list;
13565 + cert_id_end_list = new_entry;
13566 + new_entry = NULL;
13570 + if (new_entry != NULL) {
13571 + if (new_entry->certificate_id != NULL) {
13572 + pkcs11h_certificate_freeCertificateId (new_entry->certificate_id);
13574 + _pkcs11h_mem_free ((void *)&new_entry);
13579 + if (rv == CKR_OK) {
13580 + while (head != NULL) {
13581 + info_t entry = head;
13582 + head = head->next;
13584 +#if defined(USE_PKCS11H_OPENSSL)
13585 + if (entry->x509 != NULL) {
13586 + X509_free (entry->x509);
13587 + entry->x509 = NULL;
13589 +#elif defined(USE_PKCS11H_GNUTLS)
13590 + if (entry->cert != NULL) {
13591 + gnutls_x509_crt_deinit (entry->cert);
13592 + entry->cert = NULL;
13595 +#error Invalid configuration.
13598 + _pkcs11h_mem_free ((void *)&entry);
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;
13607 + if (rv == CKR_OK) {
13608 + *p_cert_id_end_list = cert_id_end_list;
13609 + cert_id_end_list = NULL;
13612 + if (cert_id_issuers_list != NULL) {
13613 + pkcs11h_certificate_freeCertificateIdList (cert_id_issuers_list);
13616 + if (cert_id_end_list != NULL) {
13617 + pkcs11h_certificate_freeCertificateIdList (cert_id_end_list);
13621 + PKCS11H_LOG_DEBUG2,
13622 + "PKCS#11: _pkcs11h_certificate_splitCertificateIdList return rv=%ld-'%s'",
13624 + pkcs11h_getMessage (rv)
13631 +pkcs11h_certificate_freeCertificateIdList (
13632 + IN const pkcs11h_certificate_id_list_t cert_id_list
13634 + pkcs11h_certificate_id_list_t _id = cert_id_list;
13636 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
13637 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
13638 + /*PKCS11H_ASSERT (cert_id_list!=NULL); NOT NEEDED*/
13641 + PKCS11H_LOG_DEBUG2,
13642 + "PKCS#11: pkcs11h_certificate_freeCertificateIdList entry cert_id_list=%p",
13643 + (void *)cert_id_list
13646 + while (_id != NULL) {
13647 + pkcs11h_certificate_id_list_t x = _id;
13649 + if (x->certificate_id != NULL) {
13650 + pkcs11h_certificate_freeCertificateId (x->certificate_id);
13653 + _pkcs11h_mem_free ((void *)&x);
13657 + PKCS11H_LOG_DEBUG2,
13658 + "PKCS#11: pkcs11h_certificate_freeCertificateIdList return"
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
13673 +#if defined(ENABLE_PKCS11H_THREADING)
13674 + PKCS11H_BOOL mutex_locked = FALSE;
13676 + pkcs11h_session_t session = NULL;
13677 + CK_RV rv = CKR_OK;
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);
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,
13693 + (void *)p_cert_id_issuers_list,
13694 + (void *)p_cert_id_end_list
13697 + if (p_cert_id_issuers_list != NULL) {
13698 + *p_cert_id_issuers_list = NULL;
13700 + *p_cert_id_end_list = NULL;
13702 +#if defined(ENABLE_PKCS11H_THREADING)
13705 + (rv = _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.cache)) == CKR_OK
13707 + mutex_locked = TRUE;
13713 + (rv = _pkcs11h_session_getSessionByTokenId (
13718 + if (method == PKCS11H_ENUM_METHOD_RELOAD) {
13719 + pkcs11h_certificate_freeCertificateIdList (session->cached_certs);
13720 + session->cached_certs = NULL;
13723 + if (session->cached_certs == NULL) {
13724 + rv = _pkcs11h_certificate_enumSessionCertificates (session, user_data, mask_prompt);
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
13736 + if (session != NULL) {
13737 + _pkcs11h_session_release (session);
13740 +#if defined(ENABLE_PKCS11H_THREADING)
13741 + if (mutex_locked) {
13742 + _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.cache);
13743 + mutex_locked = FALSE;
13748 + PKCS11H_LOG_DEBUG2,
13749 + "PKCS#11: pkcs11h_certificate_enumTokenCertificateIds return rv=%ld-'%s'",
13751 + pkcs11h_getMessage (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
13765 +#if defined(ENABLE_PKCS11H_THREADING)
13766 + PKCS11H_BOOL mutex_locked = FALSE;
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;
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);
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",
13784 + (void *)p_cert_id_issuers_list,
13785 + (void *)p_cert_id_end_list
13788 + if (p_cert_id_issuers_list != NULL) {
13789 + *p_cert_id_issuers_list = NULL;
13791 + *p_cert_id_end_list = NULL;
13793 +#if defined(ENABLE_PKCS11H_THREADING)
13796 + (rv = _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.cache)) == CKR_OK
13798 + mutex_locked = TRUE;
13803 + current_session = s_pkcs11h_data->sessions;
13804 + current_session != NULL;
13805 + current_session = current_session->next
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;
13815 + current_provider = s_pkcs11h_data->providers;
13817 + current_provider != NULL &&
13820 + current_provider = current_provider->next
13822 + CK_SLOT_ID_PTR slots = NULL;
13823 + CK_ULONG slotnum;
13824 + CK_SLOT_ID slot_index;
13826 + if (!current_provider->enabled) {
13827 + rv = CKR_CRYPTOKI_NOT_INITIALIZED;
13830 + if (rv == CKR_OK) {
13831 + rv = _pkcs11h_session_getSlotList (
13832 + current_provider,
13842 + slot_index < slotnum &&
13847 + pkcs11h_session_t session = NULL;
13848 + pkcs11h_token_id_t token_id = NULL;
13849 + CK_TOKEN_INFO info;
13851 + if (rv == CKR_OK) {
13852 + rv = current_provider->f->C_GetTokenInfo (
13853 + slots[slot_index],
13860 + (rv = _pkcs11h_token_getTokenId (
13864 + (rv = _pkcs11h_session_getSessionByTokenId (
13869 + session->touch = TRUE;
13871 + if (session->cached_certs == NULL) {
13872 + rv = _pkcs11h_certificate_enumSessionCertificates (session, user_data, mask_prompt);
13876 + if (rv != CKR_OK) {
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],
13883 + pkcs11h_getMessage (rv)
13892 + if (session != NULL) {
13893 + _pkcs11h_session_release (session);
13897 + if (token_id != NULL) {
13898 + pkcs11h_token_freeTokenId (token_id);
13903 + if (rv != CKR_OK) {
13905 + PKCS11H_LOG_DEBUG1,
13906 + "PKCS#11: Cannot get slot list for provider '%s' rv=%ld-'%s'",
13907 + current_provider->manufacturerID,
13909 + pkcs11h_getMessage (rv)
13918 + if (slots != NULL) {
13919 + _pkcs11h_mem_free ((void *)&slots);
13925 + current_session = s_pkcs11h_data->sessions;
13927 + current_session != NULL &&
13930 + current_session = current_session->next
13933 + method == PKCS11H_ENUM_METHOD_CACHE ||
13936 + method == PKCS11H_ENUM_METHOD_RELOAD ||
13937 + method == PKCS11H_ENUM_METHOD_CACHE_EXIST
13939 + current_session->touch
13942 + pkcs11h_certificate_id_list_t entry = NULL;
13945 + entry = current_session->cached_certs;
13950 + entry = entry->next
13952 + pkcs11h_certificate_id_list_t new_entry = NULL;
13956 + (rv = _pkcs11h_mem_malloc (
13957 + (void *)&new_entry,
13958 + sizeof (struct pkcs11h_certificate_id_list_s)
13960 + (rv = pkcs11h_certificate_duplicateCertificateId (
13961 + &new_entry->certificate_id,
13962 + entry->certificate_id
13965 + new_entry->next = cert_id_list;
13966 + cert_id_list = new_entry;
13967 + new_entry = NULL;
13970 + if (new_entry != NULL) {
13971 + new_entry->next = NULL;
13972 + pkcs11h_certificate_freeCertificateIdList (new_entry);
13973 + new_entry = NULL;
13979 + if (rv == CKR_OK) {
13980 + rv = _pkcs11h_certificate_splitCertificateIdList (
13982 + p_cert_id_issuers_list,
13983 + p_cert_id_end_list
13987 + if (cert_id_list != NULL) {
13988 + pkcs11h_certificate_freeCertificateIdList (cert_id_list);
13989 + cert_id_list = NULL;
13993 +#if defined(ENABLE_PKCS11H_THREADING)
13994 + if (mutex_locked) {
13995 + _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.cache);
13996 + mutex_locked = FALSE;
14001 + PKCS11H_LOG_DEBUG2,
14002 + "PKCS#11: pkcs11h_certificate_enumCertificateIds return rv=%ld-'%s'",
14004 + pkcs11h_getMessage (rv)
14010 +#endif /* ENABLE_PKCS11H_CERTIFICATE */
14012 +#endif /* ENABLE_PKCS11H_ENUM */
14014 +#if defined(ENABLE_PKCS11H_SLOTEVENT)
14015 +/*======================================================================*
14016 + * SLOTEVENT INTERFACE
14017 + *======================================================================*/
14021 +_pkcs11h_slotevent_checksum (
14022 + IN const unsigned char * const p,
14023 + IN const size_t s
14025 + unsigned long r = 0;
14027 + for (i=0;i<s;i++) {
14035 +_pkcs11h_slotevent_provider (
14038 + pkcs11h_provider_t provider = (pkcs11h_provider_t)p;
14040 + CK_RV rv = CKR_OK;
14043 + PKCS11H_LOG_DEBUG2,
14044 + "PKCS#11: _pkcs11h_slotevent_provider provider='%s' entry",
14045 + provider->manufacturerID
14048 + if (rv == CKR_OK && !provider->enabled) {
14049 + rv = CKR_OPERATION_NOT_INITIALIZED;
14052 + if (rv == CKR_OK) {
14054 + if (provider->slot_poll_interval == 0) {
14055 + provider->slot_poll_interval = PKCS11H_DEFAULT_SLOTEVENT_POLL;
14059 + * If we cannot finalize, we cannot cause
14060 + * WaitForSlotEvent to terminate
14062 + if (!provider->should_finalize) {
14064 + PKCS11H_LOG_DEBUG1,
14065 + "PKCS#11: Setup slotevent provider='%s' mode hardset to poll",
14066 + provider->manufacturerID
14068 + provider->slot_event_method = PKCS11H_SLOTEVENT_METHOD_POLL;
14072 + provider->slot_event_method == PKCS11H_SLOTEVENT_METHOD_AUTO ||
14073 + provider->slot_event_method == PKCS11H_SLOTEVENT_METHOD_TRIGGER
14076 + provider->f->C_WaitForSlotEvent (
14080 + ) == CKR_FUNCTION_NOT_SUPPORTED
14083 + PKCS11H_LOG_DEBUG1,
14084 + "PKCS#11: Setup slotevent provider='%s' mode is poll",
14085 + provider->manufacturerID
14088 + provider->slot_event_method = PKCS11H_SLOTEVENT_METHOD_POLL;
14092 + PKCS11H_LOG_DEBUG1,
14093 + "PKCS#11: Setup slotevent provider='%s' mode is trigger",
14094 + provider->manufacturerID
14097 + provider->slot_event_method = PKCS11H_SLOTEVENT_METHOD_TRIGGER;
14102 + if (provider->slot_event_method == PKCS11H_SLOTEVENT_METHOD_TRIGGER) {
14104 + !s_pkcs11h_data->slotevent.should_terminate &&
14105 + provider->enabled &&
14107 + (rv = provider->f->C_WaitForSlotEvent (
14114 + PKCS11H_LOG_DEBUG1,
14115 + "PKCS#11: Slotevent provider='%s' event",
14116 + provider->manufacturerID
14119 + _pkcs11h_threading_condSignal (&s_pkcs11h_data->slotevent.cond_event);
14123 + unsigned long ulLastChecksum = 0;
14124 + PKCS11H_BOOL is_first_time = TRUE;
14127 + !s_pkcs11h_data->slotevent.should_terminate &&
14128 + provider->enabled &&
14131 + unsigned long ulCurrentChecksum = 0;
14133 + CK_SLOT_ID_PTR slots = NULL;
14134 + CK_ULONG slotnum;
14137 + PKCS11H_LOG_DEBUG1,
14138 + "PKCS#11: Slotevent provider='%s' poll",
14139 + provider->manufacturerID
14144 + (rv = _pkcs11h_session_getSlotList (
14153 + for (i=0;i<slotnum;i++) {
14154 + CK_TOKEN_INFO info;
14156 + if (provider->f->C_GetTokenInfo (slots[i], &info) == CKR_OK) {
14157 + ulCurrentChecksum += (
14158 + _pkcs11h_slotevent_checksum (
14160 + sizeof (info.label)
14162 + _pkcs11h_slotevent_checksum (
14163 + info.manufacturerID,
14164 + sizeof (info.manufacturerID)
14166 + _pkcs11h_slotevent_checksum (
14168 + sizeof (info.model)
14170 + _pkcs11h_slotevent_checksum (
14171 + info.serialNumber,
14172 + sizeof (info.serialNumber)
14179 + if (rv == CKR_OK) {
14180 + if (is_first_time) {
14181 + is_first_time = FALSE;
14184 + if (ulLastChecksum != ulCurrentChecksum) {
14186 + PKCS11H_LOG_DEBUG1,
14187 + "PKCS#11: Slotevent provider='%s' event",
14188 + provider->manufacturerID
14191 + _pkcs11h_threading_condSignal (&s_pkcs11h_data->slotevent.cond_event);
14194 + ulLastChecksum = ulCurrentChecksum;
14197 + if (slots != NULL) {
14198 + _pkcs11h_mem_free ((void *)&slots);
14201 + if (!s_pkcs11h_data->slotevent.should_terminate) {
14202 + _pkcs11h_threading_sleep (provider->slot_poll_interval);
14208 + PKCS11H_LOG_DEBUG2,
14209 + "PKCS#11: _pkcs11h_slotevent_provider provider='%s' return",
14210 + provider->manufacturerID
14218 +_pkcs11h_slotevent_manager (
14221 + PKCS11H_BOOL first_time = TRUE;
14226 + PKCS11H_LOG_DEBUG2,
14227 + "PKCS#11: _pkcs11h_slotevent_manager entry"
14231 + * Trigger hook, so application may
14232 + * depend on initial slot change
14235 + PKCS11H_LOG_DEBUG1,
14236 + "PKCS#11: Calling slotevent hook"
14238 + s_pkcs11h_data->hooks.slotevent (s_pkcs11h_data->hooks.slotevent_data);
14241 + first_time || /* Must enter wait or mutex will never be free */
14242 + !s_pkcs11h_data->slotevent.should_terminate
14244 + pkcs11h_provider_t current_provider;
14246 + first_time = FALSE;
14249 + * Start each provider thread
14250 + * if not already started.
14251 + * This is required in order to allow
14252 + * adding new providers.
14255 + current_provider = s_pkcs11h_data->providers;
14256 + current_provider != NULL;
14257 + current_provider = current_provider->next
14259 + if (!current_provider->enabled) {
14260 + if (current_provider->slotevent_thread == PKCS11H_THREAD_NULL) {
14261 + _pkcs11h_threading_threadStart (
14262 + ¤t_provider->slotevent_thread,
14263 + _pkcs11h_slotevent_provider,
14269 + if (current_provider->slotevent_thread != PKCS11H_THREAD_NULL) {
14270 + _pkcs11h_threading_threadJoin (¤t_provider->slotevent_thread);
14276 + PKCS11H_LOG_DEBUG2,
14277 + "PKCS#11: _pkcs11h_slotevent_manager waiting for slotevent"
14279 + _pkcs11h_threading_condWait (&s_pkcs11h_data->slotevent.cond_event, PKCS11H_COND_INFINITE);
14281 + if (s_pkcs11h_data->slotevent.skip_event) {
14283 + PKCS11H_LOG_DEBUG1,
14284 + "PKCS#11: Slotevent skipping event"
14286 + s_pkcs11h_data->slotevent.skip_event = FALSE;
14290 + PKCS11H_LOG_DEBUG1,
14291 + "PKCS#11: Calling slotevent hook"
14293 + s_pkcs11h_data->hooks.slotevent (s_pkcs11h_data->hooks.slotevent_data);
14298 + pkcs11h_provider_t current_provider;
14301 + PKCS11H_LOG_DEBUG2,
14302 + "PKCS#11: _pkcs11h_slotevent_manager joining threads"
14307 + current_provider = s_pkcs11h_data->providers;
14308 + current_provider != NULL;
14309 + current_provider = current_provider->next
14311 + if (current_provider->slotevent_thread != PKCS11H_THREAD_NULL) {
14312 + _pkcs11h_threading_threadJoin (¤t_provider->slotevent_thread);
14318 + PKCS11H_LOG_DEBUG2,
14319 + "PKCS#11: _pkcs11h_slotevent_manager return"
14327 +_pkcs11h_slotevent_init () {
14328 + CK_RV rv = CKR_OK;
14331 + PKCS11H_LOG_DEBUG2,
14332 + "PKCS#11: _pkcs11h_slotevent_init entry"
14335 + if (!s_pkcs11h_data->slotevent.initialized) {
14336 + if (rv == CKR_OK) {
14337 + rv = _pkcs11h_threading_condInit (&s_pkcs11h_data->slotevent.cond_event);
14340 + if (rv == CKR_OK) {
14341 + rv = _pkcs11h_threading_threadStart (
14342 + &s_pkcs11h_data->slotevent.thread,
14343 + _pkcs11h_slotevent_manager,
14348 + if (rv == CKR_OK) {
14349 + s_pkcs11h_data->slotevent.initialized = TRUE;
14354 + PKCS11H_LOG_DEBUG2,
14355 + "PKCS#11: _pkcs11h_slotevent_init return rv=%ld-'%s'",
14357 + pkcs11h_getMessage (rv)
14365 +_pkcs11h_slotevent_notify () {
14368 + PKCS11H_LOG_DEBUG2,
14369 + "PKCS#11: _pkcs11h_slotevent_notify entry"
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);
14378 + PKCS11H_LOG_DEBUG2,
14379 + "PKCS#11: _pkcs11h_slotevent_notify return"
14387 +_pkcs11h_slotevent_terminate () {
14390 + PKCS11H_LOG_DEBUG2,
14391 + "PKCS#11: _pkcs11h_slotevent_terminate entry"
14394 + if (s_pkcs11h_data->slotevent.initialized) {
14395 + s_pkcs11h_data->slotevent.should_terminate = TRUE;
14397 + _pkcs11h_slotevent_notify ();
14399 + if (s_pkcs11h_data->slotevent.thread != PKCS11H_THREAD_NULL) {
14400 + _pkcs11h_threading_threadJoin (&s_pkcs11h_data->slotevent.thread);
14403 + _pkcs11h_threading_condFree (&s_pkcs11h_data->slotevent.cond_event);
14404 + s_pkcs11h_data->slotevent.initialized = FALSE;
14408 + PKCS11H_LOG_DEBUG2,
14409 + "PKCS#11: _pkcs11h_slotevent_terminate return"
14417 +#if defined(ENABLE_PKCS11H_OPENSSL)
14418 +/*======================================================================*
14419 + * OPENSSL INTERFACE
14420 + *======================================================================*/
14423 +pkcs11h_openssl_session_t
14424 +_pkcs11h_openssl_get_openssl_session (
14425 + IN OUT const RSA *rsa
14427 + pkcs11h_openssl_session_t session;
14429 + PKCS11H_ASSERT (rsa!=NULL);
14430 +#if OPENSSL_VERSION_NUMBER < 0x00907000L
14431 + session = (pkcs11h_openssl_session_t)RSA_get_app_data ((RSA *)rsa);
14433 + session = (pkcs11h_openssl_session_t)RSA_get_app_data (rsa);
14435 + PKCS11H_ASSERT (session!=NULL);
14441 +pkcs11h_certificate_t
14442 +_pkcs11h_openssl_get_pkcs11h_certificate (
14443 + IN OUT const RSA *rsa
14445 + pkcs11h_openssl_session_t session = _pkcs11h_openssl_get_openssl_session (rsa);
14447 + PKCS11H_ASSERT (session!=NULL);
14448 + PKCS11H_ASSERT (session->certificate!=NULL);
14450 + return session->certificate;
14453 +#if OPENSSL_VERSION_NUMBER < 0x00907000L
14456 +_pkcs11h_openssl_dec (
14458 + IN unsigned char *from,
14459 + OUT unsigned char *to,
14466 +_pkcs11h_openssl_dec (
14468 + IN const unsigned char *from,
14469 + OUT unsigned char *to,
14474 + PKCS11H_ASSERT (from!=NULL);
14475 + PKCS11H_ASSERT (to!=NULL);
14476 + PKCS11H_ASSERT (rsa!=NULL);
14479 + PKCS11H_LOG_DEBUG2,
14480 + "PKCS#11: _pkcs11h_openssl_dec entered - flen=%d, from=%p, to=%p, rsa=%p, padding=%d",
14489 + PKCS11H_LOG_ERROR,
14490 + "PKCS#11: Private key decryption is not supported"
14494 + PKCS11H_LOG_DEBUG2,
14495 + "PKCS#11: _pkcs11h_openssl_dec return"
14501 +#if OPENSSL_VERSION_NUMBER < 0x00907000L
14504 +_pkcs11h_openssl_sign (
14506 + IN unsigned char *m,
14507 + IN unsigned int m_len,
14508 + OUT unsigned char *sigret,
14509 + OUT unsigned int *siglen,
14515 +_pkcs11h_openssl_sign (
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
14524 + pkcs11h_certificate_t certificate = _pkcs11h_openssl_get_pkcs11h_certificate (rsa);
14525 + PKCS11H_BOOL session_locked = FALSE;
14526 + CK_RV rv = CKR_OK;
14528 + int myrsa_size = 0;
14530 + unsigned char *enc_alloc = NULL;
14531 + unsigned char *enc = NULL;
14534 + PKCS11H_ASSERT (m!=NULL);
14535 + PKCS11H_ASSERT (sigret!=NULL);
14536 + PKCS11H_ASSERT (siglen!=NULL);
14539 + PKCS11H_LOG_DEBUG2,
14540 + "PKCS#11: _pkcs11h_openssl_sign entered - type=%d, m=%p, m_len=%u, signret=%p, *signlen=%u, rsa=%p",
14545 + sigret != NULL ? *siglen : 0,
14549 + if (rv == CKR_OK) {
14550 + myrsa_size=RSA_size(rsa);
14553 + if (type == NID_md5_sha1) {
14554 + if (rv == CKR_OK) {
14555 + enc = (unsigned char *)m;
14561 + ASN1_TYPE parameter;
14562 + X509_ALGOR algor;
14563 + ASN1_OCTET_STRING digest;
14564 + unsigned char *p = NULL;
14568 + (rv = _pkcs11h_mem_malloc ((void*)&enc, myrsa_size+1)) == CKR_OK
14573 + if (rv == CKR_OK) {
14574 + sig.algor = &algor;
14579 + (sig.algor->algorithm = OBJ_nid2obj (type)) == NULL
14581 + rv = CKR_FUNCTION_FAILED;
14586 + sig.algor->algorithm->length == 0
14588 + rv = CKR_KEY_SIZE_RANGE;
14591 + if (rv == CKR_OK) {
14592 + parameter.type = V_ASN1_NULL;
14593 + parameter.value.ptr = NULL;
14595 + sig.algor->parameter = ¶meter;
14597 + sig.digest = &digest;
14598 + sig.digest->data = (unsigned char *)m;
14599 + sig.digest->length = m_len;
14604 + (enc_len=i2d_X509_SIG (&sig, NULL)) < 0
14606 + rv = CKR_FUNCTION_FAILED;
14610 + * d_X509_SIG increments pointer!
14616 + (enc_len=i2d_X509_SIG (&sig, &p)) < 0
14618 + rv = CKR_FUNCTION_FAILED;
14624 + enc_len > (myrsa_size-RSA_PKCS1_PADDING_SIZE)
14626 + rv = CKR_KEY_SIZE_RANGE;
14631 + (rv = pkcs11h_certificate_lockSession (certificate)) == CKR_OK
14633 + session_locked = TRUE;
14636 + if (rv == CKR_OK) {
14638 + PKCS11H_LOG_DEBUG1,
14639 + "PKCS#11: Performing signature"
14642 + *siglen = myrsa_size;
14645 + (rv = pkcs11h_certificate_signAny (
14654 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11h_getMessage (rv));
14658 + if (session_locked) {
14659 + pkcs11h_certificate_releaseSession (certificate);
14660 + session_locked = FALSE;
14663 + if (enc_alloc != NULL) {
14664 + _pkcs11h_mem_free ((void *)&enc_alloc);
14668 + PKCS11H_LOG_DEBUG2,
14669 + "PKCS#11: _pkcs11h_openssl_sign - return rv=%ld-'%s'",
14671 + pkcs11h_getMessage (rv)
14674 + return rv == CKR_OK ? 1 : -1;
14679 +_pkcs11h_openssl_finish (
14682 + pkcs11h_openssl_session_t openssl_session = _pkcs11h_openssl_get_openssl_session (rsa);
14685 + PKCS11H_LOG_DEBUG2,
14686 + "PKCS#11: _pkcs11h_openssl_finish - entered rsa=%p",
14690 + RSA_set_app_data (rsa, NULL);
14692 + if (openssl_session->orig_finish != NULL) {
14693 + openssl_session->orig_finish (rsa);
14695 +#ifdef BROKEN_OPENSSL_ENGINE
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
14703 + ENGINE *e = rsa->engine;
14704 + rsa->engine = NULL;
14706 + ENGINE_finish(e);
14712 + pkcs11h_openssl_freeSession (openssl_session);
14715 + PKCS11H_LOG_DEBUG2,
14716 + "PKCS#11: _pkcs11h_openssl_finish - return"
14723 +pkcs11h_openssl_getX509 (
14724 + IN const pkcs11h_certificate_t certificate
14726 + unsigned char *certificate_blob = NULL;
14727 + size_t certificate_blob_size = 0;
14728 + X509 *x509 = NULL;
14729 + CK_RV rv = CKR_OK;
14731 + pkcs11_openssl_d2i_t d2i1 = NULL;
14732 + PKCS11H_BOOL ok = TRUE;
14734 + PKCS11H_ASSERT (certificate!=NULL);
14737 + PKCS11H_LOG_DEBUG2,
14738 + "PKCS#11: pkcs11h_openssl_getX509 - entry certificate=%p",
14739 + (void *)certificate
14744 + (x509 = X509_new ()) == NULL
14747 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Unable to allocate certificate object");
14752 + pkcs11h_certificate_getCertificateBlob (
14755 + &certificate_blob_size
14759 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot read X.509 certificate from token %ld-'%s'", rv, pkcs11h_getMessage (rv));
14764 + (rv = _pkcs11h_mem_malloc ((void *)&certificate_blob, certificate_blob_size)) != CKR_OK
14767 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot allocate X.509 memory %ld-'%s'", rv, pkcs11h_getMessage (rv));
14772 + pkcs11h_certificate_getCertificateBlob (
14774 + certificate_blob,
14775 + &certificate_blob_size
14779 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot read X.509 certificate from token %ld-'%s'", rv, pkcs11h_getMessage (rv));
14782 + d2i1 = (pkcs11_openssl_d2i_t)certificate_blob;
14785 + !d2i_X509 (&x509, &d2i1, certificate_blob_size)
14788 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Unable to parse X.509 certificate");
14792 + X509_free (x509);
14797 + PKCS11H_LOG_DEBUG2,
14798 + "PKCS#11: pkcs11h_openssl_getX509 - return x509=%p",
14805 +pkcs11h_openssl_session_t
14806 +pkcs11h_openssl_createSession (
14807 + IN const pkcs11h_certificate_t certificate
14809 + pkcs11h_openssl_session_t openssl_session = NULL;
14810 + PKCS11H_BOOL ok = TRUE;
14813 + PKCS11H_LOG_DEBUG2,
14814 + "PKCS#11: pkcs11h_openssl_createSession - entry"
14819 + _pkcs11h_mem_malloc (
14820 + (void*)&openssl_session,
14821 + sizeof (struct pkcs11h_openssl_session_s)) != CKR_OK
14824 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot allocate memory");
14828 + const RSA_METHOD *def = RSA_get_default_method();
14830 + memmove (&openssl_session->smart_rsa, def, sizeof(RSA_METHOD));
14832 + openssl_session->orig_finish = def->finish;
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;
14844 + _pkcs11h_mem_free ((void *)&openssl_session);
14848 + PKCS11H_LOG_DEBUG2,
14849 + "PKCS#11: pkcs11h_openssl_createSession - return openssl_session=%p",
14850 + (void *)openssl_session
14853 + return openssl_session;
14856 +pkcs11h_hook_openssl_cleanup_t
14857 +pkcs11h_openssl_getCleanupHook (
14858 + IN const pkcs11h_openssl_session_t openssl_session
14860 + PKCS11H_ASSERT (openssl_session!=NULL);
14862 + return openssl_session->cleanup_hook;
14866 +pkcs11h_openssl_setCleanupHook (
14867 + IN const pkcs11h_openssl_session_t openssl_session,
14868 + IN const pkcs11h_hook_openssl_cleanup_t cleanup
14870 + PKCS11H_ASSERT (openssl_session!=NULL);
14872 + openssl_session->cleanup_hook = cleanup;
14876 +pkcs11h_openssl_freeSession (
14877 + IN const pkcs11h_openssl_session_t openssl_session
14879 + PKCS11H_ASSERT (openssl_session!=NULL);
14880 + PKCS11H_ASSERT (openssl_session->reference_count>0);
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
14889 + openssl_session->reference_count--;
14891 + if (openssl_session->reference_count == 0) {
14892 + if (openssl_session->cleanup_hook != NULL) {
14893 + openssl_session->cleanup_hook (openssl_session->certificate);
14896 + if (openssl_session->x509 != NULL) {
14897 + X509_free (openssl_session->x509);
14898 + openssl_session->x509 = NULL;
14900 + if (openssl_session->certificate != NULL) {
14901 + pkcs11h_certificate_freeCertificate (openssl_session->certificate);
14902 + openssl_session->certificate = NULL;
14905 + _pkcs11h_mem_free ((void *)&openssl_session);
14909 + PKCS11H_LOG_DEBUG2,
14910 + "PKCS#11: pkcs11h_openssl_freeSession - return"
14915 +pkcs11h_openssl_session_getRSA (
14916 + IN const pkcs11h_openssl_session_t openssl_session
14918 + X509 *x509 = NULL;
14920 + EVP_PKEY *pubkey = NULL;
14921 + PKCS11H_BOOL ok = TRUE;
14923 + PKCS11H_ASSERT (openssl_session!=NULL);
14924 + PKCS11H_ASSERT (!openssl_session->initialized);
14925 + PKCS11H_ASSERT (openssl_session!=NULL);
14928 + PKCS11H_LOG_DEBUG2,
14929 + "PKCS#11: pkcs11h_openssl_session_getRSA - entry openssl_session=%p",
14930 + (void *)openssl_session
14934 + * Dup x509 so RSA will not hold session x509
14938 + (x509 = pkcs11h_openssl_session_getX509 (openssl_session)) == NULL
14941 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get certificate object");
14946 + (pubkey = X509_get_pubkey (x509)) == NULL
14949 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get public key");
14954 + pubkey->type != EVP_PKEY_RSA
14957 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Invalid public key algorithm");
14962 + (rsa = EVP_PKEY_get1_RSA (pubkey)) == NULL
14965 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get RSA key");
14969 + RSA_set_method (rsa, &openssl_session->smart_rsa);
14970 + RSA_set_app_data (rsa, openssl_session);
14971 + openssl_session->reference_count++;
14974 +#ifdef BROKEN_OPENSSL_ENGINE
14976 + if (!rsa->engine) {
14977 + rsa->engine = ENGINE_get_default_RSA();
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");
14986 + rsa->flags |= RSA_FLAG_SIGN_VER;
14987 + openssl_session->initialized = TRUE;
14990 + if (rsa != NULL) {
14997 + * openssl objects have reference
14998 + * count, so release them
15000 + if (pubkey != NULL) {
15001 + EVP_PKEY_free (pubkey);
15005 + if (x509 != NULL) {
15006 + X509_free (x509);
15011 + PKCS11H_LOG_DEBUG2,
15012 + "PKCS#11: pkcs11h_openssl_session_getRSA - return rsa=%p",
15020 +pkcs11h_openssl_session_getX509 (
15021 + IN const pkcs11h_openssl_session_t openssl_session
15023 + X509 *x509 = NULL;
15024 + PKCS11H_BOOL ok = TRUE;
15026 + PKCS11H_ASSERT (openssl_session!=NULL);
15029 + PKCS11H_LOG_DEBUG2,
15030 + "PKCS#11: pkcs11h_openssl_session_getX509 - entry openssl_session=%p",
15031 + (void *)openssl_session
15036 + openssl_session->x509 == NULL &&
15037 + (openssl_session->x509 = pkcs11h_openssl_getX509 (openssl_session->certificate)) == NULL
15040 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get certificate object");
15045 + (x509 = X509_dup (openssl_session->x509)) == NULL
15048 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot duplicate certificate object");
15052 + PKCS11H_LOG_DEBUG2,
15053 + "PKCS#11: pkcs11h_openssl_session_getX509 - return x509=%p",
15060 +#endif /* ENABLE_PKCS11H_OPENSSL */
15062 +#if defined(ENABLE_PKCS11H_STANDALONE)
15063 +/*======================================================================*
15064 + * STANDALONE INTERFACE
15065 + *======================================================================*/
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
15073 + CK_RV rv = CKR_OK;
15075 + pkcs11h_provider_t pkcs11h_provider;
15077 + PKCS11H_ASSERT (my_output!=NULL);
15078 + /*PKCS11H_ASSERT (global_data) NOT NEEDED */
15079 + PKCS11H_ASSERT (provider!=NULL);
15083 + (rv = pkcs11h_initialize ()) != CKR_OK
15085 + my_output (global_data, "PKCS#11: Cannot initialize interface %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
15090 + (rv = pkcs11h_addProvider (
15095 + PKCS11H_SIGNMODE_MASK_SIGN |
15096 + PKCS11H_SIGNMODE_MASK_RECOVER
15098 + PKCS11H_SLOTEVENT_METHOD_AUTO,
15103 + my_output (global_data, "PKCS#11: Cannot initialize provider %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
15107 + * our provider is head
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;
15117 + if (rv == CKR_OK) {
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));
15125 + char manufacturerID[sizeof (info.manufacturerID)+1];
15127 + _pkcs11h_util_fixupFixedString (
15129 + (char *)info.manufacturerID,
15130 + sizeof (info.manufacturerID)
15136 + "Provider Information:\n"
15137 + "\tcryptokiVersion:\t%u.%u\n"
15138 + "\tmanufacturerID:\t\t%s\n"
15139 + "\tflags:\t\t\t%08x\n"
15142 + info.cryptokiVersion.major,
15143 + info.cryptokiVersion.minor,
15145 + (unsigned)info.flags
15150 + if (rv == CKR_OK) {
15151 + CK_SLOT_ID_PTR slots = NULL;
15152 + CK_ULONG slotnum;
15153 + CK_SLOT_ID slot_index;
15156 + _pkcs11h_session_getSlotList (
15157 + pkcs11h_provider,
15163 + my_output (global_data, "PKCS#11: Cannot get slot list %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
15168 + "The following slots are available for use with this provider.\n"
15171 +#if defined(PKCS11H_PRM_SLOT_TYPE)
15175 + "Each slot shown below may be used as a parameter to a\n"
15176 + "%s and %s options.\n"
15178 + PKCS11H_PRM_SLOT_TYPE,
15179 + PKCS11H_PRM_SLOT_ID
15187 + "Slots: (id - name)\n"
15191 + for (slot_index=0;slot_index < slotnum;slot_index++) {
15192 + CK_SLOT_INFO info;
15195 + (rv = pkcs11h_provider->f->C_GetSlotInfo (
15196 + slots[slot_index],
15200 + char current_name[sizeof (info.slotDescription)+1];
15202 + _pkcs11h_util_fixupFixedString (
15204 + (char *)info.slotDescription,
15205 + sizeof (info.slotDescription)
15208 + my_output (global_data, "\t%lu - %s\n", slots[slot_index], current_name);
15213 + if (slots != NULL) {
15214 + _pkcs11h_mem_free ((void *)&slots);
15218 + pkcs11h_terminate ();
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
15235 + * Don't lock card
15237 + if (retry == 0) {
15238 + strncpy (pin, (char *)global_data, pin_max);
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
15258 + for (j=0;j<p_size;j+=16) {
15259 + char line[3*16+1];
15263 + for (k=0;k<16 && j+k<p_size;k++) {
15264 + sprintf (line+strlen (line), "%02x ", p[j+k]);
15270 + max-1-strlen (sz)
15275 + max-1-strlen (sz)
15280 + max-1-strlen (sz)
15284 + sz[max-1] = '\0';
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
15296 + CK_RV rv = CKR_OK;
15298 + pkcs11h_provider_t pkcs11h_provider = NULL;
15299 + pkcs11h_token_id_t token_id = NULL;
15300 + pkcs11h_session_t session = NULL;
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);
15312 + (rv = pkcs11h_initialize ()) != CKR_OK
15314 + my_output (global_data, "PKCS#11: Cannot initialize interface %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
15319 + (rv = pkcs11h_setPINPromptHook (_pkcs11h_standalone_dump_objects_pin_prompt, (void *)pin)) != CKR_OK
15321 + my_output (global_data, "PKCS#11: Cannot set hooks %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
15326 + (rv = pkcs11h_addProvider (
15331 + PKCS11H_SIGNMODE_MASK_SIGN |
15332 + PKCS11H_SIGNMODE_MASK_RECOVER
15334 + PKCS11H_SLOTEVENT_METHOD_AUTO,
15339 + my_output (global_data, "PKCS#11: Cannot initialize provider %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
15343 + * our provider is head
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;
15353 + if (rv == CKR_OK) {
15354 + CK_TOKEN_INFO info;
15357 + (rv = pkcs11h_provider->f->C_GetTokenInfo (
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 */
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];
15372 + _pkcs11h_util_fixupFixedString (
15374 + (char *)info.label,
15375 + sizeof (info.label)
15377 + _pkcs11h_util_fixupFixedString (
15379 + (char *)info.manufacturerID,
15380 + sizeof (info.manufacturerID)
15382 + _pkcs11h_util_fixupFixedString (
15384 + (char *)info.model,
15385 + sizeof (info.model)
15387 + _pkcs11h_util_fixupFixedString (
15388 + serialNumberNumber,
15389 + (char *)info.serialNumber,
15390 + sizeof (info.serialNumber)
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"
15407 + serialNumberNumber,
15408 + (unsigned)info.flags
15411 +#if defined(PKCS11H_PRM_SLOT_TYPE)
15415 + "You can access this token using\n"
15416 + "%s \"label\" %s \"%s\" options.\n"
15419 + PKCS11H_PRM_SLOT_TYPE,
15420 + PKCS11H_PRM_SLOT_ID,
15427 + (rv = _pkcs11h_token_getTokenId (
15432 + my_output (global_data, "PKCS#11: Cannot get token id for slot %ld %ld-'%s'\n", s, rv, pkcs11h_getMessage (rv));
15438 + if (token_id != NULL) {
15440 + (rv = _pkcs11h_session_getSessionByTokenId (
15445 + my_output (global_data, "PKCS#11: Cannot session for token '%s' %ld-'%s'\n", token_id->display, rv, pkcs11h_getMessage (rv));
15450 + if (session != NULL) {
15451 + CK_OBJECT_HANDLE *objects = NULL;
15452 + CK_ULONG objects_found = 0;
15456 + (rv = _pkcs11h_session_login (
15461 + PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT
15464 + my_output (global_data, "PKCS#11: Cannot open session to token '%s' %ld-'%s'\n", session->token_id->display, rv, pkcs11h_getMessage (rv));
15469 + "The following objects are available for use with this token.\n"
15472 +#if defined(PKCS11H_PRM_OBJ_TYPE)
15476 + "Each object shown below may be used as a parameter to\n"
15477 + "%s and %s options.\n"
15479 + PKCS11H_PRM_OBJ_TYPE,
15480 + PKCS11H_PRM_OBJ_ID
15491 + (rv = _pkcs11h_session_findObjects (
15499 + my_output (global_data, "PKCS#11: Cannot query objects for token '%s' %ld-'%s'\n", session->token_id->display, rv, pkcs11h_getMessage (rv));
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)}
15509 + _pkcs11h_session_getObjectAttributes (
15513 + sizeof (attrs) / sizeof (CK_ATTRIBUTE)
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}
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;
15532 + subject[0] = '\0';
15533 + serialNumber[0] = '\0';
15537 + _pkcs11h_session_getObjectAttributes (
15541 + sizeof (attrs_cert) / sizeof (CK_ATTRIBUTE)
15543 + _pkcs11h_mem_malloc (
15544 + (void *)&attrs_label,
15545 + attrs_cert[1].ulValueLen+1
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;
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 (
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;
15572 + _pkcs11h_certificate_getDN (
15574 + attrs_value_size,
15578 + notAfter = _pkcs11h_certificate_getExpiration (
15582 +#if defined(USE_PKCS11H_OPENSSL)
15583 + if ((x509 = X509_new ()) == NULL) {
15584 + my_output (global_data, "Cannot create x509 context\n");
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");
15595 + i2a_ASN1_INTEGER(bioSerial, X509_get_serialNumber (x509));
15596 + n = BIO_read (bioSerial, serialNumber, sizeof (serialNumber)-1);
15598 + serialNumber[0] = '\0';
15601 + serialNumber[n] = '\0';
15608 + if (bioSerial != NULL) {
15609 + BIO_free_all (bioSerial);
15610 + bioSerial = NULL;
15612 + if (x509 != NULL) {
15613 + X509_free (x509);
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};
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 (
15626 + sizeof (serialNumber),
15632 + gnutls_x509_crt_deinit (cert);
15635 +#error Invalid configuration.
15643 + "\tType:\t\t\tCertificate\n"
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"
15655 + asctime (localtime (¬After))
15658 + _pkcs11h_mem_free ((void *)&attrs_label);
15660 + _pkcs11h_session_freeObjectAttributes (
15662 + sizeof (attrs_cert) / sizeof (CK_ATTRIBUTE)
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)}
15672 + CK_ATTRIBUTE attrs_key_common[] = {
15673 + {CKA_ID, NULL, 0},
15674 + {CKA_LABEL, NULL, 0}
15676 + unsigned char *attrs_id = NULL;
15677 + int attrs_id_size = 0;
15678 + char *attrs_label = NULL;
15679 + char hex_id[1024];
15681 + pkcs11h_provider->f->C_GetAttributeValue (
15682 + session->session_handle,
15685 + sizeof (attrs_key) / sizeof (CK_ATTRIBUTE)
15689 + _pkcs11h_session_getObjectAttributes (
15692 + attrs_key_common,
15693 + sizeof (attrs_key_common) / sizeof (CK_ATTRIBUTE)
15695 + _pkcs11h_mem_malloc (
15696 + (void *)&attrs_label,
15697 + attrs_key_common[1].ulValueLen+1
15700 + attrs_id = (unsigned char *)attrs_key_common[0].pValue;
15701 + attrs_id_size = attrs_key_common[0].ulValueLen;
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);
15706 + _pkcs11h_standalone_dump_objects_hex (
15720 + "\tType:\t\t\tPrivate Key\n"
15723 + "\tCKA_LABEL:\t\t%s\n"
15724 + "\tCKA_SIGN:\t\t%s\n"
15725 + "\tCKA_SIGN_RECOVER:\t%s\n"
15729 + sign ? "TRUE" : "FALSE",
15730 + sign_recover ? "TRUE" : "FALSE"
15733 + _pkcs11h_mem_free ((void *)&attrs_label);
15735 + _pkcs11h_session_freeObjectAttributes (
15736 + attrs_key_common,
15737 + sizeof (attrs_key_common) / sizeof (CK_ATTRIBUTE)
15740 + else if (attrs_class == CKO_PUBLIC_KEY) {
15741 + CK_ATTRIBUTE attrs_key_common[] = {
15742 + {CKA_ID, NULL, 0},
15743 + {CKA_LABEL, NULL, 0}
15745 + unsigned char *attrs_id = NULL;
15746 + int attrs_id_size = 0;
15747 + char *attrs_label = NULL;
15748 + char hex_id[1024];
15751 + _pkcs11h_session_getObjectAttributes (
15754 + attrs_key_common,
15755 + sizeof (attrs_key_common) / sizeof (CK_ATTRIBUTE)
15757 + _pkcs11h_mem_malloc (
15758 + (void *)&attrs_label,
15759 + attrs_key_common[1].ulValueLen+1
15762 + attrs_id = (unsigned char *)attrs_key_common[0].pValue;
15763 + attrs_id_size = attrs_key_common[0].ulValueLen;
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);
15768 + _pkcs11h_standalone_dump_objects_hex (
15782 + "\tType:\t\t\tPublic Key\n"
15785 + "\tCKA_LABEL:\t\t%s\n"
15791 + _pkcs11h_mem_free ((void *)&attrs_label);
15793 + _pkcs11h_session_freeObjectAttributes (
15794 + attrs_key_common,
15795 + sizeof (attrs_key_common) / sizeof (CK_ATTRIBUTE)
15798 + else if (attrs_class == CKO_DATA) {
15799 + CK_ATTRIBUTE attrs_key_common[] = {
15800 + {CKA_APPLICATION, NULL, 0},
15801 + {CKA_LABEL, NULL, 0}
15803 + char *attrs_application = NULL;
15804 + char *attrs_label = NULL;
15807 + _pkcs11h_session_getObjectAttributes (
15810 + attrs_key_common,
15811 + sizeof (attrs_key_common) / sizeof (CK_ATTRIBUTE)
15813 + _pkcs11h_mem_malloc (
15814 + (void *)&attrs_application,
15815 + attrs_key_common[0].ulValueLen+1
15817 + _pkcs11h_mem_malloc (
15818 + (void *)&attrs_label,
15819 + attrs_key_common[1].ulValueLen+1
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);
15832 + "\tType:\t\t\tData\n"
15833 + "\tCKA_APPLICATION\t\t%s\n"
15834 + "\tCKA_LABEL:\t\t%s\n"
15836 + attrs_application,
15840 + _pkcs11h_mem_free ((void *)&attrs_application);
15841 + _pkcs11h_mem_free ((void *)&attrs_label);
15843 + _pkcs11h_session_freeObjectAttributes (
15844 + attrs_key_common,
15845 + sizeof (attrs_key_common) / sizeof (CK_ATTRIBUTE)
15853 + "\tType:\t\t\tUnsupported\n"
15859 + _pkcs11h_session_freeObjectAttributes (
15861 + sizeof (attrs) / sizeof (CK_ATTRIBUTE)
15865 + * Ignore any error and
15866 + * perform next iteration
15871 + if (objects != NULL) {
15872 + _pkcs11h_mem_free ((void *)&objects);
15876 + * Ignore this error
15881 + if (session != NULL) {
15882 + _pkcs11h_session_release (session);
15886 + if (token_id != NULL) {
15887 + pkcs11h_token_freeTokenId (token_id);
15891 + pkcs11h_terminate ();
15894 +#endif /* ENABLE_PKCS11H_STANDALONE */
15896 +#ifdef BROKEN_OPENSSL_ENGINE
15897 +static void broken_openssl_init() __attribute__ ((constructor));
15898 +static void broken_openssl_init()
15900 + SSL_library_init();
15901 + ENGINE_load_openssl();
15902 + ENGINE_register_all_RSA();
15907 +static void dummy (void) {}
15908 +#endif /* PKCS11H_HELPER_ENABLE */
15910 diff -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
15915 + * Copyright (c) 2005-2006 Alon Bar-Lev. All rights reserved.
15917 + * Redistribution and use in source and binary forms, with or without
15918 + * modification, are permitted provided that the following conditions
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.
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.
15938 +#ifndef __PKCS11H_HELPER_CONFIG_H
15939 +#define __PKCS11H_HELPER_CONFIG_H
15941 +#if !defined(PKCS11H_NO_NEED_INCLUDE_CONFIG)
15943 +#include "includes.h"
15945 +#endif /* PKCS11H_NO_NEED_INCLUDE_CONFIG */
15947 +#ifndef SSH_PKCS11H_DISABLED
15948 +#define ENABLE_PKCS11H_HELPER
15951 +#include <assert.h>
15952 +#include <string.h>
15953 +#include <ctype.h>
15954 +#if !defined(WIN32)
15955 +#include <unistd.h>
15956 +#include <dlfcn.h>
15960 +#include "xmalloc.h"
15961 +#include "openssl/x509.h"
15963 +#if defined(HAVE_CYGWIN)
15964 +#define PKCS11H_USE_CYGWIN
15967 +#if !defined(FALSE)
15970 +#if !defined(TRUE)
15971 +#define TRUE (!FALSE)
15974 +typedef int PKCS11H_BOOL;
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
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"
16003 +#define PKCS11H_ASSERT assert
16004 +#define PKCS11H_TIME time
16005 +#define PKCS11H_MALLOC xmalloc
16006 +#define PKCS11H_FREE xfree
16008 +#ifdef ENABLE_PKCS11H_HELPER
16009 +#if defined(WIN32) || defined(PKCS11H_USE_CYGWIN)
16010 +#include "cryptoki-win32.h"
16012 +#include "cryptoki.h"
16015 +#endif /* ENABLE_PKCS11H_HELPER */
16016 +#endif /* __PKCS11H_HELPER_CONFIG_H */
16017 diff -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
16022 + * Copyright (c) 2005-2006 Alon Bar-Lev <alon.barlev@gmail.com>
16023 + * All rights reserved.
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.
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.
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.
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
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:
16050 + * o Redistributions of source code must retain the above copyright notice,
16051 + * this list of conditions and the following disclaimer.
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.
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
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.
16074 + * The routines in this file deal with providing private key cryptography
16075 + * using RSA Security Inc. PKCS #11 Cryptographic Token Interface (Cryptoki).
16079 +#ifndef __PKCS11H_HELPER_H
16080 +#define __PKCS11H_HELPER_H
16082 +#if defined(__cplusplus)
16086 +#include "pkcs11-helper-config.h"
16088 +#if !defined(USE_PKCS11H_OPENSSL) && !defined(USE_PKCS11H_GNUTLS)
16089 +#error PKCS#11: USE_PKCS11H_OPENSSL or USE_PKCS11H_GNUTLS must be defined
16092 +#if defined(ENABLE_PKCS11H_SLOTEVENT) && !defined(ENABLE_PKCS11H_THREADING)
16093 +#error PKCS#11: ENABLE_PKCS11H_SLOTEVENT requires ENABLE_PKCS11H_THREADING
16095 +#if defined(ENABLE_PKCS11H_OPENSSL) && !defined(ENABLE_PKCS11H_CERTIFICATE)
16096 +#error PKCS#11: ENABLE_PKCS11H_OPENSSL requires ENABLE_PKCS11H_CERTIFICATE
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
16106 +#define PKCS11H_PIN_CACHE_INFINITE -1
16108 +#define PKCS11H_SIGNMODE_MASK_SIGN (1<<0)
16109 +#define PKCS11H_SIGNMODE_MASK_RECOVER (1<<1)
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 \
16118 +#define PKCS11H_SLOTEVENT_METHOD_AUTO 0
16119 +#define PKCS11H_SLOTEVENT_METHOD_TRIGGER 1
16120 +#define PKCS11H_SLOTEVENT_METHOD_POLL 2
16122 +#define PKCS11H_ENUM_METHOD_CACHE 0
16123 +#define PKCS11H_ENUM_METHOD_CACHE_EXIST 1
16124 +#define PKCS11H_ENUM_METHOD_RELOAD 2
16126 +typedef void (*pkcs11h_output_print_t)(
16127 + IN void * const global_data,
16128 + IN const char * const format,
16132 + __attribute__ ((format (printf, 2, 3)))
16136 +struct pkcs11h_token_id_s;
16137 +typedef struct pkcs11h_token_id_s *pkcs11h_token_id_t;
16139 +#if defined(ENABLE_PKCS11H_CERTIFICATE)
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;
16146 +#endif /* ENABLE_PKCS11H_CERTIFICATE */
16148 +#if defined(ENABLE_PKCS11H_ENUM)
16150 +struct pkcs11h_token_id_list_s;
16151 +typedef struct pkcs11h_token_id_list_s *pkcs11h_token_id_list_t;
16153 +#if defined(ENABLE_PKCS11H_DATA)
16155 +struct pkcs11h_data_id_list_s;
16156 +typedef struct pkcs11h_data_id_list_s *pkcs11h_data_id_list_t;
16158 +#endif /* ENABLE_PKCS11H_DATA */
16160 +#if defined(ENABLE_PKCS11H_CERTIFICATE)
16162 +struct pkcs11h_certificate_id_list_s;
16163 +typedef struct pkcs11h_certificate_id_list_s *pkcs11h_certificate_id_list_t;
16165 +#endif /* ENABLE_PKCS11H_CERTIFICATE */
16167 +#endif /* ENABLE_PKCS11H_ENUM */
16169 +typedef void (*pkcs11h_hook_log_t)(
16170 + IN void * const global_data,
16171 + IN const unsigned flags,
16172 + IN const char * const format,
16176 +typedef void (*pkcs11h_hook_slotevent_t)(
16177 + IN void * const global_data
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
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
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];
16204 +#if defined(ENABLE_PKCS11H_CERTIFICATE)
16206 +struct pkcs11h_certificate_id_s {
16207 + pkcs11h_token_id_t token_id;
16209 + char displayName[1024];
16210 + CK_BYTE_PTR attrCKA_ID;
16211 + size_t attrCKA_ID_size;
16213 + unsigned char *certificate_blob;
16214 + size_t certificate_blob_size;
16219 +#if defined(ENABLE_PKCS11H_ENUM)
16221 +struct pkcs11h_token_id_list_s {
16222 + pkcs11h_token_id_list_t next;
16223 + pkcs11h_token_id_t token_id;
16226 +#if defined(ENABLE_PKCS11H_DATA)
16228 +struct pkcs11h_data_id_list_s {
16229 + pkcs11h_data_id_list_t next;
16231 + char *application;
16235 +#endif /* ENABLE_PKCS11H_DATA */
16237 +#if defined(ENABLE_PKCS11H_CERTIFICATE)
16239 +struct pkcs11h_certificate_id_list_s {
16240 + pkcs11h_certificate_id_list_t next;
16241 + pkcs11h_certificate_id_t certificate_id;
16244 +#endif /* ENABLE_PKCS11H_CERTIFICATE */
16246 +#endif /* ENABLE_PKCS11H_CERTIFICATE */
16248 +#if defined(ENABLE_PKCS11H_OPENSSL)
16250 +typedef void (*pkcs11h_hook_openssl_cleanup_t) (
16251 + IN const pkcs11h_certificate_t certificate
16254 +struct pkcs11h_openssl_session_s;
16255 +typedef struct pkcs11h_openssl_session_s *pkcs11h_openssl_session_t;
16257 +#endif /* ENABLE_PKCS11H_OPENSSL */
16260 + * pkcs11h_getMessage - Get message by return value.
16263 + * rv - Return value.
16266 +pkcs11h_getMessage (
16267 + IN const CK_RV rv
16271 + * pkcs11h_initialize - Inititalize helper interface.
16273 + * Must be called once, from main thread.
16275 + * Protected authentication enabled.
16276 + * PIN cached is infinite.
16279 +pkcs11h_initialize ();
16282 + * pkcs11h_terminate - Terminate helper interface.
16284 + * Must be called once, from main thread, after all
16285 + * related resources freed.
16288 +pkcs11h_terminate ();
16291 + * pkcs11h_setLogLevel - Set current log level of the helper.
16294 + * flags - current log level.
16296 + * The log level can be set to maximum, but setting it to lower
16297 + * level will improve performance.
16300 +pkcs11h_setLogLevel (
16301 + IN const unsigned flags
16305 + * pkcs11h_getLogLevel - Get current log level.
16308 +pkcs11h_getLogLevel ();
16311 + * pkcs11h_setLogHook - Set a log callback.
16314 + * hook - Callback.
16315 + * pData - Data to send to callback.
16318 +pkcs11h_setLogHook (
16319 + IN const pkcs11h_hook_log_t hook,
16320 + IN void * const global_data
16324 + * pkcs11h_setSlotEventHook - Set a slot event callback.
16327 + * hook - Callback.
16328 + * pData - Data to send to callback.
16330 + * Calling this function initialize slot event notifications, these
16331 + * notifications can be started, but never terminate due to PKCS#11 limitation.
16333 + * In order to use slot events you must have threading enabled.
16336 +pkcs11h_setSlotEventHook (
16337 + IN const pkcs11h_hook_slotevent_t hook,
16338 + IN void * const global_data
16342 + * pkcs11h_setTokenPromptHook - Set a token prompt callback.
16345 + * hook - Callback.
16346 + * pData - Data to send to callback.
16349 +pkcs11h_setTokenPromptHook (
16350 + IN const pkcs11h_hook_token_prompt_t hook,
16351 + IN void * const global_data
16355 + * pkcs11h_setPINPromptHook - Set a pin prompt callback.
16358 + * hook - Callback.
16359 + * pData - Data to send to callback.
16362 +pkcs11h_setPINPromptHook (
16363 + IN const pkcs11h_hook_pin_prompt_t hook,
16364 + IN void * const global_data
16368 + * pkcs11h_setProtectedAuthentication - Set global protected authentication mode.
16371 + * allow_protected_auth - Allow protected authentication if enabled by token.
16374 +pkcs11h_setProtectedAuthentication (
16375 + IN const PKCS11H_BOOL allow_protected_auth
16379 + * pkcs11h_setPINCachePeriod - Set global PIN cache timeout.
16382 + * pin_cache_period - Cache period in seconds, or PKCS11H_PIN_CACHE_INFINITE.
16385 +pkcs11h_setPINCachePeriod (
16386 + IN const int pin_cache_period
16390 + * pkcs11h_setMaxLoginRetries - Set global login retries attempts.
16393 + * max_retries - Login retries handled by the helper.
16396 +pkcs11h_setMaxLoginRetries (
16397 + IN const unsigned max_retries
16401 + * pkcs11h_addProvider - Add a PKCS#11 provider.
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.
16412 + * This function must be called from the main thread.
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.
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
16429 + * pkcs11h_delProvider - Delete a PKCS#11 provider.
16432 + * reference - Reference name for this provider.
16434 + * This function must be called from the main thread.
16437 +pkcs11h_removeProvider (
16438 + IN const char * const reference
16442 + * pkcs11h_forkFixup - Handle special case of Unix fork()
16444 + * This function should be called after fork is called. This is required
16445 + * due to a limitation of the PKCS#11 standard.
16447 + * This function must be called from the main thread.
16449 + * The helper library handles fork automatically if ENABLE_PKCS11H_THREADING
16450 + * is set on configuration file, by use of pthread_atfork.
16453 +pkcs11h_forkFixup ();
16456 + * pkcs11h_plugAndPlay - Handle slot rescan.
16458 + * This function must be called from the main thread.
16460 + * PKCS#11 providers do not allow plug&play, plug&play can be established by
16461 + * finalizing all providers and initializing them again.
16463 + * The cost of this process is invalidating all sessions, and require user
16464 + * login at the next access.
16467 +pkcs11h_plugAndPlay ();
16470 + * pkcs11h_token_freeTokenId - Free token_id object.
16473 + * token_id - token_id.
16476 +pkcs11h_token_freeTokenId (
16477 + IN pkcs11h_token_id_t token_id
16481 + * pkcs11h_duplicateTokenId - Duplicate token_id object.
16488 +pkcs11h_token_duplicateTokenId (
16489 + OUT pkcs11h_token_id_t * const to,
16490 + IN const pkcs11h_token_id_t from
16494 + * pkcs11h_sameTokenId - Returns TRUE if same token id
16501 +pkcs11h_token_sameTokenId (
16502 + IN const pkcs11h_token_id_t a,
16503 + IN const pkcs11h_token_id_t b
16507 + * pkcs11h_token_login - Force login, avoid hooks.
16510 + * token_id - Token to login into.
16511 + * readonly - Should session be readonly.
16512 + * pin - PIN to login, NULL for protected authentication
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
16521 +#if defined(ENABLE_PKCS11H_SERIALIZATION)
16524 + * pkcs11h_serializeTokenId - Serialize token_id into string.
16527 + * sz - Output string.
16528 + * max - Maximum string size.
16529 + * token_id - id to serialize
16531 + * sz may be NULL to get size
16534 +pkcs11h_token_serializeTokenId (
16535 + OUT char * const sz,
16536 + IN OUT size_t *max,
16537 + IN const pkcs11h_token_id_t token_id
16541 + * pkcs11h_deserializeTokenId - Deserialize token_id from string.
16544 + * p_token_id - id.
16545 + * sz - Input string
16548 +pkcs11h_token_deserializeTokenId (
16549 + OUT pkcs11h_token_id_t *p_token_id,
16550 + IN const char * const sz
16553 +#endif /* ENABLE_PKCS11H_SERIALIZATION */
16555 +#if defined(ENABLE_PKCS11H_TOKEN)
16558 + * pkcs11h_token_ensureAccess - Ensure token is accessible.
16561 + * token_id - Token id object.
16562 + * user_data - Optional user data, to be passed to hooks.
16563 + * mask_prompt - Allow prompt.
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
16572 +#endif /* ENABLE_PKCS11H_TOKEN */
16574 +#if defined(ENABLE_PKCS11H_DATA)
16577 + * pkcs11h_data_get - get data object.
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.
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
16602 + * pkcs11h_data_put - put data object.
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.
16612 + * blob_size - blob size.
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
16627 + * pkcs11h_data_del - delete data object.
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.
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
16647 +#endif /* ENABLE_PKCS11H_DATA */
16649 +#if defined(ENABLE_PKCS11H_CERTIFICATE)
16650 +/*======================================================================*
16651 + * CERTIFICATE INTERFACE
16652 + *======================================================================*/
16655 + * pkcs11h_certificate_freeCertificateId - Free certificate_id object.
16658 +pkcs11h_certificate_freeCertificateId (
16659 + IN pkcs11h_certificate_id_t certificate_id
16663 + * pkcs11h_duplicateCertificateId - Duplicate certificate_id object.
16666 +pkcs11h_certificate_duplicateCertificateId (
16667 + OUT pkcs11h_certificate_id_t * const to,
16668 + IN const pkcs11h_certificate_id_t from
16672 + * pkcs11h_certificate_setCertificateIdCertificateBlob - Sets internal certificate_id blob.
16675 + * certificate_id - Certificate id ojbect.
16677 + * blob_size - blob size.
16679 + * Useful to set after deserialization so certificate is available and not read from token.
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
16689 + * pkcs11h_certificate_freeCertificate - Free certificate object.
16692 + * certificate - Certificate ojbect.
16695 +pkcs11h_certificate_freeCertificate (
16696 + IN pkcs11h_certificate_t certificate
16700 + * pkcs11h_certificate_create - Create a certificate object out of certificate_id.
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.
16709 + * The certificate id object may not specify the full certificate.
16710 + * The certificate object must be freed by caller.
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
16722 + * pkcs11h_certificate_getPromptMask - Extract user data out of certificate.
16725 + * certificate - Certificate ojbect.
16728 + * mask_prompt - Allow prompt.
16732 +pkcs11h_certificate_getPromptMask (
16733 + IN const pkcs11h_certificate_t certificate
16737 + * pkcs11h_certificate_setPromptMask - Extract user data out of certificate.
16740 + * certificate - Certificate ojbect.
16741 + * mask_prompt - Allow prompt.
16744 +pkcs11h_certificate_setPromptMask (
16745 + IN const pkcs11h_certificate_t certificate,
16746 + IN const unsigned ask_prompt
16750 + * pkcs11h_certificate_getUserData - Extract user data out of certificate.
16753 + * certificate - Certificate ojbect.
16756 + * user_data - Optional user data, to be passed to hooks.
16759 +pkcs11h_certificate_getUserData (
16760 + IN const pkcs11h_certificate_t certificate
16764 + * pkcs11h_certificate_setUserData - Extract user data out of certificate.
16767 + * certificate - Certificate ojbect.
16768 + * user_data - Optional user data, to be passed to hooks.
16771 +pkcs11h_certificate_setUserData (
16772 + IN const pkcs11h_certificate_t certificate,
16773 + IN void * const user_data
16777 + * pkcs11h_certificate_getCertificateId - Get certifiate id object out of a certifiate
16780 + * certificate - Certificate object.
16781 + * p_certificate_id - Certificate id object pointer.
16783 + * The certificate id must be freed by caller.
16786 +pkcs11h_certificate_getCertificateId (
16787 + IN const pkcs11h_certificate_t certificate,
16788 + OUT pkcs11h_certificate_id_t * const p_certificate_id
16792 + * pkcs11h_certificate_getCertificateBlob - Get the certificate blob out of the certificate object.
16795 + * certificate - Certificate object.
16796 + * certificate_blob - Buffer.
16797 + * certificate_blob_size - Buffer size.
16799 + * Buffer may be NULL in order to get size.
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
16808 +#if defined(ENABLE_PKCS11H_SERIALIZATION)
16811 + * pkcs11h_certificate_serializeCertificateId - Serialize certificate_id into a string
16814 + * sz - Output string.
16815 + * max - Max buffer size.
16816 + * certificate_id - id to serialize
16818 + * sz may be NULL in order to get size.
16821 +pkcs11h_certificate_serializeCertificateId (
16822 + OUT char * const sz,
16823 + IN OUT size_t *max,
16824 + IN const pkcs11h_certificate_id_t certificate_id
16828 + * pkcs11h_certificate_deserializeCertificateId - Deserialize certificate_id out of string.
16831 + * p_certificate_id - id.
16832 + * sz - Inut string
16835 +pkcs11h_certificate_deserializeCertificateId (
16836 + OUT pkcs11h_certificate_id_t * const p_certificate_id,
16837 + IN const char * const sz
16840 +#endif /* ENABLE_PKCS11H_SERIALIZATION */
16843 + * pkcs11h_certificate_ensureCertificateAccess - Ensure certificate is accessible.
16846 + * certificate - Certificate object.
16849 +pkcs11h_certificate_ensureCertificateAccess (
16850 + IN const pkcs11h_certificate_t certificate
16854 + * pkcs11h_certificate_ensureKeyAccess - Ensure key is accessible.
16857 + * certificate - Certificate object.
16860 +pkcs11h_certificate_ensureKeyAccess (
16861 + IN const pkcs11h_certificate_t certificate
16865 + * pkcs11h_certificate_lockSession - Lock session for threded environment
16868 + * certificate - Certificate object.
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.
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.
16880 +pkcs11h_certificate_lockSession (
16881 + IN const pkcs11h_certificate_t certificate
16885 + * pkcs11h_certificate_releaseSession - Releases session lock.
16888 + * certificate - Certificate object.
16890 + * See pkcs11h_certificate_lockSession.
16893 +pkcs11h_certificate_releaseSession (
16894 + IN const pkcs11h_certificate_t certificate
16898 + * pkcs11h_certificate_sign - Sign data.
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.
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
16919 + * pkcs11h_certificate_signRecover - Sign data.
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.
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
16940 + * pkcs11h_certificate_signAny - Sign data mechanism determined by key attributes.
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.
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
16961 + * pkcs11h_certificate_decrypt - Decrypt data.
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.
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
16981 +#endif /* ENABLE_PKCS11H_CERTIFICATE */
16983 +#if defined(ENABLE_PKCS11H_LOCATE)
16984 +/*======================================================================*
16985 + * LOCATE INTERFACE
16986 + *======================================================================*/
16988 +#if defined(ENABLE_PKCS11H_TOKEN) || defined(ENABLE_PKCS11H_CERTIFICATE)
16991 + * pkcs11h_locate_token - Locate token based on atributes.
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.
17001 + * id - Slot number.
17002 + * name - Slot name.
17003 + * label - Available token label.
17005 + * Caller must free token id.
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
17016 +#endif /* ENABLE_PKCS11H_TOKEN || ENABLE_PKCS11H_CERTIFICATE */
17018 +#if defined(ENABLE_PKCS11H_CERTIFICATE)
17021 + * pkcs11h_locate_certificate - Locate certificate based on atributes.
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.
17033 + * Same as pkcs11h_locate_token.
17036 + * id - Certificate CKA_ID (hex string) (Fastest).
17037 + * label - Certificate CKA_LABEL (string).
17038 + * subject - Certificate subject (OpenSSL or gnutls DN).
17040 + * Caller must free certificate id.
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
17053 +#endif /* ENABLE_PKCS11H_CERTIFICATE */
17055 +#endif /* ENABLE_PKCS11H_LOCATE */
17057 +#if defined(ENABLE_PKCS11H_ENUM)
17058 +/*======================================================================*
17060 + *======================================================================*/
17062 +#if defined(ENABLE_PKCS11H_TOKEN)
17065 + * pkcs11h_freeTokenIdList - Free certificate_id list.
17068 +pkcs11h_token_freeTokenIdList (
17069 + IN const pkcs11h_token_id_list_t token_id_list
17073 + * pkcs11h_token_enumTokenIds - Enumerate available tokens
17076 + * p_token_id_list - A list of token ids.
17078 + * Caller must free the list.
17081 +pkcs11h_token_enumTokenIds (
17082 + IN const int method,
17083 + OUT pkcs11h_token_id_list_t * const p_token_id_list
17086 +#endif /* ENABLE_PKCS11H_TOKEN */
17088 +#if defined(ENABLE_PKCS11H_DATA)
17091 + * pkcs11h_data_freeDataIdList - free data object list..
17094 + * data_id_list - list to free.
17097 +pkcs11h_data_freeDataIdList (
17098 + IN const pkcs11h_data_id_list_t data_id_list
17102 + * pkcs11h_data_enumDataObjects - get list of data objects.
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.
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
17120 +#endif /* ENABLE_PKCS11H_DATA */
17122 +#if defined(ENABLE_PKCS11H_CERTIFICATE)
17125 + * pkcs11h_certificate_freeCertificateIdList - Free certificate_id list.
17128 +pkcs11h_certificate_freeCertificateIdList (
17129 + IN const pkcs11h_certificate_id_list_t cert_id_list
17133 + * pkcs11h_certificate_enumTokenCertificateIds - Enumerate available certificates on specific token
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.
17143 + * This function will likely take long time.
17145 + * Method can be one of the following:
17146 + * PKCS11H_ENUM_METHOD_CACHE
17147 + * Return available certificates, even if token was once detected and
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.
17156 + * Caller must free the lists.
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
17169 + * pkcs11h_enum_getCertificateIds - Enumerate available certificates.
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.
17178 + * This function will likely take long time.
17180 + * Method can be one of the following:
17181 + * PKCS11H_ENUM_METHOD_CACHE
17182 + * Return available certificates, even if token was once detected and
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.
17191 + * Caller must free lists.
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
17202 +#endif /* ENABLE_PKCS11H_CERTIFICATE */
17204 +#endif /* ENABLE_PKCS11H_ENUM */
17206 +#if defined(ENABLE_PKCS11H_OPENSSL)
17207 +/*======================================================================*
17208 + * OPENSSL INTERFACE
17209 + *======================================================================*/
17212 + * pkcs11h_openssl_getX509 - Returns an X509 object out of the openssl_session object.
17215 + * certificate - Certificate object.
17218 +pkcs11h_openssl_getX509 (
17219 + IN const pkcs11h_certificate_t certificate
17223 + * pkcs11h_openssl_createSession - Create OpenSSL session based on a certificate object.
17226 + * certificate - Certificate object.
17228 + * The certificate object will be freed by the OpenSSL interface on session end.
17230 +pkcs11h_openssl_session_t
17231 +pkcs11h_openssl_createSession (
17232 + IN const pkcs11h_certificate_t certificate
17236 + * pkcs11h_openssl_getCleanupHook - Sets cleanup hook
17239 + * openssl_session - session.
17241 +pkcs11h_hook_openssl_cleanup_t
17242 +pkcs11h_openssl_getCleanupHook (
17243 + IN const pkcs11h_openssl_session_t openssl_session
17247 + * pkcs11h_openssl_setCleanupHook - Sets cleanup hook
17250 + * openssl_session - session.
17251 + * cleanup - hook.
17254 +pkcs11h_openssl_setCleanupHook (
17255 + IN const pkcs11h_openssl_session_t openssl_session,
17256 + IN const pkcs11h_hook_openssl_cleanup_t cleanup
17260 + * pkcs11h_openssl_freeSession - Free OpenSSL session.
17263 + * openssl_session - Session to free.
17265 + * The openssl_session object has a reference count just like other OpenSSL objects.
17268 +pkcs11h_openssl_freeSession (
17269 + IN const pkcs11h_openssl_session_t openssl_session
17273 + * pkcs11h_openssl_session_getRSA - Returns an RSA object out of the openssl_session object.
17276 + * openssl_session - Session.
17279 +pkcs11h_openssl_session_getRSA (
17280 + IN const pkcs11h_openssl_session_t openssl_session
17284 + * pkcs11h_openssl_session_getX509 - Returns an X509 object out of the openssl_session object.
17287 + * openssl_session - Session.
17290 +pkcs11h_openssl_session_getX509 (
17291 + IN const pkcs11h_openssl_session_t openssl_session
17294 +#endif /* ENABLE_PKCS11H_OPENSSL */
17296 +#if defined(ENABLE_PKCS11H_STANDALONE)
17297 +/*======================================================================*
17298 + * STANDALONE INTERFACE
17299 + *======================================================================*/
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
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
17317 +#endif /* ENABLE_PKCS11H_STANDALONE */
17319 +#ifdef __cplusplus
17323 +#endif /* __PKCS11H_HELPER_H */
17324 diff -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
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).
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.
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.
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.
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.
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.
17353 +You can view full usage by:
17354 +$ ssh-agent /bin/sh
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"
17364 +In order to see available objects, you can use:
17365 +$ ssh-add --pkcs11-show-ids --pkcs11-provider /usr/lib/pkcs11/MyProvider.so
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
17371 +In order to debug open two shells:
17372 +1$ rm -fr /tmp/s; ssh-agent -d -d -d -a /tmp/s
17374 +2$ SSH_AUTH_SOCK=/tmp/s; export SSH_AUTH_SOCK;
17377 diff -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 @@
17384 +#include "pkcs11.h"
17385 #include "buffer.h"
17386 #include "authfd.h"
17387 #include "authfile.h"
17388 #include "pathnames.h"
17391 +static void usage (void);
17394 extern char *__progname;
17396 @@ -306,6 +309,261 @@ do_file(AuthenticationConnection *ac, in
17400 +#ifndef SSH_PKCS11_DISABLED
17404 +do_pkcs11 (AuthenticationConnection *ac, int argc, char *argv[])
17407 + * TEMP TEMP TEMP TEMP
17409 + * This should be fixed if another mechanism
17410 + * will be propsed.
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;
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;
17431 + int nSkipPrmCount;
17434 + for (i=0,nSkipPrmCount=0;i<argc;i++) {
17435 + if (!strcmp (argv[i], "--pkcs11-provider")) {
17436 + szPKCS11Provider = argv[i+1];
17439 + else if (!strcmp (argv[i], "--pkcs11-id")) {
17440 + szPKCS11Id = argv[i+1];
17443 + else if (!strcmp (argv[i], "--pkcs11-pin-cache")) {
17444 + nPKCS11PINCachePeriod = atoi (argv[i+1]);
17447 + else if (!strcmp (argv[i], "--pkcs11-sign-mode")) {
17448 + szPKCS11SignMode = argv[i+1];
17451 + else if (!strcmp (argv[i], "--pkcs11-ask-pin")) {
17452 + szPKCS11AskPIN = argv[i+1];
17455 + else if (!strcmp (argv[i], "--pkcs11-slot")) {
17456 + szPKCS11SlotId = argv[i+1];
17459 + else if (!strcmp (argv[i], "--pkcs11-cert-file")) {
17460 + szPKCS11CertFile = argv[i+1];
17463 + else if (!strcmp (argv[i], "--pkcs11-add-provider")) {
17464 + fPKCS11AddProvider = 1;
17466 + else if (!strcmp (argv[i], "--pkcs11-remove-id")) {
17467 + fPKCS11RemoveId = 1;
17469 + else if (!strcmp (argv[i], "--pkcs11-add-id")) {
17470 + fPKCS11AddId = 1;
17472 + else if (!strcmp (argv[i], "--pkcs11-show-ids")) {
17473 + fPKCS11ShowIds = 1;
17475 + else if (!strcmp (argv[i], "--pkcs11-dump-slots")) {
17476 + fPKCS11DumpSlots = 1;
17478 + else if (!strcmp (argv[i], "--pkcs11-dump-objects")) {
17479 + fPKCS11DumpObjects = 1;
17481 + else if (!strcmp (argv[i], "--pkcs11-protected-authentication")) {
17482 + fPKCS11ProtectedAuthentication = 1;
17484 + else if (!strcmp (argv[i], "--pkcs11-cert-private")) {
17485 + fPKCS11CertPrivate = 1;
17487 + else if (!strcmp (argv[i], "-d")) {
17495 + if (nSkipPrmCount == argc) {
17496 + /* no pkcs#11 arguments */
17503 + fPKCS11AddProvider &&
17504 + szPKCS11Provider == NULL
17513 + szPKCS11Id == NULL
17521 + fPKCS11RemoveId &&
17523 + szPKCS11Id == NULL
17531 + fPKCS11ShowIds &&
17532 + szPKCS11Provider == NULL
17539 + fPKCS11DumpSlots &&
17540 + szPKCS11Provider == NULL
17547 + fPKCS11DumpObjects &&
17549 + szPKCS11Provider == NULL ||
17550 + szPKCS11SlotId == NULL
17563 + if (fPKCS11AddId || fPKCS11RemoveId) {
17564 + id = pkcs11_identity_new ();
17565 + if (id == NULL) {
17569 + id->id = strdup (szPKCS11Id);
17570 + id->pin_cache_period = nPKCS11PINCachePeriod;
17571 + id->cert_file = szPKCS11CertFile;
17578 + log_init(__progname, SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 1);
17581 + if (fPKCS11ShowIds) {
17582 + pkcs11_show_ids (szPKCS11Provider, fPKCS11ProtectedAuthentication, fPKCS11CertPrivate);
17585 + else if (fPKCS11DumpSlots) {
17586 + pkcs11_dump_slots (szPKCS11Provider);
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);
17594 + memset (szPIN, 0, strlen (szPIN));
17598 + else if (szPKCS11AskPIN != NULL) {
17599 + ret = !ssh_pkcs11_set_ask_pin (ac, szPKCS11AskPIN);
17602 + fprintf (stderr, "Failed\n");
17605 + fprintf (stderr, "Success\n");
17608 + else if (fPKCS11AddProvider) {
17609 + ret = !ssh_pkcs11_add_provider (
17611 + szPKCS11Provider,
17612 + fPKCS11ProtectedAuthentication,
17613 + szPKCS11SignMode,
17614 + fPKCS11CertPrivate
17618 + fprintf (stderr, "Cannot add provider %s\n", szPKCS11Provider);
17621 + fprintf (stderr, "Provider %s added successfully\n", szPKCS11Provider);
17624 + else if (fPKCS11AddId) {
17625 + ret = !ssh_pkcs11_id (ac, id, 0);
17628 + fprintf (stderr, "Cannot add identity\n");
17631 + fprintf (stderr, "Identity added successfully\n");
17634 + else if (fPKCS11RemoveId) {
17635 + ret = !ssh_pkcs11_id (ac, id, 1);
17638 + fprintf (stderr, "Cannot remove identity\n");
17641 + fprintf (stderr, "Identity removed successfully\n");
17646 + if (id != NULL) {
17647 + pkcs11_identity_free (id);
17653 +#endif /* SSH_PKCS11_DISABLED */
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");
17662 +#ifndef SSH_PKCS11_DISABLED
17667 + " PKCS#11 Options:\n"
17668 + " --pkcs11-ask-pin prog Set ask-pin program\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"
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"
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"
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"
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"
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"
17705 +#endif /* SSH_PKCS11_DISABLED */
17709 @@ -350,6 +652,17 @@ main(int argc, char **argv)
17710 "Could not open a connection to your authentication agent.\n");
17714 +#ifndef SSH_PKCS11_DISABLED
17716 + int r = do_pkcs11 (ac, argc, argv);
17722 +#endif /* SSH_PKCS11_DISABLED */
17724 while ((ch = getopt(argc, argv, "lLcdDxXe:s:t:")) != -1) {
17727 diff -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
17731 #include "buffer.h"
17733 #include "authfd.h"
17734 +#include "pkcs11.h"
17735 #include "compat.h"
17738 @@ -690,6 +691,157 @@ send:
17740 #endif /* SMARTCARD */
17742 +#ifndef SSH_PKCS11_DISABLED
17746 +process_pkcs11_set_ask_pin (SocketEntry *e)
17748 + char *szAskPIN = NULL;
17751 + szAskPIN = buffer_get_string(&e->request, NULL);
17753 + success = pkcs11_setAskPIN (szAskPIN);
17755 + buffer_put_int(&e->output, 1);
17756 + buffer_put_char(&e->output,
17757 + success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
17761 +process_pkcs11_add_provider (SocketEntry *e)
17763 + char *szProvider = NULL;
17764 + int fProtectedAuthentication = 0;
17765 + char *szSignMode = NULL;
17766 + int fCertIsPrivate = 0;
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);
17774 + success = pkcs11_addProvider (szProvider, fProtectedAuthentication, szSignMode, fCertIsPrivate);
17776 + buffer_put_int(&e->output, 1);
17777 + buffer_put_char(&e->output,
17778 + success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
17783 +process_pkcs11_add_id (SocketEntry *e)
17787 + char szComment[1024];
17789 + pkcs11_identity *pkcs11_id = NULL;
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));
17801 + sizeof (szComment)
17805 + if (lookup_identity(k, version) == NULL) {
17806 + Identity *id = xmalloc(sizeof(Identity));
17807 + Idtab *tab = NULL;
17811 + id->comment = xstrdup (szComment);
17812 + id->death = 0; /* handled by pkcs#11 helper */
17815 + tab = idtab_lookup(version);
17816 + TAILQ_INSERT_TAIL(&tab->idlist, id, next);
17817 + /* Increment the number of identities. */
17828 + if (pkcs11_id != NULL) {
17829 + pkcs11_identity_free (pkcs11_id);
17832 + buffer_put_int(&e->output, 1);
17833 + buffer_put_char(&e->output,
17834 + success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
17839 +process_pkcs11_remove_id (SocketEntry *e)
17842 + Identity *id = NULL;
17844 + char szComment[1024];
17847 + pkcs11_identity *pkcs11_id = NULL;
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));
17859 + sizeof (szComment)
17863 + id = lookup_identity (k, version);
17866 + if (id != NULL) {
17867 + Idtab *tab = NULL;
17869 + tab = idtab_lookup(version);
17870 + TAILQ_REMOVE(&tab->idlist, id, next);
17872 + free_identity(id);
17882 + if (pkcs11_id != NULL) {
17883 + pkcs11_identity_free (pkcs11_id);
17886 + buffer_put_int(&e->output, 1);
17887 + buffer_put_char(&e->output,
17888 + success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
17891 +#endif /* SSH_PKCS11_DISABLED */
17893 /* dispatch incoming messages */
17896 @@ -785,6 +937,21 @@ process_message(SocketEntry *e)
17897 process_remove_smartcard_key(e);
17899 #endif /* SMARTCARD */
17901 +#ifndef SSH_PKCS11_DISABLED
17902 + case SSH_AGENTC_PKCS11_SET_ASK_PIN:
17903 + process_pkcs11_set_ask_pin (e);
17905 + case SSH_AGENTC_PKCS11_ADD_PROVIDER:
17906 + process_pkcs11_add_provider (e);
17908 + case SSH_AGENTC_PKCS11_ADD_ID:
17909 + process_pkcs11_add_id (e);
17911 + case SSH_AGENTC_PKCS11_REMOVE_ID:
17912 + process_pkcs11_remove_id (e);
17914 +#endif /* SSH_PKCS11_DISABLED */
17916 /* Unknown message. Respond with failure. */
17917 error("Unknown message %d", type);
17918 @@ -1064,7 +1231,7 @@ main(int ac, char **av)
17927 @@ -1167,7 +1334,7 @@ main(int ac, char **av)
17928 * the socket data. The child continues as the authentication agent.
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)
17941 +#ifndef SSH_PKCS11_DISABLED
17942 + pkcs11_initialize (1, -1);
17943 +#endif /* SSH_PKCS11_DISABLED */
17945 new_socket(AUTH_SOCKET, sock);
17947 mysignal(SIGALRM, check_parent_exists);
17948 @@ -1251,4 +1423,8 @@ skip:
17949 after_select(readsetp, writesetp);
17953 +#ifndef SSH_PKCS11_DISABLED
17954 + pkcs11_terminate ();
17955 +#endif /* SSH_PKCS11_DISABLED */