]> git.wh0rd.org - patches.git/blob - openssh-4.4p1pkcs11-0.17.patch
more random patches. who knows.
[patches.git] / openssh-4.4p1pkcs11-0.17.patch
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)
5 /* NOTREACHED */
6 return 0;
7 }
8 +
9 +#ifndef SSH_PKCS11_DISABLED
10 +
11 +int
12 +ssh_pkcs11_add_provider (AuthenticationConnection *auth, const char *provider,
13 + int protected_authentication, const char *sign_mode, int cert_private)
14 +{
15 + Buffer msg;
16 + int type;
17 + int code;
18 +
19 + code = SSH_AGENTC_PKCS11_ADD_PROVIDER;
20 +
21 + buffer_init(&msg);
22 + buffer_put_char(&msg, code);
23 + buffer_put_cstring(&msg, provider);
24 + buffer_put_int(&msg, protected_authentication);
25 + buffer_put_cstring(&msg, sign_mode == NULL ? "auto" : sign_mode);
26 + buffer_put_int(&msg, cert_private);
27 +
28 + if (ssh_request_reply(auth, &msg, &msg) == 0) {
29 + buffer_free(&msg);
30 + return 0;
31 + }
32 + type = buffer_get_char(&msg);
33 + buffer_free(&msg);
34 + return decode_reply(type);
35 +}
36 +
37 +int
38 +ssh_pkcs11_id (AuthenticationConnection *auth, const pkcs11_identity *id, int remove)
39 +{
40 + Buffer msg;
41 + int type;
42 + int code;
43 +
44 + code = remove ? SSH_AGENTC_PKCS11_REMOVE_ID : SSH_AGENTC_PKCS11_ADD_ID;
45 +
46 + buffer_init(&msg);
47 + buffer_put_char(&msg, code);
48 + buffer_put_cstring(&msg, id->id);
49 + buffer_put_int(&msg, id->pin_cache_period);
50 + buffer_put_cstring(&msg, id->cert_file == NULL ? "" : id->cert_file);
51 +
52 + if (ssh_request_reply(auth, &msg, &msg) == 0) {
53 + buffer_free(&msg);
54 + return 0;
55 + }
56 + type = buffer_get_char(&msg);
57 + buffer_free(&msg);
58 + return decode_reply(type);
59 +}
60 +
61 +int
62 +ssh_pkcs11_set_ask_pin (AuthenticationConnection *auth, const char *pin_prog)
63 +{
64 + Buffer msg;
65 + int type;
66 + int code;
67 +
68 + code = SSH_AGENTC_PKCS11_SET_ASK_PIN;
69 +
70 + buffer_init(&msg);
71 + buffer_put_char(&msg, code);
72 + buffer_put_cstring(&msg, pin_prog);
73 +
74 + if (ssh_request_reply(auth, &msg, &msg) == 0) {
75 + buffer_free(&msg);
76 + return 0;
77 + }
78 + type = buffer_get_char(&msg);
79 + buffer_free(&msg);
80 + return decode_reply(type);
81 +}
82 +
83 +#endif /* SSH_PKCS11_DISABLED */
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
87 @@ -16,6 +16,8 @@
88 #ifndef AUTHFD_H
89 #define AUTHFD_H
90
91 +#include "pkcs11.h"
92 +
93 /* Messages for the authentication agent connection. */
94 #define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1
95 #define SSH_AGENT_RSA_IDENTITIES_ANSWER 2
96 @@ -49,6 +51,11 @@
97 #define SSH2_AGENTC_ADD_ID_CONSTRAINED 25
98 #define SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED 26
99
100 +#define SSH_AGENTC_PKCS11_ADD_PROVIDER 27
101 +#define SSH_AGENTC_PKCS11_ADD_ID 28
102 +#define SSH_AGENTC_PKCS11_REMOVE_ID 29
103 +#define SSH_AGENTC_PKCS11_SET_ASK_PIN 30
104 +
105 #define SSH_AGENT_CONSTRAIN_LIFETIME 1
106 #define SSH_AGENT_CONSTRAIN_CONFIRM 2
107
108 @@ -92,4 +99,11 @@ int
109 ssh_agent_sign(AuthenticationConnection *, Key *, u_char **, u_int *, u_char *,
110 u_int);
111
112 +#ifndef SSH_PKCS11_DISABLED
113 +int ssh_pkcs11_add_provider (AuthenticationConnection *, const char *,
114 + int, const char *, int);
115 +int ssh_pkcs11_id (AuthenticationConnection *, const pkcs11_identity *, int remove);
116 +int ssh_pkcs11_set_ask_pin (AuthenticationConnection *, const char *);
117 +#endif /* SSH_PKCS11_DISABLED */
118 +
119 #endif /* AUTHFD_H */
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
123 @@ -0,0 +1,49 @@
124 +20061023
125 + - (alonbl) Removed logit from ssh-agent, thanks to Denniston, Todd.
126 + - (alonbl) Release 0.17
127 +
128 +20061020
129 + - (alonbl) Major modification of ssh-add command-line parameters.
130 + Now, a complete serialized certificate needs to be specified, this
131 + in order to allow people to add id without forcing card to be available.
132 + But to allow complete silent addition a certificate file also needed.
133 + --pkcs11-show-ids is used in order to get a list of resources.
134 + --pkcs11-add-id --pkcs11-id <serialized id> \
135 + [--pkcs11-cert-file <cert_file>]
136 + - (alonbl) PKCS#11 release 0.16
137 +
138 +20061012
139 + - (alonbl) OpenSC bug workaround.
140 + - (alonbl) PKCS#11 release 0.15
141 +
142 +20060930
143 + - (alonbl) Some pkcs11-helper updates.
144 + - (alonbl) Rebase against 4.4p1.
145 + - (alonbl) PKCS#11 release 0.14
146 +
147 +20060709
148 + - (alonbl) PKCS#11 fixed handling multiproviders.
149 + - (alonbl) PKCS#11 release 0.13
150 +
151 +20060608
152 + - (alonbl) PKCS#11 modifed to match X.509-5.5 patch, works OK with focing
153 + ssh-rsa id.
154 + - (alonbl) PKCS#11 removed --pkcs11-x509-force-ssh argument.
155 + - (alonbl) PKCS#11 release 0.12
156 +
157 +20060527
158 + - (alonbl) PKCS#11 fix issues with gcc-2
159 + - (alonbl) PKCS#11 fix issues with openssl-0.9.6 (first) version.
160 + - (alonbl) PKCS#11 modified to match X.509-5.4 patch.
161 + - (alonbl) PKCS#11 add --pkcs11-x509-force-ssh argument to force ssh id out
162 + of X.509 certificate.
163 + - (alonbl) PKCS#11 release 0.11
164 +
165 +20060419
166 + - (alonbl) PKCS#11 fix handling empty attributes.
167 + - (alonbl) PKCS#11 release 0.10
168 +
169 +20060404
170 + - (alonbl) PKCS#11 code sync.
171 + - (alonbl) PKCS#11 release 0.09
172 +
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
179
180 +/* Define if you don't want use PKCS#11 */
181 +#undef SSH_PKCS11_DISABLED
182 +
183 +/* Define if you don't want use X509 with PKCS#11 */
184 +#undef SSH_PKCS11_X509_DISABLED
185 +
186 /* non-privileged user for privilege separation */
187 #undef SSH_PRIVSEP_USER
188
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
197
198 Optional Packages:
199 --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
200 @@ -32163,6 +32164,33 @@ if test ! -z "$blibpath" ; then
201 echo "$as_me: WARNING: Please check and edit blibpath in LDFLAGS in Makefile" >&2;}
202 fi
203
204 +ssh_pkcs11="yes"
205 +ssh_pkcs11_x509="yes"
206 +# Check whether --enable-pkcs11 was given.
207 +if test "${enable_pkcs11+set}" = set; then
208 + enableval=$enable_pkcs11;
209 + if test "x$enableval" = "xno"; then
210 + ssh_pkcs11="no"
211 + fi
212 +
213 +
214 +fi
215 +
216 +if test "x$ssh_pkcs11" = "xno"; then
217 +
218 +cat >>confdefs.h <<_ACEOF
219 +#define SSH_PKCS11_DISABLED 1
220 +_ACEOF
221 +
222 +fi
223 +if test "x$ssh_x509" = "x"; then
224 +
225 +cat >>confdefs.h <<_ACEOF
226 +#define SSH_PKCS11_X509_DISABLED 1
227 +_ACEOF
228 +
229 +fi
230 +
231 CFLAGS="$CFLAGS $werror_flags"
232
233
234 @@ -33415,6 +33443,7 @@ echo " IP address in \$DISPLAY hac
235 echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG"
236 echo " BSD Auth support: $BSD_AUTH_MSG"
237 echo " Random number source: $RAND_MSG"
238 +echo " PKCS#11 support: $ssh_pkcs11"
239 if test ! -z "$USE_RAND_HELPER" ; then
240 echo " ssh-rand-helper collects from: $RAND_HELPER_MSG"
241 fi
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])
247 fi
248
249 +ssh_pkcs11="yes"
250 +ssh_pkcs11_x509="yes"
251 +AC_ARG_ENABLE(pkcs11,
252 + [ --disable-pkcs11 Disable PKCS#11 support],
253 + [
254 + if test "x$enableval" = "xno"; then
255 + ssh_pkcs11="no"
256 + fi
257 + ]
258 +)
259 +if test "x$ssh_pkcs11" = "xno"; then
260 + AC_DEFINE_UNQUOTED(
261 + SSH_PKCS11_DISABLED, 1,
262 + [Define if you don't want use PKCS#11])
263 +fi
264 +if test "x$ssh_x509" = "x"; then
265 + AC_DEFINE_UNQUOTED(
266 + SSH_PKCS11_X509_DISABLED, 1,
267 + [Define if you don't want use X509 with PKCS#11])
268 +fi
269 +
270 dnl Adding -Werror to CFLAGS early prevents configure tests from running.
271 dnl Add now.
272 CFLAGS="$CFLAGS $werror_flags"
273 @@ -3973,6 +3994,7 @@ echo " IP address in \$DISPLAY hac
274 echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG"
275 echo " BSD Auth support: $BSD_AUTH_MSG"
276 echo " Random number source: $RAND_MSG"
277 +echo " PKCS#11 support: $ssh_pkcs11"
278 if test ! -z "$USE_RAND_HELPER" ; then
279 echo " ssh-rand-helper collects from: $RAND_HELPER_MSG"
280 fi
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
284 @@ -0,0 +1,35 @@
285 +/* cryptoki.h include file for PKCS #11. */
286 +/* $Revision: 1.4 $ */
287 +
288 +/* License to copy and use this software is granted provided that it is
289 + * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
290 + * (Cryptoki)" in all material mentioning or referencing this software.
291 +
292 + * License is also granted to make and use derivative works provided that
293 + * such works are identified as "derived from the RSA Security Inc. PKCS #11
294 + * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
295 + * referencing the derived work.
296 +
297 + * RSA Security Inc. makes no representations concerning either the
298 + * merchantability of this software or the suitability of this software for
299 + * any particular purpose. It is provided "as is" without express or implied
300 + * warranty of any kind.
301 + */
302 +
303 +#ifndef ___CRYPTOKI_H_INC___
304 +#define ___CRYPTOKI_H_INC___
305 +
306 +#define CK_PTR *
307 +
308 +#define CK_DEFINE_FUNCTION(returnType, name) returnType name
309 +#define CK_DECLARE_FUNCTION(returnType, name) returnType name
310 +#define CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name)
311 +#define CK_CALLBACK_FUNCTION(returnType, name) returnType (* name)
312 +
313 +#ifndef NULL_PTR
314 +#define NULL_PTR 0
315 +#endif
316 +
317 +#include "pkcs11-headers/pkcs11.h"
318 +
319 +#endif /* ___CRYPTOKI_H_INC___ */
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
323 @@ -0,0 +1,66 @@
324 +/* cryptoki.h include file for PKCS #11. */
325 +/* $Revision: 1.4 $ */
326 +
327 +/* License to copy and use this software is granted provided that it is
328 + * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
329 + * (Cryptoki)" in all material mentioning or referencing this software.
330 +
331 + * License is also granted to make and use derivative works provided that
332 + * such works are identified as "derived from the RSA Security Inc. PKCS #11
333 + * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
334 + * referencing the derived work.
335 +
336 + * RSA Security Inc. makes no representations concerning either the
337 + * merchantability of this software or the suitability of this software for
338 + * any particular purpose. It is provided "as is" without express or implied
339 + * warranty of any kind.
340 + */
341 +
342 +/* This is a sample file containing the top level include directives
343 + * for building Win32 Cryptoki libraries and applications.
344 + */
345 +
346 +#ifndef ___CRYPTOKI_H_INC___
347 +#define ___CRYPTOKI_H_INC___
348 +
349 +#pragma pack(push, cryptoki, 1)
350 +
351 +/* Specifies that the function is a DLL entry point. */
352 +#define CK_IMPORT_SPEC __declspec(dllimport)
353 +
354 +/* Define CRYPTOKI_EXPORTS during the build of cryptoki libraries. Do
355 + * not define it in applications.
356 + */
357 +#ifdef CRYPTOKI_EXPORTS
358 +/* Specified that the function is an exported DLL entry point. */
359 +#define CK_EXPORT_SPEC __declspec(dllexport)
360 +#else
361 +#define CK_EXPORT_SPEC CK_IMPORT_SPEC
362 +#endif
363 +
364 +/* Ensures the calling convention for Win32 builds */
365 +#define CK_CALL_SPEC __cdecl
366 +
367 +#define CK_PTR *
368 +
369 +#define CK_DEFINE_FUNCTION(returnType, name) \
370 + returnType CK_EXPORT_SPEC CK_CALL_SPEC name
371 +
372 +#define CK_DECLARE_FUNCTION(returnType, name) \
373 + returnType CK_EXPORT_SPEC CK_CALL_SPEC name
374 +
375 +#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
376 + returnType CK_IMPORT_SPEC (CK_CALL_SPEC CK_PTR name)
377 +
378 +#define CK_CALLBACK_FUNCTION(returnType, name) \
379 + returnType (CK_CALL_SPEC CK_PTR name)
380 +
381 +#ifndef NULL_PTR
382 +#define NULL_PTR 0
383 +#endif
384 +
385 +#include "pkcs11-headers/pkcs11.h"
386 +
387 +#pragma pack(pop, cryptoki)
388 +
389 +#endif /* ___CRYPTOKI_H_INC___ */
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.
394 * authorization. *
395 ****************************************************************************/
396
397 + d) PKCS #11: Cryptographic Token Interface Standard
398 +
399 + This software uses RSA Security Inc. PKCS #11 Cryptographic Token Interface (Cryptoki).
400
401 ------
402 $OpenBSD: LICENCE,v 1.19 2004/08/30 09:18:08 markus Exp $
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
407
408 LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \
409 canohost.o channels.o cipher.o cipher-acss.o cipher-aes.o \
410 + pkcs11.o pkcs11-helper.o \
411 cipher-bf1.o cipher-ctr.o cipher-3des1.o cleanup.o \
412 compat.o compress.o crc32.o deattack.o fatal.o hostfile.o \
413 log.o match.o md-sha256.o moduli.o nchan.o packet.o \
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
417 @@ -0,0 +1,1139 @@
418 +/*
419 + * Copyright (c) 2005-2006 Alon Bar-Lev. All rights reserved.
420 + *
421 + * Redistribution and use in source and binary forms, with or without
422 + * modification, are permitted provided that the following conditions
423 + * are met:
424 + * 1. Redistributions of source code must retain the above copyright
425 + * notice, this list of conditions and the following disclaimer.
426 + * 2. Redistributions in binary form must reproduce the above copyright
427 + * notice, this list of conditions and the following disclaimer in the
428 + * documentation and/or other materials provided with the distribution.
429 + *
430 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
431 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
432 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
433 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
434 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
435 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
436 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
437 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
438 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
439 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
440 + */
441 +
442 +/*
443 + * The routines in this file deal with providing private key cryptography
444 + * using RSA Security Inc. PKCS #11 Cryptographic Token Interface (Cryptoki).
445 + *
446 + */
447 +
448 +#include "includes.h"
449 +#include <sys/wait.h>
450 +#include <errno.h>
451 +
452 +#if !defined(SSH_PKCS11_DISABLED)
453 +
454 +#include "pkcs11-helper.h"
455 +#include "pkcs11.h"
456 +#include "openssl/pem.h"
457 +#include "misc.h"
458 +
459 +static
460 +char *
461 +ssh_from_x509 (X509 *x509);
462 +
463 +static char *s_szSetPINProg = NULL;
464 +
465 +static
466 +unsigned
467 +_pkcs11_msg_pkcs112openssh (
468 + IN const unsigned flags
469 +) {
470 + unsigned openssh_flags;
471 +
472 + switch (flags) {
473 + case PKCS11H_LOG_DEBUG2:
474 + openssh_flags = SYSLOG_LEVEL_DEBUG3;
475 + break;
476 + case PKCS11H_LOG_DEBUG1:
477 + openssh_flags = SYSLOG_LEVEL_DEBUG2;
478 + break;
479 + case PKCS11H_LOG_INFO:
480 + openssh_flags = SYSLOG_LEVEL_INFO;
481 + break;
482 + case PKCS11H_LOG_WARN:
483 + openssh_flags = SYSLOG_LEVEL_ERROR;
484 + break;
485 + case PKCS11H_LOG_ERROR:
486 + openssh_flags = SYSLOG_LEVEL_FATAL;
487 + break;
488 + default:
489 + openssh_flags = SYSLOG_LEVEL_FATAL;
490 + break;
491 + }
492 +
493 + return openssh_flags;
494 +}
495 +
496 +static
497 +unsigned
498 +_pkcs11_msg_openssh2pkcs11 (
499 + IN const unsigned flags
500 +) {
501 + unsigned pkcs11_flags;
502 +
503 + switch (flags) {
504 + case SYSLOG_LEVEL_DEBUG3:
505 + pkcs11_flags = PKCS11H_LOG_DEBUG2;
506 + break;
507 + case SYSLOG_LEVEL_DEBUG2:
508 + pkcs11_flags = PKCS11H_LOG_DEBUG1;
509 + break;
510 + case SYSLOG_LEVEL_INFO:
511 + pkcs11_flags = PKCS11H_LOG_INFO;
512 + break;
513 + case SYSLOG_LEVEL_ERROR:
514 + pkcs11_flags = PKCS11H_LOG_WARN;
515 + break;
516 + case SYSLOG_LEVEL_FATAL:
517 + pkcs11_flags = PKCS11H_LOG_ERROR;
518 + break;
519 + default:
520 + pkcs11_flags = PKCS11H_LOG_ERROR;
521 + break;
522 + }
523 +
524 + return pkcs11_flags;
525 +}
526 +
527 +static
528 +void
529 +_pkcs11_openssh_log (
530 + IN void * const pData,
531 + IN unsigned flags,
532 + IN const char * const szFormat,
533 + IN va_list args
534 +) {
535 + do_log (_pkcs11_msg_pkcs112openssh (flags), szFormat, args);
536 +}
537 +
538 +static
539 +int
540 +_pkcs11_ssh_prompt (
541 + IN const char * const szType,
542 + IN const char * const szPrompt,
543 + OUT char * const szInput,
544 + IN const int nMaxInput
545 +) {
546 + pid_t pid = -1;
547 + int fds[2] = {-1, -1};
548 + int fOK = TRUE;
549 +
550 + /*
551 + * Make sure we don't reuse PIN
552 + */
553 + if (fOK) {
554 + memset (szInput, 0, nMaxInput);
555 + }
556 +
557 + if (fOK && s_szSetPINProg == NULL) {
558 + fOK = FALSE;
559 + }
560 +
561 + if (fOK && pipe (fds) == -1) {
562 + fOK = FALSE;
563 + }
564 +
565 + if (fOK && (pid = fork ()) == -1) {
566 + fOK = FALSE;
567 + }
568 +
569 + if (fOK) {
570 + if (pid == 0) {
571 + close (fds[0]);
572 + fds[0] = -1;
573 +
574 + if (fOK && dup2 (fds[1], 1) == -1) {
575 + fOK = FALSE;
576 + }
577 + if (fOK) {
578 + close (fds[1]);
579 + fds[1] = -1;
580 + }
581 +
582 + if (fOK) {
583 + execl (
584 + s_szSetPINProg,
585 + s_szSetPINProg,
586 + "-t",
587 + szType,
588 + szPrompt,
589 + NULL
590 + );
591 + }
592 +
593 + exit (1);
594 + }
595 + else {
596 + int status;
597 + int r = 0;
598 +
599 + close (fds[1]);
600 + fds[1] = -1;
601 +
602 + if (fOK) {
603 + while (
604 + (r=waitpid (pid, &status, 0)) == 0 ||
605 + (r == -1 && errno == EINTR)
606 + );
607 +
608 + if (r == -1) {
609 + fOK = FALSE;
610 + }
611 + }
612 +
613 + if (fOK && !WIFEXITED (status)) {
614 + fOK = FALSE;
615 + }
616 +
617 + if (fOK && WEXITSTATUS (status) != 0) {
618 + fOK = FALSE;
619 + }
620 +
621 + if (fOK) {
622 + if (!strcmp (szType, "password")) {
623 + if ((r = read (fds[0], szInput, nMaxInput)) == -1) {
624 + fOK = FALSE;
625 + r = 0;
626 + }
627 + }
628 + else {
629 + r = 0;
630 + }
631 + szInput[r] = '\0';
632 + }
633 +
634 + if (fOK) {
635 + if (strlen (szInput) > 0 && szInput[strlen (szInput)-1] == '\n') {
636 + szInput[strlen (szInput)-1] = '\0';
637 + }
638 + /*
639 + * for DOS compatability
640 + */
641 + if (strlen (szInput) > 0 && szInput[strlen (szInput)-1] == '\r') {
642 + szInput[strlen (szInput)-1] = '\0';
643 + }
644 + }
645 + }
646 + }
647 +
648 + if (fds[0] != -1) {
649 + close (fds[0]);
650 + fds[0] = -1;
651 + }
652 +
653 + if (fds[1] != -1) {
654 + close (fds[1]);
655 + fds[1] = -1;
656 + }
657 +
658 + return fOK;
659 +}
660 +
661 +static
662 +void
663 +_pkcs11_ssh_print (
664 + IN void * const pData,
665 + IN const char * const szFormat,
666 + IN ...
667 +) {
668 + va_list args;
669 +
670 + va_start (args, szFormat);
671 + vprintf (szFormat, args);
672 + va_end (args);
673 +}
674 +
675 +static
676 +PKCS11H_BOOL
677 +_pkcs11_ssh_token_prompt (
678 + IN void * const pData1,
679 + IN void * const pData2,
680 + IN const pkcs11h_token_id_t token,
681 + IN const unsigned retry
682 +) {
683 + char szPrompt[1024];
684 + char szPIN[1024];
685 +
686 + snprintf (szPrompt, sizeof (szPrompt), "Please insert token '%s' or cancel", token->display);
687 + return _pkcs11_ssh_prompt ("okcancel", szPrompt, szPIN, sizeof (szPIN));
688 +}
689 +
690 +static
691 +PKCS11H_BOOL
692 +_pkcs11_ssh_pin_prompt (
693 + IN void * const pData1,
694 + IN void * const pData2,
695 + IN const pkcs11h_token_id_t token,
696 + IN const unsigned retry,
697 + OUT char * const szPIN,
698 + IN const size_t nMaxPIN
699 +) {
700 + char szPrompt[1024];
701 +
702 + snprintf (szPrompt, sizeof (szPrompt), "Please enter PIN for token '%s'", token->display);
703 + return _pkcs11_ssh_prompt ("password", szPrompt, szPIN, nMaxPIN);
704 +}
705 +
706 +static
707 +PKCS11H_BOOL
708 +_pkcs11_ssh_pin_prompt_cli (
709 + IN void * const pData1,
710 + IN void * const pData2,
711 + IN const pkcs11h_token_id_t token,
712 + IN const unsigned retry,
713 + OUT char * const szPIN,
714 + IN const size_t nMaxPIN
715 +) {
716 + char szPrompt[1024];
717 + snprintf (szPrompt, sizeof (szPrompt), "Please enter '%s' PIN or 'cancel': ", token->display);
718 + char *p = getpass (szPrompt);
719 +
720 + strncpy (szPIN, p, nMaxPIN);
721 + szPIN[nMaxPIN-1] = '\0';
722 +
723 + return strcmp (szPIN, "cancel") != 0;
724 +}
725 +
726 +void
727 +_pkcs11_do_log (
728 + IN LogLevel l,
729 + IN const char *f,
730 + IN ...
731 +) {
732 + va_list args;
733 + va_start (args, f);
734 + do_log (l, f, args);
735 + va_end (args);
736 +}
737 +
738 +int
739 +pkcs11_initialize (
740 + const int fProtectedAuthentication,
741 + const int nPINCachePeriod
742 +) {
743 + CK_RV rv = CKR_OK;
744 +
745 + debug3 (
746 + "PKCS#11: pkcs11_initialize - entered fProtectedAuthentication=%d, nPINCachePeriod=%d",
747 + fProtectedAuthentication,
748 + nPINCachePeriod
749 + );
750 +
751 + if (
752 + rv == CKR_OK &&
753 + (rv = pkcs11h_initialize ()) != CKR_OK
754 + ) {
755 + error ("PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage (rv));
756 + }
757 +
758 + if (
759 + rv == CKR_OK &&
760 + (rv = pkcs11h_setLogHook (_pkcs11_openssh_log, NULL)) != CKR_OK
761 + ) {
762 + error ("PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv));
763 + }
764 +
765 + /*
766 + * WARNING!!!
767 + * There is no way to get log level,
768 + * so set to minimum.
769 + * After fix in log.c it can be fixed.
770 + */
771 + if (rv == CKR_OK) {
772 + pkcs11h_setLogLevel (_pkcs11_msg_openssh2pkcs11 (SYSLOG_LEVEL_DEBUG3));
773 + }
774 +
775 + if (
776 + rv == CKR_OK &&
777 + (rv = pkcs11h_setTokenPromptHook (_pkcs11_ssh_token_prompt, NULL)) != CKR_OK
778 + ) {
779 + error ("PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv));
780 + }
781 +
782 + if (
783 + rv == CKR_OK &&
784 + (rv = pkcs11h_setPINPromptHook (_pkcs11_ssh_pin_prompt, NULL)) != CKR_OK
785 + ) {
786 + error ("PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv));
787 + }
788 +
789 + if (
790 + rv == CKR_OK &&
791 + (rv = pkcs11h_setProtectedAuthentication (fProtectedAuthentication)) != CKR_OK
792 + ) {
793 + error ("PKCS#11: Cannot set protected authentication mode %ld-'%s'", rv, pkcs11h_getMessage (rv));
794 + }
795 +
796 + if (
797 + rv == CKR_OK &&
798 + (rv = pkcs11h_setPINCachePeriod (nPINCachePeriod)) != CKR_OK
799 + ) {
800 + error ("PKCS#11: Cannot set PIN cache period %ld-'%s'", rv, pkcs11h_getMessage (rv));
801 + }
802 +
803 + debug3 (
804 + "PKCS#11: pkcs11_initialize - return rv=%ld-'%s'",
805 + rv,
806 + pkcs11h_getMessage (rv)
807 + );
808 +
809 + return rv == CKR_OK;
810 +}
811 +
812 +void
813 +pkcs11_terminate () {
814 + debug3 ("PKCS#11: pkcs11_terminate - entered");
815 +
816 + pkcs11h_terminate ();
817 +
818 + debug3 ("PKCS#11: pkcs11_terminate - return");
819 +}
820 +
821 +void
822 +pkcs11_forkFix () {
823 + pkcs11h_forkFixup ();
824 +}
825 +
826 +int
827 +pkcs11_setAskPIN (
828 + const char * const pin_prog
829 +) {
830 + if (pin_prog != NULL) {
831 + if (s_szSetPINProg != NULL) {
832 + xfree (s_szSetPINProg);
833 + s_szSetPINProg = NULL;
834 + }
835 +
836 + s_szSetPINProg = xstrdup (pin_prog);
837 + }
838 +
839 + return 1;
840 +}
841 +
842 +int
843 +pkcs11_addProvider (
844 + const char * const provider,
845 + const int fProtectedAuthentication,
846 + const char * const sign_mode,
847 + const int fCertIsPrivate
848 +) {
849 + unsigned maskSignMode = 0;
850 + CK_RV rv = CKR_OK;
851 +
852 + PKCS11H_ASSERT (provider != NULL);
853 + PKCS11H_ASSERT (sign_mode != NULL);
854 +
855 + debug3 (
856 + "PKCS#11: pkcs11_addProvider - entered - provider='%s', fProtectedAuthentication=%d, sign_mode='%s', fCertIsPrivate=%d",
857 + provider,
858 + fProtectedAuthentication ? 1 : 0,
859 + sign_mode == NULL ? "default" : sign_mode,
860 + fCertIsPrivate ? 1 : 0
861 + );
862 +
863 + debug (
864 + "PKCS#11: Adding PKCS#11 provider '%s'",
865 + provider
866 + );
867 +
868 + if (rv == CKR_OK) {
869 + if (sign_mode == NULL || !strcmp (sign_mode, "auto")) {
870 + maskSignMode = 0;
871 + }
872 + else if (!strcmp (sign_mode, "sign")) {
873 + maskSignMode = PKCS11H_SIGNMODE_MASK_SIGN;
874 + }
875 + else if (!strcmp (sign_mode, "recover")) {
876 + maskSignMode = PKCS11H_SIGNMODE_MASK_RECOVER;
877 + }
878 + else if (!strcmp (sign_mode, "any")) {
879 + maskSignMode = (
880 + PKCS11H_SIGNMODE_MASK_SIGN |
881 + PKCS11H_SIGNMODE_MASK_RECOVER
882 + );
883 + }
884 + else {
885 + error ("PKCS#11: Invalid sign mode '%s'", sign_mode);
886 + rv = CKR_ARGUMENTS_BAD;
887 + }
888 + }
889 +
890 + if (
891 + rv == CKR_OK &&
892 + (rv = pkcs11h_addProvider (
893 + provider,
894 + provider,
895 + fProtectedAuthentication,
896 + maskSignMode,
897 + PKCS11H_SLOTEVENT_METHOD_AUTO,
898 + 0,
899 + fCertIsPrivate
900 + )) != CKR_OK
901 + ) {
902 + error ("PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv, pkcs11h_getMessage (rv));
903 + }
904 +
905 + debug3 (
906 + "PKCS#11: pkcs11_addProvider - return rv=%ld-'%s'",
907 + rv,
908 + pkcs11h_getMessage (rv)
909 + );
910 +
911 + return rv == CKR_OK;
912 +}
913 +
914 +pkcs11_identity *
915 +pkcs11_identity_new () {
916 + pkcs11_identity *id = xmalloc (sizeof (struct pkcs11_identity_s));
917 + if (id != NULL) {
918 + memset (id, 0, sizeof (struct pkcs11_identity_s));
919 + }
920 + return id;
921 +}
922 +
923 +void
924 +pkcs11_identity_free (
925 + const pkcs11_identity * const id
926 +) {
927 + if (id != NULL) {
928 + xfree ((void *)id);
929 + }
930 +}
931 +
932 +void
933 +pkcs11_getKey (
934 + IN const pkcs11_identity * const id,
935 + OUT Key ** const sshkey,
936 + OUT char * const szComment,
937 + IN const int nCommentMax
938 +) {
939 + X509 *x509 = NULL;
940 + RSA *rsa = NULL;
941 + pkcs11h_certificate_id_t certificate_id = NULL;
942 + pkcs11h_certificate_t certificate = NULL;
943 + pkcs11h_openssl_session_t openssl_session = NULL;
944 + size_t temp;
945 + CK_RV rv = CKR_OK;
946 +
947 + int fOK = TRUE;
948 +
949 + debug3 (
950 + "PKCS#11: pkcs11_getKey - entered - id=%p, sshkey=%p, szComment=%p, nCommentMax=%d",
951 + (void *)id,
952 + (void *)sshkey,
953 + (void *)szComment,
954 + nCommentMax
955 + );
956 +
957 + PKCS11H_ASSERT (id != NULL);
958 + PKCS11H_ASSERT (sshkey!=NULL);
959 + PKCS11H_ASSERT (szComment!=NULL);
960 +
961 + debug3 (
962 + "PKCS#11: pkcs11_getKey - id - id=%s, pin_cache_period=%d, cert_file=%s",
963 + id->id,
964 + id->pin_cache_period,
965 + id->cert_file
966 + );
967 +
968 + PKCS11H_ASSERT (id->id);
969 +
970 + if (
971 + fOK &&
972 + pkcs11h_certificate_deserializeCertificateId (&certificate_id, id->id)
973 + ) {
974 + fOK = FALSE;
975 + error ("PKCS#11: Cannot deserialize id %ld-'%s'", rv, pkcs11h_getMessage (rv));
976 + }
977 +
978 + if (
979 + fOK &&
980 + id->cert_file != NULL &&
981 + id->cert_file[0] != '\x0'
982 + ) {
983 + X509 *x509 = NULL;
984 + unsigned char *p = NULL;
985 + unsigned char *certificate_blob = NULL;
986 + size_t certificate_blob_size = 0;
987 + FILE *fp = NULL;
988 +
989 + if (
990 + fOK &&
991 + (fp = fopen (id->cert_file, "r")) == NULL
992 + ) {
993 + fOK = FALSE;
994 + error ("PKCS#11: Cannot open file '%s'", id->cert_file);
995 + }
996 +
997 + if (
998 + fOK &&
999 + !PEM_read_X509 (
1000 + fp,
1001 + &x509,
1002 + NULL,
1003 + 0
1004 + )
1005 + ) {
1006 + x509 = NULL;
1007 + fOK = FALSE;
1008 + error ("PKCS#11: Cannot read PEM from file '%s'", id->cert_file);
1009 + }
1010 +
1011 + if (
1012 + fOK &&
1013 + (certificate_blob_size = i2d_X509 (x509, NULL)) < 0
1014 + ) {
1015 + fOK = FALSE;
1016 + error ("PKCS#11: Cannot read decode certificate");
1017 + }
1018 +
1019 + if (
1020 + fOK &&
1021 + (certificate_blob = (unsigned char *)xmalloc (certificate_blob_size)) == NULL
1022 + ) {
1023 + fOK = FALSE;
1024 + error ("PKCS#11: Cannot allocate memory");
1025 + }
1026 +
1027 + /*
1028 + * i2d_X509 increments p!!!
1029 + */
1030 + p = certificate_blob;
1031 +
1032 + if (
1033 + fOK &&
1034 + (certificate_blob_size = i2d_X509 (x509, &p)) < 0
1035 + ) {
1036 + fOK = FALSE;
1037 + error ("PKCS#11: Cannot read decode certificate");
1038 + }
1039 +
1040 + if (
1041 + fOK &&
1042 + pkcs11h_certificate_setCertificateIdCertificateBlob (
1043 + certificate_id,
1044 + certificate_blob,
1045 + certificate_blob_size
1046 + ) != CKR_OK
1047 + ) {
1048 + fOK = FALSE;
1049 + error ("PKCS#11: Cannot set certificate blob %ld-'%s'", rv, pkcs11h_getMessage (rv));
1050 + }
1051 +
1052 + if (x509 != NULL) {
1053 + X509_free (x509);
1054 + x509 = NULL;
1055 + }
1056 +
1057 + if (certificate_blob != NULL) {
1058 + xfree (certificate_blob);
1059 + certificate_blob = NULL;
1060 + }
1061 +
1062 + if (fp != NULL) {
1063 + fclose (fp);
1064 + fp = NULL;
1065 + }
1066 + }
1067 +
1068 + if (
1069 + fOK &&
1070 + (rv = pkcs11h_certificate_create (
1071 + certificate_id,
1072 + NULL,
1073 + PKCS11H_PROMPT_MASK_ALLOW_ALL,
1074 + id->pin_cache_period,
1075 + &certificate
1076 + )) != CKR_OK
1077 + ) {
1078 + fOK = FALSE;
1079 + error ("PKCS#11: Cannot get certificate %ld-'%s'", rv, pkcs11h_getMessage (rv));
1080 + }
1081 +
1082 + if (certificate_id != NULL){
1083 + pkcs11h_certificate_freeCertificateId (certificate_id);
1084 + certificate_id = NULL;
1085 + }
1086 +
1087 + /*
1088 + * Is called so next certificate_id will
1089 + * contain a proper description
1090 + */
1091 + if (
1092 + fOK &&
1093 + (rv = pkcs11h_certificate_getCertificateBlob (
1094 + certificate,
1095 + NULL,
1096 + &temp
1097 + )) != CKR_OK
1098 + ) {
1099 + fOK = FALSE;
1100 + error ("PKCS#11: Cannot get certificate blob %ld-'%s'", rv, pkcs11h_getMessage (rv));
1101 + }
1102 +
1103 + if (
1104 + fOK &&
1105 + (rv = pkcs11h_certificate_getCertificateId (
1106 + certificate,
1107 + &certificate_id
1108 + )) != CKR_OK
1109 + ) {
1110 + fOK = FALSE;
1111 + error ("PKCS#11: Cannot get certificate_id %ld-'%s'", rv, pkcs11h_getMessage (rv));
1112 + }
1113 +
1114 + if (fOK) {
1115 + strncpy (szComment, certificate_id->displayName, nCommentMax);
1116 + szComment[nCommentMax - 1] = '\0';
1117 + }
1118 +
1119 + if (
1120 + fOK &&
1121 + (openssl_session = pkcs11h_openssl_createSession (certificate)) == NULL
1122 + ) {
1123 + fOK = FALSE;
1124 + error ("PKCS#11: Cannot initialize openssl session");
1125 + }
1126 +
1127 + if (fOK) {
1128 + /*
1129 + * will be release by openssl_session
1130 + */
1131 + certificate = NULL;
1132 + }
1133 +
1134 + if (
1135 + fOK &&
1136 + (rsa = pkcs11h_openssl_session_getRSA (openssl_session)) == NULL
1137 + ) {
1138 + fOK = FALSE;
1139 + error ("PKCS#11: Unable get rsa object");
1140 + }
1141 +
1142 + if (
1143 + fOK &&
1144 + (x509 = pkcs11h_openssl_session_getX509 (openssl_session)) == NULL
1145 + ) {
1146 + fOK = FALSE;
1147 + error ("PKCS#11: Unable get certificate object");
1148 + }
1149 +
1150 + if (fOK) {
1151 + *sshkey = key_new_private (KEY_UNSPEC);
1152 + (*sshkey)->rsa = rsa;
1153 + rsa = NULL;
1154 +#if defined(SSH_PKCS11_X509_DISABLED)
1155 + (*sshkey)->type = KEY_RSA;
1156 +#else
1157 + (*sshkey)->type = KEY_X509_RSA;
1158 + (*sshkey)->x509 = x509;
1159 + x509 = NULL;
1160 +#endif
1161 + }
1162 +
1163 + if (x509 != NULL) {
1164 + X509_free (x509);
1165 + x509 = NULL;
1166 + }
1167 +
1168 + if (openssl_session != NULL) {
1169 + pkcs11h_openssl_freeSession (openssl_session);
1170 + openssl_session = NULL;
1171 + }
1172 +
1173 + if (certificate != NULL) {
1174 + pkcs11h_certificate_freeCertificate (certificate);
1175 + certificate = NULL;
1176 + }
1177 +
1178 + if (certificate_id != NULL) {
1179 + pkcs11h_certificate_freeCertificateId (certificate_id);
1180 + certificate_id = NULL;
1181 + }
1182 +
1183 + debug3 (
1184 + "PKCS#11: pkcs11_getKey - return fOK=%d, rv=%ld",
1185 + fOK ? 1 : 0,
1186 + rv
1187 + );
1188 +}
1189 +
1190 +void
1191 +pkcs11_show_ids (
1192 + const char * const provider,
1193 + int allow_protected_auth,
1194 + int cert_is_private
1195 +) {
1196 + pkcs11h_certificate_id_list_t user_certificates = NULL;
1197 + pkcs11h_certificate_id_list_t current = NULL;
1198 + CK_RV rv = CKR_OK;
1199 +
1200 + if (rv == CKR_OK) {
1201 + rv = pkcs11h_initialize ();
1202 + }
1203 +
1204 + if (rv == CKR_OK) {
1205 + rv = pkcs11h_setLogHook (_pkcs11_openssh_log, NULL);
1206 + }
1207 +
1208 + if (rv == CKR_OK) {
1209 + pkcs11h_setLogLevel (_pkcs11_msg_openssh2pkcs11 (SYSLOG_LEVEL_DEBUG3));
1210 + }
1211 +
1212 + if (rv == CKR_OK) {
1213 + rv = pkcs11h_setPINPromptHook (_pkcs11_ssh_pin_prompt_cli, NULL);
1214 + }
1215 +
1216 + if (rv == CKR_OK) {
1217 + rv = pkcs11h_setProtectedAuthentication (TRUE);
1218 + }
1219 +
1220 + if (rv == CKR_OK) {
1221 + rv = pkcs11h_addProvider (
1222 + provider,
1223 + provider,
1224 + allow_protected_auth ? TRUE : FALSE,
1225 + 0,
1226 + FALSE,
1227 + 0,
1228 + cert_is_private ? TRUE : FALSE
1229 + );
1230 + }
1231 +
1232 + if (rv == CKR_OK) {
1233 + rv = pkcs11h_certificate_enumCertificateIds (
1234 + PKCS11H_ENUM_METHOD_CACHE_EXIST,
1235 + NULL,
1236 + PKCS11H_PROMPT_MASK_ALLOW_ALL,
1237 + NULL,
1238 + &user_certificates
1239 + );
1240 + }
1241 +
1242 + for (current = user_certificates; rv == CKR_OK && current != NULL; current = current->next) {
1243 + pkcs11h_certificate_t certificate = NULL;
1244 + X509 *x509 = NULL;
1245 + char dn[1024] = {0};
1246 + char *ser = NULL;
1247 + char *ssh_key = NULL;
1248 + size_t ser_len = 0;
1249 +
1250 + if (rv == CKR_OK) {
1251 + rv = pkcs11h_certificate_serializeCertificateId (NULL, &ser_len, current->certificate_id);
1252 + }
1253 +
1254 + if (
1255 + rv == CKR_OK &&
1256 + (ser = (char *)xmalloc (ser_len)) == NULL
1257 + ) {
1258 + rv = CKR_HOST_MEMORY;
1259 + }
1260 +
1261 + if (rv == CKR_OK) {
1262 + rv = pkcs11h_certificate_serializeCertificateId (ser, &ser_len, current->certificate_id);
1263 + }
1264 +
1265 + if (rv == CKR_OK) {
1266 + rv = pkcs11h_certificate_create (
1267 + current->certificate_id,
1268 + NULL,
1269 + PKCS11H_PROMPT_MASK_ALLOW_ALL,
1270 + PKCS11H_PIN_CACHE_INFINITE,
1271 + &certificate
1272 + );
1273 + }
1274 +
1275 + if (
1276 + rv == CKR_OK &&
1277 + (x509 = pkcs11h_openssl_getX509 (certificate)) == NULL
1278 + ) {
1279 + rv = CKR_FUNCTION_FAILED;
1280 + }
1281 +
1282 + if (rv == CKR_OK) {
1283 + X509_NAME_oneline (
1284 + X509_get_subject_name (x509),
1285 + dn,
1286 + sizeof (dn)
1287 + );
1288 + printf (
1289 + (
1290 + "\n"
1291 + "********************************************\n"
1292 + "IDENTITY:\n"
1293 + " DN: %s\n"
1294 + " Serialized id: %s\n"
1295 + "\n"
1296 + " Certificate:\n"
1297 + ),
1298 + dn,
1299 + ser
1300 + );
1301 + PEM_write_X509 (stdout, x509);
1302 + }
1303 +
1304 + if (
1305 + rv == CKR_OK &&
1306 + (ssh_key = ssh_from_x509 (x509)) != NULL
1307 + ) {
1308 + printf (
1309 + (
1310 + "\n"
1311 + " SSH:\n"
1312 + "%s\n"
1313 + ),
1314 + ssh_key
1315 + );
1316 +
1317 + xfree (ssh_key);
1318 + }
1319 +
1320 + if (x509 != NULL) {
1321 + X509_free (x509);
1322 + x509 = NULL;
1323 + }
1324 +
1325 + if (certificate != NULL) {
1326 + pkcs11h_certificate_freeCertificate (certificate);
1327 + certificate = NULL;
1328 + }
1329 +
1330 + if (ser != NULL) {
1331 + xfree (ser);
1332 + ser = NULL;
1333 + }
1334 +
1335 + /*
1336 + * Ignore error
1337 + */
1338 + if (rv != CKR_OK) {
1339 + error ("PKCS#11: Failed to get id %ld-'%s'", rv, pkcs11h_getMessage (rv));
1340 + rv = CKR_OK;
1341 + }
1342 + }
1343 +
1344 + if (user_certificates != NULL) {
1345 + pkcs11h_certificate_freeCertificateIdList (user_certificates);
1346 + user_certificates = NULL;
1347 + }
1348 +
1349 + pkcs11h_terminate ();
1350 +}
1351 +
1352 +void
1353 +pkcs11_dump_slots (
1354 + const char * const provider
1355 +) {
1356 + pkcs11h_standalone_dump_slots (
1357 + _pkcs11_ssh_print,
1358 + NULL,
1359 + provider
1360 + );
1361 +}
1362 +
1363 +void
1364 +pkcs11_dump_objects (
1365 + const char * const provider,
1366 + const char * const slot,
1367 + const char * const pin
1368 +) {
1369 + pkcs11h_standalone_dump_objects (
1370 + _pkcs11_ssh_print,
1371 + NULL,
1372 + provider,
1373 + slot,
1374 + pin
1375 + );
1376 +}
1377 +
1378 +/*
1379 + * The ssh_from_x509 is dirived of Tatu and Markus work.
1380 + *
1381 + * Copyright (c) 2006 Alon bar-Lev <alon.barlev@gmail.com>. All rights reserved.
1382 + * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
1383 + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
1384 + */
1385 +
1386 +#define PUT_32BIT(cp, value) ( \
1387 + (cp)[0] = (value) >> 24, \
1388 + (cp)[1] = (value) >> 16, \
1389 + (cp)[2] = (value) >> 8, \
1390 + (cp)[3] = (value) )
1391 +
1392 +static
1393 +char *
1394 +ssh_from_x509 (X509 *x509) {
1395 +
1396 + EVP_PKEY *pubkey = NULL;
1397 + BIO *bio = NULL, *bio2 = NULL, *bio64 = NULL;
1398 + unsigned char *blob = NULL, *buffer = NULL;
1399 + char *ret = NULL;
1400 + int blobsize = 0, retsize = 0;
1401 + int bytes_name = 0, bytes_exponent = 0, bytes_modulus = 0;
1402 + unsigned char *bp;
1403 + char *p;
1404 + int n;
1405 + const char *keyname = NULL;
1406 + int ok = 1;
1407 +
1408 + if (ok && (pubkey = X509_get_pubkey (x509)) == NULL) {
1409 + ok = 0;
1410 + }
1411 +
1412 + if (ok && (bio64 = BIO_new (BIO_f_base64 ())) == NULL) {
1413 + ok = 0;
1414 + }
1415 +
1416 + if (ok && (bio = BIO_new (BIO_s_mem ())) == NULL) {
1417 + ok = 0;
1418 + }
1419 +
1420 + if (ok && (bio2 = BIO_push (bio64, bio)) == NULL) {
1421 + ok = 0;
1422 + }
1423 +
1424 + if (ok && pubkey->type != EVP_PKEY_RSA) {
1425 + ok = 0;
1426 + }
1427 +
1428 + if (ok) {
1429 + keyname = "ssh-rsa";
1430 + }
1431 +
1432 + if (ok) {
1433 + bytes_name = strlen (keyname);
1434 + bytes_exponent = BN_num_bytes (pubkey->pkey.rsa->e);
1435 + bytes_modulus = BN_num_bytes (pubkey->pkey.rsa->n);
1436 +
1437 + blobsize = (
1438 + 4 + bytes_name +
1439 + 4 + (bytes_exponent + 1) +
1440 + 4 + (bytes_modulus + 1) +
1441 + 1
1442 + );
1443 + }
1444 +
1445 + if (ok && (blob = (unsigned char *)xmalloc (blobsize)) == NULL) {
1446 + ok = 0;
1447 + }
1448 +
1449 + if (ok && (buffer = (unsigned char *)xmalloc (blobsize)) == NULL) {
1450 + ok = 0;
1451 + }
1452 +
1453 + if (ok) {
1454 + bp = blob;
1455 +
1456 + PUT_32BIT (bp, bytes_name), bp += 4;
1457 + memcpy (bp, keyname, bytes_name), bp += bytes_name;
1458 +
1459 + BN_bn2bin (pubkey->pkey.rsa->e, buffer);
1460 + if (buffer[0] & 0x80) {
1461 + // highest bit set would indicate a negative number.
1462 + // to avoid this, we have to spend an extra byte:
1463 + PUT_32BIT (bp, bytes_exponent+1), bp += 4;
1464 + *(bp++) = 0;
1465 + } else {
1466 + PUT_32BIT (bp, bytes_exponent), bp += 4;
1467 + }
1468 + memcpy (bp, buffer, bytes_exponent), bp += bytes_exponent;
1469 +
1470 + BN_bn2bin (pubkey->pkey.rsa->n, buffer);
1471 + if (buffer[0] & 0x80) {
1472 + PUT_32BIT (bp, bytes_modulus+1), bp += 4;
1473 + *(bp++) = 0;
1474 + } else {
1475 + PUT_32BIT( bp, bytes_modulus ), bp += 4;
1476 + }
1477 + memcpy (bp, buffer, bytes_modulus), bp += bytes_modulus;
1478 + }
1479 +
1480 +
1481 + if (ok && BIO_write (bio2, blob, bp-blob) == -1) {
1482 + ok = 0;
1483 + }
1484 +
1485 + if (ok && BIO_flush (bio2) == -1) {
1486 + ok = 0;
1487 + }
1488 +
1489 + /*
1490 + * Allocate the newline too... We will remove them later
1491 + * For MS, allocate return as well.
1492 + */
1493 + if (ok) {
1494 + retsize = strlen (keyname) + 1 + (blobsize * 4 / 3) + (blobsize * 2 / 50) + 10 + 1;
1495 + }
1496 +
1497 + if (ok && (ret = xmalloc (retsize)) == NULL) {
1498 + ok = 0;
1499 + }
1500 +
1501 + if (ok) {
1502 + strcpy (ret, keyname);
1503 + strcat (ret, " ");
1504 + }
1505 +
1506 + if (ok && (n = BIO_read (bio, ret + strlen (ret), retsize - strlen (ret) - 1)) == -1) {
1507 + ok = 0;
1508 + }
1509 +
1510 + if (ok) {
1511 + ret[strlen (keyname) + 1 + n] = '\x0';
1512 + }
1513 +
1514 + if (ok) {
1515 + while ((p = strchr (ret, '\n')) != NULL) {
1516 + memmove (p, p+1, strlen (p)+1);
1517 + }
1518 + while ((p = strchr (ret, '\r')) != NULL) {
1519 + memmove (p, p+1, strlen (p)+1);
1520 + }
1521 +
1522 + }
1523 +
1524 + if (bio != NULL) {
1525 + BIO_free_all (bio);
1526 + bio = NULL;
1527 + }
1528 +
1529 + if (pubkey != NULL) {
1530 + EVP_PKEY_free (pubkey);
1531 + pubkey = NULL;
1532 + }
1533 +
1534 + if (buffer != NULL) {
1535 + xfree (buffer);
1536 + buffer = NULL;
1537 + }
1538 +
1539 + if (blob != NULL) {
1540 + xfree (blob);
1541 + blob = NULL;
1542 + }
1543 +
1544 + if (!ok) {
1545 + if (ret != NULL) {
1546 + xfree (ret);
1547 + ret = NULL;
1548 + }
1549 + }
1550 +
1551 + return ret;
1552 +}
1553 +
1554 +#else
1555 +static void dummy (void) {}
1556 +#endif /* SSH_PKCS11_DISABLED */
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
1560 @@ -0,0 +1,100 @@
1561 +/*
1562 + * Copyright (c) 2005-2006 Alon Bar-Lev. All rights reserved.
1563 + *
1564 + * Redistribution and use in source and binary forms, with or without
1565 + * modification, are permitted provided that the following conditions
1566 + * are met:
1567 + * 1. Redistributions of source code must retain the above copyright
1568 + * notice, this list of conditions and the following disclaimer.
1569 + * 2. Redistributions in binary form must reproduce the above copyright
1570 + * notice, this list of conditions and the following disclaimer in the
1571 + * documentation and/or other materials provided with the distribution.
1572 + *
1573 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1574 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1575 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1576 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1577 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1578 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1579 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1580 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1581 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
1582 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1583 + */
1584 +
1585 +#ifndef SSH_PKCS11_H
1586 +#define SSH_PKCS11_H
1587 +
1588 +#if !defined(SSH_PKCS11_DISABLED)
1589 +
1590 +#include "key.h"
1591 +
1592 +typedef struct pkcs11_identity_s {
1593 + char *id;
1594 + int pin_cache_period;
1595 + char *cert_file;
1596 +} pkcs11_identity;
1597 +
1598 +int
1599 +pkcs11_initialize (
1600 + const int fProtectedAuthentication,
1601 + const int nPINCachePeriod
1602 +);
1603 +
1604 +void
1605 +pkcs11_terminate ();
1606 +
1607 +void
1608 +pkcs11_forkFix ();
1609 +
1610 +int
1611 +pkcs11_setAskPIN (
1612 + const char * const pin_prog
1613 +);
1614 +
1615 +int
1616 +pkcs11_addProvider (
1617 + const char * const provider,
1618 + const int fProtectedAuthentication,
1619 + const char * const sign_mode,
1620 + const int fCertIsPrivate
1621 +);
1622 +
1623 +pkcs11_identity *
1624 +pkcs11_identity_new ();
1625 +
1626 +void
1627 +pkcs11_identity_free (
1628 + const pkcs11_identity * const id
1629 +);
1630 +
1631 +void
1632 +pkcs11_getKey (
1633 + const pkcs11_identity * const id,
1634 + Key ** const sshkey,
1635 + char * const szComment,
1636 + const int nCommentMax
1637 +);
1638 +
1639 +void
1640 +pkcs11_show_ids (
1641 + const char * const provider,
1642 + int allow_protected_auth,
1643 + int cert_is_private
1644 +);
1645 +
1646 +void
1647 +pkcs11_dump_slots (
1648 + const char * const provider
1649 +);
1650 +
1651 +void
1652 +pkcs11_dump_objects (
1653 + const char * const provider,
1654 + const char * const slot,
1655 + const char * const pin
1656 +);
1657 +
1658 +#endif /* SSH_PKCS11_DISABLED */
1659 +
1660 +#endif /* OPENSSH_PKCS11_H */
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
1664 @@ -0,0 +1,912 @@
1665 +/* pkcs11f.h include file for PKCS #11. */
1666 +/* $Revision: 1.4 $ */
1667 +
1668 +/* License to copy and use this software is granted provided that it is
1669 + * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
1670 + * (Cryptoki)" in all material mentioning or referencing this software.
1671 +
1672 + * License is also granted to make and use derivative works provided that
1673 + * such works are identified as "derived from the RSA Security Inc. PKCS #11
1674 + * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
1675 + * referencing the derived work.
1676 +
1677 + * RSA Security Inc. makes no representations concerning either the
1678 + * merchantability of this software or the suitability of this software for
1679 + * any particular purpose. It is provided "as is" without express or implied
1680 + * warranty of any kind.
1681 + */
1682 +
1683 +/* This header file contains pretty much everything about all the */
1684 +/* Cryptoki function prototypes. Because this information is */
1685 +/* used for more than just declaring function prototypes, the */
1686 +/* order of the functions appearing herein is important, and */
1687 +/* should not be altered. */
1688 +
1689 +/* General-purpose */
1690 +
1691 +/* C_Initialize initializes the Cryptoki library. */
1692 +CK_PKCS11_FUNCTION_INFO(C_Initialize)
1693 +#ifdef CK_NEED_ARG_LIST
1694 +(
1695 + CK_VOID_PTR pInitArgs /* if this is not NULL_PTR, it gets
1696 + * cast to CK_C_INITIALIZE_ARGS_PTR
1697 + * and dereferenced */
1698 +);
1699 +#endif
1700 +
1701 +
1702 +/* C_Finalize indicates that an application is done with the
1703 + * Cryptoki library. */
1704 +CK_PKCS11_FUNCTION_INFO(C_Finalize)
1705 +#ifdef CK_NEED_ARG_LIST
1706 +(
1707 + CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */
1708 +);
1709 +#endif
1710 +
1711 +
1712 +/* C_GetInfo returns general information about Cryptoki. */
1713 +CK_PKCS11_FUNCTION_INFO(C_GetInfo)
1714 +#ifdef CK_NEED_ARG_LIST
1715 +(
1716 + CK_INFO_PTR pInfo /* location that receives information */
1717 +);
1718 +#endif
1719 +
1720 +
1721 +/* C_GetFunctionList returns the function list. */
1722 +CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
1723 +#ifdef CK_NEED_ARG_LIST
1724 +(
1725 + CK_FUNCTION_LIST_PTR_PTR ppFunctionList /* receives pointer to
1726 + * function list */
1727 +);
1728 +#endif
1729 +
1730 +
1731 +
1732 +/* Slot and token management */
1733 +
1734 +/* C_GetSlotList obtains a list of slots in the system. */
1735 +CK_PKCS11_FUNCTION_INFO(C_GetSlotList)
1736 +#ifdef CK_NEED_ARG_LIST
1737 +(
1738 + CK_BBOOL tokenPresent, /* only slots with tokens? */
1739 + CK_SLOT_ID_PTR pSlotList, /* receives array of slot IDs */
1740 + CK_ULONG_PTR pulCount /* receives number of slots */
1741 +);
1742 +#endif
1743 +
1744 +
1745 +/* C_GetSlotInfo obtains information about a particular slot in
1746 + * the system. */
1747 +CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
1748 +#ifdef CK_NEED_ARG_LIST
1749 +(
1750 + CK_SLOT_ID slotID, /* the ID of the slot */
1751 + CK_SLOT_INFO_PTR pInfo /* receives the slot information */
1752 +);
1753 +#endif
1754 +
1755 +
1756 +/* C_GetTokenInfo obtains information about a particular token
1757 + * in the system. */
1758 +CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo)
1759 +#ifdef CK_NEED_ARG_LIST
1760 +(
1761 + CK_SLOT_ID slotID, /* ID of the token's slot */
1762 + CK_TOKEN_INFO_PTR pInfo /* receives the token information */
1763 +);
1764 +#endif
1765 +
1766 +
1767 +/* C_GetMechanismList obtains a list of mechanism types
1768 + * supported by a token. */
1769 +CK_PKCS11_FUNCTION_INFO(C_GetMechanismList)
1770 +#ifdef CK_NEED_ARG_LIST
1771 +(
1772 + CK_SLOT_ID slotID, /* ID of token's slot */
1773 + CK_MECHANISM_TYPE_PTR pMechanismList, /* gets mech. array */
1774 + CK_ULONG_PTR pulCount /* gets # of mechs. */
1775 +);
1776 +#endif
1777 +
1778 +
1779 +/* C_GetMechanismInfo obtains information about a particular
1780 + * mechanism possibly supported by a token. */
1781 +CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
1782 +#ifdef CK_NEED_ARG_LIST
1783 +(
1784 + CK_SLOT_ID slotID, /* ID of the token's slot */
1785 + CK_MECHANISM_TYPE type, /* type of mechanism */
1786 + CK_MECHANISM_INFO_PTR pInfo /* receives mechanism info */
1787 +);
1788 +#endif
1789 +
1790 +
1791 +/* C_InitToken initializes a token. */
1792 +CK_PKCS11_FUNCTION_INFO(C_InitToken)
1793 +#ifdef CK_NEED_ARG_LIST
1794 +/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */
1795 +(
1796 + CK_SLOT_ID slotID, /* ID of the token's slot */
1797 + CK_UTF8CHAR_PTR pPin, /* the SO's initial PIN */
1798 + CK_ULONG ulPinLen, /* length in bytes of the PIN */
1799 + CK_UTF8CHAR_PTR pLabel /* 32-byte token label (blank padded) */
1800 +);
1801 +#endif
1802 +
1803 +
1804 +/* C_InitPIN initializes the normal user's PIN. */
1805 +CK_PKCS11_FUNCTION_INFO(C_InitPIN)
1806 +#ifdef CK_NEED_ARG_LIST
1807 +(
1808 + CK_SESSION_HANDLE hSession, /* the session's handle */
1809 + CK_UTF8CHAR_PTR pPin, /* the normal user's PIN */
1810 + CK_ULONG ulPinLen /* length in bytes of the PIN */
1811 +);
1812 +#endif
1813 +
1814 +
1815 +/* C_SetPIN modifies the PIN of the user who is logged in. */
1816 +CK_PKCS11_FUNCTION_INFO(C_SetPIN)
1817 +#ifdef CK_NEED_ARG_LIST
1818 +(
1819 + CK_SESSION_HANDLE hSession, /* the session's handle */
1820 + CK_UTF8CHAR_PTR pOldPin, /* the old PIN */
1821 + CK_ULONG ulOldLen, /* length of the old PIN */
1822 + CK_UTF8CHAR_PTR pNewPin, /* the new PIN */
1823 + CK_ULONG ulNewLen /* length of the new PIN */
1824 +);
1825 +#endif
1826 +
1827 +
1828 +
1829 +/* Session management */
1830 +
1831 +/* C_OpenSession opens a session between an application and a
1832 + * token. */
1833 +CK_PKCS11_FUNCTION_INFO(C_OpenSession)
1834 +#ifdef CK_NEED_ARG_LIST
1835 +(
1836 + CK_SLOT_ID slotID, /* the slot's ID */
1837 + CK_FLAGS flags, /* from CK_SESSION_INFO */
1838 + CK_VOID_PTR pApplication, /* passed to callback */
1839 + CK_NOTIFY Notify, /* callback function */
1840 + CK_SESSION_HANDLE_PTR phSession /* gets session handle */
1841 +);
1842 +#endif
1843 +
1844 +
1845 +/* C_CloseSession closes a session between an application and a
1846 + * token. */
1847 +CK_PKCS11_FUNCTION_INFO(C_CloseSession)
1848 +#ifdef CK_NEED_ARG_LIST
1849 +(
1850 + CK_SESSION_HANDLE hSession /* the session's handle */
1851 +);
1852 +#endif
1853 +
1854 +
1855 +/* C_CloseAllSessions closes all sessions with a token. */
1856 +CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions)
1857 +#ifdef CK_NEED_ARG_LIST
1858 +(
1859 + CK_SLOT_ID slotID /* the token's slot */
1860 +);
1861 +#endif
1862 +
1863 +
1864 +/* C_GetSessionInfo obtains information about the session. */
1865 +CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo)
1866 +#ifdef CK_NEED_ARG_LIST
1867 +(
1868 + CK_SESSION_HANDLE hSession, /* the session's handle */
1869 + CK_SESSION_INFO_PTR pInfo /* receives session info */
1870 +);
1871 +#endif
1872 +
1873 +
1874 +/* C_GetOperationState obtains the state of the cryptographic operation
1875 + * in a session. */
1876 +CK_PKCS11_FUNCTION_INFO(C_GetOperationState)
1877 +#ifdef CK_NEED_ARG_LIST
1878 +(
1879 + CK_SESSION_HANDLE hSession, /* session's handle */
1880 + CK_BYTE_PTR pOperationState, /* gets state */
1881 + CK_ULONG_PTR pulOperationStateLen /* gets state length */
1882 +);
1883 +#endif
1884 +
1885 +
1886 +/* C_SetOperationState restores the state of the cryptographic
1887 + * operation in a session. */
1888 +CK_PKCS11_FUNCTION_INFO(C_SetOperationState)
1889 +#ifdef CK_NEED_ARG_LIST
1890 +(
1891 + CK_SESSION_HANDLE hSession, /* session's handle */
1892 + CK_BYTE_PTR pOperationState, /* holds state */
1893 + CK_ULONG ulOperationStateLen, /* holds state length */
1894 + CK_OBJECT_HANDLE hEncryptionKey, /* en/decryption key */
1895 + CK_OBJECT_HANDLE hAuthenticationKey /* sign/verify key */
1896 +);
1897 +#endif
1898 +
1899 +
1900 +/* C_Login logs a user into a token. */
1901 +CK_PKCS11_FUNCTION_INFO(C_Login)
1902 +#ifdef CK_NEED_ARG_LIST
1903 +(
1904 + CK_SESSION_HANDLE hSession, /* the session's handle */
1905 + CK_USER_TYPE userType, /* the user type */
1906 + CK_UTF8CHAR_PTR pPin, /* the user's PIN */
1907 + CK_ULONG ulPinLen /* the length of the PIN */
1908 +);
1909 +#endif
1910 +
1911 +
1912 +/* C_Logout logs a user out from a token. */
1913 +CK_PKCS11_FUNCTION_INFO(C_Logout)
1914 +#ifdef CK_NEED_ARG_LIST
1915 +(
1916 + CK_SESSION_HANDLE hSession /* the session's handle */
1917 +);
1918 +#endif
1919 +
1920 +
1921 +
1922 +/* Object management */
1923 +
1924 +/* C_CreateObject creates a new object. */
1925 +CK_PKCS11_FUNCTION_INFO(C_CreateObject)
1926 +#ifdef CK_NEED_ARG_LIST
1927 +(
1928 + CK_SESSION_HANDLE hSession, /* the session's handle */
1929 + CK_ATTRIBUTE_PTR pTemplate, /* the object's template */
1930 + CK_ULONG ulCount, /* attributes in template */
1931 + CK_OBJECT_HANDLE_PTR phObject /* gets new object's handle. */
1932 +);
1933 +#endif
1934 +
1935 +
1936 +/* C_CopyObject copies an object, creating a new object for the
1937 + * copy. */
1938 +CK_PKCS11_FUNCTION_INFO(C_CopyObject)
1939 +#ifdef CK_NEED_ARG_LIST
1940 +(
1941 + CK_SESSION_HANDLE hSession, /* the session's handle */
1942 + CK_OBJECT_HANDLE hObject, /* the object's handle */
1943 + CK_ATTRIBUTE_PTR pTemplate, /* template for new object */
1944 + CK_ULONG ulCount, /* attributes in template */
1945 + CK_OBJECT_HANDLE_PTR phNewObject /* receives handle of copy */
1946 +);
1947 +#endif
1948 +
1949 +
1950 +/* C_DestroyObject destroys an object. */
1951 +CK_PKCS11_FUNCTION_INFO(C_DestroyObject)
1952 +#ifdef CK_NEED_ARG_LIST
1953 +(
1954 + CK_SESSION_HANDLE hSession, /* the session's handle */
1955 + CK_OBJECT_HANDLE hObject /* the object's handle */
1956 +);
1957 +#endif
1958 +
1959 +
1960 +/* C_GetObjectSize gets the size of an object in bytes. */
1961 +CK_PKCS11_FUNCTION_INFO(C_GetObjectSize)
1962 +#ifdef CK_NEED_ARG_LIST
1963 +(
1964 + CK_SESSION_HANDLE hSession, /* the session's handle */
1965 + CK_OBJECT_HANDLE hObject, /* the object's handle */
1966 + CK_ULONG_PTR pulSize /* receives size of object */
1967 +);
1968 +#endif
1969 +
1970 +
1971 +/* C_GetAttributeValue obtains the value of one or more object
1972 + * attributes. */
1973 +CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
1974 +#ifdef CK_NEED_ARG_LIST
1975 +(
1976 + CK_SESSION_HANDLE hSession, /* the session's handle */
1977 + CK_OBJECT_HANDLE hObject, /* the object's handle */
1978 + CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs; gets vals */
1979 + CK_ULONG ulCount /* attributes in template */
1980 +);
1981 +#endif
1982 +
1983 +
1984 +/* C_SetAttributeValue modifies the value of one or more object
1985 + * attributes */
1986 +CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue)
1987 +#ifdef CK_NEED_ARG_LIST
1988 +(
1989 + CK_SESSION_HANDLE hSession, /* the session's handle */
1990 + CK_OBJECT_HANDLE hObject, /* the object's handle */
1991 + CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs and values */
1992 + CK_ULONG ulCount /* attributes in template */
1993 +);
1994 +#endif
1995 +
1996 +
1997 +/* C_FindObjectsInit initializes a search for token and session
1998 + * objects that match a template. */
1999 +CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit)
2000 +#ifdef CK_NEED_ARG_LIST
2001 +(
2002 + CK_SESSION_HANDLE hSession, /* the session's handle */
2003 + CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */
2004 + CK_ULONG ulCount /* attrs in search template */
2005 +);
2006 +#endif
2007 +
2008 +
2009 +/* C_FindObjects continues a search for token and session
2010 + * objects that match a template, obtaining additional object
2011 + * handles. */
2012 +CK_PKCS11_FUNCTION_INFO(C_FindObjects)
2013 +#ifdef CK_NEED_ARG_LIST
2014 +(
2015 + CK_SESSION_HANDLE hSession, /* session's handle */
2016 + CK_OBJECT_HANDLE_PTR phObject, /* gets obj. handles */
2017 + CK_ULONG ulMaxObjectCount, /* max handles to get */
2018 + CK_ULONG_PTR pulObjectCount /* actual # returned */
2019 +);
2020 +#endif
2021 +
2022 +
2023 +/* C_FindObjectsFinal finishes a search for token and session
2024 + * objects. */
2025 +CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal)
2026 +#ifdef CK_NEED_ARG_LIST
2027 +(
2028 + CK_SESSION_HANDLE hSession /* the session's handle */
2029 +);
2030 +#endif
2031 +
2032 +
2033 +
2034 +/* Encryption and decryption */
2035 +
2036 +/* C_EncryptInit initializes an encryption operation. */
2037 +CK_PKCS11_FUNCTION_INFO(C_EncryptInit)
2038 +#ifdef CK_NEED_ARG_LIST
2039 +(
2040 + CK_SESSION_HANDLE hSession, /* the session's handle */
2041 + CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */
2042 + CK_OBJECT_HANDLE hKey /* handle of encryption key */
2043 +);
2044 +#endif
2045 +
2046 +
2047 +/* C_Encrypt encrypts single-part data. */
2048 +CK_PKCS11_FUNCTION_INFO(C_Encrypt)
2049 +#ifdef CK_NEED_ARG_LIST
2050 +(
2051 + CK_SESSION_HANDLE hSession, /* session's handle */
2052 + CK_BYTE_PTR pData, /* the plaintext data */
2053 + CK_ULONG ulDataLen, /* bytes of plaintext */
2054 + CK_BYTE_PTR pEncryptedData, /* gets ciphertext */
2055 + CK_ULONG_PTR pulEncryptedDataLen /* gets c-text size */
2056 +);
2057 +#endif
2058 +
2059 +
2060 +/* C_EncryptUpdate continues a multiple-part encryption
2061 + * operation. */
2062 +CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate)
2063 +#ifdef CK_NEED_ARG_LIST
2064 +(
2065 + CK_SESSION_HANDLE hSession, /* session's handle */
2066 + CK_BYTE_PTR pPart, /* the plaintext data */
2067 + CK_ULONG ulPartLen, /* plaintext data len */
2068 + CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
2069 + CK_ULONG_PTR pulEncryptedPartLen /* gets c-text size */
2070 +);
2071 +#endif
2072 +
2073 +
2074 +/* C_EncryptFinal finishes a multiple-part encryption
2075 + * operation. */
2076 +CK_PKCS11_FUNCTION_INFO(C_EncryptFinal)
2077 +#ifdef CK_NEED_ARG_LIST
2078 +(
2079 + CK_SESSION_HANDLE hSession, /* session handle */
2080 + CK_BYTE_PTR pLastEncryptedPart, /* last c-text */
2081 + CK_ULONG_PTR pulLastEncryptedPartLen /* gets last size */
2082 +);
2083 +#endif
2084 +
2085 +
2086 +/* C_DecryptInit initializes a decryption operation. */
2087 +CK_PKCS11_FUNCTION_INFO(C_DecryptInit)
2088 +#ifdef CK_NEED_ARG_LIST
2089 +(
2090 + CK_SESSION_HANDLE hSession, /* the session's handle */
2091 + CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */
2092 + CK_OBJECT_HANDLE hKey /* handle of decryption key */
2093 +);
2094 +#endif
2095 +
2096 +
2097 +/* C_Decrypt decrypts encrypted data in a single part. */
2098 +CK_PKCS11_FUNCTION_INFO(C_Decrypt)
2099 +#ifdef CK_NEED_ARG_LIST
2100 +(
2101 + CK_SESSION_HANDLE hSession, /* session's handle */
2102 + CK_BYTE_PTR pEncryptedData, /* ciphertext */
2103 + CK_ULONG ulEncryptedDataLen, /* ciphertext length */
2104 + CK_BYTE_PTR pData, /* gets plaintext */
2105 + CK_ULONG_PTR pulDataLen /* gets p-text size */
2106 +);
2107 +#endif
2108 +
2109 +
2110 +/* C_DecryptUpdate continues a multiple-part decryption
2111 + * operation. */
2112 +CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate)
2113 +#ifdef CK_NEED_ARG_LIST
2114 +(
2115 + CK_SESSION_HANDLE hSession, /* session's handle */
2116 + CK_BYTE_PTR pEncryptedPart, /* encrypted data */
2117 + CK_ULONG ulEncryptedPartLen, /* input length */
2118 + CK_BYTE_PTR pPart, /* gets plaintext */
2119 + CK_ULONG_PTR pulPartLen /* p-text size */
2120 +);
2121 +#endif
2122 +
2123 +
2124 +/* C_DecryptFinal finishes a multiple-part decryption
2125 + * operation. */
2126 +CK_PKCS11_FUNCTION_INFO(C_DecryptFinal)
2127 +#ifdef CK_NEED_ARG_LIST
2128 +(
2129 + CK_SESSION_HANDLE hSession, /* the session's handle */
2130 + CK_BYTE_PTR pLastPart, /* gets plaintext */
2131 + CK_ULONG_PTR pulLastPartLen /* p-text size */
2132 +);
2133 +#endif
2134 +
2135 +
2136 +
2137 +/* Message digesting */
2138 +
2139 +/* C_DigestInit initializes a message-digesting operation. */
2140 +CK_PKCS11_FUNCTION_INFO(C_DigestInit)
2141 +#ifdef CK_NEED_ARG_LIST
2142 +(
2143 + CK_SESSION_HANDLE hSession, /* the session's handle */
2144 + CK_MECHANISM_PTR pMechanism /* the digesting mechanism */
2145 +);
2146 +#endif
2147 +
2148 +
2149 +/* C_Digest digests data in a single part. */
2150 +CK_PKCS11_FUNCTION_INFO(C_Digest)
2151 +#ifdef CK_NEED_ARG_LIST
2152 +(
2153 + CK_SESSION_HANDLE hSession, /* the session's handle */
2154 + CK_BYTE_PTR pData, /* data to be digested */
2155 + CK_ULONG ulDataLen, /* bytes of data to digest */
2156 + CK_BYTE_PTR pDigest, /* gets the message digest */
2157 + CK_ULONG_PTR pulDigestLen /* gets digest length */
2158 +);
2159 +#endif
2160 +
2161 +
2162 +/* C_DigestUpdate continues a multiple-part message-digesting
2163 + * operation. */
2164 +CK_PKCS11_FUNCTION_INFO(C_DigestUpdate)
2165 +#ifdef CK_NEED_ARG_LIST
2166 +(
2167 + CK_SESSION_HANDLE hSession, /* the session's handle */
2168 + CK_BYTE_PTR pPart, /* data to be digested */
2169 + CK_ULONG ulPartLen /* bytes of data to be digested */
2170 +);
2171 +#endif
2172 +
2173 +
2174 +/* C_DigestKey continues a multi-part message-digesting
2175 + * operation, by digesting the value of a secret key as part of
2176 + * the data already digested. */
2177 +CK_PKCS11_FUNCTION_INFO(C_DigestKey)
2178 +#ifdef CK_NEED_ARG_LIST
2179 +(
2180 + CK_SESSION_HANDLE hSession, /* the session's handle */
2181 + CK_OBJECT_HANDLE hKey /* secret key to digest */
2182 +);
2183 +#endif
2184 +
2185 +
2186 +/* C_DigestFinal finishes a multiple-part message-digesting
2187 + * operation. */
2188 +CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
2189 +#ifdef CK_NEED_ARG_LIST
2190 +(
2191 + CK_SESSION_HANDLE hSession, /* the session's handle */
2192 + CK_BYTE_PTR pDigest, /* gets the message digest */
2193 + CK_ULONG_PTR pulDigestLen /* gets byte count of digest */
2194 +);
2195 +#endif
2196 +
2197 +
2198 +
2199 +/* Signing and MACing */
2200 +
2201 +/* C_SignInit initializes a signature (private key encryption)
2202 + * operation, where the signature is (will be) an appendix to
2203 + * the data, and plaintext cannot be recovered from the
2204 + *signature. */
2205 +CK_PKCS11_FUNCTION_INFO(C_SignInit)
2206 +#ifdef CK_NEED_ARG_LIST
2207 +(
2208 + CK_SESSION_HANDLE hSession, /* the session's handle */
2209 + CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
2210 + CK_OBJECT_HANDLE hKey /* handle of signature key */
2211 +);
2212 +#endif
2213 +
2214 +
2215 +/* C_Sign signs (encrypts with private key) data in a single
2216 + * part, where the signature is (will be) an appendix to the
2217 + * data, and plaintext cannot be recovered from the signature. */
2218 +CK_PKCS11_FUNCTION_INFO(C_Sign)
2219 +#ifdef CK_NEED_ARG_LIST
2220 +(
2221 + CK_SESSION_HANDLE hSession, /* the session's handle */
2222 + CK_BYTE_PTR pData, /* the data to sign */
2223 + CK_ULONG ulDataLen, /* count of bytes to sign */
2224 + CK_BYTE_PTR pSignature, /* gets the signature */
2225 + CK_ULONG_PTR pulSignatureLen /* gets signature length */
2226 +);
2227 +#endif
2228 +
2229 +
2230 +/* C_SignUpdate continues a multiple-part signature operation,
2231 + * where the signature is (will be) an appendix to the data,
2232 + * and plaintext cannot be recovered from the signature. */
2233 +CK_PKCS11_FUNCTION_INFO(C_SignUpdate)
2234 +#ifdef CK_NEED_ARG_LIST
2235 +(
2236 + CK_SESSION_HANDLE hSession, /* the session's handle */
2237 + CK_BYTE_PTR pPart, /* the data to sign */
2238 + CK_ULONG ulPartLen /* count of bytes to sign */
2239 +);
2240 +#endif
2241 +
2242 +
2243 +/* C_SignFinal finishes a multiple-part signature operation,
2244 + * returning the signature. */
2245 +CK_PKCS11_FUNCTION_INFO(C_SignFinal)
2246 +#ifdef CK_NEED_ARG_LIST
2247 +(
2248 + CK_SESSION_HANDLE hSession, /* the session's handle */
2249 + CK_BYTE_PTR pSignature, /* gets the signature */
2250 + CK_ULONG_PTR pulSignatureLen /* gets signature length */
2251 +);
2252 +#endif
2253 +
2254 +
2255 +/* C_SignRecoverInit initializes a signature operation, where
2256 + * the data can be recovered from the signature. */
2257 +CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit)
2258 +#ifdef CK_NEED_ARG_LIST
2259 +(
2260 + CK_SESSION_HANDLE hSession, /* the session's handle */
2261 + CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
2262 + CK_OBJECT_HANDLE hKey /* handle of the signature key */
2263 +);
2264 +#endif
2265 +
2266 +
2267 +/* C_SignRecover signs data in a single operation, where the
2268 + * data can be recovered from the signature. */
2269 +CK_PKCS11_FUNCTION_INFO(C_SignRecover)
2270 +#ifdef CK_NEED_ARG_LIST
2271 +(
2272 + CK_SESSION_HANDLE hSession, /* the session's handle */
2273 + CK_BYTE_PTR pData, /* the data to sign */
2274 + CK_ULONG ulDataLen, /* count of bytes to sign */
2275 + CK_BYTE_PTR pSignature, /* gets the signature */
2276 + CK_ULONG_PTR pulSignatureLen /* gets signature length */
2277 +);
2278 +#endif
2279 +
2280 +
2281 +
2282 +/* Verifying signatures and MACs */
2283 +
2284 +/* C_VerifyInit initializes a verification operation, where the
2285 + * signature is an appendix to the data, and plaintext cannot
2286 + * cannot be recovered from the signature (e.g. DSA). */
2287 +CK_PKCS11_FUNCTION_INFO(C_VerifyInit)
2288 +#ifdef CK_NEED_ARG_LIST
2289 +(
2290 + CK_SESSION_HANDLE hSession, /* the session's handle */
2291 + CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
2292 + CK_OBJECT_HANDLE hKey /* verification key */
2293 +);
2294 +#endif
2295 +
2296 +
2297 +/* C_Verify verifies a signature in a single-part operation,
2298 + * where the signature is an appendix to the data, and plaintext
2299 + * cannot be recovered from the signature. */
2300 +CK_PKCS11_FUNCTION_INFO(C_Verify)
2301 +#ifdef CK_NEED_ARG_LIST
2302 +(
2303 + CK_SESSION_HANDLE hSession, /* the session's handle */
2304 + CK_BYTE_PTR pData, /* signed data */
2305 + CK_ULONG ulDataLen, /* length of signed data */
2306 + CK_BYTE_PTR pSignature, /* signature */
2307 + CK_ULONG ulSignatureLen /* signature length*/
2308 +);
2309 +#endif
2310 +
2311 +
2312 +/* C_VerifyUpdate continues a multiple-part verification
2313 + * operation, where the signature is an appendix to the data,
2314 + * and plaintext cannot be recovered from the signature. */
2315 +CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate)
2316 +#ifdef CK_NEED_ARG_LIST
2317 +(
2318 + CK_SESSION_HANDLE hSession, /* the session's handle */
2319 + CK_BYTE_PTR pPart, /* signed data */
2320 + CK_ULONG ulPartLen /* length of signed data */
2321 +);
2322 +#endif
2323 +
2324 +
2325 +/* C_VerifyFinal finishes a multiple-part verification
2326 + * operation, checking the signature. */
2327 +CK_PKCS11_FUNCTION_INFO(C_VerifyFinal)
2328 +#ifdef CK_NEED_ARG_LIST
2329 +(
2330 + CK_SESSION_HANDLE hSession, /* the session's handle */
2331 + CK_BYTE_PTR pSignature, /* signature to verify */
2332 + CK_ULONG ulSignatureLen /* signature length */
2333 +);
2334 +#endif
2335 +
2336 +
2337 +/* C_VerifyRecoverInit initializes a signature verification
2338 + * operation, where the data is recovered from the signature. */
2339 +CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit)
2340 +#ifdef CK_NEED_ARG_LIST
2341 +(
2342 + CK_SESSION_HANDLE hSession, /* the session's handle */
2343 + CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
2344 + CK_OBJECT_HANDLE hKey /* verification key */
2345 +);
2346 +#endif
2347 +
2348 +
2349 +/* C_VerifyRecover verifies a signature in a single-part
2350 + * operation, where the data is recovered from the signature. */
2351 +CK_PKCS11_FUNCTION_INFO(C_VerifyRecover)
2352 +#ifdef CK_NEED_ARG_LIST
2353 +(
2354 + CK_SESSION_HANDLE hSession, /* the session's handle */
2355 + CK_BYTE_PTR pSignature, /* signature to verify */
2356 + CK_ULONG ulSignatureLen, /* signature length */
2357 + CK_BYTE_PTR pData, /* gets signed data */
2358 + CK_ULONG_PTR pulDataLen /* gets signed data len */
2359 +);
2360 +#endif
2361 +
2362 +
2363 +
2364 +/* Dual-function cryptographic operations */
2365 +
2366 +/* C_DigestEncryptUpdate continues a multiple-part digesting
2367 + * and encryption operation. */
2368 +CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate)
2369 +#ifdef CK_NEED_ARG_LIST
2370 +(
2371 + CK_SESSION_HANDLE hSession, /* session's handle */
2372 + CK_BYTE_PTR pPart, /* the plaintext data */
2373 + CK_ULONG ulPartLen, /* plaintext length */
2374 + CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
2375 + CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
2376 +);
2377 +#endif
2378 +
2379 +
2380 +/* C_DecryptDigestUpdate continues a multiple-part decryption and
2381 + * digesting operation. */
2382 +CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate)
2383 +#ifdef CK_NEED_ARG_LIST
2384 +(
2385 + CK_SESSION_HANDLE hSession, /* session's handle */
2386 + CK_BYTE_PTR pEncryptedPart, /* ciphertext */
2387 + CK_ULONG ulEncryptedPartLen, /* ciphertext length */
2388 + CK_BYTE_PTR pPart, /* gets plaintext */
2389 + CK_ULONG_PTR pulPartLen /* gets plaintext len */
2390 +);
2391 +#endif
2392 +
2393 +
2394 +/* C_SignEncryptUpdate continues a multiple-part signing and
2395 + * encryption operation. */
2396 +CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate)
2397 +#ifdef CK_NEED_ARG_LIST
2398 +(
2399 + CK_SESSION_HANDLE hSession, /* session's handle */
2400 + CK_BYTE_PTR pPart, /* the plaintext data */
2401 + CK_ULONG ulPartLen, /* plaintext length */
2402 + CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
2403 + CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
2404 +);
2405 +#endif
2406 +
2407 +
2408 +/* C_DecryptVerifyUpdate continues a multiple-part decryption and
2409 + * verify operation. */
2410 +CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate)
2411 +#ifdef CK_NEED_ARG_LIST
2412 +(
2413 + CK_SESSION_HANDLE hSession, /* session's handle */
2414 + CK_BYTE_PTR pEncryptedPart, /* ciphertext */
2415 + CK_ULONG ulEncryptedPartLen, /* ciphertext length */
2416 + CK_BYTE_PTR pPart, /* gets plaintext */
2417 + CK_ULONG_PTR pulPartLen /* gets p-text length */
2418 +);
2419 +#endif
2420 +
2421 +
2422 +
2423 +/* Key management */
2424 +
2425 +/* C_GenerateKey generates a secret key, creating a new key
2426 + * object. */
2427 +CK_PKCS11_FUNCTION_INFO(C_GenerateKey)
2428 +#ifdef CK_NEED_ARG_LIST
2429 +(
2430 + CK_SESSION_HANDLE hSession, /* the session's handle */
2431 + CK_MECHANISM_PTR pMechanism, /* key generation mech. */
2432 + CK_ATTRIBUTE_PTR pTemplate, /* template for new key */
2433 + CK_ULONG ulCount, /* # of attrs in template */
2434 + CK_OBJECT_HANDLE_PTR phKey /* gets handle of new key */
2435 +);
2436 +#endif
2437 +
2438 +
2439 +/* C_GenerateKeyPair generates a public-key/private-key pair,
2440 + * creating new key objects. */
2441 +CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair)
2442 +#ifdef CK_NEED_ARG_LIST
2443 +(
2444 + CK_SESSION_HANDLE hSession, /* session
2445 + * handle */
2446 + CK_MECHANISM_PTR pMechanism, /* key-gen
2447 + * mech. */
2448 + CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* template
2449 + * for pub.
2450 + * key */
2451 + CK_ULONG ulPublicKeyAttributeCount, /* # pub.
2452 + * attrs. */
2453 + CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* template
2454 + * for priv.
2455 + * key */
2456 + CK_ULONG ulPrivateKeyAttributeCount, /* # priv.
2457 + * attrs. */
2458 + CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub.
2459 + * key
2460 + * handle */
2461 + CK_OBJECT_HANDLE_PTR phPrivateKey /* gets
2462 + * priv. key
2463 + * handle */
2464 +);
2465 +#endif
2466 +
2467 +
2468 +/* C_WrapKey wraps (i.e., encrypts) a key. */
2469 +CK_PKCS11_FUNCTION_INFO(C_WrapKey)
2470 +#ifdef CK_NEED_ARG_LIST
2471 +(
2472 + CK_SESSION_HANDLE hSession, /* the session's handle */
2473 + CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */
2474 + CK_OBJECT_HANDLE hWrappingKey, /* wrapping key */
2475 + CK_OBJECT_HANDLE hKey, /* key to be wrapped */
2476 + CK_BYTE_PTR pWrappedKey, /* gets wrapped key */
2477 + CK_ULONG_PTR pulWrappedKeyLen /* gets wrapped key size */
2478 +);
2479 +#endif
2480 +
2481 +
2482 +/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
2483 + * key object. */
2484 +CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
2485 +#ifdef CK_NEED_ARG_LIST
2486 +(
2487 + CK_SESSION_HANDLE hSession, /* session's handle */
2488 + CK_MECHANISM_PTR pMechanism, /* unwrapping mech. */
2489 + CK_OBJECT_HANDLE hUnwrappingKey, /* unwrapping key */
2490 + CK_BYTE_PTR pWrappedKey, /* the wrapped key */
2491 + CK_ULONG ulWrappedKeyLen, /* wrapped key len */
2492 + CK_ATTRIBUTE_PTR pTemplate, /* new key template */
2493 + CK_ULONG ulAttributeCount, /* template length */
2494 + CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
2495 +);
2496 +#endif
2497 +
2498 +
2499 +/* C_DeriveKey derives a key from a base key, creating a new key
2500 + * object. */
2501 +CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
2502 +#ifdef CK_NEED_ARG_LIST
2503 +(
2504 + CK_SESSION_HANDLE hSession, /* session's handle */
2505 + CK_MECHANISM_PTR pMechanism, /* key deriv. mech. */
2506 + CK_OBJECT_HANDLE hBaseKey, /* base key */
2507 + CK_ATTRIBUTE_PTR pTemplate, /* new key template */
2508 + CK_ULONG ulAttributeCount, /* template length */
2509 + CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
2510 +);
2511 +#endif
2512 +
2513 +
2514 +
2515 +/* Random number generation */
2516 +
2517 +/* C_SeedRandom mixes additional seed material into the token's
2518 + * random number generator. */
2519 +CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
2520 +#ifdef CK_NEED_ARG_LIST
2521 +(
2522 + CK_SESSION_HANDLE hSession, /* the session's handle */
2523 + CK_BYTE_PTR pSeed, /* the seed material */
2524 + CK_ULONG ulSeedLen /* length of seed material */
2525 +);
2526 +#endif
2527 +
2528 +
2529 +/* C_GenerateRandom generates random data. */
2530 +CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
2531 +#ifdef CK_NEED_ARG_LIST
2532 +(
2533 + CK_SESSION_HANDLE hSession, /* the session's handle */
2534 + CK_BYTE_PTR RandomData, /* receives the random data */
2535 + CK_ULONG ulRandomLen /* # of bytes to generate */
2536 +);
2537 +#endif
2538 +
2539 +
2540 +
2541 +/* Parallel function management */
2542 +
2543 +/* C_GetFunctionStatus is a legacy function; it obtains an
2544 + * updated status of a function running in parallel with an
2545 + * application. */
2546 +CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
2547 +#ifdef CK_NEED_ARG_LIST
2548 +(
2549 + CK_SESSION_HANDLE hSession /* the session's handle */
2550 +);
2551 +#endif
2552 +
2553 +
2554 +/* C_CancelFunction is a legacy function; it cancels a function
2555 + * running in parallel. */
2556 +CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
2557 +#ifdef CK_NEED_ARG_LIST
2558 +(
2559 + CK_SESSION_HANDLE hSession /* the session's handle */
2560 +);
2561 +#endif
2562 +
2563 +
2564 +
2565 +/* Functions added in for Cryptoki Version 2.01 or later */
2566 +
2567 +/* C_WaitForSlotEvent waits for a slot event (token insertion,
2568 + * removal, etc.) to occur. */
2569 +CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
2570 +#ifdef CK_NEED_ARG_LIST
2571 +(
2572 + CK_FLAGS flags, /* blocking/nonblocking flag */
2573 + CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */
2574 + CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */
2575 +);
2576 +#endif
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
2580 @@ -0,0 +1,299 @@
2581 +/* pkcs11.h include file for PKCS #11. */
2582 +/* $Revision: 1.4 $ */
2583 +
2584 +/* License to copy and use this software is granted provided that it is
2585 + * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
2586 + * (Cryptoki)" in all material mentioning or referencing this software.
2587 +
2588 + * License is also granted to make and use derivative works provided that
2589 + * such works are identified as "derived from the RSA Security Inc. PKCS #11
2590 + * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
2591 + * referencing the derived work.
2592 +
2593 + * RSA Security Inc. makes no representations concerning either the
2594 + * merchantability of this software or the suitability of this software for
2595 + * any particular purpose. It is provided "as is" without express or implied
2596 + * warranty of any kind.
2597 + */
2598 +
2599 +#ifndef _PKCS11_H_
2600 +#define _PKCS11_H_ 1
2601 +
2602 +#ifdef __cplusplus
2603 +extern "C" {
2604 +#endif
2605 +
2606 +/* Before including this file (pkcs11.h) (or pkcs11t.h by
2607 + * itself), 6 platform-specific macros must be defined. These
2608 + * macros are described below, and typical definitions for them
2609 + * are also given. Be advised that these definitions can depend
2610 + * on both the platform and the compiler used (and possibly also
2611 + * on whether a Cryptoki library is linked statically or
2612 + * dynamically).
2613 + *
2614 + * In addition to defining these 6 macros, the packing convention
2615 + * for Cryptoki structures should be set. The Cryptoki
2616 + * convention on packing is that structures should be 1-byte
2617 + * aligned.
2618 + *
2619 + * If you're using Microsoft Developer Studio 5.0 to produce
2620 + * Win32 stuff, this might be done by using the following
2621 + * preprocessor directive before including pkcs11.h or pkcs11t.h:
2622 + *
2623 + * #pragma pack(push, cryptoki, 1)
2624 + *
2625 + * and using the following preprocessor directive after including
2626 + * pkcs11.h or pkcs11t.h:
2627 + *
2628 + * #pragma pack(pop, cryptoki)
2629 + *
2630 + * If you're using an earlier version of Microsoft Developer
2631 + * Studio to produce Win16 stuff, this might be done by using
2632 + * the following preprocessor directive before including
2633 + * pkcs11.h or pkcs11t.h:
2634 + *
2635 + * #pragma pack(1)
2636 + *
2637 + * In a UNIX environment, you're on your own for this. You might
2638 + * not need to do (or be able to do!) anything.
2639 + *
2640 + *
2641 + * Now for the macros:
2642 + *
2643 + *
2644 + * 1. CK_PTR: The indirection string for making a pointer to an
2645 + * object. It can be used like this:
2646 + *
2647 + * typedef CK_BYTE CK_PTR CK_BYTE_PTR;
2648 + *
2649 + * If you're using Microsoft Developer Studio 5.0 to produce
2650 + * Win32 stuff, it might be defined by:
2651 + *
2652 + * #define CK_PTR *
2653 + *
2654 + * If you're using an earlier version of Microsoft Developer
2655 + * Studio to produce Win16 stuff, it might be defined by:
2656 + *
2657 + * #define CK_PTR far *
2658 + *
2659 + * In a typical UNIX environment, it might be defined by:
2660 + *
2661 + * #define CK_PTR *
2662 + *
2663 + *
2664 + * 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes
2665 + * an exportable Cryptoki library function definition out of a
2666 + * return type and a function name. It should be used in the
2667 + * following fashion to define the exposed Cryptoki functions in
2668 + * a Cryptoki library:
2669 + *
2670 + * CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
2671 + * CK_VOID_PTR pReserved
2672 + * )
2673 + * {
2674 + * ...
2675 + * }
2676 + *
2677 + * If you're using Microsoft Developer Studio 5.0 to define a
2678 + * function in a Win32 Cryptoki .dll, it might be defined by:
2679 + *
2680 + * #define CK_DEFINE_FUNCTION(returnType, name) \
2681 + * returnType __declspec(dllexport) name
2682 + *
2683 + * If you're using an earlier version of Microsoft Developer
2684 + * Studio to define a function in a Win16 Cryptoki .dll, it
2685 + * might be defined by:
2686 + *
2687 + * #define CK_DEFINE_FUNCTION(returnType, name) \
2688 + * returnType __export _far _pascal name
2689 + *
2690 + * In a UNIX environment, it might be defined by:
2691 + *
2692 + * #define CK_DEFINE_FUNCTION(returnType, name) \
2693 + * returnType name
2694 + *
2695 + *
2696 + * 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
2697 + * an importable Cryptoki library function declaration out of a
2698 + * return type and a function name. It should be used in the
2699 + * following fashion:
2700 + *
2701 + * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
2702 + * CK_VOID_PTR pReserved
2703 + * );
2704 + *
2705 + * If you're using Microsoft Developer Studio 5.0 to declare a
2706 + * function in a Win32 Cryptoki .dll, it might be defined by:
2707 + *
2708 + * #define CK_DECLARE_FUNCTION(returnType, name) \
2709 + * returnType __declspec(dllimport) name
2710 + *
2711 + * If you're using an earlier version of Microsoft Developer
2712 + * Studio to declare a function in a Win16 Cryptoki .dll, it
2713 + * might be defined by:
2714 + *
2715 + * #define CK_DECLARE_FUNCTION(returnType, name) \
2716 + * returnType __export _far _pascal name
2717 + *
2718 + * In a UNIX environment, it might be defined by:
2719 + *
2720 + * #define CK_DECLARE_FUNCTION(returnType, name) \
2721 + * returnType name
2722 + *
2723 + *
2724 + * 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
2725 + * which makes a Cryptoki API function pointer declaration or
2726 + * function pointer type declaration out of a return type and a
2727 + * function name. It should be used in the following fashion:
2728 + *
2729 + * // Define funcPtr to be a pointer to a Cryptoki API function
2730 + * // taking arguments args and returning CK_RV.
2731 + * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
2732 + *
2733 + * or
2734 + *
2735 + * // Define funcPtrType to be the type of a pointer to a
2736 + * // Cryptoki API function taking arguments args and returning
2737 + * // CK_RV, and then define funcPtr to be a variable of type
2738 + * // funcPtrType.
2739 + * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
2740 + * funcPtrType funcPtr;
2741 + *
2742 + * If you're using Microsoft Developer Studio 5.0 to access
2743 + * functions in a Win32 Cryptoki .dll, in might be defined by:
2744 + *
2745 + * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
2746 + * returnType __declspec(dllimport) (* name)
2747 + *
2748 + * If you're using an earlier version of Microsoft Developer
2749 + * Studio to access functions in a Win16 Cryptoki .dll, it might
2750 + * be defined by:
2751 + *
2752 + * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
2753 + * returnType __export _far _pascal (* name)
2754 + *
2755 + * In a UNIX environment, it might be defined by:
2756 + *
2757 + * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
2758 + * returnType (* name)
2759 + *
2760 + *
2761 + * 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
2762 + * a function pointer type for an application callback out of
2763 + * a return type for the callback and a name for the callback.
2764 + * It should be used in the following fashion:
2765 + *
2766 + * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
2767 + *
2768 + * to declare a function pointer, myCallback, to a callback
2769 + * which takes arguments args and returns a CK_RV. It can also
2770 + * be used like this:
2771 + *
2772 + * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
2773 + * myCallbackType myCallback;
2774 + *
2775 + * If you're using Microsoft Developer Studio 5.0 to do Win32
2776 + * Cryptoki development, it might be defined by:
2777 + *
2778 + * #define CK_CALLBACK_FUNCTION(returnType, name) \
2779 + * returnType (* name)
2780 + *
2781 + * If you're using an earlier version of Microsoft Developer
2782 + * Studio to do Win16 development, it might be defined by:
2783 + *
2784 + * #define CK_CALLBACK_FUNCTION(returnType, name) \
2785 + * returnType _far _pascal (* name)
2786 + *
2787 + * In a UNIX environment, it might be defined by:
2788 + *
2789 + * #define CK_CALLBACK_FUNCTION(returnType, name) \
2790 + * returnType (* name)
2791 + *
2792 + *
2793 + * 6. NULL_PTR: This macro is the value of a NULL pointer.
2794 + *
2795 + * In any ANSI/ISO C environment (and in many others as well),
2796 + * this should best be defined by
2797 + *
2798 + * #ifndef NULL_PTR
2799 + * #define NULL_PTR 0
2800 + * #endif
2801 + */
2802 +
2803 +
2804 +/* All the various Cryptoki types and #define'd values are in the
2805 + * file pkcs11t.h. */
2806 +#include "pkcs11t.h"
2807 +
2808 +#define __PASTE(x,y) x##y
2809 +
2810 +
2811 +/* ==============================================================
2812 + * Define the "extern" form of all the entry points.
2813 + * ==============================================================
2814 + */
2815 +
2816 +#define CK_NEED_ARG_LIST 1
2817 +#define CK_PKCS11_FUNCTION_INFO(name) \
2818 + extern CK_DECLARE_FUNCTION(CK_RV, name)
2819 +
2820 +/* pkcs11f.h has all the information about the Cryptoki
2821 + * function prototypes. */
2822 +#include "pkcs11f.h"
2823 +
2824 +#undef CK_NEED_ARG_LIST
2825 +#undef CK_PKCS11_FUNCTION_INFO
2826 +
2827 +
2828 +/* ==============================================================
2829 + * Define the typedef form of all the entry points. That is, for
2830 + * each Cryptoki function C_XXX, define a type CK_C_XXX which is
2831 + * a pointer to that kind of function.
2832 + * ==============================================================
2833 + */
2834 +
2835 +#define CK_NEED_ARG_LIST 1
2836 +#define CK_PKCS11_FUNCTION_INFO(name) \
2837 + typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
2838 +
2839 +/* pkcs11f.h has all the information about the Cryptoki
2840 + * function prototypes. */
2841 +#include "pkcs11f.h"
2842 +
2843 +#undef CK_NEED_ARG_LIST
2844 +#undef CK_PKCS11_FUNCTION_INFO
2845 +
2846 +
2847 +/* ==============================================================
2848 + * Define structed vector of entry points. A CK_FUNCTION_LIST
2849 + * contains a CK_VERSION indicating a library's Cryptoki version
2850 + * and then a whole slew of function pointers to the routines in
2851 + * the library. This type was declared, but not defined, in
2852 + * pkcs11t.h.
2853 + * ==============================================================
2854 + */
2855 +
2856 +#define CK_PKCS11_FUNCTION_INFO(name) \
2857 + __PASTE(CK_,name) name;
2858 +
2859 +struct CK_FUNCTION_LIST {
2860 +
2861 + CK_VERSION version; /* Cryptoki version */
2862 +
2863 +/* Pile all the function pointers into the CK_FUNCTION_LIST. */
2864 +/* pkcs11f.h has all the information about the Cryptoki
2865 + * function prototypes. */
2866 +#include "pkcs11f.h"
2867 +
2868 +};
2869 +
2870 +#undef CK_PKCS11_FUNCTION_INFO
2871 +
2872 +
2873 +#undef __PASTE
2874 +
2875 +#ifdef __cplusplus
2876 +}
2877 +#endif
2878 +
2879 +#endif
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
2883 @@ -0,0 +1,1685 @@
2884 +/* pkcs11t.h include file for PKCS #11. */
2885 +/* $Revision: 1.6 $ */
2886 +
2887 +/* License to copy and use this software is granted provided that it is
2888 + * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
2889 + * (Cryptoki)" in all material mentioning or referencing this software.
2890 +
2891 + * License is also granted to make and use derivative works provided that
2892 + * such works are identified as "derived from the RSA Security Inc. PKCS #11
2893 + * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
2894 + * referencing the derived work.
2895 +
2896 + * RSA Security Inc. makes no representations concerning either the
2897 + * merchantability of this software or the suitability of this software for
2898 + * any particular purpose. It is provided "as is" without express or implied
2899 + * warranty of any kind.
2900 + */
2901 +
2902 +/* See top of pkcs11.h for information about the macros that
2903 + * must be defined and the structure-packing conventions that
2904 + * must be set before including this file. */
2905 +
2906 +#ifndef _PKCS11T_H_
2907 +#define _PKCS11T_H_ 1
2908 +
2909 +#define CK_TRUE 1
2910 +#define CK_FALSE 0
2911 +
2912 +#ifndef CK_DISABLE_TRUE_FALSE
2913 +#ifndef FALSE
2914 +#define FALSE CK_FALSE
2915 +#endif
2916 +
2917 +#ifndef TRUE
2918 +#define TRUE CK_TRUE
2919 +#endif
2920 +#endif
2921 +
2922 +/* an unsigned 8-bit value */
2923 +typedef unsigned char CK_BYTE;
2924 +
2925 +/* an unsigned 8-bit character */
2926 +typedef CK_BYTE CK_CHAR;
2927 +
2928 +/* an 8-bit UTF-8 character */
2929 +typedef CK_BYTE CK_UTF8CHAR;
2930 +
2931 +/* a BYTE-sized Boolean flag */
2932 +typedef CK_BYTE CK_BBOOL;
2933 +
2934 +/* an unsigned value, at least 32 bits long */
2935 +typedef unsigned long int CK_ULONG;
2936 +
2937 +/* a signed value, the same size as a CK_ULONG */
2938 +/* CK_LONG is new for v2.0 */
2939 +typedef long int CK_LONG;
2940 +
2941 +/* at least 32 bits; each bit is a Boolean flag */
2942 +typedef CK_ULONG CK_FLAGS;
2943 +
2944 +
2945 +/* some special values for certain CK_ULONG variables */
2946 +#define CK_UNAVAILABLE_INFORMATION (~0UL)
2947 +#define CK_EFFECTIVELY_INFINITE 0
2948 +
2949 +
2950 +typedef CK_BYTE CK_PTR CK_BYTE_PTR;
2951 +typedef CK_CHAR CK_PTR CK_CHAR_PTR;
2952 +typedef CK_UTF8CHAR CK_PTR CK_UTF8CHAR_PTR;
2953 +typedef CK_ULONG CK_PTR CK_ULONG_PTR;
2954 +typedef void CK_PTR CK_VOID_PTR;
2955 +
2956 +/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */
2957 +typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR;
2958 +
2959 +
2960 +/* The following value is always invalid if used as a session */
2961 +/* handle or object handle */
2962 +#define CK_INVALID_HANDLE 0
2963 +
2964 +
2965 +typedef struct CK_VERSION {
2966 + CK_BYTE major; /* integer portion of version number */
2967 + CK_BYTE minor; /* 1/100ths portion of version number */
2968 +} CK_VERSION;
2969 +
2970 +typedef CK_VERSION CK_PTR CK_VERSION_PTR;
2971 +
2972 +
2973 +typedef struct CK_INFO {
2974 + /* manufacturerID and libraryDecription have been changed from
2975 + * CK_CHAR to CK_UTF8CHAR for v2.10 */
2976 + CK_VERSION cryptokiVersion; /* Cryptoki interface ver */
2977 + CK_UTF8CHAR manufacturerID[32]; /* blank padded */
2978 + CK_FLAGS flags; /* must be zero */
2979 +
2980 + /* libraryDescription and libraryVersion are new for v2.0 */
2981 + CK_UTF8CHAR libraryDescription[32]; /* blank padded */
2982 + CK_VERSION libraryVersion; /* version of library */
2983 +} CK_INFO;
2984 +
2985 +typedef CK_INFO CK_PTR CK_INFO_PTR;
2986 +
2987 +
2988 +/* CK_NOTIFICATION enumerates the types of notifications that
2989 + * Cryptoki provides to an application */
2990 +/* CK_NOTIFICATION has been changed from an enum to a CK_ULONG
2991 + * for v2.0 */
2992 +typedef CK_ULONG CK_NOTIFICATION;
2993 +#define CKN_SURRENDER 0
2994 +
2995 +
2996 +typedef CK_ULONG CK_SLOT_ID;
2997 +
2998 +typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
2999 +
3000 +
3001 +/* CK_SLOT_INFO provides information about a slot */
3002 +typedef struct CK_SLOT_INFO {
3003 + /* slotDescription and manufacturerID have been changed from
3004 + * CK_CHAR to CK_UTF8CHAR for v2.10 */
3005 + CK_UTF8CHAR slotDescription[64]; /* blank padded */
3006 + CK_UTF8CHAR manufacturerID[32]; /* blank padded */
3007 + CK_FLAGS flags;
3008 +
3009 + /* hardwareVersion and firmwareVersion are new for v2.0 */
3010 + CK_VERSION hardwareVersion; /* version of hardware */
3011 + CK_VERSION firmwareVersion; /* version of firmware */
3012 +} CK_SLOT_INFO;
3013 +
3014 +/* flags: bit flags that provide capabilities of the slot
3015 + * Bit Flag Mask Meaning
3016 + */
3017 +#define CKF_TOKEN_PRESENT 0x00000001 /* a token is there */
3018 +#define CKF_REMOVABLE_DEVICE 0x00000002 /* removable devices*/
3019 +#define CKF_HW_SLOT 0x00000004 /* hardware slot */
3020 +
3021 +typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
3022 +
3023 +
3024 +/* CK_TOKEN_INFO provides information about a token */
3025 +typedef struct CK_TOKEN_INFO {
3026 + /* label, manufacturerID, and model have been changed from
3027 + * CK_CHAR to CK_UTF8CHAR for v2.10 */
3028 + CK_UTF8CHAR label[32]; /* blank padded */
3029 + CK_UTF8CHAR manufacturerID[32]; /* blank padded */
3030 + CK_UTF8CHAR model[16]; /* blank padded */
3031 + CK_CHAR serialNumber[16]; /* blank padded */
3032 + CK_FLAGS flags; /* see below */
3033 +
3034 + /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount,
3035 + * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been
3036 + * changed from CK_USHORT to CK_ULONG for v2.0 */
3037 + CK_ULONG ulMaxSessionCount; /* max open sessions */
3038 + CK_ULONG ulSessionCount; /* sess. now open */
3039 + CK_ULONG ulMaxRwSessionCount; /* max R/W sessions */
3040 + CK_ULONG ulRwSessionCount; /* R/W sess. now open */
3041 + CK_ULONG ulMaxPinLen; /* in bytes */
3042 + CK_ULONG ulMinPinLen; /* in bytes */
3043 + CK_ULONG ulTotalPublicMemory; /* in bytes */
3044 + CK_ULONG ulFreePublicMemory; /* in bytes */
3045 + CK_ULONG ulTotalPrivateMemory; /* in bytes */
3046 + CK_ULONG ulFreePrivateMemory; /* in bytes */
3047 +
3048 + /* hardwareVersion, firmwareVersion, and time are new for
3049 + * v2.0 */
3050 + CK_VERSION hardwareVersion; /* version of hardware */
3051 + CK_VERSION firmwareVersion; /* version of firmware */
3052 + CK_CHAR utcTime[16]; /* time */
3053 +} CK_TOKEN_INFO;
3054 +
3055 +/* The flags parameter is defined as follows:
3056 + * Bit Flag Mask Meaning
3057 + */
3058 +#define CKF_RNG 0x00000001 /* has random #
3059 + * generator */
3060 +#define CKF_WRITE_PROTECTED 0x00000002 /* token is
3061 + * write-
3062 + * protected */
3063 +#define CKF_LOGIN_REQUIRED 0x00000004 /* user must
3064 + * login */
3065 +#define CKF_USER_PIN_INITIALIZED 0x00000008 /* normal user's
3066 + * PIN is set */
3067 +
3068 +/* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0. If it is set,
3069 + * that means that *every* time the state of cryptographic
3070 + * operations of a session is successfully saved, all keys
3071 + * needed to continue those operations are stored in the state */
3072 +#define CKF_RESTORE_KEY_NOT_NEEDED 0x00000020
3073 +
3074 +/* CKF_CLOCK_ON_TOKEN is new for v2.0. If it is set, that means
3075 + * that the token has some sort of clock. The time on that
3076 + * clock is returned in the token info structure */
3077 +#define CKF_CLOCK_ON_TOKEN 0x00000040
3078 +
3079 +/* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0. If it is
3080 + * set, that means that there is some way for the user to login
3081 + * without sending a PIN through the Cryptoki library itself */
3082 +#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100
3083 +
3084 +/* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0. If it is true,
3085 + * that means that a single session with the token can perform
3086 + * dual simultaneous cryptographic operations (digest and
3087 + * encrypt; decrypt and digest; sign and encrypt; and decrypt
3088 + * and sign) */
3089 +#define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200
3090 +
3091 +/* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the
3092 + * token has been initialized using C_InitializeToken or an
3093 + * equivalent mechanism outside the scope of PKCS #11.
3094 + * Calling C_InitializeToken when this flag is set will cause
3095 + * the token to be reinitialized. */
3096 +#define CKF_TOKEN_INITIALIZED 0x00000400
3097 +
3098 +/* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is
3099 + * true, the token supports secondary authentication for
3100 + * private key objects. This flag is deprecated in v2.11 and
3101 + onwards. */
3102 +#define CKF_SECONDARY_AUTHENTICATION 0x00000800
3103 +
3104 +/* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an
3105 + * incorrect user login PIN has been entered at least once
3106 + * since the last successful authentication. */
3107 +#define CKF_USER_PIN_COUNT_LOW 0x00010000
3108 +
3109 +/* CKF_USER_PIN_FINAL_TRY if new for v2.10. If it is true,
3110 + * supplying an incorrect user PIN will it to become locked. */
3111 +#define CKF_USER_PIN_FINAL_TRY 0x00020000
3112 +
3113 +/* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the
3114 + * user PIN has been locked. User login to the token is not
3115 + * possible. */
3116 +#define CKF_USER_PIN_LOCKED 0x00040000
3117 +
3118 +/* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
3119 + * the user PIN value is the default value set by token
3120 + * initialization or manufacturing, or the PIN has been
3121 + * expired by the card. */
3122 +#define CKF_USER_PIN_TO_BE_CHANGED 0x00080000
3123 +
3124 +/* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an
3125 + * incorrect SO login PIN has been entered at least once since
3126 + * the last successful authentication. */
3127 +#define CKF_SO_PIN_COUNT_LOW 0x00100000
3128 +
3129 +/* CKF_SO_PIN_FINAL_TRY if new for v2.10. If it is true,
3130 + * supplying an incorrect SO PIN will it to become locked. */
3131 +#define CKF_SO_PIN_FINAL_TRY 0x00200000
3132 +
3133 +/* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO
3134 + * PIN has been locked. SO login to the token is not possible.
3135 + */
3136 +#define CKF_SO_PIN_LOCKED 0x00400000
3137 +
3138 +/* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
3139 + * the SO PIN value is the default value set by token
3140 + * initialization or manufacturing, or the PIN has been
3141 + * expired by the card. */
3142 +#define CKF_SO_PIN_TO_BE_CHANGED 0x00800000
3143 +
3144 +typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
3145 +
3146 +
3147 +/* CK_SESSION_HANDLE is a Cryptoki-assigned value that
3148 + * identifies a session */
3149 +typedef CK_ULONG CK_SESSION_HANDLE;
3150 +
3151 +typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR;
3152 +
3153 +
3154 +/* CK_USER_TYPE enumerates the types of Cryptoki users */
3155 +/* CK_USER_TYPE has been changed from an enum to a CK_ULONG for
3156 + * v2.0 */
3157 +typedef CK_ULONG CK_USER_TYPE;
3158 +/* Security Officer */
3159 +#define CKU_SO 0
3160 +/* Normal user */
3161 +#define CKU_USER 1
3162 +/* Context specific (added in v2.20) */
3163 +#define CKU_CONTEXT_SPECIFIC 2
3164 +
3165 +/* CK_STATE enumerates the session states */
3166 +/* CK_STATE has been changed from an enum to a CK_ULONG for
3167 + * v2.0 */
3168 +typedef CK_ULONG CK_STATE;
3169 +#define CKS_RO_PUBLIC_SESSION 0
3170 +#define CKS_RO_USER_FUNCTIONS 1
3171 +#define CKS_RW_PUBLIC_SESSION 2
3172 +#define CKS_RW_USER_FUNCTIONS 3
3173 +#define CKS_RW_SO_FUNCTIONS 4
3174 +
3175 +
3176 +/* CK_SESSION_INFO provides information about a session */
3177 +typedef struct CK_SESSION_INFO {
3178 + CK_SLOT_ID slotID;
3179 + CK_STATE state;
3180 + CK_FLAGS flags; /* see below */
3181 +
3182 + /* ulDeviceError was changed from CK_USHORT to CK_ULONG for
3183 + * v2.0 */
3184 + CK_ULONG ulDeviceError; /* device-dependent error code */
3185 +} CK_SESSION_INFO;
3186 +
3187 +/* The flags are defined in the following table:
3188 + * Bit Flag Mask Meaning
3189 + */
3190 +#define CKF_RW_SESSION 0x00000002 /* session is r/w */
3191 +#define CKF_SERIAL_SESSION 0x00000004 /* no parallel */
3192 +
3193 +typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR;
3194 +
3195 +
3196 +/* CK_OBJECT_HANDLE is a token-specific identifier for an
3197 + * object */
3198 +typedef CK_ULONG CK_OBJECT_HANDLE;
3199 +
3200 +typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR;
3201 +
3202 +
3203 +/* CK_OBJECT_CLASS is a value that identifies the classes (or
3204 + * types) of objects that Cryptoki recognizes. It is defined
3205 + * as follows: */
3206 +/* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for
3207 + * v2.0 */
3208 +typedef CK_ULONG CK_OBJECT_CLASS;
3209 +
3210 +/* The following classes of objects are defined: */
3211 +/* CKO_HW_FEATURE is new for v2.10 */
3212 +/* CKO_DOMAIN_PARAMETERS is new for v2.11 */
3213 +/* CKO_MECHANISM is new for v2.20 */
3214 +#define CKO_DATA 0x00000000
3215 +#define CKO_CERTIFICATE 0x00000001
3216 +#define CKO_PUBLIC_KEY 0x00000002
3217 +#define CKO_PRIVATE_KEY 0x00000003
3218 +#define CKO_SECRET_KEY 0x00000004
3219 +#define CKO_HW_FEATURE 0x00000005
3220 +#define CKO_DOMAIN_PARAMETERS 0x00000006
3221 +#define CKO_MECHANISM 0x00000007
3222 +#define CKO_VENDOR_DEFINED 0x80000000
3223 +
3224 +typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
3225 +
3226 +/* CK_HW_FEATURE_TYPE is new for v2.10. CK_HW_FEATURE_TYPE is a
3227 + * value that identifies the hardware feature type of an object
3228 + * with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. */
3229 +typedef CK_ULONG CK_HW_FEATURE_TYPE;
3230 +
3231 +/* The following hardware feature types are defined */
3232 +/* CKH_USER_INTERFACE is new for v2.20 */
3233 +#define CKH_MONOTONIC_COUNTER 0x00000001
3234 +#define CKH_CLOCK 0x00000002
3235 +#define CKH_USER_INTERFACE 0x00000003
3236 +#define CKH_VENDOR_DEFINED 0x80000000
3237 +
3238 +/* CK_KEY_TYPE is a value that identifies a key type */
3239 +/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */
3240 +typedef CK_ULONG CK_KEY_TYPE;
3241 +
3242 +/* the following key types are defined: */
3243 +#define CKK_RSA 0x00000000
3244 +#define CKK_DSA 0x00000001
3245 +#define CKK_DH 0x00000002
3246 +
3247 +/* CKK_ECDSA and CKK_KEA are new for v2.0 */
3248 +/* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred. */
3249 +#define CKK_ECDSA 0x00000003
3250 +#define CKK_EC 0x00000003
3251 +#define CKK_X9_42_DH 0x00000004
3252 +#define CKK_KEA 0x00000005
3253 +
3254 +#define CKK_GENERIC_SECRET 0x00000010
3255 +#define CKK_RC2 0x00000011
3256 +#define CKK_RC4 0x00000012
3257 +#define CKK_DES 0x00000013
3258 +#define CKK_DES2 0x00000014
3259 +#define CKK_DES3 0x00000015
3260 +
3261 +/* all these key types are new for v2.0 */
3262 +#define CKK_CAST 0x00000016
3263 +#define CKK_CAST3 0x00000017
3264 +/* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred. */
3265 +#define CKK_CAST5 0x00000018
3266 +#define CKK_CAST128 0x00000018
3267 +#define CKK_RC5 0x00000019
3268 +#define CKK_IDEA 0x0000001A
3269 +#define CKK_SKIPJACK 0x0000001B
3270 +#define CKK_BATON 0x0000001C
3271 +#define CKK_JUNIPER 0x0000001D
3272 +#define CKK_CDMF 0x0000001E
3273 +#define CKK_AES 0x0000001F
3274 +
3275 +/* BlowFish and TwoFish are new for v2.20 */
3276 +#define CKK_BLOWFISH 0x00000020
3277 +#define CKK_TWOFISH 0x00000021
3278 +
3279 +#define CKK_VENDOR_DEFINED 0x80000000
3280 +
3281 +
3282 +/* CK_CERTIFICATE_TYPE is a value that identifies a certificate
3283 + * type */
3284 +/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG
3285 + * for v2.0 */
3286 +typedef CK_ULONG CK_CERTIFICATE_TYPE;
3287 +
3288 +/* The following certificate types are defined: */
3289 +/* CKC_X_509_ATTR_CERT is new for v2.10 */
3290 +/* CKC_WTLS is new for v2.20 */
3291 +#define CKC_X_509 0x00000000
3292 +#define CKC_X_509_ATTR_CERT 0x00000001
3293 +#define CKC_WTLS 0x00000002
3294 +#define CKC_VENDOR_DEFINED 0x80000000
3295 +
3296 +
3297 +/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute
3298 + * type */
3299 +/* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for
3300 + * v2.0 */
3301 +typedef CK_ULONG CK_ATTRIBUTE_TYPE;
3302 +
3303 +/* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which
3304 + consists of an array of values. */
3305 +#define CKF_ARRAY_ATTRIBUTE 0x40000000
3306 +
3307 +/* The following attribute types are defined: */
3308 +#define CKA_CLASS 0x00000000
3309 +#define CKA_TOKEN 0x00000001
3310 +#define CKA_PRIVATE 0x00000002
3311 +#define CKA_LABEL 0x00000003
3312 +#define CKA_APPLICATION 0x00000010
3313 +#define CKA_VALUE 0x00000011
3314 +
3315 +/* CKA_OBJECT_ID is new for v2.10 */
3316 +#define CKA_OBJECT_ID 0x00000012
3317 +
3318 +#define CKA_CERTIFICATE_TYPE 0x00000080
3319 +#define CKA_ISSUER 0x00000081
3320 +#define CKA_SERIAL_NUMBER 0x00000082
3321 +
3322 +/* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new
3323 + * for v2.10 */
3324 +#define CKA_AC_ISSUER 0x00000083
3325 +#define CKA_OWNER 0x00000084
3326 +#define CKA_ATTR_TYPES 0x00000085
3327 +
3328 +/* CKA_TRUSTED is new for v2.11 */
3329 +#define CKA_TRUSTED 0x00000086
3330 +
3331 +/* CKA_CERTIFICATE_CATEGORY ...
3332 + * CKA_CHECK_VALUE are new for v2.20 */
3333 +#define CKA_CERTIFICATE_CATEGORY 0x00000087
3334 +#define CKA_JAVA_MIDP_SECURITY_DOMAIN 0x00000088
3335 +#define CKA_URL 0x00000089
3336 +#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY 0x0000008A
3337 +#define CKA_HASH_OF_ISSUER_PUBLIC_KEY 0x0000008B
3338 +#define CKA_CHECK_VALUE 0x00000090
3339 +
3340 +#define CKA_KEY_TYPE 0x00000100
3341 +#define CKA_SUBJECT 0x00000101
3342 +#define CKA_ID 0x00000102
3343 +#define CKA_SENSITIVE 0x00000103
3344 +#define CKA_ENCRYPT 0x00000104
3345 +#define CKA_DECRYPT 0x00000105
3346 +#define CKA_WRAP 0x00000106
3347 +#define CKA_UNWRAP 0x00000107
3348 +#define CKA_SIGN 0x00000108
3349 +#define CKA_SIGN_RECOVER 0x00000109
3350 +#define CKA_VERIFY 0x0000010A
3351 +#define CKA_VERIFY_RECOVER 0x0000010B
3352 +#define CKA_DERIVE 0x0000010C
3353 +#define CKA_START_DATE 0x00000110
3354 +#define CKA_END_DATE 0x00000111
3355 +#define CKA_MODULUS 0x00000120
3356 +#define CKA_MODULUS_BITS 0x00000121
3357 +#define CKA_PUBLIC_EXPONENT 0x00000122
3358 +#define CKA_PRIVATE_EXPONENT 0x00000123
3359 +#define CKA_PRIME_1 0x00000124
3360 +#define CKA_PRIME_2 0x00000125
3361 +#define CKA_EXPONENT_1 0x00000126
3362 +#define CKA_EXPONENT_2 0x00000127
3363 +#define CKA_COEFFICIENT 0x00000128
3364 +#define CKA_PRIME 0x00000130
3365 +#define CKA_SUBPRIME 0x00000131
3366 +#define CKA_BASE 0x00000132
3367 +
3368 +/* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */
3369 +#define CKA_PRIME_BITS 0x00000133
3370 +#define CKA_SUBPRIME_BITS 0x00000134
3371 +#define CKA_SUB_PRIME_BITS CKA_SUBPRIME_BITS
3372 +/* (To retain backwards-compatibility) */
3373 +
3374 +#define CKA_VALUE_BITS 0x00000160
3375 +#define CKA_VALUE_LEN 0x00000161
3376 +
3377 +/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
3378 + * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS,
3379 + * and CKA_EC_POINT are new for v2.0 */
3380 +#define CKA_EXTRACTABLE 0x00000162
3381 +#define CKA_LOCAL 0x00000163
3382 +#define CKA_NEVER_EXTRACTABLE 0x00000164
3383 +#define CKA_ALWAYS_SENSITIVE 0x00000165
3384 +
3385 +/* CKA_KEY_GEN_MECHANISM is new for v2.11 */
3386 +#define CKA_KEY_GEN_MECHANISM 0x00000166
3387 +
3388 +#define CKA_MODIFIABLE 0x00000170
3389 +
3390 +/* CKA_ECDSA_PARAMS is deprecated in v2.11,
3391 + * CKA_EC_PARAMS is preferred. */
3392 +#define CKA_ECDSA_PARAMS 0x00000180
3393 +#define CKA_EC_PARAMS 0x00000180
3394 +
3395 +#define CKA_EC_POINT 0x00000181
3396 +
3397 +/* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
3398 + * are new for v2.10. Deprecated in v2.11 and onwards. */
3399 +#define CKA_SECONDARY_AUTH 0x00000200
3400 +#define CKA_AUTH_PIN_FLAGS 0x00000201
3401 +
3402 +/* CKA_ALWAYS_AUTHENTICATE ...
3403 + * CKA_UNWRAP_TEMPLATE are new for v2.20 */
3404 +#define CKA_ALWAYS_AUTHENTICATE 0x00000202
3405 +
3406 +#define CKA_WRAP_WITH_TRUSTED 0x00000210
3407 +#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000211)
3408 +#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000212)
3409 +
3410 +/* CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET
3411 + * are new for v2.10 */
3412 +#define CKA_HW_FEATURE_TYPE 0x00000300
3413 +#define CKA_RESET_ON_INIT 0x00000301
3414 +#define CKA_HAS_RESET 0x00000302
3415 +
3416 +/* The following attributes are new for v2.20 */
3417 +#define CKA_PIXEL_X 0x00000400
3418 +#define CKA_PIXEL_Y 0x00000401
3419 +#define CKA_RESOLUTION 0x00000402
3420 +#define CKA_CHAR_ROWS 0x00000403
3421 +#define CKA_CHAR_COLUMNS 0x00000404
3422 +#define CKA_COLOR 0x00000405
3423 +#define CKA_BITS_PER_PIXEL 0x00000406
3424 +#define CKA_CHAR_SETS 0x00000480
3425 +#define CKA_ENCODING_METHODS 0x00000481
3426 +#define CKA_MIME_TYPES 0x00000482
3427 +#define CKA_MECHANISM_TYPE 0x00000500
3428 +#define CKA_REQUIRED_CMS_ATTRIBUTES 0x00000501
3429 +#define CKA_DEFAULT_CMS_ATTRIBUTES 0x00000502
3430 +#define CKA_SUPPORTED_CMS_ATTRIBUTES 0x00000503
3431 +#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE|0x00000600)
3432 +
3433 +#define CKA_VENDOR_DEFINED 0x80000000
3434 +
3435 +
3436 +/* CK_ATTRIBUTE is a structure that includes the type, length
3437 + * and value of an attribute */
3438 +typedef struct CK_ATTRIBUTE {
3439 + CK_ATTRIBUTE_TYPE type;
3440 + CK_VOID_PTR pValue;
3441 +
3442 + /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */
3443 + CK_ULONG ulValueLen; /* in bytes */
3444 +} CK_ATTRIBUTE;
3445 +
3446 +typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR;
3447 +
3448 +
3449 +/* CK_DATE is a structure that defines a date */
3450 +typedef struct CK_DATE{
3451 + CK_CHAR year[4]; /* the year ("1900" - "9999") */
3452 + CK_CHAR month[2]; /* the month ("01" - "12") */
3453 + CK_CHAR day[2]; /* the day ("01" - "31") */
3454 +} CK_DATE;
3455 +
3456 +
3457 +/* CK_MECHANISM_TYPE is a value that identifies a mechanism
3458 + * type */
3459 +/* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for
3460 + * v2.0 */
3461 +typedef CK_ULONG CK_MECHANISM_TYPE;
3462 +
3463 +/* the following mechanism types are defined: */
3464 +#define CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000
3465 +#define CKM_RSA_PKCS 0x00000001
3466 +#define CKM_RSA_9796 0x00000002
3467 +#define CKM_RSA_X_509 0x00000003
3468 +
3469 +/* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS
3470 + * are new for v2.0. They are mechanisms which hash and sign */
3471 +#define CKM_MD2_RSA_PKCS 0x00000004
3472 +#define CKM_MD5_RSA_PKCS 0x00000005
3473 +#define CKM_SHA1_RSA_PKCS 0x00000006
3474 +
3475 +/* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, and
3476 + * CKM_RSA_PKCS_OAEP are new for v2.10 */
3477 +#define CKM_RIPEMD128_RSA_PKCS 0x00000007
3478 +#define CKM_RIPEMD160_RSA_PKCS 0x00000008
3479 +#define CKM_RSA_PKCS_OAEP 0x00000009
3480 +
3481 +/* CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31,
3482 + * CKM_RSA_PKCS_PSS, and CKM_SHA1_RSA_PKCS_PSS are new for v2.11 */
3483 +#define CKM_RSA_X9_31_KEY_PAIR_GEN 0x0000000A
3484 +#define CKM_RSA_X9_31 0x0000000B
3485 +#define CKM_SHA1_RSA_X9_31 0x0000000C
3486 +#define CKM_RSA_PKCS_PSS 0x0000000D
3487 +#define CKM_SHA1_RSA_PKCS_PSS 0x0000000E
3488 +
3489 +#define CKM_DSA_KEY_PAIR_GEN 0x00000010
3490 +#define CKM_DSA 0x00000011
3491 +#define CKM_DSA_SHA1 0x00000012
3492 +#define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020
3493 +#define CKM_DH_PKCS_DERIVE 0x00000021
3494 +
3495 +/* CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE,
3496 + * CKM_X9_42_DH_HYBRID_DERIVE, and CKM_X9_42_MQV_DERIVE are new for
3497 + * v2.11 */
3498 +#define CKM_X9_42_DH_KEY_PAIR_GEN 0x00000030
3499 +#define CKM_X9_42_DH_DERIVE 0x00000031
3500 +#define CKM_X9_42_DH_HYBRID_DERIVE 0x00000032
3501 +#define CKM_X9_42_MQV_DERIVE 0x00000033
3502 +
3503 +/* CKM_SHA256/384/512 are new for v2.20 */
3504 +#define CKM_SHA256_RSA_PKCS 0x00000040
3505 +#define CKM_SHA384_RSA_PKCS 0x00000041
3506 +#define CKM_SHA512_RSA_PKCS 0x00000042
3507 +#define CKM_SHA256_RSA_PKCS_PSS 0x00000043
3508 +#define CKM_SHA384_RSA_PKCS_PSS 0x00000044
3509 +#define CKM_SHA512_RSA_PKCS_PSS 0x00000045
3510 +
3511 +#define CKM_RC2_KEY_GEN 0x00000100
3512 +#define CKM_RC2_ECB 0x00000101
3513 +#define CKM_RC2_CBC 0x00000102
3514 +#define CKM_RC2_MAC 0x00000103
3515 +
3516 +/* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */
3517 +#define CKM_RC2_MAC_GENERAL 0x00000104
3518 +#define CKM_RC2_CBC_PAD 0x00000105
3519 +
3520 +#define CKM_RC4_KEY_GEN 0x00000110
3521 +#define CKM_RC4 0x00000111
3522 +#define CKM_DES_KEY_GEN 0x00000120
3523 +#define CKM_DES_ECB 0x00000121
3524 +#define CKM_DES_CBC 0x00000122
3525 +#define CKM_DES_MAC 0x00000123
3526 +
3527 +/* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */
3528 +#define CKM_DES_MAC_GENERAL 0x00000124
3529 +#define CKM_DES_CBC_PAD 0x00000125
3530 +
3531 +#define CKM_DES2_KEY_GEN 0x00000130
3532 +#define CKM_DES3_KEY_GEN 0x00000131
3533 +#define CKM_DES3_ECB 0x00000132
3534 +#define CKM_DES3_CBC 0x00000133
3535 +#define CKM_DES3_MAC 0x00000134
3536 +
3537 +/* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN,
3538 + * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC,
3539 + * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */
3540 +#define CKM_DES3_MAC_GENERAL 0x00000135
3541 +#define CKM_DES3_CBC_PAD 0x00000136
3542 +#define CKM_CDMF_KEY_GEN 0x00000140
3543 +#define CKM_CDMF_ECB 0x00000141
3544 +#define CKM_CDMF_CBC 0x00000142
3545 +#define CKM_CDMF_MAC 0x00000143
3546 +#define CKM_CDMF_MAC_GENERAL 0x00000144
3547 +#define CKM_CDMF_CBC_PAD 0x00000145
3548 +
3549 +/* the following four DES mechanisms are new for v2.20 */
3550 +#define CKM_DES_OFB64 0x00000150
3551 +#define CKM_DES_OFB8 0x00000151
3552 +#define CKM_DES_CFB64 0x00000152
3553 +#define CKM_DES_CFB8 0x00000153
3554 +
3555 +#define CKM_MD2 0x00000200
3556 +
3557 +/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */
3558 +#define CKM_MD2_HMAC 0x00000201
3559 +#define CKM_MD2_HMAC_GENERAL 0x00000202
3560 +
3561 +#define CKM_MD5 0x00000210
3562 +
3563 +/* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */
3564 +#define CKM_MD5_HMAC 0x00000211
3565 +#define CKM_MD5_HMAC_GENERAL 0x00000212
3566 +
3567 +#define CKM_SHA_1 0x00000220
3568 +
3569 +/* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */
3570 +#define CKM_SHA_1_HMAC 0x00000221
3571 +#define CKM_SHA_1_HMAC_GENERAL 0x00000222
3572 +
3573 +/* CKM_RIPEMD128, CKM_RIPEMD128_HMAC,
3574 + * CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC,
3575 + * and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */
3576 +#define CKM_RIPEMD128 0x00000230
3577 +#define CKM_RIPEMD128_HMAC 0x00000231
3578 +#define CKM_RIPEMD128_HMAC_GENERAL 0x00000232
3579 +#define CKM_RIPEMD160 0x00000240
3580 +#define CKM_RIPEMD160_HMAC 0x00000241
3581 +#define CKM_RIPEMD160_HMAC_GENERAL 0x00000242
3582 +
3583 +/* CKM_SHA256/384/512 are new for v2.20 */
3584 +#define CKM_SHA256 0x00000250
3585 +#define CKM_SHA256_HMAC 0x00000251
3586 +#define CKM_SHA256_HMAC_GENERAL 0x00000252
3587 +#define CKM_SHA384 0x00000260
3588 +#define CKM_SHA384_HMAC 0x00000261
3589 +#define CKM_SHA384_HMAC_GENERAL 0x00000262
3590 +#define CKM_SHA512 0x00000270
3591 +#define CKM_SHA512_HMAC 0x00000271
3592 +#define CKM_SHA512_HMAC_GENERAL 0x00000272
3593 +
3594 +/* All of the following mechanisms are new for v2.0 */
3595 +/* Note that CAST128 and CAST5 are the same algorithm */
3596 +#define CKM_CAST_KEY_GEN 0x00000300
3597 +#define CKM_CAST_ECB 0x00000301
3598 +#define CKM_CAST_CBC 0x00000302
3599 +#define CKM_CAST_MAC 0x00000303
3600 +#define CKM_CAST_MAC_GENERAL 0x00000304
3601 +#define CKM_CAST_CBC_PAD 0x00000305
3602 +#define CKM_CAST3_KEY_GEN 0x00000310
3603 +#define CKM_CAST3_ECB 0x00000311
3604 +#define CKM_CAST3_CBC 0x00000312
3605 +#define CKM_CAST3_MAC 0x00000313
3606 +#define CKM_CAST3_MAC_GENERAL 0x00000314
3607 +#define CKM_CAST3_CBC_PAD 0x00000315
3608 +#define CKM_CAST5_KEY_GEN 0x00000320
3609 +#define CKM_CAST128_KEY_GEN 0x00000320
3610 +#define CKM_CAST5_ECB 0x00000321
3611 +#define CKM_CAST128_ECB 0x00000321
3612 +#define CKM_CAST5_CBC 0x00000322
3613 +#define CKM_CAST128_CBC 0x00000322
3614 +#define CKM_CAST5_MAC 0x00000323
3615 +#define CKM_CAST128_MAC 0x00000323
3616 +#define CKM_CAST5_MAC_GENERAL 0x00000324
3617 +#define CKM_CAST128_MAC_GENERAL 0x00000324
3618 +#define CKM_CAST5_CBC_PAD 0x00000325
3619 +#define CKM_CAST128_CBC_PAD 0x00000325
3620 +#define CKM_RC5_KEY_GEN 0x00000330
3621 +#define CKM_RC5_ECB 0x00000331
3622 +#define CKM_RC5_CBC 0x00000332
3623 +#define CKM_RC5_MAC 0x00000333
3624 +#define CKM_RC5_MAC_GENERAL 0x00000334
3625 +#define CKM_RC5_CBC_PAD 0x00000335
3626 +#define CKM_IDEA_KEY_GEN 0x00000340
3627 +#define CKM_IDEA_ECB 0x00000341
3628 +#define CKM_IDEA_CBC 0x00000342
3629 +#define CKM_IDEA_MAC 0x00000343
3630 +#define CKM_IDEA_MAC_GENERAL 0x00000344
3631 +#define CKM_IDEA_CBC_PAD 0x00000345
3632 +#define CKM_GENERIC_SECRET_KEY_GEN 0x00000350
3633 +#define CKM_CONCATENATE_BASE_AND_KEY 0x00000360
3634 +#define CKM_CONCATENATE_BASE_AND_DATA 0x00000362
3635 +#define CKM_CONCATENATE_DATA_AND_BASE 0x00000363
3636 +#define CKM_XOR_BASE_AND_DATA 0x00000364
3637 +#define CKM_EXTRACT_KEY_FROM_KEY 0x00000365
3638 +#define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370
3639 +#define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371
3640 +#define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372
3641 +
3642 +/* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN,
3643 + * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE, and
3644 + * CKM_TLS_MASTER_KEY_DERIVE_DH are new for v2.11 */
3645 +#define CKM_SSL3_MASTER_KEY_DERIVE_DH 0x00000373
3646 +#define CKM_TLS_PRE_MASTER_KEY_GEN 0x00000374
3647 +#define CKM_TLS_MASTER_KEY_DERIVE 0x00000375
3648 +#define CKM_TLS_KEY_AND_MAC_DERIVE 0x00000376
3649 +#define CKM_TLS_MASTER_KEY_DERIVE_DH 0x00000377
3650 +
3651 +/* CKM_TLS_PRF is new for v2.20 */
3652 +#define CKM_TLS_PRF 0x00000378
3653 +
3654 +#define CKM_SSL3_MD5_MAC 0x00000380
3655 +#define CKM_SSL3_SHA1_MAC 0x00000381
3656 +#define CKM_MD5_KEY_DERIVATION 0x00000390
3657 +#define CKM_MD2_KEY_DERIVATION 0x00000391
3658 +#define CKM_SHA1_KEY_DERIVATION 0x00000392
3659 +
3660 +/* CKM_SHA256/384/512 are new for v2.20 */
3661 +#define CKM_SHA256_KEY_DERIVATION 0x00000393
3662 +#define CKM_SHA384_KEY_DERIVATION 0x00000394
3663 +#define CKM_SHA512_KEY_DERIVATION 0x00000395
3664 +
3665 +#define CKM_PBE_MD2_DES_CBC 0x000003A0
3666 +#define CKM_PBE_MD5_DES_CBC 0x000003A1
3667 +#define CKM_PBE_MD5_CAST_CBC 0x000003A2
3668 +#define CKM_PBE_MD5_CAST3_CBC 0x000003A3
3669 +#define CKM_PBE_MD5_CAST5_CBC 0x000003A4
3670 +#define CKM_PBE_MD5_CAST128_CBC 0x000003A4
3671 +#define CKM_PBE_SHA1_CAST5_CBC 0x000003A5
3672 +#define CKM_PBE_SHA1_CAST128_CBC 0x000003A5
3673 +#define CKM_PBE_SHA1_RC4_128 0x000003A6
3674 +#define CKM_PBE_SHA1_RC4_40 0x000003A7
3675 +#define CKM_PBE_SHA1_DES3_EDE_CBC 0x000003A8
3676 +#define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9
3677 +#define CKM_PBE_SHA1_RC2_128_CBC 0x000003AA
3678 +#define CKM_PBE_SHA1_RC2_40_CBC 0x000003AB
3679 +
3680 +/* CKM_PKCS5_PBKD2 is new for v2.10 */
3681 +#define CKM_PKCS5_PBKD2 0x000003B0
3682 +
3683 +#define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0
3684 +
3685 +/* WTLS mechanisms are new for v2.20 */
3686 +#define CKM_WTLS_PRE_MASTER_KEY_GEN 0x000003D0
3687 +#define CKM_WTLS_MASTER_KEY_DERIVE 0x000003D1
3688 +#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC 0x000003D2
3689 +#define CKM_WTLS_PRF 0x000003D3
3690 +#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE 0x000003D4
3691 +#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE 0x000003D5
3692 +
3693 +#define CKM_KEY_WRAP_LYNKS 0x00000400
3694 +#define CKM_KEY_WRAP_SET_OAEP 0x00000401
3695 +
3696 +/* CKM_CMS_SIG is new for v2.20 */
3697 +#define CKM_CMS_SIG 0x00000500
3698 +
3699 +/* Fortezza mechanisms */
3700 +#define CKM_SKIPJACK_KEY_GEN 0x00001000
3701 +#define CKM_SKIPJACK_ECB64 0x00001001
3702 +#define CKM_SKIPJACK_CBC64 0x00001002
3703 +#define CKM_SKIPJACK_OFB64 0x00001003
3704 +#define CKM_SKIPJACK_CFB64 0x00001004
3705 +#define CKM_SKIPJACK_CFB32 0x00001005
3706 +#define CKM_SKIPJACK_CFB16 0x00001006
3707 +#define CKM_SKIPJACK_CFB8 0x00001007
3708 +#define CKM_SKIPJACK_WRAP 0x00001008
3709 +#define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009
3710 +#define CKM_SKIPJACK_RELAYX 0x0000100a
3711 +#define CKM_KEA_KEY_PAIR_GEN 0x00001010
3712 +#define CKM_KEA_KEY_DERIVE 0x00001011
3713 +#define CKM_FORTEZZA_TIMESTAMP 0x00001020
3714 +#define CKM_BATON_KEY_GEN 0x00001030
3715 +#define CKM_BATON_ECB128 0x00001031
3716 +#define CKM_BATON_ECB96 0x00001032
3717 +#define CKM_BATON_CBC128 0x00001033
3718 +#define CKM_BATON_COUNTER 0x00001034
3719 +#define CKM_BATON_SHUFFLE 0x00001035
3720 +#define CKM_BATON_WRAP 0x00001036
3721 +
3722 +/* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11,
3723 + * CKM_EC_KEY_PAIR_GEN is preferred */
3724 +#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040
3725 +#define CKM_EC_KEY_PAIR_GEN 0x00001040
3726 +
3727 +#define CKM_ECDSA 0x00001041
3728 +#define CKM_ECDSA_SHA1 0x00001042
3729 +
3730 +/* CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE, and CKM_ECMQV_DERIVE
3731 + * are new for v2.11 */
3732 +#define CKM_ECDH1_DERIVE 0x00001050
3733 +#define CKM_ECDH1_COFACTOR_DERIVE 0x00001051
3734 +#define CKM_ECMQV_DERIVE 0x00001052
3735 +
3736 +#define CKM_JUNIPER_KEY_GEN 0x00001060
3737 +#define CKM_JUNIPER_ECB128 0x00001061
3738 +#define CKM_JUNIPER_CBC128 0x00001062
3739 +#define CKM_JUNIPER_COUNTER 0x00001063
3740 +#define CKM_JUNIPER_SHUFFLE 0x00001064
3741 +#define CKM_JUNIPER_WRAP 0x00001065
3742 +#define CKM_FASTHASH 0x00001070
3743 +
3744 +/* CKM_AES_KEY_GEN, CKM_AES_ECB, CKM_AES_CBC, CKM_AES_MAC,
3745 + * CKM_AES_MAC_GENERAL, CKM_AES_CBC_PAD, CKM_DSA_PARAMETER_GEN,
3746 + * CKM_DH_PKCS_PARAMETER_GEN, and CKM_X9_42_DH_PARAMETER_GEN are
3747 + * new for v2.11 */
3748 +#define CKM_AES_KEY_GEN 0x00001080
3749 +#define CKM_AES_ECB 0x00001081
3750 +#define CKM_AES_CBC 0x00001082
3751 +#define CKM_AES_MAC 0x00001083
3752 +#define CKM_AES_MAC_GENERAL 0x00001084
3753 +#define CKM_AES_CBC_PAD 0x00001085
3754 +
3755 +/* BlowFish and TwoFish are new for v2.20 */
3756 +#define CKM_BLOWFISH_KEY_GEN 0x00001090
3757 +#define CKM_BLOWFISH_CBC 0x00001091
3758 +#define CKM_TWOFISH_KEY_GEN 0x00001092
3759 +#define CKM_TWOFISH_CBC 0x00001093
3760 +
3761 +
3762 +/* CKM_xxx_ENCRYPT_DATA mechanisms are new for v2.20 */
3763 +#define CKM_DES_ECB_ENCRYPT_DATA 0x00001100
3764 +#define CKM_DES_CBC_ENCRYPT_DATA 0x00001101
3765 +#define CKM_DES3_ECB_ENCRYPT_DATA 0x00001102
3766 +#define CKM_DES3_CBC_ENCRYPT_DATA 0x00001103
3767 +#define CKM_AES_ECB_ENCRYPT_DATA 0x00001104
3768 +#define CKM_AES_CBC_ENCRYPT_DATA 0x00001105
3769 +
3770 +#define CKM_DSA_PARAMETER_GEN 0x00002000
3771 +#define CKM_DH_PKCS_PARAMETER_GEN 0x00002001
3772 +#define CKM_X9_42_DH_PARAMETER_GEN 0x00002002
3773 +
3774 +#define CKM_VENDOR_DEFINED 0x80000000
3775 +
3776 +typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR;
3777 +
3778 +
3779 +/* CK_MECHANISM is a structure that specifies a particular
3780 + * mechanism */
3781 +typedef struct CK_MECHANISM {
3782 + CK_MECHANISM_TYPE mechanism;
3783 + CK_VOID_PTR pParameter;
3784 +
3785 + /* ulParameterLen was changed from CK_USHORT to CK_ULONG for
3786 + * v2.0 */
3787 + CK_ULONG ulParameterLen; /* in bytes */
3788 +} CK_MECHANISM;
3789 +
3790 +typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR;
3791 +
3792 +
3793 +/* CK_MECHANISM_INFO provides information about a particular
3794 + * mechanism */
3795 +typedef struct CK_MECHANISM_INFO {
3796 + CK_ULONG ulMinKeySize;
3797 + CK_ULONG ulMaxKeySize;
3798 + CK_FLAGS flags;
3799 +} CK_MECHANISM_INFO;
3800 +
3801 +/* The flags are defined as follows:
3802 + * Bit Flag Mask Meaning */
3803 +#define CKF_HW 0x00000001 /* performed by HW */
3804 +
3805 +/* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN,
3806 + * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER,
3807 + * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP,
3808 + * and CKF_DERIVE are new for v2.0. They specify whether or not
3809 + * a mechanism can be used for a particular task */
3810 +#define CKF_ENCRYPT 0x00000100
3811 +#define CKF_DECRYPT 0x00000200
3812 +#define CKF_DIGEST 0x00000400
3813 +#define CKF_SIGN 0x00000800
3814 +#define CKF_SIGN_RECOVER 0x00001000
3815 +#define CKF_VERIFY 0x00002000
3816 +#define CKF_VERIFY_RECOVER 0x00004000
3817 +#define CKF_GENERATE 0x00008000
3818 +#define CKF_GENERATE_KEY_PAIR 0x00010000
3819 +#define CKF_WRAP 0x00020000
3820 +#define CKF_UNWRAP 0x00040000
3821 +#define CKF_DERIVE 0x00080000
3822 +
3823 +/* CKF_EC_F_P, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE,
3824 + * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11. They
3825 + * describe a token's EC capabilities not available in mechanism
3826 + * information. */
3827 +#define CKF_EC_F_P 0x00100000
3828 +#define CKF_EC_F_2M 0x00200000
3829 +#define CKF_EC_ECPARAMETERS 0x00400000
3830 +#define CKF_EC_NAMEDCURVE 0x00800000
3831 +#define CKF_EC_UNCOMPRESS 0x01000000
3832 +#define CKF_EC_COMPRESS 0x02000000
3833 +
3834 +#define CKF_EXTENSION 0x80000000 /* FALSE for this version */
3835 +
3836 +typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR;
3837 +
3838 +
3839 +/* CK_RV is a value that identifies the return value of a
3840 + * Cryptoki function */
3841 +/* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */
3842 +typedef CK_ULONG CK_RV;
3843 +
3844 +#define CKR_OK 0x00000000
3845 +#define CKR_CANCEL 0x00000001
3846 +#define CKR_HOST_MEMORY 0x00000002
3847 +#define CKR_SLOT_ID_INVALID 0x00000003
3848 +
3849 +/* CKR_FLAGS_INVALID was removed for v2.0 */
3850 +
3851 +/* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */
3852 +#define CKR_GENERAL_ERROR 0x00000005
3853 +#define CKR_FUNCTION_FAILED 0x00000006
3854 +
3855 +/* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS,
3856 + * and CKR_CANT_LOCK are new for v2.01 */
3857 +#define CKR_ARGUMENTS_BAD 0x00000007
3858 +#define CKR_NO_EVENT 0x00000008
3859 +#define CKR_NEED_TO_CREATE_THREADS 0x00000009
3860 +#define CKR_CANT_LOCK 0x0000000A
3861 +
3862 +#define CKR_ATTRIBUTE_READ_ONLY 0x00000010
3863 +#define CKR_ATTRIBUTE_SENSITIVE 0x00000011
3864 +#define CKR_ATTRIBUTE_TYPE_INVALID 0x00000012
3865 +#define CKR_ATTRIBUTE_VALUE_INVALID 0x00000013
3866 +#define CKR_DATA_INVALID 0x00000020
3867 +#define CKR_DATA_LEN_RANGE 0x00000021
3868 +#define CKR_DEVICE_ERROR 0x00000030
3869 +#define CKR_DEVICE_MEMORY 0x00000031
3870 +#define CKR_DEVICE_REMOVED 0x00000032
3871 +#define CKR_ENCRYPTED_DATA_INVALID 0x00000040
3872 +#define CKR_ENCRYPTED_DATA_LEN_RANGE 0x00000041
3873 +#define CKR_FUNCTION_CANCELED 0x00000050
3874 +#define CKR_FUNCTION_NOT_PARALLEL 0x00000051
3875 +
3876 +/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */
3877 +#define CKR_FUNCTION_NOT_SUPPORTED 0x00000054
3878 +
3879 +#define CKR_KEY_HANDLE_INVALID 0x00000060
3880 +
3881 +/* CKR_KEY_SENSITIVE was removed for v2.0 */
3882 +
3883 +#define CKR_KEY_SIZE_RANGE 0x00000062
3884 +#define CKR_KEY_TYPE_INCONSISTENT 0x00000063
3885 +
3886 +/* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED,
3887 + * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED,
3888 + * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for
3889 + * v2.0 */
3890 +#define CKR_KEY_NOT_NEEDED 0x00000064
3891 +#define CKR_KEY_CHANGED 0x00000065
3892 +#define CKR_KEY_NEEDED 0x00000066
3893 +#define CKR_KEY_INDIGESTIBLE 0x00000067
3894 +#define CKR_KEY_FUNCTION_NOT_PERMITTED 0x00000068
3895 +#define CKR_KEY_NOT_WRAPPABLE 0x00000069
3896 +#define CKR_KEY_UNEXTRACTABLE 0x0000006A
3897 +
3898 +#define CKR_MECHANISM_INVALID 0x00000070
3899 +#define CKR_MECHANISM_PARAM_INVALID 0x00000071
3900 +
3901 +/* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID
3902 + * were removed for v2.0 */
3903 +#define CKR_OBJECT_HANDLE_INVALID 0x00000082
3904 +#define CKR_OPERATION_ACTIVE 0x00000090
3905 +#define CKR_OPERATION_NOT_INITIALIZED 0x00000091
3906 +#define CKR_PIN_INCORRECT 0x000000A0
3907 +#define CKR_PIN_INVALID 0x000000A1
3908 +#define CKR_PIN_LEN_RANGE 0x000000A2
3909 +
3910 +/* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */
3911 +#define CKR_PIN_EXPIRED 0x000000A3
3912 +#define CKR_PIN_LOCKED 0x000000A4
3913 +
3914 +#define CKR_SESSION_CLOSED 0x000000B0
3915 +#define CKR_SESSION_COUNT 0x000000B1
3916 +#define CKR_SESSION_HANDLE_INVALID 0x000000B3
3917 +#define CKR_SESSION_PARALLEL_NOT_SUPPORTED 0x000000B4
3918 +#define CKR_SESSION_READ_ONLY 0x000000B5
3919 +#define CKR_SESSION_EXISTS 0x000000B6
3920 +
3921 +/* CKR_SESSION_READ_ONLY_EXISTS and
3922 + * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */
3923 +#define CKR_SESSION_READ_ONLY_EXISTS 0x000000B7
3924 +#define CKR_SESSION_READ_WRITE_SO_EXISTS 0x000000B8
3925 +
3926 +#define CKR_SIGNATURE_INVALID 0x000000C0
3927 +#define CKR_SIGNATURE_LEN_RANGE 0x000000C1
3928 +#define CKR_TEMPLATE_INCOMPLETE 0x000000D0
3929 +#define CKR_TEMPLATE_INCONSISTENT 0x000000D1
3930 +#define CKR_TOKEN_NOT_PRESENT 0x000000E0
3931 +#define CKR_TOKEN_NOT_RECOGNIZED 0x000000E1
3932 +#define CKR_TOKEN_WRITE_PROTECTED 0x000000E2
3933 +#define CKR_UNWRAPPING_KEY_HANDLE_INVALID 0x000000F0
3934 +#define CKR_UNWRAPPING_KEY_SIZE_RANGE 0x000000F1
3935 +#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT 0x000000F2
3936 +#define CKR_USER_ALREADY_LOGGED_IN 0x00000100
3937 +#define CKR_USER_NOT_LOGGED_IN 0x00000101
3938 +#define CKR_USER_PIN_NOT_INITIALIZED 0x00000102
3939 +#define CKR_USER_TYPE_INVALID 0x00000103
3940 +
3941 +/* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES
3942 + * are new to v2.01 */
3943 +#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN 0x00000104
3944 +#define CKR_USER_TOO_MANY_TYPES 0x00000105
3945 +
3946 +#define CKR_WRAPPED_KEY_INVALID 0x00000110
3947 +#define CKR_WRAPPED_KEY_LEN_RANGE 0x00000112
3948 +#define CKR_WRAPPING_KEY_HANDLE_INVALID 0x00000113
3949 +#define CKR_WRAPPING_KEY_SIZE_RANGE 0x00000114
3950 +#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115
3951 +#define CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120
3952 +
3953 +/* These are new to v2.0 */
3954 +#define CKR_RANDOM_NO_RNG 0x00000121
3955 +
3956 +/* These are new to v2.11 */
3957 +#define CKR_DOMAIN_PARAMS_INVALID 0x00000130
3958 +
3959 +/* These are new to v2.0 */
3960 +#define CKR_BUFFER_TOO_SMALL 0x00000150
3961 +#define CKR_SAVED_STATE_INVALID 0x00000160
3962 +#define CKR_INFORMATION_SENSITIVE 0x00000170
3963 +#define CKR_STATE_UNSAVEABLE 0x00000180
3964 +
3965 +/* These are new to v2.01 */
3966 +#define CKR_CRYPTOKI_NOT_INITIALIZED 0x00000190
3967 +#define CKR_CRYPTOKI_ALREADY_INITIALIZED 0x00000191
3968 +#define CKR_MUTEX_BAD 0x000001A0
3969 +#define CKR_MUTEX_NOT_LOCKED 0x000001A1
3970 +
3971 +/* This is new to v2.20 */
3972 +#define CKR_FUNCTION_REJECTED 0x00000200
3973 +
3974 +#define CKR_VENDOR_DEFINED 0x80000000
3975 +
3976 +
3977 +/* CK_NOTIFY is an application callback that processes events */
3978 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)(
3979 + CK_SESSION_HANDLE hSession, /* the session's handle */
3980 + CK_NOTIFICATION event,
3981 + CK_VOID_PTR pApplication /* passed to C_OpenSession */
3982 +);
3983 +
3984 +
3985 +/* CK_FUNCTION_LIST is a structure holding a Cryptoki spec
3986 + * version and pointers of appropriate types to all the
3987 + * Cryptoki functions */
3988 +/* CK_FUNCTION_LIST is new for v2.0 */
3989 +typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST;
3990 +
3991 +typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR;
3992 +
3993 +typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR;
3994 +
3995 +
3996 +/* CK_CREATEMUTEX is an application callback for creating a
3997 + * mutex object */
3998 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)(
3999 + CK_VOID_PTR_PTR ppMutex /* location to receive ptr to mutex */
4000 +);
4001 +
4002 +
4003 +/* CK_DESTROYMUTEX is an application callback for destroying a
4004 + * mutex object */
4005 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)(
4006 + CK_VOID_PTR pMutex /* pointer to mutex */
4007 +);
4008 +
4009 +
4010 +/* CK_LOCKMUTEX is an application callback for locking a mutex */
4011 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)(
4012 + CK_VOID_PTR pMutex /* pointer to mutex */
4013 +);
4014 +
4015 +
4016 +/* CK_UNLOCKMUTEX is an application callback for unlocking a
4017 + * mutex */
4018 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)(
4019 + CK_VOID_PTR pMutex /* pointer to mutex */
4020 +);
4021 +
4022 +
4023 +/* CK_C_INITIALIZE_ARGS provides the optional arguments to
4024 + * C_Initialize */
4025 +typedef struct CK_C_INITIALIZE_ARGS {
4026 + CK_CREATEMUTEX CreateMutex;
4027 + CK_DESTROYMUTEX DestroyMutex;
4028 + CK_LOCKMUTEX LockMutex;
4029 + CK_UNLOCKMUTEX UnlockMutex;
4030 + CK_FLAGS flags;
4031 + CK_VOID_PTR pReserved;
4032 +} CK_C_INITIALIZE_ARGS;
4033 +
4034 +/* flags: bit flags that provide capabilities of the slot
4035 + * Bit Flag Mask Meaning
4036 + */
4037 +#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001
4038 +#define CKF_OS_LOCKING_OK 0x00000002
4039 +
4040 +typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
4041 +
4042 +
4043 +/* additional flags for parameters to functions */
4044 +
4045 +/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
4046 +#define CKF_DONT_BLOCK 1
4047 +
4048 +/* CK_RSA_PKCS_OAEP_MGF_TYPE is new for v2.10.
4049 + * CK_RSA_PKCS_OAEP_MGF_TYPE is used to indicate the Message
4050 + * Generation Function (MGF) applied to a message block when
4051 + * formatting a message block for the PKCS #1 OAEP encryption
4052 + * scheme. */
4053 +typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE;
4054 +
4055 +typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR;
4056 +
4057 +/* The following MGFs are defined */
4058 +/* CKG_MGF1_SHA256, CKG_MGF1_SHA384, and CKG_MGF1_SHA512
4059 + * are new for v2.20 */
4060 +#define CKG_MGF1_SHA1 0x00000001
4061 +#define CKG_MGF1_SHA256 0x00000002
4062 +#define CKG_MGF1_SHA384 0x00000003
4063 +#define CKG_MGF1_SHA512 0x00000004
4064 +
4065 +/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is new for v2.10.
4066 + * CK_RSA_PKCS_OAEP_SOURCE_TYPE is used to indicate the source
4067 + * of the encoding parameter when formatting a message block
4068 + * for the PKCS #1 OAEP encryption scheme. */
4069 +typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE;
4070 +
4071 +typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR;
4072 +
4073 +/* The following encoding parameter sources are defined */
4074 +#define CKZ_DATA_SPECIFIED 0x00000001
4075 +
4076 +/* CK_RSA_PKCS_OAEP_PARAMS is new for v2.10.
4077 + * CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the
4078 + * CKM_RSA_PKCS_OAEP mechanism. */
4079 +typedef struct CK_RSA_PKCS_OAEP_PARAMS {
4080 + CK_MECHANISM_TYPE hashAlg;
4081 + CK_RSA_PKCS_MGF_TYPE mgf;
4082 + CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
4083 + CK_VOID_PTR pSourceData;
4084 + CK_ULONG ulSourceDataLen;
4085 +} CK_RSA_PKCS_OAEP_PARAMS;
4086 +
4087 +typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR;
4088 +
4089 +/* CK_RSA_PKCS_PSS_PARAMS is new for v2.11.
4090 + * CK_RSA_PKCS_PSS_PARAMS provides the parameters to the
4091 + * CKM_RSA_PKCS_PSS mechanism(s). */
4092 +typedef struct CK_RSA_PKCS_PSS_PARAMS {
4093 + CK_MECHANISM_TYPE hashAlg;
4094 + CK_RSA_PKCS_MGF_TYPE mgf;
4095 + CK_ULONG sLen;
4096 +} CK_RSA_PKCS_PSS_PARAMS;
4097 +
4098 +typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR;
4099 +
4100 +/* CK_EC_KDF_TYPE is new for v2.11. */
4101 +typedef CK_ULONG CK_EC_KDF_TYPE;
4102 +
4103 +/* The following EC Key Derivation Functions are defined */
4104 +#define CKD_NULL 0x00000001
4105 +#define CKD_SHA1_KDF 0x00000002
4106 +
4107 +/* CK_ECDH1_DERIVE_PARAMS is new for v2.11.
4108 + * CK_ECDH1_DERIVE_PARAMS provides the parameters to the
4109 + * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms,
4110 + * where each party contributes one key pair.
4111 + */
4112 +typedef struct CK_ECDH1_DERIVE_PARAMS {
4113 + CK_EC_KDF_TYPE kdf;
4114 + CK_ULONG ulSharedDataLen;
4115 + CK_BYTE_PTR pSharedData;
4116 + CK_ULONG ulPublicDataLen;
4117 + CK_BYTE_PTR pPublicData;
4118 +} CK_ECDH1_DERIVE_PARAMS;
4119 +
4120 +typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR;
4121 +
4122 +
4123 +/* CK_ECDH2_DERIVE_PARAMS is new for v2.11.
4124 + * CK_ECDH2_DERIVE_PARAMS provides the parameters to the
4125 + * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs. */
4126 +typedef struct CK_ECDH2_DERIVE_PARAMS {
4127 + CK_EC_KDF_TYPE kdf;
4128 + CK_ULONG ulSharedDataLen;
4129 + CK_BYTE_PTR pSharedData;
4130 + CK_ULONG ulPublicDataLen;
4131 + CK_BYTE_PTR pPublicData;
4132 + CK_ULONG ulPrivateDataLen;
4133 + CK_OBJECT_HANDLE hPrivateData;
4134 + CK_ULONG ulPublicDataLen2;
4135 + CK_BYTE_PTR pPublicData2;
4136 +} CK_ECDH2_DERIVE_PARAMS;
4137 +
4138 +typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR;
4139 +
4140 +typedef struct CK_ECMQV_DERIVE_PARAMS {
4141 + CK_EC_KDF_TYPE kdf;
4142 + CK_ULONG ulSharedDataLen;
4143 + CK_BYTE_PTR pSharedData;
4144 + CK_ULONG ulPublicDataLen;
4145 + CK_BYTE_PTR pPublicData;
4146 + CK_ULONG ulPrivateDataLen;
4147 + CK_OBJECT_HANDLE hPrivateData;
4148 + CK_ULONG ulPublicDataLen2;
4149 + CK_BYTE_PTR pPublicData2;
4150 + CK_OBJECT_HANDLE publicKey;
4151 +} CK_ECMQV_DERIVE_PARAMS;
4152 +
4153 +typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR;
4154 +
4155 +/* Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the
4156 + * CKM_X9_42_DH_PARAMETER_GEN mechanisms (new for PKCS #11 v2.11) */
4157 +typedef CK_ULONG CK_X9_42_DH_KDF_TYPE;
4158 +typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR;
4159 +
4160 +/* The following X9.42 DH key derivation functions are defined
4161 + (besides CKD_NULL already defined : */
4162 +#define CKD_SHA1_KDF_ASN1 0x00000003
4163 +#define CKD_SHA1_KDF_CONCATENATE 0x00000004
4164 +
4165 +/* CK_X9_42_DH1_DERIVE_PARAMS is new for v2.11.
4166 + * CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the
4167 + * CKM_X9_42_DH_DERIVE key derivation mechanism, where each party
4168 + * contributes one key pair */
4169 +typedef struct CK_X9_42_DH1_DERIVE_PARAMS {
4170 + CK_X9_42_DH_KDF_TYPE kdf;
4171 + CK_ULONG ulOtherInfoLen;
4172 + CK_BYTE_PTR pOtherInfo;
4173 + CK_ULONG ulPublicDataLen;
4174 + CK_BYTE_PTR pPublicData;
4175 +} CK_X9_42_DH1_DERIVE_PARAMS;
4176 +
4177 +typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR;
4178 +
4179 +/* CK_X9_42_DH2_DERIVE_PARAMS is new for v2.11.
4180 + * CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the
4181 + * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation
4182 + * mechanisms, where each party contributes two key pairs */
4183 +typedef struct CK_X9_42_DH2_DERIVE_PARAMS {
4184 + CK_X9_42_DH_KDF_TYPE kdf;
4185 + CK_ULONG ulOtherInfoLen;
4186 + CK_BYTE_PTR pOtherInfo;
4187 + CK_ULONG ulPublicDataLen;
4188 + CK_BYTE_PTR pPublicData;
4189 + CK_ULONG ulPrivateDataLen;
4190 + CK_OBJECT_HANDLE hPrivateData;
4191 + CK_ULONG ulPublicDataLen2;
4192 + CK_BYTE_PTR pPublicData2;
4193 +} CK_X9_42_DH2_DERIVE_PARAMS;
4194 +
4195 +typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR;
4196 +
4197 +typedef struct CK_X9_42_MQV_DERIVE_PARAMS {
4198 + CK_X9_42_DH_KDF_TYPE kdf;
4199 + CK_ULONG ulOtherInfoLen;
4200 + CK_BYTE_PTR pOtherInfo;
4201 + CK_ULONG ulPublicDataLen;
4202 + CK_BYTE_PTR pPublicData;
4203 + CK_ULONG ulPrivateDataLen;
4204 + CK_OBJECT_HANDLE hPrivateData;
4205 + CK_ULONG ulPublicDataLen2;
4206 + CK_BYTE_PTR pPublicData2;
4207 + CK_OBJECT_HANDLE publicKey;
4208 +} CK_X9_42_MQV_DERIVE_PARAMS;
4209 +
4210 +typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR;
4211 +
4212 +/* CK_KEA_DERIVE_PARAMS provides the parameters to the
4213 + * CKM_KEA_DERIVE mechanism */
4214 +/* CK_KEA_DERIVE_PARAMS is new for v2.0 */
4215 +typedef struct CK_KEA_DERIVE_PARAMS {
4216 + CK_BBOOL isSender;
4217 + CK_ULONG ulRandomLen;
4218 + CK_BYTE_PTR pRandomA;
4219 + CK_BYTE_PTR pRandomB;
4220 + CK_ULONG ulPublicDataLen;
4221 + CK_BYTE_PTR pPublicData;
4222 +} CK_KEA_DERIVE_PARAMS;
4223 +
4224 +typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR;
4225 +
4226 +
4227 +/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and
4228 + * CKM_RC2_MAC mechanisms. An instance of CK_RC2_PARAMS just
4229 + * holds the effective keysize */
4230 +typedef CK_ULONG CK_RC2_PARAMS;
4231 +
4232 +typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR;
4233 +
4234 +
4235 +/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC
4236 + * mechanism */
4237 +typedef struct CK_RC2_CBC_PARAMS {
4238 + /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for
4239 + * v2.0 */
4240 + CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
4241 +
4242 + CK_BYTE iv[8]; /* IV for CBC mode */
4243 +} CK_RC2_CBC_PARAMS;
4244 +
4245 +typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR;
4246 +
4247 +
4248 +/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the
4249 + * CKM_RC2_MAC_GENERAL mechanism */
4250 +/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */
4251 +typedef struct CK_RC2_MAC_GENERAL_PARAMS {
4252 + CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
4253 + CK_ULONG ulMacLength; /* Length of MAC in bytes */
4254 +} CK_RC2_MAC_GENERAL_PARAMS;
4255 +
4256 +typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \
4257 + CK_RC2_MAC_GENERAL_PARAMS_PTR;
4258 +
4259 +
4260 +/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and
4261 + * CKM_RC5_MAC mechanisms */
4262 +/* CK_RC5_PARAMS is new for v2.0 */
4263 +typedef struct CK_RC5_PARAMS {
4264 + CK_ULONG ulWordsize; /* wordsize in bits */
4265 + CK_ULONG ulRounds; /* number of rounds */
4266 +} CK_RC5_PARAMS;
4267 +
4268 +typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR;
4269 +
4270 +
4271 +/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC
4272 + * mechanism */
4273 +/* CK_RC5_CBC_PARAMS is new for v2.0 */
4274 +typedef struct CK_RC5_CBC_PARAMS {
4275 + CK_ULONG ulWordsize; /* wordsize in bits */
4276 + CK_ULONG ulRounds; /* number of rounds */
4277 + CK_BYTE_PTR pIv; /* pointer to IV */
4278 + CK_ULONG ulIvLen; /* length of IV in bytes */
4279 +} CK_RC5_CBC_PARAMS;
4280 +
4281 +typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR;
4282 +
4283 +
4284 +/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the
4285 + * CKM_RC5_MAC_GENERAL mechanism */
4286 +/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */
4287 +typedef struct CK_RC5_MAC_GENERAL_PARAMS {
4288 + CK_ULONG ulWordsize; /* wordsize in bits */
4289 + CK_ULONG ulRounds; /* number of rounds */
4290 + CK_ULONG ulMacLength; /* Length of MAC in bytes */
4291 +} CK_RC5_MAC_GENERAL_PARAMS;
4292 +
4293 +typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \
4294 + CK_RC5_MAC_GENERAL_PARAMS_PTR;
4295 +
4296 +
4297 +/* CK_MAC_GENERAL_PARAMS provides the parameters to most block
4298 + * ciphers' MAC_GENERAL mechanisms. Its value is the length of
4299 + * the MAC */
4300 +/* CK_MAC_GENERAL_PARAMS is new for v2.0 */
4301 +typedef CK_ULONG CK_MAC_GENERAL_PARAMS;
4302 +
4303 +typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
4304 +
4305 +/* CK_DES/AES_ECB/CBC_ENCRYPT_DATA_PARAMS are new for v2.20 */
4306 +typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS {
4307 + CK_BYTE iv[8];
4308 + CK_BYTE_PTR pData;
4309 + CK_ULONG length;
4310 +} CK_DES_CBC_ENCRYPT_DATA_PARAMS;
4311 +
4312 +typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR;
4313 +
4314 +typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS {
4315 + CK_BYTE iv[16];
4316 + CK_BYTE_PTR pData;
4317 + CK_ULONG length;
4318 +} CK_AES_CBC_ENCRYPT_DATA_PARAMS;
4319 +
4320 +typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR;
4321 +
4322 +/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
4323 + * CKM_SKIPJACK_PRIVATE_WRAP mechanism */
4324 +/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */
4325 +typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS {
4326 + CK_ULONG ulPasswordLen;
4327 + CK_BYTE_PTR pPassword;
4328 + CK_ULONG ulPublicDataLen;
4329 + CK_BYTE_PTR pPublicData;
4330 + CK_ULONG ulPAndGLen;
4331 + CK_ULONG ulQLen;
4332 + CK_ULONG ulRandomLen;
4333 + CK_BYTE_PTR pRandomA;
4334 + CK_BYTE_PTR pPrimeP;
4335 + CK_BYTE_PTR pBaseG;
4336 + CK_BYTE_PTR pSubprimeQ;
4337 +} CK_SKIPJACK_PRIVATE_WRAP_PARAMS;
4338 +
4339 +typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \
4340 + CK_SKIPJACK_PRIVATE_WRAP_PTR;
4341 +
4342 +
4343 +/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the
4344 + * CKM_SKIPJACK_RELAYX mechanism */
4345 +/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */
4346 +typedef struct CK_SKIPJACK_RELAYX_PARAMS {
4347 + CK_ULONG ulOldWrappedXLen;
4348 + CK_BYTE_PTR pOldWrappedX;
4349 + CK_ULONG ulOldPasswordLen;
4350 + CK_BYTE_PTR pOldPassword;
4351 + CK_ULONG ulOldPublicDataLen;
4352 + CK_BYTE_PTR pOldPublicData;
4353 + CK_ULONG ulOldRandomLen;
4354 + CK_BYTE_PTR pOldRandomA;
4355 + CK_ULONG ulNewPasswordLen;
4356 + CK_BYTE_PTR pNewPassword;
4357 + CK_ULONG ulNewPublicDataLen;
4358 + CK_BYTE_PTR pNewPublicData;
4359 + CK_ULONG ulNewRandomLen;
4360 + CK_BYTE_PTR pNewRandomA;
4361 +} CK_SKIPJACK_RELAYX_PARAMS;
4362 +
4363 +typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \
4364 + CK_SKIPJACK_RELAYX_PARAMS_PTR;
4365 +
4366 +
4367 +typedef struct CK_PBE_PARAMS {
4368 + CK_BYTE_PTR pInitVector;
4369 + CK_UTF8CHAR_PTR pPassword;
4370 + CK_ULONG ulPasswordLen;
4371 + CK_BYTE_PTR pSalt;
4372 + CK_ULONG ulSaltLen;
4373 + CK_ULONG ulIteration;
4374 +} CK_PBE_PARAMS;
4375 +
4376 +typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
4377 +
4378 +
4379 +/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the
4380 + * CKM_KEY_WRAP_SET_OAEP mechanism */
4381 +/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */
4382 +typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS {
4383 + CK_BYTE bBC; /* block contents byte */
4384 + CK_BYTE_PTR pX; /* extra data */
4385 + CK_ULONG ulXLen; /* length of extra data in bytes */
4386 +} CK_KEY_WRAP_SET_OAEP_PARAMS;
4387 +
4388 +typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \
4389 + CK_KEY_WRAP_SET_OAEP_PARAMS_PTR;
4390 +
4391 +
4392 +typedef struct CK_SSL3_RANDOM_DATA {
4393 + CK_BYTE_PTR pClientRandom;
4394 + CK_ULONG ulClientRandomLen;
4395 + CK_BYTE_PTR pServerRandom;
4396 + CK_ULONG ulServerRandomLen;
4397 +} CK_SSL3_RANDOM_DATA;
4398 +
4399 +
4400 +typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
4401 + CK_SSL3_RANDOM_DATA RandomInfo;
4402 + CK_VERSION_PTR pVersion;
4403 +} CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
4404 +
4405 +typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \
4406 + CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR;
4407 +
4408 +
4409 +typedef struct CK_SSL3_KEY_MAT_OUT {
4410 + CK_OBJECT_HANDLE hClientMacSecret;
4411 + CK_OBJECT_HANDLE hServerMacSecret;
4412 + CK_OBJECT_HANDLE hClientKey;
4413 + CK_OBJECT_HANDLE hServerKey;
4414 + CK_BYTE_PTR pIVClient;
4415 + CK_BYTE_PTR pIVServer;
4416 +} CK_SSL3_KEY_MAT_OUT;
4417 +
4418 +typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR;
4419 +
4420 +
4421 +typedef struct CK_SSL3_KEY_MAT_PARAMS {
4422 + CK_ULONG ulMacSizeInBits;
4423 + CK_ULONG ulKeySizeInBits;
4424 + CK_ULONG ulIVSizeInBits;
4425 + CK_BBOOL bIsExport;
4426 + CK_SSL3_RANDOM_DATA RandomInfo;
4427 + CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
4428 +} CK_SSL3_KEY_MAT_PARAMS;
4429 +
4430 +typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
4431 +
4432 +/* CK_TLS_PRF_PARAMS is new for version 2.20 */
4433 +typedef struct CK_TLS_PRF_PARAMS {
4434 + CK_BYTE_PTR pSeed;
4435 + CK_ULONG ulSeedLen;
4436 + CK_BYTE_PTR pLabel;
4437 + CK_ULONG ulLabelLen;
4438 + CK_BYTE_PTR pOutput;
4439 + CK_ULONG_PTR pulOutputLen;
4440 +} CK_TLS_PRF_PARAMS;
4441 +
4442 +typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR;
4443 +
4444 +/* WTLS is new for version 2.20 */
4445 +typedef struct CK_WTLS_RANDOM_DATA {
4446 + CK_BYTE_PTR pClientRandom;
4447 + CK_ULONG ulClientRandomLen;
4448 + CK_BYTE_PTR pServerRandom;
4449 + CK_ULONG ulServerRandomLen;
4450 +} CK_WTLS_RANDOM_DATA;
4451 +
4452 +typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR;
4453 +
4454 +typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS {
4455 + CK_MECHANISM_TYPE DigestMechanism;
4456 + CK_WTLS_RANDOM_DATA RandomInfo;
4457 + CK_BYTE_PTR pVersion;
4458 +} CK_WTLS_MASTER_KEY_DERIVE_PARAMS;
4459 +
4460 +typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \
4461 + CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR;
4462 +
4463 +typedef struct CK_WTLS_PRF_PARAMS {
4464 + CK_MECHANISM_TYPE DigestMechanism;
4465 + CK_BYTE_PTR pSeed;
4466 + CK_ULONG ulSeedLen;
4467 + CK_BYTE_PTR pLabel;
4468 + CK_ULONG ulLabelLen;
4469 + CK_BYTE_PTR pOutput;
4470 + CK_ULONG_PTR pulOutputLen;
4471 +} CK_WTLS_PRF_PARAMS;
4472 +
4473 +typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR;
4474 +
4475 +typedef struct CK_WTLS_KEY_MAT_OUT {
4476 + CK_OBJECT_HANDLE hMacSecret;
4477 + CK_OBJECT_HANDLE hKey;
4478 + CK_BYTE_PTR pIV;
4479 +} CK_WTLS_KEY_MAT_OUT;
4480 +
4481 +typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR;
4482 +
4483 +typedef struct CK_WTLS_KEY_MAT_PARAMS {
4484 + CK_MECHANISM_TYPE DigestMechanism;
4485 + CK_ULONG ulMacSizeInBits;
4486 + CK_ULONG ulKeySizeInBits;
4487 + CK_ULONG ulIVSizeInBits;
4488 + CK_ULONG ulSequenceNumber;
4489 + CK_BBOOL bIsExport;
4490 + CK_WTLS_RANDOM_DATA RandomInfo;
4491 + CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
4492 +} CK_WTLS_KEY_MAT_PARAMS;
4493 +
4494 +typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR;
4495 +
4496 +/* CMS is new for version 2.20 */
4497 +typedef struct CK_CMS_SIG_PARAMS {
4498 + CK_OBJECT_HANDLE certificateHandle;
4499 + CK_MECHANISM_PTR pSigningMechanism;
4500 + CK_MECHANISM_PTR pDigestMechanism;
4501 + CK_UTF8CHAR_PTR pContentType;
4502 + CK_BYTE_PTR pRequestedAttributes;
4503 + CK_ULONG ulRequestedAttributesLen;
4504 + CK_BYTE_PTR pRequiredAttributes;
4505 + CK_ULONG ulRequiredAttributesLen;
4506 +} CK_CMS_SIG_PARAMS;
4507 +
4508 +typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR;
4509 +
4510 +typedef struct CK_KEY_DERIVATION_STRING_DATA {
4511 + CK_BYTE_PTR pData;
4512 + CK_ULONG ulLen;
4513 +} CK_KEY_DERIVATION_STRING_DATA;
4514 +
4515 +typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \
4516 + CK_KEY_DERIVATION_STRING_DATA_PTR;
4517 +
4518 +
4519 +/* The CK_EXTRACT_PARAMS is used for the
4520 + * CKM_EXTRACT_KEY_FROM_KEY mechanism. It specifies which bit
4521 + * of the base key should be used as the first bit of the
4522 + * derived key */
4523 +/* CK_EXTRACT_PARAMS is new for v2.0 */
4524 +typedef CK_ULONG CK_EXTRACT_PARAMS;
4525 +
4526 +typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
4527 +
4528 +/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is new for v2.10.
4529 + * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to
4530 + * indicate the Pseudo-Random Function (PRF) used to generate
4531 + * key bits using PKCS #5 PBKDF2. */
4532 +typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE;
4533 +
4534 +typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR;
4535 +
4536 +/* The following PRFs are defined in PKCS #5 v2.0. */
4537 +#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001
4538 +
4539 +
4540 +/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is new for v2.10.
4541 + * CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the
4542 + * source of the salt value when deriving a key using PKCS #5
4543 + * PBKDF2. */
4544 +typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE;
4545 +
4546 +typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR;
4547 +
4548 +/* The following salt value sources are defined in PKCS #5 v2.0. */
4549 +#define CKZ_SALT_SPECIFIED 0x00000001
4550 +
4551 +/* CK_PKCS5_PBKD2_PARAMS is new for v2.10.
4552 + * CK_PKCS5_PBKD2_PARAMS is a structure that provides the
4553 + * parameters to the CKM_PKCS5_PBKD2 mechanism. */
4554 +typedef struct CK_PKCS5_PBKD2_PARAMS {
4555 + CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource;
4556 + CK_VOID_PTR pSaltSourceData;
4557 + CK_ULONG ulSaltSourceDataLen;
4558 + CK_ULONG iterations;
4559 + CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
4560 + CK_VOID_PTR pPrfData;
4561 + CK_ULONG ulPrfDataLen;
4562 + CK_UTF8CHAR_PTR pPassword;
4563 + CK_ULONG_PTR ulPasswordLen;
4564 +} CK_PKCS5_PBKD2_PARAMS;
4565 +
4566 +typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
4567 +
4568 +#endif
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
4572 @@ -0,0 +1,11337 @@
4573 +/*
4574 + * Copyright (c) 2005-2006 Alon Bar-Lev <alon.barlev@gmail.com>
4575 + * All rights reserved.
4576 + *
4577 + * This software is available to you under a choice of one of two
4578 + * licenses. You may choose to be licensed under the terms of the GNU
4579 + * General Public License (GPL) Version 2, or the OpenIB.org BSD license.
4580 + *
4581 + * GNU General Public License (GPL) Version 2
4582 + * ===========================================
4583 + * This program is free software; you can redistribute it and/or modify
4584 + * it under the terms of the GNU General Public License version 2
4585 + * as published by the Free Software Foundation.
4586 + *
4587 + * This program is distributed in the hope that it will be useful,
4588 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4589 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4590 + * GNU General Public License for more details.
4591 + *
4592 + * You should have received a copy of the GNU General Public License
4593 + * along with this program (see the file COPYING[.GPL2] included with this
4594 + * distribution); if not, write to the Free Software Foundation, Inc.,
4595 + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4596 + *
4597 + * OpenIB.org BSD license
4598 + * =======================
4599 + * Redistribution and use in source and binary forms, with or without modifi-
4600 + * cation, are permitted provided that the following conditions are met:
4601 + *
4602 + * o Redistributions of source code must retain the above copyright notice,
4603 + * this list of conditions and the following disclaimer.
4604 + *
4605 + * o Redistributions in binary form must reproduce the above copyright no-
4606 + * tice, this list of conditions and the following disclaimer in the do-
4607 + * cumentation and/or other materials provided with the distribution.
4608 + *
4609 + * o The names of the contributors may not be used to endorse or promote
4610 + * products derived from this software without specific prior written
4611 + * permission.
4612 + *
4613 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4614 + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
4615 + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
4616 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LI-
4617 + * ABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUEN-
4618 + * TIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4619 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEV-
4620 + * ER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABI-
4621 + * LITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
4622 + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4623 + */
4624 +
4625 +/*
4626 + * The routines in this file deal with providing private key cryptography
4627 + * using RSA Security Inc. PKCS #11 Cryptographic Token Interface (Cryptoki).
4628 + *
4629 + */
4630 +
4631 +/*
4632 + * Changelog
4633 + *
4634 + * 2006.09.24
4635 + * - (alonbl) Fix invalid certificate max size handling (Zeljko Vrba).
4636 + * - (alonbl) Added object serialization.
4637 + * - (alonbl) Added user data to hooks.
4638 + * - (alonbl) Added a force login method.
4639 + * - (alonbl) Added support for gnutls in addition to openssl.
4640 + * - (alonbl) Fixup threading lock issues.
4641 + * - (alonbl) Added support for duplicate serial tokens, based on label.
4642 + * - (alonbl) Added workaround for OpenSC cards, OpenSC bug#108, thanks to Kaupo Arulo.
4643 + * - (alonbl) Added a methods to lock session between two sign/decrypt operations.
4644 + * - (alonbl) Modified openssl interface.
4645 + * - (alonbl) Release 01.02.
4646 + *
4647 + * 2006.06.26
4648 + * - (alonbl) Fix handling mutiple providers.
4649 + * - (alonbl) Release 01.01.
4650 + *
4651 + * 2006.05.14
4652 + * - (alonbl) First stable release.
4653 + * - (alonbl) Release 01.00.
4654 + *
4655 + */
4656 +
4657 +#include "pkcs11-helper-config.h"
4658 +
4659 +#if defined(ENABLE_PKCS11H_HELPER)
4660 +
4661 +#include "pkcs11-helper.h"
4662 +
4663 +/*===========================================
4664 + * Constants
4665 + */
4666 +
4667 +#if defined(USE_PKCS11H_OPENSSL)
4668 +
4669 +#if OPENSSL_VERSION_NUMBER < 0x00907000L && defined(CRYPTO_LOCK_ENGINE)
4670 +# define RSA_get_default_method RSA_get_default_openssl_method
4671 +#else
4672 +# ifdef HAVE_ENGINE_GET_DEFAULT_RSA
4673 +# include <openssl/engine.h>
4674 +# if OPENSSL_VERSION_NUMBER < 0x0090704fL
4675 +# define BROKEN_OPENSSL_ENGINE
4676 +# endif
4677 +# endif
4678 +#endif
4679 +
4680 +#if OPENSSL_VERSION_NUMBER < 0x00907000L
4681 +#if !defined(RSA_PKCS1_PADDING_SIZE)
4682 +#define RSA_PKCS1_PADDING_SIZE 11
4683 +#endif
4684 +#endif
4685 +
4686 +#endif
4687 +
4688 +#define PKCS11H_INVALID_SLOT_ID ((CK_SLOT_ID)-1)
4689 +#define PKCS11H_INVALID_SESSION_HANDLE ((CK_SESSION_HANDLE)-1)
4690 +#define PKCS11H_INVALID_OBJECT_HANDLE ((CK_OBJECT_HANDLE)-1)
4691 +
4692 +#define PKCS11H_DEFAULT_SLOTEVENT_POLL 5000
4693 +#define PKCS11H_DEFAULT_MAX_LOGIN_RETRY 3
4694 +#define PKCS11H_DEFAULT_PIN_CACHE_PERIOD PKCS11H_PIN_CACHE_INFINITE
4695 +
4696 +#define PKCS11H_SERIALIZE_INVALID_CHARS "\\/\"'%&#@!?$* <>{}[]()`|"
4697 +
4698 +enum _pkcs11h_private_op_e {
4699 + _pkcs11h_private_op_sign=0,
4700 + _pkcs11h_private_op_sign_recover,
4701 + _pkcs11h_private_op_decrypt
4702 +};
4703 +
4704 +/*===========================================
4705 + * Macros
4706 + */
4707 +
4708 +#define PKCS11H_MSG_LEVEL_TEST(flags) (((unsigned int)flags) <= s_pkcs11h_loglevel)
4709 +
4710 +#if defined(HAVE_CPP_VARARG_MACRO_ISO) && !defined(__LCLINT__)
4711 +# define PKCS11H_LOG(flags, ...) do { if (PKCS11H_MSG_LEVEL_TEST(flags)) _pkcs11h_log((flags), __VA_ARGS__); } while (FALSE)
4712 +# ifdef ENABLE_PKCS11H_DEBUG
4713 +# define PKCS11H_DEBUG(flags, ...) do { if (PKCS11H_MSG_LEVEL_TEST(flags)) _pkcs11h_log((flags), __VA_ARGS__); } while (FALSE)
4714 +# else
4715 +# define PKCS11H_DEBUG(flags, ...)
4716 +# endif
4717 +#elif defined(HAVE_CPP_VARARG_MACRO_GCC) && !defined(__LCLINT__)
4718 +# define PKCS11H_LOG(flags, args...) do { if (PKCS11H_MSG_LEVEL_TEST(flags)) _pkcs11h_log((flags), args); } while (FALSE)
4719 +# ifdef ENABLE_PKCS11H_DEBUG
4720 +# define PKCS11H_DEBUG(flags, args...) do { if (PKCS11H_MSG_LEVEL_TEST(flags)) _pkcs11h_log((flags), args); } while (FALSE)
4721 +# else
4722 +# define PKCS11H_DEBUG(flags, args...)
4723 +# endif
4724 +#else
4725 +# define PKCS11H_LOG _pkcs11h_log
4726 +# define PKCS11H_DEBUG _pkcs11h_log
4727 +#endif
4728 +
4729 +/*===========================================
4730 + * Types
4731 + */
4732 +
4733 +struct pkcs11h_provider_s;
4734 +struct pkcs11h_session_s;
4735 +struct pkcs11h_data_s;
4736 +typedef struct pkcs11h_provider_s *pkcs11h_provider_t;
4737 +typedef struct pkcs11h_session_s *pkcs11h_session_t;
4738 +typedef struct pkcs11h_data_s *pkcs11h_data_t;
4739 +
4740 +#if defined(USE_PKCS11H_OPENSSL)
4741 +
4742 +#if OPENSSL_VERSION_NUMBER < 0x00908000L
4743 +typedef unsigned char *pkcs11_openssl_d2i_t;
4744 +#else
4745 +typedef const unsigned char *pkcs11_openssl_d2i_t;
4746 +#endif
4747 +
4748 +#endif
4749 +
4750 +#if defined(ENABLE_PKCS11H_THREADING)
4751 +
4752 +#define PKCS11H_COND_INFINITE 0xffffffff
4753 +
4754 +#if defined(WIN32)
4755 +#define PKCS11H_THREAD_NULL NULL
4756 +typedef HANDLE pkcs11h_cond_t;
4757 +typedef HANDLE pkcs11h_mutex_t;
4758 +typedef HANDLE pkcs11h_thread_t;
4759 +#else
4760 +#define PKCS11H_THREAD_NULL 0l
4761 +typedef pthread_mutex_t pkcs11h_mutex_t;
4762 +typedef pthread_t pkcs11h_thread_t;
4763 +
4764 +typedef struct {
4765 + pthread_cond_t cond;
4766 + pthread_mutex_t mut;
4767 +} pkcs11h_cond_t;
4768 +
4769 +typedef struct __pkcs11h_threading_mutex_entry_s {
4770 + struct __pkcs11h_threading_mutex_entry_s *next;
4771 + pkcs11h_mutex_t *p_mutex;
4772 + PKCS11H_BOOL locked;
4773 +} *__pkcs11h_threading_mutex_entry_t;
4774 +#endif
4775 +
4776 +typedef void * (*pkcs11h_thread_start_t)(void *);
4777 +
4778 +typedef struct {
4779 + pkcs11h_thread_start_t start;
4780 + void *data;
4781 +} __pkcs11h_thread_data_t;
4782 +
4783 +#endif /* ENABLE_PKCS11H_THREADING */
4784 +
4785 +struct pkcs11h_provider_s {
4786 + pkcs11h_provider_t next;
4787 +
4788 + PKCS11H_BOOL enabled;
4789 + char reference[1024];
4790 + char manufacturerID[sizeof (((CK_TOKEN_INFO *)NULL)->manufacturerID)+1];
4791 +
4792 +#if defined(WIN32)
4793 + HANDLE handle;
4794 +#else
4795 + void *handle;
4796 +#endif
4797 +
4798 + CK_FUNCTION_LIST_PTR f;
4799 + PKCS11H_BOOL should_finalize;
4800 + PKCS11H_BOOL allow_protected_auth;
4801 + PKCS11H_BOOL cert_is_private;
4802 + unsigned mask_sign_mode;
4803 + int slot_event_method;
4804 + int slot_poll_interval;
4805 +
4806 +#if defined(ENABLE_PKCS11H_SLOTEVENT)
4807 + pkcs11h_thread_t slotevent_thread;
4808 +#endif
4809 +};
4810 +
4811 +struct pkcs11h_session_s {
4812 + pkcs11h_session_t next;
4813 +
4814 + int reference_count;
4815 + PKCS11H_BOOL valid;
4816 +
4817 + pkcs11h_provider_t provider;
4818 +
4819 + pkcs11h_token_id_t token_id;
4820 +
4821 + CK_SESSION_HANDLE session_handle;
4822 +
4823 + PKCS11H_BOOL allow_protected_auth_supported;
4824 + int pin_cache_period;
4825 + time_t pin_expire_time;
4826 +
4827 +#if defined(ENABLE_PKCS11H_ENUM)
4828 +#if defined(ENABLE_PKCS11H_CERTIFICATE)
4829 + pkcs11h_certificate_id_list_t cached_certs;
4830 + PKCS11H_BOOL touch;
4831 +#endif
4832 +#endif
4833 +
4834 +#if defined(ENABLE_PKCS11H_THREADING)
4835 + pkcs11h_mutex_t mutex;
4836 +#endif
4837 +};
4838 +
4839 +#if defined (ENABLE_PKCS11H_CERTIFICATE)
4840 +
4841 +struct pkcs11h_certificate_s {
4842 +
4843 + pkcs11h_certificate_id_t id;
4844 + int pin_cache_period;
4845 + PKCS11H_BOOL pin_cache_populated_to_session;
4846 +
4847 + unsigned mask_sign_mode;
4848 +
4849 + pkcs11h_session_t session;
4850 + CK_OBJECT_HANDLE key_handle;
4851 +
4852 + PKCS11H_BOOL operation_active;
4853 +
4854 +#if defined(ENABLE_PKCS11H_THREADING)
4855 + pkcs11h_mutex_t mutex;
4856 +#endif
4857 +
4858 + unsigned mask_prompt;
4859 + void * user_data;
4860 +};
4861 +
4862 +#endif /* ENABLE_PKCS11H_CERTIFICATE */
4863 +
4864 +struct pkcs11h_data_s {
4865 + PKCS11H_BOOL initialized;
4866 + int pin_cache_period;
4867 +
4868 + pkcs11h_provider_t providers;
4869 + pkcs11h_session_t sessions;
4870 +
4871 + struct {
4872 + void * log_data;
4873 + void * slotevent_data;
4874 + void * token_prompt_data;
4875 + void * pin_prompt_data;
4876 + pkcs11h_hook_log_t log;
4877 + pkcs11h_hook_slotevent_t slotevent;
4878 + pkcs11h_hook_token_prompt_t token_prompt;
4879 + pkcs11h_hook_pin_prompt_t pin_prompt;
4880 + } hooks;
4881 +
4882 + PKCS11H_BOOL allow_protected_auth;
4883 + unsigned max_retries;
4884 +
4885 +#if defined(ENABLE_PKCS11H_THREADING)
4886 + struct {
4887 + pkcs11h_mutex_t global;
4888 + pkcs11h_mutex_t session;
4889 + pkcs11h_mutex_t cache;
4890 + } mutexes;
4891 +#endif
4892 +
4893 +#if defined(ENABLE_PKCS11H_SLOTEVENT)
4894 + struct {
4895 + PKCS11H_BOOL initialized;
4896 + PKCS11H_BOOL should_terminate;
4897 + PKCS11H_BOOL skip_event;
4898 + pkcs11h_cond_t cond_event;
4899 + pkcs11h_thread_t thread;
4900 + } slotevent;
4901 +#endif
4902 +};
4903 +
4904 +#if defined(ENABLE_PKCS11H_OPENSSL)
4905 +struct pkcs11h_openssl_session_s {
4906 + int reference_count;
4907 + PKCS11H_BOOL initialized;
4908 + X509 *x509;
4909 + RSA_METHOD smart_rsa;
4910 + int (*orig_finish)(RSA *rsa);
4911 + pkcs11h_certificate_t certificate;
4912 + pkcs11h_hook_openssl_cleanup_t cleanup_hook;
4913 +};
4914 +#endif
4915 +
4916 +/*======================================================================*
4917 + * MEMORY INTERFACE
4918 + *======================================================================*/
4919 +
4920 +static
4921 +CK_RV
4922 +_pkcs11h_mem_malloc (
4923 + OUT const void * * const p,
4924 + IN const size_t s
4925 +);
4926 +static
4927 +CK_RV
4928 +_pkcs11h_mem_free (
4929 + IN const void * * const p
4930 +);
4931 +static
4932 +CK_RV
4933 +_pkcs11h_mem_strdup (
4934 + OUT const char * * const dest,
4935 + IN const char * const src
4936 +);
4937 +static
4938 +CK_RV
4939 +_pkcs11h_mem_duplicate (
4940 + OUT const void * * const dest,
4941 + OUT size_t * const dest_size,
4942 + IN const void * const src,
4943 + IN const size_t mem_size
4944 +);
4945 +
4946 +#if defined(ENABLE_PKCS11H_THREADING)
4947 +/*======================================================================*
4948 + * THREADING INTERFACE
4949 + *======================================================================*/
4950 +
4951 +static
4952 +void
4953 +_pkcs11h_threading_sleep (
4954 + IN const unsigned milli
4955 +);
4956 +static
4957 +CK_RV
4958 +_pkcs11h_threading_mutexInit (
4959 + OUT pkcs11h_mutex_t * const mutex
4960 +);
4961 +static
4962 +CK_RV
4963 +_pkcs11h_threading_mutexLock (
4964 + IN OUT pkcs11h_mutex_t *const mutex
4965 +);
4966 +static
4967 +CK_RV
4968 +_pkcs11h_threading_mutexRelease (
4969 + IN OUT pkcs11h_mutex_t *const mutex
4970 +);
4971 +static
4972 +CK_RV
4973 +_pkcs11h_threading_mutexFree (
4974 + IN OUT pkcs11h_mutex_t *const mutex
4975 +);
4976 +#if !defined(WIN32)
4977 +static
4978 +void
4979 +__pkcs1h_threading_mutexLockAll ();
4980 +static
4981 +void
4982 +__pkcs1h_threading_mutexReleaseAll ();
4983 +#endif
4984 +static
4985 +CK_RV
4986 +_pkcs11h_threading_condSignal (
4987 + IN OUT pkcs11h_cond_t *const cond
4988 +);
4989 +static
4990 +CK_RV
4991 +_pkcs11h_threading_condInit (
4992 + OUT pkcs11h_cond_t * const cond
4993 +);
4994 +static
4995 +CK_RV
4996 +_pkcs11h_threading_condWait (
4997 + IN OUT pkcs11h_cond_t *const cond,
4998 + IN const unsigned milli
4999 +);
5000 +static
5001 +CK_RV
5002 +_pkcs11h_threading_condFree (
5003 + IN OUT pkcs11h_cond_t *const cond
5004 +);
5005 +static
5006 +CK_RV
5007 +_pkcs11h_threading_threadStart (
5008 + OUT pkcs11h_thread_t * const thread,
5009 + IN pkcs11h_thread_start_t const start,
5010 + IN void * data
5011 +);
5012 +static
5013 +CK_RV
5014 +_pkcs11h_threading_threadJoin (
5015 + IN pkcs11h_thread_t * const thread
5016 +);
5017 +#endif /* ENABLE_PKCS11H_THREADING */
5018 +
5019 +/*======================================================================*
5020 + * COMMON INTERNAL INTERFACE
5021 + *======================================================================*/
5022 +
5023 +static
5024 +void
5025 +_pkcs11h_util_fixupFixedString (
5026 + OUT char * const target, /* MUST BE >= length+1 */
5027 + IN const char * const source,
5028 + IN const size_t length /* FIXED STRING LENGTH */
5029 +);
5030 +static
5031 +CK_RV
5032 +_pkcs11h_util_hexToBinary (
5033 + OUT unsigned char * const target,
5034 + IN const char * const source,
5035 + IN OUT size_t * const p_target_size
5036 +);
5037 +static
5038 +CK_RV
5039 +_pkcs11h_util_binaryToHex (
5040 + OUT char * const target,
5041 + IN const size_t target_size,
5042 + IN const unsigned char * const source,
5043 + IN const size_t source_size
5044 +);
5045 +CK_RV
5046 +_pkcs11h_util_escapeString (
5047 + IN OUT char * const target,
5048 + IN const char * const source,
5049 + IN size_t * const max,
5050 + IN const char * const invalid_chars
5051 +);
5052 +static
5053 +CK_RV
5054 +_pkcs11h_util_unescapeString (
5055 + IN OUT char * const target,
5056 + IN const char * const source,
5057 + IN size_t * const max
5058 +);
5059 +static
5060 +void
5061 +_pkcs11h_log (
5062 + IN const unsigned flags,
5063 + IN const char * const format,
5064 + IN ...
5065 +)
5066 +#ifdef __GNUC__
5067 + __attribute__ ((format (printf, 2, 3)))
5068 +#endif
5069 + ;
5070 +
5071 +static
5072 +CK_RV
5073 +_pkcs11h_session_getSlotList (
5074 + IN const pkcs11h_provider_t provider,
5075 + IN const CK_BBOOL token_present,
5076 + OUT CK_SLOT_ID_PTR * const pSlotList,
5077 + OUT CK_ULONG_PTR pulCount
5078 +);
5079 +static
5080 +CK_RV
5081 +_pkcs11h_session_getObjectAttributes (
5082 + IN const pkcs11h_session_t session,
5083 + IN const CK_OBJECT_HANDLE object,
5084 + IN OUT const CK_ATTRIBUTE_PTR attrs,
5085 + IN const unsigned count
5086 +);
5087 +static
5088 +CK_RV
5089 +_pkcs11h_session_freeObjectAttributes (
5090 + IN OUT const CK_ATTRIBUTE_PTR attrs,
5091 + IN const unsigned count
5092 +);
5093 +static
5094 +CK_RV
5095 +_pkcs11h_session_findObjects (
5096 + IN const pkcs11h_session_t session,
5097 + IN const CK_ATTRIBUTE * const filter,
5098 + IN const CK_ULONG filter_attrs,
5099 + OUT CK_OBJECT_HANDLE **const p_objects,
5100 + OUT CK_ULONG *p_objects_found
5101 +);
5102 +static
5103 +CK_RV
5104 +_pkcs11h_token_getTokenId (
5105 + IN const CK_TOKEN_INFO_PTR info,
5106 + OUT pkcs11h_token_id_t * const p_token_id
5107 +);
5108 +static
5109 +CK_RV
5110 +_pkcs11h_token_newTokenId (
5111 + OUT pkcs11h_token_id_t * const token_id
5112 +);
5113 +static
5114 +CK_RV
5115 +_pkcs11h_session_getSessionByTokenId (
5116 + IN const pkcs11h_token_id_t token_id,
5117 + OUT pkcs11h_session_t * const p_session
5118 +);
5119 +static
5120 +CK_RV
5121 +_pkcs11h_session_release (
5122 + IN const pkcs11h_session_t session
5123 +);
5124 +static
5125 +CK_RV
5126 +_pkcs11h_session_reset (
5127 + IN const pkcs11h_session_t session,
5128 + IN void * const user_data,
5129 + IN const unsigned mask_prompt,
5130 + OUT CK_SLOT_ID * const p_slot
5131 +);
5132 +static
5133 +CK_RV
5134 +_pkcs11h_session_getObjectById (
5135 + IN const pkcs11h_session_t session,
5136 + IN const CK_OBJECT_CLASS class,
5137 + IN const CK_BYTE_PTR id,
5138 + IN const size_t id_size,
5139 + OUT CK_OBJECT_HANDLE * const p_handle
5140 +);
5141 +static
5142 +CK_RV
5143 +_pkcs11h_session_validate (
5144 + IN const pkcs11h_session_t session
5145 +);
5146 +static
5147 +CK_RV
5148 +_pkcs11h_session_touch (
5149 + IN const pkcs11h_session_t session
5150 +);
5151 +static
5152 +CK_RV
5153 +_pkcs11h_session_login (
5154 + IN const pkcs11h_session_t session,
5155 + IN const PKCS11H_BOOL public_only,
5156 + IN const PKCS11H_BOOL readonly,
5157 + IN void * const user_data,
5158 + IN const unsigned mask_prompt
5159 +);
5160 +static
5161 +CK_RV
5162 +_pkcs11h_session_logout (
5163 + IN const pkcs11h_session_t session
5164 +);
5165 +
5166 +static
5167 +void
5168 +_pkcs11h_hooks_default_log (
5169 + IN void * const global_data,
5170 + IN const unsigned flags,
5171 + IN const char * const format,
5172 + IN va_list args
5173 +);
5174 +
5175 +static
5176 +PKCS11H_BOOL
5177 +_pkcs11h_hooks_default_token_prompt (
5178 + IN void * const global_data,
5179 + IN void * const user_data,
5180 + IN const pkcs11h_token_id_t token,
5181 + IN const unsigned retry
5182 +);
5183 +
5184 +static
5185 +PKCS11H_BOOL
5186 +_pkcs11h_hooks_default_pin_prompt (
5187 + IN void * const global_data,
5188 + IN void * const user_data,
5189 + IN const pkcs11h_token_id_t token,
5190 + IN const unsigned retry,
5191 + OUT char * const pin,
5192 + IN const size_t pin_max
5193 +);
5194 +
5195 +#if !defined(WIN32)
5196 +#if defined(ENABLE_PKCS11H_THREADING)
5197 +static
5198 +void
5199 +__pkcs11h_threading_atfork_prepare ();
5200 +static
5201 +void
5202 +__pkcs11h_threading_atfork_parent ();
5203 +static
5204 +void
5205 +__pkcs11h_threading_atfork_child ();
5206 +#endif
5207 +static
5208 +CK_RV
5209 +_pkcs11h_forkFixup ();
5210 +#endif
5211 +
5212 +#if defined(ENABLE_PKCS11H_CERTIFICATE)
5213 +/*======================================================================*
5214 + * CERTIFICATE INTERFACE
5215 + *======================================================================*/
5216 +
5217 +static
5218 +time_t
5219 +_pkcs11h_certificate_getExpiration (
5220 + IN const unsigned char * const certificate,
5221 + IN const size_t certificate_size
5222 +);
5223 +static
5224 +PKCS11H_BOOL
5225 +_pkcs11h_certificate_isBetterCertificate (
5226 + IN const unsigned char * const current,
5227 + IN const size_t current_size,
5228 + IN const unsigned char * const newone,
5229 + IN const size_t newone_size
5230 +);
5231 +static
5232 +CK_RV
5233 +_pkcs11h_certificate_newCertificateId (
5234 + OUT pkcs11h_certificate_id_t * const certificate_id
5235 +);
5236 +static
5237 +CK_RV
5238 +_pkcs11h_certificate_getDN (
5239 + IN const unsigned char * const blob,
5240 + IN const size_t blob_size,
5241 + OUT char * const dn,
5242 + IN const size_t dn_size
5243 +);
5244 +static
5245 +CK_RV
5246 +_pkcs11h_certificate_loadCertificate (
5247 + IN const pkcs11h_certificate_t certificate
5248 +);
5249 +static
5250 +CK_RV
5251 +_pkcs11h_certificate_updateCertificateIdDescription (
5252 + IN OUT pkcs11h_certificate_id_t certificate_id
5253 +);
5254 +static
5255 +CK_RV
5256 +_pkcs11h_certificate_getKeyAttributes (
5257 + IN const pkcs11h_certificate_t certificate
5258 +);
5259 +static
5260 +CK_RV
5261 +_pkcs11h_certificate_validateSession (
5262 + IN const pkcs11h_certificate_t certificate
5263 +);
5264 +static
5265 +CK_RV
5266 +_pkcs11h_certificate_resetSession (
5267 + IN const pkcs11h_certificate_t certificate,
5268 + IN const PKCS11H_BOOL public_only,
5269 + IN const PKCS11H_BOOL session_mutex_locked
5270 +);
5271 +static
5272 +CK_RV
5273 +_pkcs11h_certificate_doPrivateOperation (
5274 + IN const pkcs11h_certificate_t certificate,
5275 + IN const enum _pkcs11h_private_op_e op,
5276 + IN const CK_MECHANISM_TYPE mech_type,
5277 + IN const unsigned char * const source,
5278 + IN const size_t source_size,
5279 + OUT unsigned char * const target,
5280 + IN OUT size_t * const p_target_size
5281 +);
5282 +#endif /* ENABLE_PKCS11H_CERTIFICATE */
5283 +
5284 +#if defined(ENABLE_PKCS11H_LOCATE)
5285 +/*======================================================================*
5286 + * LOCATE INTERFACE
5287 + *======================================================================*/
5288 +
5289 +static
5290 +CK_RV
5291 +_pkcs11h_locate_getTokenIdBySlotId (
5292 + IN const char * const slot,
5293 + OUT pkcs11h_token_id_t * const p_token_id
5294 +);
5295 +static
5296 +CK_RV
5297 +_pkcs11h_locate_getTokenIdBySlotName (
5298 + IN const char * const name,
5299 + OUT pkcs11h_token_id_t * const p_token_id
5300 +);
5301 +static
5302 +CK_RV
5303 +_pkcs11h_locate_getTokenIdByLabel (
5304 + IN const char * const label,
5305 + OUT pkcs11h_token_id_t * const p_token_id
5306 +);
5307 +
5308 +#if defined(ENABLE_PKCS11H_CERTIFICATE)
5309 +
5310 +static
5311 +CK_RV
5312 +_pkcs11h_locate_getCertificateIdByLabel (
5313 + IN const pkcs11h_session_t session,
5314 + IN OUT const pkcs11h_certificate_id_t certificate_id,
5315 + IN const char * const label
5316 +);
5317 +static
5318 +CK_RV
5319 +_pkcs11h_locate_getCertificateIdBySubject (
5320 + IN const pkcs11h_session_t session,
5321 + IN OUT const pkcs11h_certificate_id_t certificate_id,
5322 + IN const char * const subject
5323 +);
5324 +
5325 +#endif /* ENABLE_PKCS11H_CERTIFICATE */
5326 +#endif /* ENABLE_PKCS11H_LOCATE */
5327 +
5328 +#if defined(ENABLE_PKCS11H_ENUM)
5329 +/*======================================================================*
5330 + * ENUM INTERFACE
5331 + *======================================================================*/
5332 +
5333 +#if defined(ENABLE_PKCS11H_CERTIFICATE)
5334 +
5335 +static
5336 +CK_RV
5337 +_pkcs11h_certificate_enumSessionCertificates (
5338 + IN const pkcs11h_session_t session,
5339 + IN void * const user_data,
5340 + IN const unsigned mask_prompt
5341 +);
5342 +static
5343 +CK_RV
5344 +_pkcs11h_certificate_splitCertificateIdList (
5345 + IN const pkcs11h_certificate_id_list_t cert_id_all,
5346 + OUT pkcs11h_certificate_id_list_t * const p_cert_id_issuers_list,
5347 + OUT pkcs11h_certificate_id_list_t * const p_cert_id_end_list
5348 +);
5349 +
5350 +#endif /* ENABLE_PKCS11H_CERTIFICATE */
5351 +
5352 +#endif /* ENABLE_PKCS11H_ENUM */
5353 +
5354 +#if defined(ENABLE_PKCS11H_SLOTEVENT)
5355 +/*======================================================================*
5356 + * SLOTEVENT INTERFACE
5357 + *======================================================================*/
5358 +
5359 +static
5360 +unsigned long
5361 +_pkcs11h_slotevent_checksum (
5362 + IN const unsigned char * const p,
5363 + IN const size_t s
5364 +);
5365 +static
5366 +void *
5367 +_pkcs11h_slotevent_provider (
5368 + IN void *p
5369 +);
5370 +static
5371 +void *
5372 +_pkcs11h_slotevent_manager (
5373 + IN void *p
5374 +);
5375 +static
5376 +CK_RV
5377 +_pkcs11h_slotevent_init ();
5378 +static
5379 +CK_RV
5380 +_pkcs11h_slotevent_notify ();
5381 +static
5382 +CK_RV
5383 +_pkcs11h_slotevent_terminate ();
5384 +
5385 +#endif /* ENABLE_PKCS11H_SLOTEVENT */
5386 +
5387 +#if defined(ENABLE_PKCS11H_OPENSSL)
5388 +/*======================================================================*
5389 + * OPENSSL INTERFACE
5390 + *======================================================================*/
5391 +
5392 +static
5393 +int
5394 +_pkcs11h_openssl_finish (
5395 + IN OUT RSA *rsa
5396 +);
5397 +#if OPENSSL_VERSION_NUMBER < 0x00907000L
5398 +static
5399 +int
5400 +_pkcs11h_openssl_dec (
5401 + IN int flen,
5402 + IN unsigned char *from,
5403 + OUT unsigned char *to,
5404 + IN OUT RSA *rsa,
5405 + IN int padding
5406 +);
5407 +static
5408 +int
5409 +_pkcs11h_openssl_sign (
5410 + IN int type,
5411 + IN unsigned char *m,
5412 + IN unsigned int m_len,
5413 + OUT unsigned char *sigret,
5414 + OUT unsigned int *siglen,
5415 + IN OUT RSA *rsa
5416 +);
5417 +#else
5418 +static
5419 +int
5420 +_pkcs11h_openssl_dec (
5421 + IN int flen,
5422 + IN const unsigned char *from,
5423 + OUT unsigned char *to,
5424 + IN OUT RSA *rsa,
5425 + IN int padding
5426 +);
5427 +static
5428 +int
5429 +_pkcs11h_openssl_sign (
5430 + IN int type,
5431 + IN const unsigned char *m,
5432 + IN unsigned int m_len,
5433 + OUT unsigned char *sigret,
5434 + OUT unsigned int *siglen,
5435 + IN OUT const RSA *rsa
5436 +);
5437 +#endif
5438 +static
5439 +pkcs11h_openssl_session_t
5440 +_pkcs11h_openssl_get_openssl_session (
5441 + IN OUT const RSA *rsa
5442 +);
5443 +static
5444 +pkcs11h_certificate_t
5445 +_pkcs11h_openssl_get_pkcs11h_certificate (
5446 + IN OUT const RSA *rsa
5447 +);
5448 +#endif /* ENABLE_PKCS11H_OPENSSL */
5449 +
5450 +/*==========================================
5451 + * Static data
5452 + */
5453 +
5454 +#if defined(ENABLE_PKCS11H_THREADING)
5455 +#if !defined(WIN32)
5456 +static struct {
5457 + pkcs11h_mutex_t mutex;
5458 + __pkcs11h_threading_mutex_entry_t head;
5459 +} __s_pkcs11h_threading_mutex_list = {
5460 + PTHREAD_MUTEX_INITIALIZER,
5461 + NULL
5462 +};
5463 +#endif
5464 +#endif
5465 +
5466 +pkcs11h_data_t s_pkcs11h_data = NULL;
5467 +unsigned int s_pkcs11h_loglevel = PKCS11H_LOG_INFO;
5468 +
5469 +/*======================================================================*
5470 + * PUBLIC INTERFACE
5471 + *======================================================================*/
5472 +
5473 +const char *
5474 +pkcs11h_getMessage (
5475 + IN const CK_RV rv
5476 +) {
5477 + switch (rv) {
5478 + case CKR_OK: return "CKR_OK";
5479 + case CKR_CANCEL: return "CKR_CANCEL";
5480 + case CKR_HOST_MEMORY: return "CKR_HOST_MEMORY";
5481 + case CKR_SLOT_ID_INVALID: return "CKR_SLOT_ID_INVALID";
5482 + case CKR_GENERAL_ERROR: return "CKR_GENERAL_ERROR";
5483 + case CKR_FUNCTION_FAILED: return "CKR_FUNCTION_FAILED";
5484 + case CKR_ARGUMENTS_BAD: return "CKR_ARGUMENTS_BAD";
5485 + case CKR_NO_EVENT: return "CKR_NO_EVENT";
5486 + case CKR_NEED_TO_CREATE_THREADS: return "CKR_NEED_TO_CREATE_THREADS";
5487 + case CKR_CANT_LOCK: return "CKR_CANT_LOCK";
5488 + case CKR_ATTRIBUTE_READ_ONLY: return "CKR_ATTRIBUTE_READ_ONLY";
5489 + case CKR_ATTRIBUTE_SENSITIVE: return "CKR_ATTRIBUTE_SENSITIVE";
5490 + case CKR_ATTRIBUTE_TYPE_INVALID: return "CKR_ATTRIBUTE_TYPE_INVALID";
5491 + case CKR_ATTRIBUTE_VALUE_INVALID: return "CKR_ATTRIBUTE_VALUE_INVALID";
5492 + case CKR_DATA_INVALID: return "CKR_DATA_INVALID";
5493 + case CKR_DATA_LEN_RANGE: return "CKR_DATA_LEN_RANGE";
5494 + case CKR_DEVICE_ERROR: return "CKR_DEVICE_ERROR";
5495 + case CKR_DEVICE_MEMORY: return "CKR_DEVICE_MEMORY";
5496 + case CKR_DEVICE_REMOVED: return "CKR_DEVICE_REMOVED";
5497 + case CKR_ENCRYPTED_DATA_INVALID: return "CKR_ENCRYPTED_DATA_INVALID";
5498 + case CKR_ENCRYPTED_DATA_LEN_RANGE: return "CKR_ENCRYPTED_DATA_LEN_RANGE";
5499 + case CKR_FUNCTION_CANCELED: return "CKR_FUNCTION_CANCELED";
5500 + case CKR_FUNCTION_NOT_PARALLEL: return "CKR_FUNCTION_NOT_PARALLEL";
5501 + case CKR_FUNCTION_NOT_SUPPORTED: return "CKR_FUNCTION_NOT_SUPPORTED";
5502 + case CKR_KEY_HANDLE_INVALID: return "CKR_KEY_HANDLE_INVALID";
5503 + case CKR_KEY_SIZE_RANGE: return "CKR_KEY_SIZE_RANGE";
5504 + case CKR_KEY_TYPE_INCONSISTENT: return "CKR_KEY_TYPE_INCONSISTENT";
5505 + case CKR_KEY_NOT_NEEDED: return "CKR_KEY_NOT_NEEDED";
5506 + case CKR_KEY_CHANGED: return "CKR_KEY_CHANGED";
5507 + case CKR_KEY_NEEDED: return "CKR_KEY_NEEDED";
5508 + case CKR_KEY_INDIGESTIBLE: return "CKR_KEY_INDIGESTIBLE";
5509 + case CKR_KEY_FUNCTION_NOT_PERMITTED: return "CKR_KEY_FUNCTION_NOT_PERMITTED";
5510 + case CKR_KEY_NOT_WRAPPABLE: return "CKR_KEY_NOT_WRAPPABLE";
5511 + case CKR_KEY_UNEXTRACTABLE: return "CKR_KEY_UNEXTRACTABLE";
5512 + case CKR_MECHANISM_INVALID: return "CKR_MECHANISM_INVALID";
5513 + case CKR_MECHANISM_PARAM_INVALID: return "CKR_MECHANISM_PARAM_INVALID";
5514 + case CKR_OBJECT_HANDLE_INVALID: return "CKR_OBJECT_HANDLE_INVALID";
5515 + case CKR_OPERATION_ACTIVE: return "CKR_OPERATION_ACTIVE";
5516 + case CKR_OPERATION_NOT_INITIALIZED: return "CKR_OPERATION_NOT_INITIALIZED";
5517 + case CKR_PIN_INCORRECT: return "CKR_PIN_INCORRECT";
5518 + case CKR_PIN_INVALID: return "CKR_PIN_INVALID";
5519 + case CKR_PIN_LEN_RANGE: return "CKR_PIN_LEN_RANGE";
5520 + case CKR_PIN_EXPIRED: return "CKR_PIN_EXPIRED";
5521 + case CKR_PIN_LOCKED: return "CKR_PIN_LOCKED";
5522 + case CKR_SESSION_CLOSED: return "CKR_SESSION_CLOSED";
5523 + case CKR_SESSION_COUNT: return "CKR_SESSION_COUNT";
5524 + case CKR_SESSION_HANDLE_INVALID: return "CKR_SESSION_HANDLE_INVALID";
5525 + case CKR_SESSION_PARALLEL_NOT_SUPPORTED: return "CKR_SESSION_PARALLEL_NOT_SUPPORTED";
5526 + case CKR_SESSION_READ_ONLY: return "CKR_SESSION_READ_ONLY";
5527 + case CKR_SESSION_EXISTS: return "CKR_SESSION_EXISTS";
5528 + case CKR_SESSION_READ_ONLY_EXISTS: return "CKR_SESSION_READ_ONLY_EXISTS";
5529 + case CKR_SESSION_READ_WRITE_SO_EXISTS: return "CKR_SESSION_READ_WRITE_SO_EXISTS";
5530 + case CKR_SIGNATURE_INVALID: return "CKR_SIGNATURE_INVALID";
5531 + case CKR_SIGNATURE_LEN_RANGE: return "CKR_SIGNATURE_LEN_RANGE";
5532 + case CKR_TEMPLATE_INCOMPLETE: return "CKR_TEMPLATE_INCOMPLETE";
5533 + case CKR_TEMPLATE_INCONSISTENT: return "CKR_TEMPLATE_INCONSISTENT";
5534 + case CKR_TOKEN_NOT_PRESENT: return "CKR_TOKEN_NOT_PRESENT";
5535 + case CKR_TOKEN_NOT_RECOGNIZED: return "CKR_TOKEN_NOT_RECOGNIZED";
5536 + case CKR_TOKEN_WRITE_PROTECTED: return "CKR_TOKEN_WRITE_PROTECTED";
5537 + case CKR_UNWRAPPING_KEY_HANDLE_INVALID: return "CKR_UNWRAPPING_KEY_HANDLE_INVALID";
5538 + case CKR_UNWRAPPING_KEY_SIZE_RANGE: return "CKR_UNWRAPPING_KEY_SIZE_RANGE";
5539 + case CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT: return "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT";
5540 + case CKR_USER_ALREADY_LOGGED_IN: return "CKR_USER_ALREADY_LOGGED_IN";
5541 + case CKR_USER_NOT_LOGGED_IN: return "CKR_USER_NOT_LOGGED_IN";
5542 + case CKR_USER_PIN_NOT_INITIALIZED: return "CKR_USER_PIN_NOT_INITIALIZED";
5543 + case CKR_USER_TYPE_INVALID: return "CKR_USER_TYPE_INVALID";
5544 + case CKR_USER_ANOTHER_ALREADY_LOGGED_IN: return "CKR_USER_ANOTHER_ALREADY_LOGGED_IN";
5545 + case CKR_USER_TOO_MANY_TYPES: return "CKR_USER_TOO_MANY_TYPES";
5546 + case CKR_WRAPPED_KEY_INVALID: return "CKR_WRAPPED_KEY_INVALID";
5547 + case CKR_WRAPPED_KEY_LEN_RANGE: return "CKR_WRAPPED_KEY_LEN_RANGE";
5548 + case CKR_WRAPPING_KEY_HANDLE_INVALID: return "CKR_WRAPPING_KEY_HANDLE_INVALID";
5549 + case CKR_WRAPPING_KEY_SIZE_RANGE: return "CKR_WRAPPING_KEY_SIZE_RANGE";
5550 + case CKR_WRAPPING_KEY_TYPE_INCONSISTENT: return "CKR_WRAPPING_KEY_TYPE_INCONSISTENT";
5551 + case CKR_RANDOM_SEED_NOT_SUPPORTED: return "CKR_RANDOM_SEED_NOT_SUPPORTED";
5552 + case CKR_RANDOM_NO_RNG: return "CKR_RANDOM_NO_RNG";
5553 + case CKR_DOMAIN_PARAMS_INVALID: return "CKR_DOMAIN_PARAMS_INVALID";
5554 + case CKR_BUFFER_TOO_SMALL: return "CKR_BUFFER_TOO_SMALL";
5555 + case CKR_SAVED_STATE_INVALID: return "CKR_SAVED_STATE_INVALID";
5556 + case CKR_INFORMATION_SENSITIVE: return "CKR_INFORMATION_SENSITIVE";
5557 + case CKR_STATE_UNSAVEABLE: return "CKR_STATE_UNSAVEABLE";
5558 + case CKR_CRYPTOKI_NOT_INITIALIZED: return "CKR_CRYPTOKI_NOT_INITIALIZED";
5559 + case CKR_CRYPTOKI_ALREADY_INITIALIZED: return "CKR_CRYPTOKI_ALREADY_INITIALIZED";
5560 + case CKR_MUTEX_BAD: return "CKR_MUTEX_BAD";
5561 + case CKR_MUTEX_NOT_LOCKED: return "CKR_MUTEX_NOT_LOCKED";
5562 + case CKR_FUNCTION_REJECTED: return "CKR_FUNCTION_REJECTED";
5563 + case CKR_VENDOR_DEFINED: return "CKR_VENDOR_DEFINED";
5564 + default: return "Unknown PKCS#11 error";
5565 + }
5566 +}
5567 +
5568 +CK_RV
5569 +pkcs11h_initialize () {
5570 +
5571 +#if defined(ENABLE_PKCS11H_THREADING)
5572 + PKCS11H_BOOL mutex_locked = FALSE;
5573 +#endif
5574 + CK_RV rv = CKR_OK;
5575 +
5576 + PKCS11H_DEBUG (
5577 + PKCS11H_LOG_DEBUG2,
5578 + "PKCS#11: pkcs11h_initialize entry"
5579 + );
5580 +
5581 + pkcs11h_terminate ();
5582 +
5583 + if (rv == CKR_OK) {
5584 + rv = _pkcs11h_mem_malloc ((void*)&s_pkcs11h_data, sizeof (struct pkcs11h_data_s));
5585 + }
5586 +
5587 +#if defined(USE_PKCS11H_OPENSSL) || defined(ENABLE_PKCS11H_OPENSSL)
5588 + OpenSSL_add_all_digests ();
5589 +#endif
5590 +#if defined(USE_PKCS11H_GNUTLS)
5591 + if (
5592 + rv == CKR_OK &&
5593 + gnutls_global_init () != GNUTLS_E_SUCCESS
5594 + ) {
5595 + rv = CKR_FUNCTION_FAILED;
5596 + }
5597 +#endif
5598 +
5599 +#if defined(ENABLE_PKCS11H_THREADING)
5600 + if (rv == CKR_OK) {
5601 + rv = _pkcs11h_threading_mutexInit (&s_pkcs11h_data->mutexes.global);
5602 + }
5603 + if (rv == CKR_OK) {
5604 + rv = _pkcs11h_threading_mutexInit (&s_pkcs11h_data->mutexes.session);
5605 + }
5606 + if (rv == CKR_OK) {
5607 + rv = _pkcs11h_threading_mutexInit (&s_pkcs11h_data->mutexes.cache);
5608 + }
5609 +#if !defined(WIN32)
5610 + if (
5611 + rv == CKR_OK &&
5612 + pthread_atfork (
5613 + __pkcs11h_threading_atfork_prepare,
5614 + __pkcs11h_threading_atfork_parent,
5615 + __pkcs11h_threading_atfork_child
5616 + )
5617 + ) {
5618 + rv = CKR_FUNCTION_FAILED;
5619 + }
5620 +#endif
5621 + if (
5622 + rv == CKR_OK &&
5623 + (rv = _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.global)) == CKR_OK
5624 + ) {
5625 + mutex_locked = TRUE;
5626 + }
5627 +#endif
5628 +
5629 + if (rv == CKR_OK) {
5630 + s_pkcs11h_data->max_retries = PKCS11H_DEFAULT_MAX_LOGIN_RETRY;
5631 + s_pkcs11h_data->allow_protected_auth = TRUE;
5632 + s_pkcs11h_data->pin_cache_period = PKCS11H_DEFAULT_PIN_CACHE_PERIOD;
5633 + s_pkcs11h_data->initialized = TRUE;
5634 + }
5635 +
5636 + if (rv == CKR_OK) {
5637 + pkcs11h_setLogHook (_pkcs11h_hooks_default_log, NULL);
5638 + pkcs11h_setTokenPromptHook (_pkcs11h_hooks_default_token_prompt, NULL);
5639 + pkcs11h_setPINPromptHook (_pkcs11h_hooks_default_pin_prompt, NULL);
5640 + }
5641 +
5642 +#if defined(ENABLE_PKCS11H_THREADING)
5643 + if (mutex_locked) {
5644 + _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.global);
5645 + mutex_locked = FALSE;
5646 + }
5647 +#endif
5648 +
5649 + PKCS11H_DEBUG (
5650 + PKCS11H_LOG_DEBUG2,
5651 + "PKCS#11: pkcs11h_initialize return rv=%ld-'%s'",
5652 + rv,
5653 + pkcs11h_getMessage (rv)
5654 + );
5655 +
5656 + return rv;
5657 +}
5658 +
5659 +CK_RV
5660 +pkcs11h_terminate () {
5661 +
5662 + PKCS11H_DEBUG (
5663 + PKCS11H_LOG_DEBUG2,
5664 + "PKCS#11: pkcs11h_terminate entry"
5665 + );
5666 +
5667 + if (s_pkcs11h_data != NULL) {
5668 + pkcs11h_provider_t current_provider = NULL;
5669 +
5670 + PKCS11H_DEBUG (
5671 + PKCS11H_LOG_DEBUG1,
5672 + "PKCS#11: Removing providers"
5673 + );
5674 +
5675 + for (
5676 + current_provider = s_pkcs11h_data->providers;
5677 + current_provider != NULL;
5678 + current_provider = current_provider->next
5679 + ) {
5680 + pkcs11h_removeProvider (current_provider->reference);
5681 + }
5682 +
5683 +#if defined(ENABLE_PKCS11H_THREADING)
5684 + _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.cache);
5685 + _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.session);
5686 + _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.global);
5687 +#endif
5688 +
5689 + PKCS11H_DEBUG (
5690 + PKCS11H_LOG_DEBUG1,
5691 + "PKCS#11: Releasing sessions"
5692 + );
5693 +
5694 + while (s_pkcs11h_data->sessions != NULL) {
5695 + pkcs11h_session_t current = s_pkcs11h_data->sessions;
5696 + s_pkcs11h_data->sessions = s_pkcs11h_data->sessions->next;
5697 +
5698 +#if defined(ENABLE_PKCS11H_THREADING)
5699 + _pkcs11h_threading_mutexLock (&current->mutex);
5700 +#endif
5701 +
5702 + current->valid = FALSE;
5703 +
5704 + if (current->reference_count != 0) {
5705 + PKCS11H_DEBUG (
5706 + PKCS11H_LOG_DEBUG1,
5707 + "PKCS#11: Warning: Found session with references"
5708 + );
5709 + }
5710 +
5711 + if (current->token_id != NULL) {
5712 + pkcs11h_token_freeTokenId (current->token_id);
5713 + current->token_id = NULL;
5714 + }
5715 +
5716 +#if defined(ENABLE_PKCS11H_ENUM)
5717 +#if defined(ENABLE_PKCS11H_CERTIFICATE)
5718 + pkcs11h_certificate_freeCertificateIdList (current->cached_certs);
5719 +#endif
5720 +#endif
5721 +
5722 + current->provider = NULL;
5723 +
5724 +#if defined(ENABLE_PKCS11H_THREADING)
5725 + _pkcs11h_threading_mutexFree (&current->mutex);
5726 +#endif
5727 +
5728 + _pkcs11h_mem_free ((void *)&current);
5729 + }
5730 +
5731 +#if defined(ENABLE_PKCS11H_SLOTEVENT)
5732 + PKCS11H_DEBUG (
5733 + PKCS11H_LOG_DEBUG1,
5734 + "PKCS#11: Terminating slotevent"
5735 + );
5736 +
5737 + _pkcs11h_slotevent_terminate ();
5738 +#endif
5739 + PKCS11H_DEBUG (
5740 + PKCS11H_LOG_DEBUG1,
5741 + "PKCS#11: Marking as uninitialized"
5742 + );
5743 +
5744 + s_pkcs11h_data->initialized = FALSE;
5745 +
5746 + while (s_pkcs11h_data->providers != NULL) {
5747 + pkcs11h_provider_t current = s_pkcs11h_data->providers;
5748 + s_pkcs11h_data->providers = s_pkcs11h_data->providers->next;
5749 +
5750 + _pkcs11h_mem_free ((void *)&current);
5751 + }
5752 +
5753 +#if defined(ENABLE_PKCS11H_THREADING)
5754 + _pkcs11h_threading_mutexFree (&s_pkcs11h_data->mutexes.cache);
5755 + _pkcs11h_threading_mutexFree (&s_pkcs11h_data->mutexes.global);
5756 + _pkcs11h_threading_mutexFree (&s_pkcs11h_data->mutexes.session);
5757 +#endif
5758 +
5759 +#if defined(USE_PKCS11H_GNUTLS)
5760 + gnutls_global_deinit ();
5761 +#endif
5762 +
5763 + _pkcs11h_mem_free ((void *)&s_pkcs11h_data);
5764 + }
5765 +
5766 + PKCS11H_DEBUG (
5767 + PKCS11H_LOG_DEBUG2,
5768 + "PKCS#11: pkcs11h_terminate return"
5769 + );
5770 +
5771 + return CKR_OK;
5772 +}
5773 +
5774 +void
5775 +pkcs11h_setLogLevel (
5776 + IN const unsigned flags
5777 +) {
5778 + s_pkcs11h_loglevel = flags;
5779 +}
5780 +
5781 +unsigned
5782 +pkcs11h_getLogLevel () {
5783 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
5784 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
5785 +
5786 + return s_pkcs11h_loglevel;
5787 +}
5788 +
5789 +CK_RV
5790 +pkcs11h_setLogHook (
5791 + IN const pkcs11h_hook_log_t hook,
5792 + IN void * const global_data
5793 +) {
5794 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
5795 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
5796 + PKCS11H_ASSERT (hook!=NULL);
5797 +
5798 + s_pkcs11h_data->hooks.log = hook;
5799 + s_pkcs11h_data->hooks.log_data = global_data;
5800 +
5801 + return CKR_OK;
5802 +}
5803 +
5804 +CK_RV
5805 +pkcs11h_setSlotEventHook (
5806 + IN const pkcs11h_hook_slotevent_t hook,
5807 + IN void * const global_data
5808 +) {
5809 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
5810 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
5811 + PKCS11H_ASSERT (hook!=NULL);
5812 +
5813 +#if defined(ENABLE_PKCS11H_SLOTEVENT)
5814 + s_pkcs11h_data->hooks.slotevent = hook;
5815 + s_pkcs11h_data->hooks.slotevent_data = global_data;
5816 +
5817 + return _pkcs11h_slotevent_init ();
5818 +#else
5819 + (void)global_data;
5820 +
5821 + return CKR_FUNCTION_NOT_SUPPORTED;
5822 +#endif
5823 +}
5824 +
5825 +CK_RV
5826 +pkcs11h_setPINPromptHook (
5827 + IN const pkcs11h_hook_pin_prompt_t hook,
5828 + IN void * const global_data
5829 +) {
5830 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
5831 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
5832 + PKCS11H_ASSERT (hook!=NULL);
5833 +
5834 + s_pkcs11h_data->hooks.pin_prompt = hook;
5835 + s_pkcs11h_data->hooks.pin_prompt_data = global_data;
5836 +
5837 + return CKR_OK;
5838 +}
5839 +
5840 +CK_RV
5841 +pkcs11h_setTokenPromptHook (
5842 + IN const pkcs11h_hook_token_prompt_t hook,
5843 + IN void * const global_data
5844 +) {
5845 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
5846 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
5847 + PKCS11H_ASSERT (hook!=NULL);
5848 +
5849 + s_pkcs11h_data->hooks.token_prompt = hook;
5850 + s_pkcs11h_data->hooks.token_prompt_data = global_data;
5851 +
5852 + return CKR_OK;
5853 +}
5854 +
5855 +CK_RV
5856 +pkcs11h_setPINCachePeriod (
5857 + IN const int pin_cache_period
5858 +) {
5859 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
5860 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
5861 +
5862 + s_pkcs11h_data->pin_cache_period = pin_cache_period;
5863 +
5864 + return CKR_OK;
5865 +}
5866 +
5867 +CK_RV
5868 +pkcs11h_setMaxLoginRetries (
5869 + IN const unsigned max_retries
5870 +) {
5871 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
5872 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
5873 +
5874 + s_pkcs11h_data->max_retries = max_retries;
5875 +
5876 + return CKR_OK;
5877 +}
5878 +
5879 +CK_RV
5880 +pkcs11h_setProtectedAuthentication (
5881 + IN const PKCS11H_BOOL allow_protected_auth
5882 +) {
5883 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
5884 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
5885 +
5886 + s_pkcs11h_data->allow_protected_auth = allow_protected_auth;
5887 +
5888 + return CKR_OK;
5889 +}
5890 +
5891 +CK_RV
5892 +pkcs11h_addProvider (
5893 + IN const char * const reference,
5894 + IN const char * const provider_location,
5895 + IN const PKCS11H_BOOL allow_protected_auth,
5896 + IN const unsigned mask_sign_mode,
5897 + IN const int slot_event_method,
5898 + IN const int slot_poll_interval,
5899 + IN const PKCS11H_BOOL cert_is_private
5900 +) {
5901 +#if defined(ENABLE_PKCS11H_THREADING)
5902 + PKCS11H_BOOL mutex_locked = FALSE;
5903 +#endif
5904 +#if defined(WIN32)
5905 + int mypid = 0;
5906 +#else
5907 + pid_t mypid = getpid ();
5908 +#endif
5909 + pkcs11h_provider_t provider = NULL;
5910 + CK_C_GetFunctionList gfl = NULL;
5911 + CK_INFO info;
5912 + CK_RV rv = CKR_OK;
5913 +
5914 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
5915 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
5916 + PKCS11H_ASSERT (provider_location!=NULL);
5917 + /*PKCS11H_ASSERT (szSignMode!=NULL); NOT NEEDED*/
5918 +
5919 + PKCS11H_DEBUG (
5920 + PKCS11H_LOG_DEBUG2,
5921 + "PKCS#11: pkcs11h_addProvider entry pid=%d, reference='%s', provider_location='%s', allow_protected_auth=%d, mask_sign_mode=%08x, cert_is_private=%d",
5922 + mypid,
5923 + reference,
5924 + provider_location,
5925 + allow_protected_auth ? 1 : 0,
5926 + mask_sign_mode,
5927 + cert_is_private ? 1 : 0
5928 + );
5929 +
5930 + PKCS11H_DEBUG (
5931 + PKCS11H_LOG_DEBUG1,
5932 + "PKCS#11: Adding provider '%s'-'%s'",
5933 + reference,
5934 + provider_location
5935 + );
5936 +
5937 +#if defined(ENABLE_PKCS11H_THREADING)
5938 + if (
5939 + rv == CKR_OK &&
5940 + (rv = _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.global)) == CKR_OK
5941 + ) {
5942 + mutex_locked = TRUE;
5943 + }
5944 +#endif
5945 +
5946 + if (
5947 + rv == CKR_OK &&
5948 + (rv = _pkcs11h_mem_malloc ((void *)&provider, sizeof (struct pkcs11h_provider_s))) == CKR_OK
5949 + ) {
5950 + strncpy (
5951 + provider->reference,
5952 + reference,
5953 + sizeof (provider->reference)-1
5954 + );
5955 + provider->reference[sizeof (provider->reference)-1] = '\x0';
5956 + strncpy (
5957 + provider->manufacturerID,
5958 + (
5959 + strlen (provider_location) < sizeof (provider->manufacturerID) ?
5960 + provider_location :
5961 + provider_location+strlen (provider_location)-sizeof (provider->manufacturerID)+1
5962 + ),
5963 + sizeof (provider->manufacturerID)-1
5964 + );
5965 + provider->manufacturerID[sizeof (provider->manufacturerID)-1] = '\x0';
5966 + provider->allow_protected_auth = allow_protected_auth;
5967 + provider->mask_sign_mode = mask_sign_mode;
5968 + provider->slot_event_method = slot_event_method;
5969 + provider->slot_poll_interval = slot_poll_interval;
5970 + provider->cert_is_private = cert_is_private;
5971 + }
5972 +
5973 + if (rv == CKR_OK) {
5974 +#if defined(WIN32)
5975 + provider->handle = LoadLibraryA (provider_location);
5976 +#else
5977 + provider->handle = dlopen (provider_location, RTLD_NOW);
5978 +#endif
5979 + if (provider->handle == NULL) {
5980 + rv = CKR_FUNCTION_FAILED;
5981 + }
5982 + }
5983 +
5984 + if (rv == CKR_OK) {
5985 +#if defined(WIN32)
5986 + gfl = (CK_C_GetFunctionList)GetProcAddress (
5987 + provider->handle,
5988 + "C_GetFunctionList"
5989 + );
5990 +#else
5991 + /*
5992 + * Make compiler happy!
5993 + */
5994 + void *p = dlsym (
5995 + provider->handle,
5996 + "C_GetFunctionList"
5997 + );
5998 + memmove (
5999 + &gfl,
6000 + &p,
6001 + sizeof (void *)
6002 + );
6003 +#endif
6004 + if (gfl == NULL) {
6005 + rv = CKR_FUNCTION_FAILED;
6006 + }
6007 + }
6008 +
6009 + if (rv == CKR_OK) {
6010 + rv = gfl (&provider->f);
6011 + }
6012 +
6013 + if (rv == CKR_OK) {
6014 + if ((rv = provider->f->C_Initialize (NULL)) != CKR_OK) {
6015 + if (rv == CKR_CRYPTOKI_ALREADY_INITIALIZED) {
6016 + rv = CKR_OK;
6017 + }
6018 + }
6019 + else {
6020 + provider->should_finalize = TRUE;
6021 + }
6022 + }
6023 +
6024 + if (
6025 + rv == CKR_OK &&
6026 + (rv = provider->f->C_GetInfo (&info)) == CKR_OK
6027 + ) {
6028 + _pkcs11h_util_fixupFixedString (
6029 + provider->manufacturerID,
6030 + (char *)info.manufacturerID,
6031 + sizeof (info.manufacturerID)
6032 + );
6033 + }
6034 +
6035 + if (rv == CKR_OK) {
6036 + provider->enabled = TRUE;
6037 + }
6038 +
6039 + if (provider != NULL) {
6040 + if (s_pkcs11h_data->providers == NULL) {
6041 + s_pkcs11h_data->providers = provider;
6042 + }
6043 + else {
6044 + pkcs11h_provider_t last = NULL;
6045 +
6046 + for (
6047 + last = s_pkcs11h_data->providers;
6048 + last->next != NULL;
6049 + last = last->next
6050 + );
6051 + last->next = provider;
6052 + }
6053 + }
6054 +
6055 +#if defined(ENABLE_PKCS11H_THREADING)
6056 + if (mutex_locked) {
6057 + _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.global);
6058 + mutex_locked = FALSE;
6059 + }
6060 +#endif
6061 +
6062 +#if defined(ENABLE_PKCS11H_SLOTEVENT)
6063 + _pkcs11h_slotevent_notify ();
6064 +#endif
6065 +
6066 + PKCS11H_DEBUG (
6067 + PKCS11H_LOG_DEBUG1,
6068 + "PKCS#11: Provider '%s' added rv=%ld-'%s'",
6069 + reference,
6070 + rv,
6071 + pkcs11h_getMessage (rv)
6072 + );
6073 +
6074 + PKCS11H_DEBUG (
6075 + PKCS11H_LOG_DEBUG2,
6076 + "PKCS#11: pkcs11h_addProvider return rv=%ld-'%s'",
6077 + rv,
6078 + pkcs11h_getMessage (rv)
6079 + );
6080 +
6081 + return rv;
6082 +}
6083 +
6084 +CK_RV
6085 +pkcs11h_removeProvider (
6086 + IN const char * const reference
6087 +) {
6088 +#if defined(ENABLE_PKCS11H_THREADING)
6089 + pkcs11h_session_t current_session = NULL;
6090 +#endif
6091 + pkcs11h_provider_t provider = NULL;
6092 + CK_RV rv = CKR_OK;
6093 +
6094 + PKCS11H_ASSERT (reference!=NULL);
6095 +
6096 + PKCS11H_DEBUG (
6097 + PKCS11H_LOG_DEBUG2,
6098 + "PKCS#11: pkcs11h_removeProvider entry reference='%s'",
6099 + reference
6100 + );
6101 +
6102 + PKCS11H_DEBUG (
6103 + PKCS11H_LOG_DEBUG1,
6104 + "PKCS#11: Removing provider '%s'",
6105 + reference
6106 + );
6107 +
6108 +#if defined(ENABLE_PKCS11H_THREADING)
6109 + _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.cache);
6110 + _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.session);
6111 + _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.global);
6112 +
6113 + for (
6114 + current_session = s_pkcs11h_data->sessions;
6115 + current_session != NULL;
6116 + current_session = current_session->next
6117 + ) {
6118 + _pkcs11h_threading_mutexLock (&current_session->mutex);
6119 + }
6120 +#endif
6121 +
6122 + provider = s_pkcs11h_data->providers;
6123 + while (
6124 + rv == CKR_OK &&
6125 + provider != NULL &&
6126 + strcmp (reference, provider->reference)
6127 + ) {
6128 + provider = provider->next;
6129 + }
6130 +
6131 + if (rv == CKR_OK && provider == NULL) {
6132 + rv = CKR_OBJECT_HANDLE_INVALID;
6133 + }
6134 +
6135 + if (rv == CKR_OK) {
6136 + provider->enabled = FALSE;
6137 + provider->reference[0] = '\0';
6138 +
6139 + if (provider->should_finalize) {
6140 + provider->f->C_Finalize (NULL);
6141 + provider->should_finalize = FALSE;
6142 + }
6143 +
6144 +#if defined(ENABLE_PKCS11H_SLOTEVENT)
6145 + _pkcs11h_slotevent_notify ();
6146 +
6147 + /*
6148 + * Wait until manager join this thread
6149 + * this happens saldom so I can poll
6150 + */
6151 + while (provider->slotevent_thread != PKCS11H_THREAD_NULL) {
6152 + _pkcs11h_threading_sleep (500);
6153 + }
6154 +#endif
6155 +
6156 + if (provider->f != NULL) {
6157 + provider->f = NULL;
6158 + }
6159 +
6160 + if (provider->handle != NULL) {
6161 +#if defined(WIN32)
6162 + FreeLibrary (provider->handle);
6163 +#else
6164 + dlclose (provider->handle);
6165 +#endif
6166 + provider->handle = NULL;
6167 + }
6168 + }
6169 +
6170 +#if defined(ENABLE_PKCS11H_THREADING)
6171 + for (
6172 + current_session = s_pkcs11h_data->sessions;
6173 + current_session != NULL;
6174 + current_session = current_session->next
6175 + ) {
6176 + _pkcs11h_threading_mutexRelease (&current_session->mutex);
6177 + }
6178 +
6179 + _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.cache);
6180 + _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.session);
6181 + _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.global);
6182 +#endif
6183 +
6184 + PKCS11H_DEBUG (
6185 + PKCS11H_LOG_DEBUG2,
6186 + "PKCS#11: pkcs11h_removeProvider return rv=%ld-'%s'",
6187 + rv,
6188 + pkcs11h_getMessage (rv)
6189 + );
6190 +
6191 + return rv;
6192 +}
6193 +
6194 +CK_RV
6195 +pkcs11h_forkFixup () {
6196 +#if defined(WIN32)
6197 + return CKR_OK;
6198 +#else
6199 +#if defined(ENABLE_PKCS11H_THREADING)
6200 + return CKR_OK;
6201 +#else
6202 + return _pkcs11h_forkFixup ();
6203 +#endif
6204 +#endif
6205 +}
6206 +
6207 +CK_RV
6208 +pkcs11h_plugAndPlay () {
6209 +#if defined(WIN32)
6210 + int mypid = 0;
6211 +#else
6212 + pid_t mypid = getpid ();
6213 +#endif
6214 +
6215 + PKCS11H_DEBUG (
6216 + PKCS11H_LOG_DEBUG2,
6217 + "PKCS#11: pkcs11h_forkFixup entry pid=%d",
6218 + mypid
6219 + );
6220 +
6221 + if (s_pkcs11h_data != NULL && s_pkcs11h_data->initialized) {
6222 + pkcs11h_provider_t current;
6223 +#if defined(ENABLE_PKCS11H_SLOTEVENT)
6224 + PKCS11H_BOOL slot_event_active = FALSE;
6225 +#endif
6226 +
6227 +#if defined(ENABLE_PKCS11H_THREADING)
6228 + _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.global);
6229 +#endif
6230 + for (
6231 + current = s_pkcs11h_data->providers;
6232 + current != NULL;
6233 + current = current->next
6234 + ) {
6235 + if (current->enabled) {
6236 + current->f->C_Finalize (NULL);
6237 + }
6238 + }
6239 +
6240 +#if defined(ENABLE_PKCS11H_SLOTEVENT)
6241 + if (s_pkcs11h_data->slotevent.initialized) {
6242 + slot_event_active = TRUE;
6243 + _pkcs11h_slotevent_terminate ();
6244 + }
6245 +#endif
6246 +
6247 + for (
6248 + current = s_pkcs11h_data->providers;
6249 + current != NULL;
6250 + current = current->next
6251 + ) {
6252 + if (current->enabled) {
6253 + current->f->C_Initialize (NULL);
6254 + }
6255 + }
6256 +
6257 +#if defined(ENABLE_PKCS11H_SLOTEVENT)
6258 + if (slot_event_active) {
6259 + _pkcs11h_slotevent_init ();
6260 + }
6261 +#endif
6262 +
6263 +#if defined(ENABLE_PKCS11H_THREADING)
6264 + _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.global);
6265 +#endif
6266 + }
6267 +
6268 + PKCS11H_DEBUG (
6269 + PKCS11H_LOG_DEBUG2,
6270 + "PKCS#11: pkcs11h_forkFixup return"
6271 + );
6272 +
6273 + return CKR_OK;
6274 +}
6275 +
6276 +CK_RV
6277 +pkcs11h_token_freeTokenId (
6278 + IN pkcs11h_token_id_t token_id
6279 +) {
6280 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
6281 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
6282 + PKCS11H_ASSERT (token_id!=NULL);
6283 +
6284 + PKCS11H_DEBUG (
6285 + PKCS11H_LOG_DEBUG2,
6286 + "PKCS#11: pkcs11h_token_freeTokenId entry certificate_id=%p",
6287 + (void *)token_id
6288 + );
6289 +
6290 + _pkcs11h_mem_free ((void *)&token_id);
6291 +
6292 + PKCS11H_DEBUG (
6293 + PKCS11H_LOG_DEBUG2,
6294 + "PKCS#11: pkcs11h_token_freeTokenId return"
6295 + );
6296 +
6297 + return CKR_OK;
6298 +}
6299 +
6300 +CK_RV
6301 +pkcs11h_token_duplicateTokenId (
6302 + OUT pkcs11h_token_id_t * const to,
6303 + IN const pkcs11h_token_id_t from
6304 +) {
6305 + CK_RV rv = CKR_OK;
6306 +
6307 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
6308 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
6309 + PKCS11H_ASSERT (to!=NULL);
6310 + PKCS11H_ASSERT (from!=NULL);
6311 +
6312 + PKCS11H_DEBUG (
6313 + PKCS11H_LOG_DEBUG2,
6314 + "PKCS#11: pkcs11h_token_duplicateTokenId entry to=%p form=%p",
6315 + (void *)to,
6316 + (void *)from
6317 + );
6318 +
6319 + *to = NULL;
6320 +
6321 + if (rv == CKR_OK) {
6322 + rv = _pkcs11h_mem_duplicate (
6323 + (void*)to,
6324 + NULL,
6325 + from,
6326 + sizeof (struct pkcs11h_token_id_s)
6327 + );
6328 + }
6329 +
6330 + PKCS11H_DEBUG (
6331 + PKCS11H_LOG_DEBUG2,
6332 + "PKCS#11: pkcs11h_token_duplicateTokenId return rv=%ld-'%s', *to=%p",
6333 + rv,
6334 + pkcs11h_getMessage (rv),
6335 + (void *)*to
6336 + );
6337 +
6338 + return rv;
6339 +}
6340 +
6341 +PKCS11H_BOOL
6342 +pkcs11h_token_sameTokenId (
6343 + IN const pkcs11h_token_id_t a,
6344 + IN const pkcs11h_token_id_t b
6345 +) {
6346 + PKCS11H_ASSERT (a!=NULL);
6347 + PKCS11H_ASSERT (b!=NULL);
6348 +
6349 + return (
6350 + !strcmp (a->manufacturerID, b->manufacturerID) &&
6351 + !strcmp (a->model, b->model) &&
6352 + !strcmp (a->serialNumber, b->serialNumber) &&
6353 + !strcmp (a->label, b->label)
6354 + );
6355 +}
6356 +
6357 +#if defined(ENABLE_PKCS11H_SERIALIZATION)
6358 +
6359 +CK_RV
6360 +pkcs11h_token_serializeTokenId (
6361 + OUT char * const sz,
6362 + IN OUT size_t *max,
6363 + IN const pkcs11h_token_id_t token_id
6364 +) {
6365 + const char *sources[5];
6366 + CK_RV rv = CKR_OK;
6367 + size_t n;
6368 + int e;
6369 +
6370 + /*PKCS11H_ASSERT (sz!=NULL); Not required*/
6371 + PKCS11H_ASSERT (max!=NULL);
6372 + PKCS11H_ASSERT (token_id!=NULL);
6373 +
6374 + { /* Must be after assert */
6375 + sources[0] = token_id->manufacturerID;
6376 + sources[1] = token_id->model;
6377 + sources[2] = token_id->serialNumber;
6378 + sources[3] = token_id->label;
6379 + sources[4] = NULL;
6380 + }
6381 +
6382 + PKCS11H_DEBUG (
6383 + PKCS11H_LOG_DEBUG2,
6384 + "PKCS#11: pkcs11h_token_serializeTokenId entry sz=%p, *max=%u, token_id=%p",
6385 + sz,
6386 + sz != NULL ? *max : 0,
6387 + (void *)token_id
6388 + );
6389 +
6390 + n = 0;
6391 + for (e=0;rv == CKR_OK && sources[e] != NULL;e++) {
6392 + size_t t;
6393 + rv = _pkcs11h_util_escapeString (NULL, sources[e], &t, PKCS11H_SERIALIZE_INVALID_CHARS);
6394 + n+=t;
6395 + }
6396 +
6397 + if (sz != NULL) {
6398 + if (*max < n) {
6399 + rv = CKR_ATTRIBUTE_VALUE_INVALID;
6400 + }
6401 + else {
6402 + n = 0;
6403 + for (e=0;sources[e] != NULL;e++) {
6404 + size_t t = *max-n;
6405 + _pkcs11h_util_escapeString (sz+n, sources[e], &t, PKCS11H_SERIALIZE_INVALID_CHARS);
6406 + n+=t;
6407 + sz[n-1] = '/';
6408 + }
6409 + sz[n-1] = '\x0';
6410 + }
6411 + }
6412 +
6413 + *max = n;
6414 +
6415 + PKCS11H_DEBUG (
6416 + PKCS11H_LOG_DEBUG2,
6417 + "PKCS#11: pkcs11h_token_serializeTokenId return rv=%ld-'%s', *max=%u, sz='%s'",
6418 + rv,
6419 + pkcs11h_getMessage (rv),
6420 + *max,
6421 + sz
6422 + );
6423 +
6424 + return rv;
6425 +}
6426 +
6427 +CK_RV
6428 +pkcs11h_token_deserializeTokenId (
6429 + OUT pkcs11h_token_id_t *p_token_id,
6430 + IN const char * const sz
6431 +) {
6432 +#define __PKCS11H_TARGETS_NUMBER 4
6433 + struct {
6434 + char *p;
6435 + size_t s;
6436 + } targets[__PKCS11H_TARGETS_NUMBER];
6437 +
6438 + pkcs11h_token_id_t token_id = NULL;
6439 + char *p1 = NULL;
6440 + char *_sz = NULL;
6441 + int e;
6442 + CK_RV rv = CKR_OK;
6443 +
6444 + PKCS11H_ASSERT (p_token_id!=NULL);
6445 + PKCS11H_ASSERT (sz!=NULL);
6446 +
6447 + PKCS11H_DEBUG (
6448 + PKCS11H_LOG_DEBUG2,
6449 + "PKCS#11: pkcs11h_token_deserializeTokenId entry p_token_id=%p, sz='%s'",
6450 + (void *)p_token_id,
6451 + sz
6452 + );
6453 +
6454 + *p_token_id = NULL;
6455 +
6456 + if (rv == CKR_OK) {
6457 + rv = _pkcs11h_mem_strdup (
6458 + (void *)&_sz,
6459 + sz
6460 + );
6461 + }
6462 +
6463 + if (rv == CKR_OK) {
6464 + p1 = _sz;
6465 + }
6466 +
6467 + if (
6468 + rv == CKR_OK &&
6469 + (rv = _pkcs11h_token_newTokenId (&token_id)) == CKR_OK
6470 + ) {
6471 + targets[0].p = token_id->manufacturerID;
6472 + targets[0].s = sizeof (token_id->manufacturerID);
6473 + targets[1].p = token_id->model;
6474 + targets[1].s = sizeof (token_id->model);
6475 + targets[2].p = token_id->serialNumber;
6476 + targets[2].s = sizeof (token_id->serialNumber);
6477 + targets[3].p = token_id->label;
6478 + targets[3].s = sizeof (token_id->label);
6479 + }
6480 +
6481 + for (e=0;rv == CKR_OK && e < __PKCS11H_TARGETS_NUMBER;e++) {
6482 + size_t l;
6483 + char *p2 = NULL;
6484 +
6485 + /*
6486 + * Don't search for last
6487 + * separator
6488 + */
6489 + if (rv == CKR_OK) {
6490 + if (e != __PKCS11H_TARGETS_NUMBER-1) {
6491 + p2 = strchr (p1, '/');
6492 + if (p2 == NULL) {
6493 + rv = CKR_ATTRIBUTE_VALUE_INVALID;
6494 + }
6495 + else {
6496 + *p2 = '\x0';
6497 + }
6498 + }
6499 + }
6500 +
6501 + if (rv == CKR_OK) {
6502 + _pkcs11h_util_unescapeString (
6503 + NULL,
6504 + p1,
6505 + &l
6506 + );
6507 + }
6508 +
6509 + if (rv == CKR_OK) {
6510 + if (l > targets[e].s) {
6511 + rv = CKR_ATTRIBUTE_VALUE_INVALID;
6512 + }
6513 + }
6514 +
6515 + if (rv == CKR_OK) {
6516 + l = targets[e].s;
6517 + _pkcs11h_util_unescapeString (
6518 + targets[e].p,
6519 + p1,
6520 + &l
6521 + );
6522 + }
6523 +
6524 + if (rv == CKR_OK) {
6525 + p1 = p2+1;
6526 + }
6527 + }
6528 +
6529 + if (rv == CKR_OK) {
6530 + strncpy (
6531 + token_id->display,
6532 + token_id->label,
6533 + sizeof (token_id->display)
6534 + );
6535 + }
6536 +
6537 + if (rv == CKR_OK) {
6538 + *p_token_id = token_id;
6539 + token_id = NULL;
6540 + }
6541 +
6542 + if (_sz != NULL) {
6543 + _pkcs11h_mem_free ((void *)&_sz);
6544 + }
6545 +
6546 + if (token_id != NULL) {
6547 + pkcs11h_token_freeTokenId (token_id);
6548 + }
6549 +
6550 + return rv;
6551 +#undef __PKCS11H_TARGETS_NUMBER
6552 +}
6553 +
6554 +#endif /* ENABLE_PKCS11H_SERIALIZATION */
6555 +
6556 +/*======================================================================*
6557 + * MEMORY INTERFACE
6558 + *======================================================================*/
6559 +
6560 +static
6561 +CK_RV
6562 +_pkcs11h_mem_malloc (
6563 + OUT const void * * const p,
6564 + IN const size_t s
6565 +) {
6566 + CK_RV rv = CKR_OK;
6567 +
6568 + PKCS11H_ASSERT (p!=NULL);
6569 + PKCS11H_ASSERT (s!=0);
6570 +
6571 + *p = NULL;
6572 +
6573 + if (s > 0) {
6574 + if (
6575 + (*p = (void *)PKCS11H_MALLOC (s)) == NULL
6576 + ) {
6577 + rv = CKR_HOST_MEMORY;
6578 + }
6579 + else {
6580 + memset ((void *)*p, 0, s);
6581 + }
6582 + }
6583 +
6584 + return rv;
6585 +}
6586 +
6587 +static
6588 +CK_RV
6589 +_pkcs11h_mem_free (
6590 + IN const void * * const p
6591 +) {
6592 + PKCS11H_ASSERT (p!=NULL);
6593 +
6594 + PKCS11H_FREE ((void *)*p);
6595 + *p = NULL;
6596 +
6597 + return CKR_OK;
6598 +}
6599 +
6600 +static
6601 +CK_RV
6602 +_pkcs11h_mem_strdup (
6603 + OUT const char * * const dest,
6604 + IN const char * const src
6605 +) {
6606 + return _pkcs11h_mem_duplicate (
6607 + (void *)dest,
6608 + NULL,
6609 + src,
6610 + strlen (src)+1
6611 + );
6612 +}
6613 +
6614 +static
6615 +CK_RV
6616 +_pkcs11h_mem_duplicate (
6617 + OUT const void * * const dest,
6618 + OUT size_t * const p_dest_size,
6619 + IN const void * const src,
6620 + IN const size_t mem_size
6621 +) {
6622 + CK_RV rv = CKR_OK;
6623 +
6624 + PKCS11H_ASSERT (dest!=NULL);
6625 + /*PKCS11H_ASSERT (dest_size!=NULL); NOT NEEDED*/
6626 + PKCS11H_ASSERT (!(mem_size!=0&&src==NULL));
6627 +
6628 + *dest = NULL;
6629 + if (p_dest_size != NULL) {
6630 + *p_dest_size = 0;
6631 + }
6632 +
6633 + if (src != NULL) {
6634 + if (
6635 + rv == CKR_OK &&
6636 + (rv = _pkcs11h_mem_malloc (dest, mem_size)) == CKR_OK
6637 + ) {
6638 + if (p_dest_size != NULL) {
6639 + *p_dest_size = mem_size;
6640 + }
6641 + memmove ((void*)*dest, src, mem_size);
6642 + }
6643 + }
6644 +
6645 + return rv;
6646 +}
6647 +
6648 +#if defined(ENABLE_PKCS11H_THREADING)
6649 +/*======================================================================*
6650 + * THREADING INTERFACE
6651 + *======================================================================*/
6652 +
6653 +static
6654 +void
6655 +_pkcs11h_threading_sleep (
6656 + IN const unsigned milli
6657 +) {
6658 +#if defined(WIN32)
6659 + Sleep (milli);
6660 +#else
6661 + usleep (milli*1000);
6662 +#endif
6663 +}
6664 +
6665 +static
6666 +CK_RV
6667 +_pkcs11h_threading_mutexInit (
6668 + OUT pkcs11h_mutex_t * const mutex
6669 +) {
6670 + CK_RV rv = CKR_OK;
6671 +#if defined(WIN32)
6672 + if (
6673 + rv == CKR_OK &&
6674 + (*mutex = CreateMutex (NULL, FALSE, NULL)) == NULL
6675 + ) {
6676 + rv = CKR_FUNCTION_FAILED;
6677 + }
6678 +#else
6679 + {
6680 + __pkcs11h_threading_mutex_entry_t entry = NULL;
6681 + PKCS11H_BOOL mutex_locked = FALSE;
6682 +
6683 + if (
6684 + rv == CKR_OK &&
6685 + (rv = _pkcs11h_threading_mutexLock (&__s_pkcs11h_threading_mutex_list.mutex)) == CKR_OK
6686 + ) {
6687 + mutex_locked = TRUE;
6688 + }
6689 +
6690 + if (rv == CKR_OK) {
6691 + rv = _pkcs11h_mem_malloc (
6692 + (void *)&entry,
6693 + sizeof (struct __pkcs11h_threading_mutex_entry_s)
6694 + );
6695 + }
6696 +
6697 + if (
6698 + rv == CKR_OK &&
6699 + pthread_mutex_init (mutex, NULL)
6700 + ) {
6701 + rv = CKR_FUNCTION_FAILED;
6702 + }
6703 +
6704 + if (rv == CKR_OK) {
6705 + entry->p_mutex = mutex;
6706 + entry->next = __s_pkcs11h_threading_mutex_list.head;
6707 + __s_pkcs11h_threading_mutex_list.head = entry;
6708 + entry = NULL;
6709 + }
6710 +
6711 + if (entry != NULL) {
6712 + _pkcs11h_mem_free ((void *)&entry);
6713 + }
6714 +
6715 + if (mutex_locked) {
6716 + _pkcs11h_threading_mutexRelease (&__s_pkcs11h_threading_mutex_list.mutex);
6717 + mutex_locked = FALSE;
6718 + }
6719 + }
6720 +#endif
6721 + return rv;
6722 +}
6723 +
6724 +static
6725 +CK_RV
6726 +_pkcs11h_threading_mutexLock (
6727 + IN OUT pkcs11h_mutex_t *const mutex
6728 +) {
6729 + CK_RV rv = CKR_OK;
6730 +#if defined(WIN32)
6731 + if (
6732 + rv == CKR_OK &&
6733 + WaitForSingleObject (*mutex, INFINITE) == WAIT_FAILED
6734 + ) {
6735 + rv = CKR_FUNCTION_FAILED;
6736 + }
6737 +#else
6738 + if (
6739 + rv == CKR_OK &&
6740 + pthread_mutex_lock (mutex)
6741 + ) {
6742 + rv = CKR_FUNCTION_FAILED;
6743 + }
6744 +#endif
6745 + return rv;
6746 +}
6747 +
6748 +static
6749 +CK_RV
6750 +_pkcs11h_threading_mutexRelease (
6751 + IN OUT pkcs11h_mutex_t *const mutex
6752 +) {
6753 + CK_RV rv = CKR_OK;
6754 +#if defined(WIN32)
6755 + if (
6756 + rv == CKR_OK &&
6757 + !ReleaseMutex (*mutex)
6758 + ) {
6759 + rv = CKR_FUNCTION_FAILED;
6760 + }
6761 +#else
6762 + if (
6763 + rv == CKR_OK &&
6764 + pthread_mutex_unlock (mutex)
6765 + ) {
6766 + rv = CKR_FUNCTION_FAILED;
6767 + }
6768 +#endif
6769 + return rv;
6770 +}
6771 +
6772 +static
6773 +CK_RV
6774 +_pkcs11h_threading_mutexFree (
6775 + IN OUT pkcs11h_mutex_t *const mutex
6776 +) {
6777 +#if defined(WIN32)
6778 + if (*mutex != NULL) {
6779 + CloseHandle (*mutex);
6780 + *mutex = NULL;
6781 + }
6782 +#else
6783 + {
6784 + __pkcs11h_threading_mutex_entry_t last = NULL;
6785 + __pkcs11h_threading_mutex_entry_t entry = NULL;
6786 + PKCS11H_BOOL mutex_locked = FALSE;
6787 +
6788 + if (_pkcs11h_threading_mutexLock (&__s_pkcs11h_threading_mutex_list.mutex) == CKR_OK) {
6789 + mutex_locked = TRUE;
6790 + }
6791 +
6792 + entry = __s_pkcs11h_threading_mutex_list.head;
6793 + while (
6794 + entry != NULL &&
6795 + entry->p_mutex != mutex
6796 + ) {
6797 + last = entry;
6798 + entry = entry->next;
6799 + }
6800 +
6801 + if (entry != NULL) {
6802 + if (last == NULL) {
6803 + __s_pkcs11h_threading_mutex_list.head = entry->next;
6804 + }
6805 + else {
6806 + last->next = entry->next;
6807 + }
6808 + _pkcs11h_mem_free ((void *)&entry);
6809 + }
6810 +
6811 + pthread_mutex_destroy (mutex);
6812 +
6813 + if (mutex_locked) {
6814 + _pkcs11h_threading_mutexRelease (&__s_pkcs11h_threading_mutex_list.mutex);
6815 + mutex_locked = FALSE;
6816 + }
6817 + }
6818 +#endif
6819 + return CKR_OK;
6820 +}
6821 +
6822 +#if !defined(WIN32)
6823 +/*
6824 + * This function is required in order
6825 + * to lock all mutexes before fork is called,
6826 + * and to avoid dedlocks.
6827 + * The loop is required because there is no
6828 + * way to lock all mutex in one system call...
6829 + */
6830 +static
6831 +void
6832 +__pkcs1h_threading_mutexLockAll () {
6833 + __pkcs11h_threading_mutex_entry_t entry = NULL;
6834 + PKCS11H_BOOL mutex_locked = FALSE;
6835 + PKCS11H_BOOL all_mutexes_locked = FALSE;
6836 +
6837 + if (_pkcs11h_threading_mutexLock (&__s_pkcs11h_threading_mutex_list.mutex) == CKR_OK) {
6838 + mutex_locked = TRUE;
6839 + }
6840 +
6841 + for (
6842 + entry = __s_pkcs11h_threading_mutex_list.head;
6843 + entry != NULL;
6844 + entry = entry->next
6845 + ) {
6846 + entry->locked = FALSE;
6847 + }
6848 +
6849 + while (!all_mutexes_locked) {
6850 + PKCS11H_BOOL ok = TRUE;
6851 +
6852 + for (
6853 + entry = __s_pkcs11h_threading_mutex_list.head;
6854 + entry != NULL && ok;
6855 + entry = entry->next
6856 + ) {
6857 + if (!pthread_mutex_trylock (entry->p_mutex)) {
6858 + entry->locked = TRUE;
6859 + }
6860 + else {
6861 + ok = FALSE;
6862 + }
6863 + }
6864 +
6865 + if (!ok) {
6866 + for (
6867 + entry = __s_pkcs11h_threading_mutex_list.head;
6868 + entry != NULL;
6869 + entry = entry->next
6870 + ) {
6871 + if (entry->locked == TRUE) {
6872 + pthread_mutex_unlock (entry->p_mutex);
6873 + entry->locked = FALSE;
6874 + }
6875 + }
6876 +
6877 + _pkcs11h_threading_mutexRelease (&__s_pkcs11h_threading_mutex_list.mutex);
6878 + _pkcs11h_threading_sleep (1000);
6879 + _pkcs11h_threading_mutexLock (&__s_pkcs11h_threading_mutex_list.mutex);
6880 + }
6881 + else {
6882 + all_mutexes_locked = TRUE;
6883 + }
6884 + }
6885 +
6886 + if (mutex_locked) {
6887 + _pkcs11h_threading_mutexRelease (&__s_pkcs11h_threading_mutex_list.mutex);
6888 + mutex_locked = FALSE;
6889 + }
6890 +}
6891 +
6892 +static
6893 +void
6894 +__pkcs1h_threading_mutexReleaseAll () {
6895 + __pkcs11h_threading_mutex_entry_t entry = NULL;
6896 + PKCS11H_BOOL mutex_locked = FALSE;
6897 +
6898 + if (_pkcs11h_threading_mutexLock (&__s_pkcs11h_threading_mutex_list.mutex) == CKR_OK) {
6899 + mutex_locked = TRUE;
6900 + }
6901 +
6902 + for (
6903 + entry = __s_pkcs11h_threading_mutex_list.head;
6904 + entry != NULL;
6905 + entry = entry->next
6906 + ) {
6907 + pthread_mutex_unlock (entry->p_mutex);
6908 + entry->locked = FALSE;
6909 + }
6910 +
6911 + if (mutex_locked) {
6912 + _pkcs11h_threading_mutexRelease (&__s_pkcs11h_threading_mutex_list.mutex);
6913 + mutex_locked = FALSE;
6914 + }
6915 +}
6916 +#endif
6917 +
6918 +CK_RV
6919 +_pkcs11h_threading_condSignal (
6920 + IN OUT pkcs11h_cond_t *const cond
6921 +) {
6922 + CK_RV rv = CKR_OK;
6923 +#if defined(WIN32)
6924 + if (
6925 + rv == CKR_OK &&
6926 + !SetEvent (*cond)
6927 + ) {
6928 + rv = CKR_FUNCTION_FAILED;
6929 + }
6930 +#else
6931 + if (
6932 + rv == CKR_OK &&
6933 + (
6934 + pthread_mutex_lock (&cond->mut) ||
6935 + pthread_cond_signal (&cond->cond) ||
6936 + pthread_mutex_unlock (&cond->mut)
6937 + )
6938 + ) {
6939 + rv = CKR_FUNCTION_FAILED;
6940 + }
6941 +#endif
6942 +
6943 + return rv;
6944 +}
6945 +
6946 +static
6947 +CK_RV
6948 +_pkcs11h_threading_condInit (
6949 + OUT pkcs11h_cond_t * const cond
6950 +) {
6951 + CK_RV rv = CKR_OK;
6952 +#if defined(WIN32)
6953 + if (
6954 + rv == CKR_OK &&
6955 + (*cond = CreateEvent (NULL, FALSE, FALSE, NULL)) == NULL
6956 + ) {
6957 + rv = CKR_FUNCTION_FAILED;
6958 + }
6959 +#else
6960 + if (
6961 + rv == CKR_OK &&
6962 + (
6963 + pthread_mutex_init (&cond->mut, NULL) ||
6964 + pthread_cond_init (&cond->cond, NULL) ||
6965 + pthread_mutex_lock (&cond->mut)
6966 + )
6967 + ) {
6968 + rv = CKR_FUNCTION_FAILED;
6969 + }
6970 +#endif
6971 + return rv;
6972 +}
6973 +
6974 +static
6975 +CK_RV
6976 +_pkcs11h_threading_condWait (
6977 + IN OUT pkcs11h_cond_t *const cond,
6978 + IN const unsigned milli
6979 +) {
6980 + CK_RV rv = CKR_OK;
6981 +
6982 +#if defined(WIN32)
6983 + DWORD dwMilli;
6984 +
6985 + if (milli == PKCS11H_COND_INFINITE) {
6986 + dwMilli = INFINITE;
6987 + }
6988 + else {
6989 + dwMilli = milli;
6990 + }
6991 +
6992 + if (
6993 + rv == CKR_OK &&
6994 + WaitForSingleObject (*cond, dwMilli) == WAIT_FAILED
6995 + ) {
6996 + rv = CKR_FUNCTION_FAILED;
6997 + }
6998 +#else
6999 + if (milli == PKCS11H_COND_INFINITE) {
7000 + if (
7001 + rv == CKR_OK &&
7002 + pthread_cond_wait (&cond->cond, &cond->mut)
7003 + ) {
7004 + rv = CKR_FUNCTION_FAILED;
7005 + }
7006 + }
7007 + else {
7008 + struct timeval now;
7009 + struct timespec timeout;
7010 +
7011 + if (
7012 + rv == CKR_OK &&
7013 + gettimeofday (&now, NULL)
7014 + ) {
7015 + rv = CKR_FUNCTION_FAILED;
7016 + }
7017 +
7018 + if (rv == CKR_OK) {
7019 + timeout.tv_sec = now.tv_sec + milli/1000;
7020 + timeout.tv_nsec = now.tv_usec*1000 + milli%1000;
7021 + }
7022 +
7023 + if (
7024 + rv == CKR_OK &&
7025 + pthread_cond_timedwait (&cond->cond, &cond->mut, &timeout)
7026 + ) {
7027 + rv = CKR_FUNCTION_FAILED;
7028 + }
7029 + }
7030 +#endif
7031 + return rv;
7032 +}
7033 +
7034 +static
7035 +CK_RV
7036 +_pkcs11h_threading_condFree (
7037 + IN OUT pkcs11h_cond_t *const cond
7038 +) {
7039 +#if defined(WIN32)
7040 + CloseHandle (*cond);
7041 + *cond = NULL;
7042 +#else
7043 + pthread_mutex_unlock (&cond->mut);
7044 +#endif
7045 + return CKR_OK;
7046 +}
7047 +
7048 +#if defined(WIN32)
7049 +static
7050 +unsigned
7051 +__stdcall
7052 +__pkcs11h_thread_start (void *p) {
7053 + __pkcs11h_thread_data_t *_data = (__pkcs11h_thread_data_t *)p;
7054 + unsigned ret;
7055 +
7056 + ret = (unsigned)_data->start (_data->data);
7057 +
7058 + _pkcs11h_mem_free ((void *)&_data);
7059 +
7060 + return ret;
7061 +}
7062 +#else
7063 +static
7064 +void *
7065 +__pkcs11h_thread_start (void *p) {
7066 + __pkcs11h_thread_data_t *_data = (__pkcs11h_thread_data_t *)p;
7067 + void *ret;
7068 + int i;
7069 +
7070 + /*
7071 + * Ignore any signal in
7072 + * this thread
7073 + */
7074 + for (i=1;i<16;i++) {
7075 + signal (i, SIG_IGN);
7076 + }
7077 +
7078 + ret = _data->start (_data->data);
7079 +
7080 + _pkcs11h_mem_free ((void *)&_data);
7081 +
7082 + return ret;
7083 +}
7084 +#endif
7085 +
7086 +static
7087 +CK_RV
7088 +_pkcs11h_threading_threadStart (
7089 + OUT pkcs11h_thread_t * const thread,
7090 + IN pkcs11h_thread_start_t const start,
7091 + IN void * data
7092 +) {
7093 + __pkcs11h_thread_data_t *_data = NULL;
7094 + CK_RV rv = CKR_OK;
7095 +
7096 + if (rv == CKR_OK) {
7097 + rv = _pkcs11h_mem_malloc (
7098 + (void *)&_data,
7099 + sizeof (__pkcs11h_thread_data_t)
7100 + );
7101 + }
7102 +
7103 + if (rv == CKR_OK) {
7104 + _data->start = start;
7105 + _data->data = data;
7106 + }
7107 +
7108 +#if defined(WIN32)
7109 + {
7110 + unsigned tmp;
7111 +
7112 + if (
7113 + rv == CKR_OK &&
7114 + (*thread = (HANDLE)_beginthreadex (
7115 + NULL,
7116 + 0,
7117 + __pkcs11h_thread_start,
7118 + _data,
7119 + 0,
7120 + &tmp
7121 + )) == NULL
7122 + ) {
7123 + rv = CKR_FUNCTION_FAILED;
7124 + }
7125 + }
7126 +#else
7127 + if (
7128 + rv == CKR_OK &&
7129 + pthread_create (thread, NULL, __pkcs11h_thread_start, _data)
7130 + ) {
7131 + rv = CKR_FUNCTION_FAILED;
7132 + }
7133 +#endif
7134 + return rv;
7135 +}
7136 +
7137 +static
7138 +CK_RV
7139 +_pkcs11h_threading_threadJoin (
7140 + IN pkcs11h_thread_t * const thread
7141 +) {
7142 +#if defined(WIN32)
7143 + WaitForSingleObject (*thread, INFINITE);
7144 + CloseHandle (*thread);
7145 + *thread = NULL;
7146 +#else
7147 + pthread_join (*thread, NULL);
7148 + *thread = 0l;
7149 +#endif
7150 + return CKR_OK;
7151 +}
7152 +
7153 +#endif /* ENABLE_PKCS11H_THREADING */
7154 +
7155 +/*======================================================================*
7156 + * COMMON INTERNAL INTERFACE
7157 + *======================================================================*/
7158 +
7159 +static
7160 +void
7161 +_pkcs11h_util_fixupFixedString (
7162 + OUT char * const target, /* MUST BE >= length+1 */
7163 + IN const char * const source,
7164 + IN const size_t length /* FIXED STRING LENGTH */
7165 +) {
7166 + char *p;
7167 +
7168 + PKCS11H_ASSERT (source!=NULL);
7169 + PKCS11H_ASSERT (target!=NULL);
7170 +
7171 + p = target+length;
7172 + memmove (target, source, length);
7173 + *p = '\0';
7174 + p--;
7175 + while (p >= target && *p == ' ') {
7176 + *p = '\0';
7177 + p--;
7178 + }
7179 +}
7180 +
7181 +static
7182 +CK_RV
7183 +_pkcs11h_util_hexToBinary (
7184 + OUT unsigned char * const target,
7185 + IN const char * const source,
7186 + IN OUT size_t * const p_target_size
7187 +) {
7188 + size_t target_max_size;
7189 + const char *p;
7190 + char buf[3] = {'\0', '\0', '\0'};
7191 + int i = 0;
7192 +
7193 + PKCS11H_ASSERT (source!=NULL);
7194 + PKCS11H_ASSERT (target!=NULL);
7195 + PKCS11H_ASSERT (p_target_size!=NULL);
7196 +
7197 + target_max_size = *p_target_size;
7198 + p = source;
7199 + *p_target_size = 0;
7200 +
7201 + while (*p != '\x0' && *p_target_size < target_max_size) {
7202 + if (isxdigit ((unsigned char)*p)) {
7203 + buf[i%2] = *p;
7204 +
7205 + if ((i%2) == 1) {
7206 + unsigned v;
7207 + if (sscanf (buf, "%x", &v) != 1) {
7208 + v = 0;
7209 + }
7210 + target[*p_target_size] = v & 0xff;
7211 + (*p_target_size)++;
7212 + }
7213 +
7214 + i++;
7215 + }
7216 + p++;
7217 + }
7218 +
7219 + if (*p != '\x0') {
7220 + return CKR_ATTRIBUTE_VALUE_INVALID;
7221 + }
7222 + else {
7223 + return CKR_OK;
7224 + }
7225 +}
7226 +
7227 +static
7228 +CK_RV
7229 +_pkcs11h_util_binaryToHex (
7230 + OUT char * const target,
7231 + IN const size_t target_size,
7232 + IN const unsigned char * const source,
7233 + IN const size_t source_size
7234 +) {
7235 + static const char *x = "0123456789ABCDEF";
7236 + size_t i;
7237 +
7238 + PKCS11H_ASSERT (target!=NULL);
7239 + PKCS11H_ASSERT (source!=NULL);
7240 +
7241 + if (target_size < source_size * 2 + 1) {
7242 + return CKR_ATTRIBUTE_VALUE_INVALID;
7243 + }
7244 +
7245 + for (i=0;i<source_size;i++) {
7246 + target[i*2] = x[(source[i]&0xf0)>>4];
7247 + target[i*2+1] = x[(source[i]&0x0f)>>0];
7248 + }
7249 + target[source_size*2] = '\x0';
7250 +
7251 + return CKR_OK;
7252 +}
7253 +
7254 +CK_RV
7255 +_pkcs11h_util_escapeString (
7256 + IN OUT char * const target,
7257 + IN const char * const source,
7258 + IN size_t * const max,
7259 + IN const char * const invalid_chars
7260 +) {
7261 + static const char *x = "0123456789ABCDEF";
7262 + CK_RV rv = CKR_OK;
7263 + const char *s = source;
7264 + char *t = target;
7265 + size_t n = 0;
7266 +
7267 + /*PKCS11H_ASSERT (target!=NULL); Not required*/
7268 + PKCS11H_ASSERT (source!=NULL);
7269 + PKCS11H_ASSERT (max!=NULL);
7270 +
7271 + while (rv == CKR_OK && *s != '\x0') {
7272 +
7273 + if (*s == '\\' || strchr (invalid_chars, *s) || !isgraph (*s)) {
7274 + if (t != NULL) {
7275 + if (n+4 > *max) {
7276 + rv = CKR_ATTRIBUTE_VALUE_INVALID;
7277 + }
7278 + else {
7279 + t[0] = '\\';
7280 + t[1] = 'x';
7281 + t[2] = x[(*s&0xf0)>>4];
7282 + t[3] = x[(*s&0x0f)>>0];
7283 + t+=4;
7284 + }
7285 + }
7286 + n+=4;
7287 + }
7288 + else {
7289 + if (t != NULL) {
7290 + if (n+1 > *max) {
7291 + rv = CKR_ATTRIBUTE_VALUE_INVALID;
7292 + }
7293 + else {
7294 + *t = *s;
7295 + t++;
7296 + }
7297 + }
7298 + n+=1;
7299 + }
7300 +
7301 + s++;
7302 + }
7303 +
7304 + if (t != NULL) {
7305 + if (n+1 > *max) {
7306 + rv = CKR_ATTRIBUTE_VALUE_INVALID;
7307 + }
7308 + else {
7309 + *t = '\x0';
7310 + t++;
7311 + }
7312 + }
7313 + n++;
7314 +
7315 + *max = n;
7316 +
7317 + return rv;
7318 +}
7319 +
7320 +static
7321 +CK_RV
7322 +_pkcs11h_util_unescapeString (
7323 + IN OUT char * const target,
7324 + IN const char * const source,
7325 + IN size_t * const max
7326 +) {
7327 + CK_RV rv = CKR_OK;
7328 + const char *s = source;
7329 + char *t = target;
7330 + size_t n = 0;
7331 +
7332 + /*PKCS11H_ASSERT (target!=NULL); Not required*/
7333 + PKCS11H_ASSERT (source!=NULL);
7334 + PKCS11H_ASSERT (max!=NULL);
7335 +
7336 + while (rv == CKR_OK && *s != '\x0') {
7337 + if (*s == '\\') {
7338 + if (t != NULL) {
7339 + if (n+1 > *max) {
7340 + rv = CKR_ATTRIBUTE_VALUE_INVALID;
7341 + }
7342 + else {
7343 + char b[3];
7344 + unsigned u;
7345 + b[0] = s[2];
7346 + b[1] = s[3];
7347 + b[2] = '\x0';
7348 + sscanf (b, "%08x", &u);
7349 + *t = u&0xff;
7350 + t++;
7351 + }
7352 + }
7353 + s+=4;
7354 + }
7355 + else {
7356 + if (t != NULL) {
7357 + if (n+1 > *max) {
7358 + rv = CKR_ATTRIBUTE_VALUE_INVALID;
7359 + }
7360 + else {
7361 + *t = *s;
7362 + t++;
7363 + }
7364 + }
7365 + s++;
7366 + }
7367 +
7368 + n+=1;
7369 + }
7370 +
7371 + if (t != NULL) {
7372 + if (n+1 > *max) {
7373 + rv = CKR_ATTRIBUTE_VALUE_INVALID;
7374 + }
7375 + else {
7376 + *t = '\x0';
7377 + t++;
7378 + }
7379 + }
7380 + n++;
7381 +
7382 + *max = n;
7383 +
7384 + return rv;
7385 +}
7386 +
7387 +static
7388 +void
7389 +_pkcs11h_log (
7390 + IN const unsigned flags,
7391 + IN const char * const format,
7392 + IN ...
7393 +) {
7394 + va_list args;
7395 +
7396 + PKCS11H_ASSERT (format!=NULL);
7397 +
7398 + va_start (args, format);
7399 +
7400 + if (
7401 + s_pkcs11h_data != NULL &&
7402 + s_pkcs11h_data->initialized
7403 + ) {
7404 + if (PKCS11H_MSG_LEVEL_TEST (flags)) {
7405 + if (s_pkcs11h_data->hooks.log == NULL) {
7406 + _pkcs11h_hooks_default_log (
7407 + NULL,
7408 + flags,
7409 + format,
7410 + args
7411 + );
7412 + }
7413 + else {
7414 + s_pkcs11h_data->hooks.log (
7415 + s_pkcs11h_data->hooks.log_data,
7416 + flags,
7417 + format,
7418 + args
7419 + );
7420 + }
7421 + }
7422 + }
7423 +
7424 + va_end (args);
7425 +}
7426 +
7427 +static
7428 +CK_RV
7429 +_pkcs11h_session_getSlotList (
7430 + IN const pkcs11h_provider_t provider,
7431 + IN const CK_BBOOL token_present,
7432 + OUT CK_SLOT_ID_PTR * const pSlotList,
7433 + OUT CK_ULONG_PTR pulCount
7434 +) {
7435 + CK_SLOT_ID_PTR _slots = NULL;
7436 + CK_ULONG _slotnum = 0;
7437 + CK_RV rv = CKR_OK;
7438 +
7439 + PKCS11H_ASSERT (provider!=NULL);
7440 + PKCS11H_ASSERT (pSlotList!=NULL);
7441 + PKCS11H_ASSERT (pulCount!=NULL);
7442 +
7443 + PKCS11H_DEBUG (
7444 + PKCS11H_LOG_DEBUG2,
7445 + "PKCS#11: _pkcs11h_session_getSlotList entry provider=%p, token_present=%d, pSlotList=%p, pulCount=%p",
7446 + (void *)provider,
7447 + token_present,
7448 + (void *)pSlotList,
7449 + (void *)pulCount
7450 + );
7451 +
7452 + *pSlotList = NULL;
7453 + *pulCount = 0;
7454 +
7455 + if (
7456 + rv == CKR_OK &&
7457 + !provider->enabled
7458 + ) {
7459 + rv = CKR_CRYPTOKI_NOT_INITIALIZED;
7460 + }
7461 +
7462 + if (rv == CKR_OK) {
7463 + rv = provider->f->C_GetSlotList (
7464 + token_present,
7465 + NULL_PTR,
7466 + &_slotnum
7467 + );
7468 + }
7469 +
7470 + if (rv == CKR_OK && _slotnum > 0) {
7471 + rv = _pkcs11h_mem_malloc ((void *)&_slots, _slotnum * sizeof (CK_SLOT_ID));
7472 + }
7473 +
7474 + if (rv == CKR_OK && _slotnum > 0) {
7475 + rv = provider->f->C_GetSlotList (
7476 + token_present,
7477 + _slots,
7478 + &_slotnum
7479 + );
7480 + }
7481 +
7482 + if (rv == CKR_OK) {
7483 + *pSlotList = _slots;
7484 + _slots = NULL;
7485 + *pulCount = _slotnum;
7486 + }
7487 +
7488 + if (_slots != NULL) {
7489 + _pkcs11h_mem_free ((void *)&_slots);
7490 + }
7491 +
7492 + PKCS11H_DEBUG (
7493 + PKCS11H_LOG_DEBUG2,
7494 + "PKCS#11: _pkcs11h_session_getSlotList return rv=%ld-'%s' *pulCount=%ld",
7495 + rv,
7496 + pkcs11h_getMessage (rv),
7497 + *pulCount
7498 + );
7499 +
7500 + return rv;
7501 +}
7502 +
7503 +static
7504 +CK_RV
7505 +_pkcs11h_session_getObjectAttributes (
7506 + IN const pkcs11h_session_t session,
7507 + IN const CK_OBJECT_HANDLE object,
7508 + IN OUT const CK_ATTRIBUTE_PTR attrs,
7509 + IN const unsigned count
7510 +) {
7511 + /*
7512 + * THREADING:
7513 + * session->mutex must be locked
7514 + */
7515 + CK_RV rv = CKR_OK;
7516 +
7517 + PKCS11H_ASSERT (session!=NULL);
7518 + PKCS11H_ASSERT (attrs!=NULL);
7519 +
7520 + PKCS11H_DEBUG (
7521 + PKCS11H_LOG_DEBUG2,
7522 + "PKCS#11: _pkcs11h_session_getObjectAttributes entry session=%p, object=%ld, attrs=%p, count=%u",
7523 + (void *)session,
7524 + object,
7525 + (void *)attrs,
7526 + count
7527 + );
7528 +
7529 + if (
7530 + rv == CKR_OK &&
7531 + (rv = session->provider->f->C_GetAttributeValue (
7532 + session->session_handle,
7533 + object,
7534 + attrs,
7535 + count
7536 + )) == CKR_OK
7537 + ) {
7538 + unsigned i;
7539 + for (i=0;rv == CKR_OK && i<count;i++) {
7540 + if (attrs[i].ulValueLen == (CK_ULONG)-1) {
7541 + rv = CKR_ATTRIBUTE_VALUE_INVALID;
7542 + }
7543 + else if (attrs[i].ulValueLen == 0) {
7544 + attrs[i].pValue = NULL;
7545 + }
7546 + else {
7547 + rv = _pkcs11h_mem_malloc (
7548 + (void *)&attrs[i].pValue,
7549 + attrs[i].ulValueLen
7550 + );
7551 + }
7552 + }
7553 + }
7554 +
7555 + if (rv == CKR_OK) {
7556 + rv = session->provider->f->C_GetAttributeValue (
7557 + session->session_handle,
7558 + object,
7559 + attrs,
7560 + count
7561 + );
7562 + }
7563 +
7564 + PKCS11H_DEBUG (
7565 + PKCS11H_LOG_DEBUG2,
7566 + "PKCS#11: _pkcs11h_session_getObjectAttributes return rv=%ld-'%s'",
7567 + rv,
7568 + pkcs11h_getMessage (rv)
7569 + );
7570 +
7571 + return rv;
7572 +}
7573 +
7574 +static
7575 +CK_RV
7576 +_pkcs11h_session_freeObjectAttributes (
7577 + IN OUT const CK_ATTRIBUTE_PTR attrs,
7578 + IN const unsigned count
7579 +) {
7580 + unsigned i;
7581 +
7582 + CK_RV rv = CKR_OK;
7583 +
7584 + PKCS11H_ASSERT (attrs!=NULL);
7585 +
7586 + PKCS11H_DEBUG (
7587 + PKCS11H_LOG_DEBUG2,
7588 + "PKCS#11: _pkcs11h_session_freeObjectAttributes entry attrs=%p, count=%u",
7589 + (void *)attrs,
7590 + count
7591 + );
7592 +
7593 + for (i=0;i<count;i++) {
7594 + if (attrs[i].pValue != NULL) {
7595 + _pkcs11h_mem_free ((void *)&attrs[i].pValue);
7596 + attrs[i].pValue = NULL;
7597 + }
7598 + }
7599 +
7600 + PKCS11H_DEBUG (
7601 + PKCS11H_LOG_DEBUG2,
7602 + "PKCS#11: _pkcs11h_session_freeObjectAttributes return rv=%ld-'%s'",
7603 + rv,
7604 + pkcs11h_getMessage (rv)
7605 + );
7606 +
7607 + return rv;
7608 +}
7609 +
7610 +static
7611 +CK_RV
7612 +_pkcs11h_session_findObjects (
7613 + IN const pkcs11h_session_t session,
7614 + IN const CK_ATTRIBUTE * const filter,
7615 + IN const CK_ULONG filter_attrs,
7616 + OUT CK_OBJECT_HANDLE **const p_objects,
7617 + OUT CK_ULONG *p_objects_found
7618 +) {
7619 + /*
7620 + * THREADING:
7621 + * session->mutex must be locked
7622 + */
7623 + PKCS11H_BOOL should_FindObjectsFinal = FALSE;
7624 +
7625 + CK_OBJECT_HANDLE *objects = NULL;
7626 + CK_ULONG objects_size = 0;
7627 + CK_OBJECT_HANDLE objects_buffer[100];
7628 + CK_ULONG objects_found;
7629 + CK_OBJECT_HANDLE oLast = PKCS11H_INVALID_OBJECT_HANDLE;
7630 + CK_RV rv = CKR_OK;
7631 +
7632 + PKCS11H_ASSERT (session!=NULL);
7633 + PKCS11H_ASSERT (!(filter==NULL && filter_attrs!=0) || filter!=NULL);
7634 + PKCS11H_ASSERT (p_objects!=NULL);
7635 + PKCS11H_ASSERT (p_objects_found!=NULL);
7636 +
7637 + PKCS11H_DEBUG (
7638 + PKCS11H_LOG_DEBUG2,
7639 + "PKCS#11: _pkcs11h_session_findObjects entry session=%p, filter=%p, filter_attrs=%ld, p_objects=%p, p_objects_found=%p",
7640 + (void *)session,
7641 + (void *)filter,
7642 + filter_attrs,
7643 + (void *)p_objects,
7644 + (void *)p_objects_found
7645 + );
7646 +
7647 + *p_objects = NULL;
7648 + *p_objects_found = 0;
7649 +
7650 + if (
7651 + rv == CKR_OK &&
7652 + (rv = session->provider->f->C_FindObjectsInit (
7653 + session->session_handle,
7654 + (CK_ATTRIBUTE *)filter,
7655 + filter_attrs
7656 + )) == CKR_OK
7657 + ) {
7658 + should_FindObjectsFinal = TRUE;
7659 + }
7660 +
7661 + while (
7662 + rv == CKR_OK &&
7663 + (rv = session->provider->f->C_FindObjects (
7664 + session->session_handle,
7665 + objects_buffer,
7666 + sizeof (objects_buffer) / sizeof (CK_OBJECT_HANDLE),
7667 + &objects_found
7668 + )) == CKR_OK &&
7669 + objects_found > 0
7670 + ) {
7671 + CK_OBJECT_HANDLE *temp = NULL;
7672 +
7673 + /*
7674 + * Begin workaround
7675 + *
7676 + * Workaround iKey bug
7677 + * It returns the same objects over and over
7678 + */
7679 + if (oLast == objects_buffer[0]) {
7680 + PKCS11H_LOG (
7681 + PKCS11H_LOG_WARN,
7682 + "PKCS#11: Bad PKCS#11 C_FindObjects implementation detected, workaround applied"
7683 + );
7684 + break;
7685 + }
7686 + oLast = objects_buffer[0];
7687 + /* End workaround */
7688 +
7689 + if (
7690 + (rv = _pkcs11h_mem_malloc (
7691 + (void *)&temp,
7692 + (objects_size+objects_found) * sizeof (CK_OBJECT_HANDLE)
7693 + )) == CKR_OK
7694 + ) {
7695 + if (objects != NULL) {
7696 + memmove (
7697 + temp,
7698 + objects,
7699 + objects_size * sizeof (CK_OBJECT_HANDLE)
7700 + );
7701 + }
7702 + memmove (
7703 + temp + objects_size,
7704 + objects_buffer,
7705 + objects_found * sizeof (CK_OBJECT_HANDLE)
7706 + );
7707 + }
7708 +
7709 + if (objects != NULL) {
7710 + _pkcs11h_mem_free ((void *)&objects);
7711 + objects = NULL;
7712 + }
7713 +
7714 + if (rv == CKR_OK) {
7715 + objects = temp;
7716 + objects_size += objects_found;
7717 + temp = NULL;
7718 + }
7719 +
7720 + if (temp != NULL) {
7721 + _pkcs11h_mem_free ((void *)&temp);
7722 + temp = NULL;
7723 + }
7724 + }
7725 +
7726 + if (should_FindObjectsFinal) {
7727 + session->provider->f->C_FindObjectsFinal (
7728 + session->session_handle
7729 + );
7730 + should_FindObjectsFinal = FALSE;
7731 + }
7732 +
7733 + if (rv == CKR_OK) {
7734 + *p_objects = objects;
7735 + *p_objects_found = objects_size;
7736 + objects = NULL;
7737 + objects_size = 0;
7738 + }
7739 +
7740 + if (objects != NULL) {
7741 + _pkcs11h_mem_free ((void *)&objects);
7742 + objects = NULL;
7743 + objects_size = 0;
7744 + }
7745 +
7746 + PKCS11H_DEBUG (
7747 + PKCS11H_LOG_DEBUG2,
7748 + "PKCS#11: _pkcs11h_session_findObjects return rv=%ld-'%s', *p_objects_found=%ld",
7749 + rv,
7750 + pkcs11h_getMessage (rv),
7751 + *p_objects_found
7752 + );
7753 +
7754 + return rv;
7755 +}
7756 +
7757 +static
7758 +CK_RV
7759 +_pkcs11h_token_getTokenId (
7760 + IN const CK_TOKEN_INFO_PTR info,
7761 + OUT pkcs11h_token_id_t * const p_token_id
7762 +) {
7763 + pkcs11h_token_id_t token_id;
7764 + CK_RV rv = CKR_OK;
7765 +
7766 + PKCS11H_ASSERT (info!=NULL);
7767 + PKCS11H_ASSERT (p_token_id!=NULL);
7768 +
7769 + PKCS11H_DEBUG (
7770 + PKCS11H_LOG_DEBUG2,
7771 + "PKCS#11: _pkcs11h_token_getTokenId entry p_token_id=%p",
7772 + (void *)p_token_id
7773 + );
7774 +
7775 + *p_token_id = NULL;
7776 +
7777 + if (
7778 + rv == CKR_OK &&
7779 + (rv = _pkcs11h_token_newTokenId (&token_id)) == CKR_OK
7780 + ) {
7781 + _pkcs11h_util_fixupFixedString (
7782 + token_id->label,
7783 + (char *)info->label,
7784 + sizeof (info->label)
7785 + );
7786 + _pkcs11h_util_fixupFixedString (
7787 + token_id->manufacturerID,
7788 + (char *)info->manufacturerID,
7789 + sizeof (info->manufacturerID)
7790 + );
7791 + _pkcs11h_util_fixupFixedString (
7792 + token_id->model,
7793 + (char *)info->model,
7794 + sizeof (info->model)
7795 + );
7796 + _pkcs11h_util_fixupFixedString (
7797 + token_id->serialNumber,
7798 + (char *)info->serialNumber,
7799 + sizeof (info->serialNumber)
7800 + );
7801 + strncpy (
7802 + token_id->display,
7803 + token_id->label,
7804 + sizeof (token_id->display)
7805 + );
7806 + }
7807 +
7808 + if (rv == CKR_OK) {
7809 + *p_token_id = token_id;
7810 + token_id = NULL;
7811 + }
7812 +
7813 + if (token_id != NULL) {
7814 + _pkcs11h_mem_free ((void *)&token_id);
7815 + }
7816 +
7817 + PKCS11H_DEBUG (
7818 + PKCS11H_LOG_DEBUG2,
7819 + "PKCS#11: _pkcs11h_token_getTokenId return rv=%ld-'%s', *p_token_id=%p",
7820 + rv,
7821 + pkcs11h_getMessage (rv),
7822 + (void *)*p_token_id
7823 + );
7824 +
7825 + return rv;
7826 +}
7827 +
7828 +static
7829 +CK_RV
7830 +_pkcs11h_token_newTokenId (
7831 + OUT pkcs11h_token_id_t * const p_token_id
7832 +) {
7833 + CK_RV rv = CKR_OK;
7834 +
7835 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
7836 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
7837 + PKCS11H_ASSERT (p_token_id!=NULL);
7838 +
7839 + PKCS11H_DEBUG (
7840 + PKCS11H_LOG_DEBUG2,
7841 + "PKCS#11: _pkcs11h_token_newTokenId entry p_token_id=%p",
7842 + (void *)p_token_id
7843 + );
7844 +
7845 + *p_token_id = NULL;
7846 +
7847 + if (rv == CKR_OK) {
7848 + rv = _pkcs11h_mem_malloc ((void *)p_token_id, sizeof (struct pkcs11h_token_id_s));
7849 + }
7850 +
7851 + PKCS11H_DEBUG (
7852 + PKCS11H_LOG_DEBUG2,
7853 + "PKCS#11: _pkcs11h_token_newTokenId return rv=%ld-'%s', *p_token_id=%p",
7854 + rv,
7855 + pkcs11h_getMessage (rv),
7856 + (void *)*p_token_id
7857 + );
7858 +
7859 + return rv;
7860 +}
7861 +
7862 +static
7863 +CK_RV
7864 +_pkcs11h_session_getSessionByTokenId (
7865 + IN const pkcs11h_token_id_t token_id,
7866 + OUT pkcs11h_session_t * const p_session
7867 +) {
7868 +#if defined(ENABLE_PKCS11H_THREADING)
7869 + PKCS11H_BOOL mutex_locked = FALSE;
7870 +#endif
7871 + pkcs11h_session_t session = NULL;
7872 + PKCS11H_BOOL is_new_session = FALSE;
7873 + CK_RV rv = CKR_OK;
7874 +
7875 + PKCS11H_ASSERT (token_id!=NULL);
7876 + PKCS11H_ASSERT (p_session!=NULL);
7877 +
7878 + PKCS11H_DEBUG (
7879 + PKCS11H_LOG_DEBUG2,
7880 + "PKCS#11: _pkcs11h_session_getSessionByTokenId entry token_id=%p, p_session=%p",
7881 + (void *)token_id,
7882 + (void *)p_session
7883 + );
7884 +
7885 + *p_session = NULL;
7886 +
7887 +#if defined(ENABLE_PKCS11H_THREADING)
7888 + if (
7889 + rv == CKR_OK &&
7890 + (rv = _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.session)) == CKR_OK
7891 + ) {
7892 + mutex_locked = TRUE;
7893 + }
7894 +#endif
7895 +
7896 + if (rv == CKR_OK) {
7897 + pkcs11h_session_t current_session;
7898 +
7899 + for (
7900 + current_session = s_pkcs11h_data->sessions;
7901 + current_session != NULL && session == NULL;
7902 + current_session = current_session->next
7903 + ) {
7904 + if (
7905 + pkcs11h_token_sameTokenId (
7906 + current_session->token_id,
7907 + token_id
7908 + )
7909 + ) {
7910 + PKCS11H_DEBUG (
7911 + PKCS11H_LOG_DEBUG1,
7912 + "PKCS#11: Using cached session"
7913 + );
7914 + session = current_session;
7915 + session->reference_count++;
7916 + }
7917 + }
7918 + }
7919 +
7920 + if (
7921 + rv == CKR_OK &&
7922 + session == NULL
7923 + ) {
7924 + is_new_session = TRUE;
7925 + }
7926 +
7927 + if (is_new_session) {
7928 + PKCS11H_DEBUG (
7929 + PKCS11H_LOG_DEBUG1,
7930 + "PKCS#11: Creating a new session"
7931 + );
7932 +
7933 + if (
7934 + rv == CKR_OK &&
7935 + (rv = _pkcs11h_mem_malloc ((void *)&session, sizeof (struct pkcs11h_session_s))) == CKR_OK
7936 + ) {
7937 + session->reference_count = 1;
7938 + session->session_handle = PKCS11H_INVALID_SESSION_HANDLE;
7939 +
7940 + session->pin_cache_period = s_pkcs11h_data->pin_cache_period;
7941 +
7942 + }
7943 +
7944 + if (rv == CKR_OK) {
7945 + rv = pkcs11h_token_duplicateTokenId (
7946 + &session->token_id,
7947 + token_id
7948 + );
7949 + }
7950 +
7951 +#if defined(ENABLE_PKCS11H_THREADING)
7952 + if (rv == CKR_OK) {
7953 + rv = _pkcs11h_threading_mutexInit (&session->mutex);
7954 + }
7955 +#endif
7956 +
7957 + if (rv == CKR_OK) {
7958 + session->valid = TRUE;
7959 + session->next = s_pkcs11h_data->sessions;
7960 + s_pkcs11h_data->sessions = session;
7961 + }
7962 + else {
7963 +#if defined(ENABLE_PKCS11H_THREADING)
7964 + _pkcs11h_threading_mutexFree (&session->mutex);
7965 +#endif
7966 + _pkcs11h_mem_free ((void *)&session);
7967 + }
7968 + }
7969 +
7970 + if (rv == CKR_OK) {
7971 + *p_session = session;
7972 + session = NULL;
7973 + }
7974 +
7975 +#if defined(ENABLE_PKCS11H_THREADING)
7976 + if (mutex_locked) {
7977 + _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.session);
7978 + mutex_locked = FALSE;
7979 + }
7980 +#endif
7981 +
7982 + PKCS11H_DEBUG (
7983 + PKCS11H_LOG_DEBUG2,
7984 + "PKCS#11: _pkcs11h_session_getSessionByTokenId return rv=%ld-'%s', *p_session=%p",
7985 + rv,
7986 + pkcs11h_getMessage (rv),
7987 + (void *)*p_session
7988 + );
7989 +
7990 + return rv;
7991 +}
7992 +
7993 +static
7994 +CK_RV
7995 +_pkcs11h_session_release (
7996 + IN const pkcs11h_session_t session
7997 +) {
7998 +#if defined(ENABLE_PKCS11H_THREADING)
7999 + PKCS11H_BOOL mutex_locked = FALSE;
8000 +#endif
8001 + CK_RV rv = CKR_OK;
8002 +
8003 + PKCS11H_ASSERT (session!=NULL);
8004 + PKCS11H_ASSERT (session->reference_count>=0);
8005 +
8006 + PKCS11H_DEBUG (
8007 + PKCS11H_LOG_DEBUG2,
8008 + "PKCS#11: _pkcs11h_session_release entry session=%p",
8009 + (void *)session
8010 + );
8011 +
8012 +#if defined(ENABLE_PKCS11H_THREADING)
8013 + if (
8014 + rv == CKR_OK &&
8015 + (rv = _pkcs11h_threading_mutexLock (&session->mutex)) == CKR_OK
8016 + ) {
8017 + mutex_locked = TRUE;
8018 + }
8019 +#endif
8020 +
8021 + /*
8022 + * Never logout for now
8023 + */
8024 + if (rv == CKR_OK) {
8025 + if (session->reference_count > 0) {
8026 + session->reference_count--;
8027 + }
8028 + }
8029 +
8030 +#if defined(ENABLE_PKCS11H_THREADING)
8031 + if (mutex_locked) {
8032 + _pkcs11h_threading_mutexRelease (&session->mutex);
8033 + mutex_locked = FALSE;
8034 + }
8035 +#endif
8036 +
8037 + PKCS11H_DEBUG (
8038 + PKCS11H_LOG_DEBUG2,
8039 + "PKCS#11: _pkcs11h_session_release return rv=%ld-'%s'",
8040 + rv,
8041 + pkcs11h_getMessage (rv)
8042 + );
8043 +
8044 + return rv;
8045 +}
8046 +
8047 +static
8048 +CK_RV
8049 +_pkcs11h_session_reset (
8050 + IN const pkcs11h_session_t session,
8051 + IN void * const user_data,
8052 + IN const unsigned mask_prompt,
8053 + OUT CK_SLOT_ID * const p_slot
8054 +) {
8055 + PKCS11H_BOOL found = FALSE;
8056 +
8057 + CK_RV rv = CKR_OK;
8058 +
8059 + unsigned nRetry = 0;
8060 +
8061 + PKCS11H_ASSERT (session!=NULL);
8062 + /*PKCS11H_ASSERT (user_data) NOT NEEDED */
8063 + PKCS11H_ASSERT (p_slot!=NULL);
8064 +
8065 + PKCS11H_DEBUG (
8066 + PKCS11H_LOG_DEBUG2,
8067 + "PKCS#11: _pkcs11h_session_reset entry session=%p, user_data=%p, mask_prompt=%08x, p_slot=%p",
8068 + (void *)session,
8069 + user_data,
8070 + mask_prompt,
8071 + (void *)p_slot
8072 + );
8073 +
8074 + *p_slot = PKCS11H_INVALID_SLOT_ID;
8075 +
8076 + while (
8077 + rv == CKR_OK &&
8078 + !found
8079 + ) {
8080 + pkcs11h_provider_t current_provider = NULL;
8081 +
8082 + for (
8083 + current_provider = s_pkcs11h_data->providers;
8084 + (
8085 + rv == CKR_OK &&
8086 + current_provider != NULL &&
8087 + !found
8088 + );
8089 + current_provider = current_provider->next
8090 + ) {
8091 + CK_SLOT_ID_PTR slots = NULL;
8092 + CK_ULONG slotnum;
8093 + CK_SLOT_ID slot_index;
8094 +
8095 + /*
8096 + * Skip all other providers,
8097 + * if one was set in the past
8098 + */
8099 + if (
8100 + session->provider != NULL &&
8101 + session->provider != current_provider
8102 + ) {
8103 + rv = CKR_CANCEL;
8104 + }
8105 +
8106 + if (rv == CKR_OK) {
8107 + rv = _pkcs11h_session_getSlotList (
8108 + current_provider,
8109 + CK_TRUE,
8110 + &slots,
8111 + &slotnum
8112 + );
8113 + }
8114 +
8115 + for (
8116 + slot_index=0;
8117 + (
8118 + slot_index < slotnum &&
8119 + rv == CKR_OK &&
8120 + !found
8121 + );
8122 + slot_index++
8123 + ) {
8124 + pkcs11h_token_id_t token_id = NULL;
8125 + CK_TOKEN_INFO info;
8126 +
8127 + if (rv == CKR_OK) {
8128 + rv = current_provider->f->C_GetTokenInfo (
8129 + slots[slot_index],
8130 + &info
8131 + );
8132 + }
8133 +
8134 + if (
8135 + rv == CKR_OK &&
8136 + (rv = _pkcs11h_token_getTokenId (
8137 + &info,
8138 + &token_id
8139 + )) == CKR_OK &&
8140 + pkcs11h_token_sameTokenId (
8141 + session->token_id,
8142 + token_id
8143 + )
8144 + ) {
8145 + found = TRUE;
8146 + *p_slot = slots[slot_index];
8147 + if (session->provider == NULL) {
8148 + session->provider = current_provider;
8149 + session->allow_protected_auth_supported = (info.flags & CKF_PROTECTED_AUTHENTICATION_PATH) != 0;
8150 + }
8151 + }
8152 +
8153 + if (rv != CKR_OK) {
8154 + PKCS11H_DEBUG (
8155 + PKCS11H_LOG_DEBUG1,
8156 + "PKCS#11: Cannot get token information for provider '%s' slot %ld rv=%ld-'%s'",
8157 + current_provider->manufacturerID,
8158 + slots[slot_index],
8159 + rv,
8160 + pkcs11h_getMessage (rv)
8161 + );
8162 +
8163 + /*
8164 + * Ignore error
8165 + */
8166 + rv = CKR_OK;
8167 + }
8168 +
8169 + if (token_id != NULL) {
8170 + pkcs11h_token_freeTokenId (token_id);
8171 + }
8172 + }
8173 +
8174 + if (rv != CKR_OK) {
8175 + PKCS11H_DEBUG (
8176 + PKCS11H_LOG_DEBUG1,
8177 + "PKCS#11: Cannot get slot list for provider '%s' rv=%ld-'%s'",
8178 + current_provider->manufacturerID,
8179 + rv,
8180 + pkcs11h_getMessage (rv)
8181 + );
8182 +
8183 + /*
8184 + * Ignore error
8185 + */
8186 + rv = CKR_OK;
8187 + }
8188 +
8189 + if (slots != NULL) {
8190 + _pkcs11h_mem_free ((void *)&slots);
8191 + slots = NULL;
8192 + }
8193 + }
8194 +
8195 + if (rv == CKR_OK && !found && (mask_prompt & PKCS11H_PROMPT_MAST_ALLOW_CARD_PROMPT) == 0) {
8196 + rv = CKR_TOKEN_NOT_PRESENT;
8197 + }
8198 +
8199 + if (
8200 + rv == CKR_OK &&
8201 + !found
8202 + ) {
8203 + PKCS11H_DEBUG (
8204 + PKCS11H_LOG_DEBUG1,
8205 + "PKCS#11: Calling token_prompt hook for '%s'",
8206 + session->token_id->display
8207 + );
8208 +
8209 + if (
8210 + !s_pkcs11h_data->hooks.token_prompt (
8211 + s_pkcs11h_data->hooks.token_prompt_data,
8212 + user_data,
8213 + session->token_id,
8214 + nRetry++
8215 + )
8216 + ) {
8217 + rv = CKR_CANCEL;
8218 + }
8219 +
8220 + PKCS11H_DEBUG (
8221 + PKCS11H_LOG_DEBUG1,
8222 + "PKCS#11: token_prompt returned %ld",
8223 + rv
8224 + );
8225 + }
8226 + }
8227 +
8228 + PKCS11H_DEBUG (
8229 + PKCS11H_LOG_DEBUG2,
8230 + "PKCS#11: _pkcs11h_session_reset return rv=%ld-'%s', *p_slot=%ld",
8231 + rv,
8232 + pkcs11h_getMessage (rv),
8233 + *p_slot
8234 + );
8235 +
8236 + return rv;
8237 +}
8238 +
8239 +static
8240 +CK_RV
8241 +_pkcs11h_session_getObjectById (
8242 + IN const pkcs11h_session_t session,
8243 + IN const CK_OBJECT_CLASS class,
8244 + IN const CK_BYTE_PTR id,
8245 + IN const size_t id_size,
8246 + OUT CK_OBJECT_HANDLE * const p_handle
8247 +) {
8248 + /*
8249 + * THREADING:
8250 + * session->mutex must be locked
8251 + */
8252 + CK_ATTRIBUTE filter[] = {
8253 + {CKA_CLASS, (void *)&class, sizeof (class)},
8254 + {CKA_ID, (void *)id, id_size}
8255 + };
8256 + CK_OBJECT_HANDLE *objects = NULL;
8257 + CK_ULONG objects_found = 0;
8258 + CK_RV rv = CKR_OK;
8259 +
8260 + /*PKCS11H_ASSERT (session!=NULL); NOT NEEDED*/
8261 + PKCS11H_ASSERT (id!=NULL);
8262 + PKCS11H_ASSERT (p_handle!=NULL);
8263 +
8264 + PKCS11H_DEBUG (
8265 + PKCS11H_LOG_DEBUG2,
8266 + "PKCS#11: _pkcs11h_session_getObjectById entry session=%p, class=%ld, id=%p, id_size=%u, p_handle=%p",
8267 + (void *)session,
8268 + class,
8269 + id,
8270 + id_size,
8271 + (void *)p_handle
8272 + );
8273 +
8274 + *p_handle = PKCS11H_INVALID_OBJECT_HANDLE;
8275 +
8276 + if (rv == CKR_OK) {
8277 + rv = _pkcs11h_session_validate (session);
8278 + }
8279 +
8280 + if (rv == CKR_OK) {
8281 + rv = _pkcs11h_session_findObjects (
8282 + session,
8283 + filter,
8284 + sizeof (filter) / sizeof (CK_ATTRIBUTE),
8285 + &objects,
8286 + &objects_found
8287 + );
8288 + }
8289 +
8290 + if (
8291 + rv == CKR_OK &&
8292 + objects_found == 0
8293 + ) {
8294 + rv = CKR_FUNCTION_REJECTED;
8295 + }
8296 +
8297 + if (rv == CKR_OK) {
8298 + *p_handle = objects[0];
8299 + }
8300 +
8301 + if (objects != NULL) {
8302 + _pkcs11h_mem_free ((void *)&objects);
8303 + }
8304 +
8305 + PKCS11H_DEBUG (
8306 + PKCS11H_LOG_DEBUG2,
8307 + "PKCS#11: _pkcs11h_session_getObjectById return rv=%ld-'%s', *p_handle=%p",
8308 + rv,
8309 + pkcs11h_getMessage (rv),
8310 + (void *)*p_handle
8311 + );
8312 +
8313 + return rv;
8314 +}
8315 +
8316 +static
8317 +CK_RV
8318 +_pkcs11h_session_validate (
8319 + IN const pkcs11h_session_t session
8320 +) {
8321 + CK_RV rv = CKR_OK;
8322 +
8323 + /*PKCS11H_ASSERT (session!=NULL); NOT NEEDED*/
8324 +
8325 + PKCS11H_DEBUG (
8326 + PKCS11H_LOG_DEBUG2,
8327 + "PKCS#11: _pkcs11h_session_validate entry session=%p",
8328 + (void *)session
8329 + );
8330 +
8331 + if (
8332 + rv == CKR_OK &&
8333 + session == NULL
8334 + ) {
8335 + rv = CKR_SESSION_HANDLE_INVALID;
8336 + }
8337 +
8338 + if (
8339 + rv == CKR_OK &&
8340 + (
8341 + session->provider == NULL ||
8342 + !session->provider->enabled ||
8343 + session->session_handle == PKCS11H_INVALID_SESSION_HANDLE
8344 + )
8345 + ) {
8346 + rv = CKR_SESSION_HANDLE_INVALID;
8347 + }
8348 +
8349 + if (
8350 + rv == CKR_OK &&
8351 + session->pin_expire_time != (time_t)0 &&
8352 + session->pin_expire_time < PKCS11H_TIME (NULL)
8353 + ) {
8354 + PKCS11H_DEBUG (
8355 + PKCS11H_LOG_DEBUG1,
8356 + "PKCS#11: Forcing logout due to pin timeout"
8357 + );
8358 + _pkcs11h_session_logout (session);
8359 + rv = CKR_SESSION_HANDLE_INVALID;
8360 + }
8361 +
8362 + PKCS11H_DEBUG (
8363 + PKCS11H_LOG_DEBUG2,
8364 + "PKCS#11: _pkcs11h_session_validate return rv=%ld-'%s'",
8365 + rv,
8366 + pkcs11h_getMessage (rv)
8367 + );
8368 +
8369 + return rv;
8370 +}
8371 +
8372 +static
8373 +CK_RV
8374 +_pkcs11h_session_touch (
8375 + IN const pkcs11h_session_t session
8376 +) {
8377 + /*
8378 + * THREADING:
8379 + * session->mutex must be locked
8380 + */
8381 + PKCS11H_ASSERT (session!=NULL);
8382 +
8383 + if (session->pin_cache_period == PKCS11H_PIN_CACHE_INFINITE) {
8384 + session->pin_expire_time = 0;
8385 + }
8386 + else {
8387 + session->pin_expire_time = (
8388 + PKCS11H_TIME (NULL) +
8389 + (time_t)session->pin_cache_period
8390 + );
8391 + }
8392 +
8393 + return CKR_OK;
8394 +}
8395 +
8396 +CK_RV
8397 +pkcs11h_token_login (
8398 + IN const pkcs11h_token_id_t token_id,
8399 + IN const PKCS11H_BOOL readonly,
8400 + IN const char * const pin
8401 +) {
8402 +#if defined(ENABLE_PKCS11H_THREADING)
8403 + PKCS11H_BOOL mutex_locked = FALSE;
8404 +#endif
8405 + CK_SLOT_ID slot = PKCS11H_INVALID_SLOT_ID;
8406 + CK_ULONG pin_size = 0;
8407 + CK_RV rv = CKR_OK;
8408 +
8409 + pkcs11h_session_t session = NULL;
8410 +
8411 + PKCS11H_ASSERT (token_id!=NULL);
8412 + /*PKCS11H_ASSERT (pin!=NULL); NOT NEEDED*/
8413 +
8414 + PKCS11H_DEBUG (
8415 + PKCS11H_LOG_DEBUG2,
8416 + "PKCS#11: pkcs11h_token_login entry token_id=%p, readonly=%d\n",
8417 + (void *)token_id,
8418 + readonly ? 1 : 0
8419 + );
8420 +
8421 + if (pin != NULL) {
8422 + pin_size = strlen (pin);
8423 + }
8424 +
8425 + if (rv == CKR_OK) {
8426 + rv = _pkcs11h_session_getSessionByTokenId (
8427 + token_id,
8428 + &session
8429 + );
8430 + }
8431 +
8432 +#if defined(ENABLE_PKCS11H_THREADING)
8433 + if (
8434 + rv == CKR_OK &&
8435 + (rv = _pkcs11h_threading_mutexLock (&session->mutex)) == CKR_OK
8436 + ) {
8437 + mutex_locked = TRUE;
8438 + }
8439 +#endif
8440 +
8441 + if (rv == CKR_OK) {
8442 + rv = _pkcs11h_session_logout (session);
8443 + }
8444 +
8445 + if (rv == CKR_OK) {
8446 + rv = _pkcs11h_session_reset (session, NULL, 0, &slot);
8447 + }
8448 +
8449 + if (rv == CKR_OK) {
8450 + rv = _pkcs11h_session_touch (session);
8451 + }
8452 +
8453 + if (rv == CKR_OK) {
8454 + rv = session->provider->f->C_OpenSession (
8455 + slot,
8456 + (
8457 + CKF_SERIAL_SESSION |
8458 + (readonly ? 0 : CKF_RW_SESSION)
8459 + ),
8460 + NULL_PTR,
8461 + NULL_PTR,
8462 + &session->session_handle
8463 + );
8464 + }
8465 +
8466 + if (
8467 + rv == CKR_OK &&
8468 + (rv = session->provider->f->C_Login (
8469 + session->session_handle,
8470 + CKU_USER,
8471 + (CK_UTF8CHAR_PTR)pin,
8472 + pin_size
8473 + )) != CKR_OK
8474 + ) {
8475 + if (rv == CKR_USER_ALREADY_LOGGED_IN) {
8476 + rv = CKR_OK;
8477 + }
8478 + }
8479 +
8480 +#if defined(ENABLE_PKCS11H_THREADING)
8481 + if (mutex_locked) {
8482 + _pkcs11h_threading_mutexRelease (&session->mutex);
8483 + mutex_locked = FALSE;
8484 + }
8485 +#endif
8486 +
8487 + if (session != NULL) {
8488 + _pkcs11h_session_release (session);
8489 + session = NULL;
8490 + }
8491 +
8492 + PKCS11H_DEBUG (
8493 + PKCS11H_LOG_DEBUG2,
8494 + "PKCS#11: pkcs11h_token_login return rv=%ld-'%s'",
8495 + rv,
8496 + pkcs11h_getMessage (rv)
8497 + );
8498 +
8499 + return rv;
8500 +}
8501 +
8502 +static
8503 +CK_RV
8504 +_pkcs11h_session_login (
8505 + IN const pkcs11h_session_t session,
8506 + IN const PKCS11H_BOOL is_publicOnly,
8507 + IN const PKCS11H_BOOL readonly,
8508 + IN void * const user_data,
8509 + IN const unsigned mask_prompt
8510 +) {
8511 + /*
8512 + * THREADING:
8513 + * session->mutex must be locked
8514 + */
8515 + CK_SLOT_ID slot = PKCS11H_INVALID_SLOT_ID;
8516 + CK_RV rv = CKR_OK;
8517 +
8518 + PKCS11H_ASSERT (session!=NULL);
8519 + /*PKCS11H_ASSERT (user_data) NOT NEEDED */
8520 +
8521 + PKCS11H_DEBUG (
8522 + PKCS11H_LOG_DEBUG2,
8523 + "PKCS#11: _pkcs11h_session_login entry session=%p, is_publicOnly=%d, readonly=%d, user_data=%p, mask_prompt=%08x",
8524 + (void *)session,
8525 + is_publicOnly ? 1 : 0,
8526 + readonly ? 1 : 0,
8527 + user_data,
8528 + mask_prompt
8529 + );
8530 +
8531 + if (rv == CKR_OK) {
8532 + rv = _pkcs11h_session_logout (session);
8533 + }
8534 +
8535 + if (rv == CKR_OK) {
8536 + rv = _pkcs11h_session_reset (session, user_data, mask_prompt, &slot);
8537 + }
8538 +
8539 + if (rv == CKR_OK) {
8540 + rv = session->provider->f->C_OpenSession (
8541 + slot,
8542 + (
8543 + CKF_SERIAL_SESSION |
8544 + (readonly ? 0 : CKF_RW_SESSION)
8545 + ),
8546 + NULL_PTR,
8547 + NULL_PTR,
8548 + &session->session_handle
8549 + );
8550 + }
8551 +
8552 + if (
8553 + rv == CKR_OK &&
8554 + (
8555 + !is_publicOnly ||
8556 + session->provider->cert_is_private
8557 + )
8558 + ) {
8559 + PKCS11H_BOOL login_succeeded = FALSE;
8560 + unsigned nRetryCount = 0;
8561 +
8562 + if ((mask_prompt & PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT) == 0) {
8563 + rv = CKR_USER_NOT_LOGGED_IN;
8564 +
8565 + PKCS11H_DEBUG (
8566 + PKCS11H_LOG_DEBUG1,
8567 + "PKCS#11: Calling pin_prompt hook denied because of prompt mask"
8568 + );
8569 + }
8570 +
8571 + while (
8572 + rv == CKR_OK &&
8573 + !login_succeeded &&
8574 + nRetryCount < s_pkcs11h_data->max_retries
8575 + ) {
8576 + CK_UTF8CHAR_PTR utfPIN = NULL;
8577 + CK_ULONG lPINLength = 0;
8578 + char pin[1024];
8579 +
8580 + if (
8581 + rv == CKR_OK &&
8582 + !(
8583 + s_pkcs11h_data->allow_protected_auth &&
8584 + session->provider->allow_protected_auth &&
8585 + session->allow_protected_auth_supported
8586 + )
8587 + ) {
8588 + PKCS11H_DEBUG (
8589 + PKCS11H_LOG_DEBUG1,
8590 + "PKCS#11: Calling pin_prompt hook for '%s'",
8591 + session->token_id->display
8592 + );
8593 +
8594 + if (
8595 + !s_pkcs11h_data->hooks.pin_prompt (
8596 + s_pkcs11h_data->hooks.pin_prompt_data,
8597 + user_data,
8598 + session->token_id,
8599 + nRetryCount,
8600 + pin,
8601 + sizeof (pin)
8602 + )
8603 + ) {
8604 + rv = CKR_CANCEL;
8605 + }
8606 + else {
8607 + utfPIN = (CK_UTF8CHAR_PTR)pin;
8608 + lPINLength = strlen (pin);
8609 + }
8610 +
8611 + PKCS11H_DEBUG (
8612 + PKCS11H_LOG_DEBUG1,
8613 + "PKCS#11: pin_prompt hook return rv=%ld",
8614 + rv
8615 + );
8616 + }
8617 +
8618 + if (rv == CKR_OK) {
8619 + rv = _pkcs11h_session_touch (session);
8620 + }
8621 +
8622 + if (
8623 + rv == CKR_OK &&
8624 + (rv = session->provider->f->C_Login (
8625 + session->session_handle,
8626 + CKU_USER,
8627 + utfPIN,
8628 + lPINLength
8629 + )) != CKR_OK
8630 + ) {
8631 + if (rv == CKR_USER_ALREADY_LOGGED_IN) {
8632 + rv = CKR_OK;
8633 + }
8634 + }
8635 +
8636 + /*
8637 + * Clean PIN buffer
8638 + */
8639 + memset (pin, 0, sizeof (pin));
8640 +
8641 + if (rv == CKR_OK) {
8642 + login_succeeded = TRUE;
8643 + }
8644 + else if (
8645 + rv == CKR_PIN_INCORRECT ||
8646 + rv == CKR_PIN_INVALID
8647 + ) {
8648 + /*
8649 + * Ignore these errors
8650 + * so retry can be performed
8651 + */
8652 + rv = CKR_OK;
8653 + }
8654 +
8655 + nRetryCount++;
8656 + }
8657 +
8658 + /*
8659 + * Retry limit
8660 + */
8661 + if (!login_succeeded && rv == CKR_OK) {
8662 + rv = CKR_PIN_INCORRECT;
8663 + }
8664 + }
8665 +
8666 + PKCS11H_DEBUG (
8667 + PKCS11H_LOG_DEBUG2,
8668 + "PKCS#11: _pkcs11h_session_login return rv=%ld-'%s'",
8669 + rv,
8670 + pkcs11h_getMessage (rv)
8671 + );
8672 +
8673 + return rv;
8674 +}
8675 +
8676 +static
8677 +CK_RV
8678 +_pkcs11h_session_logout (
8679 + IN const pkcs11h_session_t session
8680 +) {
8681 + /*
8682 + * THREADING:
8683 + * session->mutex must be locked
8684 + */
8685 + /*PKCS11H_ASSERT (session!=NULL); NOT NEEDED*/
8686 +
8687 + PKCS11H_DEBUG (
8688 + PKCS11H_LOG_DEBUG2,
8689 + "PKCS#11: _pkcs11h_session_logout entry session=%p",
8690 + (void *)session
8691 + );
8692 +
8693 + if (
8694 + session != NULL &&
8695 + session->session_handle != PKCS11H_INVALID_SESSION_HANDLE
8696 + ) {
8697 + CK_RV rv = CKR_OK;
8698 +
8699 + if (rv == CKR_OK) {
8700 + if (session->provider != NULL) {
8701 + session->provider->f->C_Logout (session->session_handle);
8702 + session->provider->f->C_CloseSession (session->session_handle);
8703 + }
8704 + session->session_handle = PKCS11H_INVALID_SESSION_HANDLE;
8705 + }
8706 + }
8707 +
8708 + PKCS11H_DEBUG (
8709 + PKCS11H_LOG_DEBUG2,
8710 + "PKCS#11: _pkcs11h_session_logout return"
8711 + );
8712 +
8713 + return CKR_OK;
8714 +}
8715 +
8716 +static
8717 +void
8718 +_pkcs11h_hooks_default_log (
8719 + IN void * const global_data,
8720 + IN const unsigned flags,
8721 + IN const char * const format,
8722 + IN va_list args
8723 +) {
8724 + (void)global_data;
8725 + (void)flags;
8726 + (void)format;
8727 + (void)args;
8728 +}
8729 +
8730 +static
8731 +PKCS11H_BOOL
8732 +_pkcs11h_hooks_default_token_prompt (
8733 + IN void * const global_data,
8734 + IN void * const user_data,
8735 + IN const pkcs11h_token_id_t token,
8736 + IN const unsigned retry
8737 +) {
8738 + /*PKCS11H_ASSERT (global_data) NOT NEEDED */
8739 + /*PKCS11H_ASSERT (user_data) NOT NEEDED */
8740 + PKCS11H_ASSERT (token!=NULL);
8741 +
8742 + (void)global_data;
8743 + (void)user_data;
8744 + (void)retry;
8745 +
8746 + PKCS11H_DEBUG (
8747 + PKCS11H_LOG_DEBUG2,
8748 + "PKCS#11: _pkcs11h_hooks_default_token_prompt global_data=%p, user_data=%p, display='%s'",
8749 + global_data,
8750 + user_data,
8751 + token->display
8752 + );
8753 +
8754 + return FALSE;
8755 +}
8756 +
8757 +static
8758 +PKCS11H_BOOL
8759 +_pkcs11h_hooks_default_pin_prompt (
8760 + IN void * const global_data,
8761 + IN void * const user_data,
8762 + IN const pkcs11h_token_id_t token,
8763 + IN const unsigned retry,
8764 + OUT char * const pin,
8765 + IN const size_t pin_max
8766 +) {
8767 + /*PKCS11H_ASSERT (global_data) NOT NEEDED */
8768 + /*PKCS11H_ASSERT (user_data) NOT NEEDED */
8769 + PKCS11H_ASSERT (token!=NULL);
8770 +
8771 + (void)global_data;
8772 + (void)user_data;
8773 + (void)retry;
8774 + (void)pin;
8775 + (void)pin_max;
8776 +
8777 + PKCS11H_DEBUG (
8778 + PKCS11H_LOG_DEBUG2,
8779 + "PKCS#11: _pkcs11h_hooks_default_pin_prompt global_data=%p, user_data=%p, display='%s'",
8780 + global_data,
8781 + user_data,
8782 + token->display
8783 + );
8784 +
8785 + return FALSE;
8786 +}
8787 +
8788 +#if !defined(WIN32)
8789 +#if defined(ENABLE_PKCS11H_THREADING)
8790 +
8791 +static
8792 +void
8793 +__pkcs11h_threading_atfork_prepare () {
8794 + __pkcs1h_threading_mutexLockAll ();
8795 +}
8796 +static
8797 +void
8798 +__pkcs11h_threading_atfork_parent () {
8799 + __pkcs1h_threading_mutexReleaseAll ();
8800 +}
8801 +static
8802 +void
8803 +__pkcs11h_threading_atfork_child () {
8804 + __pkcs1h_threading_mutexReleaseAll ();
8805 + _pkcs11h_forkFixup ();
8806 +}
8807 +
8808 +#endif /* ENABLE_PKCS11H_THREADING */
8809 +
8810 +static
8811 +CK_RV
8812 +_pkcs11h_forkFixup () {
8813 +#if defined(ENABLE_PKCS11H_THREADING)
8814 + PKCS11H_BOOL mutex_locked = FALSE;
8815 +#endif
8816 + pid_t mypid = getpid ();
8817 +
8818 + PKCS11H_DEBUG (
8819 + PKCS11H_LOG_DEBUG2,
8820 + "PKCS#11: pkcs11h_forkFixup entry pid=%d",
8821 + mypid
8822 + );
8823 +
8824 + if (s_pkcs11h_data != NULL && s_pkcs11h_data->initialized) {
8825 + pkcs11h_provider_t current;
8826 +
8827 +#if defined(ENABLE_PKCS11H_THREADING)
8828 + if (_pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.global) == CKR_OK) {
8829 + mutex_locked = TRUE;
8830 + }
8831 +#endif
8832 +
8833 + for (
8834 + current = s_pkcs11h_data->providers;
8835 + current != NULL;
8836 + current = current->next
8837 + ) {
8838 + if (current->enabled) {
8839 + current->f->C_Initialize (NULL);
8840 + }
8841 +
8842 +#if defined(ENABLE_PKCS11H_SLOTEVENT)
8843 + /*
8844 + * After fork we have no threads...
8845 + * So just initialized.
8846 + */
8847 + if (s_pkcs11h_data->slotevent.initialized) {
8848 + s_pkcs11h_data->slotevent.initialized = FALSE;
8849 + _pkcs11h_slotevent_init ();
8850 + }
8851 +#endif
8852 + }
8853 + }
8854 +
8855 +#if defined(ENABLE_PKCS11H_THREADING)
8856 + if (mutex_locked) {
8857 + _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.global);
8858 + mutex_locked = FALSE;
8859 + }
8860 +#endif
8861 +
8862 + PKCS11H_DEBUG (
8863 + PKCS11H_LOG_DEBUG2,
8864 + "PKCS#11: pkcs11h_forkFixup return"
8865 + );
8866 +
8867 + return CKR_OK;
8868 +}
8869 +
8870 +#endif /* !WIN32 */
8871 +
8872 +#if defined(ENABLE_PKCS11H_TOKEN)
8873 +/*======================================================================*
8874 + * TOKEN INTERFACE
8875 + *======================================================================*/
8876 +
8877 +CK_RV
8878 +pkcs11h_token_ensureAccess (
8879 + IN const pkcs11h_token_id_t token_id,
8880 + IN void * const user_data,
8881 + IN const unsigned mask_prompt
8882 +) {
8883 +#if defined(ENABLE_PKCS11H_THREADING)
8884 + PKCS11H_BOOL mutex_locked = FALSE;
8885 +#endif
8886 + pkcs11h_session_t session = NULL;
8887 + CK_RV rv = CKR_OK;
8888 +
8889 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
8890 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
8891 + PKCS11H_ASSERT (token_id!=NULL);
8892 + /*PKCS11H_ASSERT (user_data) NOT NEEDED */
8893 +
8894 + PKCS11H_DEBUG (
8895 + PKCS11H_LOG_DEBUG2,
8896 + "PKCS#11: pkcs11h_token_ensureAccess entry token_id=%p, user_data=%p, mask_prompt=%08x",
8897 + (void *)token_id,
8898 + user_data,
8899 + mask_prompt
8900 + );
8901 +
8902 + if (rv == CKR_OK) {
8903 + rv = _pkcs11h_session_getSessionByTokenId (
8904 + token_id,
8905 + &session
8906 + );
8907 + }
8908 +
8909 +#if defined(ENABLE_PKCS11H_THREADING)
8910 + if (
8911 + rv == CKR_OK &&
8912 + (rv = _pkcs11h_threading_mutexLock (&session->mutex)) == CKR_OK
8913 + ) {
8914 + mutex_locked = TRUE;
8915 + }
8916 +#endif
8917 +
8918 + if (rv == CKR_OK) {
8919 + CK_SLOT_ID slot;
8920 +
8921 + rv = _pkcs11h_session_reset (
8922 + session,
8923 + user_data,
8924 + mask_prompt,
8925 + &slot
8926 + );
8927 + }
8928 +
8929 +#if defined(ENABLE_PKCS11H_THREADING)
8930 + if (mutex_locked) {
8931 + _pkcs11h_threading_mutexRelease (&session->mutex);
8932 + mutex_locked = FALSE;
8933 + }
8934 +#endif
8935 +
8936 + if (session != NULL) {
8937 + _pkcs11h_session_release (session);
8938 + session = NULL;
8939 + }
8940 +
8941 + PKCS11H_DEBUG (
8942 + PKCS11H_LOG_DEBUG2,
8943 + "PKCS#11: pkcs11h_token_ensureAccess return rv=%ld-'%s'",
8944 + rv,
8945 + pkcs11h_getMessage (rv)
8946 + );
8947 +
8948 + return rv;
8949 +}
8950 +
8951 +#endif /* ENABLE_PKCS11H_TOKEN */
8952 +
8953 +#if defined(ENABLE_PKCS11H_DATA)
8954 +/*======================================================================*
8955 + * DATA INTERFACE
8956 + *======================================================================*/
8957 +
8958 +static
8959 +CK_RV
8960 +_pkcs11h_data_getObject (
8961 + IN const pkcs11h_session_t session,
8962 + IN const char * const application,
8963 + IN const char * const label,
8964 + OUT CK_OBJECT_HANDLE * const p_handle
8965 +) {
8966 + CK_OBJECT_CLASS class = CKO_DATA;
8967 + CK_ATTRIBUTE filter[] = {
8968 + {CKA_CLASS, (void *)&class, sizeof (class)},
8969 + {CKA_APPLICATION, (void *)application, application == NULL ? 0 : strlen (application)},
8970 + {CKA_LABEL, (void *)label, label == NULL ? 0 : strlen (label)}
8971 + };
8972 + CK_OBJECT_HANDLE *objects = NULL;
8973 + CK_ULONG objects_found = 0;
8974 + CK_RV rv = CKR_OK;
8975 +
8976 + PKCS11H_ASSERT (session!=NULL);
8977 + PKCS11H_ASSERT (application!=NULL);
8978 + PKCS11H_ASSERT (label!=NULL);
8979 +
8980 + PKCS11H_DEBUG (
8981 + PKCS11H_LOG_DEBUG2,
8982 + "PKCS#11: _pkcs11h_data_getObject entry session=%p, application='%s', label='%s', p_handle=%p",
8983 + (void *)session,
8984 + application,
8985 + label,
8986 + (void *)p_handle
8987 + );
8988 +
8989 + *p_handle = PKCS11H_INVALID_OBJECT_HANDLE;
8990 +
8991 + if (rv == CKR_OK) {
8992 + rv = _pkcs11h_session_validate (session);
8993 + }
8994 +
8995 + if (rv == CKR_OK) {
8996 + rv = _pkcs11h_session_findObjects (
8997 + session,
8998 + filter,
8999 + sizeof (filter) / sizeof (CK_ATTRIBUTE),
9000 + &objects,
9001 + &objects_found
9002 + );
9003 + }
9004 +
9005 + if (
9006 + rv == CKR_OK &&
9007 + objects_found == 0
9008 + ) {
9009 + rv = CKR_FUNCTION_REJECTED;
9010 + }
9011 +
9012 + if (rv == CKR_OK) {
9013 + *p_handle = objects[0];
9014 + }
9015 +
9016 + if (objects != NULL) {
9017 + _pkcs11h_mem_free ((void *)&objects);
9018 + }
9019 +
9020 + PKCS11H_DEBUG (
9021 + PKCS11H_LOG_DEBUG2,
9022 + "PKCS#11: _pkcs11h_data_getObject return rv=%ld-'%s', *p_handle=%p",
9023 + rv,
9024 + pkcs11h_getMessage (rv),
9025 + (void *)*p_handle
9026 + );
9027 +
9028 + return rv;
9029 +}
9030 +
9031 +CK_RV
9032 +pkcs11h_data_get (
9033 + IN const pkcs11h_token_id_t token_id,
9034 + IN const PKCS11H_BOOL is_public,
9035 + IN const char * const application,
9036 + IN const char * const label,
9037 + IN void * const user_data,
9038 + IN const unsigned mask_prompt,
9039 + OUT unsigned char * const blob,
9040 + IN OUT size_t * const p_blob_size
9041 +) {
9042 + CK_ATTRIBUTE attrs[] = {
9043 + {CKA_VALUE, NULL, 0}
9044 + };
9045 + CK_OBJECT_HANDLE handle = PKCS11H_INVALID_OBJECT_HANDLE;
9046 + CK_RV rv = CKR_OK;
9047 +
9048 +#if defined(ENABLE_PKCS11H_THREADING)
9049 + PKCS11H_BOOL mutex_locked = FALSE;
9050 +#endif
9051 + pkcs11h_session_t session = NULL;
9052 + PKCS11H_BOOL op_succeed = FALSE;
9053 + PKCS11H_BOOL login_retry = FALSE;
9054 + size_t blob_size_max = 0;
9055 +
9056 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
9057 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
9058 + PKCS11H_ASSERT (token_id!=NULL);
9059 + PKCS11H_ASSERT (application!=NULL);
9060 + PKCS11H_ASSERT (label!=NULL);
9061 + /*PKCS11H_ASSERT (user_data) NOT NEEDED */
9062 + /*PKCS11H_ASSERT (blob!=NULL); NOT NEEDED*/
9063 + PKCS11H_ASSERT (p_blob_size!=NULL);
9064 +
9065 + PKCS11H_DEBUG (
9066 + PKCS11H_LOG_DEBUG2,
9067 + "PKCS#11: pkcs11h_data_get entry token_id=%p, application='%s', label='%s', user_data=%p, mask_prompt=%08x, blob=%p, *p_blob_size=%u",
9068 + (void *)token_id,
9069 + application,
9070 + label,
9071 + user_data,
9072 + mask_prompt,
9073 + blob,
9074 + blob != NULL ? *p_blob_size : 0
9075 + );
9076 +
9077 + if (blob != NULL) {
9078 + blob_size_max = *p_blob_size;
9079 + }
9080 + *p_blob_size = 0;
9081 +
9082 + if (rv == CKR_OK) {
9083 + rv = _pkcs11h_session_getSessionByTokenId (
9084 + token_id,
9085 + &session
9086 + );
9087 + }
9088 +
9089 +#if defined(ENABLE_PKCS11H_THREADING)
9090 + if (
9091 + rv == CKR_OK &&
9092 + (rv = _pkcs11h_threading_mutexLock (&session->mutex)) == CKR_OK
9093 + ) {
9094 + mutex_locked = TRUE;
9095 + }
9096 +#endif
9097 +
9098 + while (rv == CKR_OK && !op_succeed) {
9099 +
9100 + if (rv == CKR_OK) {
9101 + rv = _pkcs11h_session_validate (session);
9102 + }
9103 +
9104 + if (rv == CKR_OK) {
9105 + rv = _pkcs11h_data_getObject (
9106 + session,
9107 + application,
9108 + label,
9109 + &handle
9110 + );
9111 + }
9112 +
9113 + if (rv == CKR_OK) {
9114 + rv = _pkcs11h_session_getObjectAttributes (
9115 + session,
9116 + handle,
9117 + attrs,
9118 + sizeof (attrs)/sizeof (CK_ATTRIBUTE)
9119 + );
9120 + }
9121 +
9122 + if (rv == CKR_OK) {
9123 + op_succeed = TRUE;
9124 + }
9125 + else {
9126 + if (!login_retry) {
9127 + PKCS11H_DEBUG (
9128 + PKCS11H_LOG_DEBUG1,
9129 + "PKCS#11: Read data object failed rv=%ld-'%s'",
9130 + rv,
9131 + pkcs11h_getMessage (rv)
9132 + );
9133 + login_retry = TRUE;
9134 + rv = _pkcs11h_session_login (
9135 + session,
9136 + is_public,
9137 + TRUE,
9138 + user_data,
9139 + mask_prompt
9140 + );
9141 + }
9142 + }
9143 + }
9144 +
9145 +#if defined(ENABLE_PKCS11H_THREADING)
9146 + if (mutex_locked) {
9147 + _pkcs11h_threading_mutexRelease (&session->mutex);
9148 + mutex_locked = FALSE;
9149 + }
9150 +#endif
9151 +
9152 + if (rv == CKR_OK) {
9153 + *p_blob_size = attrs[0].ulValueLen;
9154 + }
9155 +
9156 + if (rv == CKR_OK) {
9157 + if (blob != NULL) {
9158 + if (*p_blob_size > blob_size_max) {
9159 + rv = CKR_BUFFER_TOO_SMALL;
9160 + }
9161 + else {
9162 + memmove (blob, attrs[0].pValue, *p_blob_size);
9163 + }
9164 + }
9165 + }
9166 +
9167 + _pkcs11h_session_freeObjectAttributes (
9168 + attrs,
9169 + sizeof (attrs)/sizeof (CK_ATTRIBUTE)
9170 + );
9171 +
9172 + if (session != NULL) {
9173 + _pkcs11h_session_release (session);
9174 + session = NULL;
9175 + }
9176 +
9177 + PKCS11H_DEBUG (
9178 + PKCS11H_LOG_DEBUG2,
9179 + "PKCS#11: pkcs11h_data_get return rv=%ld-'%s', *p_blob_size=%u",
9180 + rv,
9181 + pkcs11h_getMessage (rv),
9182 + *p_blob_size
9183 + );
9184 +
9185 + return rv;
9186 +}
9187 +
9188 +CK_RV
9189 +pkcs11h_data_put (
9190 + IN const pkcs11h_token_id_t token_id,
9191 + IN const PKCS11H_BOOL is_public,
9192 + IN const char * const application,
9193 + IN const char * const label,
9194 + IN void * const user_data,
9195 + IN const unsigned mask_prompt,
9196 + OUT unsigned char * const blob,
9197 + IN const size_t blob_size
9198 +) {
9199 + CK_OBJECT_CLASS class = CKO_DATA;
9200 + CK_BBOOL ck_true = CK_TRUE;
9201 + CK_BBOOL ck_false = CK_FALSE;
9202 +
9203 + CK_ATTRIBUTE attrs[] = {
9204 + {CKA_CLASS, &class, sizeof (class)},
9205 + {CKA_TOKEN, &ck_true, sizeof (ck_true)},
9206 + {CKA_PRIVATE, is_public ? &ck_false : &ck_true, sizeof (CK_BBOOL)},
9207 + {CKA_APPLICATION, (void *)application, strlen (application)},
9208 + {CKA_LABEL, (void *)label, strlen (label)},
9209 + {CKA_VALUE, blob, blob_size}
9210 + };
9211 +
9212 + CK_OBJECT_HANDLE handle = PKCS11H_INVALID_OBJECT_HANDLE;
9213 + CK_RV rv = CKR_OK;
9214 +
9215 +#if defined(ENABLE_PKCS11H_THREADING)
9216 + PKCS11H_BOOL mutex_locked = FALSE;
9217 +#endif
9218 + pkcs11h_session_t session = NULL;
9219 + PKCS11H_BOOL op_succeed = FALSE;
9220 + PKCS11H_BOOL login_retry = FALSE;
9221 +
9222 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
9223 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
9224 + PKCS11H_ASSERT (token_id!=NULL);
9225 + PKCS11H_ASSERT (application!=NULL);
9226 + PKCS11H_ASSERT (label!=NULL);
9227 + /*PKCS11H_ASSERT (user_data) NOT NEEDED */
9228 + PKCS11H_ASSERT (blob!=NULL);
9229 +
9230 + PKCS11H_DEBUG (
9231 + PKCS11H_LOG_DEBUG2,
9232 + "PKCS#11: pkcs11h_data_put entry token_id=%p, application='%s', label='%s', user_data=%p, mask_prompt=%08x, blob=%p, blob_size=%u",
9233 + (void *)token_id,
9234 + application,
9235 + label,
9236 + user_data,
9237 + mask_prompt,
9238 + blob,
9239 + blob != NULL ? blob_size : 0
9240 + );
9241 +
9242 + if (rv == CKR_OK) {
9243 + rv = _pkcs11h_session_getSessionByTokenId (
9244 + token_id,
9245 + &session
9246 + );
9247 + }
9248 +
9249 +#if defined(ENABLE_PKCS11H_THREADING)
9250 + if (
9251 + rv == CKR_OK &&
9252 + (rv = _pkcs11h_threading_mutexLock (&session->mutex)) == CKR_OK
9253 + ) {
9254 + mutex_locked = TRUE;
9255 + }
9256 +#endif
9257 +
9258 + while (rv == CKR_OK && !op_succeed) {
9259 +
9260 + if (rv == CKR_OK) {
9261 + rv = _pkcs11h_session_validate (session);
9262 + }
9263 +
9264 + if (rv == CKR_OK) {
9265 + rv = session->provider->f->C_CreateObject (
9266 + session->session_handle,
9267 + attrs,
9268 + sizeof (attrs)/sizeof (CK_ATTRIBUTE),
9269 + &handle
9270 + );
9271 + }
9272 +
9273 + if (rv == CKR_OK) {
9274 + op_succeed = TRUE;
9275 + }
9276 + else {
9277 + if (!login_retry) {
9278 + PKCS11H_DEBUG (
9279 + PKCS11H_LOG_DEBUG1,
9280 + "PKCS#11: Write data object failed rv=%ld-'%s'",
9281 + rv,
9282 + pkcs11h_getMessage (rv)
9283 + );
9284 + login_retry = TRUE;
9285 + rv = _pkcs11h_session_login (
9286 + session,
9287 + is_public,
9288 + FALSE,
9289 + user_data,
9290 + mask_prompt
9291 + );
9292 + }
9293 + }
9294 + }
9295 +
9296 +#if defined(ENABLE_PKCS11H_THREADING)
9297 + if (mutex_locked) {
9298 + _pkcs11h_threading_mutexRelease (&session->mutex);
9299 + mutex_locked = FALSE;
9300 + }
9301 +#endif
9302 +
9303 + if (session != NULL) {
9304 + _pkcs11h_session_release (session);
9305 + session = NULL;
9306 + }
9307 +
9308 + PKCS11H_DEBUG (
9309 + PKCS11H_LOG_DEBUG2,
9310 + "PKCS#11: pkcs11h_data_put return rv=%ld-'%s'",
9311 + rv,
9312 + pkcs11h_getMessage (rv)
9313 + );
9314 +
9315 + return rv;
9316 +}
9317 +
9318 +CK_RV
9319 +pkcs11h_data_del (
9320 + IN const pkcs11h_token_id_t token_id,
9321 + IN const PKCS11H_BOOL is_public,
9322 + IN const char * const application,
9323 + IN const char * const label,
9324 + IN void * const user_data,
9325 + IN const unsigned mask_prompt
9326 +) {
9327 +#if defined(ENABLE_PKCS11H_THREADING)
9328 + PKCS11H_BOOL mutex_locked = FALSE;
9329 +#endif
9330 + pkcs11h_session_t session = NULL;
9331 + PKCS11H_BOOL op_succeed = FALSE;
9332 + PKCS11H_BOOL login_retry = FALSE;
9333 + CK_OBJECT_HANDLE handle = PKCS11H_INVALID_OBJECT_HANDLE;
9334 + CK_RV rv = CKR_OK;
9335 +
9336 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
9337 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
9338 + PKCS11H_ASSERT (token_id!=NULL);
9339 + PKCS11H_ASSERT (application!=NULL);
9340 + PKCS11H_ASSERT (label!=NULL);
9341 + /*PKCS11H_ASSERT (user_data) NOT NEEDED */
9342 +
9343 + PKCS11H_DEBUG (
9344 + PKCS11H_LOG_DEBUG2,
9345 + "PKCS#11: pkcs11h_data_del entry token_id=%p, application='%s', label='%s', user_data=%p, mask_prompt=%08x",
9346 + (void *)token_id,
9347 + application,
9348 + label,
9349 + user_data,
9350 + mask_prompt
9351 + );
9352 +
9353 + if (rv == CKR_OK) {
9354 + rv = _pkcs11h_session_getSessionByTokenId (
9355 + token_id,
9356 + &session
9357 + );
9358 + }
9359 +
9360 +#if defined(ENABLE_PKCS11H_THREADING)
9361 + if (
9362 + rv == CKR_OK &&
9363 + (rv = _pkcs11h_threading_mutexLock (&session->mutex)) == CKR_OK
9364 + ) {
9365 + mutex_locked = TRUE;
9366 + }
9367 +#endif
9368 +
9369 + while (rv == CKR_OK && !op_succeed) {
9370 +
9371 + if (rv == CKR_OK) {
9372 + rv = _pkcs11h_session_validate (session);
9373 + }
9374 +
9375 + if (rv == CKR_OK) {
9376 + rv = _pkcs11h_data_getObject (
9377 + session,
9378 + application,
9379 + label,
9380 + &handle
9381 + );
9382 + }
9383 +
9384 + if (rv == CKR_OK) {
9385 + rv = session->provider->f->C_DestroyObject (
9386 + session->session_handle,
9387 + handle
9388 + );
9389 + }
9390 +
9391 + if (rv == CKR_OK) {
9392 + op_succeed = TRUE;
9393 + }
9394 + else {
9395 + if (!login_retry) {
9396 + PKCS11H_DEBUG (
9397 + PKCS11H_LOG_DEBUG1,
9398 + "PKCS#11: Remove data object failed rv=%ld-'%s'",
9399 + rv,
9400 + pkcs11h_getMessage (rv)
9401 + );
9402 + login_retry = TRUE;
9403 + rv = _pkcs11h_session_login (
9404 + session,
9405 + is_public,
9406 + FALSE,
9407 + user_data,
9408 + mask_prompt
9409 + );
9410 + }
9411 + }
9412 + }
9413 +
9414 +#if defined(ENABLE_PKCS11H_THREADING)
9415 + if (mutex_locked) {
9416 + _pkcs11h_threading_mutexRelease (&session->mutex);
9417 + mutex_locked = FALSE;
9418 + }
9419 +#endif
9420 +
9421 + if (session != NULL) {
9422 + _pkcs11h_session_release (session);
9423 + session = NULL;
9424 + }
9425 +
9426 + PKCS11H_DEBUG (
9427 + PKCS11H_LOG_DEBUG2,
9428 + "PKCS#11: pkcs11h_data_del return rv=%ld-'%s'",
9429 + rv,
9430 + pkcs11h_getMessage (rv)
9431 + );
9432 +
9433 + return rv;
9434 +}
9435 +
9436 +#endif /* ENABLE_PKCS11H_DATA */
9437 +
9438 +#if defined(ENABLE_PKCS11H_CERTIFICATE)
9439 +/*======================================================================*
9440 + * CERTIFICATE INTERFACE
9441 + *======================================================================*/
9442 +
9443 +static
9444 +time_t
9445 +_pkcs11h_certificate_getExpiration (
9446 + IN const unsigned char * const certificate,
9447 + IN const size_t certificate_size
9448 +) {
9449 + /*
9450 + * This function compare the notAfter
9451 + * and select the most recent certificate
9452 + */
9453 +
9454 +#if defined(USE_PKCS11H_OPENSSL)
9455 + X509 *x509 = NULL;
9456 +#elif defined(USE_PKCS11H_GNUTLS)
9457 + gnutls_x509_crt_t cert = NULL;
9458 +#endif
9459 + time_t expire = (time_t)0;
9460 +
9461 + PKCS11H_ASSERT (certificate!=NULL);
9462 +
9463 +#if defined(USE_PKCS11H_OPENSSL)
9464 + x509 = X509_new ();
9465 +
9466 + if (x509 != NULL) {
9467 + pkcs11_openssl_d2i_t d2i = (pkcs11_openssl_d2i_t)certificate;
9468 +
9469 + if (
9470 + d2i_X509 (&x509, &d2i, certificate_size)
9471 + ) {
9472 + ASN1_TIME *notBefore = X509_get_notBefore (x509);
9473 + ASN1_TIME *notAfter = X509_get_notAfter (x509);
9474 +
9475 + if (
9476 + notBefore != NULL &&
9477 + notAfter != NULL &&
9478 + X509_cmp_current_time (notBefore) <= 0 &&
9479 + X509_cmp_current_time (notAfter) >= 0 &&
9480 + notAfter->length >= 12
9481 + ) {
9482 + struct tm tm1;
9483 + time_t now = time (NULL);
9484 +
9485 + memset (&tm1, 0, sizeof (tm1));
9486 + tm1.tm_year = (notAfter->data[ 0] - '0') * 10 + (notAfter->data[ 1] - '0') + 100;
9487 + tm1.tm_mon = (notAfter->data[ 2] - '0') * 10 + (notAfter->data[ 3] - '0') - 1;
9488 + tm1.tm_mday = (notAfter->data[ 4] - '0') * 10 + (notAfter->data[ 5] - '0');
9489 + tm1.tm_hour = (notAfter->data[ 6] - '0') * 10 + (notAfter->data[ 7] - '0');
9490 + tm1.tm_min = (notAfter->data[ 8] - '0') * 10 + (notAfter->data[ 9] - '0');
9491 + tm1.tm_sec = (notAfter->data[10] - '0') * 10 + (notAfter->data[11] - '0');
9492 +
9493 + tm1.tm_sec += (int)(mktime (localtime (&now)) - mktime (gmtime (&now)));
9494 +
9495 + expire = mktime (&tm1);
9496 + }
9497 + }
9498 + }
9499 +
9500 + if (x509 != NULL) {
9501 + X509_free (x509);
9502 + x509 = NULL;
9503 + }
9504 +#elif defined(USE_PKCS11H_GNUTLS)
9505 + if (gnutls_x509_crt_init (&cert) == GNUTLS_E_SUCCESS) {
9506 + gnutls_datum_t datum = {(unsigned char *)certificate, certificate_size};
9507 +
9508 + if (gnutls_x509_crt_import (cert, &datum, GNUTLS_X509_FMT_DER) == GNUTLS_E_SUCCESS) {
9509 +
9510 + time_t activation_time = gnutls_x509_crt_get_activation_time (cert);
9511 + time_t expiration_time = gnutls_x509_crt_get_expiration_time (cert);
9512 + time_t now = time (NULL);
9513 +
9514 + if (
9515 + now >= activation_time &&
9516 + now <= expiration_time
9517 + ) {
9518 + expire = expiration_time;
9519 + }
9520 + }
9521 + gnutls_x509_crt_deinit (cert);
9522 + }
9523 +#else
9524 +#error Invalid configuration
9525 +#endif
9526 +
9527 + return expire;
9528 +}
9529 +
9530 +static
9531 +PKCS11H_BOOL
9532 +_pkcs11h_certificate_isBetterCertificate (
9533 + IN const unsigned char * const current,
9534 + IN const size_t current_size,
9535 + IN const unsigned char * const newone,
9536 + IN const size_t newone_size
9537 +) {
9538 + PKCS11H_BOOL is_better = FALSE;
9539 +
9540 + /*PKCS11H_ASSERT (current!=NULL); NOT NEEDED */
9541 + PKCS11H_ASSERT (newone!=NULL);
9542 +
9543 + PKCS11H_DEBUG (
9544 + PKCS11H_LOG_DEBUG2,
9545 + "PKCS#11: _pkcs11h_certificate_isBetterCertificate entry current=%p, current_size=%u, newone=%p, newone_size=%u",
9546 + current,
9547 + current_size,
9548 + newone,
9549 + newone_size
9550 + );
9551 +
9552 + /*
9553 + * First certificae
9554 + * always select
9555 + */
9556 + if (current_size == 0 || current == NULL) {
9557 + is_better = TRUE;
9558 + }
9559 + else {
9560 + time_t notAfterCurrent, notAfterNew;
9561 +
9562 + notAfterCurrent = _pkcs11h_certificate_getExpiration (
9563 + current,
9564 + current_size
9565 + );
9566 + notAfterNew = _pkcs11h_certificate_getExpiration (
9567 + newone,
9568 + newone_size
9569 + );
9570 +
9571 + PKCS11H_DEBUG (
9572 + PKCS11H_LOG_DEBUG2,
9573 + "PKCS#11: _pkcs11h_certificate_isBetterCertificate notAfterCurrent='%s', notAfterNew='%s'",
9574 + asctime (localtime (&notAfterCurrent)),
9575 + asctime (localtime (&notAfterNew))
9576 + );
9577 +
9578 + is_better = notAfterNew > notAfterCurrent;
9579 + }
9580 +
9581 + PKCS11H_DEBUG (
9582 + PKCS11H_LOG_DEBUG2,
9583 + "PKCS#11: _pkcs11h_certificate_isBetterCertificate return is_better=%d",
9584 + is_better ? 1 : 0
9585 + );
9586 +
9587 + return is_better;
9588 +}
9589 +
9590 +static
9591 +CK_RV
9592 +_pkcs11h_certificate_newCertificateId (
9593 + OUT pkcs11h_certificate_id_t * const p_certificate_id
9594 +) {
9595 + CK_RV rv = CKR_OK;
9596 +
9597 + PKCS11H_ASSERT (p_certificate_id!=NULL);
9598 +
9599 + PKCS11H_DEBUG (
9600 + PKCS11H_LOG_DEBUG2,
9601 + "PKCS#11: _pkcs11h_certificate_newCertificateId entry p_certificate_id=%p",
9602 + (void *)p_certificate_id
9603 + );
9604 +
9605 + *p_certificate_id = NULL;
9606 +
9607 + if (rv == CKR_OK) {
9608 + rv = _pkcs11h_mem_malloc ((void *)p_certificate_id, sizeof (struct pkcs11h_certificate_id_s));
9609 + }
9610 +
9611 + PKCS11H_DEBUG (
9612 + PKCS11H_LOG_DEBUG2,
9613 + "PKCS#11: _pkcs11h_certificate_newCertificateId return rv=%ld-'%s', *p_certificate_id=%p",
9614 + rv,
9615 + pkcs11h_getMessage (rv),
9616 + (void *)*p_certificate_id
9617 + );
9618 +
9619 + return rv;
9620 +}
9621 +
9622 +static
9623 +CK_RV
9624 +_pkcs11h_certificate_getDN (
9625 + IN const unsigned char * const blob,
9626 + IN const size_t blob_size,
9627 + OUT char * const dn,
9628 + IN const size_t dn_size
9629 +) {
9630 +#if defined(USE_PKCS11H_OPENSSL)
9631 + X509 *x509 = NULL;
9632 + pkcs11_openssl_d2i_t d2i1;
9633 +#elif defined(USE_PKCS11H_GNUTLS)
9634 + gnutls_x509_crt_t cert = NULL;
9635 +#endif
9636 +
9637 + PKCS11H_ASSERT (blob_size==0||blob!=NULL);
9638 + PKCS11H_ASSERT (dn!=NULL);
9639 +
9640 + dn[0] = '\x0';
9641 +
9642 +#if defined(USE_PKCS11H_OPENSSL)
9643 +
9644 + if (blob_size > 0) {
9645 + x509 = X509_new ();
9646 +
9647 + d2i1 = (pkcs11_openssl_d2i_t)blob;
9648 + if (d2i_X509 (&x509, &d2i1, blob_size)) {
9649 + X509_NAME_oneline (
9650 + X509_get_subject_name (x509),
9651 + dn,
9652 + dn_size
9653 + );
9654 + }
9655 +
9656 + if (x509 != NULL) {
9657 + X509_free (x509);
9658 + x509 = NULL;
9659 + }
9660 + }
9661 +
9662 +#elif defined(USE_PKCS11H_GNUTLS)
9663 +
9664 + if (blob_size > 0) {
9665 + if (gnutls_x509_crt_init (&cert) == GNUTLS_E_SUCCESS) {
9666 + gnutls_datum_t datum = {(unsigned char *)blob, blob_size};
9667 +
9668 + if (gnutls_x509_crt_import (cert, &datum, GNUTLS_X509_FMT_DER) == GNUTLS_E_SUCCESS) {
9669 + size_t s = dn_size;
9670 + if (
9671 + gnutls_x509_crt_get_dn (
9672 + cert,
9673 + dn,
9674 + &s
9675 + ) != GNUTLS_E_SUCCESS
9676 + ) {
9677 + /* gnutls sets output parameters */
9678 + dn[0] = '\x0';
9679 + }
9680 + }
9681 + gnutls_x509_crt_deinit (cert);
9682 + }
9683 + }
9684 +
9685 +#else
9686 +#error Invalid configuration
9687 +#endif
9688 +
9689 + return CKR_OK;
9690 +}
9691 +
9692 +static
9693 +CK_RV
9694 +_pkcs11h_certificate_loadCertificate (
9695 + IN const pkcs11h_certificate_t certificate
9696 +) {
9697 + /*
9698 + * THREADING:
9699 + * certificate->mutex must be locked
9700 + */
9701 +#if defined(ENABLE_PKCS11H_THREADING)
9702 + PKCS11H_BOOL mutex_locked = FALSE;
9703 +#endif
9704 + CK_OBJECT_CLASS cert_filter_class = CKO_CERTIFICATE;
9705 + CK_ATTRIBUTE cert_filter[] = {
9706 + {CKA_CLASS, &cert_filter_class, sizeof (cert_filter_class)},
9707 + {CKA_ID, NULL, 0}
9708 + };
9709 +
9710 + CK_OBJECT_HANDLE *objects = NULL;
9711 + CK_ULONG objects_found = 0;
9712 + CK_RV rv = CKR_OK;
9713 +
9714 + CK_ULONG i;
9715 +
9716 + PKCS11H_ASSERT (certificate!=NULL);
9717 + PKCS11H_ASSERT (certificate->id!=NULL);
9718 +
9719 + /* Must be after assert */
9720 + cert_filter[1].pValue = certificate->id->attrCKA_ID;
9721 + cert_filter[1].ulValueLen = certificate->id->attrCKA_ID_size;
9722 +
9723 + PKCS11H_DEBUG (
9724 + PKCS11H_LOG_DEBUG2,
9725 + "PKCS#11: _pkcs11h_certificate_loadCertificate entry certificate=%p",
9726 + (void *)certificate
9727 + );
9728 +
9729 +#if defined(ENABLE_PKCS11H_THREADING)
9730 + if (
9731 + rv == CKR_OK &&
9732 + (rv = _pkcs11h_threading_mutexLock (&certificate->session->mutex)) == CKR_OK
9733 + ) {
9734 + mutex_locked = TRUE;
9735 + }
9736 +#endif
9737 +
9738 + if (rv == CKR_OK) {
9739 + rv = _pkcs11h_session_validate (certificate->session);
9740 + }
9741 +
9742 + if (rv == CKR_OK) {
9743 + rv = _pkcs11h_session_findObjects (
9744 + certificate->session,
9745 + cert_filter,
9746 + sizeof (cert_filter) / sizeof (CK_ATTRIBUTE),
9747 + &objects,
9748 + &objects_found
9749 + );
9750 + }
9751 +
9752 + for (i=0;rv == CKR_OK && i < objects_found;i++) {
9753 + CK_ATTRIBUTE attrs[] = {
9754 + {CKA_VALUE, NULL, 0}
9755 + };
9756 +
9757 + if (
9758 + rv == CKR_OK &&
9759 + (rv = _pkcs11h_session_getObjectAttributes (
9760 + certificate->session,
9761 + objects[i],
9762 + attrs,
9763 + sizeof (attrs) / sizeof (CK_ATTRIBUTE)
9764 + )) == CKR_OK
9765 + ) {
9766 + if (
9767 + _pkcs11h_certificate_isBetterCertificate (
9768 + certificate->id->certificate_blob,
9769 + certificate->id->certificate_blob_size,
9770 + attrs[0].pValue,
9771 + attrs[0].ulValueLen
9772 + )
9773 + ) {
9774 + if (certificate->id->certificate_blob != NULL) {
9775 + _pkcs11h_mem_free ((void *)&certificate->id->certificate_blob);
9776 + }
9777 +
9778 + rv = _pkcs11h_mem_duplicate (
9779 + (void*)&certificate->id->certificate_blob,
9780 + &certificate->id->certificate_blob_size,
9781 + attrs[0].pValue,
9782 + attrs[0].ulValueLen
9783 + );
9784 + }
9785 + }
9786 +
9787 + if (rv != CKR_OK) {
9788 + PKCS11H_DEBUG (
9789 + PKCS11H_LOG_DEBUG1,
9790 + "PKCS#11: Cannot get object attribute for provider '%s' object %ld rv=%ld-'%s'",
9791 + certificate->session->provider->manufacturerID,
9792 + objects[i],
9793 + rv,
9794 + pkcs11h_getMessage (rv)
9795 + );
9796 +
9797 + /*
9798 + * Ignore error
9799 + */
9800 + rv = CKR_OK;
9801 + }
9802 +
9803 + _pkcs11h_session_freeObjectAttributes (
9804 + attrs,
9805 + sizeof (attrs) / sizeof (CK_ATTRIBUTE)
9806 + );
9807 + }
9808 +
9809 +#if defined(ENABLE_PKCS11H_THREADING)
9810 + if (mutex_locked) {
9811 + _pkcs11h_threading_mutexRelease (&certificate->session->mutex);
9812 + mutex_locked = FALSE;
9813 + }
9814 +#endif
9815 +
9816 + if (
9817 + rv == CKR_OK &&
9818 + certificate->id->certificate_blob == NULL
9819 + ) {
9820 + rv = CKR_ATTRIBUTE_VALUE_INVALID;
9821 + }
9822 +
9823 + if (objects != NULL) {
9824 + _pkcs11h_mem_free ((void *)&objects);
9825 + }
9826 +
9827 + /*
9828 + * No need to free allocated objects
9829 + * on error, since the certificate_id
9830 + * should be free by caller.
9831 + */
9832 +
9833 + PKCS11H_DEBUG (
9834 + PKCS11H_LOG_DEBUG2,
9835 + "PKCS#11: _pkcs11h_certificate_loadCertificate return rv=%ld-'%s'",
9836 + rv,
9837 + pkcs11h_getMessage (rv)
9838 + );
9839 +
9840 + return rv;
9841 +}
9842 +
9843 +static
9844 +CK_RV
9845 +_pkcs11h_certificate_updateCertificateIdDescription (
9846 + IN OUT pkcs11h_certificate_id_t certificate_id
9847 +) {
9848 + static const char * separator = " on ";
9849 + static const char * unknown = "UNKNOWN";
9850 +
9851 + PKCS11H_ASSERT (certificate_id!=NULL);
9852 +
9853 + PKCS11H_DEBUG (
9854 + PKCS11H_LOG_DEBUG2,
9855 + "PKCS#11: _pkcs11h_certificate_updateCertificateIdDescription entry certificate_id=%p",
9856 + (void *)certificate_id
9857 + );
9858 +
9859 + certificate_id->displayName[0] = '\x0';
9860 +
9861 + _pkcs11h_certificate_getDN (
9862 + certificate_id->certificate_blob,
9863 + certificate_id->certificate_blob_size,
9864 + certificate_id->displayName,
9865 + sizeof (certificate_id->displayName)
9866 + );
9867 +
9868 + if (strlen (certificate_id->displayName) == 0) {
9869 + strncpy (
9870 + certificate_id->displayName,
9871 + unknown,
9872 + sizeof (certificate_id->displayName)-1
9873 + );
9874 + }
9875 +
9876 + /*
9877 + * Try to avoid using snprintf,
9878 + * may be unavailable
9879 + */
9880 + strncat (
9881 + certificate_id->displayName,
9882 + separator,
9883 + sizeof (certificate_id->displayName)-1-strlen (certificate_id->displayName)
9884 + );
9885 + strncat (
9886 + certificate_id->displayName,
9887 + certificate_id->token_id->display,
9888 + sizeof (certificate_id->displayName)-1-strlen (certificate_id->displayName)
9889 + );
9890 + certificate_id->displayName[sizeof (certificate_id->displayName) - 1] = '\0';
9891 +
9892 + PKCS11H_DEBUG (
9893 + PKCS11H_LOG_DEBUG2,
9894 + "PKCS#11: _pkcs11h_certificate_updateCertificateIdDescription return displayName='%s'",
9895 + certificate_id->displayName
9896 + );
9897 +
9898 + return CKR_OK;
9899 +}
9900 +
9901 +static
9902 +CK_RV
9903 +_pkcs11h_certificate_getKeyAttributes (
9904 + IN const pkcs11h_certificate_t certificate
9905 +) {
9906 +#if defined(ENABLE_PKCS11H_THREADING)
9907 + PKCS11H_BOOL mutex_locked = FALSE;
9908 +#endif
9909 + CK_RV rv = CKR_OK;
9910 +
9911 + PKCS11H_BOOL op_succeed = FALSE;
9912 + PKCS11H_BOOL login_retry = FALSE;
9913 +
9914 + PKCS11H_ASSERT (certificate!=NULL);
9915 +
9916 + PKCS11H_DEBUG (
9917 + PKCS11H_LOG_DEBUG2,
9918 + "PKCS#11: _pkcs11h_certificate_getKeyAttributes entry certificate=%p",
9919 + (void *)certificate
9920 + );
9921 +
9922 +#if defined(ENABLE_PKCS11H_THREADING)
9923 + if (
9924 + rv == CKR_OK &&
9925 + (rv = _pkcs11h_threading_mutexLock (&certificate->mutex)) == CKR_OK
9926 + ) {
9927 + mutex_locked = TRUE;
9928 + }
9929 +#endif
9930 +
9931 + certificate->mask_sign_mode = 0;
9932 +
9933 + while (rv == CKR_OK && !op_succeed) {
9934 + CK_ATTRIBUTE key_attrs[] = {
9935 + {CKA_SIGN, NULL, 0},
9936 + {CKA_SIGN_RECOVER, NULL, 0}
9937 + };
9938 +
9939 + /*
9940 + * Don't try invalid object
9941 + */
9942 + if (
9943 + rv == CKR_OK &&
9944 + certificate->key_handle == PKCS11H_INVALID_OBJECT_HANDLE
9945 + ) {
9946 + rv = CKR_OBJECT_HANDLE_INVALID;
9947 + }
9948 +
9949 + if (rv == CKR_OK) {
9950 + if (certificate->session->provider->mask_sign_mode != 0) {
9951 + certificate->mask_sign_mode = certificate->session->provider->mask_sign_mode;
9952 + op_succeed = TRUE;
9953 + PKCS11H_DEBUG (
9954 + PKCS11H_LOG_DEBUG1,
9955 + "PKCS#11: Key attributes enforced by provider (%08x)",
9956 + certificate->mask_sign_mode
9957 + );
9958 + }
9959 + }
9960 +
9961 + if (rv == CKR_OK && !op_succeed) {
9962 + rv = _pkcs11h_session_getObjectAttributes (
9963 + certificate->session,
9964 + certificate->key_handle,
9965 + key_attrs,
9966 + sizeof (key_attrs) / sizeof (CK_ATTRIBUTE)
9967 + );
9968 + }
9969 +
9970 + if (rv == CKR_OK && !op_succeed) {
9971 + CK_BBOOL *key_attrs_sign = (CK_BBOOL *)key_attrs[0].pValue;
9972 + CK_BBOOL *key_attrs_sign_recover = (CK_BBOOL *)key_attrs[1].pValue;
9973 +
9974 + if (key_attrs_sign != NULL && *key_attrs_sign != CK_FALSE) {
9975 + certificate->mask_sign_mode |= PKCS11H_SIGNMODE_MASK_SIGN;
9976 + }
9977 + if (key_attrs_sign_recover != NULL && *key_attrs_sign_recover != CK_FALSE) {
9978 + certificate->mask_sign_mode |= PKCS11H_SIGNMODE_MASK_RECOVER;
9979 + }
9980 + if (certificate->mask_sign_mode == 0) {
9981 + rv = CKR_KEY_TYPE_INCONSISTENT;
9982 + }
9983 + PKCS11H_DEBUG (
9984 + PKCS11H_LOG_DEBUG1,
9985 + "PKCS#11: Key attributes loaded (%08x)",
9986 + certificate->mask_sign_mode
9987 + );
9988 + }
9989 +
9990 + _pkcs11h_session_freeObjectAttributes (
9991 + key_attrs,
9992 + sizeof (key_attrs) / sizeof (CK_ATTRIBUTE)
9993 + );
9994 +
9995 + if (rv == CKR_OK) {
9996 + op_succeed = TRUE;
9997 + }
9998 + else {
9999 + if (!login_retry) {
10000 + PKCS11H_DEBUG (
10001 + PKCS11H_LOG_DEBUG1,
10002 + "PKCS#11: Get private key attributes failed: %ld:'%s'",
10003 + rv,
10004 + pkcs11h_getMessage (rv)
10005 + );
10006 +
10007 + rv = _pkcs11h_certificate_resetSession (
10008 + certificate,
10009 + FALSE,
10010 + TRUE
10011 + );
10012 +
10013 + login_retry = TRUE;
10014 + }
10015 + }
10016 + }
10017 +
10018 +#if defined(ENABLE_PKCS11H_THREADING)
10019 + if (mutex_locked) {
10020 + _pkcs11h_threading_mutexRelease (&certificate->mutex);
10021 + mutex_locked = FALSE;
10022 + }
10023 +#endif
10024 +
10025 + PKCS11H_DEBUG (
10026 + PKCS11H_LOG_DEBUG2,
10027 + "PKCS#11: _pkcs11h_certificate_getKeyAttributes return rv=%ld-'%s'",
10028 + rv,
10029 + pkcs11h_getMessage (rv)
10030 + );
10031 +
10032 + return rv;
10033 +}
10034 +
10035 +static
10036 +CK_RV
10037 +_pkcs11h_certificate_validateSession (
10038 + IN const pkcs11h_certificate_t certificate
10039 +) {
10040 + /*
10041 + * THREADING:
10042 + * certificate->mutex must be locked
10043 + * certificate->session->mutex must be locked
10044 + */
10045 + CK_RV rv = CKR_OK;
10046 +
10047 + PKCS11H_ASSERT (certificate!=NULL);
10048 +
10049 + PKCS11H_DEBUG (
10050 + PKCS11H_LOG_DEBUG2,
10051 + "PKCS#11: _pkcs11h_certificate_validateSession entry certificate=%p",
10052 + (void *)certificate
10053 + );
10054 +
10055 + if (certificate->session == NULL) {
10056 + rv = CKR_SESSION_HANDLE_INVALID;
10057 + }
10058 +
10059 + if (rv == CKR_OK) {
10060 + rv = _pkcs11h_session_validate (certificate->session);
10061 + }
10062 +
10063 + if (rv == CKR_OK) {
10064 + if (certificate->key_handle == PKCS11H_INVALID_OBJECT_HANDLE) {
10065 + rv = CKR_OBJECT_HANDLE_INVALID;
10066 + }
10067 + }
10068 +
10069 + PKCS11H_DEBUG (
10070 + PKCS11H_LOG_DEBUG2,
10071 + "PKCS#11: _pkcs11h_certificate_validateSession return rv=%ld-'%s'",
10072 + rv,
10073 + pkcs11h_getMessage (rv)
10074 + );
10075 +
10076 + return rv;
10077 +}
10078 +
10079 +CK_RV
10080 +_pkcs11h_certificate_resetSession (
10081 + IN const pkcs11h_certificate_t certificate,
10082 + IN const PKCS11H_BOOL public_only,
10083 + IN const PKCS11H_BOOL session_mutex_locked
10084 +) {
10085 + /*
10086 + * THREADING:
10087 + * certificate->mutex must be locked
10088 + */
10089 +#if defined(ENABLE_PKCS11H_THREADING)
10090 + PKCS11H_BOOL mutex_locked = FALSE;
10091 +#endif
10092 + PKCS11H_BOOL is_key_valid = FALSE;
10093 + CK_RV rv = CKR_OK;
10094 +
10095 + PKCS11H_ASSERT (certificate!=NULL);
10096 +
10097 + PKCS11H_DEBUG (
10098 + PKCS11H_LOG_DEBUG2,
10099 + "PKCS#11: _pkcs11h_certificate_resetSession entry certificate=%p, public_only=%d, session_mutex_locked=%d",
10100 + (void *)certificate,
10101 + public_only ? 1 : 0,
10102 + session_mutex_locked ? 1 : 0
10103 + );
10104 +
10105 + if (rv == CKR_OK && certificate->session == NULL) {
10106 + rv = _pkcs11h_session_getSessionByTokenId (certificate->id->token_id, &certificate->session);
10107 + }
10108 +
10109 +#if defined(ENABLE_PKCS11H_THREADING)
10110 + if (
10111 + rv == CKR_OK &&
10112 + !session_mutex_locked &&
10113 + (rv = _pkcs11h_threading_mutexLock (&certificate->session->mutex)) == CKR_OK
10114 + ) {
10115 + mutex_locked = TRUE;
10116 + }
10117 +#endif
10118 +
10119 + if (
10120 + rv == CKR_OK &&
10121 + !certificate->pin_cache_populated_to_session
10122 + ) {
10123 + certificate->pin_cache_populated_to_session = TRUE;
10124 +
10125 + if (certificate->pin_cache_period != PKCS11H_PIN_CACHE_INFINITE) {
10126 + if (certificate->session->pin_cache_period != PKCS11H_PIN_CACHE_INFINITE) {
10127 + if (certificate->session->pin_cache_period > certificate->pin_cache_period) {
10128 + certificate->session->pin_expire_time = (
10129 + certificate->session->pin_expire_time -
10130 + (time_t)certificate->session->pin_cache_period +
10131 + (time_t)certificate->pin_cache_period
10132 + );
10133 + certificate->session->pin_cache_period = certificate->pin_cache_period;
10134 + }
10135 + }
10136 + else {
10137 + certificate->session->pin_expire_time = (
10138 + PKCS11H_TIME (NULL) +
10139 + (time_t)certificate->pin_cache_period
10140 + );
10141 + certificate->session->pin_cache_period = certificate->pin_cache_period;
10142 + }
10143 + }
10144 + }
10145 +
10146 + /*
10147 + * First, if session seems to be valid
10148 + * and key handle is invalid (hard-set),
10149 + * try to fetch key handle,
10150 + * maybe the token is already logged in
10151 + */
10152 + if (rv == CKR_OK) {
10153 + if (
10154 + certificate->session->session_handle != PKCS11H_INVALID_SESSION_HANDLE &&
10155 + certificate->key_handle == PKCS11H_INVALID_OBJECT_HANDLE
10156 + ) {
10157 + if (!public_only || certificate->session->provider->cert_is_private) {
10158 + if (
10159 + (rv = _pkcs11h_session_getObjectById (
10160 + certificate->session,
10161 + CKO_PRIVATE_KEY,
10162 + certificate->id->attrCKA_ID,
10163 + certificate->id->attrCKA_ID_size,
10164 + &certificate->key_handle
10165 + )) == CKR_OK
10166 + ) {
10167 + is_key_valid = TRUE;
10168 + }
10169 + else {
10170 + /*
10171 + * Ignore error
10172 + */
10173 + rv = CKR_OK;
10174 + certificate->key_handle = PKCS11H_INVALID_OBJECT_HANDLE;
10175 + }
10176 + }
10177 + }
10178 + }
10179 +
10180 + if (
10181 + !is_key_valid &&
10182 + rv == CKR_OK &&
10183 + (rv = _pkcs11h_session_login (
10184 + certificate->session,
10185 + public_only,
10186 + TRUE,
10187 + certificate->user_data,
10188 + certificate->mask_prompt
10189 + )) == CKR_OK
10190 + ) {
10191 + rv = _pkcs11h_certificate_updateCertificateIdDescription (certificate->id);
10192 + }
10193 +
10194 + if (
10195 + !is_key_valid &&
10196 + rv == CKR_OK &&
10197 + !public_only &&
10198 + (rv = _pkcs11h_session_getObjectById (
10199 + certificate->session,
10200 + CKO_PRIVATE_KEY,
10201 + certificate->id->attrCKA_ID,
10202 + certificate->id->attrCKA_ID_size,
10203 + &certificate->key_handle
10204 + )) == CKR_OK
10205 + ) {
10206 + is_key_valid = TRUE;
10207 + }
10208 +
10209 + if (
10210 + rv == CKR_OK &&
10211 + !public_only &&
10212 + !is_key_valid
10213 + ) {
10214 + rv = CKR_FUNCTION_REJECTED;
10215 + }
10216 +
10217 +#if defined(ENABLE_PKCS11H_THREADING)
10218 + if (mutex_locked) {
10219 + _pkcs11h_threading_mutexRelease (&certificate->session->mutex);
10220 + mutex_locked = FALSE;
10221 + }
10222 +#endif
10223 +
10224 + PKCS11H_DEBUG (
10225 + PKCS11H_LOG_DEBUG2,
10226 + "PKCS#11: _pkcs11h_certificate_resetSession return rv=%ld-'%s'",
10227 + rv,
10228 + pkcs11h_getMessage (rv)
10229 + );
10230 +
10231 + return rv;
10232 +}
10233 +
10234 +static
10235 +CK_RV
10236 +_pkcs11h_certificate_doPrivateOperation (
10237 + IN const pkcs11h_certificate_t certificate,
10238 + IN const enum _pkcs11h_private_op_e op,
10239 + IN const CK_MECHANISM_TYPE mech_type,
10240 + IN const unsigned char * const source,
10241 + IN const size_t source_size,
10242 + OUT unsigned char * const target,
10243 + IN OUT size_t * const p_target_size
10244 +) {
10245 +#if defined(ENABLE_PKCS11H_THREADING)
10246 + PKCS11H_BOOL mutex_locked = FALSE;
10247 +#endif
10248 + CK_MECHANISM mech = {
10249 + mech_type, NULL, 0
10250 + };
10251 +
10252 + CK_RV rv = CKR_OK;
10253 + PKCS11H_BOOL login_retry = FALSE;
10254 + PKCS11H_BOOL op_succeed = FALSE;
10255 +
10256 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
10257 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
10258 + PKCS11H_ASSERT (certificate!=NULL);
10259 + PKCS11H_ASSERT (source!=NULL);
10260 + /*PKCS11H_ASSERT (target); NOT NEEDED*/
10261 + PKCS11H_ASSERT (p_target_size!=NULL);
10262 +
10263 + PKCS11H_DEBUG (
10264 + PKCS11H_LOG_DEBUG2,
10265 + "PKCS#11: _pkcs11h_certificate_doPrivateOperation entry certificate=%p, op=%d, mech_type=%ld, source=%p, source_size=%u, target=%p, *p_target_size=%u",
10266 + (void *)certificate,
10267 + op,
10268 + mech_type,
10269 + source,
10270 + source_size,
10271 + target,
10272 + target != NULL ? *p_target_size : 0
10273 + );
10274 +
10275 + if (target == NULL) {
10276 + *p_target_size = 0;
10277 + }
10278 +
10279 +#if defined(ENABLE_PKCS11H_THREADING)
10280 + if (
10281 + rv == CKR_OK &&
10282 + (rv = _pkcs11h_threading_mutexLock (&certificate->mutex)) == CKR_OK
10283 + ) {
10284 + mutex_locked = TRUE;
10285 + }
10286 +#endif
10287 +
10288 + while (rv == CKR_OK && !op_succeed) {
10289 + if (rv == CKR_OK && !certificate->operation_active) {
10290 + rv = _pkcs11h_certificate_validateSession (certificate);
10291 + }
10292 +
10293 + if (rv == CKR_OK && !certificate->operation_active) {
10294 + switch (op) {
10295 + case _pkcs11h_private_op_sign:
10296 + rv = certificate->session->provider->f->C_SignInit (
10297 + certificate->session->session_handle,
10298 + &mech,
10299 + certificate->key_handle
10300 + );
10301 + break;
10302 + case _pkcs11h_private_op_sign_recover:
10303 + rv = certificate->session->provider->f->C_SignRecoverInit (
10304 + certificate->session->session_handle,
10305 + &mech,
10306 + certificate->key_handle
10307 + );
10308 + break;
10309 + case _pkcs11h_private_op_decrypt:
10310 + rv = certificate->session->provider->f->C_DecryptInit (
10311 + certificate->session->session_handle,
10312 + &mech,
10313 + certificate->key_handle
10314 + );
10315 + break;
10316 + default:
10317 + rv = CKR_ARGUMENTS_BAD;
10318 + break;
10319 + }
10320 +
10321 + PKCS11H_DEBUG (
10322 + PKCS11H_LOG_DEBUG2,
10323 + "PKCS#11: _pkcs11h_certificate_doPrivateOperation init rv=%ld",
10324 + rv
10325 + );
10326 + }
10327 +
10328 + if (rv == CKR_OK) {
10329 + CK_ULONG size = *p_target_size;
10330 +
10331 + switch (op) {
10332 + case _pkcs11h_private_op_sign:
10333 + rv = certificate->session->provider->f->C_Sign (
10334 + certificate->session->session_handle,
10335 + (CK_BYTE_PTR)source,
10336 + source_size,
10337 + (CK_BYTE_PTR)target,
10338 + &size
10339 + );
10340 + break;
10341 + case _pkcs11h_private_op_sign_recover:
10342 + rv = certificate->session->provider->f->C_SignRecover (
10343 + certificate->session->session_handle,
10344 + (CK_BYTE_PTR)source,
10345 + source_size,
10346 + (CK_BYTE_PTR)target,
10347 + &size
10348 + );
10349 + break;
10350 + case _pkcs11h_private_op_decrypt:
10351 + rv = certificate->session->provider->f->C_Decrypt (
10352 + certificate->session->session_handle,
10353 + (CK_BYTE_PTR)source,
10354 + source_size,
10355 + (CK_BYTE_PTR)target,
10356 + &size
10357 + );
10358 + break;
10359 + default:
10360 + rv = CKR_ARGUMENTS_BAD;
10361 + break;
10362 + }
10363 +
10364 + *p_target_size = size;
10365 +
10366 + PKCS11H_DEBUG (
10367 + PKCS11H_LOG_DEBUG2,
10368 + "PKCS#11: _pkcs11h_certificate_doPrivateOperation op rv=%ld",
10369 + rv
10370 + );
10371 + }
10372 +
10373 + if (
10374 + target == NULL &&
10375 + (
10376 + rv == CKR_BUFFER_TOO_SMALL ||
10377 + rv == CKR_OK
10378 + )
10379 + ) {
10380 + certificate->operation_active = TRUE;
10381 + rv = CKR_OK;
10382 + }
10383 + else {
10384 + certificate->operation_active = FALSE;
10385 + }
10386 +
10387 + if (rv == CKR_OK) {
10388 + op_succeed = TRUE;
10389 + }
10390 + else {
10391 + /*
10392 + * OpenSC workaround
10393 + * It still allows C_FindObjectsInit when
10394 + * token is removed/inserted but fails
10395 + * private key operation.
10396 + * So we force logout.
10397 + * bug#108 at OpenSC trac
10398 + */
10399 + if (login_retry && rv == CKR_DEVICE_REMOVED) {
10400 + login_retry = FALSE;
10401 + _pkcs11h_session_logout (certificate->session);
10402 + }
10403 +
10404 + if (!login_retry) {
10405 + PKCS11H_DEBUG (
10406 + PKCS11H_LOG_DEBUG1,
10407 + "PKCS#11: Private key operation failed rv=%ld-'%s'",
10408 + rv,
10409 + pkcs11h_getMessage (rv)
10410 + );
10411 + login_retry = TRUE;
10412 + rv = _pkcs11h_certificate_resetSession (
10413 + certificate,
10414 + FALSE,
10415 + TRUE
10416 + );
10417 + }
10418 + }
10419 +
10420 + }
10421 +
10422 +#if defined(ENABLE_PKCS11H_THREADING)
10423 + if (mutex_locked) {
10424 + _pkcs11h_threading_mutexRelease (&certificate->mutex);
10425 + mutex_locked = FALSE;
10426 + }
10427 +#endif
10428 +
10429 + PKCS11H_DEBUG (
10430 + PKCS11H_LOG_DEBUG2,
10431 + "PKCS#11: _pkcs11h_certificate_doPrivateOperation return rv=%ld-'%s', *p_target_size=%u",
10432 + rv,
10433 + pkcs11h_getMessage (rv),
10434 + *p_target_size
10435 + );
10436 +
10437 + return rv;
10438 +}
10439 +
10440 +CK_RV
10441 +pkcs11h_certificate_freeCertificateId (
10442 + IN pkcs11h_certificate_id_t certificate_id
10443 +) {
10444 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
10445 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
10446 + PKCS11H_ASSERT (certificate_id!=NULL);
10447 +
10448 + PKCS11H_DEBUG (
10449 + PKCS11H_LOG_DEBUG2,
10450 + "PKCS#11: pkcs11h_certificate_freeCertificateId entry certificate_id=%p",
10451 + (void *)certificate_id
10452 + );
10453 +
10454 + if (certificate_id->attrCKA_ID != NULL) {
10455 + _pkcs11h_mem_free ((void *)&certificate_id->attrCKA_ID);
10456 + }
10457 + if (certificate_id->certificate_blob != NULL) {
10458 + _pkcs11h_mem_free ((void *)&certificate_id->certificate_blob);
10459 + }
10460 + if (certificate_id->token_id != NULL) {
10461 + pkcs11h_token_freeTokenId (certificate_id->token_id);
10462 + certificate_id->token_id = NULL;
10463 + }
10464 + _pkcs11h_mem_free ((void *)&certificate_id);
10465 +
10466 + PKCS11H_DEBUG (
10467 + PKCS11H_LOG_DEBUG2,
10468 + "PKCS#11: pkcs11h_certificate_freeCertificateId return"
10469 + );
10470 +
10471 + return CKR_OK;
10472 +}
10473 +
10474 +CK_RV
10475 +pkcs11h_certificate_duplicateCertificateId (
10476 + OUT pkcs11h_certificate_id_t * const to,
10477 + IN const pkcs11h_certificate_id_t from
10478 +) {
10479 + CK_RV rv = CKR_OK;
10480 +
10481 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
10482 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
10483 + PKCS11H_ASSERT (to!=NULL);
10484 + PKCS11H_ASSERT (from!=NULL);
10485 +
10486 + PKCS11H_DEBUG (
10487 + PKCS11H_LOG_DEBUG2,
10488 + "PKCS#11: pkcs11h_certificate_duplicateCertificateId entry to=%p form=%p",
10489 + (void *)to,
10490 + (void *)from
10491 + );
10492 +
10493 + *to = NULL;
10494 +
10495 + if (rv == CKR_OK) {
10496 + rv = _pkcs11h_mem_duplicate (
10497 + (void*)to,
10498 + NULL,
10499 + from,
10500 + sizeof (struct pkcs11h_certificate_id_s)
10501 + );
10502 + }
10503 +
10504 + if (rv == CKR_OK) {
10505 + rv = _pkcs11h_mem_duplicate (
10506 + (void*)&(*to)->token_id,
10507 + NULL,
10508 + from->token_id,
10509 + sizeof (struct pkcs11h_token_id_s)
10510 + );
10511 + }
10512 +
10513 + if (rv == CKR_OK) {
10514 + rv = _pkcs11h_mem_duplicate (
10515 + (void*)&(*to)->attrCKA_ID,
10516 + &(*to)->attrCKA_ID_size,
10517 + from->attrCKA_ID,
10518 + from->attrCKA_ID_size
10519 + );
10520 + }
10521 +
10522 + if (rv == CKR_OK) {
10523 + rv = _pkcs11h_mem_duplicate (
10524 + (void*)&(*to)->certificate_blob,
10525 + &(*to)->certificate_blob_size,
10526 + from->certificate_blob,
10527 + from->certificate_blob_size
10528 + );
10529 + }
10530 +
10531 + PKCS11H_DEBUG (
10532 + PKCS11H_LOG_DEBUG2,
10533 + "PKCS#11: pkcs11h_certificate_duplicateCertificateId return rv=%ld-'%s', *to=%p",
10534 + rv,
10535 + pkcs11h_getMessage (rv),
10536 + (void *)*to
10537 + );
10538 +
10539 + return rv;
10540 +}
10541 +
10542 +CK_RV
10543 +pkcs11h_certificate_setCertificateIdCertificateBlob (
10544 + IN const pkcs11h_certificate_id_t certificate_id,
10545 + IN const unsigned char * const blob,
10546 + IN const size_t blob_size
10547 +) {
10548 + CK_RV rv = CKR_OK;
10549 +
10550 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
10551 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
10552 + PKCS11H_ASSERT (certificate_id!=NULL);
10553 + PKCS11H_ASSERT (blob!=NULL);
10554 +
10555 + PKCS11H_DEBUG (
10556 + PKCS11H_LOG_DEBUG2,
10557 + "PKCS#11: pkcs11h_certificate_setCertificateIdCertificateBlob entry certificate_id=%p",
10558 + (void *)certificate_id
10559 + );
10560 +
10561 + if (rv == CKR_OK && certificate_id->certificate_blob != NULL) {
10562 + rv = _pkcs11h_mem_free ((void *)&certificate_id->certificate_blob);
10563 + }
10564 +
10565 + if (rv == CKR_OK) {
10566 + rv = _pkcs11h_mem_duplicate (
10567 + (void *)&certificate_id->certificate_blob,
10568 + &certificate_id->certificate_blob_size,
10569 + blob,
10570 + blob_size
10571 + );
10572 + }
10573 +
10574 + PKCS11H_DEBUG (
10575 + PKCS11H_LOG_DEBUG2,
10576 + "PKCS#11: pkcs11h_certificate_setCertificateIdCertificateBlob return rv=%ld-'%s'",
10577 + rv,
10578 + pkcs11h_getMessage (rv)
10579 + );
10580 +
10581 + return rv;
10582 +}
10583 +
10584 +CK_RV
10585 +pkcs11h_certificate_freeCertificate (
10586 + IN pkcs11h_certificate_t certificate
10587 +) {
10588 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
10589 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
10590 +
10591 + PKCS11H_DEBUG (
10592 + PKCS11H_LOG_DEBUG2,
10593 + "PKCS#11: pkcs11h_certificate_freeCertificate entry certificate=%p",
10594 + (void *)certificate
10595 + );
10596 +
10597 + if (certificate != NULL) {
10598 + if (certificate->session != NULL) {
10599 + _pkcs11h_session_release (certificate->session);
10600 + }
10601 + pkcs11h_certificate_freeCertificateId (certificate->id);
10602 + certificate->id = NULL;
10603 +
10604 +#if defined(ENABLE_PKCS11H_THREADING)
10605 + _pkcs11h_threading_mutexFree (&certificate->mutex);
10606 +#endif
10607 +
10608 + _pkcs11h_mem_free ((void *)&certificate);
10609 + }
10610 +
10611 + PKCS11H_DEBUG (
10612 + PKCS11H_LOG_DEBUG2,
10613 + "PKCS#11: pkcs11h_certificate_freeCertificate return"
10614 + );
10615 +
10616 + return CKR_OK;
10617 +}
10618 +
10619 +CK_RV
10620 +pkcs11h_certificate_lockSession (
10621 + IN const pkcs11h_certificate_t certificate
10622 +) {
10623 +#if defined(ENABLE_PKCS11H_THREADING)
10624 + CK_RV rv = CKR_OK;
10625 +
10626 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
10627 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
10628 + PKCS11H_ASSERT (certificate!=NULL);
10629 +
10630 + if (rv == CKR_OK && certificate->session == NULL) {
10631 + rv = _pkcs11h_session_getSessionByTokenId (certificate->id->token_id, &certificate->session);
10632 + }
10633 +
10634 + if (rv == CKR_OK) {
10635 + rv = _pkcs11h_threading_mutexLock (&certificate->session->mutex);
10636 + }
10637 +
10638 + return rv;
10639 +#else
10640 + return CKR_OK;
10641 +#endif
10642 +}
10643 +
10644 +CK_RV
10645 +pkcs11h_certificate_releaseSession (
10646 + IN const pkcs11h_certificate_t certificate
10647 +) {
10648 +#if defined(ENABLE_PKCS11H_THREADING)
10649 + CK_RV rv = CKR_OK;
10650 +
10651 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
10652 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
10653 + PKCS11H_ASSERT (certificate!=NULL);
10654 +
10655 + if (certificate->session != NULL) {
10656 + rv = _pkcs11h_threading_mutexRelease (&certificate->session->mutex);
10657 + }
10658 +
10659 + return rv;
10660 +#else
10661 + return CKR_OK;
10662 +#endif
10663 +}
10664 +
10665 +CK_RV
10666 +pkcs11h_certificate_sign (
10667 + IN const pkcs11h_certificate_t certificate,
10668 + IN const CK_MECHANISM_TYPE mech_type,
10669 + IN const unsigned char * const source,
10670 + IN const size_t source_size,
10671 + OUT unsigned char * const target,
10672 + IN OUT size_t * const p_target_size
10673 +) {
10674 + CK_RV rv = CKR_OK;
10675 +
10676 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
10677 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
10678 + PKCS11H_ASSERT (certificate!=NULL);
10679 + PKCS11H_ASSERT (source!=NULL);
10680 + /*PKCS11H_ASSERT (target); NOT NEEDED*/
10681 + PKCS11H_ASSERT (p_target_size!=NULL);
10682 +
10683 + PKCS11H_DEBUG (
10684 + PKCS11H_LOG_DEBUG2,
10685 + "PKCS#11: pkcs11h_certificate_sign entry certificate=%p, mech_type=%ld, source=%p, source_size=%u, target=%p, *p_target_size=%u",
10686 + (void *)certificate,
10687 + mech_type,
10688 + source,
10689 + source_size,
10690 + target,
10691 + target != NULL ? *p_target_size : 0
10692 + );
10693 +
10694 + if (target == NULL) {
10695 + *p_target_size = 0;
10696 + }
10697 +
10698 + if (rv == CKR_OK) {
10699 + rv = _pkcs11h_certificate_doPrivateOperation (
10700 + certificate,
10701 + _pkcs11h_private_op_sign,
10702 + mech_type,
10703 + source,
10704 + source_size,
10705 + target,
10706 + p_target_size
10707 + );
10708 + }
10709 +
10710 + PKCS11H_DEBUG (
10711 + PKCS11H_LOG_DEBUG2,
10712 + "PKCS#11: pkcs11h_certificate_sign return rv=%ld-'%s', *p_target_size=%u",
10713 + rv,
10714 + pkcs11h_getMessage (rv),
10715 + *p_target_size
10716 + );
10717 +
10718 + return rv;
10719 +}
10720 +
10721 +CK_RV
10722 +pkcs11h_certificate_signRecover (
10723 + IN const pkcs11h_certificate_t certificate,
10724 + IN const CK_MECHANISM_TYPE mech_type,
10725 + IN const unsigned char * const source,
10726 + IN const size_t source_size,
10727 + OUT unsigned char * const target,
10728 + IN OUT size_t * const p_target_size
10729 +) {
10730 + CK_RV rv = CKR_OK;
10731 +
10732 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
10733 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
10734 + PKCS11H_ASSERT (certificate!=NULL);
10735 + PKCS11H_ASSERT (source!=NULL);
10736 + /*PKCS11H_ASSERT (target); NOT NEEDED*/
10737 + PKCS11H_ASSERT (p_target_size!=NULL);
10738 +
10739 + PKCS11H_DEBUG (
10740 + PKCS11H_LOG_DEBUG2,
10741 + "PKCS#11: pkcs11h_certificate_signRecover entry certificate=%p, mech_type=%ld, source=%p, source_size=%u, target=%p, *p_target_size=%u",
10742 + (void *)certificate,
10743 + mech_type,
10744 + source,
10745 + source_size,
10746 + target,
10747 + target != NULL ? *p_target_size : 0
10748 + );
10749 +
10750 + if (target == NULL) {
10751 + *p_target_size = 0;
10752 + }
10753 +
10754 + if (rv == CKR_OK) {
10755 + rv = _pkcs11h_certificate_doPrivateOperation (
10756 + certificate,
10757 + _pkcs11h_private_op_sign_recover,
10758 + mech_type,
10759 + source,
10760 + source_size,
10761 + target,
10762 + p_target_size
10763 + );
10764 + }
10765 +
10766 + PKCS11H_DEBUG (
10767 + PKCS11H_LOG_DEBUG2,
10768 + "PKCS#11: pkcs11h_certificate_signRecover return rv=%ld-'%s', *p_target_size=%u",
10769 + rv,
10770 + pkcs11h_getMessage (rv),
10771 + *p_target_size
10772 + );
10773 +
10774 + return rv;
10775 +}
10776 +
10777 +CK_RV
10778 +pkcs11h_certificate_signAny (
10779 + IN const pkcs11h_certificate_t certificate,
10780 + IN const CK_MECHANISM_TYPE mech_type,
10781 + IN const unsigned char * const source,
10782 + IN const size_t source_size,
10783 + OUT unsigned char * const target,
10784 + IN OUT size_t * const p_target_size
10785 +) {
10786 + CK_RV rv = CKR_OK;
10787 + PKCS11H_BOOL fSigned = FALSE;
10788 +
10789 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
10790 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
10791 + PKCS11H_ASSERT (certificate!=NULL);
10792 + PKCS11H_ASSERT (source!=NULL);
10793 + /*PKCS11H_ASSERT (target); NOT NEEDED*/
10794 + PKCS11H_ASSERT (p_target_size!=NULL);
10795 +
10796 + PKCS11H_DEBUG (
10797 + PKCS11H_LOG_DEBUG2,
10798 + "PKCS#11: pkcs11h_certificate_signAny entry certificate=%p, mech_type=%ld, source=%p, source_size=%u, target=%p, *p_target_size=%u",
10799 + (void *)certificate,
10800 + mech_type,
10801 + source,
10802 + source_size,
10803 + target,
10804 + target != NULL ? *p_target_size : 0
10805 + );
10806 +
10807 + if (
10808 + rv == CKR_OK &&
10809 + certificate->mask_sign_mode == 0
10810 + ) {
10811 + PKCS11H_DEBUG (
10812 + PKCS11H_LOG_DEBUG1,
10813 + "PKCS#11: Getting key attributes"
10814 + );
10815 + rv = _pkcs11h_certificate_getKeyAttributes (certificate);
10816 + }
10817 +
10818 + if (
10819 + rv == CKR_OK &&
10820 + !fSigned &&
10821 + (certificate->mask_sign_mode & PKCS11H_SIGNMODE_MASK_SIGN) != 0
10822 + ) {
10823 + rv = pkcs11h_certificate_sign (
10824 + certificate,
10825 + mech_type,
10826 + source,
10827 + source_size,
10828 + target,
10829 + p_target_size
10830 + );
10831 +
10832 + if (rv == CKR_OK) {
10833 + fSigned = TRUE;
10834 + }
10835 + else if (
10836 + rv == CKR_FUNCTION_NOT_SUPPORTED ||
10837 + rv == CKR_KEY_FUNCTION_NOT_PERMITTED
10838 + ) {
10839 + certificate->mask_sign_mode &= ~PKCS11H_SIGNMODE_MASK_SIGN;
10840 + rv = CKR_OK;
10841 + }
10842 + }
10843 +
10844 + if (
10845 + rv == CKR_OK &&
10846 + !fSigned &&
10847 + (certificate->mask_sign_mode & PKCS11H_SIGNMODE_MASK_RECOVER) != 0
10848 + ) {
10849 + rv = pkcs11h_certificate_signRecover (
10850 + certificate,
10851 + mech_type,
10852 + source,
10853 + source_size,
10854 + target,
10855 + p_target_size
10856 + );
10857 +
10858 + if (rv == CKR_OK) {
10859 + fSigned = TRUE;
10860 + }
10861 + else if (
10862 + rv == CKR_FUNCTION_NOT_SUPPORTED ||
10863 + rv == CKR_KEY_FUNCTION_NOT_PERMITTED
10864 + ) {
10865 + certificate->mask_sign_mode &= ~PKCS11H_SIGNMODE_MASK_RECOVER;
10866 + rv = CKR_OK;
10867 + }
10868 + }
10869 +
10870 + if (rv == CKR_OK && !fSigned) {
10871 + rv = CKR_FUNCTION_FAILED;
10872 + }
10873 +
10874 + PKCS11H_DEBUG (
10875 + PKCS11H_LOG_DEBUG2,
10876 + "PKCS#11: pkcs11h_certificate_signAny return rv=%ld-'%s', *p_target_size=%p",
10877 + rv,
10878 + pkcs11h_getMessage (rv),
10879 + (void *)*p_target_size
10880 + );
10881 +
10882 + return rv;
10883 +}
10884 +
10885 +CK_RV
10886 +pkcs11h_certificate_decrypt (
10887 + IN const pkcs11h_certificate_t certificate,
10888 + IN const CK_MECHANISM_TYPE mech_type,
10889 + IN const unsigned char * const source,
10890 + IN const size_t source_size,
10891 + OUT unsigned char * const target,
10892 + IN OUT size_t * const p_target_size
10893 +) {
10894 + CK_RV rv = CKR_OK;
10895 +
10896 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
10897 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
10898 + PKCS11H_ASSERT (certificate!=NULL);
10899 + PKCS11H_ASSERT (source!=NULL);
10900 + /*PKCS11H_ASSERT (target); NOT NEEDED*/
10901 + PKCS11H_ASSERT (p_target_size!=NULL);
10902 +
10903 + PKCS11H_DEBUG (
10904 + PKCS11H_LOG_DEBUG2,
10905 + "PKCS#11: pkcs11h_decrypt entry certificate=%p, mech_type=%ld, source=%p, source_size=%u, target=%p, *p_target_size=%u",
10906 + (void *)certificate,
10907 + mech_type,
10908 + source,
10909 + source_size,
10910 + target,
10911 + target != NULL ? *p_target_size : 0
10912 + );
10913 +
10914 + if (target == NULL) {
10915 + *p_target_size = 0;
10916 + }
10917 +
10918 + if (rv == CKR_OK) {
10919 + rv = _pkcs11h_certificate_doPrivateOperation (
10920 + certificate,
10921 + _pkcs11h_private_op_decrypt,
10922 + mech_type,
10923 + source,
10924 + source_size,
10925 + target,
10926 + p_target_size
10927 + );
10928 + }
10929 +
10930 + PKCS11H_DEBUG (
10931 + PKCS11H_LOG_DEBUG2,
10932 + "PKCS#11: pkcs11h_decrypt return rv=%ld-'%s', *p_target_size=%u",
10933 + rv,
10934 + pkcs11h_getMessage (rv),
10935 + *p_target_size
10936 + );
10937 +
10938 + return rv;
10939 +}
10940 +
10941 +CK_RV
10942 +pkcs11h_certificate_create (
10943 + IN const pkcs11h_certificate_id_t certificate_id,
10944 + IN void * const user_data,
10945 + IN const unsigned mask_prompt,
10946 + IN const int pin_cache_period,
10947 + OUT pkcs11h_certificate_t * const p_certificate
10948 +) {
10949 + pkcs11h_certificate_t certificate = NULL;
10950 + CK_RV rv = CKR_OK;
10951 +
10952 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
10953 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
10954 + /*PKCS11H_ASSERT (user_data!=NULL); NOT NEEDED */
10955 + PKCS11H_ASSERT (p_certificate!=NULL);
10956 +
10957 + PKCS11H_DEBUG (
10958 + PKCS11H_LOG_DEBUG2,
10959 + "PKCS#11: pkcs11h_certificate_create entry certificate_id=%p, user_data=%p, mask_prompt=%08x, pin_cache_period=%d, p_certificate=%p",
10960 + (void *)certificate_id,
10961 + user_data,
10962 + mask_prompt,
10963 + pin_cache_period,
10964 + (void *)p_certificate
10965 + );
10966 +
10967 + *p_certificate = NULL;
10968 +
10969 + if (
10970 + rv == CKR_OK &&
10971 + (rv = _pkcs11h_mem_malloc ((void*)&certificate, sizeof (struct pkcs11h_certificate_s))) == CKR_OK
10972 + ) {
10973 + certificate->user_data = user_data;
10974 + certificate->mask_prompt = mask_prompt;
10975 + certificate->key_handle = PKCS11H_INVALID_OBJECT_HANDLE;
10976 + certificate->pin_cache_period = pin_cache_period;
10977 + }
10978 +
10979 +#if defined(ENABLE_PKCS11H_THREADING)
10980 + if (rv == CKR_OK) {
10981 + rv = _pkcs11h_threading_mutexInit (&certificate->mutex);
10982 + }
10983 +#endif
10984 +
10985 + if (rv == CKR_OK) {
10986 + rv = pkcs11h_certificate_duplicateCertificateId (&certificate->id, certificate_id);
10987 + }
10988 +
10989 + if (rv == CKR_OK) {
10990 + *p_certificate = certificate;
10991 + certificate = NULL;
10992 + }
10993 +
10994 + if (certificate != NULL) {
10995 +#if defined(ENABLE_PKCS11H_THREADING)
10996 + _pkcs11h_threading_mutexFree (&certificate->mutex);
10997 +#endif
10998 + _pkcs11h_mem_free ((void *)&certificate);
10999 + }
11000 +
11001 + PKCS11H_DEBUG (
11002 + PKCS11H_LOG_DEBUG2,
11003 + "PKCS#11: pkcs11h_certificate_create return rv=%ld-'%s' *p_certificate=%p",
11004 + rv,
11005 + pkcs11h_getMessage (rv),
11006 + (void *)*p_certificate
11007 + );
11008 +
11009 + return rv;
11010 +}
11011 +
11012 +unsigned
11013 +pkcs11h_certificate_getPromptMask (
11014 + IN const pkcs11h_certificate_t certificate
11015 +) {
11016 + PKCS11H_ASSERT (certificate!=NULL);
11017 +
11018 + return certificate->mask_prompt;
11019 +}
11020 +
11021 +void
11022 +pkcs11h_certificate_setPromptMask (
11023 + IN const pkcs11h_certificate_t certificate,
11024 + IN const unsigned mask_prompt
11025 +) {
11026 + PKCS11H_ASSERT (certificate!=NULL);
11027 +
11028 + certificate->mask_prompt = mask_prompt;
11029 +}
11030 +
11031 +void *
11032 +pkcs11h_certificate_getUserData (
11033 + IN const pkcs11h_certificate_t certificate
11034 +) {
11035 + PKCS11H_ASSERT (certificate!=NULL);
11036 +
11037 + return certificate->user_data;
11038 +}
11039 +
11040 +void
11041 +pkcs11h_certificate_setUserData (
11042 + IN const pkcs11h_certificate_t certificate,
11043 + IN void * const user_data
11044 +) {
11045 + PKCS11H_ASSERT (certificate!=NULL);
11046 +
11047 + certificate->user_data = user_data;
11048 +}
11049 +
11050 +CK_RV
11051 +pkcs11h_certificate_getCertificateId (
11052 + IN const pkcs11h_certificate_t certificate,
11053 + OUT pkcs11h_certificate_id_t * const p_certificate_id
11054 +) {
11055 + CK_RV rv = CKR_OK;
11056 +
11057 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
11058 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
11059 + PKCS11H_ASSERT (certificate!=NULL);
11060 + PKCS11H_ASSERT (p_certificate_id!=NULL);
11061 +
11062 + PKCS11H_DEBUG (
11063 + PKCS11H_LOG_DEBUG2,
11064 + "PKCS#11: pkcs11h_certificate_getCertificateId entry certificate=%p, certificate_id=%p",
11065 + (void *)certificate,
11066 + (void *)p_certificate_id
11067 + );
11068 +
11069 + if (rv == CKR_OK) {
11070 + rv = pkcs11h_certificate_duplicateCertificateId (
11071 + p_certificate_id,
11072 + certificate->id
11073 + );
11074 + }
11075 +
11076 + PKCS11H_DEBUG (
11077 + PKCS11H_LOG_DEBUG2,
11078 + "PKCS#11: pkcs11h_certificate_getCertificateId return rv=%ld-'%s'",
11079 + rv,
11080 + pkcs11h_getMessage (rv)
11081 + );
11082 +
11083 + return rv;
11084 +}
11085 +
11086 +CK_RV
11087 +pkcs11h_certificate_getCertificateBlob (
11088 + IN const pkcs11h_certificate_t certificate,
11089 + OUT unsigned char * const certificate_blob,
11090 + IN OUT size_t * const p_certificate_blob_size
11091 +) {
11092 +#if defined(ENABLE_PKCS11H_THREADING)
11093 + PKCS11H_BOOL mutex_locked = FALSE;
11094 +#endif
11095 + CK_RV rv = CKR_OK;
11096 + size_t certifiate_blob_size_max = 0;
11097 +
11098 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
11099 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
11100 + PKCS11H_ASSERT (certificate!=NULL);
11101 + /*PKCS11H_ASSERT (certificate_blob!=NULL); NOT NEEDED */
11102 + PKCS11H_ASSERT (p_certificate_blob_size!=NULL);
11103 +
11104 + PKCS11H_DEBUG (
11105 + PKCS11H_LOG_DEBUG2,
11106 + "PKCS#11: pkcs11h_certificate_getCertificateBlob entry certificate=%p, certificate_blob=%p, *p_certificate_blob_size=%u",
11107 + (void *)certificate,
11108 + certificate_blob,
11109 + certificate_blob != NULL ? *p_certificate_blob_size : 0
11110 + );
11111 +
11112 + if (certificate_blob != NULL) {
11113 + certifiate_blob_size_max = *p_certificate_blob_size;
11114 + }
11115 + *p_certificate_blob_size = 0;
11116 +
11117 +#if defined(ENABLE_PKCS11H_THREADING)
11118 + if (
11119 + rv == CKR_OK &&
11120 + (rv = _pkcs11h_threading_mutexLock (&certificate->mutex)) == CKR_OK
11121 + ) {
11122 + mutex_locked = TRUE;
11123 + }
11124 +#endif
11125 +
11126 + if (rv == CKR_OK && certificate->id->certificate_blob == NULL) {
11127 + PKCS11H_BOOL op_succeed = FALSE;
11128 + PKCS11H_BOOL login_retry = FALSE;
11129 + while (rv == CKR_OK && !op_succeed) {
11130 + if (certificate->session == NULL) {
11131 + rv = CKR_SESSION_HANDLE_INVALID;
11132 + }
11133 +
11134 + if (rv == CKR_OK) {
11135 + rv = _pkcs11h_certificate_loadCertificate (certificate);
11136 + }
11137 +
11138 + if (rv == CKR_OK) {
11139 + op_succeed = TRUE;
11140 + }
11141 + else {
11142 + if (!login_retry) {
11143 + login_retry = TRUE;
11144 + rv = _pkcs11h_certificate_resetSession (
11145 + certificate,
11146 + TRUE,
11147 + FALSE
11148 + );
11149 + }
11150 + }
11151 + }
11152 + }
11153 +
11154 + if (
11155 + rv == CKR_OK &&
11156 + certificate->id->certificate_blob == NULL
11157 + ) {
11158 + rv = CKR_FUNCTION_REJECTED;
11159 + }
11160 +
11161 + if (rv == CKR_OK) {
11162 + _pkcs11h_certificate_updateCertificateIdDescription (certificate->id);
11163 + }
11164 +
11165 + if (rv == CKR_OK) {
11166 + *p_certificate_blob_size = certificate->id->certificate_blob_size;
11167 + }
11168 +
11169 + if (certificate_blob != NULL) {
11170 + if (
11171 + rv == CKR_OK &&
11172 + certificate->id->certificate_blob_size > certifiate_blob_size_max
11173 + ) {
11174 + rv = CKR_BUFFER_TOO_SMALL;
11175 + }
11176 +
11177 + if (rv == CKR_OK) {
11178 + memmove (
11179 + certificate_blob,
11180 + certificate->id->certificate_blob,
11181 + *p_certificate_blob_size
11182 + );
11183 + }
11184 + }
11185 +
11186 +#if defined(ENABLE_PKCS11H_THREADING)
11187 + if (mutex_locked) {
11188 + _pkcs11h_threading_mutexRelease (&certificate->mutex);
11189 + mutex_locked = FALSE;
11190 + }
11191 +#endif
11192 +
11193 + PKCS11H_DEBUG (
11194 + PKCS11H_LOG_DEBUG2,
11195 + "PKCS#11: pkcs11h_certificate_getCertificateBlob return rv=%ld-'%s'",
11196 + rv,
11197 + pkcs11h_getMessage (rv)
11198 + );
11199 +
11200 + return rv;
11201 +}
11202 +
11203 +#if defined(ENABLE_PKCS11H_SERIALIZATION)
11204 +
11205 +CK_RV
11206 +pkcs11h_certificate_serializeCertificateId (
11207 + OUT char * const sz,
11208 + IN OUT size_t *max,
11209 + IN const pkcs11h_certificate_id_t certificate_id
11210 +) {
11211 + CK_RV rv = CKR_OK;
11212 + size_t saved_max = 0;
11213 + size_t n = 0;
11214 + size_t _max = 0;
11215 +
11216 + /*PKCS11H_ASSERT (sz!=NULL); Not required */
11217 + PKCS11H_ASSERT (max!=NULL);
11218 + PKCS11H_ASSERT (certificate_id!=NULL);
11219 +
11220 + PKCS11H_DEBUG (
11221 + PKCS11H_LOG_DEBUG2,
11222 + "PKCS#11: pkcs11h_certificate_serializeCertificateId entry sz=%p, *max=%u, certificate_id=%p",
11223 + sz,
11224 + sz != NULL ? *max : 0,
11225 + (void *)certificate_id
11226 + );
11227 +
11228 + if (sz != NULL) {
11229 + saved_max = n = *max;
11230 + }
11231 + *max = 0;
11232 +
11233 + if (rv == CKR_OK) {
11234 + rv = pkcs11h_token_serializeTokenId (
11235 + sz,
11236 + &n,
11237 + certificate_id->token_id
11238 + );
11239 + }
11240 +
11241 + if (rv == CKR_OK) {
11242 + _max = n + certificate_id->attrCKA_ID_size*2 + 1;
11243 + }
11244 +
11245 + if (sz != NULL) {
11246 + if (saved_max < _max) {
11247 + rv = CKR_ATTRIBUTE_VALUE_INVALID;
11248 + }
11249 +
11250 + if (rv == CKR_OK) {
11251 + sz[n-1] = '/';
11252 + rv = _pkcs11h_util_binaryToHex (
11253 + sz+n,
11254 + saved_max-n,
11255 + certificate_id->attrCKA_ID,
11256 + certificate_id->attrCKA_ID_size
11257 + );
11258 +
11259 + }
11260 + }
11261 +
11262 + *max = _max;
11263 +
11264 + PKCS11H_DEBUG (
11265 + PKCS11H_LOG_DEBUG2,
11266 + "PKCS#11: pkcs11h_certificate_serializeCertificateId return rv=%ld-'%s', *max=%u, sz='%s'",
11267 + rv,
11268 + pkcs11h_getMessage (rv),
11269 + *max,
11270 + sz
11271 + );
11272 +
11273 + return rv;
11274 +}
11275 +
11276 +CK_RV
11277 +pkcs11h_certificate_deserializeCertificateId (
11278 + OUT pkcs11h_certificate_id_t * const p_certificate_id,
11279 + IN const char * const sz
11280 +) {
11281 + pkcs11h_certificate_id_t certificate_id = NULL;
11282 + CK_RV rv = CKR_OK;
11283 + char *p = NULL;
11284 + char *_sz = NULL;
11285 +
11286 + PKCS11H_ASSERT (p_certificate_id!=NULL);
11287 + PKCS11H_ASSERT (sz!=NULL);
11288 +
11289 + *p_certificate_id = NULL;
11290 +
11291 + PKCS11H_DEBUG (
11292 + PKCS11H_LOG_DEBUG2,
11293 + "PKCS#11: pkcs11h_certificate_deserializeCertificateId entry p_certificate_id=%p, sz='%s'",
11294 + (void *)p_certificate_id,
11295 + sz
11296 + );
11297 +
11298 + if (rv == CKR_OK) {
11299 + rv = _pkcs11h_mem_strdup (
11300 + (void *)&_sz,
11301 + sz
11302 + );
11303 + }
11304 +
11305 + if (rv == CKR_OK) {
11306 + p = _sz;
11307 + }
11308 +
11309 + if (rv == CKR_OK) {
11310 + rv = _pkcs11h_certificate_newCertificateId (&certificate_id);
11311 + }
11312 +
11313 + if (
11314 + rv == CKR_OK &&
11315 + (p = strrchr (_sz, '/')) == NULL
11316 + ) {
11317 + rv = CKR_ATTRIBUTE_VALUE_INVALID;
11318 + }
11319 +
11320 + if (rv == CKR_OK) {
11321 + *p = '\x0';
11322 + p++;
11323 + }
11324 +
11325 + if (rv == CKR_OK) {
11326 + rv = pkcs11h_token_deserializeTokenId (
11327 + &certificate_id->token_id,
11328 + _sz
11329 + );
11330 + }
11331 +
11332 + if (rv == CKR_OK) {
11333 + certificate_id->attrCKA_ID_size = strlen (p)/2;
11334 + }
11335 +
11336 + if (
11337 + rv == CKR_OK &&
11338 + (rv = _pkcs11h_mem_malloc (
11339 + (void *)&certificate_id->attrCKA_ID,
11340 + certificate_id->attrCKA_ID_size)
11341 + ) == CKR_OK
11342 + ) {
11343 + rv = _pkcs11h_util_hexToBinary (
11344 + certificate_id->attrCKA_ID,
11345 + p,
11346 + &certificate_id->attrCKA_ID_size
11347 + );
11348 + }
11349 +
11350 + if (rv == CKR_OK) {
11351 + *p_certificate_id = certificate_id;
11352 + certificate_id = NULL;
11353 + }
11354 +
11355 + if (certificate_id != NULL) {
11356 + pkcs11h_certificate_freeCertificateId (certificate_id);
11357 + certificate_id = NULL;
11358 + }
11359 +
11360 + if (_sz != NULL) {
11361 + _pkcs11h_mem_free ((void *)&_sz);
11362 + }
11363 +
11364 + PKCS11H_DEBUG (
11365 + PKCS11H_LOG_DEBUG2,
11366 + "PKCS#11: pkcs11h_certificate_deserializeCertificateId return rv=%ld-'%s'",
11367 + rv,
11368 + pkcs11h_getMessage (rv)
11369 + );
11370 +
11371 + return rv;
11372 +
11373 +}
11374 +
11375 +#endif /* ENABLE_PKCS11H_SERIALIZATION */
11376 +
11377 +CK_RV
11378 +pkcs11h_certificate_ensureCertificateAccess (
11379 + IN const pkcs11h_certificate_t certificate
11380 +) {
11381 +#if defined(ENABLE_PKCS11H_THREADING)
11382 + PKCS11H_BOOL mutex_locked_cert = FALSE;
11383 + PKCS11H_BOOL mutex_locked_sess = FALSE;
11384 +#endif
11385 + PKCS11H_BOOL validCert = FALSE;
11386 + CK_RV rv = CKR_OK;
11387 +
11388 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
11389 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
11390 + PKCS11H_ASSERT (certificate!=NULL);
11391 +
11392 + PKCS11H_DEBUG (
11393 + PKCS11H_LOG_DEBUG2,
11394 + "PKCS#11: pkcs11h_certificate_ensureCertificateAccess entry certificate=%p",
11395 + (void *)certificate
11396 + );
11397 +
11398 +#if defined(ENABLE_PKCS11H_THREADING)
11399 + if (
11400 + rv == CKR_OK &&
11401 + (rv = _pkcs11h_threading_mutexLock (&certificate->mutex)) == CKR_OK
11402 + ) {
11403 + mutex_locked_cert = TRUE;
11404 + }
11405 +#endif
11406 +
11407 + if (!validCert && rv == CKR_OK) {
11408 + CK_OBJECT_HANDLE h = PKCS11H_INVALID_OBJECT_HANDLE;
11409 +
11410 + if (certificate->session == NULL) {
11411 + rv = CKR_SESSION_HANDLE_INVALID;
11412 + }
11413 +
11414 +#if defined(ENABLE_PKCS11H_THREADING)
11415 + if (
11416 + rv == CKR_OK &&
11417 + (rv = _pkcs11h_threading_mutexLock (&certificate->session->mutex)) == CKR_OK
11418 + ) {
11419 + mutex_locked_sess = TRUE;
11420 + }
11421 +#endif
11422 +
11423 + if (
11424 + (rv = _pkcs11h_session_getObjectById (
11425 + certificate->session,
11426 + CKO_CERTIFICATE,
11427 + certificate->id->attrCKA_ID,
11428 + certificate->id->attrCKA_ID_size,
11429 + &h
11430 + )) == CKR_OK
11431 + ) {
11432 + validCert = TRUE;
11433 + }
11434 +
11435 +#if defined(ENABLE_PKCS11H_THREADING)
11436 + if (mutex_locked_sess) {
11437 + _pkcs11h_threading_mutexRelease (&certificate->session->mutex);
11438 + mutex_locked_sess = FALSE;
11439 + }
11440 +#endif
11441 +
11442 + if (rv != CKR_OK) {
11443 + PKCS11H_DEBUG (
11444 + PKCS11H_LOG_DEBUG1,
11445 + "PKCS#11: Cannot access existing object rv=%ld-'%s'",
11446 + rv,
11447 + pkcs11h_getMessage (rv)
11448 + );
11449 +
11450 + /*
11451 + * Ignore error
11452 + */
11453 + rv = CKR_OK;
11454 + }
11455 + }
11456 +
11457 + if (!validCert && rv == CKR_OK) {
11458 + if (
11459 + (rv = _pkcs11h_certificate_resetSession (
11460 + certificate,
11461 + TRUE,
11462 + FALSE
11463 + )) == CKR_OK
11464 + ) {
11465 + validCert = TRUE;
11466 + }
11467 + }
11468 +
11469 +#if defined(ENABLE_PKCS11H_THREADING)
11470 + if (mutex_locked_cert) {
11471 + _pkcs11h_threading_mutexRelease (&certificate->mutex);
11472 + mutex_locked_cert = FALSE;
11473 + }
11474 +#endif
11475 +
11476 + PKCS11H_DEBUG (
11477 + PKCS11H_LOG_DEBUG2,
11478 + "PKCS#11: pkcs11h_certificate_ensureCertificateAccess return rv=%ld-'%s'",
11479 + rv,
11480 + pkcs11h_getMessage (rv)
11481 + );
11482 +
11483 + return rv;
11484 +}
11485 +
11486 +CK_RV
11487 +pkcs11h_certificate_ensureKeyAccess (
11488 + IN const pkcs11h_certificate_t certificate
11489 +) {
11490 +#if defined(ENABLE_PKCS11H_THREADING)
11491 + PKCS11H_BOOL mutex_locked_cert = FALSE;
11492 + PKCS11H_BOOL mutex_locked_sess = FALSE;
11493 +#endif
11494 + CK_RV rv = CKR_OK;
11495 + PKCS11H_BOOL valid_key = FALSE;
11496 +
11497 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
11498 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
11499 + PKCS11H_ASSERT (certificate!=NULL);
11500 +
11501 + PKCS11H_DEBUG (
11502 + PKCS11H_LOG_DEBUG2,
11503 + "PKCS#11: pkcs11h_certificate_ensureKeyAccess entry certificate=%p",
11504 + (void *)certificate
11505 + );
11506 +
11507 +#if defined(ENABLE_PKCS11H_THREADING)
11508 + if (
11509 + rv == CKR_OK &&
11510 + (rv = _pkcs11h_threading_mutexLock (&certificate->mutex)) == CKR_OK
11511 + ) {
11512 + mutex_locked_cert = TRUE;
11513 + }
11514 +#endif
11515 +
11516 + if (!valid_key && rv == CKR_OK) {
11517 +
11518 + if (certificate->session == NULL) {
11519 + rv = CKR_SESSION_HANDLE_INVALID;
11520 + }
11521 +
11522 +#if defined(ENABLE_PKCS11H_THREADING)
11523 + if (
11524 + rv == CKR_OK &&
11525 + (rv = _pkcs11h_threading_mutexLock (&certificate->session->mutex)) == CKR_OK
11526 + ) {
11527 + mutex_locked_sess = TRUE;
11528 + }
11529 +#endif
11530 +
11531 + if (
11532 + (rv = _pkcs11h_session_getObjectById (
11533 + certificate->session,
11534 + CKO_PRIVATE_KEY,
11535 + certificate->id->attrCKA_ID,
11536 + certificate->id->attrCKA_ID_size,
11537 + &certificate->key_handle
11538 + )) == CKR_OK
11539 + ) {
11540 + valid_key = TRUE;
11541 + }
11542 +
11543 +#if defined(ENABLE_PKCS11H_THREADING)
11544 + if (mutex_locked_sess) {
11545 + _pkcs11h_threading_mutexRelease (&certificate->session->mutex);
11546 + mutex_locked_sess = FALSE;
11547 + }
11548 +#endif
11549 +
11550 + if (rv != CKR_OK) {
11551 + PKCS11H_DEBUG (
11552 + PKCS11H_LOG_DEBUG1,
11553 + "PKCS#11: Cannot access existing object rv=%ld-'%s'",
11554 + rv,
11555 + pkcs11h_getMessage (rv)
11556 + );
11557 +
11558 + /*
11559 + * Ignore error
11560 + */
11561 + rv = CKR_OK;
11562 + certificate->key_handle = PKCS11H_INVALID_OBJECT_HANDLE;
11563 + }
11564 + }
11565 +
11566 + if (!valid_key && rv == CKR_OK) {
11567 + if (
11568 + (rv = _pkcs11h_certificate_resetSession (
11569 + certificate,
11570 + FALSE,
11571 + FALSE
11572 + )) == CKR_OK
11573 + ) {
11574 + valid_key = TRUE;
11575 + }
11576 + }
11577 +
11578 +#if defined(ENABLE_PKCS11H_THREADING)
11579 + if (mutex_locked_sess) {
11580 + _pkcs11h_threading_mutexRelease (&certificate->session->mutex);
11581 + mutex_locked_sess = FALSE;
11582 + }
11583 +#endif
11584 +
11585 + PKCS11H_DEBUG (
11586 + PKCS11H_LOG_DEBUG2,
11587 + "PKCS#11: pkcs11h_certificate_ensureKeyAccess return rv=%ld-'%s'",
11588 + rv,
11589 + pkcs11h_getMessage (rv)
11590 + );
11591 +
11592 + return rv;
11593 +}
11594 +
11595 +#endif /* ENABLE_PKCS11H_CERTIFICATE */
11596 +
11597 +#if defined(ENABLE_PKCS11H_LOCATE)
11598 +/*======================================================================*
11599 + * LOCATE INTERFACE
11600 + *======================================================================*/
11601 +
11602 +#if defined(ENABLE_PKCS11H_TOKEN) || defined(ENABLE_PKCS11H_CERTIFICATE)
11603 +
11604 +static
11605 +CK_RV
11606 +_pkcs11h_locate_getTokenIdBySlotId (
11607 + IN const char * const slot,
11608 + OUT pkcs11h_token_id_t * const p_token_id
11609 +) {
11610 + pkcs11h_provider_t current_provider = NULL;
11611 + char reference[sizeof (((pkcs11h_provider_t)NULL)->reference)];
11612 +
11613 + CK_SLOT_ID selected_slot = PKCS11H_INVALID_SLOT_ID;
11614 + CK_TOKEN_INFO info;
11615 + CK_RV rv = CKR_OK;
11616 +
11617 + PKCS11H_ASSERT (slot!=NULL);
11618 + PKCS11H_ASSERT (p_token_id!=NULL);
11619 +
11620 + PKCS11H_DEBUG (
11621 + PKCS11H_LOG_DEBUG2,
11622 + "PKCS#11: _pkcs11h_locate_getTokenIdBySlotId entry slot='%s', p_token_id=%p",
11623 + slot,
11624 + (void *)p_token_id
11625 + );
11626 +
11627 + *p_token_id = NULL;
11628 +
11629 + if (rv == CKR_OK) {
11630 + if (strchr (slot, ':') == NULL) {
11631 + reference[0] = '\0';
11632 + selected_slot = atol (slot);
11633 + }
11634 + else {
11635 + char *p;
11636 +
11637 + strncpy (reference, slot, sizeof (reference));
11638 + reference[sizeof (reference)-1] = '\0';
11639 +
11640 + p = strchr (reference, ':');
11641 +
11642 + *p = '\0';
11643 + p++;
11644 + selected_slot = atol (p);
11645 + }
11646 + }
11647 +
11648 + if (rv == CKR_OK) {
11649 + current_provider=s_pkcs11h_data->providers;
11650 + while (
11651 + current_provider != NULL &&
11652 + reference[0] != '\0' && /* So first provider will be selected */
11653 + strcmp (current_provider->reference, reference)
11654 + ) {
11655 + current_provider = current_provider->next;
11656 + }
11657 +
11658 + if (
11659 + current_provider == NULL ||
11660 + (
11661 + current_provider != NULL &&
11662 + !current_provider->enabled
11663 + )
11664 + ) {
11665 + rv = CKR_SLOT_ID_INVALID;
11666 + }
11667 + }
11668 +
11669 + if (
11670 + rv == CKR_OK &&
11671 + (rv = current_provider->f->C_GetTokenInfo (selected_slot, &info)) == CKR_OK
11672 + ) {
11673 + rv = _pkcs11h_token_getTokenId (
11674 + &info,
11675 + p_token_id
11676 + );
11677 + }
11678 +
11679 + PKCS11H_DEBUG (
11680 + PKCS11H_LOG_DEBUG2,
11681 + "PKCS#11: _pkcs11h_locate_getTokenIdBySlotId return rv=%ld-'%s', *p_token_id=%p",
11682 + rv,
11683 + pkcs11h_getMessage (rv),
11684 + (void *)*p_token_id
11685 + );
11686 +
11687 + return rv;
11688 +}
11689 +
11690 +static
11691 +CK_RV
11692 +_pkcs11h_locate_getTokenIdBySlotName (
11693 + IN const char * const name,
11694 + OUT pkcs11h_token_id_t * const p_token_id
11695 +) {
11696 + pkcs11h_provider_t current_provider = NULL;
11697 +
11698 + CK_SLOT_ID selected_slot = PKCS11H_INVALID_SLOT_ID;
11699 + CK_TOKEN_INFO info;
11700 + CK_RV rv = CKR_OK;
11701 +
11702 + PKCS11H_BOOL found = FALSE;
11703 +
11704 + PKCS11H_ASSERT (name!=NULL);
11705 + PKCS11H_ASSERT (p_token_id!=NULL);
11706 +
11707 + PKCS11H_DEBUG (
11708 + PKCS11H_LOG_DEBUG2,
11709 + "PKCS#11: _pkcs11h_locate_getTokenIdBySlotName entry name='%s', p_token_id=%p",
11710 + name,
11711 + (void *)p_token_id
11712 + );
11713 +
11714 + *p_token_id = NULL;
11715 +
11716 + current_provider = s_pkcs11h_data->providers;
11717 + while (
11718 + current_provider != NULL &&
11719 + rv == CKR_OK &&
11720 + !found
11721 + ) {
11722 + CK_SLOT_ID_PTR slots = NULL;
11723 + CK_ULONG slotnum;
11724 + CK_SLOT_ID slot_index;
11725 +
11726 + if (!current_provider->enabled) {
11727 + rv = CKR_CRYPTOKI_NOT_INITIALIZED;
11728 + }
11729 +
11730 + if (rv == CKR_OK) {
11731 + rv = _pkcs11h_session_getSlotList (
11732 + current_provider,
11733 + CK_TRUE,
11734 + &slots,
11735 + &slotnum
11736 + );
11737 + }
11738 +
11739 + for (
11740 + slot_index=0;
11741 + (
11742 + slot_index < slotnum &&
11743 + rv == CKR_OK &&
11744 + !found
11745 + );
11746 + slot_index++
11747 + ) {
11748 + CK_SLOT_INFO info;
11749 +
11750 + if (
11751 + (rv = current_provider->f->C_GetSlotInfo (
11752 + slots[slot_index],
11753 + &info
11754 + )) == CKR_OK
11755 + ) {
11756 + char current_name[sizeof (info.slotDescription)+1];
11757 +
11758 + _pkcs11h_util_fixupFixedString (
11759 + current_name,
11760 + (char *)info.slotDescription,
11761 + sizeof (info.slotDescription)
11762 + );
11763 +
11764 + if (!strcmp (current_name, name)) {
11765 + found = TRUE;
11766 + selected_slot = slots[slot_index];
11767 + }
11768 + }
11769 +
11770 + if (rv != CKR_OK) {
11771 + PKCS11H_DEBUG (
11772 + PKCS11H_LOG_DEBUG1,
11773 + "PKCS#11: Cannot get slot information for provider '%s' slot %ld rv=%ld-'%s'",
11774 + current_provider->manufacturerID,
11775 + slots[slot_index],
11776 + rv,
11777 + pkcs11h_getMessage (rv)
11778 + );
11779 +
11780 + /*
11781 + * Ignore error
11782 + */
11783 + rv = CKR_OK;
11784 + }
11785 + }
11786 +
11787 + if (rv != CKR_OK) {
11788 + PKCS11H_DEBUG (
11789 + PKCS11H_LOG_DEBUG1,
11790 + "PKCS#11: Cannot get slot list for provider '%s' rv=%ld-'%s'",
11791 + current_provider->manufacturerID,
11792 + rv,
11793 + pkcs11h_getMessage (rv)
11794 + );
11795 +
11796 + /*
11797 + * Ignore error
11798 + */
11799 + rv = CKR_OK;
11800 + }
11801 +
11802 + if (slots != NULL) {
11803 + _pkcs11h_mem_free ((void *)&slots);
11804 + slots = NULL;
11805 + }
11806 +
11807 + if (!found) {
11808 + current_provider = current_provider->next;
11809 + }
11810 + }
11811 +
11812 + if (rv == CKR_OK && !found) {
11813 + rv = CKR_SLOT_ID_INVALID;
11814 + }
11815 +
11816 + if (
11817 + rv == CKR_OK &&
11818 + (rv = current_provider->f->C_GetTokenInfo (selected_slot, &info)) == CKR_OK
11819 + ) {
11820 + rv = _pkcs11h_token_getTokenId (
11821 + &info,
11822 + p_token_id
11823 + );
11824 + }
11825 +
11826 + PKCS11H_DEBUG (
11827 + PKCS11H_LOG_DEBUG2,
11828 + "PKCS#11: _pkcs11h_locate_getTokenIdBySlotName return rv=%ld-'%s' *p_token_id=%p",
11829 + rv,
11830 + pkcs11h_getMessage (rv),
11831 + (void *)*p_token_id
11832 + );
11833 +
11834 + return rv;
11835 +}
11836 +
11837 +static
11838 +CK_RV
11839 +_pkcs11h_locate_getTokenIdByLabel (
11840 + IN const char * const label,
11841 + OUT pkcs11h_token_id_t * const p_token_id
11842 +) {
11843 + pkcs11h_provider_t current_provider = NULL;
11844 +
11845 + CK_SLOT_ID selected_slot = PKCS11H_INVALID_SLOT_ID;
11846 + CK_TOKEN_INFO info;
11847 + CK_RV rv = CKR_OK;
11848 +
11849 + PKCS11H_BOOL found = FALSE;
11850 +
11851 + PKCS11H_ASSERT (label!=NULL);
11852 + PKCS11H_ASSERT (p_token_id!=NULL);
11853 +
11854 + PKCS11H_DEBUG (
11855 + PKCS11H_LOG_DEBUG2,
11856 + "PKCS#11: _pkcs11h_locate_getTokenIdByLabel entry label='%s', p_token_id=%p",
11857 + label,
11858 + (void *)p_token_id
11859 + );
11860 +
11861 + *p_token_id = NULL;
11862 +
11863 + current_provider = s_pkcs11h_data->providers;
11864 + while (
11865 + current_provider != NULL &&
11866 + rv == CKR_OK &&
11867 + !found
11868 + ) {
11869 + CK_SLOT_ID_PTR slots = NULL;
11870 + CK_ULONG slotnum;
11871 + CK_SLOT_ID slot_index;
11872 +
11873 + if (!current_provider->enabled) {
11874 + rv = CKR_CRYPTOKI_NOT_INITIALIZED;
11875 + }
11876 +
11877 + if (rv == CKR_OK) {
11878 + rv = _pkcs11h_session_getSlotList (
11879 + current_provider,
11880 + CK_TRUE,
11881 + &slots,
11882 + &slotnum
11883 + );
11884 + }
11885 +
11886 + for (
11887 + slot_index=0;
11888 + (
11889 + slot_index < slotnum &&
11890 + rv == CKR_OK &&
11891 + !found
11892 + );
11893 + slot_index++
11894 + ) {
11895 + CK_TOKEN_INFO info;
11896 +
11897 + if (rv == CKR_OK) {
11898 + rv = current_provider->f->C_GetTokenInfo (
11899 + slots[slot_index],
11900 + &info
11901 + );
11902 + }
11903 +
11904 + if (rv == CKR_OK) {
11905 + char current_label[sizeof (info.label)+1];
11906 +
11907 + _pkcs11h_util_fixupFixedString (
11908 + current_label,
11909 + (char *)info.label,
11910 + sizeof (info.label)
11911 + );
11912 +
11913 + if (!strcmp (current_label, label)) {
11914 + found = TRUE;
11915 + selected_slot = slots[slot_index];
11916 + }
11917 + }
11918 +
11919 + if (rv != CKR_OK) {
11920 + PKCS11H_DEBUG (
11921 + PKCS11H_LOG_DEBUG1,
11922 + "PKCS#11: Cannot get token information for provider '%s' slot %ld rv=%ld-'%s'",
11923 + current_provider->manufacturerID,
11924 + slots[slot_index],
11925 + rv,
11926 + pkcs11h_getMessage (rv)
11927 + );
11928 +
11929 + /*
11930 + * Ignore error
11931 + */
11932 + rv = CKR_OK;
11933 + }
11934 + }
11935 +
11936 + if (rv != CKR_OK) {
11937 + PKCS11H_DEBUG (
11938 + PKCS11H_LOG_DEBUG1,
11939 + "PKCS#11: Cannot get slot list for provider '%s' rv=%ld-'%s'",
11940 + current_provider->manufacturerID,
11941 + rv,
11942 + pkcs11h_getMessage (rv)
11943 + );
11944 +
11945 + /*
11946 + * Ignore error
11947 + */
11948 + rv = CKR_OK;
11949 + }
11950 +
11951 + if (slots != NULL) {
11952 + _pkcs11h_mem_free ((void *)&slots);
11953 + slots = NULL;
11954 + }
11955 +
11956 + if (!found) {
11957 + current_provider = current_provider->next;
11958 + }
11959 + }
11960 +
11961 + if (rv == CKR_OK && !found) {
11962 + rv = CKR_SLOT_ID_INVALID;
11963 + }
11964 +
11965 + if (
11966 + rv == CKR_OK &&
11967 + (rv = current_provider->f->C_GetTokenInfo (selected_slot, &info)) == CKR_OK
11968 + ) {
11969 + rv = _pkcs11h_token_getTokenId (
11970 + &info,
11971 + p_token_id
11972 + );
11973 + }
11974 +
11975 + PKCS11H_DEBUG (
11976 + PKCS11H_LOG_DEBUG2,
11977 + "PKCS#11: _pkcs11h_locate_getTokenIdByLabel return rv=%ld-'%s', *p_token_id=%p",
11978 + rv,
11979 + pkcs11h_getMessage (rv),
11980 + (void *)*p_token_id
11981 + );
11982 +
11983 + return rv;
11984 +}
11985 +
11986 +CK_RV
11987 +pkcs11h_locate_token (
11988 + IN const char * const slot_type,
11989 + IN const char * const slot,
11990 + IN void * const user_data,
11991 + IN const unsigned mask_prompt,
11992 + OUT pkcs11h_token_id_t * const p_token_id
11993 +) {
11994 +#if defined(ENABLE_PKCS11H_THREADING)
11995 + PKCS11H_BOOL mutex_locked = FALSE;
11996 +#endif
11997 +
11998 + pkcs11h_token_id_t dummy_token_id = NULL;
11999 + pkcs11h_token_id_t token_id = NULL;
12000 + PKCS11H_BOOL found = FALSE;
12001 +
12002 + CK_RV rv = CKR_OK;
12003 +
12004 + unsigned nRetry = 0;
12005 +
12006 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
12007 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
12008 + PKCS11H_ASSERT (slot_type!=NULL);
12009 + PKCS11H_ASSERT (slot!=NULL);
12010 + /*PKCS11H_ASSERT (user_data) NOT NEEDED */
12011 + PKCS11H_ASSERT (p_token_id!=NULL);
12012 +
12013 + PKCS11H_DEBUG (
12014 + PKCS11H_LOG_DEBUG2,
12015 + "PKCS#11: pkcs11h_locate_token entry slot_type='%s', slot='%s', user_data=%p, p_token_id=%p",
12016 + slot_type,
12017 + slot,
12018 + user_data,
12019 + (void *)p_token_id
12020 + );
12021 +
12022 + *p_token_id = NULL;
12023 +
12024 +#if defined(ENABLE_PKCS11H_THREADING)
12025 + if (
12026 + rv == CKR_OK &&
12027 + (rv = _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.global)) == CKR_OK
12028 + ) {
12029 + mutex_locked = TRUE;
12030 + }
12031 +#endif
12032 +
12033 + if (
12034 + rv == CKR_OK &&
12035 + (rv = _pkcs11h_token_newTokenId (&dummy_token_id)) == CKR_OK
12036 + ) {
12037 + /*
12038 + * Temperary slot id
12039 + */
12040 + strcpy (dummy_token_id->display, "SLOT(");
12041 + strncat (dummy_token_id->display, slot_type, sizeof (dummy_token_id->display)-1-strlen (dummy_token_id->display));
12042 + strncat (dummy_token_id->display, "=", sizeof (dummy_token_id->display)-1-strlen (dummy_token_id->display));
12043 + strncat (dummy_token_id->display, slot, sizeof (dummy_token_id->display)-1-strlen (dummy_token_id->display));
12044 + strncat (dummy_token_id->display, ")", sizeof (dummy_token_id->display)-1-strlen (dummy_token_id->display));
12045 + dummy_token_id->display[sizeof (dummy_token_id->display)-1] = 0;
12046 + }
12047 +
12048 + while (rv == CKR_OK && !found) {
12049 + if (!strcmp (slot_type, "id")) {
12050 + rv = _pkcs11h_locate_getTokenIdBySlotId (
12051 + slot,
12052 + &token_id
12053 + );
12054 + }
12055 + else if (!strcmp (slot_type, "name")) {
12056 + rv = _pkcs11h_locate_getTokenIdBySlotName (
12057 + slot,
12058 + &token_id
12059 + );
12060 + }
12061 + else if (!strcmp (slot_type, "label")) {
12062 + rv = _pkcs11h_locate_getTokenIdByLabel (
12063 + slot,
12064 + &token_id
12065 + );
12066 + }
12067 + else {
12068 + rv = CKR_ARGUMENTS_BAD;
12069 + }
12070 +
12071 + if (rv == CKR_OK) {
12072 + found = TRUE;
12073 + }
12074 +
12075 + /*
12076 + * Ignore error, since we have what we
12077 + * want in found.
12078 + */
12079 + if (rv != CKR_OK && rv != CKR_ARGUMENTS_BAD) {
12080 + PKCS11H_DEBUG (
12081 + PKCS11H_LOG_DEBUG1,
12082 + "PKCS#11: pkcs11h_locate_token failed rv=%ld-'%s'",
12083 + rv,
12084 + pkcs11h_getMessage (rv)
12085 + );
12086 +
12087 + rv = CKR_OK;
12088 + }
12089 +
12090 + if (rv == CKR_OK && !found && (mask_prompt & PKCS11H_PROMPT_MAST_ALLOW_CARD_PROMPT) == 0) {
12091 + rv = CKR_TOKEN_NOT_PRESENT;
12092 + }
12093 +
12094 + if (rv == CKR_OK && !found) {
12095 +
12096 + PKCS11H_DEBUG (
12097 + PKCS11H_LOG_DEBUG1,
12098 + "PKCS#11: Calling token_prompt hook for '%s'",
12099 + dummy_token_id->display
12100 + );
12101 +
12102 + if (
12103 + !s_pkcs11h_data->hooks.token_prompt (
12104 + s_pkcs11h_data->hooks.token_prompt_data,
12105 + user_data,
12106 + dummy_token_id,
12107 + nRetry++
12108 + )
12109 + ) {
12110 + rv = CKR_CANCEL;
12111 + }
12112 +
12113 + PKCS11H_DEBUG (
12114 + PKCS11H_LOG_DEBUG1,
12115 + "PKCS#11: token_prompt returned %ld",
12116 + rv
12117 + );
12118 + }
12119 + }
12120 +
12121 + if (rv == CKR_OK && !found) {
12122 + rv = CKR_SLOT_ID_INVALID;
12123 + }
12124 +
12125 + if (rv == CKR_OK) {
12126 + *p_token_id = token_id;
12127 + token_id = NULL;
12128 + }
12129 +
12130 + if (dummy_token_id != NULL) {
12131 + pkcs11h_token_freeTokenId (dummy_token_id);
12132 + dummy_token_id = NULL;
12133 + }
12134 +
12135 +#if defined(ENABLE_PKCS11H_THREADING)
12136 + if (mutex_locked) {
12137 + _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.global);
12138 + mutex_locked = FALSE;
12139 + }
12140 +#endif
12141 +
12142 + PKCS11H_DEBUG (
12143 + PKCS11H_LOG_DEBUG2,
12144 + "PKCS#11: pkcs11h_locate_token return rv=%ld-'%s', *p_token_id=%p",
12145 + rv,
12146 + pkcs11h_getMessage (rv),
12147 + (void *)*p_token_id
12148 + );
12149 +
12150 + return rv;
12151 +}
12152 +
12153 +#endif /* ENABLE_PKCS11H_TOKEN || ENABLE_PKCS11H_CERTIFICATE */
12154 +
12155 +#if defined(ENABLE_PKCS11H_CERTIFICATE)
12156 +
12157 +static
12158 +CK_RV
12159 +_pkcs11h_locate_getCertificateIdByLabel (
12160 + IN const pkcs11h_session_t session,
12161 + IN OUT const pkcs11h_certificate_id_t certificate_id,
12162 + IN const char * const label
12163 +) {
12164 +#if defined(ENABLE_PKCS11H_THREADING)
12165 + PKCS11H_BOOL mutex_locked = FALSE;
12166 +#endif
12167 + CK_OBJECT_CLASS cert_filter_class = CKO_CERTIFICATE;
12168 + CK_ATTRIBUTE cert_filter[] = {
12169 + {CKA_CLASS, &cert_filter_class, sizeof (cert_filter_class)},
12170 + {CKA_LABEL, (CK_BYTE_PTR)label, strlen (label)}
12171 + };
12172 +
12173 + CK_OBJECT_HANDLE *objects = NULL;
12174 + CK_ULONG objects_found = 0;
12175 + CK_RV rv = CKR_OK;
12176 +
12177 + CK_ULONG i;
12178 +
12179 + PKCS11H_ASSERT (session!=NULL);
12180 + PKCS11H_ASSERT (certificate_id!=NULL);
12181 + PKCS11H_ASSERT (label!=NULL);
12182 +
12183 + PKCS11H_DEBUG (
12184 + PKCS11H_LOG_DEBUG2,
12185 + "PKCS#11: _pkcs11h_locate_getCertificateIdByLabel entry session=%p, certificate_id=%p, label='%s'",
12186 + (void *)session,
12187 + (void *)certificate_id,
12188 + label
12189 + );
12190 +
12191 +#if defined(ENABLE_PKCS11H_THREADING)
12192 + if (
12193 + rv == CKR_OK &&
12194 + (rv = _pkcs11h_threading_mutexLock (&session->mutex)) == CKR_OK
12195 + ) {
12196 + mutex_locked = TRUE;
12197 + }
12198 +#endif
12199 +
12200 + if (rv == CKR_OK) {
12201 + rv = _pkcs11h_session_validate (session);
12202 + }
12203 +
12204 + if (rv == CKR_OK) {
12205 + rv = _pkcs11h_session_findObjects (
12206 + session,
12207 + cert_filter,
12208 + sizeof (cert_filter) / sizeof (CK_ATTRIBUTE),
12209 + &objects,
12210 + &objects_found
12211 + );
12212 + }
12213 +
12214 + for (i=0;rv == CKR_OK && i < objects_found;i++) {
12215 + CK_ATTRIBUTE attrs[] = {
12216 + {CKA_ID, NULL, 0},
12217 + {CKA_VALUE, NULL, 0}
12218 + };
12219 +
12220 + if (rv == CKR_OK) {
12221 + rv = _pkcs11h_session_getObjectAttributes (
12222 + session,
12223 + objects[i],
12224 + attrs,
12225 + sizeof (attrs) / sizeof (CK_ATTRIBUTE)
12226 + );
12227 + }
12228 +
12229 + if (
12230 + rv == CKR_OK &&
12231 + _pkcs11h_certificate_isBetterCertificate (
12232 + certificate_id->certificate_blob,
12233 + certificate_id->certificate_blob_size,
12234 + attrs[1].pValue,
12235 + attrs[1].ulValueLen
12236 + )
12237 + ) {
12238 + if (certificate_id->attrCKA_ID != NULL) {
12239 + _pkcs11h_mem_free ((void *)&certificate_id->attrCKA_ID);
12240 + }
12241 + if (certificate_id->certificate_blob != NULL) {
12242 + _pkcs11h_mem_free ((void *)&certificate_id->certificate_blob);
12243 + }
12244 + rv = _pkcs11h_mem_duplicate (
12245 + (void *)&certificate_id->attrCKA_ID,
12246 + &certificate_id->attrCKA_ID_size,
12247 + attrs[0].pValue,
12248 + attrs[0].ulValueLen
12249 + );
12250 + rv = _pkcs11h_mem_duplicate (
12251 + (void *)&certificate_id->certificate_blob,
12252 + &certificate_id->certificate_blob_size,
12253 + attrs[1].pValue,
12254 + attrs[1].ulValueLen
12255 + );
12256 + }
12257 +
12258 + if (rv != CKR_OK) {
12259 + PKCS11H_DEBUG (
12260 + PKCS11H_LOG_DEBUG1,
12261 + "PKCS#11: Cannot get object attribute for provider '%s' object %ld rv=%ld-'%s'",
12262 + session->provider->manufacturerID,
12263 + objects[i],
12264 + rv,
12265 + pkcs11h_getMessage (rv)
12266 + );
12267 +
12268 + /*
12269 + * Ignore error
12270 + */
12271 + rv = CKR_OK;
12272 + }
12273 +
12274 + _pkcs11h_session_freeObjectAttributes (
12275 + attrs,
12276 + sizeof (attrs) / sizeof (CK_ATTRIBUTE)
12277 + );
12278 + }
12279 +
12280 + if (
12281 + rv == CKR_OK &&
12282 + certificate_id->certificate_blob == NULL
12283 + ) {
12284 + rv = CKR_ATTRIBUTE_VALUE_INVALID;
12285 + }
12286 +
12287 + if (objects != NULL) {
12288 + _pkcs11h_mem_free ((void *)&objects);
12289 + }
12290 +
12291 +#if defined(ENABLE_PKCS11H_THREADING)
12292 + if (mutex_locked) {
12293 + _pkcs11h_threading_mutexRelease (&session->mutex);
12294 + mutex_locked = FALSE;
12295 + }
12296 +#endif
12297 +
12298 + /*
12299 + * No need to free allocated objects
12300 + * on error, since the certificate_id
12301 + * should be free by caller.
12302 + */
12303 +
12304 + PKCS11H_DEBUG (
12305 + PKCS11H_LOG_DEBUG2,
12306 + "PKCS#11: _pkcs11h_locate_getCertificateIdByLabel return rv=%ld-'%s'",
12307 + rv,
12308 + pkcs11h_getMessage (rv)
12309 + );
12310 +
12311 + return rv;
12312 +}
12313 +
12314 +static
12315 +CK_RV
12316 +_pkcs11h_locate_getCertificateIdBySubject (
12317 + IN const pkcs11h_session_t session,
12318 + IN OUT const pkcs11h_certificate_id_t certificate_id,
12319 + IN const char * const subject
12320 +) {
12321 +#if defined(ENABLE_PKCS11H_THREADING)
12322 + PKCS11H_BOOL mutex_locked = FALSE;
12323 +#endif
12324 + CK_OBJECT_CLASS cert_filter_class = CKO_CERTIFICATE;
12325 + CK_ATTRIBUTE cert_filter[] = {
12326 + {CKA_CLASS, &cert_filter_class, sizeof (cert_filter_class)}
12327 + };
12328 +
12329 + CK_OBJECT_HANDLE *objects = NULL;
12330 + CK_ULONG objects_found = 0;
12331 + CK_RV rv = CKR_OK;
12332 +
12333 + CK_ULONG i;
12334 +
12335 + PKCS11H_ASSERT (session!=NULL);
12336 + PKCS11H_ASSERT (certificate_id!=NULL);
12337 + PKCS11H_ASSERT (subject!=NULL);
12338 +
12339 + PKCS11H_DEBUG (
12340 + PKCS11H_LOG_DEBUG2,
12341 + "PKCS#11: _pkcs11h_locate_getCertificateIdBySubject entry session=%p, certificate_id=%p, subject='%s'",
12342 + (void *)session,
12343 + (void *)certificate_id,
12344 + subject
12345 + );
12346 +
12347 +#if defined(ENABLE_PKCS11H_THREADING)
12348 + if (
12349 + rv == CKR_OK &&
12350 + (rv = _pkcs11h_threading_mutexLock (&session->mutex)) == CKR_OK
12351 + ) {
12352 + mutex_locked = TRUE;
12353 + }
12354 +#endif
12355 +
12356 + if (rv == CKR_OK) {
12357 + rv = _pkcs11h_session_validate (session);
12358 + }
12359 +
12360 + if (rv == CKR_OK) {
12361 + rv = _pkcs11h_session_findObjects (
12362 + session,
12363 + cert_filter,
12364 + sizeof (cert_filter) / sizeof (CK_ATTRIBUTE),
12365 + &objects,
12366 + &objects_found
12367 + );
12368 + }
12369 +
12370 +#if defined(ENABLE_PKCS11H_THREADING)
12371 + if (mutex_locked) {
12372 + _pkcs11h_threading_mutexRelease (&session->mutex);
12373 + mutex_locked = FALSE;
12374 + }
12375 +#endif
12376 +
12377 + for (i=0;rv == CKR_OK && i < objects_found;i++) {
12378 + CK_ATTRIBUTE attrs[] = {
12379 + {CKA_ID, NULL, 0},
12380 + {CKA_VALUE, NULL, 0}
12381 + };
12382 + char current_subject[1024];
12383 + current_subject[0] = '\0';
12384 +
12385 + if (rv == CKR_OK) {
12386 + rv = _pkcs11h_session_getObjectAttributes (
12387 + session,
12388 + objects[i],
12389 + attrs,
12390 + sizeof (attrs) / sizeof (CK_ATTRIBUTE)
12391 + );
12392 + }
12393 +
12394 + if (rv == CKR_OK) {
12395 + rv = _pkcs11h_certificate_getDN (
12396 + attrs[1].pValue,
12397 + attrs[1].ulValueLen,
12398 + current_subject,
12399 + sizeof (current_subject)
12400 + );
12401 + }
12402 +
12403 + if (
12404 + rv == CKR_OK &&
12405 + !strcmp (subject, current_subject) &&
12406 + _pkcs11h_certificate_isBetterCertificate (
12407 + certificate_id->certificate_blob,
12408 + certificate_id->certificate_blob_size,
12409 + attrs[1].pValue,
12410 + attrs[1].ulValueLen
12411 + )
12412 + ) {
12413 + if (certificate_id->attrCKA_ID != NULL) {
12414 + _pkcs11h_mem_free ((void *)&certificate_id->attrCKA_ID);
12415 + }
12416 + if (certificate_id->certificate_blob != NULL) {
12417 + _pkcs11h_mem_free ((void *)&certificate_id->certificate_blob);
12418 + }
12419 + rv = _pkcs11h_mem_duplicate (
12420 + (void *)&certificate_id->attrCKA_ID,
12421 + &certificate_id->attrCKA_ID_size,
12422 + attrs[0].pValue,
12423 + attrs[0].ulValueLen
12424 + );
12425 + rv = _pkcs11h_mem_duplicate (
12426 + (void *)&certificate_id->certificate_blob,
12427 + &certificate_id->certificate_blob_size,
12428 + attrs[1].pValue,
12429 + attrs[1].ulValueLen
12430 + );
12431 + }
12432 +
12433 + if (rv != CKR_OK) {
12434 + PKCS11H_DEBUG (
12435 + PKCS11H_LOG_DEBUG1,
12436 + "PKCS#11: Cannot get object attribute for provider '%s' object %ld rv=%ld-'%s'",
12437 + session->provider->manufacturerID,
12438 + objects[i],
12439 + rv,
12440 + pkcs11h_getMessage (rv)
12441 + );
12442 +
12443 + /*
12444 + * Ignore error
12445 + */
12446 + rv = CKR_OK;
12447 + }
12448 +
12449 + _pkcs11h_session_freeObjectAttributes (
12450 + attrs,
12451 + sizeof (attrs) / sizeof (CK_ATTRIBUTE)
12452 + );
12453 + }
12454 +
12455 + if (
12456 + rv == CKR_OK &&
12457 + certificate_id->certificate_blob == NULL
12458 + ) {
12459 + rv = CKR_ATTRIBUTE_VALUE_INVALID;
12460 + }
12461 +
12462 + if (objects != NULL) {
12463 + _pkcs11h_mem_free ((void *)&objects);
12464 + }
12465 +
12466 + /*
12467 + * No need to free allocated objects
12468 + * on error, since the certificate_id
12469 + * should be free by caller.
12470 + */
12471 +
12472 + PKCS11H_DEBUG (
12473 + PKCS11H_LOG_DEBUG2,
12474 + "PKCS#11: _pkcs11h_locate_getCertificateIdBySubject return rv=%ld-'%s'",
12475 + rv,
12476 + pkcs11h_getMessage (rv)
12477 + );
12478 +
12479 + return rv;
12480 +}
12481 +
12482 +CK_RV
12483 +pkcs11h_locate_certificate (
12484 + IN const char * const slot_type,
12485 + IN const char * const slot,
12486 + IN const char * const id_type,
12487 + IN const char * const id,
12488 + IN void * const user_data,
12489 + IN const unsigned mask_prompt,
12490 + OUT pkcs11h_certificate_id_t * const p_certificate_id
12491 +) {
12492 +#if defined(ENABLE_PKCS11H_THREADING)
12493 + PKCS11H_BOOL mutex_locked = FALSE;
12494 +#endif
12495 + pkcs11h_certificate_id_t certificate_id = NULL;
12496 + pkcs11h_session_t session = NULL;
12497 + PKCS11H_BOOL op_succeed = FALSE;
12498 + PKCS11H_BOOL login_retry = FALSE;
12499 +
12500 + CK_RV rv = CKR_OK;
12501 +
12502 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
12503 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
12504 + PKCS11H_ASSERT (slot_type!=NULL);
12505 + PKCS11H_ASSERT (slot!=NULL);
12506 + PKCS11H_ASSERT (id_type!=NULL);
12507 + PKCS11H_ASSERT (id!=NULL);
12508 + /*PKCS11H_ASSERT (user_data) NOT NEEDED */
12509 + PKCS11H_ASSERT (p_certificate_id!=NULL);
12510 +
12511 + PKCS11H_DEBUG (
12512 + PKCS11H_LOG_DEBUG2,
12513 + "PKCS#11: pkcs11h_locateCertificate entry slot_type='%s', slot='%s', id_type='%s', id='%s', user_data=%p, mask_prompt=%08x, p_certificate_id=%p",
12514 + slot_type,
12515 + slot,
12516 + id_type,
12517 + id,
12518 + user_data,
12519 + mask_prompt,
12520 + (void *)p_certificate_id
12521 + );
12522 +
12523 + *p_certificate_id = NULL;
12524 +
12525 + if (rv == CKR_OK) {
12526 + rv = _pkcs11h_certificate_newCertificateId (&certificate_id);
12527 + }
12528 +
12529 + if (rv == CKR_OK) {
12530 + rv = pkcs11h_locate_token (
12531 + slot_type,
12532 + slot,
12533 + user_data,
12534 + mask_prompt,
12535 + &certificate_id->token_id
12536 + );
12537 + }
12538 +
12539 + if (rv == CKR_OK) {
12540 + rv = _pkcs11h_session_getSessionByTokenId (
12541 + certificate_id->token_id,
12542 + &session
12543 + );
12544 + }
12545 +
12546 +#if defined(ENABLE_PKCS11H_THREADING)
12547 + if (
12548 + rv == CKR_OK &&
12549 + (rv = _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.global)) == CKR_OK
12550 + ) {
12551 + mutex_locked = TRUE;
12552 + }
12553 +#endif
12554 +
12555 + while (rv == CKR_OK && !op_succeed) {
12556 + if (!strcmp (id_type, "id")) {
12557 + certificate_id->attrCKA_ID_size = strlen (id)/2;
12558 +
12559 + if (certificate_id->attrCKA_ID_size == 0) {
12560 + rv = CKR_FUNCTION_FAILED;
12561 + }
12562 +
12563 + if (
12564 + rv == CKR_OK &&
12565 + (rv = _pkcs11h_mem_malloc (
12566 + (void*)&certificate_id->attrCKA_ID,
12567 + certificate_id->attrCKA_ID_size
12568 + )) == CKR_OK
12569 + ) {
12570 + _pkcs11h_util_hexToBinary (
12571 + certificate_id->attrCKA_ID,
12572 + id,
12573 + &certificate_id->attrCKA_ID_size
12574 + );
12575 + }
12576 + }
12577 + else if (!strcmp (id_type, "label")) {
12578 + rv = _pkcs11h_locate_getCertificateIdByLabel (
12579 + session,
12580 + certificate_id,
12581 + id
12582 + );
12583 + }
12584 + else if (!strcmp (id_type, "subject")) {
12585 + rv = _pkcs11h_locate_getCertificateIdBySubject (
12586 + session,
12587 + certificate_id,
12588 + id
12589 + );
12590 + }
12591 + else {
12592 + rv = CKR_ARGUMENTS_BAD;
12593 + }
12594 +
12595 + if (rv == CKR_OK) {
12596 + op_succeed = TRUE;
12597 + }
12598 + else {
12599 + if (!login_retry) {
12600 + PKCS11H_DEBUG (
12601 + PKCS11H_LOG_DEBUG1,
12602 + "PKCS#11: Get certificate failed: %ld:'%s'",
12603 + rv,
12604 + pkcs11h_getMessage (rv)
12605 + );
12606 +
12607 + rv = _pkcs11h_session_login (
12608 + session,
12609 + TRUE,
12610 + TRUE,
12611 + user_data,
12612 + mask_prompt
12613 + );
12614 +
12615 + login_retry = TRUE;
12616 + }
12617 + }
12618 + }
12619 +
12620 +#if defined(ENABLE_PKCS11H_THREADING)
12621 + if (mutex_locked) {
12622 + _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.global);
12623 + mutex_locked = FALSE;
12624 + }
12625 +#endif
12626 +
12627 + if (rv == CKR_OK) {
12628 + *p_certificate_id = certificate_id;
12629 + certificate_id = NULL;
12630 + }
12631 +
12632 + if (certificate_id != NULL) {
12633 + pkcs11h_certificate_freeCertificateId (certificate_id);
12634 + certificate_id = NULL;
12635 + }
12636 +
12637 + if (session != NULL) {
12638 + _pkcs11h_session_release (session);
12639 + session = NULL;
12640 + }
12641 +
12642 + PKCS11H_DEBUG (
12643 + PKCS11H_LOG_DEBUG2,
12644 + "PKCS#11: pkcs11h_locateCertificate return rv=%ld-'%s' *p_certificate_id=%p",
12645 + rv,
12646 + pkcs11h_getMessage (rv),
12647 + (void *)*p_certificate_id
12648 + );
12649 +
12650 + return rv;
12651 +}
12652 +
12653 +#endif /* ENABLE_PKCS11H_CERTIFICATE */
12654 +
12655 +#endif /* ENABLE_PKCS11H_LOCATE */
12656 +
12657 +#if defined(ENABLE_PKCS11H_ENUM)
12658 +/*======================================================================*
12659 + * ENUM INTERFACE
12660 + *======================================================================*/
12661 +
12662 +#if defined(ENABLE_PKCS11H_TOKEN)
12663 +
12664 +CK_RV
12665 +pkcs11h_token_freeTokenIdList (
12666 + IN const pkcs11h_token_id_list_t token_id_list
12667 +) {
12668 + pkcs11h_token_id_list_t _id = token_id_list;
12669 +
12670 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
12671 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
12672 + /*PKCS11H_ASSERT (token_id_list!=NULL); NOT NEEDED*/
12673 +
12674 + PKCS11H_DEBUG (
12675 + PKCS11H_LOG_DEBUG2,
12676 + "PKCS#11: pkcs11h_token_freeTokenIdList entry token_id_list=%p",
12677 + (void *)token_id_list
12678 + );
12679 +
12680 + while (_id != NULL) {
12681 + pkcs11h_token_id_list_t x = _id;
12682 + _id = _id->next;
12683 + if (x->token_id != NULL) {
12684 + pkcs11h_token_freeTokenId (x->token_id);
12685 + }
12686 + x->next = NULL;
12687 + _pkcs11h_mem_free ((void *)&x);
12688 + }
12689 +
12690 + PKCS11H_DEBUG (
12691 + PKCS11H_LOG_DEBUG2,
12692 + "PKCS#11: pkcs11h_token_freeTokenIdList return"
12693 + );
12694 +
12695 + return CKR_OK;
12696 +}
12697 +
12698 +CK_RV
12699 +pkcs11h_token_enumTokenIds (
12700 + IN const int method,
12701 + OUT pkcs11h_token_id_list_t * const p_token_id_list
12702 +) {
12703 +#if defined(ENABLE_PKCS11H_THREADING)
12704 + PKCS11H_BOOL mutex_locked = FALSE;
12705 +#endif
12706 +
12707 + pkcs11h_token_id_list_t token_id_list = NULL;
12708 + pkcs11h_provider_t current_provider;
12709 + CK_RV rv = CKR_OK;
12710 +
12711 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
12712 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
12713 + PKCS11H_ASSERT (p_token_id_list!=NULL);
12714 +
12715 + PKCS11H_DEBUG (
12716 + PKCS11H_LOG_DEBUG2,
12717 + "PKCS#11: pkcs11h_token_enumTokenIds entry p_token_id_list=%p",
12718 + (void *)p_token_id_list
12719 + );
12720 +
12721 + *p_token_id_list = NULL;
12722 +
12723 +#if defined(ENABLE_PKCS11H_THREADING)
12724 + if (
12725 + rv == CKR_OK &&
12726 + (rv = _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.global)) == CKR_OK
12727 + ) {
12728 + mutex_locked = TRUE;
12729 + }
12730 +#endif
12731 +
12732 + for (
12733 + current_provider = s_pkcs11h_data->providers;
12734 + (
12735 + current_provider != NULL &&
12736 + rv == CKR_OK
12737 + );
12738 + current_provider = current_provider->next
12739 + ) {
12740 + CK_SLOT_ID_PTR slots = NULL;
12741 + CK_ULONG slotnum;
12742 + CK_SLOT_ID slot_index;
12743 +
12744 + if (!current_provider->enabled) {
12745 + rv = CKR_CRYPTOKI_NOT_INITIALIZED;
12746 + }
12747 +
12748 + if (rv == CKR_OK) {
12749 + rv = _pkcs11h_session_getSlotList (
12750 + current_provider,
12751 + CK_TRUE,
12752 + &slots,
12753 + &slotnum
12754 + );
12755 + }
12756 +
12757 + for (
12758 + slot_index=0;
12759 + (
12760 + slot_index < slotnum &&
12761 + rv == CKR_OK
12762 + );
12763 + slot_index++
12764 + ) {
12765 + pkcs11h_token_id_list_t entry = NULL;
12766 + CK_TOKEN_INFO info;
12767 +
12768 + if (rv == CKR_OK) {
12769 + rv = _pkcs11h_mem_malloc ((void *)&entry, sizeof (struct pkcs11h_token_id_list_s));
12770 + }
12771 +
12772 + if (rv == CKR_OK) {
12773 + rv = current_provider->f->C_GetTokenInfo (
12774 + slots[slot_index],
12775 + &info
12776 + );
12777 + }
12778 +
12779 + if (rv == CKR_OK) {
12780 + rv = _pkcs11h_token_getTokenId (
12781 + &info,
12782 + &entry->token_id
12783 + );
12784 + }
12785 +
12786 + if (rv == CKR_OK) {
12787 + entry->next = token_id_list;
12788 + token_id_list = entry;
12789 + entry = NULL;
12790 + }
12791 +
12792 + if (entry != NULL) {
12793 + pkcs11h_token_freeTokenIdList (entry);
12794 + entry = NULL;
12795 + }
12796 + }
12797 +
12798 + if (rv != CKR_OK) {
12799 + PKCS11H_DEBUG (
12800 + PKCS11H_LOG_DEBUG1,
12801 + "PKCS#11: Cannot get slot list for provider '%s' rv=%ld-'%s'",
12802 + current_provider->manufacturerID,
12803 + rv,
12804 + pkcs11h_getMessage (rv)
12805 + );
12806 +
12807 + /*
12808 + * Ignore error
12809 + */
12810 + rv = CKR_OK;
12811 + }
12812 +
12813 + if (slots != NULL) {
12814 + _pkcs11h_mem_free ((void *)&slots);
12815 + slots = NULL;
12816 + }
12817 + }
12818 +
12819 + if (rv == CKR_OK && method == PKCS11H_ENUM_METHOD_CACHE) {
12820 + pkcs11h_session_t session = NULL;
12821 +
12822 + for (
12823 + session = s_pkcs11h_data->sessions;
12824 + session != NULL && rv == CKR_OK;
12825 + session = session->next
12826 + ) {
12827 + pkcs11h_token_id_list_t entry = NULL;
12828 + PKCS11H_BOOL found = FALSE;
12829 +
12830 + for (
12831 + entry = token_id_list;
12832 + entry != NULL && !found;
12833 + entry = entry->next
12834 + ) {
12835 + if (
12836 + pkcs11h_token_sameTokenId (
12837 + session->token_id,
12838 + entry->token_id
12839 + )
12840 + ) {
12841 + found = TRUE;
12842 + }
12843 + }
12844 +
12845 + if (!found) {
12846 + entry = NULL;
12847 +
12848 + if (rv == CKR_OK) {
12849 + rv = _pkcs11h_mem_malloc (
12850 + (void *)&entry,
12851 + sizeof (struct pkcs11h_token_id_list_s)
12852 + );
12853 + }
12854 +
12855 + if (rv == CKR_OK) {
12856 + rv = pkcs11h_token_duplicateTokenId (
12857 + &entry->token_id,
12858 + session->token_id
12859 + );
12860 + }
12861 +
12862 + if (rv == CKR_OK) {
12863 + entry->next = token_id_list;
12864 + token_id_list = entry;
12865 + entry = NULL;
12866 + }
12867 +
12868 + if (entry != NULL) {
12869 + if (entry->token_id != NULL) {
12870 + pkcs11h_token_freeTokenId (entry->token_id);
12871 + }
12872 + _pkcs11h_mem_free ((void *)&entry);
12873 + }
12874 + }
12875 + }
12876 + }
12877 +
12878 + if (rv == CKR_OK) {
12879 + *p_token_id_list = token_id_list;
12880 + token_id_list = NULL;
12881 + }
12882 +
12883 + if (token_id_list != NULL) {
12884 + pkcs11h_token_freeTokenIdList (token_id_list);
12885 + token_id_list = NULL;
12886 + }
12887 +
12888 +#if defined(ENABLE_PKCS11H_THREADING)
12889 + if (mutex_locked) {
12890 + rv = _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.global);
12891 + mutex_locked = FALSE;
12892 + }
12893 +#endif
12894 +
12895 + PKCS11H_DEBUG (
12896 + PKCS11H_LOG_DEBUG2,
12897 + "PKCS#11: pkcs11h_token_enumTokenIds return rv=%ld-'%s', *p_token_id_list=%p",
12898 + rv,
12899 + pkcs11h_getMessage (rv),
12900 + (void *)p_token_id_list
12901 + );
12902 +
12903 + return rv;
12904 +}
12905 +
12906 +#endif
12907 +
12908 +#if defined(ENABLE_PKCS11H_DATA)
12909 +
12910 +CK_RV
12911 +pkcs11h_data_freeDataIdList (
12912 + IN const pkcs11h_data_id_list_t data_id_list
12913 +) {
12914 + pkcs11h_data_id_list_t _id = data_id_list;
12915 +
12916 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
12917 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
12918 + /*PKCS11H_ASSERT (data_id_list!=NULL); NOT NEEDED*/
12919 +
12920 + PKCS11H_DEBUG (
12921 + PKCS11H_LOG_DEBUG2,
12922 + "PKCS#11: pkcs11h_freeDataIdList entry token_id_list=%p",
12923 + (void *)data_id_list
12924 + );
12925 +
12926 + while (_id != NULL) {
12927 + pkcs11h_data_id_list_t x = _id;
12928 + _id = _id->next;
12929 +
12930 + if (x->application != NULL) {
12931 + _pkcs11h_mem_free ((void *)&x->application);
12932 + }
12933 + if (x->label != NULL) {
12934 + _pkcs11h_mem_free ((void *)&x->label);
12935 + }
12936 + _pkcs11h_mem_free ((void *)&x);
12937 + }
12938 +
12939 + PKCS11H_DEBUG (
12940 + PKCS11H_LOG_DEBUG2,
12941 + "PKCS#11: pkcs11h_token_freeDataIdList return"
12942 + );
12943 +
12944 + return CKR_OK;
12945 +}
12946 +
12947 +CK_RV
12948 +pkcs11h_data_enumDataObjects (
12949 + IN const pkcs11h_token_id_t token_id,
12950 + IN const PKCS11H_BOOL is_public,
12951 + IN void * const user_data,
12952 + IN const unsigned mask_prompt,
12953 + OUT pkcs11h_data_id_list_t * const p_data_id_list
12954 +) {
12955 +#if defined(ENABLE_PKCS11H_THREADING)
12956 + PKCS11H_BOOL mutex_locked = FALSE;
12957 +#endif
12958 + pkcs11h_session_t session = NULL;
12959 + pkcs11h_data_id_list_t data_id_list = NULL;
12960 + CK_RV rv = CKR_OK;
12961 +
12962 + PKCS11H_BOOL op_succeed = FALSE;
12963 + PKCS11H_BOOL login_retry = FALSE;
12964 +
12965 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
12966 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
12967 + PKCS11H_ASSERT (p_data_id_list!=NULL);
12968 +
12969 + PKCS11H_DEBUG (
12970 + PKCS11H_LOG_DEBUG2,
12971 + "PKCS#11: pkcs11h_data_enumDataObjects entry token_id=%p, is_public=%d, user_data=%p, mask_prompt=%08x, p_data_id_list=%p",
12972 + (void *)token_id,
12973 + is_public ? 1 : 0,
12974 + user_data,
12975 + mask_prompt,
12976 + (void *)p_data_id_list
12977 + );
12978 +
12979 + *p_data_id_list = NULL;
12980 +
12981 + if (rv == CKR_OK) {
12982 + rv = _pkcs11h_session_getSessionByTokenId (
12983 + token_id,
12984 + &session
12985 + );
12986 + }
12987 +
12988 +#if defined(ENABLE_PKCS11H_THREADING)
12989 + if (
12990 + rv == CKR_OK &&
12991 + (rv = _pkcs11h_threading_mutexLock (&session->mutex)) == CKR_OK
12992 + ) {
12993 + mutex_locked = TRUE;
12994 + }
12995 +#endif
12996 +
12997 + while (rv == CKR_OK && !op_succeed) {
12998 +
12999 + CK_OBJECT_CLASS class = CKO_DATA;
13000 + CK_ATTRIBUTE filter[] = {
13001 + {CKA_CLASS, (void *)&class, sizeof (class)}
13002 + };
13003 + CK_OBJECT_HANDLE *objects = NULL;
13004 + CK_ULONG objects_found = 0;
13005 +
13006 + CK_ULONG i;
13007 +
13008 + if (rv == CKR_OK) {
13009 + rv = _pkcs11h_session_validate (session);
13010 + }
13011 +
13012 + if (rv == CKR_OK) {
13013 + rv = _pkcs11h_session_findObjects (
13014 + session,
13015 + filter,
13016 + sizeof (filter) / sizeof (CK_ATTRIBUTE),
13017 + &objects,
13018 + &objects_found
13019 + );
13020 + }
13021 +
13022 + for (i = 0;rv == CKR_OK && i < objects_found;i++) {
13023 + pkcs11h_data_id_list_t entry = NULL;
13024 +
13025 + CK_ATTRIBUTE attrs[] = {
13026 + {CKA_APPLICATION, NULL, 0},
13027 + {CKA_LABEL, NULL, 0}
13028 + };
13029 +
13030 + if (rv == CKR_OK) {
13031 + rv = _pkcs11h_session_getObjectAttributes (
13032 + session,
13033 + objects[i],
13034 + attrs,
13035 + sizeof (attrs) / sizeof (CK_ATTRIBUTE)
13036 + );
13037 + }
13038 +
13039 + if (rv == CKR_OK) {
13040 + rv = _pkcs11h_mem_malloc (
13041 + (void *)&entry,
13042 + sizeof (struct pkcs11h_data_id_list_s)
13043 + );
13044 + }
13045 +
13046 + if (
13047 + rv == CKR_OK &&
13048 + (rv = _pkcs11h_mem_malloc (
13049 + (void *)&entry->application,
13050 + attrs[0].ulValueLen+1
13051 + )) == CKR_OK
13052 + ) {
13053 + memmove (entry->application, attrs[0].pValue, attrs[0].ulValueLen);
13054 + entry->application[attrs[0].ulValueLen] = '\0';
13055 + }
13056 +
13057 + if (
13058 + rv == CKR_OK &&
13059 + (rv = _pkcs11h_mem_malloc (
13060 + (void *)&entry->label,
13061 + attrs[1].ulValueLen+1
13062 + )) == CKR_OK
13063 + ) {
13064 + memmove (entry->label, attrs[1].pValue, attrs[1].ulValueLen);
13065 + entry->label[attrs[1].ulValueLen] = '\0';
13066 + }
13067 +
13068 + if (rv == CKR_OK) {
13069 + entry->next = data_id_list;
13070 + data_id_list = entry;
13071 + entry = NULL;
13072 + }
13073 +
13074 + _pkcs11h_session_freeObjectAttributes (
13075 + attrs,
13076 + sizeof (attrs) / sizeof (CK_ATTRIBUTE)
13077 + );
13078 +
13079 + if (entry != NULL) {
13080 + if (entry->application != NULL) {
13081 + _pkcs11h_mem_free ((void *)&entry->application);
13082 + }
13083 + if (entry->label != NULL) {
13084 + _pkcs11h_mem_free ((void *)&entry->label);
13085 + }
13086 + _pkcs11h_mem_free ((void *)&entry);
13087 + }
13088 + }
13089 +
13090 + if (objects != NULL) {
13091 + _pkcs11h_mem_free ((void *)&objects);
13092 + }
13093 +
13094 + if (rv == CKR_OK) {
13095 + op_succeed = TRUE;
13096 + }
13097 + else {
13098 + if (!login_retry) {
13099 + PKCS11H_DEBUG (
13100 + PKCS11H_LOG_DEBUG1,
13101 + "PKCS#11: Enumerate data objects failed rv=%ld-'%s'",
13102 + rv,
13103 + pkcs11h_getMessage (rv)
13104 + );
13105 + login_retry = TRUE;
13106 + rv = _pkcs11h_session_login (
13107 + session,
13108 + is_public,
13109 + TRUE,
13110 + user_data,
13111 + mask_prompt
13112 + );
13113 + }
13114 + }
13115 + }
13116 +
13117 +#if defined(ENABLE_PKCS11H_THREADING)
13118 + if (mutex_locked) {
13119 + _pkcs11h_threading_mutexRelease (&session->mutex);
13120 + mutex_locked = FALSE;
13121 + }
13122 +#endif
13123 +
13124 + if (rv == CKR_OK) {
13125 + *p_data_id_list = data_id_list;
13126 + data_id_list = NULL;
13127 + }
13128 +
13129 + if (session != NULL) {
13130 + _pkcs11h_session_release (session);
13131 + session = NULL;
13132 + }
13133 +
13134 + if (data_id_list != NULL) {
13135 + pkcs11h_data_freeDataIdList (data_id_list);
13136 + data_id_list = NULL;
13137 + }
13138 +
13139 + PKCS11H_DEBUG (
13140 + PKCS11H_LOG_DEBUG2,
13141 + "PKCS#11: pkcs11h_data_enumDataObjects return rv=%ld-'%s', *p_data_id_list=%p",
13142 + rv,
13143 + pkcs11h_getMessage (rv),
13144 + (void *)*p_data_id_list
13145 + );
13146 +
13147 + return rv;
13148 +}
13149 +
13150 +#endif /* ENABLE_PKCS11H_DATA */
13151 +
13152 +#if defined(ENABLE_PKCS11H_CERTIFICATE)
13153 +
13154 +static
13155 +CK_RV
13156 +_pkcs11h_certificate_enumSessionCertificates (
13157 + IN const pkcs11h_session_t session,
13158 + IN void * const user_data,
13159 + IN const unsigned mask_prompt
13160 +) {
13161 +#if defined(ENABLE_PKCS11H_THREADING)
13162 + PKCS11H_BOOL mutex_locked = FALSE;
13163 +#endif
13164 + PKCS11H_BOOL op_succeed = FALSE;
13165 + PKCS11H_BOOL login_retry = FALSE;
13166 +
13167 + CK_RV rv = CKR_OK;
13168 +
13169 + PKCS11H_ASSERT (session!=NULL);
13170 + /*PKCS11H_ASSERT (user_data) NOT NEEDED */
13171 +
13172 + PKCS11H_DEBUG (
13173 + PKCS11H_LOG_DEBUG2,
13174 + "PKCS#11: _pkcs11h_certificate_enumSessionCertificates entry session=%p, user_data=%p, mask_prompt=%08x",
13175 + (void *)session,
13176 + user_data,
13177 + mask_prompt
13178 + );
13179 +
13180 + /* THREADS: NO NEED TO LOCK, GLOBAL CACHE IS LOCKED */
13181 +#if defined(ENABLE_PKCS11H_THREADING)
13182 + if (
13183 + rv == CKR_OK &&
13184 + (rv = _pkcs11h_threading_mutexLock (&session->mutex)) == CKR_OK
13185 + ) {
13186 + mutex_locked = TRUE;
13187 + }
13188 +#endif
13189 +
13190 + while (rv == CKR_OK && !op_succeed) {
13191 + CK_OBJECT_CLASS cert_filter_class = CKO_CERTIFICATE;
13192 + CK_ATTRIBUTE cert_filter[] = {
13193 + {CKA_CLASS, &cert_filter_class, sizeof (cert_filter_class)}
13194 + };
13195 +
13196 + CK_OBJECT_HANDLE *objects = NULL;
13197 + CK_ULONG objects_found = 0;
13198 +
13199 + CK_ULONG i;
13200 +
13201 + if (rv == CKR_OK) {
13202 + rv = _pkcs11h_session_validate (session);
13203 + }
13204 +
13205 + if (rv == CKR_OK) {
13206 + rv = _pkcs11h_session_findObjects (
13207 + session,
13208 + cert_filter,
13209 + sizeof (cert_filter) / sizeof (CK_ATTRIBUTE),
13210 + &objects,
13211 + &objects_found
13212 + );
13213 + }
13214 +
13215 + for (i=0;rv == CKR_OK && i < objects_found;i++) {
13216 + pkcs11h_certificate_id_t certificate_id = NULL;
13217 + pkcs11h_certificate_id_list_t new_element = NULL;
13218 +
13219 + CK_ATTRIBUTE attrs[] = {
13220 + {CKA_ID, NULL, 0},
13221 + {CKA_VALUE, NULL, 0}
13222 + };
13223 +
13224 + if (rv == CKR_OK) {
13225 + rv = _pkcs11h_session_getObjectAttributes (
13226 + session,
13227 + objects[i],
13228 + attrs,
13229 + sizeof (attrs) / sizeof (CK_ATTRIBUTE)
13230 + );
13231 + }
13232 +
13233 + if (
13234 + rv == CKR_OK &&
13235 + (rv = _pkcs11h_certificate_newCertificateId (&certificate_id)) == CKR_OK
13236 + ) {
13237 + rv = pkcs11h_token_duplicateTokenId (
13238 + &certificate_id->token_id,
13239 + session->token_id
13240 + );
13241 + }
13242 +
13243 + if (rv == CKR_OK) {
13244 + rv = _pkcs11h_mem_duplicate (
13245 + (void*)&certificate_id->attrCKA_ID,
13246 + &certificate_id->attrCKA_ID_size,
13247 + attrs[0].pValue,
13248 + attrs[0].ulValueLen
13249 + );
13250 + }
13251 +
13252 + if (rv == CKR_OK) {
13253 + rv = _pkcs11h_mem_duplicate (
13254 + (void*)&certificate_id->certificate_blob,
13255 + &certificate_id->certificate_blob_size,
13256 + attrs[1].pValue,
13257 + attrs[1].ulValueLen
13258 + );
13259 + }
13260 +
13261 + if (rv == CKR_OK) {
13262 + rv = _pkcs11h_certificate_updateCertificateIdDescription (certificate_id);
13263 + }
13264 +
13265 + if (
13266 + rv == CKR_OK &&
13267 + (rv = _pkcs11h_mem_malloc (
13268 + (void *)&new_element,
13269 + sizeof (struct pkcs11h_certificate_id_list_s)
13270 + )) == CKR_OK
13271 + ) {
13272 + new_element->next = session->cached_certs;
13273 + new_element->certificate_id = certificate_id;
13274 + certificate_id = NULL;
13275 +
13276 + session->cached_certs = new_element;
13277 + new_element = NULL;
13278 + }
13279 +
13280 + if (certificate_id != NULL) {
13281 + pkcs11h_certificate_freeCertificateId (certificate_id);
13282 + certificate_id = NULL;
13283 + }
13284 +
13285 + if (new_element != NULL) {
13286 + _pkcs11h_mem_free ((void *)&new_element);
13287 + new_element = NULL;
13288 + }
13289 +
13290 + _pkcs11h_session_freeObjectAttributes (
13291 + attrs,
13292 + sizeof (attrs) / sizeof (CK_ATTRIBUTE)
13293 + );
13294 +
13295 + if (rv != CKR_OK) {
13296 + PKCS11H_DEBUG (
13297 + PKCS11H_LOG_DEBUG1,
13298 + "PKCS#11: Cannot get object attribute for provider '%s' object %ld rv=%ld-'%s'",
13299 + session->provider->manufacturerID,
13300 + objects[i],
13301 + rv,
13302 + pkcs11h_getMessage (rv)
13303 + );
13304 +
13305 + /*
13306 + * Ignore error
13307 + */
13308 + rv = CKR_OK;
13309 + }
13310 + }
13311 +
13312 + if (objects != NULL) {
13313 + _pkcs11h_mem_free ((void *)&objects);
13314 + }
13315 +
13316 + if (rv == CKR_OK) {
13317 + op_succeed = TRUE;
13318 + }
13319 + else {
13320 + if (!login_retry) {
13321 + PKCS11H_DEBUG (
13322 + PKCS11H_LOG_DEBUG1,
13323 + "PKCS#11: Get certificate attributes failed: %ld:'%s'",
13324 + rv,
13325 + pkcs11h_getMessage (rv)
13326 + );
13327 +
13328 + rv = _pkcs11h_session_login (
13329 + session,
13330 + TRUE,
13331 + TRUE,
13332 + user_data,
13333 + (mask_prompt & PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT)
13334 + );
13335 +
13336 + login_retry = TRUE;
13337 + }
13338 + }
13339 + }
13340 +
13341 +#if defined(ENABLE_PKCS11H_THREADING)
13342 + if (mutex_locked) {
13343 + _pkcs11h_threading_mutexRelease (&session->mutex);
13344 + mutex_locked = FALSE;
13345 + }
13346 +#endif
13347 +
13348 + PKCS11H_DEBUG (
13349 + PKCS11H_LOG_DEBUG2,
13350 + "PKCS#11: _pkcs11h_certificate_enumSessionCertificates return rv=%ld-'%s'",
13351 + rv,
13352 + pkcs11h_getMessage (rv)
13353 + );
13354 +
13355 + return rv;
13356 +}
13357 +
13358 +static
13359 +CK_RV
13360 +_pkcs11h_certificate_splitCertificateIdList (
13361 + IN const pkcs11h_certificate_id_list_t cert_id_all,
13362 + OUT pkcs11h_certificate_id_list_t * const p_cert_id_issuers_list,
13363 + OUT pkcs11h_certificate_id_list_t * const p_cert_id_end_list
13364 +) {
13365 + typedef struct info_s {
13366 + struct info_s *next;
13367 + pkcs11h_certificate_id_t e;
13368 +#if defined(USE_PKCS11H_OPENSSL)
13369 + X509 *x509;
13370 +#elif defined(USE_PKCS11H_GNUTLS)
13371 + gnutls_x509_crt_t cert;
13372 +#endif
13373 + PKCS11H_BOOL is_issuer;
13374 + } *info_t;
13375 +
13376 + pkcs11h_certificate_id_list_t cert_id_issuers_list = NULL;
13377 + pkcs11h_certificate_id_list_t cert_id_end_list = NULL;
13378 +
13379 + info_t head = NULL;
13380 + info_t info = NULL;
13381 +
13382 + CK_RV rv = CKR_OK;
13383 +
13384 + /*PKCS11H_ASSERT (cert_id_all!=NULL); NOT NEEDED */
13385 + /*PKCS11H_ASSERT (p_cert_id_issuers_list!=NULL); NOT NEEDED*/
13386 + PKCS11H_ASSERT (p_cert_id_end_list!=NULL);
13387 +
13388 + PKCS11H_DEBUG (
13389 + PKCS11H_LOG_DEBUG2,
13390 + "PKCS#11: _pkcs11h_certificate_splitCertificateIdList entry cert_id_all=%p, p_cert_id_issuers_list=%p, p_cert_id_end_list=%p",
13391 + (void *)cert_id_all,
13392 + (void *)p_cert_id_issuers_list,
13393 + (void *)p_cert_id_end_list
13394 + );
13395 +
13396 + if (p_cert_id_issuers_list != NULL) {
13397 + *p_cert_id_issuers_list = NULL;
13398 + }
13399 + *p_cert_id_end_list = NULL;
13400 +
13401 + if (rv == CKR_OK) {
13402 + pkcs11h_certificate_id_list_t entry = NULL;
13403 +
13404 + for (
13405 + entry = cert_id_all;
13406 + entry != NULL && rv == CKR_OK;
13407 + entry = entry->next
13408 + ) {
13409 + info_t new_info = NULL;
13410 +
13411 + if (
13412 + rv == CKR_OK &&
13413 + (rv = _pkcs11h_mem_malloc ((void *)&new_info, sizeof (struct info_s))) == CKR_OK &&
13414 + entry->certificate_id->certificate_blob != NULL
13415 + ) {
13416 +#if defined(USE_PKCS11H_OPENSSL)
13417 + pkcs11_openssl_d2i_t d2i = (pkcs11_openssl_d2i_t)entry->certificate_id->certificate_blob;
13418 +#endif
13419 +
13420 + new_info->next = head;
13421 + new_info->e = entry->certificate_id;
13422 +#if defined(USE_PKCS11H_OPENSSL)
13423 + new_info->x509 = X509_new ();
13424 + if (
13425 + new_info->x509 != NULL &&
13426 + !d2i_X509 (
13427 + &new_info->x509,
13428 + &d2i,
13429 + entry->certificate_id->certificate_blob_size
13430 + )
13431 + ) {
13432 + X509_free (new_info->x509);
13433 + new_info->x509 = NULL;
13434 + }
13435 +#elif defined(USE_PKCS11H_GNUTLS)
13436 + if (gnutls_x509_crt_init (&new_info->cert) != GNUTLS_E_SUCCESS) {
13437 + /* gnutls sets output */
13438 + new_info->cert = NULL;
13439 + }
13440 + else {
13441 + gnutls_datum_t datum = {
13442 + entry->certificate_id->certificate_blob,
13443 + entry->certificate_id->certificate_blob_size
13444 + };
13445 +
13446 + if (
13447 + gnutls_x509_crt_import (
13448 + new_info->cert,
13449 + &datum,
13450 + GNUTLS_X509_FMT_DER
13451 + ) != GNUTLS_E_SUCCESS
13452 + ) {
13453 + gnutls_x509_crt_deinit (new_info->cert);
13454 + new_info->cert = NULL;
13455 + }
13456 + }
13457 +#else
13458 +#error Invalid configuration.
13459 +#endif
13460 + head = new_info;
13461 + new_info = NULL;
13462 + }
13463 + }
13464 +
13465 + }
13466 +
13467 + if (rv == CKR_OK) {
13468 + for (
13469 + info = head;
13470 + info != NULL;
13471 + info = info->next
13472 + ) {
13473 + info_t info2 = NULL;
13474 +#if defined(USE_PKCS11H_OPENSSL)
13475 + EVP_PKEY *pub = X509_get_pubkey (info->x509);
13476 +#endif
13477 +
13478 + for (
13479 + info2 = head;
13480 + info2 != NULL && !info->is_issuer;
13481 + info2 = info2->next
13482 + ) {
13483 + if (info != info2) {
13484 +#if defined(USE_PKCS11H_OPENSSL)
13485 + if (
13486 + info->x509 != NULL &&
13487 + info2->x509 != NULL &&
13488 + !X509_NAME_cmp (
13489 + X509_get_subject_name (info->x509),
13490 + X509_get_issuer_name (info2->x509)
13491 + ) &&
13492 + X509_verify (info2->x509, pub) == 1
13493 + ) {
13494 + info->is_issuer = TRUE;
13495 + }
13496 +#elif defined(USE_PKCS11H_GNUTLS)
13497 + unsigned result;
13498 +
13499 + if (
13500 + info->cert != NULL &&
13501 + info2->cert != NULL &&
13502 + gnutls_x509_crt_verify (
13503 + info2->cert,
13504 + &info->cert,
13505 + 1,
13506 + 0,
13507 + &result
13508 + ) &&
13509 + (result & GNUTLS_CERT_INVALID) == 0
13510 + ) {
13511 + info->is_issuer = TRUE;
13512 + }
13513 +#else
13514 +#error Invalid configuration.
13515 +#endif
13516 + }
13517 +
13518 + }
13519 +
13520 +#if defined(USE_PKCS11H_OPENSSL)
13521 + if (pub != NULL) {
13522 + EVP_PKEY_free (pub);
13523 + pub = NULL;
13524 + }
13525 +#endif
13526 + }
13527 + }
13528 +
13529 + if (rv == CKR_OK) {
13530 + for (
13531 + info = head;
13532 + info != NULL && rv == CKR_OK;
13533 + info = info->next
13534 + ) {
13535 + pkcs11h_certificate_id_list_t new_entry = NULL;
13536 +
13537 + if (rv == CKR_OK) {
13538 + rv = _pkcs11h_mem_malloc (
13539 + (void *)&new_entry,
13540 + sizeof (struct pkcs11h_certificate_id_list_s)
13541 + );
13542 + }
13543 +
13544 + if (
13545 + rv == CKR_OK &&
13546 + (rv = pkcs11h_certificate_duplicateCertificateId (
13547 + &new_entry->certificate_id,
13548 + info->e
13549 + )) == CKR_OK
13550 + ) {
13551 + /*
13552 + * Should not free base list
13553 + */
13554 + info->e = NULL;
13555 + }
13556 +
13557 + if (rv == CKR_OK) {
13558 + if (info->is_issuer) {
13559 + new_entry->next = cert_id_issuers_list;
13560 + cert_id_issuers_list = new_entry;
13561 + new_entry = NULL;
13562 + }
13563 + else {
13564 + new_entry->next = cert_id_end_list;
13565 + cert_id_end_list = new_entry;
13566 + new_entry = NULL;
13567 + }
13568 + }
13569 +
13570 + if (new_entry != NULL) {
13571 + if (new_entry->certificate_id != NULL) {
13572 + pkcs11h_certificate_freeCertificateId (new_entry->certificate_id);
13573 + }
13574 + _pkcs11h_mem_free ((void *)&new_entry);
13575 + }
13576 + }
13577 + }
13578 +
13579 + if (rv == CKR_OK) {
13580 + while (head != NULL) {
13581 + info_t entry = head;
13582 + head = head->next;
13583 +
13584 +#if defined(USE_PKCS11H_OPENSSL)
13585 + if (entry->x509 != NULL) {
13586 + X509_free (entry->x509);
13587 + entry->x509 = NULL;
13588 + }
13589 +#elif defined(USE_PKCS11H_GNUTLS)
13590 + if (entry->cert != NULL) {
13591 + gnutls_x509_crt_deinit (entry->cert);
13592 + entry->cert = NULL;
13593 + }
13594 +#else
13595 +#error Invalid configuration.
13596 +#endif
13597 +
13598 + _pkcs11h_mem_free ((void *)&entry);
13599 + }
13600 + }
13601 +
13602 + if (rv == CKR_OK && p_cert_id_issuers_list != NULL ) {
13603 + *p_cert_id_issuers_list = cert_id_issuers_list;
13604 + cert_id_issuers_list = NULL;
13605 + }
13606 +
13607 + if (rv == CKR_OK) {
13608 + *p_cert_id_end_list = cert_id_end_list;
13609 + cert_id_end_list = NULL;
13610 + }
13611 +
13612 + if (cert_id_issuers_list != NULL) {
13613 + pkcs11h_certificate_freeCertificateIdList (cert_id_issuers_list);
13614 + }
13615 +
13616 + if (cert_id_end_list != NULL) {
13617 + pkcs11h_certificate_freeCertificateIdList (cert_id_end_list);
13618 + }
13619 +
13620 + PKCS11H_DEBUG (
13621 + PKCS11H_LOG_DEBUG2,
13622 + "PKCS#11: _pkcs11h_certificate_splitCertificateIdList return rv=%ld-'%s'",
13623 + rv,
13624 + pkcs11h_getMessage (rv)
13625 + );
13626 +
13627 + return rv;
13628 +}
13629 +
13630 +CK_RV
13631 +pkcs11h_certificate_freeCertificateIdList (
13632 + IN const pkcs11h_certificate_id_list_t cert_id_list
13633 +) {
13634 + pkcs11h_certificate_id_list_t _id = cert_id_list;
13635 +
13636 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
13637 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
13638 + /*PKCS11H_ASSERT (cert_id_list!=NULL); NOT NEEDED*/
13639 +
13640 + PKCS11H_DEBUG (
13641 + PKCS11H_LOG_DEBUG2,
13642 + "PKCS#11: pkcs11h_certificate_freeCertificateIdList entry cert_id_list=%p",
13643 + (void *)cert_id_list
13644 + );
13645 +
13646 + while (_id != NULL) {
13647 + pkcs11h_certificate_id_list_t x = _id;
13648 + _id = _id->next;
13649 + if (x->certificate_id != NULL) {
13650 + pkcs11h_certificate_freeCertificateId (x->certificate_id);
13651 + }
13652 + x->next = NULL;
13653 + _pkcs11h_mem_free ((void *)&x);
13654 + }
13655 +
13656 + PKCS11H_DEBUG (
13657 + PKCS11H_LOG_DEBUG2,
13658 + "PKCS#11: pkcs11h_certificate_freeCertificateIdList return"
13659 + );
13660 +
13661 + return CKR_OK;
13662 +}
13663 +
13664 +CK_RV
13665 +pkcs11h_certificate_enumTokenCertificateIds (
13666 + IN const pkcs11h_token_id_t token_id,
13667 + IN const int method,
13668 + IN void * const user_data,
13669 + IN const unsigned mask_prompt,
13670 + OUT pkcs11h_certificate_id_list_t * const p_cert_id_issuers_list,
13671 + OUT pkcs11h_certificate_id_list_t * const p_cert_id_end_list
13672 +) {
13673 +#if defined(ENABLE_PKCS11H_THREADING)
13674 + PKCS11H_BOOL mutex_locked = FALSE;
13675 +#endif
13676 + pkcs11h_session_t session = NULL;
13677 + CK_RV rv = CKR_OK;
13678 +
13679 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
13680 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
13681 + PKCS11H_ASSERT (token_id!=NULL);
13682 + /*PKCS11H_ASSERT (user_data) NOT NEEDED */
13683 + /*PKCS11H_ASSERT (p_cert_id_issuers_list!=NULL); NOT NEEDED*/
13684 + PKCS11H_ASSERT (p_cert_id_end_list!=NULL);
13685 +
13686 + PKCS11H_DEBUG (
13687 + PKCS11H_LOG_DEBUG2,
13688 + "PKCS#11: pkcs11h_certificate_enumTokenCertificateIds entry token_id=%p, method=%d, user_data=%p, mask_prompt=%08x, p_cert_id_issuers_list=%p, p_cert_id_end_list=%p",
13689 + (void *)token_id,
13690 + method,
13691 + user_data,
13692 + mask_prompt,
13693 + (void *)p_cert_id_issuers_list,
13694 + (void *)p_cert_id_end_list
13695 + );
13696 +
13697 + if (p_cert_id_issuers_list != NULL) {
13698 + *p_cert_id_issuers_list = NULL;
13699 + }
13700 + *p_cert_id_end_list = NULL;
13701 +
13702 +#if defined(ENABLE_PKCS11H_THREADING)
13703 + if (
13704 + rv == CKR_OK &&
13705 + (rv = _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.cache)) == CKR_OK
13706 + ) {
13707 + mutex_locked = TRUE;
13708 + }
13709 +#endif
13710 +
13711 + if (
13712 + rv == CKR_OK &&
13713 + (rv = _pkcs11h_session_getSessionByTokenId (
13714 + token_id,
13715 + &session
13716 + )) == CKR_OK
13717 + ) {
13718 + if (method == PKCS11H_ENUM_METHOD_RELOAD) {
13719 + pkcs11h_certificate_freeCertificateIdList (session->cached_certs);
13720 + session->cached_certs = NULL;
13721 + }
13722 +
13723 + if (session->cached_certs == NULL) {
13724 + rv = _pkcs11h_certificate_enumSessionCertificates (session, user_data, mask_prompt);
13725 + }
13726 + }
13727 +
13728 + if (rv == CKR_OK) {
13729 + rv = _pkcs11h_certificate_splitCertificateIdList (
13730 + session->cached_certs,
13731 + p_cert_id_issuers_list,
13732 + p_cert_id_end_list
13733 + );
13734 + }
13735 +
13736 + if (session != NULL) {
13737 + _pkcs11h_session_release (session);
13738 + }
13739 +
13740 +#if defined(ENABLE_PKCS11H_THREADING)
13741 + if (mutex_locked) {
13742 + _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.cache);
13743 + mutex_locked = FALSE;
13744 + }
13745 +#endif
13746 +
13747 + PKCS11H_DEBUG (
13748 + PKCS11H_LOG_DEBUG2,
13749 + "PKCS#11: pkcs11h_certificate_enumTokenCertificateIds return rv=%ld-'%s'",
13750 + rv,
13751 + pkcs11h_getMessage (rv)
13752 + );
13753 +
13754 + return rv;
13755 +}
13756 +
13757 +CK_RV
13758 +pkcs11h_certificate_enumCertificateIds (
13759 + IN const int method,
13760 + IN void * const user_data,
13761 + IN const unsigned mask_prompt,
13762 + OUT pkcs11h_certificate_id_list_t * const p_cert_id_issuers_list,
13763 + OUT pkcs11h_certificate_id_list_t * const p_cert_id_end_list
13764 +) {
13765 +#if defined(ENABLE_PKCS11H_THREADING)
13766 + PKCS11H_BOOL mutex_locked = FALSE;
13767 +#endif
13768 + pkcs11h_certificate_id_list_t cert_id_list = NULL;
13769 + pkcs11h_provider_t current_provider;
13770 + pkcs11h_session_t current_session;
13771 + CK_RV rv = CKR_OK;
13772 +
13773 + PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
13774 + PKCS11H_ASSERT (s_pkcs11h_data->initialized);
13775 + /*PKCS11H_ASSERT (user_data!=NULL); NOT NEEDED*/
13776 + /*PKCS11H_ASSERT (p_cert_id_issuers_list!=NULL); NOT NEEDED*/
13777 + PKCS11H_ASSERT (p_cert_id_end_list!=NULL);
13778 +
13779 + PKCS11H_DEBUG (
13780 + PKCS11H_LOG_DEBUG2,
13781 + "PKCS#11: pkcs11h_certificate_enumCertificateIds entry method=%d, mask_prompt=%08x, p_cert_id_issuers_list=%p, p_cert_id_end_list=%p",
13782 + method,
13783 + mask_prompt,
13784 + (void *)p_cert_id_issuers_list,
13785 + (void *)p_cert_id_end_list
13786 + );
13787 +
13788 + if (p_cert_id_issuers_list != NULL) {
13789 + *p_cert_id_issuers_list = NULL;
13790 + }
13791 + *p_cert_id_end_list = NULL;
13792 +
13793 +#if defined(ENABLE_PKCS11H_THREADING)
13794 + if (
13795 + rv == CKR_OK &&
13796 + (rv = _pkcs11h_threading_mutexLock (&s_pkcs11h_data->mutexes.cache)) == CKR_OK
13797 + ) {
13798 + mutex_locked = TRUE;
13799 + }
13800 +#endif
13801 +
13802 + for (
13803 + current_session = s_pkcs11h_data->sessions;
13804 + current_session != NULL;
13805 + current_session = current_session->next
13806 + ) {
13807 + current_session->touch = FALSE;
13808 + if (method == PKCS11H_ENUM_METHOD_RELOAD) {
13809 + pkcs11h_certificate_freeCertificateIdList (current_session->cached_certs);
13810 + current_session->cached_certs = NULL;
13811 + }
13812 + }
13813 +
13814 + for (
13815 + current_provider = s_pkcs11h_data->providers;
13816 + (
13817 + current_provider != NULL &&
13818 + rv == CKR_OK
13819 + );
13820 + current_provider = current_provider->next
13821 + ) {
13822 + CK_SLOT_ID_PTR slots = NULL;
13823 + CK_ULONG slotnum;
13824 + CK_SLOT_ID slot_index;
13825 +
13826 + if (!current_provider->enabled) {
13827 + rv = CKR_CRYPTOKI_NOT_INITIALIZED;
13828 + }
13829 +
13830 + if (rv == CKR_OK) {
13831 + rv = _pkcs11h_session_getSlotList (
13832 + current_provider,
13833 + CK_TRUE,
13834 + &slots,
13835 + &slotnum
13836 + );
13837 + }
13838 +
13839 + for (
13840 + slot_index=0;
13841 + (
13842 + slot_index < slotnum &&
13843 + rv == CKR_OK
13844 + );
13845 + slot_index++
13846 + ) {
13847 + pkcs11h_session_t session = NULL;
13848 + pkcs11h_token_id_t token_id = NULL;
13849 + CK_TOKEN_INFO info;
13850 +
13851 + if (rv == CKR_OK) {
13852 + rv = current_provider->f->C_GetTokenInfo (
13853 + slots[slot_index],
13854 + &info
13855 + );
13856 + }
13857 +
13858 + if (
13859 + rv == CKR_OK &&
13860 + (rv = _pkcs11h_token_getTokenId (
13861 + &info,
13862 + &token_id
13863 + )) == CKR_OK &&
13864 + (rv = _pkcs11h_session_getSessionByTokenId (
13865 + token_id,
13866 + &session
13867 + )) == CKR_OK
13868 + ) {
13869 + session->touch = TRUE;
13870 +
13871 + if (session->cached_certs == NULL) {
13872 + rv = _pkcs11h_certificate_enumSessionCertificates (session, user_data, mask_prompt);
13873 + }
13874 + }
13875 +
13876 + if (rv != CKR_OK) {
13877 + PKCS11H_DEBUG (
13878 + PKCS11H_LOG_DEBUG1,
13879 + "PKCS#11: Cannot get token information for provider '%s' slot %ld rv=%ld-'%s'",
13880 + current_provider->manufacturerID,
13881 + slots[slot_index],
13882 + rv,
13883 + pkcs11h_getMessage (rv)
13884 + );
13885 +
13886 + /*
13887 + * Ignore error
13888 + */
13889 + rv = CKR_OK;
13890 + }
13891 +
13892 + if (session != NULL) {
13893 + _pkcs11h_session_release (session);
13894 + session = NULL;
13895 + }
13896 +
13897 + if (token_id != NULL) {
13898 + pkcs11h_token_freeTokenId (token_id);
13899 + token_id = NULL;
13900 + }
13901 + }
13902 +
13903 + if (rv != CKR_OK) {
13904 + PKCS11H_DEBUG (
13905 + PKCS11H_LOG_DEBUG1,
13906 + "PKCS#11: Cannot get slot list for provider '%s' rv=%ld-'%s'",
13907 + current_provider->manufacturerID,
13908 + rv,
13909 + pkcs11h_getMessage (rv)
13910 + );
13911 +
13912 + /*
13913 + * Ignore error
13914 + */
13915 + rv = CKR_OK;
13916 + }
13917 +
13918 + if (slots != NULL) {
13919 + _pkcs11h_mem_free ((void *)&slots);
13920 + slots = NULL;
13921 + }
13922 + }
13923 +
13924 + for (
13925 + current_session = s_pkcs11h_data->sessions;
13926 + (
13927 + current_session != NULL &&
13928 + rv == CKR_OK
13929 + );
13930 + current_session = current_session->next
13931 + ) {
13932 + if (
13933 + method == PKCS11H_ENUM_METHOD_CACHE ||
13934 + (
13935 + (
13936 + method == PKCS11H_ENUM_METHOD_RELOAD ||
13937 + method == PKCS11H_ENUM_METHOD_CACHE_EXIST
13938 + ) &&
13939 + current_session->touch
13940 + )
13941 + ) {
13942 + pkcs11h_certificate_id_list_t entry = NULL;
13943 +
13944 + for (
13945 + entry = current_session->cached_certs;
13946 + (
13947 + entry != NULL &&
13948 + rv == CKR_OK
13949 + );
13950 + entry = entry->next
13951 + ) {
13952 + pkcs11h_certificate_id_list_t new_entry = NULL;
13953 +
13954 + if (
13955 + rv == CKR_OK &&
13956 + (rv = _pkcs11h_mem_malloc (
13957 + (void *)&new_entry,
13958 + sizeof (struct pkcs11h_certificate_id_list_s)
13959 + )) == CKR_OK &&
13960 + (rv = pkcs11h_certificate_duplicateCertificateId (
13961 + &new_entry->certificate_id,
13962 + entry->certificate_id
13963 + )) == CKR_OK
13964 + ) {
13965 + new_entry->next = cert_id_list;
13966 + cert_id_list = new_entry;
13967 + new_entry = NULL;
13968 + }
13969 +
13970 + if (new_entry != NULL) {
13971 + new_entry->next = NULL;
13972 + pkcs11h_certificate_freeCertificateIdList (new_entry);
13973 + new_entry = NULL;
13974 + }
13975 + }
13976 + }
13977 + }
13978 +
13979 + if (rv == CKR_OK) {
13980 + rv = _pkcs11h_certificate_splitCertificateIdList (
13981 + cert_id_list,
13982 + p_cert_id_issuers_list,
13983 + p_cert_id_end_list
13984 + );
13985 + }
13986 +
13987 + if (cert_id_list != NULL) {
13988 + pkcs11h_certificate_freeCertificateIdList (cert_id_list);
13989 + cert_id_list = NULL;
13990 + }
13991 +
13992 +
13993 +#if defined(ENABLE_PKCS11H_THREADING)
13994 + if (mutex_locked) {
13995 + _pkcs11h_threading_mutexRelease (&s_pkcs11h_data->mutexes.cache);
13996 + mutex_locked = FALSE;
13997 + }
13998 +#endif
13999 +
14000 + PKCS11H_DEBUG (
14001 + PKCS11H_LOG_DEBUG2,
14002 + "PKCS#11: pkcs11h_certificate_enumCertificateIds return rv=%ld-'%s'",
14003 + rv,
14004 + pkcs11h_getMessage (rv)
14005 + );
14006 +
14007 + return rv;
14008 +}
14009 +
14010 +#endif /* ENABLE_PKCS11H_CERTIFICATE */
14011 +
14012 +#endif /* ENABLE_PKCS11H_ENUM */
14013 +
14014 +#if defined(ENABLE_PKCS11H_SLOTEVENT)
14015 +/*======================================================================*
14016 + * SLOTEVENT INTERFACE
14017 + *======================================================================*/
14018 +
14019 +static
14020 +unsigned long
14021 +_pkcs11h_slotevent_checksum (
14022 + IN const unsigned char * const p,
14023 + IN const size_t s
14024 +) {
14025 + unsigned long r = 0;
14026 + size_t i;
14027 + for (i=0;i<s;i++) {
14028 + r += p[i];
14029 + }
14030 + return r;
14031 +}
14032 +
14033 +static
14034 +void *
14035 +_pkcs11h_slotevent_provider (
14036 + IN void *p
14037 +) {
14038 + pkcs11h_provider_t provider = (pkcs11h_provider_t)p;
14039 + CK_SLOT_ID slot;
14040 + CK_RV rv = CKR_OK;
14041 +
14042 + PKCS11H_DEBUG (
14043 + PKCS11H_LOG_DEBUG2,
14044 + "PKCS#11: _pkcs11h_slotevent_provider provider='%s' entry",
14045 + provider->manufacturerID
14046 + );
14047 +
14048 + if (rv == CKR_OK && !provider->enabled) {
14049 + rv = CKR_OPERATION_NOT_INITIALIZED;
14050 + }
14051 +
14052 + if (rv == CKR_OK) {
14053 +
14054 + if (provider->slot_poll_interval == 0) {
14055 + provider->slot_poll_interval = PKCS11H_DEFAULT_SLOTEVENT_POLL;
14056 + }
14057 +
14058 + /*
14059 + * If we cannot finalize, we cannot cause
14060 + * WaitForSlotEvent to terminate
14061 + */
14062 + if (!provider->should_finalize) {
14063 + PKCS11H_DEBUG (
14064 + PKCS11H_LOG_DEBUG1,
14065 + "PKCS#11: Setup slotevent provider='%s' mode hardset to poll",
14066 + provider->manufacturerID
14067 + );
14068 + provider->slot_event_method = PKCS11H_SLOTEVENT_METHOD_POLL;
14069 + }
14070 +
14071 + if (
14072 + provider->slot_event_method == PKCS11H_SLOTEVENT_METHOD_AUTO ||
14073 + provider->slot_event_method == PKCS11H_SLOTEVENT_METHOD_TRIGGER
14074 + ) {
14075 + if (
14076 + provider->f->C_WaitForSlotEvent (
14077 + CKF_DONT_BLOCK,
14078 + &slot,
14079 + NULL_PTR
14080 + ) == CKR_FUNCTION_NOT_SUPPORTED
14081 + ) {
14082 + PKCS11H_DEBUG (
14083 + PKCS11H_LOG_DEBUG1,
14084 + "PKCS#11: Setup slotevent provider='%s' mode is poll",
14085 + provider->manufacturerID
14086 + );
14087 +
14088 + provider->slot_event_method = PKCS11H_SLOTEVENT_METHOD_POLL;
14089 + }
14090 + else {
14091 + PKCS11H_DEBUG (
14092 + PKCS11H_LOG_DEBUG1,
14093 + "PKCS#11: Setup slotevent provider='%s' mode is trigger",
14094 + provider->manufacturerID
14095 + );
14096 +
14097 + provider->slot_event_method = PKCS11H_SLOTEVENT_METHOD_TRIGGER;
14098 + }
14099 + }
14100 + }
14101 +
14102 + if (provider->slot_event_method == PKCS11H_SLOTEVENT_METHOD_TRIGGER) {
14103 + while (
14104 + !s_pkcs11h_data->slotevent.should_terminate &&
14105 + provider->enabled &&
14106 + rv == CKR_OK &&
14107 + (rv = provider->f->C_WaitForSlotEvent (
14108 + 0,
14109 + &slot,
14110 + NULL_PTR
14111 + )) == CKR_OK
14112 + ) {
14113 + PKCS11H_DEBUG (
14114 + PKCS11H_LOG_DEBUG1,
14115 + "PKCS#11: Slotevent provider='%s' event",
14116 + provider->manufacturerID
14117 + );
14118 +
14119 + _pkcs11h_threading_condSignal (&s_pkcs11h_data->slotevent.cond_event);
14120 + }
14121 + }
14122 + else {
14123 + unsigned long ulLastChecksum = 0;
14124 + PKCS11H_BOOL is_first_time = TRUE;
14125 +
14126 + while (
14127 + !s_pkcs11h_data->slotevent.should_terminate &&
14128 + provider->enabled &&
14129 + rv == CKR_OK
14130 + ) {
14131 + unsigned long ulCurrentChecksum = 0;
14132 +
14133 + CK_SLOT_ID_PTR slots = NULL;
14134 + CK_ULONG slotnum;
14135 +
14136 + PKCS11H_DEBUG (
14137 + PKCS11H_LOG_DEBUG1,
14138 + "PKCS#11: Slotevent provider='%s' poll",
14139 + provider->manufacturerID
14140 + );
14141 +
14142 + if (
14143 + rv == CKR_OK &&
14144 + (rv = _pkcs11h_session_getSlotList (
14145 + provider,
14146 + TRUE,
14147 + &slots,
14148 + &slotnum
14149 + )) == CKR_OK
14150 + ) {
14151 + CK_ULONG i;
14152 +
14153 + for (i=0;i<slotnum;i++) {
14154 + CK_TOKEN_INFO info;
14155 +
14156 + if (provider->f->C_GetTokenInfo (slots[i], &info) == CKR_OK) {
14157 + ulCurrentChecksum += (
14158 + _pkcs11h_slotevent_checksum (
14159 + info.label,
14160 + sizeof (info.label)
14161 + ) +
14162 + _pkcs11h_slotevent_checksum (
14163 + info.manufacturerID,
14164 + sizeof (info.manufacturerID)
14165 + ) +
14166 + _pkcs11h_slotevent_checksum (
14167 + info.model,
14168 + sizeof (info.model)
14169 + ) +
14170 + _pkcs11h_slotevent_checksum (
14171 + info.serialNumber,
14172 + sizeof (info.serialNumber)
14173 + )
14174 + );
14175 + }
14176 + }
14177 + }
14178 +
14179 + if (rv == CKR_OK) {
14180 + if (is_first_time) {
14181 + is_first_time = FALSE;
14182 + }
14183 + else {
14184 + if (ulLastChecksum != ulCurrentChecksum) {
14185 + PKCS11H_DEBUG (
14186 + PKCS11H_LOG_DEBUG1,
14187 + "PKCS#11: Slotevent provider='%s' event",
14188 + provider->manufacturerID
14189 + );
14190 +
14191 + _pkcs11h_threading_condSignal (&s_pkcs11h_data->slotevent.cond_event);
14192 + }
14193 + }
14194 + ulLastChecksum = ulCurrentChecksum;
14195 + }
14196 +
14197 + if (slots != NULL) {
14198 + _pkcs11h_mem_free ((void *)&slots);
14199 + }
14200 +
14201 + if (!s_pkcs11h_data->slotevent.should_terminate) {
14202 + _pkcs11h_threading_sleep (provider->slot_poll_interval);
14203 + }
14204 + }
14205 + }
14206 +
14207 + PKCS11H_DEBUG (
14208 + PKCS11H_LOG_DEBUG2,
14209 + "PKCS#11: _pkcs11h_slotevent_provider provider='%s' return",
14210 + provider->manufacturerID
14211 + );
14212 +
14213 + return NULL;
14214 +}
14215 +
14216 +static
14217 +void *
14218 +_pkcs11h_slotevent_manager (
14219 + IN void *p
14220 +) {
14221 + PKCS11H_BOOL first_time = TRUE;
14222 +
14223 + (void)p;
14224 +
14225 + PKCS11H_DEBUG (
14226 + PKCS11H_LOG_DEBUG2,
14227 + "PKCS#11: _pkcs11h_slotevent_manager entry"
14228 + );
14229 +
14230 + /*
14231 + * Trigger hook, so application may
14232 + * depend on initial slot change
14233 + */
14234 + PKCS11H_DEBUG (
14235 + PKCS11H_LOG_DEBUG1,
14236 + "PKCS#11: Calling slotevent hook"
14237 + );
14238 + s_pkcs11h_data->hooks.slotevent (s_pkcs11h_data->hooks.slotevent_data);
14239 +
14240 + while (
14241 + first_time || /* Must enter wait or mutex will never be free */
14242 + !s_pkcs11h_data->slotevent.should_terminate
14243 + ) {
14244 + pkcs11h_provider_t current_provider;
14245 +
14246 + first_time = FALSE;
14247 +
14248 + /*
14249 + * Start each provider thread
14250 + * if not already started.
14251 + * This is required in order to allow
14252 + * adding new providers.
14253 + */
14254 + for (
14255 + current_provider = s_pkcs11h_data->providers;
14256 + current_provider != NULL;
14257 + current_provider = current_provider->next
14258 + ) {
14259 + if (!current_provider->enabled) {
14260 + if (current_provider->slotevent_thread == PKCS11H_THREAD_NULL) {
14261 + _pkcs11h_threading_threadStart (
14262 + &current_provider->slotevent_thread,
14263 + _pkcs11h_slotevent_provider,
14264 + current_provider
14265 + );
14266 + }
14267 + }
14268 + else {
14269 + if (current_provider->slotevent_thread != PKCS11H_THREAD_NULL) {
14270 + _pkcs11h_threading_threadJoin (&current_provider->slotevent_thread);
14271 + }
14272 + }
14273 + }
14274 +
14275 + PKCS11H_DEBUG (
14276 + PKCS11H_LOG_DEBUG2,
14277 + "PKCS#11: _pkcs11h_slotevent_manager waiting for slotevent"
14278 + );
14279 + _pkcs11h_threading_condWait (&s_pkcs11h_data->slotevent.cond_event, PKCS11H_COND_INFINITE);
14280 +
14281 + if (s_pkcs11h_data->slotevent.skip_event) {
14282 + PKCS11H_DEBUG (
14283 + PKCS11H_LOG_DEBUG1,
14284 + "PKCS#11: Slotevent skipping event"
14285 + );
14286 + s_pkcs11h_data->slotevent.skip_event = FALSE;
14287 + }
14288 + else {
14289 + PKCS11H_DEBUG (
14290 + PKCS11H_LOG_DEBUG1,
14291 + "PKCS#11: Calling slotevent hook"
14292 + );
14293 + s_pkcs11h_data->hooks.slotevent (s_pkcs11h_data->hooks.slotevent_data);
14294 + }
14295 + }
14296 +
14297 + {
14298 + pkcs11h_provider_t current_provider;
14299 +
14300 + PKCS11H_DEBUG (
14301 + PKCS11H_LOG_DEBUG2,
14302 + "PKCS#11: _pkcs11h_slotevent_manager joining threads"
14303 + );
14304 +
14305 +
14306 + for (
14307 + current_provider = s_pkcs11h_data->providers;
14308 + current_provider != NULL;
14309 + current_provider = current_provider->next
14310 + ) {
14311 + if (current_provider->slotevent_thread != PKCS11H_THREAD_NULL) {
14312 + _pkcs11h_threading_threadJoin (&current_provider->slotevent_thread);
14313 + }
14314 + }
14315 + }
14316 +
14317 + PKCS11H_DEBUG (
14318 + PKCS11H_LOG_DEBUG2,
14319 + "PKCS#11: _pkcs11h_slotevent_manager return"
14320 + );
14321 +
14322 + return NULL;
14323 +}
14324 +
14325 +static
14326 +CK_RV
14327 +_pkcs11h_slotevent_init () {
14328 + CK_RV rv = CKR_OK;
14329 +
14330 + PKCS11H_DEBUG (
14331 + PKCS11H_LOG_DEBUG2,
14332 + "PKCS#11: _pkcs11h_slotevent_init entry"
14333 + );
14334 +
14335 + if (!s_pkcs11h_data->slotevent.initialized) {
14336 + if (rv == CKR_OK) {
14337 + rv = _pkcs11h_threading_condInit (&s_pkcs11h_data->slotevent.cond_event);
14338 + }
14339 +
14340 + if (rv == CKR_OK) {
14341 + rv = _pkcs11h_threading_threadStart (
14342 + &s_pkcs11h_data->slotevent.thread,
14343 + _pkcs11h_slotevent_manager,
14344 + NULL
14345 + );
14346 + }
14347 +
14348 + if (rv == CKR_OK) {
14349 + s_pkcs11h_data->slotevent.initialized = TRUE;
14350 + }
14351 + }
14352 +
14353 + PKCS11H_DEBUG (
14354 + PKCS11H_LOG_DEBUG2,
14355 + "PKCS#11: _pkcs11h_slotevent_init return rv=%ld-'%s'",
14356 + rv,
14357 + pkcs11h_getMessage (rv)
14358 + );
14359 +
14360 + return rv;
14361 +}
14362 +
14363 +static
14364 +CK_RV
14365 +_pkcs11h_slotevent_notify () {
14366 +
14367 + PKCS11H_DEBUG (
14368 + PKCS11H_LOG_DEBUG2,
14369 + "PKCS#11: _pkcs11h_slotevent_notify entry"
14370 + );
14371 +
14372 + if (s_pkcs11h_data->slotevent.initialized) {
14373 + s_pkcs11h_data->slotevent.skip_event = TRUE;
14374 + _pkcs11h_threading_condSignal (&s_pkcs11h_data->slotevent.cond_event);
14375 + }
14376 +
14377 + PKCS11H_DEBUG (
14378 + PKCS11H_LOG_DEBUG2,
14379 + "PKCS#11: _pkcs11h_slotevent_notify return"
14380 + );
14381 +
14382 + return CKR_OK;
14383 +}
14384 +
14385 +static
14386 +CK_RV
14387 +_pkcs11h_slotevent_terminate () {
14388 +
14389 + PKCS11H_DEBUG (
14390 + PKCS11H_LOG_DEBUG2,
14391 + "PKCS#11: _pkcs11h_slotevent_terminate entry"
14392 + );
14393 +
14394 + if (s_pkcs11h_data->slotevent.initialized) {
14395 + s_pkcs11h_data->slotevent.should_terminate = TRUE;
14396 +
14397 + _pkcs11h_slotevent_notify ();
14398 +
14399 + if (s_pkcs11h_data->slotevent.thread != PKCS11H_THREAD_NULL) {
14400 + _pkcs11h_threading_threadJoin (&s_pkcs11h_data->slotevent.thread);
14401 + }
14402 +
14403 + _pkcs11h_threading_condFree (&s_pkcs11h_data->slotevent.cond_event);
14404 + s_pkcs11h_data->slotevent.initialized = FALSE;
14405 + }
14406 +
14407 + PKCS11H_DEBUG (
14408 + PKCS11H_LOG_DEBUG2,
14409 + "PKCS#11: _pkcs11h_slotevent_terminate return"
14410 + );
14411 +
14412 + return CKR_OK;
14413 +}
14414 +
14415 +#endif
14416 +
14417 +#if defined(ENABLE_PKCS11H_OPENSSL)
14418 +/*======================================================================*
14419 + * OPENSSL INTERFACE
14420 + *======================================================================*/
14421 +
14422 +static
14423 +pkcs11h_openssl_session_t
14424 +_pkcs11h_openssl_get_openssl_session (
14425 + IN OUT const RSA *rsa
14426 +) {
14427 + pkcs11h_openssl_session_t session;
14428 +
14429 + PKCS11H_ASSERT (rsa!=NULL);
14430 +#if OPENSSL_VERSION_NUMBER < 0x00907000L
14431 + session = (pkcs11h_openssl_session_t)RSA_get_app_data ((RSA *)rsa);
14432 +#else
14433 + session = (pkcs11h_openssl_session_t)RSA_get_app_data (rsa);
14434 +#endif
14435 + PKCS11H_ASSERT (session!=NULL);
14436 +
14437 + return session;
14438 +}
14439 +
14440 +static
14441 +pkcs11h_certificate_t
14442 +_pkcs11h_openssl_get_pkcs11h_certificate (
14443 + IN OUT const RSA *rsa
14444 +) {
14445 + pkcs11h_openssl_session_t session = _pkcs11h_openssl_get_openssl_session (rsa);
14446 +
14447 + PKCS11H_ASSERT (session!=NULL);
14448 + PKCS11H_ASSERT (session->certificate!=NULL);
14449 +
14450 + return session->certificate;
14451 +}
14452 +
14453 +#if OPENSSL_VERSION_NUMBER < 0x00907000L
14454 +static
14455 +int
14456 +_pkcs11h_openssl_dec (
14457 + IN int flen,
14458 + IN unsigned char *from,
14459 + OUT unsigned char *to,
14460 + IN OUT RSA *rsa,
14461 + IN int padding
14462 +) {
14463 +#else
14464 +static
14465 +int
14466 +_pkcs11h_openssl_dec (
14467 + IN int flen,
14468 + IN const unsigned char *from,
14469 + OUT unsigned char *to,
14470 + IN OUT RSA *rsa,
14471 + IN int padding
14472 +) {
14473 +#endif
14474 + PKCS11H_ASSERT (from!=NULL);
14475 + PKCS11H_ASSERT (to!=NULL);
14476 + PKCS11H_ASSERT (rsa!=NULL);
14477 +
14478 + PKCS11H_DEBUG (
14479 + PKCS11H_LOG_DEBUG2,
14480 + "PKCS#11: _pkcs11h_openssl_dec entered - flen=%d, from=%p, to=%p, rsa=%p, padding=%d",
14481 + flen,
14482 + from,
14483 + to,
14484 + (void *)rsa,
14485 + padding
14486 + );
14487 +
14488 + PKCS11H_LOG (
14489 + PKCS11H_LOG_ERROR,
14490 + "PKCS#11: Private key decryption is not supported"
14491 + );
14492 +
14493 + PKCS11H_DEBUG (
14494 + PKCS11H_LOG_DEBUG2,
14495 + "PKCS#11: _pkcs11h_openssl_dec return"
14496 + );
14497 +
14498 + return -1;
14499 +}
14500 +
14501 +#if OPENSSL_VERSION_NUMBER < 0x00907000L
14502 +static
14503 +int
14504 +_pkcs11h_openssl_sign (
14505 + IN int type,
14506 + IN unsigned char *m,
14507 + IN unsigned int m_len,
14508 + OUT unsigned char *sigret,
14509 + OUT unsigned int *siglen,
14510 + IN OUT RSA *rsa
14511 +) {
14512 +#else
14513 +static
14514 +int
14515 +_pkcs11h_openssl_sign (
14516 + IN int type,
14517 + IN const unsigned char *m,
14518 + IN unsigned int m_len,
14519 + OUT unsigned char *sigret,
14520 + OUT unsigned int *siglen,
14521 + IN OUT const RSA *rsa
14522 +) {
14523 +#endif
14524 + pkcs11h_certificate_t certificate = _pkcs11h_openssl_get_pkcs11h_certificate (rsa);
14525 + PKCS11H_BOOL session_locked = FALSE;
14526 + CK_RV rv = CKR_OK;
14527 +
14528 + int myrsa_size = 0;
14529 +
14530 + unsigned char *enc_alloc = NULL;
14531 + unsigned char *enc = NULL;
14532 + int enc_len = 0;
14533 +
14534 + PKCS11H_ASSERT (m!=NULL);
14535 + PKCS11H_ASSERT (sigret!=NULL);
14536 + PKCS11H_ASSERT (siglen!=NULL);
14537 +
14538 + PKCS11H_DEBUG (
14539 + PKCS11H_LOG_DEBUG2,
14540 + "PKCS#11: _pkcs11h_openssl_sign entered - type=%d, m=%p, m_len=%u, signret=%p, *signlen=%u, rsa=%p",
14541 + type,
14542 + m,
14543 + m_len,
14544 + sigret,
14545 + sigret != NULL ? *siglen : 0,
14546 + (void *)rsa
14547 + );
14548 +
14549 + if (rv == CKR_OK) {
14550 + myrsa_size=RSA_size(rsa);
14551 + }
14552 +
14553 + if (type == NID_md5_sha1) {
14554 + if (rv == CKR_OK) {
14555 + enc = (unsigned char *)m;
14556 + enc_len = m_len;
14557 + }
14558 + }
14559 + else {
14560 + X509_SIG sig;
14561 + ASN1_TYPE parameter;
14562 + X509_ALGOR algor;
14563 + ASN1_OCTET_STRING digest;
14564 + unsigned char *p = NULL;
14565 +
14566 + if (
14567 + rv == CKR_OK &&
14568 + (rv = _pkcs11h_mem_malloc ((void*)&enc, myrsa_size+1)) == CKR_OK
14569 + ) {
14570 + enc_alloc = enc;
14571 + }
14572 +
14573 + if (rv == CKR_OK) {
14574 + sig.algor = &algor;
14575 + }
14576 +
14577 + if (
14578 + rv == CKR_OK &&
14579 + (sig.algor->algorithm = OBJ_nid2obj (type)) == NULL
14580 + ) {
14581 + rv = CKR_FUNCTION_FAILED;
14582 + }
14583 +
14584 + if (
14585 + rv == CKR_OK &&
14586 + sig.algor->algorithm->length == 0
14587 + ) {
14588 + rv = CKR_KEY_SIZE_RANGE;
14589 + }
14590 +
14591 + if (rv == CKR_OK) {
14592 + parameter.type = V_ASN1_NULL;
14593 + parameter.value.ptr = NULL;
14594 +
14595 + sig.algor->parameter = &parameter;
14596 +
14597 + sig.digest = &digest;
14598 + sig.digest->data = (unsigned char *)m;
14599 + sig.digest->length = m_len;
14600 + }
14601 +
14602 + if (
14603 + rv == CKR_OK &&
14604 + (enc_len=i2d_X509_SIG (&sig, NULL)) < 0
14605 + ) {
14606 + rv = CKR_FUNCTION_FAILED;
14607 + }
14608 +
14609 + /*
14610 + * d_X509_SIG increments pointer!
14611 + */
14612 + p = enc;
14613 +
14614 + if (
14615 + rv == CKR_OK &&
14616 + (enc_len=i2d_X509_SIG (&sig, &p)) < 0
14617 + ) {
14618 + rv = CKR_FUNCTION_FAILED;
14619 + }
14620 + }
14621 +
14622 + if (
14623 + rv == CKR_OK &&
14624 + enc_len > (myrsa_size-RSA_PKCS1_PADDING_SIZE)
14625 + ) {
14626 + rv = CKR_KEY_SIZE_RANGE;
14627 + }
14628 +
14629 + if (
14630 + rv == CKR_OK &&
14631 + (rv = pkcs11h_certificate_lockSession (certificate)) == CKR_OK
14632 + ) {
14633 + session_locked = TRUE;
14634 + }
14635 +
14636 + if (rv == CKR_OK) {
14637 + PKCS11H_DEBUG (
14638 + PKCS11H_LOG_DEBUG1,
14639 + "PKCS#11: Performing signature"
14640 + );
14641 +
14642 + *siglen = myrsa_size;
14643 +
14644 + if (
14645 + (rv = pkcs11h_certificate_signAny (
14646 + certificate,
14647 + CKM_RSA_PKCS,
14648 + enc,
14649 + enc_len,
14650 + sigret,
14651 + siglen
14652 + )) != CKR_OK
14653 + ) {
14654 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11h_getMessage (rv));
14655 + }
14656 + }
14657 +
14658 + if (session_locked) {
14659 + pkcs11h_certificate_releaseSession (certificate);
14660 + session_locked = FALSE;
14661 + }
14662 +
14663 + if (enc_alloc != NULL) {
14664 + _pkcs11h_mem_free ((void *)&enc_alloc);
14665 + }
14666 +
14667 + PKCS11H_DEBUG (
14668 + PKCS11H_LOG_DEBUG2,
14669 + "PKCS#11: _pkcs11h_openssl_sign - return rv=%ld-'%s'",
14670 + rv,
14671 + pkcs11h_getMessage (rv)
14672 + );
14673 +
14674 + return rv == CKR_OK ? 1 : -1;
14675 +}
14676 +
14677 +static
14678 +int
14679 +_pkcs11h_openssl_finish (
14680 + IN OUT RSA *rsa
14681 +) {
14682 + pkcs11h_openssl_session_t openssl_session = _pkcs11h_openssl_get_openssl_session (rsa);
14683 +
14684 + PKCS11H_DEBUG (
14685 + PKCS11H_LOG_DEBUG2,
14686 + "PKCS#11: _pkcs11h_openssl_finish - entered rsa=%p",
14687 + (void *)rsa
14688 + );
14689 +
14690 + RSA_set_app_data (rsa, NULL);
14691 +
14692 + if (openssl_session->orig_finish != NULL) {
14693 + openssl_session->orig_finish (rsa);
14694 +
14695 +#ifdef BROKEN_OPENSSL_ENGINE
14696 + {
14697 + /* We get called TWICE here, once for
14698 + * releasing the key and also for
14699 + * releasing the engine.
14700 + * To prevent endless recursion, FIRST
14701 + * clear rsa->engine, THEN call engine->finish
14702 + */
14703 + ENGINE *e = rsa->engine;
14704 + rsa->engine = NULL;
14705 + if (e) {
14706 + ENGINE_finish(e);
14707 + }
14708 + }
14709 +#endif
14710 + }
14711 +
14712 + pkcs11h_openssl_freeSession (openssl_session);
14713 +
14714 + PKCS11H_DEBUG (
14715 + PKCS11H_LOG_DEBUG2,
14716 + "PKCS#11: _pkcs11h_openssl_finish - return"
14717 + );
14718 +
14719 + return 1;
14720 +}
14721 +
14722 +X509 *
14723 +pkcs11h_openssl_getX509 (
14724 + IN const pkcs11h_certificate_t certificate
14725 +) {
14726 + unsigned char *certificate_blob = NULL;
14727 + size_t certificate_blob_size = 0;
14728 + X509 *x509 = NULL;
14729 + CK_RV rv = CKR_OK;
14730 +
14731 + pkcs11_openssl_d2i_t d2i1 = NULL;
14732 + PKCS11H_BOOL ok = TRUE;
14733 +
14734 + PKCS11H_ASSERT (certificate!=NULL);
14735 +
14736 + PKCS11H_DEBUG (
14737 + PKCS11H_LOG_DEBUG2,
14738 + "PKCS#11: pkcs11h_openssl_getX509 - entry certificate=%p",
14739 + (void *)certificate
14740 + );
14741 +
14742 + if (
14743 + ok &&
14744 + (x509 = X509_new ()) == NULL
14745 + ) {
14746 + ok = FALSE;
14747 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Unable to allocate certificate object");
14748 + }
14749 +
14750 + if (
14751 + ok &&
14752 + pkcs11h_certificate_getCertificateBlob (
14753 + certificate,
14754 + NULL,
14755 + &certificate_blob_size
14756 + ) != CKR_OK
14757 + ) {
14758 + ok = FALSE;
14759 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot read X.509 certificate from token %ld-'%s'", rv, pkcs11h_getMessage (rv));
14760 + }
14761 +
14762 + if (
14763 + ok &&
14764 + (rv = _pkcs11h_mem_malloc ((void *)&certificate_blob, certificate_blob_size)) != CKR_OK
14765 + ) {
14766 + ok = FALSE;
14767 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot allocate X.509 memory %ld-'%s'", rv, pkcs11h_getMessage (rv));
14768 + }
14769 +
14770 + if (
14771 + ok &&
14772 + pkcs11h_certificate_getCertificateBlob (
14773 + certificate,
14774 + certificate_blob,
14775 + &certificate_blob_size
14776 + ) != CKR_OK
14777 + ) {
14778 + ok = FALSE;
14779 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot read X.509 certificate from token %ld-'%s'", rv, pkcs11h_getMessage (rv));
14780 + }
14781 +
14782 + d2i1 = (pkcs11_openssl_d2i_t)certificate_blob;
14783 + if (
14784 + ok &&
14785 + !d2i_X509 (&x509, &d2i1, certificate_blob_size)
14786 + ) {
14787 + ok = FALSE;
14788 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Unable to parse X.509 certificate");
14789 + }
14790 +
14791 + if (!ok) {
14792 + X509_free (x509);
14793 + x509 = NULL;
14794 + }
14795 +
14796 + PKCS11H_DEBUG (
14797 + PKCS11H_LOG_DEBUG2,
14798 + "PKCS#11: pkcs11h_openssl_getX509 - return x509=%p",
14799 + (void *)x509
14800 + );
14801 +
14802 + return x509;
14803 +}
14804 +
14805 +pkcs11h_openssl_session_t
14806 +pkcs11h_openssl_createSession (
14807 + IN const pkcs11h_certificate_t certificate
14808 +) {
14809 + pkcs11h_openssl_session_t openssl_session = NULL;
14810 + PKCS11H_BOOL ok = TRUE;
14811 +
14812 + PKCS11H_DEBUG (
14813 + PKCS11H_LOG_DEBUG2,
14814 + "PKCS#11: pkcs11h_openssl_createSession - entry"
14815 + );
14816 +
14817 + if (
14818 + ok &&
14819 + _pkcs11h_mem_malloc (
14820 + (void*)&openssl_session,
14821 + sizeof (struct pkcs11h_openssl_session_s)) != CKR_OK
14822 + ) {
14823 + ok = FALSE;
14824 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot allocate memory");
14825 + }
14826 +
14827 + if (ok) {
14828 + const RSA_METHOD *def = RSA_get_default_method();
14829 +
14830 + memmove (&openssl_session->smart_rsa, def, sizeof(RSA_METHOD));
14831 +
14832 + openssl_session->orig_finish = def->finish;
14833 +
14834 + openssl_session->smart_rsa.name = "pkcs11";
14835 + openssl_session->smart_rsa.rsa_priv_dec = _pkcs11h_openssl_dec;
14836 + openssl_session->smart_rsa.rsa_sign = _pkcs11h_openssl_sign;
14837 + openssl_session->smart_rsa.finish = _pkcs11h_openssl_finish;
14838 + openssl_session->smart_rsa.flags = RSA_METHOD_FLAG_NO_CHECK | RSA_FLAG_EXT_PKEY;
14839 + openssl_session->certificate = certificate;
14840 + openssl_session->reference_count = 1;
14841 + }
14842 +
14843 + if (!ok) {
14844 + _pkcs11h_mem_free ((void *)&openssl_session);
14845 + }
14846 +
14847 + PKCS11H_DEBUG (
14848 + PKCS11H_LOG_DEBUG2,
14849 + "PKCS#11: pkcs11h_openssl_createSession - return openssl_session=%p",
14850 + (void *)openssl_session
14851 + );
14852 +
14853 + return openssl_session;
14854 +}
14855 +
14856 +pkcs11h_hook_openssl_cleanup_t
14857 +pkcs11h_openssl_getCleanupHook (
14858 + IN const pkcs11h_openssl_session_t openssl_session
14859 +) {
14860 + PKCS11H_ASSERT (openssl_session!=NULL);
14861 +
14862 + return openssl_session->cleanup_hook;
14863 +}
14864 +
14865 +void
14866 +pkcs11h_openssl_setCleanupHook (
14867 + IN const pkcs11h_openssl_session_t openssl_session,
14868 + IN const pkcs11h_hook_openssl_cleanup_t cleanup
14869 +) {
14870 + PKCS11H_ASSERT (openssl_session!=NULL);
14871 +
14872 + openssl_session->cleanup_hook = cleanup;
14873 +}
14874 +
14875 +void
14876 +pkcs11h_openssl_freeSession (
14877 + IN const pkcs11h_openssl_session_t openssl_session
14878 +) {
14879 + PKCS11H_ASSERT (openssl_session!=NULL);
14880 + PKCS11H_ASSERT (openssl_session->reference_count>0);
14881 +
14882 + PKCS11H_DEBUG (
14883 + PKCS11H_LOG_DEBUG2,
14884 + "PKCS#11: pkcs11h_openssl_freeSession - entry openssl_session=%p, count=%d",
14885 + (void *)openssl_session,
14886 + openssl_session->reference_count
14887 + );
14888 +
14889 + openssl_session->reference_count--;
14890 +
14891 + if (openssl_session->reference_count == 0) {
14892 + if (openssl_session->cleanup_hook != NULL) {
14893 + openssl_session->cleanup_hook (openssl_session->certificate);
14894 + }
14895 +
14896 + if (openssl_session->x509 != NULL) {
14897 + X509_free (openssl_session->x509);
14898 + openssl_session->x509 = NULL;
14899 + }
14900 + if (openssl_session->certificate != NULL) {
14901 + pkcs11h_certificate_freeCertificate (openssl_session->certificate);
14902 + openssl_session->certificate = NULL;
14903 + }
14904 +
14905 + _pkcs11h_mem_free ((void *)&openssl_session);
14906 + }
14907 +
14908 + PKCS11H_DEBUG (
14909 + PKCS11H_LOG_DEBUG2,
14910 + "PKCS#11: pkcs11h_openssl_freeSession - return"
14911 + );
14912 +}
14913 +
14914 +RSA *
14915 +pkcs11h_openssl_session_getRSA (
14916 + IN const pkcs11h_openssl_session_t openssl_session
14917 +) {
14918 + X509 *x509 = NULL;
14919 + RSA *rsa = NULL;
14920 + EVP_PKEY *pubkey = NULL;
14921 + PKCS11H_BOOL ok = TRUE;
14922 +
14923 + PKCS11H_ASSERT (openssl_session!=NULL);
14924 + PKCS11H_ASSERT (!openssl_session->initialized);
14925 + PKCS11H_ASSERT (openssl_session!=NULL);
14926 +
14927 + PKCS11H_DEBUG (
14928 + PKCS11H_LOG_DEBUG2,
14929 + "PKCS#11: pkcs11h_openssl_session_getRSA - entry openssl_session=%p",
14930 + (void *)openssl_session
14931 + );
14932 +
14933 + /*
14934 + * Dup x509 so RSA will not hold session x509
14935 + */
14936 + if (
14937 + ok &&
14938 + (x509 = pkcs11h_openssl_session_getX509 (openssl_session)) == NULL
14939 + ) {
14940 + ok = FALSE;
14941 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get certificate object");
14942 + }
14943 +
14944 + if (
14945 + ok &&
14946 + (pubkey = X509_get_pubkey (x509)) == NULL
14947 + ) {
14948 + ok = FALSE;
14949 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get public key");
14950 + }
14951 +
14952 + if (
14953 + ok &&
14954 + pubkey->type != EVP_PKEY_RSA
14955 + ) {
14956 + ok = FALSE;
14957 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Invalid public key algorithm");
14958 + }
14959 +
14960 + if (
14961 + ok &&
14962 + (rsa = EVP_PKEY_get1_RSA (pubkey)) == NULL
14963 + ) {
14964 + ok = FALSE;
14965 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get RSA key");
14966 + }
14967 +
14968 + if (ok) {
14969 + RSA_set_method (rsa, &openssl_session->smart_rsa);
14970 + RSA_set_app_data (rsa, openssl_session);
14971 + openssl_session->reference_count++;
14972 + }
14973 +
14974 +#ifdef BROKEN_OPENSSL_ENGINE
14975 + if (ok) {
14976 + if (!rsa->engine) {
14977 + rsa->engine = ENGINE_get_default_RSA();
14978 + }
14979 +
14980 + ENGINE_set_RSA(ENGINE_get_default_RSA(), &openssl_session->smart_rsa);
14981 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: OpenSSL engine support is broken! Workaround enabled");
14982 + }
14983 +#endif
14984 +
14985 + if (ok) {
14986 + rsa->flags |= RSA_FLAG_SIGN_VER;
14987 + openssl_session->initialized = TRUE;
14988 + }
14989 + else {
14990 + if (rsa != NULL) {
14991 + RSA_free (rsa);
14992 + rsa = NULL;
14993 + }
14994 + }
14995 +
14996 + /*
14997 + * openssl objects have reference
14998 + * count, so release them
14999 + */
15000 + if (pubkey != NULL) {
15001 + EVP_PKEY_free (pubkey);
15002 + pubkey = NULL;
15003 + }
15004 +
15005 + if (x509 != NULL) {
15006 + X509_free (x509);
15007 + x509 = NULL;
15008 + }
15009 +
15010 + PKCS11H_DEBUG (
15011 + PKCS11H_LOG_DEBUG2,
15012 + "PKCS#11: pkcs11h_openssl_session_getRSA - return rsa=%p",
15013 + (void *)rsa
15014 + );
15015 +
15016 + return rsa;
15017 +}
15018 +
15019 +X509 *
15020 +pkcs11h_openssl_session_getX509 (
15021 + IN const pkcs11h_openssl_session_t openssl_session
15022 +) {
15023 + X509 *x509 = NULL;
15024 + PKCS11H_BOOL ok = TRUE;
15025 +
15026 + PKCS11H_ASSERT (openssl_session!=NULL);
15027 +
15028 + PKCS11H_DEBUG (
15029 + PKCS11H_LOG_DEBUG2,
15030 + "PKCS#11: pkcs11h_openssl_session_getX509 - entry openssl_session=%p",
15031 + (void *)openssl_session
15032 + );
15033 +
15034 + if (
15035 + ok &&
15036 + openssl_session->x509 == NULL &&
15037 + (openssl_session->x509 = pkcs11h_openssl_getX509 (openssl_session->certificate)) == NULL
15038 + ) {
15039 + ok = FALSE;
15040 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get certificate object");
15041 + }
15042 +
15043 + if (
15044 + ok &&
15045 + (x509 = X509_dup (openssl_session->x509)) == NULL
15046 + ) {
15047 + ok = FALSE;
15048 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot duplicate certificate object");
15049 + }
15050 +
15051 + PKCS11H_DEBUG (
15052 + PKCS11H_LOG_DEBUG2,
15053 + "PKCS#11: pkcs11h_openssl_session_getX509 - return x509=%p",
15054 + (void *)x509
15055 + );
15056 +
15057 + return x509;
15058 +}
15059 +
15060 +#endif /* ENABLE_PKCS11H_OPENSSL */
15061 +
15062 +#if defined(ENABLE_PKCS11H_STANDALONE)
15063 +/*======================================================================*
15064 + * STANDALONE INTERFACE
15065 + *======================================================================*/
15066 +
15067 +void
15068 +pkcs11h_standalone_dump_slots (
15069 + IN const pkcs11h_output_print_t my_output,
15070 + IN void * const global_data,
15071 + IN const char * const provider
15072 +) {
15073 + CK_RV rv = CKR_OK;
15074 +
15075 + pkcs11h_provider_t pkcs11h_provider;
15076 +
15077 + PKCS11H_ASSERT (my_output!=NULL);
15078 + /*PKCS11H_ASSERT (global_data) NOT NEEDED */
15079 + PKCS11H_ASSERT (provider!=NULL);
15080 +
15081 + if (
15082 + rv == CKR_OK &&
15083 + (rv = pkcs11h_initialize ()) != CKR_OK
15084 + ) {
15085 + my_output (global_data, "PKCS#11: Cannot initialize interface %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
15086 + }
15087 +
15088 + if (
15089 + rv == CKR_OK &&
15090 + (rv = pkcs11h_addProvider (
15091 + provider,
15092 + provider,
15093 + FALSE,
15094 + (
15095 + PKCS11H_SIGNMODE_MASK_SIGN |
15096 + PKCS11H_SIGNMODE_MASK_RECOVER
15097 + ),
15098 + PKCS11H_SLOTEVENT_METHOD_AUTO,
15099 + 0,
15100 + FALSE
15101 + )) != CKR_OK
15102 + ) {
15103 + my_output (global_data, "PKCS#11: Cannot initialize provider %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
15104 + }
15105 +
15106 + /*
15107 + * our provider is head
15108 + */
15109 + if (rv == CKR_OK) {
15110 + pkcs11h_provider = s_pkcs11h_data->providers;
15111 + if (pkcs11h_provider == NULL || !pkcs11h_provider->enabled) {
15112 + my_output (global_data, "PKCS#11: Cannot get provider %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
15113 + rv = CKR_GENERAL_ERROR;
15114 + }
15115 + }
15116 +
15117 + if (rv == CKR_OK) {
15118 + CK_INFO info;
15119 +
15120 + if ((rv = pkcs11h_provider->f->C_GetInfo (&info)) != CKR_OK) {
15121 + my_output (global_data, "PKCS#11: Cannot get PKCS#11 provider information %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
15122 + rv = CKR_OK;
15123 + }
15124 + else {
15125 + char manufacturerID[sizeof (info.manufacturerID)+1];
15126 +
15127 + _pkcs11h_util_fixupFixedString (
15128 + manufacturerID,
15129 + (char *)info.manufacturerID,
15130 + sizeof (info.manufacturerID)
15131 + );
15132 +
15133 + my_output (
15134 + global_data,
15135 + (
15136 + "Provider Information:\n"
15137 + "\tcryptokiVersion:\t%u.%u\n"
15138 + "\tmanufacturerID:\t\t%s\n"
15139 + "\tflags:\t\t\t%08x\n"
15140 + "\n"
15141 + ),
15142 + info.cryptokiVersion.major,
15143 + info.cryptokiVersion.minor,
15144 + manufacturerID,
15145 + (unsigned)info.flags
15146 + );
15147 + }
15148 + }
15149 +
15150 + if (rv == CKR_OK) {
15151 + CK_SLOT_ID_PTR slots = NULL;
15152 + CK_ULONG slotnum;
15153 + CK_SLOT_ID slot_index;
15154 +
15155 + if (
15156 + _pkcs11h_session_getSlotList (
15157 + pkcs11h_provider,
15158 + CK_FALSE,
15159 + &slots,
15160 + &slotnum
15161 + ) != CKR_OK
15162 + ) {
15163 + my_output (global_data, "PKCS#11: Cannot get slot list %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
15164 + }
15165 + else {
15166 + my_output (
15167 + global_data,
15168 + "The following slots are available for use with this provider.\n"
15169 + );
15170 +
15171 +#if defined(PKCS11H_PRM_SLOT_TYPE)
15172 + my_output (
15173 + global_data,
15174 + (
15175 + "Each slot shown below may be used as a parameter to a\n"
15176 + "%s and %s options.\n"
15177 + ),
15178 + PKCS11H_PRM_SLOT_TYPE,
15179 + PKCS11H_PRM_SLOT_ID
15180 + );
15181 +#endif
15182 +
15183 + my_output (
15184 + global_data,
15185 + (
15186 + "\n"
15187 + "Slots: (id - name)\n"
15188 + )
15189 + );
15190 +
15191 + for (slot_index=0;slot_index < slotnum;slot_index++) {
15192 + CK_SLOT_INFO info;
15193 +
15194 + if (
15195 + (rv = pkcs11h_provider->f->C_GetSlotInfo (
15196 + slots[slot_index],
15197 + &info
15198 + )) == CKR_OK
15199 + ) {
15200 + char current_name[sizeof (info.slotDescription)+1];
15201 +
15202 + _pkcs11h_util_fixupFixedString (
15203 + current_name,
15204 + (char *)info.slotDescription,
15205 + sizeof (info.slotDescription)
15206 + );
15207 +
15208 + my_output (global_data, "\t%lu - %s\n", slots[slot_index], current_name);
15209 + }
15210 + }
15211 + }
15212 +
15213 + if (slots != NULL) {
15214 + _pkcs11h_mem_free ((void *)&slots);
15215 + }
15216 + }
15217 +
15218 + pkcs11h_terminate ();
15219 +}
15220 +
15221 +static
15222 +PKCS11H_BOOL
15223 +_pkcs11h_standalone_dump_objects_pin_prompt (
15224 + IN void * const global_data,
15225 + IN void * const user_data,
15226 + IN const pkcs11h_token_id_t token,
15227 + IN const unsigned retry,
15228 + OUT char * const pin,
15229 + IN const size_t pin_max
15230 +) {
15231 + (void)user_data;
15232 + (void)token;
15233 +
15234 + /*
15235 + * Don't lock card
15236 + */
15237 + if (retry == 0) {
15238 + strncpy (pin, (char *)global_data, pin_max);
15239 + return TRUE;
15240 + }
15241 + else {
15242 + return FALSE;
15243 + }
15244 +}
15245 +
15246 +void
15247 +_pkcs11h_standalone_dump_objects_hex (
15248 + IN const unsigned char * const p,
15249 + IN const size_t p_size,
15250 + OUT char * const sz,
15251 + IN const size_t max,
15252 + IN const char * const prefix
15253 +) {
15254 + size_t j;
15255 +
15256 + sz[0] = '\0';
15257 +
15258 + for (j=0;j<p_size;j+=16) {
15259 + char line[3*16+1];
15260 + size_t k;
15261 +
15262 + line[0] = '\0';
15263 + for (k=0;k<16 && j+k<p_size;k++) {
15264 + sprintf (line+strlen (line), "%02x ", p[j+k]);
15265 + }
15266 +
15267 + strncat (
15268 + sz,
15269 + prefix,
15270 + max-1-strlen (sz)
15271 + );
15272 + strncat (
15273 + sz,
15274 + line,
15275 + max-1-strlen (sz)
15276 + );
15277 + strncat (
15278 + sz,
15279 + "\n",
15280 + max-1-strlen (sz)
15281 + );
15282 + }
15283 +
15284 + sz[max-1] = '\0';
15285 +}
15286 +
15287 +void
15288 +pkcs11h_standalone_dump_objects (
15289 + IN const pkcs11h_output_print_t my_output,
15290 + IN void * const global_data,
15291 + IN const char * const provider,
15292 + IN const char * const slot,
15293 + IN const char * const pin
15294 +) {
15295 + CK_SLOT_ID s;
15296 + CK_RV rv = CKR_OK;
15297 +
15298 + pkcs11h_provider_t pkcs11h_provider = NULL;
15299 + pkcs11h_token_id_t token_id = NULL;
15300 + pkcs11h_session_t session = NULL;
15301 +
15302 + PKCS11H_ASSERT (my_output!=NULL);
15303 + /*PKCS11H_ASSERT (global_data) NOT NEEDED */
15304 + PKCS11H_ASSERT (provider!=NULL);
15305 + PKCS11H_ASSERT (slot!=NULL);
15306 + PKCS11H_ASSERT (pin!=NULL);
15307 +
15308 + s = atoi (slot);
15309 +
15310 + if (
15311 + rv == CKR_OK &&
15312 + (rv = pkcs11h_initialize ()) != CKR_OK
15313 + ) {
15314 + my_output (global_data, "PKCS#11: Cannot initialize interface %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
15315 + }
15316 +
15317 + if (
15318 + rv == CKR_OK &&
15319 + (rv = pkcs11h_setPINPromptHook (_pkcs11h_standalone_dump_objects_pin_prompt, (void *)pin)) != CKR_OK
15320 + ) {
15321 + my_output (global_data, "PKCS#11: Cannot set hooks %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
15322 + }
15323 +
15324 + if (
15325 + rv == CKR_OK &&
15326 + (rv = pkcs11h_addProvider (
15327 + provider,
15328 + provider,
15329 + FALSE,
15330 + (
15331 + PKCS11H_SIGNMODE_MASK_SIGN |
15332 + PKCS11H_SIGNMODE_MASK_RECOVER
15333 + ),
15334 + PKCS11H_SLOTEVENT_METHOD_AUTO,
15335 + 0,
15336 + FALSE
15337 + )) != CKR_OK
15338 + ) {
15339 + my_output (global_data, "PKCS#11: Cannot initialize provider %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
15340 + }
15341 +
15342 + /*
15343 + * our provider is head
15344 + */
15345 + if (rv == CKR_OK) {
15346 + pkcs11h_provider = s_pkcs11h_data->providers;
15347 + if (pkcs11h_provider == NULL || !pkcs11h_provider->enabled) {
15348 + my_output (global_data, "PKCS#11: Cannot get provider %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
15349 + rv = CKR_GENERAL_ERROR;
15350 + }
15351 + }
15352 +
15353 + if (rv == CKR_OK) {
15354 + CK_TOKEN_INFO info;
15355 +
15356 + if (
15357 + (rv = pkcs11h_provider->f->C_GetTokenInfo (
15358 + s,
15359 + &info
15360 + )) != CKR_OK
15361 + ) {
15362 + my_output (global_data, "PKCS#11: Cannot get token information for slot %ld %ld-'%s'\n", s, rv, pkcs11h_getMessage (rv));
15363 + /* Ignore this error */
15364 + rv = CKR_OK;
15365 + }
15366 + else {
15367 + char label[sizeof (info.label)+1];
15368 + char manufacturerID[sizeof (info.manufacturerID)+1];
15369 + char model[sizeof (info.model)+1];
15370 + char serialNumberNumber[sizeof (info.serialNumber)+1];
15371 +
15372 + _pkcs11h_util_fixupFixedString (
15373 + label,
15374 + (char *)info.label,
15375 + sizeof (info.label)
15376 + );
15377 + _pkcs11h_util_fixupFixedString (
15378 + manufacturerID,
15379 + (char *)info.manufacturerID,
15380 + sizeof (info.manufacturerID)
15381 + );
15382 + _pkcs11h_util_fixupFixedString (
15383 + model,
15384 + (char *)info.model,
15385 + sizeof (info.model)
15386 + );
15387 + _pkcs11h_util_fixupFixedString (
15388 + serialNumberNumber,
15389 + (char *)info.serialNumber,
15390 + sizeof (info.serialNumber)
15391 + );
15392 +
15393 + my_output (
15394 + global_data,
15395 + (
15396 + "Token Information:\n"
15397 + "\tlabel:\t\t%s\n"
15398 + "\tmanufacturerID:\t%s\n"
15399 + "\tmodel:\t\t%s\n"
15400 + "\tserialNumber:\t%s\n"
15401 + "\tflags:\t\t%08x\n"
15402 + "\n"
15403 + ),
15404 + label,
15405 + manufacturerID,
15406 + model,
15407 + serialNumberNumber,
15408 + (unsigned)info.flags
15409 + );
15410 +
15411 +#if defined(PKCS11H_PRM_SLOT_TYPE)
15412 + my_output (
15413 + global_data,
15414 + (
15415 + "You can access this token using\n"
15416 + "%s \"label\" %s \"%s\" options.\n"
15417 + "\n"
15418 + ),
15419 + PKCS11H_PRM_SLOT_TYPE,
15420 + PKCS11H_PRM_SLOT_ID,
15421 + label
15422 + );
15423 +#endif
15424 +
15425 + if (
15426 + rv == CKR_OK &&
15427 + (rv = _pkcs11h_token_getTokenId (
15428 + &info,
15429 + &token_id
15430 + )) != CKR_OK
15431 + ) {
15432 + my_output (global_data, "PKCS#11: Cannot get token id for slot %ld %ld-'%s'\n", s, rv, pkcs11h_getMessage (rv));
15433 + rv = CKR_OK;
15434 + }
15435 + }
15436 + }
15437 +
15438 + if (token_id != NULL) {
15439 + if (
15440 + (rv = _pkcs11h_session_getSessionByTokenId (
15441 + token_id,
15442 + &session
15443 + )) != CKR_OK
15444 + ) {
15445 + my_output (global_data, "PKCS#11: Cannot session for token '%s' %ld-'%s'\n", token_id->display, rv, pkcs11h_getMessage (rv));
15446 + rv = CKR_OK;
15447 + }
15448 + }
15449 +
15450 + if (session != NULL) {
15451 + CK_OBJECT_HANDLE *objects = NULL;
15452 + CK_ULONG objects_found = 0;
15453 + CK_ULONG i;
15454 +
15455 + if (
15456 + (rv = _pkcs11h_session_login (
15457 + session,
15458 + FALSE,
15459 + TRUE,
15460 + NULL,
15461 + PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT
15462 + )) != CKR_OK
15463 + ) {
15464 + my_output (global_data, "PKCS#11: Cannot open session to token '%s' %ld-'%s'\n", session->token_id->display, rv, pkcs11h_getMessage (rv));
15465 + }
15466 +
15467 + my_output (
15468 + global_data,
15469 + "The following objects are available for use with this token.\n"
15470 + );
15471 +
15472 +#if defined(PKCS11H_PRM_OBJ_TYPE)
15473 + my_output (
15474 + global_data,
15475 + (
15476 + "Each object shown below may be used as a parameter to\n"
15477 + "%s and %s options.\n"
15478 + ),
15479 + PKCS11H_PRM_OBJ_TYPE,
15480 + PKCS11H_PRM_OBJ_ID
15481 + );
15482 +#endif
15483 +
15484 + my_output (
15485 + global_data,
15486 + "\n"
15487 + );
15488 +
15489 + if (
15490 + rv == CKR_OK &&
15491 + (rv = _pkcs11h_session_findObjects (
15492 + session,
15493 + NULL,
15494 + 0,
15495 + &objects,
15496 + &objects_found
15497 + )) != CKR_OK
15498 + ) {
15499 + my_output (global_data, "PKCS#11: Cannot query objects for token '%s' %ld-'%s'\n", session->token_id->display, rv, pkcs11h_getMessage (rv));
15500 + }
15501 +
15502 + for (i=0;rv == CKR_OK && i < objects_found;i++) {
15503 + CK_OBJECT_CLASS attrs_class = 0;
15504 + CK_ATTRIBUTE attrs[] = {
15505 + {CKA_CLASS, &attrs_class, sizeof (attrs_class)}
15506 + };
15507 +
15508 + if (
15509 + _pkcs11h_session_getObjectAttributes (
15510 + session,
15511 + objects[i],
15512 + attrs,
15513 + sizeof (attrs) / sizeof (CK_ATTRIBUTE)
15514 + ) == CKR_OK
15515 + ) {
15516 + if (attrs_class == CKO_CERTIFICATE) {
15517 + CK_ATTRIBUTE attrs_cert[] = {
15518 + {CKA_ID, NULL, 0},
15519 + {CKA_LABEL, NULL, 0},
15520 + {CKA_VALUE, NULL, 0}
15521 + };
15522 + unsigned char *attrs_id = NULL;
15523 + int attrs_id_size = 0;
15524 + unsigned char *attrs_value = NULL;
15525 + int attrs_value_size = 0;
15526 + char *attrs_label = NULL;
15527 + char hex_id[1024];
15528 + char subject[1024];
15529 + char serialNumber[1024];
15530 + time_t notAfter = 0;
15531 +
15532 + subject[0] = '\0';
15533 + serialNumber[0] = '\0';
15534 +
15535 +
15536 + if (
15537 + _pkcs11h_session_getObjectAttributes (
15538 + session,
15539 + objects[i],
15540 + attrs_cert,
15541 + sizeof (attrs_cert) / sizeof (CK_ATTRIBUTE)
15542 + ) == CKR_OK &&
15543 + _pkcs11h_mem_malloc (
15544 + (void *)&attrs_label,
15545 + attrs_cert[1].ulValueLen+1
15546 + ) == CKR_OK
15547 + ) {
15548 + attrs_id = (unsigned char *)attrs_cert[0].pValue;
15549 + attrs_id_size = attrs_cert[0].ulValueLen;
15550 + attrs_value = (unsigned char *)attrs_cert[2].pValue;
15551 + attrs_value_size = attrs_cert[2].ulValueLen;
15552 +
15553 + memset (attrs_label, 0, attrs_cert[1].ulValueLen+1);
15554 + memmove (attrs_label, attrs_cert[1].pValue, attrs_cert[1].ulValueLen);
15555 + _pkcs11h_standalone_dump_objects_hex (
15556 + attrs_id,
15557 + attrs_id_size,
15558 + hex_id,
15559 + sizeof (hex_id),
15560 + "\t\t"
15561 + );
15562 + }
15563 +
15564 + if (attrs_value != NULL) {
15565 +#if defined(USE_PKCS11H_OPENSSL)
15566 + X509 *x509 = NULL;
15567 + BIO *bioSerial = NULL;
15568 +#elif defined(USE_PKCS11H_GNUTLS)
15569 + gnutls_x509_crt_t cert = NULL;
15570 +#endif
15571 +
15572 + _pkcs11h_certificate_getDN (
15573 + attrs_value,
15574 + attrs_value_size,
15575 + subject,
15576 + sizeof (subject)
15577 + );
15578 + notAfter = _pkcs11h_certificate_getExpiration (
15579 + attrs_value,
15580 + attrs_value_size
15581 + );
15582 +#if defined(USE_PKCS11H_OPENSSL)
15583 + if ((x509 = X509_new ()) == NULL) {
15584 + my_output (global_data, "Cannot create x509 context\n");
15585 + }
15586 + else {
15587 + pkcs11_openssl_d2i_t d2i1 = (pkcs11_openssl_d2i_t)attrs_value;
15588 + if (d2i_X509 (&x509, &d2i1, attrs_value_size)) {
15589 + if ((bioSerial = BIO_new (BIO_s_mem ())) == NULL) {
15590 + my_output (global_data, "Cannot create BIO context\n");
15591 + }
15592 + else {
15593 + int n;
15594 +
15595 + i2a_ASN1_INTEGER(bioSerial, X509_get_serialNumber (x509));
15596 + n = BIO_read (bioSerial, serialNumber, sizeof (serialNumber)-1);
15597 + if (n<0) {
15598 + serialNumber[0] = '\0';
15599 + }
15600 + else {
15601 + serialNumber[n] = '\0';
15602 + }
15603 + }
15604 + }
15605 + }
15606 +
15607 +
15608 + if (bioSerial != NULL) {
15609 + BIO_free_all (bioSerial);
15610 + bioSerial = NULL;
15611 + }
15612 + if (x509 != NULL) {
15613 + X509_free (x509);
15614 + x509 = NULL;
15615 + }
15616 +#elif defined(USE_PKCS11H_GNUTLS)
15617 + if (gnutls_x509_crt_init (&cert) == GNUTLS_E_SUCCESS) {
15618 + gnutls_datum_t datum = {attrs_value, attrs_value_size};
15619 +
15620 + if (gnutls_x509_crt_import (cert, &datum, GNUTLS_X509_FMT_DER) == GNUTLS_E_SUCCESS) {
15621 + unsigned char ser[1024];
15622 + size_t ser_size = sizeof (ser);
15623 + if (gnutls_x509_crt_get_serial (cert, ser, &ser_size) == GNUTLS_E_SUCCESS) {
15624 + _pkcs11h_util_binaryToHex (
15625 + serialNumber,
15626 + sizeof (serialNumber),
15627 + ser,
15628 + ser_size
15629 + );
15630 + }
15631 + }
15632 + gnutls_x509_crt_deinit (cert);
15633 + }
15634 +#else
15635 +#error Invalid configuration.
15636 +#endif
15637 + }
15638 +
15639 + my_output (
15640 + global_data,
15641 + (
15642 + "Object\n"
15643 + "\tType:\t\t\tCertificate\n"
15644 + "\tCKA_ID:\n"
15645 + "%s"
15646 + "\tCKA_LABEL:\t\t%s\n"
15647 + "\tsubject:\t\t%s\n"
15648 + "\tserialNumber:\t\t%s\n"
15649 + "\tnotAfter:\t\t%s\n"
15650 + ),
15651 + hex_id,
15652 + attrs_label,
15653 + subject,
15654 + serialNumber,
15655 + asctime (localtime (&notAfter))
15656 + );
15657 +
15658 + _pkcs11h_mem_free ((void *)&attrs_label);
15659 +
15660 + _pkcs11h_session_freeObjectAttributes (
15661 + attrs_cert,
15662 + sizeof (attrs_cert) / sizeof (CK_ATTRIBUTE)
15663 + );
15664 + }
15665 + else if (attrs_class == CKO_PRIVATE_KEY) {
15666 + CK_BBOOL sign_recover = CK_FALSE;
15667 + CK_BBOOL sign = CK_FALSE;
15668 + CK_ATTRIBUTE attrs_key[] = {
15669 + {CKA_SIGN, &sign, sizeof (sign)},
15670 + {CKA_SIGN_RECOVER, &sign_recover, sizeof (sign_recover)}
15671 + };
15672 + CK_ATTRIBUTE attrs_key_common[] = {
15673 + {CKA_ID, NULL, 0},
15674 + {CKA_LABEL, NULL, 0}
15675 + };
15676 + unsigned char *attrs_id = NULL;
15677 + int attrs_id_size = 0;
15678 + char *attrs_label = NULL;
15679 + char hex_id[1024];
15680 +
15681 + pkcs11h_provider->f->C_GetAttributeValue (
15682 + session->session_handle,
15683 + objects[i],
15684 + attrs_key,
15685 + sizeof (attrs_key) / sizeof (CK_ATTRIBUTE)
15686 + );
15687 +
15688 + if (
15689 + _pkcs11h_session_getObjectAttributes (
15690 + session,
15691 + objects[i],
15692 + attrs_key_common,
15693 + sizeof (attrs_key_common) / sizeof (CK_ATTRIBUTE)
15694 + ) == CKR_OK &&
15695 + _pkcs11h_mem_malloc (
15696 + (void *)&attrs_label,
15697 + attrs_key_common[1].ulValueLen+1
15698 + ) == CKR_OK
15699 + ) {
15700 + attrs_id = (unsigned char *)attrs_key_common[0].pValue;
15701 + attrs_id_size = attrs_key_common[0].ulValueLen;
15702 +
15703 + memset (attrs_label, 0, attrs_key_common[1].ulValueLen+1);
15704 + memmove (attrs_label, attrs_key_common[1].pValue, attrs_key_common[1].ulValueLen);
15705 +
15706 + _pkcs11h_standalone_dump_objects_hex (
15707 + attrs_id,
15708 + attrs_id_size,
15709 + hex_id,
15710 + sizeof (hex_id),
15711 + "\t\t"
15712 + );
15713 +
15714 + }
15715 +
15716 + my_output (
15717 + global_data,
15718 + (
15719 + "Object\n"
15720 + "\tType:\t\t\tPrivate Key\n"
15721 + "\tCKA_ID:\n"
15722 + "%s"
15723 + "\tCKA_LABEL:\t\t%s\n"
15724 + "\tCKA_SIGN:\t\t%s\n"
15725 + "\tCKA_SIGN_RECOVER:\t%s\n"
15726 + ),
15727 + hex_id,
15728 + attrs_label,
15729 + sign ? "TRUE" : "FALSE",
15730 + sign_recover ? "TRUE" : "FALSE"
15731 + );
15732 +
15733 + _pkcs11h_mem_free ((void *)&attrs_label);
15734 +
15735 + _pkcs11h_session_freeObjectAttributes (
15736 + attrs_key_common,
15737 + sizeof (attrs_key_common) / sizeof (CK_ATTRIBUTE)
15738 + );
15739 + }
15740 + else if (attrs_class == CKO_PUBLIC_KEY) {
15741 + CK_ATTRIBUTE attrs_key_common[] = {
15742 + {CKA_ID, NULL, 0},
15743 + {CKA_LABEL, NULL, 0}
15744 + };
15745 + unsigned char *attrs_id = NULL;
15746 + int attrs_id_size = 0;
15747 + char *attrs_label = NULL;
15748 + char hex_id[1024];
15749 +
15750 + if (
15751 + _pkcs11h_session_getObjectAttributes (
15752 + session,
15753 + objects[i],
15754 + attrs_key_common,
15755 + sizeof (attrs_key_common) / sizeof (CK_ATTRIBUTE)
15756 + ) == CKR_OK &&
15757 + _pkcs11h_mem_malloc (
15758 + (void *)&attrs_label,
15759 + attrs_key_common[1].ulValueLen+1
15760 + ) == CKR_OK
15761 + ) {
15762 + attrs_id = (unsigned char *)attrs_key_common[0].pValue;
15763 + attrs_id_size = attrs_key_common[0].ulValueLen;
15764 +
15765 + memset (attrs_label, 0, attrs_key_common[1].ulValueLen+1);
15766 + memmove (attrs_label, attrs_key_common[1].pValue, attrs_key_common[1].ulValueLen);
15767 +
15768 + _pkcs11h_standalone_dump_objects_hex (
15769 + attrs_id,
15770 + attrs_id_size,
15771 + hex_id,
15772 + sizeof (hex_id),
15773 + "\t\t"
15774 + );
15775 +
15776 + }
15777 +
15778 + my_output (
15779 + global_data,
15780 + (
15781 + "Object\n"
15782 + "\tType:\t\t\tPublic Key\n"
15783 + "\tCKA_ID:\n"
15784 + "%s"
15785 + "\tCKA_LABEL:\t\t%s\n"
15786 + ),
15787 + hex_id,
15788 + attrs_label
15789 + );
15790 +
15791 + _pkcs11h_mem_free ((void *)&attrs_label);
15792 +
15793 + _pkcs11h_session_freeObjectAttributes (
15794 + attrs_key_common,
15795 + sizeof (attrs_key_common) / sizeof (CK_ATTRIBUTE)
15796 + );
15797 + }
15798 + else if (attrs_class == CKO_DATA) {
15799 + CK_ATTRIBUTE attrs_key_common[] = {
15800 + {CKA_APPLICATION, NULL, 0},
15801 + {CKA_LABEL, NULL, 0}
15802 + };
15803 + char *attrs_application = NULL;
15804 + char *attrs_label = NULL;
15805 +
15806 + if (
15807 + _pkcs11h_session_getObjectAttributes (
15808 + session,
15809 + objects[i],
15810 + attrs_key_common,
15811 + sizeof (attrs_key_common) / sizeof (CK_ATTRIBUTE)
15812 + ) == CKR_OK &&
15813 + _pkcs11h_mem_malloc (
15814 + (void *)&attrs_application,
15815 + attrs_key_common[0].ulValueLen+1
15816 + ) == CKR_OK &&
15817 + _pkcs11h_mem_malloc (
15818 + (void *)&attrs_label,
15819 + attrs_key_common[1].ulValueLen+1
15820 + ) == CKR_OK
15821 + ) {
15822 + memset (attrs_application, 0, attrs_key_common[0].ulValueLen+1);
15823 + memmove (attrs_application, attrs_key_common[0].pValue, attrs_key_common[0].ulValueLen);
15824 + memset (attrs_label, 0, attrs_key_common[1].ulValueLen+1);
15825 + memmove (attrs_label, attrs_key_common[1].pValue, attrs_key_common[1].ulValueLen);
15826 + }
15827 +
15828 + my_output (
15829 + global_data,
15830 + (
15831 + "Object\n"
15832 + "\tType:\t\t\tData\n"
15833 + "\tCKA_APPLICATION\t\t%s\n"
15834 + "\tCKA_LABEL:\t\t%s\n"
15835 + ),
15836 + attrs_application,
15837 + attrs_label
15838 + );
15839 +
15840 + _pkcs11h_mem_free ((void *)&attrs_application);
15841 + _pkcs11h_mem_free ((void *)&attrs_label);
15842 +
15843 + _pkcs11h_session_freeObjectAttributes (
15844 + attrs_key_common,
15845 + sizeof (attrs_key_common) / sizeof (CK_ATTRIBUTE)
15846 + );
15847 + }
15848 + else {
15849 + my_output (
15850 + global_data,
15851 + (
15852 + "Object\n"
15853 + "\tType:\t\t\tUnsupported\n"
15854 + )
15855 + );
15856 + }
15857 + }
15858 +
15859 + _pkcs11h_session_freeObjectAttributes (
15860 + attrs,
15861 + sizeof (attrs) / sizeof (CK_ATTRIBUTE)
15862 + );
15863 +
15864 + /*
15865 + * Ignore any error and
15866 + * perform next iteration
15867 + */
15868 + rv = CKR_OK;
15869 + }
15870 +
15871 + if (objects != NULL) {
15872 + _pkcs11h_mem_free ((void *)&objects);
15873 + }
15874 +
15875 + /*
15876 + * Ignore this error
15877 + */
15878 + rv = CKR_OK;
15879 + }
15880 +
15881 + if (session != NULL) {
15882 + _pkcs11h_session_release (session);
15883 + session = NULL;
15884 + }
15885 +
15886 + if (token_id != NULL) {
15887 + pkcs11h_token_freeTokenId (token_id);
15888 + token_id = NULL;
15889 + }
15890 +
15891 + pkcs11h_terminate ();
15892 +}
15893 +
15894 +#endif /* ENABLE_PKCS11H_STANDALONE */
15895 +
15896 +#ifdef BROKEN_OPENSSL_ENGINE
15897 +static void broken_openssl_init() __attribute__ ((constructor));
15898 +static void broken_openssl_init()
15899 +{
15900 + SSL_library_init();
15901 + ENGINE_load_openssl();
15902 + ENGINE_register_all_RSA();
15903 +}
15904 +#endif
15905 +
15906 +#else
15907 +static void dummy (void) {}
15908 +#endif /* PKCS11H_HELPER_ENABLE */
15909 +
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
15913 @@ -0,0 +1,103 @@
15914 +/*
15915 + * Copyright (c) 2005-2006 Alon Bar-Lev. All rights reserved.
15916 + *
15917 + * Redistribution and use in source and binary forms, with or without
15918 + * modification, are permitted provided that the following conditions
15919 + * are met:
15920 + * 1. Redistributions of source code must retain the above copyright
15921 + * notice, this list of conditions and the following disclaimer.
15922 + * 2. Redistributions in binary form must reproduce the above copyright
15923 + * notice, this list of conditions and the following disclaimer in the
15924 + * documentation and/or other materials provided with the distribution.
15925 + *
15926 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15927 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15928 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
15929 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
15930 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
15931 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
15932 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
15933 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
15934 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
15935 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15936 + */
15937 +
15938 +#ifndef __PKCS11H_HELPER_CONFIG_H
15939 +#define __PKCS11H_HELPER_CONFIG_H
15940 +
15941 +#if !defined(PKCS11H_NO_NEED_INCLUDE_CONFIG)
15942 +
15943 +#include "includes.h"
15944 +
15945 +#endif /* PKCS11H_NO_NEED_INCLUDE_CONFIG */
15946 +
15947 +#ifndef SSH_PKCS11H_DISABLED
15948 +#define ENABLE_PKCS11H_HELPER
15949 +#endif
15950 +
15951 +#include <assert.h>
15952 +#include <string.h>
15953 +#include <ctype.h>
15954 +#if !defined(WIN32)
15955 +#include <unistd.h>
15956 +#include <dlfcn.h>
15957 +#endif
15958 +
15959 +#include "log.h"
15960 +#include "xmalloc.h"
15961 +#include "openssl/x509.h"
15962 +
15963 +#if defined(HAVE_CYGWIN)
15964 +#define PKCS11H_USE_CYGWIN
15965 +#endif
15966 +
15967 +#if !defined(FALSE)
15968 +#define FALSE 0
15969 +#endif
15970 +#if !defined(TRUE)
15971 +#define TRUE (!FALSE)
15972 +#endif
15973 +
15974 +typedef int PKCS11H_BOOL;
15975 +
15976 +#if !defined(IN)
15977 +#define IN
15978 +#endif
15979 +#if !defined(OUT)
15980 +#define OUT
15981 +#endif
15982 +
15983 +#define USE_PKCS11H_OPENSSL
15984 +#define ENABLE_PKCS11H_DEBUG
15985 +#undef ENABLE_PKCS11H_THREADING
15986 +#undef ENABLE_PKCS11H_TOKEN
15987 +#undef ENABLE_PKCS11H_DATA
15988 +#define ENABLE_PKCS11H_CERTIFICATE
15989 +#undef ENABLE_PKCS11H_LOCATE
15990 +#define ENABLE_PKCS11H_ENUM
15991 +#define ENABLE_PKCS11H_SERIALIZATION
15992 +#undef ENABLE_PKCS11H_SLOTEVENT
15993 +#define ENABLE_PKCS11H_OPENSSL
15994 +#define ENABLE_PKCS11H_STANDALONE
15995 +
15996 +/*
15997 +#define PKCS11H_PRM_SLOT_TYPE "--pkcs11-slot-type"
15998 +#define PKCS11H_PRM_SLOT_ID "--pkcs11-slot"
15999 +#define PKCS11H_PRM_OBJ_TYPE "--pkcs11-id-type"
16000 +#define PKCS11H_PRM_OBJ_ID "--pkcs11-id"
16001 +*/
16002 +
16003 +#define PKCS11H_ASSERT assert
16004 +#define PKCS11H_TIME time
16005 +#define PKCS11H_MALLOC xmalloc
16006 +#define PKCS11H_FREE xfree
16007 +
16008 +#ifdef ENABLE_PKCS11H_HELPER
16009 +#if defined(WIN32) || defined(PKCS11H_USE_CYGWIN)
16010 +#include "cryptoki-win32.h"
16011 +#else
16012 +#include "cryptoki.h"
16013 +#endif
16014 +
16015 +#endif /* ENABLE_PKCS11H_HELPER */
16016 +#endif /* __PKCS11H_HELPER_CONFIG_H */
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
16020 @@ -0,0 +1,1303 @@
16021 +/*
16022 + * Copyright (c) 2005-2006 Alon Bar-Lev <alon.barlev@gmail.com>
16023 + * All rights reserved.
16024 + *
16025 + * This software is available to you under a choice of one of two
16026 + * licenses. You may choose to be licensed under the terms of the GNU
16027 + * General Public License (GPL) Version 2, or the OpenIB.org BSD license.
16028 + *
16029 + * GNU General Public License (GPL) Version 2
16030 + * ===========================================
16031 + * This program is free software; you can redistribute it and/or modify
16032 + * it under the terms of the GNU General Public License version 2
16033 + * as published by the Free Software Foundation.
16034 + *
16035 + * This program is distributed in the hope that it will be useful,
16036 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
16037 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16038 + * GNU General Public License for more details.
16039 + *
16040 + * You should have received a copy of the GNU General Public License
16041 + * along with this program (see the file COPYING[.GPL2] included with this
16042 + * distribution); if not, write to the Free Software Foundation, Inc.,
16043 + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16044 + *
16045 + * OpenIB.org BSD license
16046 + * =======================
16047 + * Redistribution and use in source and binary forms, with or without modifi-
16048 + * cation, are permitted provided that the following conditions are met:
16049 + *
16050 + * o Redistributions of source code must retain the above copyright notice,
16051 + * this list of conditions and the following disclaimer.
16052 + *
16053 + * o Redistributions in binary form must reproduce the above copyright no-
16054 + * tice, this list of conditions and the following disclaimer in the do-
16055 + * cumentation and/or other materials provided with the distribution.
16056 + *
16057 + * o The names of the contributors may not be used to endorse or promote
16058 + * products derived from this software without specific prior written
16059 + * permission.
16060 + *
16061 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16062 + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
16063 + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16064 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LI-
16065 + * ABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUEN-
16066 + * TIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
16067 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEV-
16068 + * ER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABI-
16069 + * LITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
16070 + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16071 + */
16072 +
16073 +/*
16074 + * The routines in this file deal with providing private key cryptography
16075 + * using RSA Security Inc. PKCS #11 Cryptographic Token Interface (Cryptoki).
16076 + *
16077 + */
16078 +
16079 +#ifndef __PKCS11H_HELPER_H
16080 +#define __PKCS11H_HELPER_H
16081 +
16082 +#if defined(__cplusplus)
16083 +extern "C" {
16084 +#endif
16085 +
16086 +#include "pkcs11-helper-config.h"
16087 +
16088 +#if !defined(USE_PKCS11H_OPENSSL) && !defined(USE_PKCS11H_GNUTLS)
16089 +#error PKCS#11: USE_PKCS11H_OPENSSL or USE_PKCS11H_GNUTLS must be defined
16090 +#endif
16091 +
16092 +#if defined(ENABLE_PKCS11H_SLOTEVENT) && !defined(ENABLE_PKCS11H_THREADING)
16093 +#error PKCS#11: ENABLE_PKCS11H_SLOTEVENT requires ENABLE_PKCS11H_THREADING
16094 +#endif
16095 +#if defined(ENABLE_PKCS11H_OPENSSL) && !defined(ENABLE_PKCS11H_CERTIFICATE)
16096 +#error PKCS#11: ENABLE_PKCS11H_OPENSSL requires ENABLE_PKCS11H_CERTIFICATE
16097 +#endif
16098 +
16099 +#define PKCS11H_LOG_DEBUG2 5
16100 +#define PKCS11H_LOG_DEBUG1 4
16101 +#define PKCS11H_LOG_INFO 3
16102 +#define PKCS11H_LOG_WARN 2
16103 +#define PKCS11H_LOG_ERROR 1
16104 +#define PKCS11H_LOG_QUITE 0
16105 +
16106 +#define PKCS11H_PIN_CACHE_INFINITE -1
16107 +
16108 +#define PKCS11H_SIGNMODE_MASK_SIGN (1<<0)
16109 +#define PKCS11H_SIGNMODE_MASK_RECOVER (1<<1)
16110 +
16111 +#define PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT (1<<0)
16112 +#define PKCS11H_PROMPT_MAST_ALLOW_CARD_PROMPT (1<<1)
16113 +#define PKCS11H_PROMPT_MASK_ALLOW_ALL ( \
16114 + PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT | \
16115 + PKCS11H_PROMPT_MAST_ALLOW_CARD_PROMPT \
16116 + )
16117 +
16118 +#define PKCS11H_SLOTEVENT_METHOD_AUTO 0
16119 +#define PKCS11H_SLOTEVENT_METHOD_TRIGGER 1
16120 +#define PKCS11H_SLOTEVENT_METHOD_POLL 2
16121 +
16122 +#define PKCS11H_ENUM_METHOD_CACHE 0
16123 +#define PKCS11H_ENUM_METHOD_CACHE_EXIST 1
16124 +#define PKCS11H_ENUM_METHOD_RELOAD 2
16125 +
16126 +typedef void (*pkcs11h_output_print_t)(
16127 + IN void * const global_data,
16128 + IN const char * const format,
16129 + IN ...
16130 +)
16131 +#if __GNUC__ > 2
16132 + __attribute__ ((format (printf, 2, 3)))
16133 +#endif
16134 + ;
16135 +
16136 +struct pkcs11h_token_id_s;
16137 +typedef struct pkcs11h_token_id_s *pkcs11h_token_id_t;
16138 +
16139 +#if defined(ENABLE_PKCS11H_CERTIFICATE)
16140 +
16141 +struct pkcs11h_certificate_id_s;
16142 +struct pkcs11h_certificate_s;
16143 +typedef struct pkcs11h_certificate_id_s *pkcs11h_certificate_id_t;
16144 +typedef struct pkcs11h_certificate_s *pkcs11h_certificate_t;
16145 +
16146 +#endif /* ENABLE_PKCS11H_CERTIFICATE */
16147 +
16148 +#if defined(ENABLE_PKCS11H_ENUM)
16149 +
16150 +struct pkcs11h_token_id_list_s;
16151 +typedef struct pkcs11h_token_id_list_s *pkcs11h_token_id_list_t;
16152 +
16153 +#if defined(ENABLE_PKCS11H_DATA)
16154 +
16155 +struct pkcs11h_data_id_list_s;
16156 +typedef struct pkcs11h_data_id_list_s *pkcs11h_data_id_list_t;
16157 +
16158 +#endif /* ENABLE_PKCS11H_DATA */
16159 +
16160 +#if defined(ENABLE_PKCS11H_CERTIFICATE)
16161 +
16162 +struct pkcs11h_certificate_id_list_s;
16163 +typedef struct pkcs11h_certificate_id_list_s *pkcs11h_certificate_id_list_t;
16164 +
16165 +#endif /* ENABLE_PKCS11H_CERTIFICATE */
16166 +
16167 +#endif /* ENABLE_PKCS11H_ENUM */
16168 +
16169 +typedef void (*pkcs11h_hook_log_t)(
16170 + IN void * const global_data,
16171 + IN const unsigned flags,
16172 + IN const char * const format,
16173 + IN va_list args
16174 +);
16175 +
16176 +typedef void (*pkcs11h_hook_slotevent_t)(
16177 + IN void * const global_data
16178 +);
16179 +
16180 +typedef PKCS11H_BOOL (*pkcs11h_hook_token_prompt_t)(
16181 + IN void * const global_data,
16182 + IN void * const user_data,
16183 + IN const pkcs11h_token_id_t token,
16184 + IN const unsigned retry
16185 +);
16186 +
16187 +typedef PKCS11H_BOOL (*pkcs11h_hook_pin_prompt_t)(
16188 + IN void * const global_data,
16189 + IN void * const user_data,
16190 + IN const pkcs11h_token_id_t token,
16191 + IN const unsigned retry,
16192 + OUT char * const pin,
16193 + IN const size_t pin_max
16194 +);
16195 +
16196 +struct pkcs11h_token_id_s {
16197 + char display[1024];
16198 + char manufacturerID[sizeof (((CK_TOKEN_INFO *)NULL)->manufacturerID)+1];
16199 + char model[sizeof (((CK_TOKEN_INFO *)NULL)->model)+1];
16200 + char serialNumber[sizeof (((CK_TOKEN_INFO *)NULL)->serialNumber)+1];
16201 + char label[sizeof (((CK_TOKEN_INFO *)NULL)->label)+1];
16202 +};
16203 +
16204 +#if defined(ENABLE_PKCS11H_CERTIFICATE)
16205 +
16206 +struct pkcs11h_certificate_id_s {
16207 + pkcs11h_token_id_t token_id;
16208 +
16209 + char displayName[1024];
16210 + CK_BYTE_PTR attrCKA_ID;
16211 + size_t attrCKA_ID_size;
16212 +
16213 + unsigned char *certificate_blob;
16214 + size_t certificate_blob_size;
16215 +};
16216 +
16217 +#endif
16218 +
16219 +#if defined(ENABLE_PKCS11H_ENUM)
16220 +
16221 +struct pkcs11h_token_id_list_s {
16222 + pkcs11h_token_id_list_t next;
16223 + pkcs11h_token_id_t token_id;
16224 +};
16225 +
16226 +#if defined(ENABLE_PKCS11H_DATA)
16227 +
16228 +struct pkcs11h_data_id_list_s {
16229 + pkcs11h_data_id_list_t next;
16230 +
16231 + char *application;
16232 + char *label;
16233 +};
16234 +
16235 +#endif /* ENABLE_PKCS11H_DATA */
16236 +
16237 +#if defined(ENABLE_PKCS11H_CERTIFICATE)
16238 +
16239 +struct pkcs11h_certificate_id_list_s {
16240 + pkcs11h_certificate_id_list_t next;
16241 + pkcs11h_certificate_id_t certificate_id;
16242 +};
16243 +
16244 +#endif /* ENABLE_PKCS11H_CERTIFICATE */
16245 +
16246 +#endif /* ENABLE_PKCS11H_CERTIFICATE */
16247 +
16248 +#if defined(ENABLE_PKCS11H_OPENSSL)
16249 +
16250 +typedef void (*pkcs11h_hook_openssl_cleanup_t) (
16251 + IN const pkcs11h_certificate_t certificate
16252 +);
16253 +
16254 +struct pkcs11h_openssl_session_s;
16255 +typedef struct pkcs11h_openssl_session_s *pkcs11h_openssl_session_t;
16256 +
16257 +#endif /* ENABLE_PKCS11H_OPENSSL */
16258 +
16259 +/*
16260 + * pkcs11h_getMessage - Get message by return value.
16261 + *
16262 + * Parameters:
16263 + * rv - Return value.
16264 + */
16265 +const char *
16266 +pkcs11h_getMessage (
16267 + IN const CK_RV rv
16268 +);
16269 +
16270 +/*
16271 + * pkcs11h_initialize - Inititalize helper interface.
16272 + *
16273 + * Must be called once, from main thread.
16274 + * Defaults:
16275 + * Protected authentication enabled.
16276 + * PIN cached is infinite.
16277 + */
16278 +CK_RV
16279 +pkcs11h_initialize ();
16280 +
16281 +/*
16282 + * pkcs11h_terminate - Terminate helper interface.
16283 + *
16284 + * Must be called once, from main thread, after all
16285 + * related resources freed.
16286 + */
16287 +CK_RV
16288 +pkcs11h_terminate ();
16289 +
16290 +/*
16291 + * pkcs11h_setLogLevel - Set current log level of the helper.
16292 + *
16293 + * Parameters:
16294 + * flags - current log level.
16295 + *
16296 + * The log level can be set to maximum, but setting it to lower
16297 + * level will improve performance.
16298 + */
16299 +void
16300 +pkcs11h_setLogLevel (
16301 + IN const unsigned flags
16302 +);
16303 +
16304 +/*
16305 + * pkcs11h_getLogLevel - Get current log level.
16306 + */
16307 +unsigned
16308 +pkcs11h_getLogLevel ();
16309 +
16310 +/*
16311 + * pkcs11h_setLogHook - Set a log callback.
16312 + *
16313 + * Parameters:
16314 + * hook - Callback.
16315 + * pData - Data to send to callback.
16316 + */
16317 +CK_RV
16318 +pkcs11h_setLogHook (
16319 + IN const pkcs11h_hook_log_t hook,
16320 + IN void * const global_data
16321 +);
16322 +
16323 +/*
16324 + * pkcs11h_setSlotEventHook - Set a slot event callback.
16325 + *
16326 + * Parameters:
16327 + * hook - Callback.
16328 + * pData - Data to send to callback.
16329 + *
16330 + * Calling this function initialize slot event notifications, these
16331 + * notifications can be started, but never terminate due to PKCS#11 limitation.
16332 + *
16333 + * In order to use slot events you must have threading enabled.
16334 + */
16335 +CK_RV
16336 +pkcs11h_setSlotEventHook (
16337 + IN const pkcs11h_hook_slotevent_t hook,
16338 + IN void * const global_data
16339 +);
16340 +
16341 +/*
16342 + * pkcs11h_setTokenPromptHook - Set a token prompt callback.
16343 + *
16344 + * Parameters:
16345 + * hook - Callback.
16346 + * pData - Data to send to callback.
16347 + */
16348 +CK_RV
16349 +pkcs11h_setTokenPromptHook (
16350 + IN const pkcs11h_hook_token_prompt_t hook,
16351 + IN void * const global_data
16352 +);
16353 +
16354 +/*
16355 + * pkcs11h_setPINPromptHook - Set a pin prompt callback.
16356 + *
16357 + * Parameters:
16358 + * hook - Callback.
16359 + * pData - Data to send to callback.
16360 + */
16361 +CK_RV
16362 +pkcs11h_setPINPromptHook (
16363 + IN const pkcs11h_hook_pin_prompt_t hook,
16364 + IN void * const global_data
16365 +);
16366 +
16367 +/*
16368 + * pkcs11h_setProtectedAuthentication - Set global protected authentication mode.
16369 + *
16370 + * Parameters:
16371 + * allow_protected_auth - Allow protected authentication if enabled by token.
16372 + */
16373 +CK_RV
16374 +pkcs11h_setProtectedAuthentication (
16375 + IN const PKCS11H_BOOL allow_protected_auth
16376 +);
16377 +
16378 +/*
16379 + * pkcs11h_setPINCachePeriod - Set global PIN cache timeout.
16380 + *
16381 + * Parameters:
16382 + * pin_cache_period - Cache period in seconds, or PKCS11H_PIN_CACHE_INFINITE.
16383 + */
16384 +CK_RV
16385 +pkcs11h_setPINCachePeriod (
16386 + IN const int pin_cache_period
16387 +);
16388 +
16389 +/*
16390 + * pkcs11h_setMaxLoginRetries - Set global login retries attempts.
16391 + *
16392 + * Parameters:
16393 + * max_retries - Login retries handled by the helper.
16394 + */
16395 +CK_RV
16396 +pkcs11h_setMaxLoginRetries (
16397 + IN const unsigned max_retries
16398 +);
16399 +
16400 +/*
16401 + * pkcs11h_addProvider - Add a PKCS#11 provider.
16402 + *
16403 + * Parameters:
16404 + * reference - Reference name for this provider.
16405 + * provider - Provider library location.
16406 + * allow_protected_auth - Allow this provider to use protected authentication.
16407 + * mask_sign_mode - Provider signmode override.
16408 + * slot_event_method - Provider slot event method.
16409 + * slot_poll_interval - Slot event poll interval (If in polling mode).
16410 + * cert_is_private - Provider's certificate access should be done after login.
16411 + *
16412 + * This function must be called from the main thread.
16413 + *
16414 + * The global allow_protected_auth must be enabled in order to allow provider specific.
16415 + * The mask_sign_mode can be 0 in order to automatically detect key sign mode.
16416 + */
16417 +CK_RV
16418 +pkcs11h_addProvider (
16419 + IN const char * const reference,
16420 + IN const char * const provider_location,
16421 + IN const PKCS11H_BOOL allow_protected_auth,
16422 + IN const unsigned mask_sign_mode,
16423 + IN const int slot_event_method,
16424 + IN const int slot_poll_interval,
16425 + IN const PKCS11H_BOOL cert_is_private
16426 +);
16427 +
16428 +/*
16429 + * pkcs11h_delProvider - Delete a PKCS#11 provider.
16430 + *
16431 + * Parameters:
16432 + * reference - Reference name for this provider.
16433 + *
16434 + * This function must be called from the main thread.
16435 + */
16436 +CK_RV
16437 +pkcs11h_removeProvider (
16438 + IN const char * const reference
16439 +);
16440 +
16441 +/*
16442 + * pkcs11h_forkFixup - Handle special case of Unix fork()
16443 + *
16444 + * This function should be called after fork is called. This is required
16445 + * due to a limitation of the PKCS#11 standard.
16446 + *
16447 + * This function must be called from the main thread.
16448 + *
16449 + * The helper library handles fork automatically if ENABLE_PKCS11H_THREADING
16450 + * is set on configuration file, by use of pthread_atfork.
16451 + */
16452 +CK_RV
16453 +pkcs11h_forkFixup ();
16454 +
16455 +/*
16456 + * pkcs11h_plugAndPlay - Handle slot rescan.
16457 + *
16458 + * This function must be called from the main thread.
16459 + *
16460 + * PKCS#11 providers do not allow plug&play, plug&play can be established by
16461 + * finalizing all providers and initializing them again.
16462 + *
16463 + * The cost of this process is invalidating all sessions, and require user
16464 + * login at the next access.
16465 + */
16466 +CK_RV
16467 +pkcs11h_plugAndPlay ();
16468 +
16469 +/*
16470 + * pkcs11h_token_freeTokenId - Free token_id object.
16471 + *
16472 + * Parameters:
16473 + * token_id - token_id.
16474 + */
16475 +CK_RV
16476 +pkcs11h_token_freeTokenId (
16477 + IN pkcs11h_token_id_t token_id
16478 +);
16479 +
16480 +/*
16481 + * pkcs11h_duplicateTokenId - Duplicate token_id object.
16482 + *
16483 + * Parameters:
16484 + * to - target.
16485 + * from - source.
16486 + */
16487 +CK_RV
16488 +pkcs11h_token_duplicateTokenId (
16489 + OUT pkcs11h_token_id_t * const to,
16490 + IN const pkcs11h_token_id_t from
16491 +);
16492 +
16493 +/*
16494 + * pkcs11h_sameTokenId - Returns TRUE if same token id
16495 + *
16496 + * Parameters:
16497 + * a - a.
16498 + * b - b.
16499 + */
16500 +PKCS11H_BOOL
16501 +pkcs11h_token_sameTokenId (
16502 + IN const pkcs11h_token_id_t a,
16503 + IN const pkcs11h_token_id_t b
16504 +);
16505 +
16506 +/*
16507 + * pkcs11h_token_login - Force login, avoid hooks.
16508 + *
16509 + * Parameters:
16510 + * token_id - Token to login into.
16511 + * readonly - Should session be readonly.
16512 + * pin - PIN to login, NULL for protected authentication
16513 + */
16514 +CK_RV
16515 +pkcs11h_token_login (
16516 + IN const pkcs11h_token_id_t token_id,
16517 + IN const PKCS11H_BOOL readonly,
16518 + IN const char * const pin
16519 +);
16520 +
16521 +#if defined(ENABLE_PKCS11H_SERIALIZATION)
16522 +
16523 +/*
16524 + * pkcs11h_serializeTokenId - Serialize token_id into string.
16525 + *
16526 + * Parameters:
16527 + * sz - Output string.
16528 + * max - Maximum string size.
16529 + * token_id - id to serialize
16530 + *
16531 + * sz may be NULL to get size
16532 + */
16533 +CK_RV
16534 +pkcs11h_token_serializeTokenId (
16535 + OUT char * const sz,
16536 + IN OUT size_t *max,
16537 + IN const pkcs11h_token_id_t token_id
16538 +);
16539 +
16540 +/*
16541 + * pkcs11h_deserializeTokenId - Deserialize token_id from string.
16542 + *
16543 + * Parameters:
16544 + * p_token_id - id.
16545 + * sz - Input string
16546 + */
16547 +CK_RV
16548 +pkcs11h_token_deserializeTokenId (
16549 + OUT pkcs11h_token_id_t *p_token_id,
16550 + IN const char * const sz
16551 +);
16552 +
16553 +#endif /* ENABLE_PKCS11H_SERIALIZATION */
16554 +
16555 +#if defined(ENABLE_PKCS11H_TOKEN)
16556 +
16557 +/*
16558 + * pkcs11h_token_ensureAccess - Ensure token is accessible.
16559 + *
16560 + * Parameters:
16561 + * token_id - Token id object.
16562 + * user_data - Optional user data, to be passed to hooks.
16563 + * mask_prompt - Allow prompt.
16564 + */
16565 +CK_RV
16566 +pkcs11h_token_ensureAccess (
16567 + IN const pkcs11h_token_id_t token_id,
16568 + IN void * const user_data,
16569 + IN const unsigned mask_prompt
16570 +);
16571 +
16572 +#endif /* ENABLE_PKCS11H_TOKEN */
16573 +
16574 +#if defined(ENABLE_PKCS11H_DATA)
16575 +
16576 +/*
16577 + * pkcs11h_data_get - get data object.
16578 + *
16579 + * Parameters:
16580 + * token_id - Token id object.
16581 + * is_public - Object is public.
16582 + * application - Object application attribute.
16583 + * label - Object label attribute.
16584 + * user_data - Optional user data, to be passed to hooks.
16585 + * mask_prompt - Allow prompt.
16586 + * blob - blob, set to NULL to get size.
16587 + * p_blob_size - blob size.
16588 + */
16589 +CK_RV
16590 +pkcs11h_data_get (
16591 + IN const pkcs11h_token_id_t token_id,
16592 + IN const PKCS11H_BOOL is_public,
16593 + IN const char * const application,
16594 + IN const char * const label,
16595 + IN void * const user_data,
16596 + IN const unsigned mask_prompt,
16597 + OUT unsigned char * const blob,
16598 + IN OUT size_t * const p_blob_size
16599 +);
16600 +
16601 +/*
16602 + * pkcs11h_data_put - put data object.
16603 + *
16604 + * Parameters:
16605 + * token_id - Token id object.
16606 + * is_public - Object is public.
16607 + * application - Object application attribute.
16608 + * label - Object label attribute.
16609 + * user_data - Optional user data, to be passed to hooks.
16610 + * mask_prompt - Allow prompt.
16611 + * blob - blob.
16612 + * blob_size - blob size.
16613 + */
16614 +CK_RV
16615 +pkcs11h_data_put (
16616 + IN const pkcs11h_token_id_t token_id,
16617 + IN const PKCS11H_BOOL is_public,
16618 + IN const char * const application,
16619 + IN const char * const label,
16620 + IN void * const user_data,
16621 + IN const unsigned mask_prompt,
16622 + OUT unsigned char * const blob,
16623 + IN const size_t blob_size
16624 +);
16625 +
16626 +/*
16627 + * pkcs11h_data_del - delete data object.
16628 + *
16629 + * Parameters:
16630 + * token_id - Token id object.
16631 + * is_public - Object is public.
16632 + * application - Object application attribute.
16633 + * label - Object label attribute.
16634 + * user_data - Optional user data, to be passed to hooks.
16635 + * mask_prompt - Allow prompt.
16636 + */
16637 +CK_RV
16638 +pkcs11h_data_del (
16639 + IN const pkcs11h_token_id_t token_id,
16640 + IN const PKCS11H_BOOL is_public,
16641 + IN const char * const application,
16642 + IN const char * const label,
16643 + IN void * const user_data,
16644 + IN const unsigned mask_prompt
16645 +);
16646 +
16647 +#endif /* ENABLE_PKCS11H_DATA */
16648 +
16649 +#if defined(ENABLE_PKCS11H_CERTIFICATE)
16650 +/*======================================================================*
16651 + * CERTIFICATE INTERFACE
16652 + *======================================================================*/
16653 +
16654 +/*
16655 + * pkcs11h_certificate_freeCertificateId - Free certificate_id object.
16656 + */
16657 +CK_RV
16658 +pkcs11h_certificate_freeCertificateId (
16659 + IN pkcs11h_certificate_id_t certificate_id
16660 +);
16661 +
16662 +/*
16663 + * pkcs11h_duplicateCertificateId - Duplicate certificate_id object.
16664 + */
16665 +CK_RV
16666 +pkcs11h_certificate_duplicateCertificateId (
16667 + OUT pkcs11h_certificate_id_t * const to,
16668 + IN const pkcs11h_certificate_id_t from
16669 +);
16670 +
16671 +/*
16672 + * pkcs11h_certificate_setCertificateIdCertificateBlob - Sets internal certificate_id blob.
16673 + *
16674 + * Parameters:
16675 + * certificate_id - Certificate id ojbect.
16676 + * blob - blob.
16677 + * blob_size - blob size.
16678 + *
16679 + * Useful to set after deserialization so certificate is available and not read from token.
16680 + */
16681 +CK_RV
16682 +pkcs11h_certificate_setCertificateIdCertificateBlob (
16683 + IN const pkcs11h_certificate_id_t certificate_id,
16684 + IN const unsigned char * const blob,
16685 + IN const size_t blob_size
16686 +);
16687 +
16688 +/*
16689 + * pkcs11h_certificate_freeCertificate - Free certificate object.
16690 + *
16691 + * Parameters:
16692 + * certificate - Certificate ojbect.
16693 + */
16694 +CK_RV
16695 +pkcs11h_certificate_freeCertificate (
16696 + IN pkcs11h_certificate_t certificate
16697 +);
16698 +
16699 +/*
16700 + * pkcs11h_certificate_create - Create a certificate object out of certificate_id.
16701 + *
16702 + * Parameters:
16703 + * certificate_id - Certificate id object to be based on.
16704 + * user_data - Optional user data, to be passed to hooks.
16705 + * mask_prompt - Allow prompt.
16706 + * pin_cache_period - Session specific cache period.
16707 + * p_certificate - Receives certificate object.
16708 + *
16709 + * The certificate id object may not specify the full certificate.
16710 + * The certificate object must be freed by caller.
16711 + */
16712 +CK_RV
16713 +pkcs11h_certificate_create (
16714 + IN const pkcs11h_certificate_id_t certificate_id,
16715 + IN void * const user_data,
16716 + IN const unsigned mask_prompt,
16717 + IN const int pin_cache_period,
16718 + OUT pkcs11h_certificate_t * const p_certificate
16719 +);
16720 +
16721 +/*
16722 + * pkcs11h_certificate_getPromptMask - Extract user data out of certificate.
16723 + *
16724 + * Parameters:
16725 + * certificate - Certificate ojbect.
16726 + *
16727 + * Returns:
16728 + * mask_prompt - Allow prompt.
16729 + *
16730 + */
16731 +unsigned
16732 +pkcs11h_certificate_getPromptMask (
16733 + IN const pkcs11h_certificate_t certificate
16734 +);
16735 +
16736 +/*
16737 + * pkcs11h_certificate_setPromptMask - Extract user data out of certificate.
16738 + *
16739 + * Parameters:
16740 + * certificate - Certificate ojbect.
16741 + * mask_prompt - Allow prompt.
16742 + */
16743 +void
16744 +pkcs11h_certificate_setPromptMask (
16745 + IN const pkcs11h_certificate_t certificate,
16746 + IN const unsigned ask_prompt
16747 +);
16748 +
16749 +/*
16750 + * pkcs11h_certificate_getUserData - Extract user data out of certificate.
16751 + *
16752 + * Parameters:
16753 + * certificate - Certificate ojbect.
16754 + *
16755 + * Returns:
16756 + * user_data - Optional user data, to be passed to hooks.
16757 + */
16758 +void *
16759 +pkcs11h_certificate_getUserData (
16760 + IN const pkcs11h_certificate_t certificate
16761 +);
16762 +
16763 +/*
16764 + * pkcs11h_certificate_setUserData - Extract user data out of certificate.
16765 + *
16766 + * Parameters:
16767 + * certificate - Certificate ojbect.
16768 + * user_data - Optional user data, to be passed to hooks.
16769 + */
16770 +void
16771 +pkcs11h_certificate_setUserData (
16772 + IN const pkcs11h_certificate_t certificate,
16773 + IN void * const user_data
16774 +);
16775 +
16776 +/*
16777 + * pkcs11h_certificate_getCertificateId - Get certifiate id object out of a certifiate
16778 + *
16779 + * Parameters:
16780 + * certificate - Certificate object.
16781 + * p_certificate_id - Certificate id object pointer.
16782 + *
16783 + * The certificate id must be freed by caller.
16784 + */
16785 +CK_RV
16786 +pkcs11h_certificate_getCertificateId (
16787 + IN const pkcs11h_certificate_t certificate,
16788 + OUT pkcs11h_certificate_id_t * const p_certificate_id
16789 +);
16790 +
16791 +/*
16792 + * pkcs11h_certificate_getCertificateBlob - Get the certificate blob out of the certificate object.
16793 + *
16794 + * Parameters:
16795 + * certificate - Certificate object.
16796 + * certificate_blob - Buffer.
16797 + * certificate_blob_size - Buffer size.
16798 + *
16799 + * Buffer may be NULL in order to get size.
16800 + */
16801 +CK_RV
16802 +pkcs11h_certificate_getCertificateBlob (
16803 + IN const pkcs11h_certificate_t certificate,
16804 + OUT unsigned char * const certificate_blob,
16805 + IN OUT size_t * const p_certificate_blob_size
16806 +);
16807 +
16808 +#if defined(ENABLE_PKCS11H_SERIALIZATION)
16809 +
16810 +/*
16811 + * pkcs11h_certificate_serializeCertificateId - Serialize certificate_id into a string
16812 + *
16813 + * Parametrs:
16814 + * sz - Output string.
16815 + * max - Max buffer size.
16816 + * certificate_id - id to serialize
16817 + *
16818 + * sz may be NULL in order to get size.
16819 + */
16820 +CK_RV
16821 +pkcs11h_certificate_serializeCertificateId (
16822 + OUT char * const sz,
16823 + IN OUT size_t *max,
16824 + IN const pkcs11h_certificate_id_t certificate_id
16825 +);
16826 +
16827 +/*
16828 + * pkcs11h_certificate_deserializeCertificateId - Deserialize certificate_id out of string.
16829 + *
16830 + * Parameters:
16831 + * p_certificate_id - id.
16832 + * sz - Inut string
16833 + */
16834 +CK_RV
16835 +pkcs11h_certificate_deserializeCertificateId (
16836 + OUT pkcs11h_certificate_id_t * const p_certificate_id,
16837 + IN const char * const sz
16838 +);
16839 +
16840 +#endif /* ENABLE_PKCS11H_SERIALIZATION */
16841 +
16842 +/*
16843 + * pkcs11h_certificate_ensureCertificateAccess - Ensure certificate is accessible.
16844 + *
16845 + * Parameters:
16846 + * certificate - Certificate object.
16847 + */
16848 +CK_RV
16849 +pkcs11h_certificate_ensureCertificateAccess (
16850 + IN const pkcs11h_certificate_t certificate
16851 +);
16852 +
16853 +/*
16854 + * pkcs11h_certificate_ensureKeyAccess - Ensure key is accessible.
16855 + *
16856 + * Parameters:
16857 + * certificate - Certificate object.
16858 + */
16859 +CK_RV
16860 +pkcs11h_certificate_ensureKeyAccess (
16861 + IN const pkcs11h_certificate_t certificate
16862 +);
16863 +
16864 +/*
16865 + * pkcs11h_certificate_lockSession - Lock session for threded environment
16866 + *
16867 + * Parameters:
16868 + * certificate - Certificate object.
16869 + *
16870 + * This must be called on threaded environment, so both calls to _sign and
16871 + * _signRecover and _decrypt will be from the same source.
16872 + * Failing to lock session, will result with CKR_OPERATION_ACTIVE if
16873 + * provider is good, or unexpected behaviour for others.
16874 + *
16875 + * It is save to call this also in none threaded environment, it will do nothing.
16876 + * Call this also if you are doing one stage operation, since locking is not
16877 + * done by method.
16878 + */
16879 +CK_RV
16880 +pkcs11h_certificate_lockSession (
16881 + IN const pkcs11h_certificate_t certificate
16882 +);
16883 +
16884 +/*
16885 + * pkcs11h_certificate_releaseSession - Releases session lock.
16886 + *
16887 + * Parameters:
16888 + * certificate - Certificate object.
16889 + *
16890 + * See pkcs11h_certificate_lockSession.
16891 + */
16892 +CK_RV
16893 +pkcs11h_certificate_releaseSession (
16894 + IN const pkcs11h_certificate_t certificate
16895 +);
16896 +
16897 +/*
16898 + * pkcs11h_certificate_sign - Sign data.
16899 + *
16900 + * Parameters:
16901 + * certificate - Certificate object.
16902 + * mech_type - PKCS#11 mechanism.
16903 + * source - Buffer to sign.
16904 + * source_size - Buffer size.
16905 + * target - Target buffer, can be NULL to get size.
16906 + * target_size - Target buffer size.
16907 + */
16908 +CK_RV
16909 +pkcs11h_certificate_sign (
16910 + IN const pkcs11h_certificate_t certificate,
16911 + IN const CK_MECHANISM_TYPE mech_type,
16912 + IN const unsigned char * const source,
16913 + IN const size_t source_size,
16914 + OUT unsigned char * const target,
16915 + IN OUT size_t * const p_target_size
16916 +);
16917 +
16918 +/*
16919 + * pkcs11h_certificate_signRecover - Sign data.
16920 + *
16921 + * Parameters:
16922 + * certificate - Certificate object.
16923 + * mech_type - PKCS#11 mechanism.
16924 + * source - Buffer to sign.
16925 + * source_size - Buffer size.
16926 + * target - Target buffer, can be NULL to get size.
16927 + * target_size - Target buffer size.
16928 + */
16929 +CK_RV
16930 +pkcs11h_certificate_signRecover (
16931 + IN const pkcs11h_certificate_t certificate,
16932 + IN const CK_MECHANISM_TYPE mech_type,
16933 + IN const unsigned char * const source,
16934 + IN const size_t source_size,
16935 + OUT unsigned char * const target,
16936 + IN OUT size_t * const p_target_size
16937 +);
16938 +
16939 +/*
16940 + * pkcs11h_certificate_signAny - Sign data mechanism determined by key attributes.
16941 + *
16942 + * Parameters:
16943 + * certificate - Certificate object.
16944 + * mech_type - PKCS#11 mechanism.
16945 + * source - Buffer to sign.
16946 + * source_size - Buffer size.
16947 + * target - Target buffer, can be NULL to get size.
16948 + * target_size - Target buffer size.
16949 + */
16950 +CK_RV
16951 +pkcs11h_certificate_signAny (
16952 + IN const pkcs11h_certificate_t certificate,
16953 + IN const CK_MECHANISM_TYPE mech_type,
16954 + IN const unsigned char * const source,
16955 + IN const size_t source_size,
16956 + OUT unsigned char * const target,
16957 + IN OUT size_t * const p_target_size
16958 +);
16959 +
16960 +/*
16961 + * pkcs11h_certificate_decrypt - Decrypt data.
16962 + *
16963 + * Parameters:
16964 + * certificate - Certificate object.
16965 + * mech_type - PKCS#11 mechanism.
16966 + * source - Buffer to sign.
16967 + * source_size - Buffer size.
16968 + * target - Target buffer, can be NULL to get size.
16969 + * target_size - Target buffer size.
16970 + */
16971 +CK_RV
16972 +pkcs11h_certificate_decrypt (
16973 + IN const pkcs11h_certificate_t certificate,
16974 + IN const CK_MECHANISM_TYPE mech_type,
16975 + IN const unsigned char * const source,
16976 + IN const size_t source_size,
16977 + OUT unsigned char * const target,
16978 + IN OUT size_t * const p_target_size
16979 +);
16980 +
16981 +#endif /* ENABLE_PKCS11H_CERTIFICATE */
16982 +
16983 +#if defined(ENABLE_PKCS11H_LOCATE)
16984 +/*======================================================================*
16985 + * LOCATE INTERFACE
16986 + *======================================================================*/
16987 +
16988 +#if defined(ENABLE_PKCS11H_TOKEN) || defined(ENABLE_PKCS11H_CERTIFICATE)
16989 +
16990 +/*
16991 + * pkcs11h_locate_token - Locate token based on atributes.
16992 + *
16993 + * Parameters:
16994 + * slot_type - How to locate slot.
16995 + * slot - Slot name.
16996 + * user_data - Optional user data, to be passed to hooks.
16997 + * mask_prompt - Allow prompt.
16998 + * p_token_id - Token object.
16999 + *
17000 + * Slot:
17001 + * id - Slot number.
17002 + * name - Slot name.
17003 + * label - Available token label.
17004 + *
17005 + * Caller must free token id.
17006 + */
17007 +CK_RV
17008 +pkcs11h_locate_token (
17009 + IN const char * const slot_type,
17010 + IN const char * const slot,
17011 + IN void * const user_data,
17012 + IN const unsigned mask_prompt,
17013 + OUT pkcs11h_token_id_t * const p_token_id
17014 +);
17015 +
17016 +#endif /* ENABLE_PKCS11H_TOKEN || ENABLE_PKCS11H_CERTIFICATE */
17017 +
17018 +#if defined(ENABLE_PKCS11H_CERTIFICATE)
17019 +
17020 +/*
17021 + * pkcs11h_locate_certificate - Locate certificate based on atributes.
17022 + *
17023 + * Parameters:
17024 + * slot_type - How to locate slot.
17025 + * slot - Slot name.
17026 + * id_type - How to locate object.
17027 + * id - Object name.
17028 + * user_data - Optional user data, to be passed to hooks.
17029 + * mask_prompt - Allow prompt.
17030 + * p_certificate_id - Certificate object.
17031 + *
17032 + * Slot:
17033 + * Same as pkcs11h_locate_token.
17034 + *
17035 + * Object:
17036 + * id - Certificate CKA_ID (hex string) (Fastest).
17037 + * label - Certificate CKA_LABEL (string).
17038 + * subject - Certificate subject (OpenSSL or gnutls DN).
17039 + *
17040 + * Caller must free certificate id.
17041 + */
17042 +CK_RV
17043 +pkcs11h_locate_certificate (
17044 + IN const char * const slot_type,
17045 + IN const char * const slot,
17046 + IN const char * const id_type,
17047 + IN const char * const id,
17048 + IN void * const user_data,
17049 + IN const unsigned mask_prompt,
17050 + OUT pkcs11h_certificate_id_t * const p_certificate_id
17051 +);
17052 +
17053 +#endif /* ENABLE_PKCS11H_CERTIFICATE */
17054 +
17055 +#endif /* ENABLE_PKCS11H_LOCATE */
17056 +
17057 +#if defined(ENABLE_PKCS11H_ENUM)
17058 +/*======================================================================*
17059 + * ENUM INTERFACE
17060 + *======================================================================*/
17061 +
17062 +#if defined(ENABLE_PKCS11H_TOKEN)
17063 +
17064 +/*
17065 + * pkcs11h_freeTokenIdList - Free certificate_id list.
17066 + */
17067 +CK_RV
17068 +pkcs11h_token_freeTokenIdList (
17069 + IN const pkcs11h_token_id_list_t token_id_list
17070 +);
17071 +
17072 +/*
17073 + * pkcs11h_token_enumTokenIds - Enumerate available tokens
17074 + *
17075 + * Parameters:
17076 + * p_token_id_list - A list of token ids.
17077 + *
17078 + * Caller must free the list.
17079 + */
17080 +CK_RV
17081 +pkcs11h_token_enumTokenIds (
17082 + IN const int method,
17083 + OUT pkcs11h_token_id_list_t * const p_token_id_list
17084 +);
17085 +
17086 +#endif /* ENABLE_PKCS11H_TOKEN */
17087 +
17088 +#if defined(ENABLE_PKCS11H_DATA)
17089 +
17090 +/*
17091 + * pkcs11h_data_freeDataIdList - free data object list..
17092 + *
17093 + * Parameters:
17094 + * data_id_list - list to free.
17095 + */
17096 +CK_RV
17097 +pkcs11h_data_freeDataIdList (
17098 + IN const pkcs11h_data_id_list_t data_id_list
17099 +);
17100 +
17101 +/*
17102 + * pkcs11h_data_enumDataObjects - get list of data objects.
17103 + *
17104 + * Parameters:
17105 + * token_id - token id.
17106 + * is_public - Get a list of public objects.
17107 + * user_data - Optional user data, to be passed to hooks.
17108 + * mask_prompt - Allow prompt.
17109 + * p_data_id_list - List location.
17110 + */
17111 +CK_RV
17112 +pkcs11h_data_enumDataObjects (
17113 + IN const pkcs11h_token_id_t token_id,
17114 + IN const PKCS11H_BOOL is_public,
17115 + IN void * const user_data,
17116 + IN const unsigned mask_prompt,
17117 + OUT pkcs11h_data_id_list_t * const p_data_id_list
17118 +);
17119 +
17120 +#endif /* ENABLE_PKCS11H_DATA */
17121 +
17122 +#if defined(ENABLE_PKCS11H_CERTIFICATE)
17123 +
17124 +/*
17125 + * pkcs11h_certificate_freeCertificateIdList - Free certificate_id list.
17126 + */
17127 +CK_RV
17128 +pkcs11h_certificate_freeCertificateIdList (
17129 + IN const pkcs11h_certificate_id_list_t cert_id_list
17130 +);
17131 +
17132 +/*
17133 + * pkcs11h_certificate_enumTokenCertificateIds - Enumerate available certificates on specific token
17134 + *
17135 + * Parameters:
17136 + * token_id - Token id to enum.
17137 + * method - How to fetch certificates.
17138 + * user_data - Some user specific data.
17139 + * mask_prompt - Allow prompt.
17140 + * p_cert_id_issuers_list - Receives issues list, can be NULL.
17141 + * p_cert_id_end_list - Receives end certificates list.
17142 + *
17143 + * This function will likely take long time.
17144 + *
17145 + * Method can be one of the following:
17146 + * PKCS11H_ENUM_METHOD_CACHE
17147 + * Return available certificates, even if token was once detected and
17148 + * was removed.
17149 + * PKCS11H_ENUM_METHOD_CACHE_EXIST
17150 + * Return available certificates for available tokens only, don't
17151 + * read the contents of the token if already read, even if this token
17152 + * removed and inserted.
17153 + * PKCS11H_ENUM_METHOD_RELOAD
17154 + * Clear all caches and then enum.
17155 + *
17156 + * Caller must free the lists.
17157 + */
17158 +CK_RV
17159 +pkcs11h_certificate_enumTokenCertificateIds (
17160 + IN const pkcs11h_token_id_t token_id,
17161 + IN const int method,
17162 + IN void * const user_data,
17163 + IN const unsigned mask_prompt,
17164 + OUT pkcs11h_certificate_id_list_t * const p_cert_id_issuers_list,
17165 + OUT pkcs11h_certificate_id_list_t * const p_cert_id_end_list
17166 +);
17167 +
17168 +/*
17169 + * pkcs11h_enum_getCertificateIds - Enumerate available certificates.
17170 + *
17171 + * Parameters:
17172 + * method - How to fetch certificates.
17173 + * user_data - Some user specific data.
17174 + * mask_prompt - Allow prompt.
17175 + * p_cert_id_issuers_list - Receives issues list, can be NULL.
17176 + * p_cert_id_end_list - Receives end certificates list.
17177 + *
17178 + * This function will likely take long time.
17179 + *
17180 + * Method can be one of the following:
17181 + * PKCS11H_ENUM_METHOD_CACHE
17182 + * Return available certificates, even if token was once detected and
17183 + * was removed.
17184 + * PKCS11H_ENUM_METHOD_CACHE_EXIST
17185 + * Return available certificates for available tokens only, don't
17186 + * read the contents of the token if already read, even if this token
17187 + * removed and inserted.
17188 + * PKCS11H_ENUM_METHOD_RELOAD
17189 + * Clear all caches and then enum.
17190 + *
17191 + * Caller must free lists.
17192 + */
17193 +CK_RV
17194 +pkcs11h_certificate_enumCertificateIds (
17195 + IN const int method,
17196 + IN void * const user_data,
17197 + IN const unsigned mask_prompt,
17198 + OUT pkcs11h_certificate_id_list_t * const p_cert_id_issuers_list,
17199 + OUT pkcs11h_certificate_id_list_t * const p_cert_id_end_list
17200 +);
17201 +
17202 +#endif /* ENABLE_PKCS11H_CERTIFICATE */
17203 +
17204 +#endif /* ENABLE_PKCS11H_ENUM */
17205 +
17206 +#if defined(ENABLE_PKCS11H_OPENSSL)
17207 +/*======================================================================*
17208 + * OPENSSL INTERFACE
17209 + *======================================================================*/
17210 +
17211 +/*
17212 + * pkcs11h_openssl_getX509 - Returns an X509 object out of the openssl_session object.
17213 + *
17214 + * Parameters:
17215 + * certificate - Certificate object.
17216 + */
17217 +X509 *
17218 +pkcs11h_openssl_getX509 (
17219 + IN const pkcs11h_certificate_t certificate
17220 +);
17221 +
17222 +/*
17223 + * pkcs11h_openssl_createSession - Create OpenSSL session based on a certificate object.
17224 + *
17225 + * Parameters:
17226 + * certificate - Certificate object.
17227 + *
17228 + * The certificate object will be freed by the OpenSSL interface on session end.
17229 + */
17230 +pkcs11h_openssl_session_t
17231 +pkcs11h_openssl_createSession (
17232 + IN const pkcs11h_certificate_t certificate
17233 +);
17234 +
17235 +/*
17236 + * pkcs11h_openssl_getCleanupHook - Sets cleanup hook
17237 + *
17238 + * Parameters:
17239 + * openssl_session - session.
17240 + */
17241 +pkcs11h_hook_openssl_cleanup_t
17242 +pkcs11h_openssl_getCleanupHook (
17243 + IN const pkcs11h_openssl_session_t openssl_session
17244 +);
17245 +
17246 +/*
17247 + * pkcs11h_openssl_setCleanupHook - Sets cleanup hook
17248 + *
17249 + * Parameters:
17250 + * openssl_session - session.
17251 + * cleanup - hook.
17252 + */
17253 +void
17254 +pkcs11h_openssl_setCleanupHook (
17255 + IN const pkcs11h_openssl_session_t openssl_session,
17256 + IN const pkcs11h_hook_openssl_cleanup_t cleanup
17257 +);
17258 +
17259 +/*
17260 + * pkcs11h_openssl_freeSession - Free OpenSSL session.
17261 + *
17262 + * Parameters:
17263 + * openssl_session - Session to free.
17264 + *
17265 + * The openssl_session object has a reference count just like other OpenSSL objects.
17266 + */
17267 +void
17268 +pkcs11h_openssl_freeSession (
17269 + IN const pkcs11h_openssl_session_t openssl_session
17270 +);
17271 +
17272 +/*
17273 + * pkcs11h_openssl_session_getRSA - Returns an RSA object out of the openssl_session object.
17274 + *
17275 + * Parameters:
17276 + * openssl_session - Session.
17277 + */
17278 +RSA *
17279 +pkcs11h_openssl_session_getRSA (
17280 + IN const pkcs11h_openssl_session_t openssl_session
17281 +);
17282 +
17283 +/*
17284 + * pkcs11h_openssl_session_getX509 - Returns an X509 object out of the openssl_session object.
17285 + *
17286 + * Parameters:
17287 + * openssl_session - Session.
17288 + */
17289 +X509 *
17290 +pkcs11h_openssl_session_getX509 (
17291 + IN const pkcs11h_openssl_session_t openssl_session
17292 +);
17293 +
17294 +#endif /* ENABLE_PKCS11H_OPENSSL */
17295 +
17296 +#if defined(ENABLE_PKCS11H_STANDALONE)
17297 +/*======================================================================*
17298 + * STANDALONE INTERFACE
17299 + *======================================================================*/
17300 +
17301 +void
17302 +pkcs11h_standalone_dump_slots (
17303 + IN const pkcs11h_output_print_t my_output,
17304 + IN void * const global_data,
17305 + IN const char * const provider
17306 +);
17307 +
17308 +void
17309 +pkcs11h_standalone_dump_objects (
17310 + IN const pkcs11h_output_print_t my_output,
17311 + IN void * const global_data,
17312 + IN const char * const provider,
17313 + IN const char * const slot,
17314 + IN const char * const pin
17315 +);
17316 +
17317 +#endif /* ENABLE_PKCS11H_STANDALONE */
17318 +
17319 +#ifdef __cplusplus
17320 +}
17321 +#endif
17322 +
17323 +#endif /* __PKCS11H_HELPER_H */
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
17327 @@ -0,0 +1,49 @@
17328 +The PKCS#11 patch modify ssh-add and ssh-agent to support PKCS#11 private keys
17329 +and certificates (http://alon.barlev.googlepages.com/openssh-pkcs11).
17330 +
17331 +It allows using multiple PKCS#11 providers at the same time, selecting keys by
17332 +id, label or certificate subject, handling card removal and card insert events,
17333 +handling card re-insert to a different slot, supporting session expiration.
17334 +
17335 +A valid X.509 certificate should exist on the token, without X.509 support it is
17336 +exported as regular RSA key. Self-signed certificates are treated as RSA key and
17337 +not as X.509 RSA key.
17338 +
17339 +If you like X.509 (http://roumenpetrov.info/openssh) support apply the X.509
17340 +patch AFTER the PKCS#11 patch. You can use -o PubkeyAlgorithms=ssh-rsa in order to
17341 +authenticate to none X.509 servers.
17342 +
17343 +One significant change is that the ssh-agent prompts for passwords now... So you
17344 +need to configure it with a program that asks for card insert or PIN, a program
17345 +such as x11-ssh-askpass. Current implementation (ssh-add asks for passwords) is
17346 +not valid for dynamic smartcard environment.
17347 +
17348 +Current implementation uses the askpin program also for prompting card insert...
17349 +Don't be confused, it only expects ok or cancel, some simple scripts available
17350 +at http://alon.barlev.googlepages.com/openssh-pkcs11 that uses KDE, Gnome and .NET
17351 +in order to display these dialogs.
17352 +
17353 +You can view full usage by:
17354 +$ ssh-agent /bin/sh
17355 +$ ssh-add -h
17356 +
17357 +A common scenario is the following:
17358 +$ ssh-agent /bin/sh
17359 +$ ssh-add --pkcs11-ask-pin `which openssh-kde-dialogs.sh`
17360 +$ ssh-add --pkcs11-add-provider --pkcs11-provider /usr/lib/pkcs11/MyProvider.so
17361 +$ ssh-add --pkcs11-add-id --pkcs11-id "serialized id"
17362 +$ ssh myhost
17363 +
17364 +In order to see available objects, you can use:
17365 +$ ssh-add --pkcs11-show-ids --pkcs11-provider /usr/lib/pkcs11/MyProvider.so
17366 +
17367 +In order to add id without accessing the token, you must put the certificate in
17368 +a PEM file and use:
17369 +$ ssh-add --pkcs11-add-id --pkcs11-id "serialized id" --pkcs11-cert-file my.pem
17370 +
17371 +In order to debug open two shells:
17372 +1$ rm -fr /tmp/s; ssh-agent -d -d -d -a /tmp/s
17373 +
17374 +2$ SSH_AUTH_SOCK=/tmp/s; export SSH_AUTH_SOCK;
17375 +2$ [ssh-add]...
17376 +
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 @@
17381 #include "rsa.h"
17382 #include "log.h"
17383 #include "key.h"
17384 +#include "pkcs11.h"
17385 #include "buffer.h"
17386 #include "authfd.h"
17387 #include "authfile.h"
17388 #include "pathnames.h"
17389 #include "misc.h"
17390
17391 +static void usage (void);
17392 +
17393 /* argv0 */
17394 extern char *__progname;
17395
17396 @@ -306,6 +309,261 @@ do_file(AuthenticationConnection *ac, in
17397 return 0;
17398 }
17399
17400 +#ifndef SSH_PKCS11_DISABLED
17401 +
17402 +static
17403 +int
17404 +do_pkcs11 (AuthenticationConnection *ac, int argc, char *argv[])
17405 +{
17406 + /*
17407 + * TEMP TEMP TEMP TEMP
17408 + *
17409 + * This should be fixed if another mechanism
17410 + * will be propsed.
17411 + */
17412 + pkcs11_identity *id = NULL;
17413 + char *szPKCS11Provider = NULL;
17414 + char *szPKCS11Id = NULL;
17415 + char *szPKCS11SignMode = NULL;
17416 + char *szPKCS11AskPIN = NULL;
17417 + char *szPKCS11SlotId = NULL;
17418 + char *szPKCS11CertFile = NULL;
17419 + int fDebug = 0;
17420 + int fPKCS11AddProvider = 0;
17421 + int fPKCS11AddId = 0;
17422 + int fPKCS11RemoveId = 0;
17423 + int fPKCS11ShowIds = 0;
17424 + int fPKCS11DumpSlots = 0;
17425 + int fPKCS11DumpObjects = 0;
17426 + int fPKCS11ProtectedAuthentication = 0;
17427 + int fPKCS11CertPrivate = 0;
17428 + int nPKCS11PINCachePeriod = -1;
17429 + int fBadUsage = 0;
17430 + int ret = 0;
17431 + int nSkipPrmCount;
17432 + int i;
17433 +
17434 + for (i=0,nSkipPrmCount=0;i<argc;i++) {
17435 + if (!strcmp (argv[i], "--pkcs11-provider")) {
17436 + szPKCS11Provider = argv[i+1];
17437 + i++;
17438 + }
17439 + else if (!strcmp (argv[i], "--pkcs11-id")) {
17440 + szPKCS11Id = argv[i+1];
17441 + i++;
17442 + }
17443 + else if (!strcmp (argv[i], "--pkcs11-pin-cache")) {
17444 + nPKCS11PINCachePeriod = atoi (argv[i+1]);
17445 + i++;
17446 + }
17447 + else if (!strcmp (argv[i], "--pkcs11-sign-mode")) {
17448 + szPKCS11SignMode = argv[i+1];
17449 + i++;
17450 + }
17451 + else if (!strcmp (argv[i], "--pkcs11-ask-pin")) {
17452 + szPKCS11AskPIN = argv[i+1];
17453 + i++;
17454 + }
17455 + else if (!strcmp (argv[i], "--pkcs11-slot")) {
17456 + szPKCS11SlotId = argv[i+1];
17457 + i++;
17458 + }
17459 + else if (!strcmp (argv[i], "--pkcs11-cert-file")) {
17460 + szPKCS11CertFile = argv[i+1];
17461 + i++;
17462 + }
17463 + else if (!strcmp (argv[i], "--pkcs11-add-provider")) {
17464 + fPKCS11AddProvider = 1;
17465 + }
17466 + else if (!strcmp (argv[i], "--pkcs11-remove-id")) {
17467 + fPKCS11RemoveId = 1;
17468 + }
17469 + else if (!strcmp (argv[i], "--pkcs11-add-id")) {
17470 + fPKCS11AddId = 1;
17471 + }
17472 + else if (!strcmp (argv[i], "--pkcs11-show-ids")) {
17473 + fPKCS11ShowIds = 1;
17474 + }
17475 + else if (!strcmp (argv[i], "--pkcs11-dump-slots")) {
17476 + fPKCS11DumpSlots = 1;
17477 + }
17478 + else if (!strcmp (argv[i], "--pkcs11-dump-objects")) {
17479 + fPKCS11DumpObjects = 1;
17480 + }
17481 + else if (!strcmp (argv[i], "--pkcs11-protected-authentication")) {
17482 + fPKCS11ProtectedAuthentication = 1;
17483 + }
17484 + else if (!strcmp (argv[i], "--pkcs11-cert-private")) {
17485 + fPKCS11CertPrivate = 1;
17486 + }
17487 + else if (!strcmp (argv[i], "-d")) {
17488 + fDebug = 1;
17489 + }
17490 + else {
17491 + nSkipPrmCount++;
17492 + }
17493 + }
17494 +
17495 + if (nSkipPrmCount == argc) {
17496 + /* no pkcs#11 arguments */
17497 + ret = -2;
17498 + }
17499 +
17500 + if (ret == 0) {
17501 + if (
17502 + !fBadUsage &&
17503 + fPKCS11AddProvider &&
17504 + szPKCS11Provider == NULL
17505 + ) {
17506 + fBadUsage = 1;
17507 + }
17508 +
17509 + if (
17510 + !fBadUsage &&
17511 + fPKCS11AddId &&
17512 + (
17513 + szPKCS11Id == NULL
17514 + )
17515 + ) {
17516 + fBadUsage = 1;
17517 + }
17518 +
17519 + if (
17520 + !fBadUsage &&
17521 + fPKCS11RemoveId &&
17522 + (
17523 + szPKCS11Id == NULL
17524 + )
17525 + ) {
17526 + fBadUsage = 1;
17527 + }
17528 +
17529 + if (
17530 + !fBadUsage &&
17531 + fPKCS11ShowIds &&
17532 + szPKCS11Provider == NULL
17533 + ) {
17534 + fBadUsage = 1;
17535 + }
17536 +
17537 + if (
17538 + !fBadUsage &&
17539 + fPKCS11DumpSlots &&
17540 + szPKCS11Provider == NULL
17541 + ) {
17542 + fBadUsage = 1;
17543 + }
17544 +
17545 + if (
17546 + !fBadUsage &&
17547 + fPKCS11DumpObjects &&
17548 + (
17549 + szPKCS11Provider == NULL ||
17550 + szPKCS11SlotId == NULL
17551 + )
17552 + ) {
17553 + fBadUsage = 1;
17554 + }
17555 +
17556 + if (fBadUsage) {
17557 + usage ();
17558 + ret = 1;
17559 + }
17560 + }
17561 +
17562 + if (ret == 0) {
17563 + if (fPKCS11AddId || fPKCS11RemoveId) {
17564 + id = pkcs11_identity_new ();
17565 + if (id == NULL) {
17566 + ret = 1;
17567 + }
17568 + else {
17569 + id->id = strdup (szPKCS11Id);
17570 + id->pin_cache_period = nPKCS11PINCachePeriod;
17571 + id->cert_file = szPKCS11CertFile;
17572 + }
17573 + }
17574 + }
17575 +
17576 + if (ret == 0) {
17577 + if (fDebug) {
17578 + log_init(__progname, SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 1);
17579 + }
17580 +
17581 + if (fPKCS11ShowIds) {
17582 + pkcs11_show_ids (szPKCS11Provider, fPKCS11ProtectedAuthentication, fPKCS11CertPrivate);
17583 + ret = 0;
17584 + }
17585 + else if (fPKCS11DumpSlots) {
17586 + pkcs11_dump_slots (szPKCS11Provider);
17587 + ret = 0;
17588 + }
17589 + else if (fPKCS11DumpObjects) {
17590 + char *szPIN = read_passphrase("PIN: ", RP_ALLOW_STDIN);
17591 + if (szPIN[0] != '\0') {
17592 + pkcs11_dump_objects (szPKCS11Provider, szPKCS11SlotId, szPIN);
17593 + }
17594 + memset (szPIN, 0, strlen (szPIN));
17595 + xfree (szPIN);
17596 + ret = 0;
17597 + }
17598 + else if (szPKCS11AskPIN != NULL) {
17599 + ret = !ssh_pkcs11_set_ask_pin (ac, szPKCS11AskPIN);
17600 +
17601 + if (ret) {
17602 + fprintf (stderr, "Failed\n");
17603 + }
17604 + else {
17605 + fprintf (stderr, "Success\n");
17606 + }
17607 + }
17608 + else if (fPKCS11AddProvider) {
17609 + ret = !ssh_pkcs11_add_provider (
17610 + ac,
17611 + szPKCS11Provider,
17612 + fPKCS11ProtectedAuthentication,
17613 + szPKCS11SignMode,
17614 + fPKCS11CertPrivate
17615 + );
17616 +
17617 + if (ret) {
17618 + fprintf (stderr, "Cannot add provider %s\n", szPKCS11Provider);
17619 + }
17620 + else {
17621 + fprintf (stderr, "Provider %s added successfully\n", szPKCS11Provider);
17622 + }
17623 + }
17624 + else if (fPKCS11AddId) {
17625 + ret = !ssh_pkcs11_id (ac, id, 0);
17626 +
17627 + if (ret) {
17628 + fprintf (stderr, "Cannot add identity\n");
17629 + }
17630 + else {
17631 + fprintf (stderr, "Identity added successfully\n");
17632 + }
17633 + }
17634 + else if (fPKCS11RemoveId) {
17635 + ret = !ssh_pkcs11_id (ac, id, 1);
17636 +
17637 + if (ret) {
17638 + fprintf (stderr, "Cannot remove identity\n");
17639 + }
17640 + else {
17641 + fprintf (stderr, "Identity removed successfully\n");
17642 + }
17643 + }
17644 + }
17645 +
17646 + if (id != NULL) {
17647 + pkcs11_identity_free (id);
17648 + }
17649 +
17650 + return ret;
17651 +}
17652 +
17653 +#endif /* SSH_PKCS11_DISABLED */
17654 +
17655 static void
17656 usage(void)
17657 {
17658 @@ -323,6 +581,50 @@ usage(void)
17659 fprintf(stderr, " -s reader Add key in smartcard reader.\n");
17660 fprintf(stderr, " -e reader Remove key in smartcard reader.\n");
17661 #endif
17662 +#ifndef SSH_PKCS11_DISABLED
17663 + fprintf(
17664 + stderr,
17665 + (
17666 + "\n"
17667 + " PKCS#11 Options:\n"
17668 + " --pkcs11-ask-pin prog Set ask-pin program\n"
17669 + "\n"
17670 + " --pkcs11-add-provider Add PKCS#11 provider\n"
17671 + " --pkcs11-provider provider PKCS#11 provider library\n"
17672 + " [--pkcs11-protected-authentication] Use PKCS#11 protected authentication\n"
17673 + " [--pkcs11-sign-mode mode] Provider signature mode\n"
17674 + " auto - determine automatically\n"
17675 + " sign - perform sign\n"
17676 + " recover - perform sign recover\n"
17677 + " any - perform sign and then sign recover\n"
17678 + " [--pkcs11-cert-private] Login required in order to access certificate\n"
17679 + "\n"
17680 + " --pkcs11-show-ids Show available identities\n"
17681 + " --pkcs11-provider provider PKCS#11 provider library\n"
17682 + " [--pkcs11-protected-authentication] Use PKCS#11 protected authentication\n"
17683 + " [--pkcs11-cert-private] Login required in order to access certificate\n"
17684 + " [-d] debug\n"
17685 + "\n"
17686 + " --pkcs11-add-id Add PKCS#11 identity\n"
17687 + " --pkcs11-id id Serialized string\n"
17688 + " [--pkcs11-cert-file file] Use this PEM file, don't access token\n"
17689 + " [--pkcs11-pin-cache period] PIN cache period (seconds)\n"
17690 + "\n"
17691 + " --pkcs11-remove-id Remove PKCS#11 identity\n"
17692 + " --pkcs11-id id Serialized string\n"
17693 + " [--pkcs11-cert-file file] Use this PEM file, don't access token\n"
17694 + "\n"
17695 + " PKCS#11 Debugging Options:\n"
17696 + " --pkcs11-dump-slots Dump available PKCS#11 slots\n"
17697 + " --pkcs11-provider provider PKCS#11 provider library\n"
17698 + "\n"
17699 + " --pkcs11-dump-objects Dump available PKCS#11 objects\n"
17700 + " --pkcs11-provider provider PKCS#11 provider library\n"
17701 + " --pkcs11-slot slot Slot numeric id\n"
17702 + "\n"
17703 + )
17704 + );
17705 +#endif /* SSH_PKCS11_DISABLED */
17706 }
17707
17708 int
17709 @@ -350,6 +652,17 @@ main(int argc, char **argv)
17710 "Could not open a connection to your authentication agent.\n");
17711 exit(2);
17712 }
17713 +
17714 +#ifndef SSH_PKCS11_DISABLED
17715 + {
17716 + int r = do_pkcs11 (ac, argc, argv);
17717 + if (r != -2) {
17718 + ret = r;
17719 + goto done;
17720 + }
17721 + }
17722 +#endif /* SSH_PKCS11_DISABLED */
17723 +
17724 while ((ch = getopt(argc, argv, "lLcdDxXe:s:t:")) != -1) {
17725 switch (ch) {
17726 case 'l':
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
17730 @@ -71,6 +71,7 @@
17731 #include "buffer.h"
17732 #include "key.h"
17733 #include "authfd.h"
17734 +#include "pkcs11.h"
17735 #include "compat.h"
17736 #include "log.h"
17737 #include "misc.h"
17738 @@ -690,6 +691,157 @@ send:
17739 }
17740 #endif /* SMARTCARD */
17741
17742 +#ifndef SSH_PKCS11_DISABLED
17743 +
17744 +static
17745 +void
17746 +process_pkcs11_set_ask_pin (SocketEntry *e)
17747 +{
17748 + char *szAskPIN = NULL;
17749 + int success = 0;
17750 +
17751 + szAskPIN = buffer_get_string(&e->request, NULL);
17752 +
17753 + success = pkcs11_setAskPIN (szAskPIN);
17754 +
17755 + buffer_put_int(&e->output, 1);
17756 + buffer_put_char(&e->output,
17757 + success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
17758 +}
17759 +
17760 +static void
17761 +process_pkcs11_add_provider (SocketEntry *e)
17762 +{
17763 + char *szProvider = NULL;
17764 + int fProtectedAuthentication = 0;
17765 + char *szSignMode = NULL;
17766 + int fCertIsPrivate = 0;
17767 + int success = 0;
17768 +
17769 + szProvider = buffer_get_string(&e->request, NULL);
17770 + fProtectedAuthentication = buffer_get_int (&e->request);
17771 + szSignMode = buffer_get_string(&e->request, NULL);
17772 + fCertIsPrivate = buffer_get_int (&e->request);
17773 +
17774 + success = pkcs11_addProvider (szProvider, fProtectedAuthentication, szSignMode, fCertIsPrivate);
17775 +
17776 + buffer_put_int(&e->output, 1);
17777 + buffer_put_char(&e->output,
17778 + success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
17779 +}
17780 +
17781 +static
17782 +void
17783 +process_pkcs11_add_id (SocketEntry *e)
17784 +{
17785 + int success = 0;
17786 + int version = 2;
17787 + char szComment[1024];
17788 + Key *k = NULL;
17789 + pkcs11_identity *pkcs11_id = NULL;
17790 +
17791 + pkcs11_id = pkcs11_identity_new ();
17792 + if (pkcs11_id != NULL) {
17793 + pkcs11_id->id = strdup (buffer_get_string(&e->request, NULL));
17794 + pkcs11_id->pin_cache_period = buffer_get_int(&e->request);
17795 + pkcs11_id->cert_file = strdup (buffer_get_string(&e->request, NULL));
17796 +
17797 + pkcs11_getKey (
17798 + pkcs11_id,
17799 + &k,
17800 + szComment,
17801 + sizeof (szComment)
17802 + );
17803 +
17804 + if (k != NULL) {
17805 + if (lookup_identity(k, version) == NULL) {
17806 + Identity *id = xmalloc(sizeof(Identity));
17807 + Idtab *tab = NULL;
17808 +
17809 + id->key = k;
17810 + k = NULL;
17811 + id->comment = xstrdup (szComment);
17812 + id->death = 0; /* handled by pkcs#11 helper */
17813 + id->confirm = 0;
17814 +
17815 + tab = idtab_lookup(version);
17816 + TAILQ_INSERT_TAIL(&tab->idlist, id, next);
17817 + /* Increment the number of identities. */
17818 + tab->nentries++;
17819 + success = 1;
17820 + }
17821 + }
17822 + }
17823 +
17824 + if (k != NULL) {
17825 + key_free (k);
17826 + }
17827 +
17828 + if (pkcs11_id != NULL) {
17829 + pkcs11_identity_free (pkcs11_id);
17830 + }
17831 +
17832 + buffer_put_int(&e->output, 1);
17833 + buffer_put_char(&e->output,
17834 + success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
17835 +}
17836 +
17837 +static
17838 +void
17839 +process_pkcs11_remove_id (SocketEntry *e)
17840 +{
17841 + int success = 0;
17842 + Identity *id = NULL;
17843 + int version = 2;
17844 + char szComment[1024];
17845 + Key *k = NULL;
17846 +
17847 + pkcs11_identity *pkcs11_id = NULL;
17848 +
17849 + pkcs11_id = pkcs11_identity_new ();
17850 + if (pkcs11_id != NULL) {
17851 + pkcs11_id->id = strdup (buffer_get_string(&e->request, NULL));
17852 + pkcs11_id->pin_cache_period = buffer_get_int(&e->request);
17853 + pkcs11_id->cert_file = strdup (buffer_get_string(&e->request, NULL));
17854 +
17855 + pkcs11_getKey (
17856 + pkcs11_id,
17857 + &k,
17858 + szComment,
17859 + sizeof (szComment)
17860 + );
17861 +
17862 + if (k != NULL) {
17863 + id = lookup_identity (k, version);
17864 + }
17865 +
17866 + if (id != NULL) {
17867 + Idtab *tab = NULL;
17868 +
17869 + tab = idtab_lookup(version);
17870 + TAILQ_REMOVE(&tab->idlist, id, next);
17871 + tab->nentries--;
17872 + free_identity(id);
17873 + id = NULL;
17874 + success = 1;
17875 + }
17876 + }
17877 +
17878 + if (k != NULL) {
17879 + key_free (k);
17880 + }
17881 +
17882 + if (pkcs11_id != NULL) {
17883 + pkcs11_identity_free (pkcs11_id);
17884 + }
17885 +
17886 + buffer_put_int(&e->output, 1);
17887 + buffer_put_char(&e->output,
17888 + success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
17889 +}
17890 +
17891 +#endif /* SSH_PKCS11_DISABLED */
17892 +
17893 /* dispatch incoming messages */
17894
17895 static void
17896 @@ -785,6 +937,21 @@ process_message(SocketEntry *e)
17897 process_remove_smartcard_key(e);
17898 break;
17899 #endif /* SMARTCARD */
17900 +
17901 +#ifndef SSH_PKCS11_DISABLED
17902 + case SSH_AGENTC_PKCS11_SET_ASK_PIN:
17903 + process_pkcs11_set_ask_pin (e);
17904 + break;
17905 + case SSH_AGENTC_PKCS11_ADD_PROVIDER:
17906 + process_pkcs11_add_provider (e);
17907 + break;
17908 + case SSH_AGENTC_PKCS11_ADD_ID:
17909 + process_pkcs11_add_id (e);
17910 + break;
17911 + case SSH_AGENTC_PKCS11_REMOVE_ID:
17912 + process_pkcs11_remove_id (e);
17913 + break;
17914 +#endif /* SSH_PKCS11_DISABLED */
17915 default:
17916 /* Unknown message. Respond with failure. */
17917 error("Unknown message %d", type);
17918 @@ -1064,7 +1231,7 @@ main(int ac, char **av)
17919 s_flag++;
17920 break;
17921 case 'd':
17922 - if (d_flag)
17923 + if (d_flag > 3)
17924 usage();
17925 d_flag++;
17926 break;
17927 @@ -1167,7 +1334,7 @@ main(int ac, char **av)
17928 * the socket data. The child continues as the authentication agent.
17929 */
17930 if (d_flag) {
17931 - log_init(__progname, SYSLOG_LEVEL_DEBUG1, SYSLOG_FACILITY_AUTH, 1);
17932 + log_init(__progname, SYSLOG_LEVEL_DEBUG1+d_flag-1, SYSLOG_FACILITY_AUTH, 1);
17933 format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n";
17934 printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name,
17935 SSH_AUTHSOCKET_ENV_NAME);
17936 @@ -1228,6 +1395,11 @@ main(int ac, char **av)
17937 #endif
17938
17939 skip:
17940 +
17941 +#ifndef SSH_PKCS11_DISABLED
17942 + pkcs11_initialize (1, -1);
17943 +#endif /* SSH_PKCS11_DISABLED */
17944 +
17945 new_socket(AUTH_SOCKET, sock);
17946 if (ac > 0) {
17947 mysignal(SIGALRM, check_parent_exists);
17948 @@ -1251,4 +1423,8 @@ skip:
17949 after_select(readsetp, writesetp);
17950 }
17951 /* NOTREACHED */
17952 +
17953 +#ifndef SSH_PKCS11_DISABLED
17954 + pkcs11_terminate ();
17955 +#endif /* SSH_PKCS11_DISABLED */
17956 }