|
Lines 32-37
Link Here
|
| 32 |
#include "openbsd-compat/sys-queue.h" |
32 |
#include "openbsd-compat/sys-queue.h" |
| 33 |
|
33 |
|
| 34 |
#include <openssl/x509.h> |
34 |
#include <openssl/x509.h> |
|
|
35 |
#include <openssl/rsa.h> |
| 36 |
#ifdef OPENSSL_HAS_ECC |
| 37 |
#include <openssl/ecdsa.h> |
| 38 |
#if ((defined(LIBRESSL_VERSION_NUMBER) && \ |
| 39 |
(LIBRESSL_VERSION_NUMBER >= 0x20010002L))) || \ |
| 40 |
(defined(ECDSA_F_ECDSA_METHOD_NEW)) |
| 41 |
#define ENABLE_PKCS11_ECDSA 1 |
| 42 |
#endif |
| 43 |
#endif |
| 35 |
|
44 |
|
| 36 |
#define CRYPTOKI_COMPAT |
45 |
#define CRYPTOKI_COMPAT |
| 37 |
#include "pkcs11.h" |
46 |
#include "pkcs11.h" |
|
Lines 66-71
Link Here
|
| 66 |
struct pkcs11_key { |
75 |
struct pkcs11_key { |
| 67 |
struct pkcs11_provider *provider; |
76 |
struct pkcs11_provider *provider; |
| 68 |
CK_ULONG slotidx; |
77 |
CK_ULONG slotidx; |
|
|
78 |
CK_ULONG key_type; |
| 69 |
int (*orig_finish)(RSA *rsa); |
79 |
int (*orig_finish)(RSA *rsa); |
| 70 |
RSA_METHOD rsa_method; |
80 |
RSA_METHOD rsa_method; |
| 71 |
char *keyid; |
81 |
char *keyid; |
|
Lines 73-78
Link Here
|
| 73 |
}; |
83 |
}; |
| 74 |
|
84 |
|
| 75 |
int pkcs11_interactive = 0; |
85 |
int pkcs11_interactive = 0; |
|
|
86 |
#ifdef ENABLE_PKCS11_ECDSA |
| 87 |
static int pkcs11_key_idx = -1; |
| 88 |
#endif /* ENABLE_PKCS11_ECDSA */ |
| 76 |
|
89 |
|
| 77 |
int |
90 |
int |
| 78 |
pkcs11_init(int interactive) |
91 |
pkcs11_init(int interactive) |
|
Lines 216-221
Link Here
|
| 216 |
return (ret); |
229 |
return (ret); |
| 217 |
} |
230 |
} |
| 218 |
|
231 |
|
|
|
232 |
int pkcs11_login(struct pkcs11_key *k11, CK_FUNCTION_LIST *f, struct pkcs11_slotinfo *si) { |
| 233 |
char *pin = NULL, prompt[1024]; |
| 234 |
CK_RV rv; |
| 235 |
if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) { |
| 236 |
if (!pkcs11_interactive) { |
| 237 |
error("need pin entry%s", (si->token.flags & |
| 238 |
CKF_PROTECTED_AUTHENTICATION_PATH) ? |
| 239 |
" on reader keypad" : ""); |
| 240 |
return (-1); |
| 241 |
} |
| 242 |
if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH) |
| 243 |
verbose("Deferring PIN entry to reader keypad."); |
| 244 |
else { |
| 245 |
snprintf(prompt, sizeof(prompt), |
| 246 |
"Enter PIN for '%s': ", si->token.label); |
| 247 |
pin = read_passphrase(prompt, RP_ALLOW_EOF); |
| 248 |
if (pin == NULL) |
| 249 |
return (-1); /* bail out */ |
| 250 |
} |
| 251 |
rv = f->C_Login(si->session, CKU_USER, (u_char *)pin, |
| 252 |
(pin != NULL) ? strlen(pin) : 0); |
| 253 |
if (pin != NULL) { |
| 254 |
explicit_bzero(pin, strlen(pin)); |
| 255 |
free(pin); |
| 256 |
} |
| 257 |
if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) { |
| 258 |
error("C_Login failed: %lu", rv); |
| 259 |
return (-1); |
| 260 |
} |
| 261 |
si->logged_in = 1; |
| 262 |
} |
| 263 |
return 0; |
| 264 |
} |
| 265 |
|
| 219 |
/* openssl callback doing the actual signing operation */ |
266 |
/* openssl callback doing the actual signing operation */ |
| 220 |
static int |
267 |
static int |
| 221 |
pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, |
268 |
pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, |
|
Lines 237-243
Link Here
|
| 237 |
{CKA_ID, NULL, 0}, |
284 |
{CKA_ID, NULL, 0}, |
| 238 |
{CKA_SIGN, NULL, sizeof(true_val) } |
285 |
{CKA_SIGN, NULL, sizeof(true_val) } |
| 239 |
}; |
286 |
}; |
| 240 |
char *pin = NULL, prompt[1024]; |
|
|
| 241 |
int rval = -1; |
287 |
int rval = -1; |
| 242 |
|
288 |
|
| 243 |
key_filter[0].pValue = &private_key_class; |
289 |
key_filter[0].pValue = &private_key_class; |
|
Lines 253-285
Link Here
|
| 253 |
} |
299 |
} |
| 254 |
f = k11->provider->function_list; |
300 |
f = k11->provider->function_list; |
| 255 |
si = &k11->provider->slotinfo[k11->slotidx]; |
301 |
si = &k11->provider->slotinfo[k11->slotidx]; |
| 256 |
if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) { |
302 |
if(pkcs11_login(k11, f, si)) { |
| 257 |
if (!pkcs11_interactive) { |
303 |
return (-1); |
| 258 |
error("need pin entry%s", (si->token.flags & |
|
|
| 259 |
CKF_PROTECTED_AUTHENTICATION_PATH) ? |
| 260 |
" on reader keypad" : ""); |
| 261 |
return (-1); |
| 262 |
} |
| 263 |
if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH) |
| 264 |
verbose("Deferring PIN entry to reader keypad."); |
| 265 |
else { |
| 266 |
snprintf(prompt, sizeof(prompt), |
| 267 |
"Enter PIN for '%s': ", si->token.label); |
| 268 |
pin = read_passphrase(prompt, RP_ALLOW_EOF); |
| 269 |
if (pin == NULL) |
| 270 |
return (-1); /* bail out */ |
| 271 |
} |
| 272 |
rv = f->C_Login(si->session, CKU_USER, (u_char *)pin, |
| 273 |
(pin != NULL) ? strlen(pin) : 0); |
| 274 |
if (pin != NULL) { |
| 275 |
explicit_bzero(pin, strlen(pin)); |
| 276 |
free(pin); |
| 277 |
} |
| 278 |
if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) { |
| 279 |
error("C_Login failed: %lu", rv); |
| 280 |
return (-1); |
| 281 |
} |
| 282 |
si->logged_in = 1; |
| 283 |
} |
304 |
} |
| 284 |
key_filter[1].pValue = k11->keyid; |
305 |
key_filter[1].pValue = k11->keyid; |
| 285 |
key_filter[1].ulValueLen = k11->keyid_len; |
306 |
key_filter[1].ulValueLen = k11->keyid_len; |
|
Lines 317-322
Link Here
|
| 317 |
const RSA_METHOD *def = RSA_get_default_method(); |
338 |
const RSA_METHOD *def = RSA_get_default_method(); |
| 318 |
|
339 |
|
| 319 |
k11 = xcalloc(1, sizeof(*k11)); |
340 |
k11 = xcalloc(1, sizeof(*k11)); |
|
|
341 |
k11->key_type = CKK_RSA; |
| 320 |
k11->provider = provider; |
342 |
k11->provider = provider; |
| 321 |
provider->refcount++; /* provider referenced by RSA key */ |
343 |
provider->refcount++; /* provider referenced by RSA key */ |
| 322 |
k11->slotidx = slotidx; |
344 |
k11->slotidx = slotidx; |
|
Lines 337-342
Link Here
|
| 337 |
return (0); |
359 |
return (0); |
| 338 |
} |
360 |
} |
| 339 |
|
361 |
|
|
|
362 |
#ifdef ENABLE_PKCS11_ECDSA |
| 363 |
static ECDSA_SIG *pkcs11_ecdsa_sign(const unsigned char *dgst, int dgst_len, |
| 364 |
const BIGNUM *inv, const BIGNUM *rp, |
| 365 |
EC_KEY *ecdsa) { |
| 366 |
struct pkcs11_key *k11; |
| 367 |
struct pkcs11_slotinfo *si; |
| 368 |
CK_FUNCTION_LIST *f; |
| 369 |
CK_OBJECT_HANDLE obj; |
| 370 |
CK_ULONG tlen = 0; |
| 371 |
CK_RV rv; |
| 372 |
CK_OBJECT_CLASS private_key_class = CKO_PRIVATE_KEY; |
| 373 |
CK_BBOOL true_val = CK_TRUE; |
| 374 |
CK_MECHANISM mech = { |
| 375 |
CKM_ECDSA, NULL_PTR, 0 |
| 376 |
}; |
| 377 |
CK_ATTRIBUTE key_filter[] = { |
| 378 |
{CKA_CLASS, NULL, sizeof(private_key_class) }, |
| 379 |
{CKA_ID, NULL, 0}, |
| 380 |
{CKA_SIGN, NULL, sizeof(true_val) } |
| 381 |
}; |
| 382 |
ECDSA_SIG *rval = NULL; |
| 383 |
key_filter[0].pValue = &private_key_class; |
| 384 |
key_filter[2].pValue = &true_val; |
| 385 |
|
| 386 |
if ((k11 = (struct pkcs11_key *)ECDSA_get_ex_data(ecdsa, pkcs11_key_idx)) == NULL) { |
| 387 |
error("ECDSA_get_ex_data failed for ecdsa %p", ecdsa); |
| 388 |
return NULL; |
| 389 |
} |
| 390 |
if (!k11->provider || !k11->provider->valid) { |
| 391 |
error("no pkcs11 (valid) provider for ecdsa %p", ecdsa); |
| 392 |
return NULL; |
| 393 |
} |
| 394 |
f = k11->provider->function_list; |
| 395 |
si = &k11->provider->slotinfo[k11->slotidx]; |
| 396 |
if(pkcs11_login(k11, f, si)) { |
| 397 |
return NULL; |
| 398 |
} |
| 399 |
key_filter[1].pValue = k11->keyid; |
| 400 |
key_filter[1].ulValueLen = k11->keyid_len; |
| 401 |
/* try to find object w/CKA_SIGN first, retry w/o */ |
| 402 |
if (pkcs11_find(k11->provider, k11->slotidx, key_filter, 3, &obj) < 0 && |
| 403 |
pkcs11_find(k11->provider, k11->slotidx, key_filter, 2, &obj) < 0) { |
| 404 |
error("cannot find private key"); |
| 405 |
} else if ((rv = f->C_SignInit(si->session, &mech, obj)) != CKR_OK) { |
| 406 |
error("C_SignInit failed: %lu", rv); |
| 407 |
} else { |
| 408 |
CK_BYTE_PTR buf = NULL; |
| 409 |
int nlen; |
| 410 |
/* Make a call to C_Sign to find out the size of the signature */ |
| 411 |
rv = f->C_Sign(si->session, (CK_BYTE *)dgst, dgst_len, NULL, &tlen); |
| 412 |
if (rv != CKR_OK) { |
| 413 |
error("C_Sign failed: %lu", rv); |
| 414 |
return NULL; |
| 415 |
} |
| 416 |
if ((buf = xmalloc(tlen)) == NULL) { |
| 417 |
error("failure to allocate signature buffer"); |
| 418 |
return NULL; |
| 419 |
} |
| 420 |
rv = f->C_Sign(si->session, (CK_BYTE *)dgst, dgst_len, buf, &tlen); |
| 421 |
if (rv != CKR_OK) { |
| 422 |
error("C_Sign failed: %lu", rv); |
| 423 |
} |
| 424 |
|
| 425 |
if ((rval = ECDSA_SIG_new()) == NULL) { |
| 426 |
error("failure to allocate ECDSA signature"); |
| 427 |
} else { |
| 428 |
/* |
| 429 |
* ECDSA signature is 2 large integers of same size returned |
| 430 |
* concatenated by PKCS#11, we separate them to create an |
| 431 |
* ECDSA_SIG for OpenSSL. |
| 432 |
*/ |
| 433 |
nlen = tlen / 2; |
| 434 |
BN_bin2bn(&buf[0], nlen, rval->r); |
| 435 |
BN_bin2bn(&buf[nlen], nlen, rval->s); |
| 436 |
} |
| 437 |
free(buf); |
| 438 |
} |
| 439 |
return (rval); |
| 440 |
} |
| 441 |
|
| 442 |
static ECDSA_METHOD *get_pkcs11_ecdsa_method(void) { |
| 443 |
static ECDSA_METHOD *pkcs11_ecdsa_method = NULL; |
| 444 |
if(pkcs11_key_idx == -1) { |
| 445 |
pkcs11_key_idx = ECDSA_get_ex_new_index(0, NULL, NULL, NULL, 0); |
| 446 |
} |
| 447 |
if(pkcs11_ecdsa_method == NULL) { |
| 448 |
const ECDSA_METHOD *def = ECDSA_get_default_method(); |
| 449 |
#ifdef ECDSA_F_ECDSA_METHOD_NEW |
| 450 |
pkcs11_ecdsa_method = ECDSA_METHOD_new((ECDSA_METHOD *)def); |
| 451 |
ECDSA_METHOD_set_name(pkcs11_ecdsa_method, "pkcs11"); |
| 452 |
ECDSA_METHOD_set_sign(pkcs11_ecdsa_method, pkcs11_ecdsa_sign); |
| 453 |
#else |
| 454 |
pkcs11_ecdsa_method = xcalloc(1, sizeof(*pkcs11_ecdsa_method)); |
| 455 |
memcpy(pkcs11_ecdsa_method, def, sizeof(*pkcs11_ecdsa_method)); |
| 456 |
pkcs11_ecdsa_method->name = "pkcs11"; |
| 457 |
pkcs11_ecdsa_method->ecdsa_do_sign = pkcs11_ecdsa_sign; |
| 458 |
#endif |
| 459 |
} |
| 460 |
return pkcs11_ecdsa_method; |
| 461 |
} |
| 462 |
|
| 463 |
static int |
| 464 |
pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, |
| 465 |
CK_ATTRIBUTE *keyid_attrib, EC_KEY *ecdsa) |
| 466 |
{ |
| 467 |
struct pkcs11_key *k11; |
| 468 |
k11 = xcalloc(1, sizeof(*k11)); |
| 469 |
k11->key_type = CKK_EC; |
| 470 |
k11->provider = provider; |
| 471 |
provider->refcount++; /* provider referenced by ECDSA key */ |
| 472 |
k11->slotidx = slotidx; |
| 473 |
/* identify key object on smartcard */ |
| 474 |
k11->keyid_len = keyid_attrib->ulValueLen; |
| 475 |
if (k11->keyid_len > 0) { |
| 476 |
k11->keyid = xmalloc(k11->keyid_len); |
| 477 |
memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); |
| 478 |
} |
| 479 |
ECDSA_set_method(ecdsa, get_pkcs11_ecdsa_method()); |
| 480 |
ECDSA_set_ex_data(ecdsa, pkcs11_key_idx, k11); |
| 481 |
return (0); |
| 482 |
} |
| 483 |
#endif /* ENABLE_PKCS11_ECDSA */ |
| 484 |
|
| 485 |
int pkcs11_del_key(struct sshkey *key) { |
| 486 |
#ifdef ENABLE_PKCS11_ECDSA |
| 487 |
if(key->type == KEY_ECDSA) { |
| 488 |
struct pkcs11_key *k11 = (struct pkcs11_key *) |
| 489 |
ECDSA_get_ex_data(key->ecdsa, pkcs11_key_idx); |
| 490 |
if (k11 == NULL) { |
| 491 |
error("ECDSA_get_ex_data failed for ecdsa %p", key->ecdsa); |
| 492 |
} else { |
| 493 |
if (k11->provider) |
| 494 |
pkcs11_provider_unref(k11->provider); |
| 495 |
free(k11->keyid); |
| 496 |
free(k11); |
| 497 |
} |
| 498 |
} |
| 499 |
#endif /* ENABLE_PKCS11_ECDSA */ |
| 500 |
sshkey_free(key); |
| 501 |
return (0); |
| 502 |
} |
| 503 |
|
| 340 |
/* remove trailing spaces */ |
504 |
/* remove trailing spaces */ |
| 341 |
static void |
505 |
static void |
| 342 |
rmspace(u_char *buf, size_t len) |
506 |
rmspace(u_char *buf, size_t len) |
|
Lines 397-413
Link Here
|
| 397 |
* keysp points to an (possibly empty) array with *nkeys keys. |
561 |
* keysp points to an (possibly empty) array with *nkeys keys. |
| 398 |
*/ |
562 |
*/ |
| 399 |
static int pkcs11_fetch_keys_filter(struct pkcs11_provider *, CK_ULONG, |
563 |
static int pkcs11_fetch_keys_filter(struct pkcs11_provider *, CK_ULONG, |
| 400 |
CK_ATTRIBUTE [], CK_ATTRIBUTE [3], struct sshkey ***, int *) |
564 |
CK_ATTRIBUTE [], int, CK_ATTRIBUTE [3], struct sshkey ***, int *) |
| 401 |
__attribute__((__bounded__(__minbytes__,4, 3 * sizeof(CK_ATTRIBUTE)))); |
565 |
__attribute__((__bounded__(__minbytes__,4, 3 * sizeof(CK_ATTRIBUTE)))); |
| 402 |
|
566 |
|
| 403 |
static int |
567 |
static int |
| 404 |
pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, |
568 |
pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, |
| 405 |
struct sshkey ***keysp, int *nkeys) |
569 |
struct sshkey ***keysp, int *nkeys) |
| 406 |
{ |
570 |
{ |
| 407 |
CK_OBJECT_CLASS pubkey_class = CKO_PUBLIC_KEY; |
571 |
CK_KEY_TYPE pubkey_type = CKK_RSA; |
| 408 |
CK_OBJECT_CLASS cert_class = CKO_CERTIFICATE; |
572 |
CK_OBJECT_CLASS pubkey_class = CKO_PUBLIC_KEY; |
|
|
573 |
CK_OBJECT_CLASS cert_class = CKO_CERTIFICATE; |
| 409 |
CK_ATTRIBUTE pubkey_filter[] = { |
574 |
CK_ATTRIBUTE pubkey_filter[] = { |
| 410 |
{ CKA_CLASS, NULL, sizeof(pubkey_class) } |
575 |
{ CKA_CLASS, NULL, sizeof(pubkey_class) }, |
|
|
576 |
{ CKA_KEY_TYPE, NULL, sizeof(pubkey_type) } |
| 411 |
}; |
577 |
}; |
| 412 |
CK_ATTRIBUTE cert_filter[] = { |
578 |
CK_ATTRIBUTE cert_filter[] = { |
| 413 |
{ CKA_CLASS, NULL, sizeof(cert_class) } |
579 |
{ CKA_CLASS, NULL, sizeof(cert_class) } |
|
Lines 422-433
Link Here
|
| 422 |
{ CKA_SUBJECT, NULL, 0 }, |
588 |
{ CKA_SUBJECT, NULL, 0 }, |
| 423 |
{ CKA_VALUE, NULL, 0 } |
589 |
{ CKA_VALUE, NULL, 0 } |
| 424 |
}; |
590 |
}; |
|
|
591 |
#ifdef ENABLE_PKCS11_ECDSA |
| 592 |
CK_KEY_TYPE ecdsa_type = CKK_EC; |
| 593 |
CK_ATTRIBUTE ecdsa_filter[] = { |
| 594 |
{ CKA_CLASS, NULL, sizeof(pubkey_class) }, |
| 595 |
{ CKA_KEY_TYPE, NULL, sizeof(ecdsa_type) } |
| 596 |
}; |
| 597 |
CK_ATTRIBUTE ecdsa_attribs[] = { |
| 598 |
{ CKA_ID, NULL, 0 }, |
| 599 |
{ CKA_EC_PARAMS, NULL, 0 }, |
| 600 |
{ CKA_EC_POINT, NULL, 0 } |
| 601 |
}; |
| 602 |
ecdsa_filter[0].pValue = &pubkey_class; |
| 603 |
ecdsa_filter[1].pValue = &ecdsa_type; |
| 604 |
#endif /* ENABLE_PKCS11_ECDSA */ |
| 425 |
pubkey_filter[0].pValue = &pubkey_class; |
605 |
pubkey_filter[0].pValue = &pubkey_class; |
|
|
606 |
pubkey_filter[1].pValue = &pubkey_type; |
| 426 |
cert_filter[0].pValue = &cert_class; |
607 |
cert_filter[0].pValue = &cert_class; |
| 427 |
|
608 |
|
| 428 |
if (pkcs11_fetch_keys_filter(p, slotidx, pubkey_filter, pubkey_attribs, |
609 |
if (pkcs11_fetch_keys_filter(p, slotidx, pubkey_filter, 2, pubkey_attribs, |
| 429 |
keysp, nkeys) < 0 || |
610 |
keysp, nkeys) < 0 || |
| 430 |
pkcs11_fetch_keys_filter(p, slotidx, cert_filter, cert_attribs, |
611 |
#ifdef ENABLE_PKCS11_ECDSA |
|
|
612 |
pkcs11_fetch_keys_filter(p, slotidx, ecdsa_filter, 2, ecdsa_attribs, |
| 613 |
keysp, nkeys) < 0|| |
| 614 |
#endif /* ENABLE_PKCS11_ECDSA */ |
| 615 |
pkcs11_fetch_keys_filter(p, slotidx, cert_filter, 1, cert_attribs, |
| 431 |
keysp, nkeys) < 0) |
616 |
keysp, nkeys) < 0) |
| 432 |
return (-1); |
617 |
return (-1); |
| 433 |
return (0); |
618 |
return (0); |
|
Lines 446-456
Link Here
|
| 446 |
|
631 |
|
| 447 |
static int |
632 |
static int |
| 448 |
pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, |
633 |
pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, |
| 449 |
CK_ATTRIBUTE filter[], CK_ATTRIBUTE attribs[3], |
634 |
CK_ATTRIBUTE filter[], int nfilter, CK_ATTRIBUTE attribs[3], |
| 450 |
struct sshkey ***keysp, int *nkeys) |
635 |
struct sshkey ***keysp, int *nkeys) |
| 451 |
{ |
636 |
{ |
| 452 |
struct sshkey *key; |
637 |
struct sshkey *key; |
| 453 |
RSA *rsa; |
638 |
RSA *rsa; |
|
|
639 |
#ifdef ENABLE_PKCS11_ECDSA |
| 640 |
EC_KEY *ecdsa; |
| 641 |
#else |
| 642 |
void *ecdsa; |
| 643 |
#endif /* ENABLE_PKCS11_ECDSA */ |
| 454 |
X509 *x509; |
644 |
X509 *x509; |
| 455 |
EVP_PKEY *evp; |
645 |
EVP_PKEY *evp; |
| 456 |
int i; |
646 |
int i; |
|
Lines 464-470
Link Here
|
| 464 |
f = p->function_list; |
654 |
f = p->function_list; |
| 465 |
session = p->slotinfo[slotidx].session; |
655 |
session = p->slotinfo[slotidx].session; |
| 466 |
/* setup a filter the looks for public keys */ |
656 |
/* setup a filter the looks for public keys */ |
| 467 |
if ((rv = f->C_FindObjectsInit(session, filter, 1)) != CKR_OK) { |
657 |
if ((rv = f->C_FindObjectsInit(session, filter, nfilter)) != CKR_OK) { |
| 468 |
error("C_FindObjectsInit failed: %lu", rv); |
658 |
error("C_FindObjectsInit failed: %lu", rv); |
| 469 |
return (-1); |
659 |
return (-1); |
| 470 |
} |
660 |
} |
|
Lines 505-510
Link Here
|
| 505 |
* or ID, subject and value for certificates. |
695 |
* or ID, subject and value for certificates. |
| 506 |
*/ |
696 |
*/ |
| 507 |
rsa = NULL; |
697 |
rsa = NULL; |
|
|
698 |
#ifdef ENABLE_PKCS11_ECDSA |
| 699 |
ecdsa = NULL; |
| 700 |
#endif /* ENABLE_PKCS11_ECDSA */ |
| 508 |
if ((rv = f->C_GetAttributeValue(session, obj, attribs, 3)) |
701 |
if ((rv = f->C_GetAttributeValue(session, obj, attribs, 3)) |
| 509 |
!= CKR_OK) { |
702 |
!= CKR_OK) { |
| 510 |
error("C_GetAttributeValue failed: %lu", rv); |
703 |
error("C_GetAttributeValue failed: %lu", rv); |
|
Lines 517-522
Link Here
|
| 517 |
rsa->e = BN_bin2bn(attribs[2].pValue, |
710 |
rsa->e = BN_bin2bn(attribs[2].pValue, |
| 518 |
attribs[2].ulValueLen, NULL); |
711 |
attribs[2].ulValueLen, NULL); |
| 519 |
} |
712 |
} |
|
|
713 |
#ifdef ENABLE_PKCS11_ECDSA |
| 714 |
} else if (attribs[1].type == CKA_EC_PARAMS ) { |
| 715 |
if ((ecdsa = EC_KEY_new()) == NULL) { |
| 716 |
error("EC_KEY_new failed"); |
| 717 |
} else { |
| 718 |
const unsigned char *ptr1 = attribs[1].pValue; |
| 719 |
const unsigned char *ptr2 = attribs[2].pValue; |
| 720 |
CK_ULONG len1 = attribs[1].ulValueLen; |
| 721 |
CK_ULONG len2 = attribs[2].ulValueLen; |
| 722 |
ASN1_OCTET_STRING *point = NULL; |
| 723 |
|
| 724 |
/* |
| 725 |
* CKA_EC_PARAMS contains the curve parameters of the key |
| 726 |
* either referenced as an OID or directly with all values. |
| 727 |
* CKA_EC_POINT contains the point (public key) on the curve. |
| 728 |
* The point is should be returned inside a DER-encoded |
| 729 |
* ASN.1 OCTET STRING value (but some implementation). |
| 730 |
*/ |
| 731 |
if ((point = d2i_ASN1_OCTET_STRING(NULL, &ptr2, len2))) { |
| 732 |
/* Pointing to OCTET STRING content */ |
| 733 |
ptr2 = point->data; |
| 734 |
len2 = point->length; |
| 735 |
} else { |
| 736 |
/* No OCTET STRING */ |
| 737 |
ptr2 = attribs[2].pValue; |
| 738 |
} |
| 739 |
|
| 740 |
if((d2i_ECParameters(&ecdsa, &ptr1, len1) == NULL) || |
| 741 |
(o2i_ECPublicKey(&ecdsa, &ptr2, len2) == NULL)) { |
| 742 |
EC_KEY_free(ecdsa); |
| 743 |
ecdsa = NULL; |
| 744 |
error("EC public key parsing failed"); |
| 745 |
} |
| 746 |
|
| 747 |
if(point) { |
| 748 |
M_ASN1_OCTET_STRING_free(point); |
| 749 |
} |
| 750 |
} |
| 751 |
#endif /* ENABLE_PKCS11_ECDSA */ |
| 520 |
} else { |
752 |
} else { |
| 521 |
cp = attribs[2].pValue; |
753 |
cp = attribs[2].pValue; |
| 522 |
if ((x509 = X509_new()) == NULL) { |
754 |
if ((x509 = X509_new()) == NULL) { |
|
Lines 535-547
Link Here
|
| 535 |
if (x509) |
767 |
if (x509) |
| 536 |
X509_free(x509); |
768 |
X509_free(x509); |
| 537 |
} |
769 |
} |
| 538 |
if (rsa && rsa->n && rsa->e && |
770 |
key = NULL; |
| 539 |
pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) { |
771 |
if (rsa || ecdsa) { |
| 540 |
if ((key = sshkey_new(KEY_UNSPEC)) == NULL) |
772 |
if (rsa && rsa->n && rsa->e && |
| 541 |
fatal("sshkey_new failed"); |
773 |
pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) { |
| 542 |
key->rsa = rsa; |
774 |
if ((key = sshkey_new(KEY_UNSPEC)) == NULL) |
| 543 |
key->type = KEY_RSA; |
775 |
fatal("sshkey_new failed"); |
| 544 |
key->flags |= SSHKEY_FLAG_EXT; |
776 |
key->rsa = rsa; |
|
|
777 |
key->type = KEY_RSA; |
| 778 |
key->flags |= SSHKEY_FLAG_EXT; |
| 779 |
#ifdef ENABLE_PKCS11_ECDSA |
| 780 |
} else if(ecdsa && pkcs11_ecdsa_wrap(p, slotidx, &attribs[0], ecdsa) == 0) { |
| 781 |
if ((key = sshkey_new(KEY_UNSPEC)) == NULL) |
| 782 |
fatal("sshkey_new failed"); |
| 783 |
key->ecdsa = ecdsa; |
| 784 |
key->ecdsa_nid = sshkey_ecdsa_key_to_nid(ecdsa); |
| 785 |
key->type = KEY_ECDSA; |
| 786 |
key->flags |= SSHKEY_FLAG_EXT; |
| 787 |
#endif /* ENABLE_PKCS11_ECDSA */ |
| 788 |
} |
| 789 |
} |
| 790 |
|
| 791 |
if(key) { |
| 545 |
if (pkcs11_key_included(keysp, nkeys, key)) { |
792 |
if (pkcs11_key_included(keysp, nkeys, key)) { |
| 546 |
sshkey_free(key); |
793 |
sshkey_free(key); |
| 547 |
} else { |
794 |
} else { |
|
Lines 554-559
Link Here
|
| 554 |
} |
801 |
} |
| 555 |
} else if (rsa) { |
802 |
} else if (rsa) { |
| 556 |
RSA_free(rsa); |
803 |
RSA_free(rsa); |
|
|
804 |
#ifdef ENABLE_PKCS11_ECDSA |
| 805 |
} else if (ecdsa) { |
| 806 |
EC_KEY_free(ecdsa); |
| 807 |
#endif /* ENABLE_PKCS11_ECDSA */ |
| 557 |
} |
808 |
} |
| 558 |
for (i = 0; i < 3; i++) |
809 |
for (i = 0; i < 3; i++) |
| 559 |
free(attribs[i].pValue); |
810 |
free(attribs[i].pValue); |