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 (¤t->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 (¤t->mutex); 5726 +#endif 5727 + 5728 + _pkcs11h_mem_free ((void *)¤t); 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 *)¤t); 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 (¤t_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 (¤t_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 (¬AfterCurrent)), 9575 + asctime (localtime (¬AfterNew)) 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 + ¤t_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 (¤t_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 (¤t_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 = ¶meter; 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 (¬After)) 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 } |