1 /* $OpenBSD: ssh-pkcs11.c,v 1.56 2023/03/08 05:33:53 tb Exp $ */ 2 /* 3 * Copyright (c) 2010 Markus Friedl. All rights reserved. 4 * Copyright (c) 2014 Pedro Martelletto. All rights reserved. 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include "includes.h" 20 21 #ifdef ENABLE_PKCS11 22 23 #ifdef HAVE_SYS_TIME_H 24 # include <sys/time.h> 25 #endif 26 27 #include <sys/types.h> 28 #include <stdarg.h> 29 #include <stdio.h> 30 31 #include <ctype.h> 32 #include <string.h> 33 #include <dlfcn.h> 34 35 #include "openbsd-compat/sys-queue.h" 36 #include "openbsd-compat/openssl-compat.h" 37 38 #include <openssl/ecdsa.h> 39 #include <openssl/x509.h> 40 #include <openssl/err.h> 41 42 #define CRYPTOKI_COMPAT 43 #include "pkcs11.h" 44 45 #include "log.h" 46 #include "misc.h" 47 #include "sshkey.h" 48 #include "ssh-pkcs11.h" 49 #include "digest.h" 50 #include "xmalloc.h" 51 52 struct pkcs11_slotinfo { 53 CK_TOKEN_INFO token; 54 CK_SESSION_HANDLE session; 55 int logged_in; 56 }; 57 58 struct pkcs11_provider { 59 char *name; 60 void *handle; 61 CK_FUNCTION_LIST *function_list; 62 CK_INFO info; 63 CK_ULONG nslots; 64 CK_SLOT_ID *slotlist; 65 struct pkcs11_slotinfo *slotinfo; 66 int valid; 67 int refcount; 68 TAILQ_ENTRY(pkcs11_provider) next; 69 }; 70 71 TAILQ_HEAD(, pkcs11_provider) pkcs11_providers; 72 73 struct pkcs11_key { 74 struct pkcs11_provider *provider; 75 CK_ULONG slotidx; 76 char *keyid; 77 int keyid_len; 78 }; 79 80 int pkcs11_interactive = 0; 81 82 #if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) 83 static void 84 ossl_error(const char *msg) 85 { 86 unsigned long e; 87 88 error_f("%s", msg); 89 while ((e = ERR_get_error()) != 0) 90 error_f("libcrypto error: %s", ERR_error_string(e, NULL)); 91 } 92 #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ 93 94 int 95 pkcs11_init(int interactive) 96 { 97 pkcs11_interactive = interactive; 98 TAILQ_INIT(&pkcs11_providers); 99 return (0); 100 } 101 102 /* 103 * finalize a provider shared library, it's no longer usable. 104 * however, there might still be keys referencing this provider, 105 * so the actual freeing of memory is handled by pkcs11_provider_unref(). 106 * this is called when a provider gets unregistered. 107 */ 108 static void 109 pkcs11_provider_finalize(struct pkcs11_provider *p) 110 { 111 CK_RV rv; 112 CK_ULONG i; 113 114 debug_f("provider \"%s\" refcount %d valid %d", 115 p->name, p->refcount, p->valid); 116 if (!p->valid) 117 return; 118 for (i = 0; i < p->nslots; i++) { 119 if (p->slotinfo[i].session && 120 (rv = p->function_list->C_CloseSession( 121 p->slotinfo[i].session)) != CKR_OK) 122 error("C_CloseSession failed: %lu", rv); 123 } 124 if ((rv = p->function_list->C_Finalize(NULL)) != CKR_OK) 125 error("C_Finalize failed: %lu", rv); 126 p->valid = 0; 127 p->function_list = NULL; 128 dlclose(p->handle); 129 } 130 131 /* 132 * remove a reference to the provider. 133 * called when a key gets destroyed or when the provider is unregistered. 134 */ 135 static void 136 pkcs11_provider_unref(struct pkcs11_provider *p) 137 { 138 debug_f("provider \"%s\" refcount %d", p->name, p->refcount); 139 if (--p->refcount <= 0) { 140 if (p->valid) 141 error_f("provider \"%s\" still valid", p->name); 142 free(p->name); 143 free(p->slotlist); 144 free(p->slotinfo); 145 free(p); 146 } 147 } 148 149 /* unregister all providers, keys might still point to the providers */ 150 void 151 pkcs11_terminate(void) 152 { 153 struct pkcs11_provider *p; 154 155 while ((p = TAILQ_FIRST(&pkcs11_providers)) != NULL) { 156 TAILQ_REMOVE(&pkcs11_providers, p, next); 157 pkcs11_provider_finalize(p); 158 pkcs11_provider_unref(p); 159 } 160 } 161 162 /* lookup provider by name */ 163 static struct pkcs11_provider * 164 pkcs11_provider_lookup(char *provider_id) 165 { 166 struct pkcs11_provider *p; 167 168 TAILQ_FOREACH(p, &pkcs11_providers, next) { 169 debug("check provider \"%s\"", p->name); 170 if (!strcmp(provider_id, p->name)) 171 return (p); 172 } 173 return (NULL); 174 } 175 176 /* unregister provider by name */ 177 int 178 pkcs11_del_provider(char *provider_id) 179 { 180 struct pkcs11_provider *p; 181 182 if ((p = pkcs11_provider_lookup(provider_id)) != NULL) { 183 TAILQ_REMOVE(&pkcs11_providers, p, next); 184 pkcs11_provider_finalize(p); 185 pkcs11_provider_unref(p); 186 return (0); 187 } 188 return (-1); 189 } 190 191 static RSA_METHOD *rsa_method; 192 static int rsa_idx = 0; 193 #if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) 194 static EC_KEY_METHOD *ec_key_method; 195 static int ec_key_idx = 0; 196 #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ 197 198 /* release a wrapped object */ 199 static void 200 pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, 201 long argl, void *argp) 202 { 203 struct pkcs11_key *k11 = ptr; 204 205 debug_f("parent %p ptr %p idx %d", parent, ptr, idx); 206 if (k11 == NULL) 207 return; 208 if (k11->provider) 209 pkcs11_provider_unref(k11->provider); 210 free(k11->keyid); 211 free(k11); 212 } 213 214 /* find a single 'obj' for given attributes */ 215 static int 216 pkcs11_find(struct pkcs11_provider *p, CK_ULONG slotidx, CK_ATTRIBUTE *attr, 217 CK_ULONG nattr, CK_OBJECT_HANDLE *obj) 218 { 219 CK_FUNCTION_LIST *f; 220 CK_SESSION_HANDLE session; 221 CK_ULONG nfound = 0; 222 CK_RV rv; 223 int ret = -1; 224 225 f = p->function_list; 226 session = p->slotinfo[slotidx].session; 227 if ((rv = f->C_FindObjectsInit(session, attr, nattr)) != CKR_OK) { 228 error("C_FindObjectsInit failed (nattr %lu): %lu", nattr, rv); 229 return (-1); 230 } 231 if ((rv = f->C_FindObjects(session, obj, 1, &nfound)) != CKR_OK || 232 nfound != 1) { 233 debug("C_FindObjects failed (nfound %lu nattr %lu): %lu", 234 nfound, nattr, rv); 235 } else 236 ret = 0; 237 if ((rv = f->C_FindObjectsFinal(session)) != CKR_OK) 238 error("C_FindObjectsFinal failed: %lu", rv); 239 return (ret); 240 } 241 242 static int 243 pkcs11_login_slot(struct pkcs11_provider *provider, struct pkcs11_slotinfo *si, 244 CK_USER_TYPE type) 245 { 246 char *pin = NULL, prompt[1024]; 247 CK_RV rv; 248 249 if (provider == NULL || si == NULL || !provider->valid) { 250 error("no pkcs11 (valid) provider found"); 251 return (-1); 252 } 253 254 if (!pkcs11_interactive) { 255 error("need pin entry%s", 256 (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH) ? 257 " on reader keypad" : ""); 258 return (-1); 259 } 260 if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH) 261 verbose("Deferring PIN entry to reader keypad."); 262 else { 263 snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ", 264 si->token.label); 265 if ((pin = read_passphrase(prompt, RP_ALLOW_EOF)) == NULL) { 266 debug_f("no pin specified"); 267 return (-1); /* bail out */ 268 } 269 } 270 rv = provider->function_list->C_Login(si->session, type, (u_char *)pin, 271 (pin != NULL) ? strlen(pin) : 0); 272 if (pin != NULL) 273 freezero(pin, strlen(pin)); 274 275 switch (rv) { 276 case CKR_OK: 277 case CKR_USER_ALREADY_LOGGED_IN: 278 /* success */ 279 break; 280 case CKR_PIN_LEN_RANGE: 281 error("PKCS#11 login failed: PIN length out of range"); 282 return -1; 283 case CKR_PIN_INCORRECT: 284 error("PKCS#11 login failed: PIN incorrect"); 285 return -1; 286 case CKR_PIN_LOCKED: 287 error("PKCS#11 login failed: PIN locked"); 288 return -1; 289 default: 290 error("PKCS#11 login failed: error %lu", rv); 291 return -1; 292 } 293 si->logged_in = 1; 294 return (0); 295 } 296 297 static int 298 pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type) 299 { 300 if (k11 == NULL || k11->provider == NULL || !k11->provider->valid) { 301 error("no pkcs11 (valid) provider found"); 302 return (-1); 303 } 304 305 return pkcs11_login_slot(k11->provider, 306 &k11->provider->slotinfo[k11->slotidx], type); 307 } 308 309 310 static int 311 pkcs11_check_obj_bool_attrib(struct pkcs11_key *k11, CK_OBJECT_HANDLE obj, 312 CK_ATTRIBUTE_TYPE type, int *val) 313 { 314 struct pkcs11_slotinfo *si; 315 CK_FUNCTION_LIST *f; 316 CK_BBOOL flag = 0; 317 CK_ATTRIBUTE attr; 318 CK_RV rv; 319 320 *val = 0; 321 322 if (!k11->provider || !k11->provider->valid) { 323 error("no pkcs11 (valid) provider found"); 324 return (-1); 325 } 326 327 f = k11->provider->function_list; 328 si = &k11->provider->slotinfo[k11->slotidx]; 329 330 attr.type = type; 331 attr.pValue = &flag; 332 attr.ulValueLen = sizeof(flag); 333 334 rv = f->C_GetAttributeValue(si->session, obj, &attr, 1); 335 if (rv != CKR_OK) { 336 error("C_GetAttributeValue failed: %lu", rv); 337 return (-1); 338 } 339 *val = flag != 0; 340 debug_f("provider \"%s\" slot %lu object %lu: attrib %lu = %d", 341 k11->provider->name, k11->slotidx, obj, type, *val); 342 return (0); 343 } 344 345 static int 346 pkcs11_get_key(struct pkcs11_key *k11, CK_MECHANISM_TYPE mech_type) 347 { 348 struct pkcs11_slotinfo *si; 349 CK_FUNCTION_LIST *f; 350 CK_OBJECT_HANDLE obj; 351 CK_RV rv; 352 CK_OBJECT_CLASS private_key_class; 353 CK_BBOOL true_val; 354 CK_MECHANISM mech; 355 CK_ATTRIBUTE key_filter[3]; 356 int always_auth = 0; 357 int did_login = 0; 358 359 if (!k11->provider || !k11->provider->valid) { 360 error("no pkcs11 (valid) provider found"); 361 return (-1); 362 } 363 364 f = k11->provider->function_list; 365 si = &k11->provider->slotinfo[k11->slotidx]; 366 367 if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) { 368 if (pkcs11_login(k11, CKU_USER) < 0) { 369 error("login failed"); 370 return (-1); 371 } 372 did_login = 1; 373 } 374 375 memset(&key_filter, 0, sizeof(key_filter)); 376 private_key_class = CKO_PRIVATE_KEY; 377 key_filter[0].type = CKA_CLASS; 378 key_filter[0].pValue = &private_key_class; 379 key_filter[0].ulValueLen = sizeof(private_key_class); 380 381 key_filter[1].type = CKA_ID; 382 key_filter[1].pValue = k11->keyid; 383 key_filter[1].ulValueLen = k11->keyid_len; 384 385 true_val = CK_TRUE; 386 key_filter[2].type = CKA_SIGN; 387 key_filter[2].pValue = &true_val; 388 key_filter[2].ulValueLen = sizeof(true_val); 389 390 /* try to find object w/CKA_SIGN first, retry w/o */ 391 if (pkcs11_find(k11->provider, k11->slotidx, key_filter, 3, &obj) < 0 && 392 pkcs11_find(k11->provider, k11->slotidx, key_filter, 2, &obj) < 0) { 393 error("cannot find private key"); 394 return (-1); 395 } 396 397 memset(&mech, 0, sizeof(mech)); 398 mech.mechanism = mech_type; 399 mech.pParameter = NULL_PTR; 400 mech.ulParameterLen = 0; 401 402 if ((rv = f->C_SignInit(si->session, &mech, obj)) != CKR_OK) { 403 error("C_SignInit failed: %lu", rv); 404 return (-1); 405 } 406 407 pkcs11_check_obj_bool_attrib(k11, obj, CKA_ALWAYS_AUTHENTICATE, 408 &always_auth); /* ignore errors here */ 409 if (always_auth && !did_login) { 410 debug_f("always-auth key"); 411 if (pkcs11_login(k11, CKU_CONTEXT_SPECIFIC) < 0) { 412 error("login failed for always-auth key"); 413 return (-1); 414 } 415 } 416 417 return (0); 418 } 419 420 /* openssl callback doing the actual signing operation */ 421 static int 422 pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, 423 int padding) 424 { 425 struct pkcs11_key *k11; 426 struct pkcs11_slotinfo *si; 427 CK_FUNCTION_LIST *f; 428 CK_ULONG tlen = 0; 429 CK_RV rv; 430 int rval = -1; 431 432 if ((k11 = RSA_get_ex_data(rsa, rsa_idx)) == NULL) { 433 error("RSA_get_ex_data failed"); 434 return (-1); 435 } 436 437 if (pkcs11_get_key(k11, CKM_RSA_PKCS) == -1) { 438 error("pkcs11_get_key failed"); 439 return (-1); 440 } 441 442 f = k11->provider->function_list; 443 si = &k11->provider->slotinfo[k11->slotidx]; 444 tlen = RSA_size(rsa); 445 446 /* XXX handle CKR_BUFFER_TOO_SMALL */ 447 rv = f->C_Sign(si->session, (CK_BYTE *)from, flen, to, &tlen); 448 if (rv == CKR_OK) 449 rval = tlen; 450 else 451 error("C_Sign failed: %lu", rv); 452 453 return (rval); 454 } 455 456 static int 457 pkcs11_rsa_private_decrypt(int flen, const u_char *from, u_char *to, RSA *rsa, 458 int padding) 459 { 460 return (-1); 461 } 462 463 static int 464 pkcs11_rsa_start_wrapper(void) 465 { 466 if (rsa_method != NULL) 467 return (0); 468 rsa_method = RSA_meth_dup(RSA_get_default_method()); 469 if (rsa_method == NULL) 470 return (-1); 471 rsa_idx = RSA_get_ex_new_index(0, "ssh-pkcs11-rsa", 472 NULL, NULL, pkcs11_k11_free); 473 if (rsa_idx == -1) 474 return (-1); 475 if (!RSA_meth_set1_name(rsa_method, "pkcs11") || 476 !RSA_meth_set_priv_enc(rsa_method, pkcs11_rsa_private_encrypt) || 477 !RSA_meth_set_priv_dec(rsa_method, pkcs11_rsa_private_decrypt)) { 478 error_f("setup pkcs11 method failed"); 479 return (-1); 480 } 481 return (0); 482 } 483 484 /* redirect private key operations for rsa key to pkcs11 token */ 485 static int 486 pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, 487 CK_ATTRIBUTE *keyid_attrib, RSA *rsa) 488 { 489 struct pkcs11_key *k11; 490 491 if (pkcs11_rsa_start_wrapper() == -1) 492 return (-1); 493 494 k11 = xcalloc(1, sizeof(*k11)); 495 k11->provider = provider; 496 provider->refcount++; /* provider referenced by RSA key */ 497 k11->slotidx = slotidx; 498 /* identify key object on smartcard */ 499 k11->keyid_len = keyid_attrib->ulValueLen; 500 if (k11->keyid_len > 0) { 501 k11->keyid = xmalloc(k11->keyid_len); 502 memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); 503 } 504 505 RSA_set_method(rsa, rsa_method); 506 RSA_set_ex_data(rsa, rsa_idx, k11); 507 return (0); 508 } 509 510 #if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) 511 /* openssl callback doing the actual signing operation */ 512 static ECDSA_SIG * 513 ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, 514 const BIGNUM *rp, EC_KEY *ec) 515 { 516 struct pkcs11_key *k11; 517 struct pkcs11_slotinfo *si; 518 CK_FUNCTION_LIST *f; 519 CK_ULONG siglen = 0, bnlen; 520 CK_RV rv; 521 ECDSA_SIG *ret = NULL; 522 u_char *sig; 523 BIGNUM *r = NULL, *s = NULL; 524 525 if ((k11 = EC_KEY_get_ex_data(ec, ec_key_idx)) == NULL) { 526 ossl_error("EC_KEY_get_ex_data failed for ec"); 527 return (NULL); 528 } 529 530 if (pkcs11_get_key(k11, CKM_ECDSA) == -1) { 531 error("pkcs11_get_key failed"); 532 return (NULL); 533 } 534 535 f = k11->provider->function_list; 536 si = &k11->provider->slotinfo[k11->slotidx]; 537 538 siglen = ECDSA_size(ec); 539 sig = xmalloc(siglen); 540 541 /* XXX handle CKR_BUFFER_TOO_SMALL */ 542 rv = f->C_Sign(si->session, (CK_BYTE *)dgst, dgst_len, sig, &siglen); 543 if (rv != CKR_OK) { 544 error("C_Sign failed: %lu", rv); 545 goto done; 546 } 547 if (siglen < 64 || siglen > 132 || siglen % 2) { 548 error_f("bad signature length: %lu", (u_long)siglen); 549 goto done; 550 } 551 bnlen = siglen/2; 552 if ((ret = ECDSA_SIG_new()) == NULL) { 553 error("ECDSA_SIG_new failed"); 554 goto done; 555 } 556 if ((r = BN_bin2bn(sig, bnlen, NULL)) == NULL || 557 (s = BN_bin2bn(sig+bnlen, bnlen, NULL)) == NULL) { 558 ossl_error("BN_bin2bn failed"); 559 ECDSA_SIG_free(ret); 560 ret = NULL; 561 goto done; 562 } 563 if (!ECDSA_SIG_set0(ret, r, s)) { 564 error_f("ECDSA_SIG_set0 failed"); 565 ECDSA_SIG_free(ret); 566 ret = NULL; 567 goto done; 568 } 569 r = s = NULL; /* now owned by ret */ 570 /* success */ 571 done: 572 BN_free(r); 573 BN_free(s); 574 free(sig); 575 576 return (ret); 577 } 578 579 static int 580 pkcs11_ecdsa_start_wrapper(void) 581 { 582 int (*orig_sign)(int, const unsigned char *, int, unsigned char *, 583 unsigned int *, const BIGNUM *, const BIGNUM *, EC_KEY *) = NULL; 584 585 if (ec_key_method != NULL) 586 return (0); 587 ec_key_idx = EC_KEY_get_ex_new_index(0, "ssh-pkcs11-ecdsa", 588 NULL, NULL, pkcs11_k11_free); 589 if (ec_key_idx == -1) 590 return (-1); 591 ec_key_method = EC_KEY_METHOD_new(EC_KEY_OpenSSL()); 592 if (ec_key_method == NULL) 593 return (-1); 594 EC_KEY_METHOD_get_sign(ec_key_method, &orig_sign, NULL, NULL); 595 EC_KEY_METHOD_set_sign(ec_key_method, orig_sign, NULL, ecdsa_do_sign); 596 return (0); 597 } 598 599 static int 600 pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, 601 CK_ATTRIBUTE *keyid_attrib, EC_KEY *ec) 602 { 603 struct pkcs11_key *k11; 604 605 if (pkcs11_ecdsa_start_wrapper() == -1) 606 return (-1); 607 608 k11 = xcalloc(1, sizeof(*k11)); 609 k11->provider = provider; 610 provider->refcount++; /* provider referenced by ECDSA key */ 611 k11->slotidx = slotidx; 612 /* identify key object on smartcard */ 613 k11->keyid_len = keyid_attrib->ulValueLen; 614 if (k11->keyid_len > 0) { 615 k11->keyid = xmalloc(k11->keyid_len); 616 memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); 617 } 618 EC_KEY_set_method(ec, ec_key_method); 619 EC_KEY_set_ex_data(ec, ec_key_idx, k11); 620 621 return (0); 622 } 623 #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ 624 625 /* remove trailing spaces */ 626 static void 627 rmspace(u_char *buf, size_t len) 628 { 629 size_t i; 630 631 if (!len) 632 return; 633 for (i = len - 1; i > 0; i--) 634 if (i == len - 1 || buf[i] == ' ') 635 buf[i] = '\0'; 636 else 637 break; 638 } 639 640 /* 641 * open a pkcs11 session and login if required. 642 * if pin == NULL we delay login until key use 643 */ 644 static int 645 pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin, 646 CK_ULONG user) 647 { 648 struct pkcs11_slotinfo *si; 649 CK_FUNCTION_LIST *f; 650 CK_RV rv; 651 CK_SESSION_HANDLE session; 652 int login_required, ret; 653 654 f = p->function_list; 655 si = &p->slotinfo[slotidx]; 656 657 login_required = si->token.flags & CKF_LOGIN_REQUIRED; 658 659 /* fail early before opening session */ 660 if (login_required && !pkcs11_interactive && 661 (pin == NULL || strlen(pin) == 0)) { 662 error("pin required"); 663 return (-SSH_PKCS11_ERR_PIN_REQUIRED); 664 } 665 if ((rv = f->C_OpenSession(p->slotlist[slotidx], CKF_RW_SESSION| 666 CKF_SERIAL_SESSION, NULL, NULL, &session)) != CKR_OK) { 667 error("C_OpenSession failed: %lu", rv); 668 return (-1); 669 } 670 if (login_required && pin != NULL && strlen(pin) != 0) { 671 rv = f->C_Login(session, user, (u_char *)pin, strlen(pin)); 672 if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) { 673 error("C_Login failed: %lu", rv); 674 ret = (rv == CKR_PIN_LOCKED) ? 675 -SSH_PKCS11_ERR_PIN_LOCKED : 676 -SSH_PKCS11_ERR_LOGIN_FAIL; 677 if ((rv = f->C_CloseSession(session)) != CKR_OK) 678 error("C_CloseSession failed: %lu", rv); 679 return (ret); 680 } 681 si->logged_in = 1; 682 } 683 si->session = session; 684 return (0); 685 } 686 687 static int 688 pkcs11_key_included(struct sshkey ***keysp, int *nkeys, struct sshkey *key) 689 { 690 int i; 691 692 for (i = 0; i < *nkeys; i++) 693 if (sshkey_equal(key, (*keysp)[i])) 694 return (1); 695 return (0); 696 } 697 698 #if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) 699 static struct sshkey * 700 pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, 701 CK_OBJECT_HANDLE *obj) 702 { 703 CK_ATTRIBUTE key_attr[3]; 704 CK_SESSION_HANDLE session; 705 CK_FUNCTION_LIST *f = NULL; 706 CK_RV rv; 707 ASN1_OCTET_STRING *octet = NULL; 708 EC_KEY *ec = NULL; 709 EC_GROUP *group = NULL; 710 struct sshkey *key = NULL; 711 const unsigned char *attrp = NULL; 712 int i; 713 int nid; 714 715 memset(&key_attr, 0, sizeof(key_attr)); 716 key_attr[0].type = CKA_ID; 717 key_attr[1].type = CKA_EC_POINT; 718 key_attr[2].type = CKA_EC_PARAMS; 719 720 session = p->slotinfo[slotidx].session; 721 f = p->function_list; 722 723 /* figure out size of the attributes */ 724 rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); 725 if (rv != CKR_OK) { 726 error("C_GetAttributeValue failed: %lu", rv); 727 return (NULL); 728 } 729 730 /* 731 * Allow CKA_ID (always first attribute) to be empty, but 732 * ensure that none of the others are zero length. 733 * XXX assumes CKA_ID is always first. 734 */ 735 if (key_attr[1].ulValueLen == 0 || 736 key_attr[2].ulValueLen == 0) { 737 error("invalid attribute length"); 738 return (NULL); 739 } 740 741 /* allocate buffers for attributes */ 742 for (i = 0; i < 3; i++) 743 if (key_attr[i].ulValueLen > 0) 744 key_attr[i].pValue = xcalloc(1, key_attr[i].ulValueLen); 745 746 /* retrieve ID, public point and curve parameters of EC key */ 747 rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); 748 if (rv != CKR_OK) { 749 error("C_GetAttributeValue failed: %lu", rv); 750 goto fail; 751 } 752 753 ec = EC_KEY_new(); 754 if (ec == NULL) { 755 error("EC_KEY_new failed"); 756 goto fail; 757 } 758 759 attrp = key_attr[2].pValue; 760 group = d2i_ECPKParameters(NULL, &attrp, key_attr[2].ulValueLen); 761 if (group == NULL) { 762 ossl_error("d2i_ECPKParameters failed"); 763 goto fail; 764 } 765 766 if (EC_KEY_set_group(ec, group) == 0) { 767 ossl_error("EC_KEY_set_group failed"); 768 goto fail; 769 } 770 771 if (key_attr[1].ulValueLen <= 2) { 772 error("CKA_EC_POINT too small"); 773 goto fail; 774 } 775 776 attrp = key_attr[1].pValue; 777 octet = d2i_ASN1_OCTET_STRING(NULL, &attrp, key_attr[1].ulValueLen); 778 if (octet == NULL) { 779 ossl_error("d2i_ASN1_OCTET_STRING failed"); 780 goto fail; 781 } 782 attrp = octet->data; 783 if (o2i_ECPublicKey(&ec, &attrp, octet->length) == NULL) { 784 ossl_error("o2i_ECPublicKey failed"); 785 goto fail; 786 } 787 788 nid = sshkey_ecdsa_key_to_nid(ec); 789 if (nid < 0) { 790 error("couldn't get curve nid"); 791 goto fail; 792 } 793 794 if (pkcs11_ecdsa_wrap(p, slotidx, &key_attr[0], ec)) 795 goto fail; 796 797 key = sshkey_new(KEY_UNSPEC); 798 if (key == NULL) { 799 error("sshkey_new failed"); 800 goto fail; 801 } 802 803 key->ecdsa = ec; 804 key->ecdsa_nid = nid; 805 key->type = KEY_ECDSA; 806 key->flags |= SSHKEY_FLAG_EXT; 807 ec = NULL; /* now owned by key */ 808 809 fail: 810 for (i = 0; i < 3; i++) 811 free(key_attr[i].pValue); 812 if (ec) 813 EC_KEY_free(ec); 814 if (group) 815 EC_GROUP_free(group); 816 if (octet) 817 ASN1_OCTET_STRING_free(octet); 818 819 return (key); 820 } 821 #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ 822 823 static struct sshkey * 824 pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, 825 CK_OBJECT_HANDLE *obj) 826 { 827 CK_ATTRIBUTE key_attr[3]; 828 CK_SESSION_HANDLE session; 829 CK_FUNCTION_LIST *f = NULL; 830 CK_RV rv; 831 RSA *rsa = NULL; 832 BIGNUM *rsa_n, *rsa_e; 833 struct sshkey *key = NULL; 834 int i; 835 836 memset(&key_attr, 0, sizeof(key_attr)); 837 key_attr[0].type = CKA_ID; 838 key_attr[1].type = CKA_MODULUS; 839 key_attr[2].type = CKA_PUBLIC_EXPONENT; 840 841 session = p->slotinfo[slotidx].session; 842 f = p->function_list; 843 844 /* figure out size of the attributes */ 845 rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); 846 if (rv != CKR_OK) { 847 error("C_GetAttributeValue failed: %lu", rv); 848 return (NULL); 849 } 850 851 /* 852 * Allow CKA_ID (always first attribute) to be empty, but 853 * ensure that none of the others are zero length. 854 * XXX assumes CKA_ID is always first. 855 */ 856 if (key_attr[1].ulValueLen == 0 || 857 key_attr[2].ulValueLen == 0) { 858 error("invalid attribute length"); 859 return (NULL); 860 } 861 862 /* allocate buffers for attributes */ 863 for (i = 0; i < 3; i++) 864 if (key_attr[i].ulValueLen > 0) 865 key_attr[i].pValue = xcalloc(1, key_attr[i].ulValueLen); 866 867 /* retrieve ID, modulus and public exponent of RSA key */ 868 rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); 869 if (rv != CKR_OK) { 870 error("C_GetAttributeValue failed: %lu", rv); 871 goto fail; 872 } 873 874 rsa = RSA_new(); 875 if (rsa == NULL) { 876 error("RSA_new failed"); 877 goto fail; 878 } 879 880 rsa_n = BN_bin2bn(key_attr[1].pValue, key_attr[1].ulValueLen, NULL); 881 rsa_e = BN_bin2bn(key_attr[2].pValue, key_attr[2].ulValueLen, NULL); 882 if (rsa_n == NULL || rsa_e == NULL) { 883 error("BN_bin2bn failed"); 884 goto fail; 885 } 886 if (!RSA_set0_key(rsa, rsa_n, rsa_e, NULL)) 887 fatal_f("set key"); 888 rsa_n = rsa_e = NULL; /* transferred */ 889 890 if (pkcs11_rsa_wrap(p, slotidx, &key_attr[0], rsa)) 891 goto fail; 892 893 key = sshkey_new(KEY_UNSPEC); 894 if (key == NULL) { 895 error("sshkey_new failed"); 896 goto fail; 897 } 898 899 key->rsa = rsa; 900 key->type = KEY_RSA; 901 key->flags |= SSHKEY_FLAG_EXT; 902 rsa = NULL; /* now owned by key */ 903 904 fail: 905 for (i = 0; i < 3; i++) 906 free(key_attr[i].pValue); 907 RSA_free(rsa); 908 909 return (key); 910 } 911 912 static int 913 pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, 914 CK_OBJECT_HANDLE *obj, struct sshkey **keyp, char **labelp) 915 { 916 CK_ATTRIBUTE cert_attr[3]; 917 CK_SESSION_HANDLE session; 918 CK_FUNCTION_LIST *f = NULL; 919 CK_RV rv; 920 X509 *x509 = NULL; 921 X509_NAME *x509_name = NULL; 922 EVP_PKEY *evp; 923 RSA *rsa = NULL; 924 #ifdef OPENSSL_HAS_ECC 925 EC_KEY *ec = NULL; 926 #endif 927 struct sshkey *key = NULL; 928 int i; 929 #if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) 930 int nid; 931 #endif 932 const u_char *cp; 933 char *subject = NULL; 934 935 *keyp = NULL; 936 *labelp = NULL; 937 938 memset(&cert_attr, 0, sizeof(cert_attr)); 939 cert_attr[0].type = CKA_ID; 940 cert_attr[1].type = CKA_SUBJECT; 941 cert_attr[2].type = CKA_VALUE; 942 943 session = p->slotinfo[slotidx].session; 944 f = p->function_list; 945 946 /* figure out size of the attributes */ 947 rv = f->C_GetAttributeValue(session, *obj, cert_attr, 3); 948 if (rv != CKR_OK) { 949 error("C_GetAttributeValue failed: %lu", rv); 950 return -1; 951 } 952 953 /* 954 * Allow CKA_ID (always first attribute) to be empty, but 955 * ensure that none of the others are zero length. 956 * XXX assumes CKA_ID is always first. 957 */ 958 if (cert_attr[1].ulValueLen == 0 || 959 cert_attr[2].ulValueLen == 0) { 960 error("invalid attribute length"); 961 return -1; 962 } 963 964 /* allocate buffers for attributes */ 965 for (i = 0; i < 3; i++) 966 if (cert_attr[i].ulValueLen > 0) 967 cert_attr[i].pValue = xcalloc(1, cert_attr[i].ulValueLen); 968 969 /* retrieve ID, subject and value of certificate */ 970 rv = f->C_GetAttributeValue(session, *obj, cert_attr, 3); 971 if (rv != CKR_OK) { 972 error("C_GetAttributeValue failed: %lu", rv); 973 goto out; 974 } 975 976 /* Decode DER-encoded cert subject */ 977 cp = cert_attr[1].pValue; 978 if ((x509_name = d2i_X509_NAME(NULL, &cp, 979 cert_attr[1].ulValueLen)) == NULL || 980 (subject = X509_NAME_oneline(x509_name, NULL, 0)) == NULL) 981 subject = xstrdup("invalid subject"); 982 X509_NAME_free(x509_name); 983 984 cp = cert_attr[2].pValue; 985 if ((x509 = d2i_X509(NULL, &cp, cert_attr[2].ulValueLen)) == NULL) { 986 error("d2i_x509 failed"); 987 goto out; 988 } 989 990 if ((evp = X509_get_pubkey(x509)) == NULL) { 991 error("X509_get_pubkey failed"); 992 goto out; 993 } 994 995 if (EVP_PKEY_base_id(evp) == EVP_PKEY_RSA) { 996 if (EVP_PKEY_get0_RSA(evp) == NULL) { 997 error("invalid x509; no rsa key"); 998 goto out; 999 } 1000 if ((rsa = RSAPublicKey_dup(EVP_PKEY_get0_RSA(evp))) == NULL) { 1001 error("RSAPublicKey_dup failed"); 1002 goto out; 1003 } 1004 1005 if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], rsa)) 1006 goto out; 1007 1008 key = sshkey_new(KEY_UNSPEC); 1009 if (key == NULL) { 1010 error("sshkey_new failed"); 1011 goto out; 1012 } 1013 1014 key->rsa = rsa; 1015 key->type = KEY_RSA; 1016 key->flags |= SSHKEY_FLAG_EXT; 1017 rsa = NULL; /* now owned by key */ 1018 #if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) 1019 } else if (EVP_PKEY_base_id(evp) == EVP_PKEY_EC) { 1020 if (EVP_PKEY_get0_EC_KEY(evp) == NULL) { 1021 error("invalid x509; no ec key"); 1022 goto out; 1023 } 1024 if ((ec = EC_KEY_dup(EVP_PKEY_get0_EC_KEY(evp))) == NULL) { 1025 error("EC_KEY_dup failed"); 1026 goto out; 1027 } 1028 1029 nid = sshkey_ecdsa_key_to_nid(ec); 1030 if (nid < 0) { 1031 error("couldn't get curve nid"); 1032 goto out; 1033 } 1034 1035 if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], ec)) 1036 goto out; 1037 1038 key = sshkey_new(KEY_UNSPEC); 1039 if (key == NULL) { 1040 error("sshkey_new failed"); 1041 goto out; 1042 } 1043 1044 key->ecdsa = ec; 1045 key->ecdsa_nid = nid; 1046 key->type = KEY_ECDSA; 1047 key->flags |= SSHKEY_FLAG_EXT; 1048 ec = NULL; /* now owned by key */ 1049 #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ 1050 } else { 1051 error("unknown certificate key type"); 1052 goto out; 1053 } 1054 out: 1055 for (i = 0; i < 3; i++) 1056 free(cert_attr[i].pValue); 1057 X509_free(x509); 1058 RSA_free(rsa); 1059 #ifdef OPENSSL_HAS_ECC 1060 EC_KEY_free(ec); 1061 #endif 1062 if (key == NULL) { 1063 free(subject); 1064 return -1; 1065 } 1066 /* success */ 1067 *keyp = key; 1068 *labelp = subject; 1069 return 0; 1070 } 1071 1072 #if 0 1073 static int 1074 have_rsa_key(const RSA *rsa) 1075 { 1076 const BIGNUM *rsa_n, *rsa_e; 1077 1078 RSA_get0_key(rsa, &rsa_n, &rsa_e, NULL); 1079 return rsa_n != NULL && rsa_e != NULL; 1080 } 1081 #endif 1082 1083 static void 1084 note_key(struct pkcs11_provider *p, CK_ULONG slotidx, const char *context, 1085 struct sshkey *key) 1086 { 1087 char *fp; 1088 1089 if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT, 1090 SSH_FP_DEFAULT)) == NULL) { 1091 error_f("sshkey_fingerprint failed"); 1092 return; 1093 } 1094 debug2("%s: provider %s slot %lu: %s %s", context, p->name, 1095 (u_long)slotidx, sshkey_type(key), fp); 1096 free(fp); 1097 } 1098 1099 /* 1100 * lookup certificates for token in slot identified by slotidx, 1101 * add 'wrapped' public keys to the 'keysp' array and increment nkeys. 1102 * keysp points to an (possibly empty) array with *nkeys keys. 1103 */ 1104 static int 1105 pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, 1106 struct sshkey ***keysp, char ***labelsp, int *nkeys) 1107 { 1108 struct sshkey *key = NULL; 1109 CK_OBJECT_CLASS key_class; 1110 CK_ATTRIBUTE key_attr[1]; 1111 CK_SESSION_HANDLE session; 1112 CK_FUNCTION_LIST *f = NULL; 1113 CK_RV rv; 1114 CK_OBJECT_HANDLE obj; 1115 CK_ULONG n = 0; 1116 int ret = -1; 1117 char *label; 1118 1119 memset(&key_attr, 0, sizeof(key_attr)); 1120 memset(&obj, 0, sizeof(obj)); 1121 1122 key_class = CKO_CERTIFICATE; 1123 key_attr[0].type = CKA_CLASS; 1124 key_attr[0].pValue = &key_class; 1125 key_attr[0].ulValueLen = sizeof(key_class); 1126 1127 session = p->slotinfo[slotidx].session; 1128 f = p->function_list; 1129 1130 rv = f->C_FindObjectsInit(session, key_attr, 1); 1131 if (rv != CKR_OK) { 1132 error("C_FindObjectsInit failed: %lu", rv); 1133 goto fail; 1134 } 1135 1136 while (1) { 1137 CK_CERTIFICATE_TYPE ck_cert_type; 1138 1139 rv = f->C_FindObjects(session, &obj, 1, &n); 1140 if (rv != CKR_OK) { 1141 error("C_FindObjects failed: %lu", rv); 1142 goto fail; 1143 } 1144 if (n == 0) 1145 break; 1146 1147 memset(&ck_cert_type, 0, sizeof(ck_cert_type)); 1148 memset(&key_attr, 0, sizeof(key_attr)); 1149 key_attr[0].type = CKA_CERTIFICATE_TYPE; 1150 key_attr[0].pValue = &ck_cert_type; 1151 key_attr[0].ulValueLen = sizeof(ck_cert_type); 1152 1153 rv = f->C_GetAttributeValue(session, obj, key_attr, 1); 1154 if (rv != CKR_OK) { 1155 error("C_GetAttributeValue failed: %lu", rv); 1156 goto fail; 1157 } 1158 1159 key = NULL; 1160 label = NULL; 1161 switch (ck_cert_type) { 1162 case CKC_X_509: 1163 if (pkcs11_fetch_x509_pubkey(p, slotidx, &obj, 1164 &key, &label) != 0) { 1165 error("failed to fetch key"); 1166 continue; 1167 } 1168 break; 1169 default: 1170 error("skipping unsupported certificate type %lu", 1171 ck_cert_type); 1172 continue; 1173 } 1174 note_key(p, slotidx, __func__, key); 1175 if (pkcs11_key_included(keysp, nkeys, key)) { 1176 debug2_f("key already included");; 1177 sshkey_free(key); 1178 } else { 1179 /* expand key array and add key */ 1180 *keysp = xrecallocarray(*keysp, *nkeys, 1181 *nkeys + 1, sizeof(struct sshkey *)); 1182 (*keysp)[*nkeys] = key; 1183 if (labelsp != NULL) { 1184 *labelsp = xrecallocarray(*labelsp, *nkeys, 1185 *nkeys + 1, sizeof(char *)); 1186 (*labelsp)[*nkeys] = xstrdup((char *)label); 1187 } 1188 *nkeys = *nkeys + 1; 1189 debug("have %d keys", *nkeys); 1190 } 1191 } 1192 1193 ret = 0; 1194 fail: 1195 rv = f->C_FindObjectsFinal(session); 1196 if (rv != CKR_OK) { 1197 error("C_FindObjectsFinal failed: %lu", rv); 1198 ret = -1; 1199 } 1200 1201 return (ret); 1202 } 1203 1204 /* 1205 * lookup public keys for token in slot identified by slotidx, 1206 * add 'wrapped' public keys to the 'keysp' array and increment nkeys. 1207 * keysp points to an (possibly empty) array with *nkeys keys. 1208 */ 1209 static int 1210 pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, 1211 struct sshkey ***keysp, char ***labelsp, int *nkeys) 1212 { 1213 struct sshkey *key = NULL; 1214 CK_OBJECT_CLASS key_class; 1215 CK_ATTRIBUTE key_attr[2]; 1216 CK_SESSION_HANDLE session; 1217 CK_FUNCTION_LIST *f = NULL; 1218 CK_RV rv; 1219 CK_OBJECT_HANDLE obj; 1220 CK_ULONG n = 0; 1221 int ret = -1; 1222 1223 memset(&key_attr, 0, sizeof(key_attr)); 1224 memset(&obj, 0, sizeof(obj)); 1225 1226 key_class = CKO_PUBLIC_KEY; 1227 key_attr[0].type = CKA_CLASS; 1228 key_attr[0].pValue = &key_class; 1229 key_attr[0].ulValueLen = sizeof(key_class); 1230 1231 session = p->slotinfo[slotidx].session; 1232 f = p->function_list; 1233 1234 rv = f->C_FindObjectsInit(session, key_attr, 1); 1235 if (rv != CKR_OK) { 1236 error("C_FindObjectsInit failed: %lu", rv); 1237 goto fail; 1238 } 1239 1240 while (1) { 1241 CK_KEY_TYPE ck_key_type; 1242 CK_UTF8CHAR label[256]; 1243 1244 rv = f->C_FindObjects(session, &obj, 1, &n); 1245 if (rv != CKR_OK) { 1246 error("C_FindObjects failed: %lu", rv); 1247 goto fail; 1248 } 1249 if (n == 0) 1250 break; 1251 1252 memset(&ck_key_type, 0, sizeof(ck_key_type)); 1253 memset(&key_attr, 0, sizeof(key_attr)); 1254 key_attr[0].type = CKA_KEY_TYPE; 1255 key_attr[0].pValue = &ck_key_type; 1256 key_attr[0].ulValueLen = sizeof(ck_key_type); 1257 key_attr[1].type = CKA_LABEL; 1258 key_attr[1].pValue = &label; 1259 key_attr[1].ulValueLen = sizeof(label) - 1; 1260 1261 rv = f->C_GetAttributeValue(session, obj, key_attr, 2); 1262 if (rv != CKR_OK) { 1263 error("C_GetAttributeValue failed: %lu", rv); 1264 goto fail; 1265 } 1266 1267 label[key_attr[1].ulValueLen] = '\0'; 1268 1269 switch (ck_key_type) { 1270 case CKK_RSA: 1271 key = pkcs11_fetch_rsa_pubkey(p, slotidx, &obj); 1272 break; 1273 #if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) 1274 case CKK_ECDSA: 1275 key = pkcs11_fetch_ecdsa_pubkey(p, slotidx, &obj); 1276 break; 1277 #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ 1278 default: 1279 /* XXX print key type? */ 1280 key = NULL; 1281 error("skipping unsupported key type"); 1282 } 1283 1284 if (key == NULL) { 1285 error("failed to fetch key"); 1286 continue; 1287 } 1288 note_key(p, slotidx, __func__, key); 1289 if (pkcs11_key_included(keysp, nkeys, key)) { 1290 debug2_f("key already included");; 1291 sshkey_free(key); 1292 } else { 1293 /* expand key array and add key */ 1294 *keysp = xrecallocarray(*keysp, *nkeys, 1295 *nkeys + 1, sizeof(struct sshkey *)); 1296 (*keysp)[*nkeys] = key; 1297 if (labelsp != NULL) { 1298 *labelsp = xrecallocarray(*labelsp, *nkeys, 1299 *nkeys + 1, sizeof(char *)); 1300 (*labelsp)[*nkeys] = xstrdup((char *)label); 1301 } 1302 *nkeys = *nkeys + 1; 1303 debug("have %d keys", *nkeys); 1304 } 1305 } 1306 1307 ret = 0; 1308 fail: 1309 rv = f->C_FindObjectsFinal(session); 1310 if (rv != CKR_OK) { 1311 error("C_FindObjectsFinal failed: %lu", rv); 1312 ret = -1; 1313 } 1314 1315 return (ret); 1316 } 1317 1318 #ifdef WITH_PKCS11_KEYGEN 1319 #define FILL_ATTR(attr, idx, typ, val, len) \ 1320 { (attr[idx]).type=(typ); (attr[idx]).pValue=(val); (attr[idx]).ulValueLen=len; idx++; } 1321 1322 static struct sshkey * 1323 pkcs11_rsa_generate_private_key(struct pkcs11_provider *p, CK_ULONG slotidx, 1324 char *label, CK_ULONG bits, CK_BYTE keyid, u_int32_t *err) 1325 { 1326 struct pkcs11_slotinfo *si; 1327 char *plabel = label ? label : ""; 1328 int npub = 0, npriv = 0; 1329 CK_RV rv; 1330 CK_FUNCTION_LIST *f; 1331 CK_SESSION_HANDLE session; 1332 CK_BBOOL true_val = CK_TRUE, false_val = CK_FALSE; 1333 CK_OBJECT_HANDLE pubKey, privKey; 1334 CK_ATTRIBUTE tpub[16], tpriv[16]; 1335 CK_MECHANISM mech = { 1336 CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0 1337 }; 1338 CK_BYTE pubExponent[] = { 1339 0x01, 0x00, 0x01 /* RSA_F4 in bytes */ 1340 }; 1341 pubkey_filter[0].pValue = &pubkey_class; 1342 cert_filter[0].pValue = &cert_class; 1343 1344 *err = 0; 1345 1346 FILL_ATTR(tpub, npub, CKA_TOKEN, &true_val, sizeof(true_val)); 1347 FILL_ATTR(tpub, npub, CKA_LABEL, plabel, strlen(plabel)); 1348 FILL_ATTR(tpub, npub, CKA_ENCRYPT, &false_val, sizeof(false_val)); 1349 FILL_ATTR(tpub, npub, CKA_VERIFY, &true_val, sizeof(true_val)); 1350 FILL_ATTR(tpub, npub, CKA_VERIFY_RECOVER, &false_val, 1351 sizeof(false_val)); 1352 FILL_ATTR(tpub, npub, CKA_WRAP, &false_val, sizeof(false_val)); 1353 FILL_ATTR(tpub, npub, CKA_DERIVE, &false_val, sizeof(false_val)); 1354 FILL_ATTR(tpub, npub, CKA_MODULUS_BITS, &bits, sizeof(bits)); 1355 FILL_ATTR(tpub, npub, CKA_PUBLIC_EXPONENT, pubExponent, 1356 sizeof(pubExponent)); 1357 FILL_ATTR(tpub, npub, CKA_ID, &keyid, sizeof(keyid)); 1358 1359 FILL_ATTR(tpriv, npriv, CKA_TOKEN, &true_val, sizeof(true_val)); 1360 FILL_ATTR(tpriv, npriv, CKA_LABEL, plabel, strlen(plabel)); 1361 FILL_ATTR(tpriv, npriv, CKA_PRIVATE, &true_val, sizeof(true_val)); 1362 FILL_ATTR(tpriv, npriv, CKA_SENSITIVE, &true_val, sizeof(true_val)); 1363 FILL_ATTR(tpriv, npriv, CKA_DECRYPT, &false_val, sizeof(false_val)); 1364 FILL_ATTR(tpriv, npriv, CKA_SIGN, &true_val, sizeof(true_val)); 1365 FILL_ATTR(tpriv, npriv, CKA_SIGN_RECOVER, &false_val, 1366 sizeof(false_val)); 1367 FILL_ATTR(tpriv, npriv, CKA_UNWRAP, &false_val, sizeof(false_val)); 1368 FILL_ATTR(tpriv, npriv, CKA_DERIVE, &false_val, sizeof(false_val)); 1369 FILL_ATTR(tpriv, npriv, CKA_ID, &keyid, sizeof(keyid)); 1370 1371 f = p->function_list; 1372 si = &p->slotinfo[slotidx]; 1373 session = si->session; 1374 1375 if ((rv = f->C_GenerateKeyPair(session, &mech, tpub, npub, tpriv, npriv, 1376 &pubKey, &privKey)) != CKR_OK) { 1377 error_f("key generation failed: error 0x%lx", rv); 1378 *err = rv; 1379 return NULL; 1380 } 1381 1382 return pkcs11_fetch_rsa_pubkey(p, slotidx, &pubKey); 1383 } 1384 1385 static int 1386 pkcs11_decode_hex(const char *hex, unsigned char **dest, size_t *rlen) 1387 { 1388 size_t i, len; 1389 char ptr[3]; 1390 1391 if (dest) 1392 *dest = NULL; 1393 if (rlen) 1394 *rlen = 0; 1395 1396 if ((len = strlen(hex)) % 2) 1397 return -1; 1398 len /= 2; 1399 1400 *dest = xmalloc(len); 1401 1402 ptr[2] = '\0'; 1403 for (i = 0; i < len; i++) { 1404 ptr[0] = hex[2 * i]; 1405 ptr[1] = hex[(2 * i) + 1]; 1406 if (!isxdigit(ptr[0]) || !isxdigit(ptr[1])) 1407 return -1; 1408 (*dest)[i] = (unsigned char)strtoul(ptr, NULL, 16); 1409 } 1410 1411 if (rlen) 1412 *rlen = len; 1413 1414 return 0; 1415 } 1416 1417 static struct ec_curve_info { 1418 const char *name; 1419 const char *oid; 1420 const char *oid_encoded; 1421 size_t size; 1422 } ec_curve_infos[] = { 1423 {"prime256v1", "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256}, 1424 {"secp384r1", "1.3.132.0.34", "06052B81040022", 384}, 1425 {"secp521r1", "1.3.132.0.35", "06052B81040023", 521}, 1426 {NULL, NULL, NULL, 0}, 1427 }; 1428 1429 static struct sshkey * 1430 pkcs11_ecdsa_generate_private_key(struct pkcs11_provider *p, CK_ULONG slotidx, 1431 char *label, CK_ULONG bits, CK_BYTE keyid, u_int32_t *err) 1432 { 1433 struct pkcs11_slotinfo *si; 1434 char *plabel = label ? label : ""; 1435 int i; 1436 size_t ecparams_size; 1437 unsigned char *ecparams = NULL; 1438 int npub = 0, npriv = 0; 1439 CK_RV rv; 1440 CK_FUNCTION_LIST *f; 1441 CK_SESSION_HANDLE session; 1442 CK_BBOOL true_val = CK_TRUE, false_val = CK_FALSE; 1443 CK_OBJECT_HANDLE pubKey, privKey; 1444 CK_MECHANISM mech = { 1445 CKM_EC_KEY_PAIR_GEN, NULL_PTR, 0 1446 }; 1447 CK_ATTRIBUTE tpub[16], tpriv[16]; 1448 1449 *err = 0; 1450 1451 for (i = 0; ec_curve_infos[i].name; i++) { 1452 if (ec_curve_infos[i].size == bits) 1453 break; 1454 } 1455 if (!ec_curve_infos[i].name) { 1456 error_f("invalid key size %lu", bits); 1457 return NULL; 1458 } 1459 if (pkcs11_decode_hex(ec_curve_infos[i].oid_encoded, &ecparams, 1460 &ecparams_size) == -1) { 1461 error_f("invalid oid"); 1462 return NULL; 1463 } 1464 1465 FILL_ATTR(tpub, npub, CKA_TOKEN, &true_val, sizeof(true_val)); 1466 FILL_ATTR(tpub, npub, CKA_LABEL, plabel, strlen(plabel)); 1467 FILL_ATTR(tpub, npub, CKA_ENCRYPT, &false_val, sizeof(false_val)); 1468 FILL_ATTR(tpub, npub, CKA_VERIFY, &true_val, sizeof(true_val)); 1469 FILL_ATTR(tpub, npub, CKA_VERIFY_RECOVER, &false_val, 1470 sizeof(false_val)); 1471 FILL_ATTR(tpub, npub, CKA_WRAP, &false_val, sizeof(false_val)); 1472 FILL_ATTR(tpub, npub, CKA_DERIVE, &false_val, sizeof(false_val)); 1473 FILL_ATTR(tpub, npub, CKA_EC_PARAMS, ecparams, ecparams_size); 1474 FILL_ATTR(tpub, npub, CKA_ID, &keyid, sizeof(keyid)); 1475 1476 FILL_ATTR(tpriv, npriv, CKA_TOKEN, &true_val, sizeof(true_val)); 1477 FILL_ATTR(tpriv, npriv, CKA_LABEL, plabel, strlen(plabel)); 1478 FILL_ATTR(tpriv, npriv, CKA_PRIVATE, &true_val, sizeof(true_val)); 1479 FILL_ATTR(tpriv, npriv, CKA_SENSITIVE, &true_val, sizeof(true_val)); 1480 FILL_ATTR(tpriv, npriv, CKA_DECRYPT, &false_val, sizeof(false_val)); 1481 FILL_ATTR(tpriv, npriv, CKA_SIGN, &true_val, sizeof(true_val)); 1482 FILL_ATTR(tpriv, npriv, CKA_SIGN_RECOVER, &false_val, 1483 sizeof(false_val)); 1484 FILL_ATTR(tpriv, npriv, CKA_UNWRAP, &false_val, sizeof(false_val)); 1485 FILL_ATTR(tpriv, npriv, CKA_DERIVE, &false_val, sizeof(false_val)); 1486 FILL_ATTR(tpriv, npriv, CKA_ID, &keyid, sizeof(keyid)); 1487 1488 f = p->function_list; 1489 si = &p->slotinfo[slotidx]; 1490 session = si->session; 1491 1492 if ((rv = f->C_GenerateKeyPair(session, &mech, tpub, npub, tpriv, npriv, 1493 &pubKey, &privKey)) != CKR_OK) { 1494 error_f("key generation failed: error 0x%lx", rv); 1495 *err = rv; 1496 return NULL; 1497 } 1498 1499 return pkcs11_fetch_ecdsa_pubkey(p, slotidx, &pubKey); 1500 } 1501 #endif /* WITH_PKCS11_KEYGEN */ 1502 1503 /* 1504 * register a new provider, fails if provider already exists. if 1505 * keyp is provided, fetch keys. 1506 */ 1507 static int 1508 pkcs11_register_provider(char *provider_id, char *pin, 1509 struct sshkey ***keyp, char ***labelsp, 1510 struct pkcs11_provider **providerp, CK_ULONG user) 1511 { 1512 int nkeys, need_finalize = 0; 1513 int ret = -1; 1514 struct pkcs11_provider *p = NULL; 1515 void *handle = NULL; 1516 CK_RV (*getfunctionlist)(CK_FUNCTION_LIST **); 1517 CK_RV rv; 1518 CK_FUNCTION_LIST *f = NULL; 1519 CK_TOKEN_INFO *token; 1520 CK_ULONG i; 1521 1522 if (providerp == NULL) 1523 goto fail; 1524 *providerp = NULL; 1525 1526 if (keyp != NULL) 1527 *keyp = NULL; 1528 if (labelsp != NULL) 1529 *labelsp = NULL; 1530 1531 if (pkcs11_provider_lookup(provider_id) != NULL) { 1532 debug_f("provider already registered: %s", provider_id); 1533 goto fail; 1534 } 1535 /* open shared pkcs11-library */ 1536 if ((handle = dlopen(provider_id, RTLD_NOW)) == NULL) { 1537 error("dlopen %s failed: %s", provider_id, dlerror()); 1538 goto fail; 1539 } 1540 if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) { 1541 error("dlsym(C_GetFunctionList) failed: %s", dlerror()); 1542 goto fail; 1543 } 1544 p = xcalloc(1, sizeof(*p)); 1545 p->name = xstrdup(provider_id); 1546 p->handle = handle; 1547 /* setup the pkcs11 callbacks */ 1548 if ((rv = (*getfunctionlist)(&f)) != CKR_OK) { 1549 error("C_GetFunctionList for provider %s failed: %lu", 1550 provider_id, rv); 1551 goto fail; 1552 } 1553 p->function_list = f; 1554 if ((rv = f->C_Initialize(NULL)) != CKR_OK) { 1555 error("C_Initialize for provider %s failed: %lu", 1556 provider_id, rv); 1557 goto fail; 1558 } 1559 need_finalize = 1; 1560 if ((rv = f->C_GetInfo(&p->info)) != CKR_OK) { 1561 error("C_GetInfo for provider %s failed: %lu", 1562 provider_id, rv); 1563 goto fail; 1564 } 1565 rmspace(p->info.manufacturerID, sizeof(p->info.manufacturerID)); 1566 rmspace(p->info.libraryDescription, sizeof(p->info.libraryDescription)); 1567 debug("provider %s: manufacturerID <%s> cryptokiVersion %d.%d" 1568 " libraryDescription <%s> libraryVersion %d.%d", 1569 provider_id, 1570 p->info.manufacturerID, 1571 p->info.cryptokiVersion.major, 1572 p->info.cryptokiVersion.minor, 1573 p->info.libraryDescription, 1574 p->info.libraryVersion.major, 1575 p->info.libraryVersion.minor); 1576 if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &p->nslots)) != CKR_OK) { 1577 error("C_GetSlotList failed: %lu", rv); 1578 goto fail; 1579 } 1580 if (p->nslots == 0) { 1581 debug_f("provider %s returned no slots", provider_id); 1582 ret = -SSH_PKCS11_ERR_NO_SLOTS; 1583 goto fail; 1584 } 1585 p->slotlist = xcalloc(p->nslots, sizeof(CK_SLOT_ID)); 1586 if ((rv = f->C_GetSlotList(CK_TRUE, p->slotlist, &p->nslots)) 1587 != CKR_OK) { 1588 error("C_GetSlotList for provider %s failed: %lu", 1589 provider_id, rv); 1590 goto fail; 1591 } 1592 p->slotinfo = xcalloc(p->nslots, sizeof(struct pkcs11_slotinfo)); 1593 p->valid = 1; 1594 nkeys = 0; 1595 for (i = 0; i < p->nslots; i++) { 1596 token = &p->slotinfo[i].token; 1597 if ((rv = f->C_GetTokenInfo(p->slotlist[i], token)) 1598 != CKR_OK) { 1599 error("C_GetTokenInfo for provider %s slot %lu " 1600 "failed: %lu", provider_id, (u_long)i, rv); 1601 continue; 1602 } 1603 if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) { 1604 debug2_f("ignoring uninitialised token in " 1605 "provider %s slot %lu", provider_id, (u_long)i); 1606 continue; 1607 } 1608 rmspace(token->label, sizeof(token->label)); 1609 rmspace(token->manufacturerID, sizeof(token->manufacturerID)); 1610 rmspace(token->model, sizeof(token->model)); 1611 rmspace(token->serialNumber, sizeof(token->serialNumber)); 1612 debug("provider %s slot %lu: label <%s> manufacturerID <%s> " 1613 "model <%s> serial <%s> flags 0x%lx", 1614 provider_id, (unsigned long)i, 1615 token->label, token->manufacturerID, token->model, 1616 token->serialNumber, token->flags); 1617 /* 1618 * open session, login with pin and retrieve public 1619 * keys (if keyp is provided) 1620 */ 1621 if ((ret = pkcs11_open_session(p, i, pin, user)) != 0 || 1622 keyp == NULL) 1623 continue; 1624 pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); 1625 pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); 1626 if (nkeys == 0 && !p->slotinfo[i].logged_in && 1627 pkcs11_interactive) { 1628 /* 1629 * Some tokens require login before they will 1630 * expose keys. 1631 */ 1632 if (pkcs11_login_slot(p, &p->slotinfo[i], 1633 CKU_USER) < 0) { 1634 error("login failed"); 1635 continue; 1636 } 1637 pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); 1638 pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); 1639 } 1640 } 1641 1642 /* now owned by caller */ 1643 *providerp = p; 1644 1645 TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); 1646 p->refcount++; /* add to provider list */ 1647 1648 return (nkeys); 1649 fail: 1650 if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) 1651 error("C_Finalize for provider %s failed: %lu", 1652 provider_id, rv); 1653 if (p) { 1654 free(p->name); 1655 free(p->slotlist); 1656 free(p->slotinfo); 1657 free(p); 1658 } 1659 if (handle) 1660 dlclose(handle); 1661 if (ret > 0) 1662 ret = -1; 1663 return (ret); 1664 } 1665 1666 /* 1667 * register a new provider and get number of keys hold by the token, 1668 * fails if provider already exists 1669 */ 1670 int 1671 pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp, 1672 char ***labelsp) 1673 { 1674 struct pkcs11_provider *p = NULL; 1675 int nkeys; 1676 1677 nkeys = pkcs11_register_provider(provider_id, pin, keyp, labelsp, 1678 &p, CKU_USER); 1679 1680 /* no keys found or some other error, de-register provider */ 1681 if (nkeys <= 0 && p != NULL) { 1682 TAILQ_REMOVE(&pkcs11_providers, p, next); 1683 pkcs11_provider_finalize(p); 1684 pkcs11_provider_unref(p); 1685 } 1686 if (nkeys == 0) 1687 debug_f("provider %s returned no keys", provider_id); 1688 1689 return (nkeys); 1690 } 1691 1692 #ifdef WITH_PKCS11_KEYGEN 1693 struct sshkey * 1694 pkcs11_gakp(char *provider_id, char *pin, unsigned int slotidx, char *label, 1695 unsigned int type, unsigned int bits, unsigned char keyid, u_int32_t *err) 1696 { 1697 struct pkcs11_provider *p = NULL; 1698 struct pkcs11_slotinfo *si; 1699 CK_FUNCTION_LIST *f; 1700 CK_SESSION_HANDLE session; 1701 struct sshkey *k = NULL; 1702 int ret = -1, reset_pin = 0, reset_provider = 0; 1703 CK_RV rv; 1704 1705 *err = 0; 1706 1707 if ((p = pkcs11_provider_lookup(provider_id)) != NULL) 1708 debug_f("provider \"%s\" available", provider_id); 1709 else if ((ret = pkcs11_register_provider(provider_id, pin, NULL, NULL, 1710 &p, CKU_SO)) < 0) { 1711 debug_f("could not register provider %s", provider_id); 1712 goto out; 1713 } else 1714 reset_provider = 1; 1715 1716 f = p->function_list; 1717 si = &p->slotinfo[slotidx]; 1718 session = si->session; 1719 1720 if ((rv = f->C_SetOperationState(session , pin, strlen(pin), 1721 CK_INVALID_HANDLE, CK_INVALID_HANDLE)) != CKR_OK) { 1722 debug_f("could not supply SO pin: %lu", rv); 1723 reset_pin = 0; 1724 } else 1725 reset_pin = 1; 1726 1727 switch (type) { 1728 case KEY_RSA: 1729 if ((k = pkcs11_rsa_generate_private_key(p, slotidx, label, 1730 bits, keyid, err)) == NULL) { 1731 debug_f("failed to generate RSA key"); 1732 goto out; 1733 } 1734 break; 1735 case KEY_ECDSA: 1736 if ((k = pkcs11_ecdsa_generate_private_key(p, slotidx, label, 1737 bits, keyid, err)) == NULL) { 1738 debug_f("failed to generate ECDSA key"); 1739 goto out; 1740 } 1741 break; 1742 default: 1743 *err = SSH_PKCS11_ERR_GENERIC; 1744 debug_f("unknown type %d", type); 1745 goto out; 1746 } 1747 1748 out: 1749 if (reset_pin) 1750 f->C_SetOperationState(session , NULL, 0, CK_INVALID_HANDLE, 1751 CK_INVALID_HANDLE); 1752 1753 if (reset_provider) 1754 pkcs11_del_provider(provider_id); 1755 1756 return (k); 1757 } 1758 1759 struct sshkey * 1760 pkcs11_destroy_keypair(char *provider_id, char *pin, unsigned long slotidx, 1761 unsigned char keyid, u_int32_t *err) 1762 { 1763 struct pkcs11_provider *p = NULL; 1764 struct pkcs11_slotinfo *si; 1765 struct sshkey *k = NULL; 1766 int reset_pin = 0, reset_provider = 0; 1767 CK_ULONG nattrs; 1768 CK_FUNCTION_LIST *f; 1769 CK_SESSION_HANDLE session; 1770 CK_ATTRIBUTE attrs[16]; 1771 CK_OBJECT_CLASS key_class; 1772 CK_KEY_TYPE key_type; 1773 CK_OBJECT_HANDLE obj = CK_INVALID_HANDLE; 1774 CK_RV rv; 1775 1776 *err = 0; 1777 1778 if ((p = pkcs11_provider_lookup(provider_id)) != NULL) { 1779 debug_f("using provider \"%s\"", provider_id); 1780 } else if (pkcs11_register_provider(provider_id, pin, NULL, NULL, &p, 1781 CKU_SO) < 0) { 1782 debug_f("could not register provider %s", 1783 provider_id); 1784 goto out; 1785 } else 1786 reset_provider = 1; 1787 1788 f = p->function_list; 1789 si = &p->slotinfo[slotidx]; 1790 session = si->session; 1791 1792 if ((rv = f->C_SetOperationState(session , pin, strlen(pin), 1793 CK_INVALID_HANDLE, CK_INVALID_HANDLE)) != CKR_OK) { 1794 debug_f("could not supply SO pin: %lu", rv); 1795 reset_pin = 0; 1796 } else 1797 reset_pin = 1; 1798 1799 /* private key */ 1800 nattrs = 0; 1801 key_class = CKO_PRIVATE_KEY; 1802 FILL_ATTR(attrs, nattrs, CKA_CLASS, &key_class, sizeof(key_class)); 1803 FILL_ATTR(attrs, nattrs, CKA_ID, &keyid, sizeof(keyid)); 1804 1805 if (pkcs11_find(p, slotidx, attrs, nattrs, &obj) == 0 && 1806 obj != CK_INVALID_HANDLE) { 1807 if ((rv = f->C_DestroyObject(session, obj)) != CKR_OK) { 1808 debug_f("could not destroy private key 0x%hhx", 1809 keyid); 1810 *err = rv; 1811 goto out; 1812 } 1813 } 1814 1815 /* public key */ 1816 nattrs = 0; 1817 key_class = CKO_PUBLIC_KEY; 1818 FILL_ATTR(attrs, nattrs, CKA_CLASS, &key_class, sizeof(key_class)); 1819 FILL_ATTR(attrs, nattrs, CKA_ID, &keyid, sizeof(keyid)); 1820 1821 if (pkcs11_find(p, slotidx, attrs, nattrs, &obj) == 0 && 1822 obj != CK_INVALID_HANDLE) { 1823 1824 /* get key type */ 1825 nattrs = 0; 1826 FILL_ATTR(attrs, nattrs, CKA_KEY_TYPE, &key_type, 1827 sizeof(key_type)); 1828 rv = f->C_GetAttributeValue(session, obj, attrs, nattrs); 1829 if (rv != CKR_OK) { 1830 debug_f("could not get key type of public key 0x%hhx", 1831 keyid); 1832 *err = rv; 1833 key_type = -1; 1834 } 1835 if (key_type == CKK_RSA) 1836 k = pkcs11_fetch_rsa_pubkey(p, slotidx, &obj); 1837 else if (key_type == CKK_ECDSA) 1838 k = pkcs11_fetch_ecdsa_pubkey(p, slotidx, &obj); 1839 1840 if ((rv = f->C_DestroyObject(session, obj)) != CKR_OK) { 1841 debug_f("could not destroy public key 0x%hhx", keyid); 1842 *err = rv; 1843 goto out; 1844 } 1845 } 1846 1847 out: 1848 if (reset_pin) 1849 f->C_SetOperationState(session , NULL, 0, CK_INVALID_HANDLE, 1850 CK_INVALID_HANDLE); 1851 1852 if (reset_provider) 1853 pkcs11_del_provider(provider_id); 1854 1855 return (k); 1856 } 1857 #endif /* WITH_PKCS11_KEYGEN */ 1858 #else /* ENABLE_PKCS11 */ 1859 1860 #include <sys/types.h> 1861 #include <stdarg.h> 1862 #include <stdio.h> 1863 1864 #include "log.h" 1865 #include "sshkey.h" 1866 1867 int 1868 pkcs11_init(int interactive) 1869 { 1870 error("%s: dlopen() not supported", __func__); 1871 return (-1); 1872 } 1873 1874 int 1875 pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp, 1876 char ***labelsp) 1877 { 1878 error("%s: dlopen() not supported", __func__); 1879 return (-1); 1880 } 1881 1882 void 1883 pkcs11_terminate(void) 1884 { 1885 error("%s: dlopen() not supported", __func__); 1886 } 1887 #endif /* ENABLE_PKCS11 */ 1888