|
Lines 168-173
pkcs11_del_provider(char *provider_id)
Link Here
|
| 168 |
return (-1); |
168 |
return (-1); |
| 169 |
} |
169 |
} |
| 170 |
|
170 |
|
|
|
171 |
static int |
| 172 |
pkcs11_login(struct pkcs11_provider *p, struct pkcs11_slotinfo *si) { |
| 173 |
CK_FUNCTION_LIST *f; |
| 174 |
CK_RV rv; |
| 175 |
char *pin, prompt[1024]; |
| 176 |
|
| 177 |
f = p->function_list; |
| 178 |
|
| 179 |
if (!pkcs11_interactive) { |
| 180 |
error("need pin"); |
| 181 |
return (-1); |
| 182 |
} |
| 183 |
snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ", |
| 184 |
si->token.label); |
| 185 |
pin = read_passphrase(prompt, RP_ALLOW_EOF); |
| 186 |
if (pin == NULL) |
| 187 |
return (-1); /* bail out */ |
| 188 |
if ((rv = f->C_Login(si->session, CKU_USER, pin, strlen(pin))) |
| 189 |
!= CKR_OK) { |
| 190 |
xfree(pin); |
| 191 |
error("C_Login failed: %lu", rv); |
| 192 |
return (-1); |
| 193 |
} |
| 194 |
xfree(pin); |
| 195 |
si->logged_in = 1; |
| 196 |
|
| 197 |
return 0; |
| 198 |
} |
| 199 |
|
| 171 |
/* openssl callback for freeing an RSA key */ |
200 |
/* openssl callback for freeing an RSA key */ |
| 172 |
static int |
201 |
static int |
| 173 |
pkcs11_rsa_finish(RSA *rsa) |
202 |
pkcs11_rsa_finish(RSA *rsa) |
|
Lines 236-242
pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
Link Here
|
| 236 |
{CKA_ID, NULL, 0}, |
265 |
{CKA_ID, NULL, 0}, |
| 237 |
{CKA_SIGN, NULL, sizeof(true_val) } |
266 |
{CKA_SIGN, NULL, sizeof(true_val) } |
| 238 |
}; |
267 |
}; |
| 239 |
char *pin, prompt[1024]; |
|
|
| 240 |
int rval = -1; |
268 |
int rval = -1; |
| 241 |
|
269 |
|
| 242 |
/* some compilers complain about non-constant initializer so we |
270 |
/* some compilers complain about non-constant initializer so we |
|
Lines 254-277
pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
Link Here
|
| 254 |
} |
282 |
} |
| 255 |
f = k11->provider->function_list; |
283 |
f = k11->provider->function_list; |
| 256 |
si = &k11->provider->slotinfo[k11->slotidx]; |
284 |
si = &k11->provider->slotinfo[k11->slotidx]; |
| 257 |
if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) { |
285 |
if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in && |
| 258 |
if (!pkcs11_interactive) { |
286 |
pkcs11_login(k11->provider, si)) { |
| 259 |
error("need pin"); |
287 |
return (-1); |
| 260 |
return (-1); |
|
|
| 261 |
} |
| 262 |
snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ", |
| 263 |
si->token.label); |
| 264 |
pin = read_passphrase(prompt, RP_ALLOW_EOF); |
| 265 |
if (pin == NULL) |
| 266 |
return (-1); /* bail out */ |
| 267 |
if ((rv = f->C_Login(si->session, CKU_USER, pin, strlen(pin))) |
| 268 |
!= CKR_OK) { |
| 269 |
xfree(pin); |
| 270 |
error("C_Login failed: %lu", rv); |
| 271 |
return (-1); |
| 272 |
} |
| 273 |
xfree(pin); |
| 274 |
si->logged_in = 1; |
| 275 |
} |
288 |
} |
| 276 |
key_filter[1].pValue = k11->keyid; |
289 |
key_filter[1].pValue = k11->keyid; |
| 277 |
key_filter[1].ulValueLen = k11->keyid_len; |
290 |
key_filter[1].ulValueLen = k11->keyid_len; |
|
Lines 327-332
pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx,
Link Here
|
| 327 |
return (0); |
340 |
return (0); |
| 328 |
} |
341 |
} |
| 329 |
|
342 |
|
|
|
343 |
static Key* |
| 344 |
extract_key(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE obj) { |
| 345 |
Key *key; |
| 346 |
RSA *rsa; |
| 347 |
CK_RV rv; |
| 348 |
CK_SESSION_HANDLE session; |
| 349 |
CK_FUNCTION_LIST *f; |
| 350 |
CK_ATTRIBUTE attribs[] = { |
| 351 |
{ CKA_ID, NULL, 0 }, |
| 352 |
{ CKA_MODULUS, NULL, 0 }, |
| 353 |
{ CKA_PUBLIC_EXPONENT, NULL, 0 } |
| 354 |
}; |
| 355 |
int i; |
| 356 |
|
| 357 |
key = NULL; |
| 358 |
|
| 359 |
f = p->function_list; |
| 360 |
session = p->slotinfo[slotidx].session; |
| 361 |
|
| 362 |
/* figure out size of the attributes */ |
| 363 |
if ((rv = f->C_GetAttributeValue(session, obj, attribs, 3)) |
| 364 |
!= CKR_OK) { |
| 365 |
error("C_GetAttributeValue failed: %lu", rv); |
| 366 |
return NULL; |
| 367 |
} |
| 368 |
/* check that none of the attributes are zero length */ |
| 369 |
if (attribs[0].ulValueLen == 0 || |
| 370 |
attribs[1].ulValueLen == 0 || |
| 371 |
attribs[2].ulValueLen == 0) { |
| 372 |
return NULL; |
| 373 |
} |
| 374 |
/* allocate buffers for attributes */ |
| 375 |
for (i = 0; i < 3; i++) |
| 376 |
attribs[i].pValue = xmalloc(attribs[i].ulValueLen); |
| 377 |
/* retrieve ID, modulus and public exponent of RSA key */ |
| 378 |
if ((rv = f->C_GetAttributeValue(session, obj, attribs, 3)) |
| 379 |
!= CKR_OK) { |
| 380 |
error("C_GetAttributeValue failed: %lu", rv); |
| 381 |
} else if ((rsa = RSA_new()) == NULL) { |
| 382 |
error("RSA_new failed"); |
| 383 |
} else { |
| 384 |
rsa->n = BN_bin2bn(attribs[1].pValue, |
| 385 |
attribs[1].ulValueLen, NULL); |
| 386 |
rsa->e = BN_bin2bn(attribs[2].pValue, |
| 387 |
attribs[2].ulValueLen, NULL); |
| 388 |
if (rsa->n && rsa->e && |
| 389 |
pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) { |
| 390 |
key = key_new(KEY_UNSPEC); |
| 391 |
key->rsa = rsa; |
| 392 |
key->type = KEY_RSA; |
| 393 |
key->flags |= KEY_FLAG_EXT; |
| 394 |
} else { |
| 395 |
RSA_free(rsa); |
| 396 |
} |
| 397 |
} |
| 398 |
for (i = 0; i < 3; i++) |
| 399 |
xfree(attribs[i].pValue); |
| 400 |
|
| 401 |
return key; |
| 402 |
} |
| 403 |
|
| 330 |
/* remove trailing spaces */ |
404 |
/* remove trailing spaces */ |
| 331 |
static void |
405 |
static void |
| 332 |
rmspace(char *buf, size_t len) |
406 |
rmspace(char *buf, size_t len) |
|
Lines 380-385
pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin)
Link Here
|
| 380 |
return (0); |
454 |
return (0); |
| 381 |
} |
455 |
} |
| 382 |
|
456 |
|
|
|
457 |
static Key* |
| 458 |
pkcs11_rsa_generate_private_key(struct pkcs11_provider *p, CK_ULONG slotidx, |
| 459 |
char *label, CK_ULONG bits) |
| 460 |
{ |
| 461 |
struct pkcs11_slotinfo *si; |
| 462 |
CK_FUNCTION_LIST *f; |
| 463 |
CK_SESSION_HANDLE session; |
| 464 |
CK_BBOOL true_val = CK_TRUE; |
| 465 |
CK_MECHANISM mech = { |
| 466 |
CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0 |
| 467 |
}; |
| 468 |
CK_BYTE pubExponent[] = { |
| 469 |
0x01, 0x00, 0x01 /* RSA_F4 in bytes */ |
| 470 |
}; |
| 471 |
CK_ATTRIBUTE pubKeyTemplate[] = { |
| 472 |
{CKA_TOKEN, &true_val, sizeof(true_val)}, |
| 473 |
{CKA_LABEL, label, strlen(label)}, |
| 474 |
{CKA_ENCRYPT, &true_val, sizeof(true_val)}, |
| 475 |
{CKA_VERIFY, &true_val, sizeof(true_val)}, |
| 476 |
{CKA_WRAP, &true_val, sizeof(true_val)}, |
| 477 |
{CKA_MODULUS_BITS, &bits, sizeof(bits)}, |
| 478 |
{CKA_PUBLIC_EXPONENT, pubExponent, sizeof(pubExponent)} |
| 479 |
}; |
| 480 |
CK_ATTRIBUTE privKeyTemplate[] = { |
| 481 |
{CKA_TOKEN, &true_val, sizeof(true_val)}, |
| 482 |
{CKA_LABEL, label, strlen(label)}, |
| 483 |
{CKA_PRIVATE, &true_val, sizeof(true_val)}, |
| 484 |
{CKA_SENSITIVE, &true_val, sizeof(true_val)}, |
| 485 |
{CKA_DECRYPT, &true_val, sizeof(true_val)}, |
| 486 |
{CKA_SIGN, &true_val, sizeof(true_val)}, |
| 487 |
{CKA_UNWRAP, &true_val, sizeof(true_val)} |
| 488 |
}; |
| 489 |
CK_ATTRIBUTE modulus[] = { |
| 490 |
{ CKA_MODULUS, NULL, 0 } |
| 491 |
}; |
| 492 |
CK_ATTRIBUTE id[] = { |
| 493 |
{ CKA_ID, NULL, 0 } |
| 494 |
}; |
| 495 |
CK_OBJECT_HANDLE pubKey, privKey; |
| 496 |
CK_RV rv; |
| 497 |
|
| 498 |
f = p->function_list; |
| 499 |
si = &p->slotinfo[slotidx]; |
| 500 |
session = si->session; |
| 501 |
|
| 502 |
/* login if we haven't done so yet */ |
| 503 |
if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in && |
| 504 |
pkcs11_login(p, si)) |
| 505 |
fatal("Unable to login to slotidx %lu", slotidx); |
| 506 |
|
| 507 |
/* generate public / private key pair */ |
| 508 |
if ((rv = f->C_GenerateKeyPair(session, &mech, pubKeyTemplate, 7, |
| 509 |
privKeyTemplate, 6, &pubKey, &privKey)) != CKR_OK) { |
| 510 |
fatal("pkcs11 rsa key pair generation failed with error 0x%lx", rv); |
| 511 |
} |
| 512 |
|
| 513 |
/* get the generated public modulus */ |
| 514 |
if ((rv = f->C_GetAttributeValue(session, pubKey, modulus, 1)) != CKR_OK) { |
| 515 |
fatal("C_GetAttributeValue failed: %lu", rv); |
| 516 |
} |
| 517 |
modulus[0].pValue = xmalloc(modulus[0].ulValueLen); |
| 518 |
if ((rv = f->C_GetAttributeValue(session, pubKey, modulus, 1)) != CKR_OK) { |
| 519 |
fatal("C_GetAttributeValue failed: %lu", rv); |
| 520 |
} |
| 521 |
|
| 522 |
/* set the id of the generated public and private keys to the modulus */ |
| 523 |
id[0].pValue = modulus[0].pValue; |
| 524 |
id[0].ulValueLen = modulus[0].ulValueLen; |
| 525 |
if ((rv = f->C_SetAttributeValue(session, pubKey, id, 1)) != CKR_OK) { |
| 526 |
fatal("C_SetAttributeValue failed: %lu", rv); |
| 527 |
} |
| 528 |
if ((rv = f->C_SetAttributeValue(session, privKey, id, 1)) != CKR_OK) { |
| 529 |
fatal("C_SetAttributeValue failed: %lu", rv); |
| 530 |
} |
| 531 |
|
| 532 |
xfree(modulus[0].pValue); |
| 533 |
|
| 534 |
return extract_key(p, slotidx, privKey); |
| 535 |
} |
| 536 |
|
| 383 |
/* |
537 |
/* |
| 384 |
* lookup public keys for token in slot identified by slotidx, |
538 |
* lookup public keys for token in slot identified by slotidx, |
| 385 |
* add 'wrapped' public keys to the 'keysp' array and increment nkeys. |
539 |
* add 'wrapped' public keys to the 'keysp' array and increment nkeys. |
|
Lines 390-397
pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, Key ***keysp,
Link Here
|
| 390 |
int *nkeys) |
544 |
int *nkeys) |
| 391 |
{ |
545 |
{ |
| 392 |
Key *key; |
546 |
Key *key; |
| 393 |
RSA *rsa; |
|
|
| 394 |
int i; |
| 395 |
CK_RV rv; |
547 |
CK_RV rv; |
| 396 |
CK_OBJECT_HANDLE obj; |
548 |
CK_OBJECT_HANDLE obj; |
| 397 |
CK_ULONG nfound; |
549 |
CK_ULONG nfound; |
|
Lines 401-411
pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, Key ***keysp,
Link Here
|
| 401 |
CK_ATTRIBUTE pubkey_filter[] = { |
553 |
CK_ATTRIBUTE pubkey_filter[] = { |
| 402 |
{ CKA_CLASS, NULL, sizeof(pubkey_class) } |
554 |
{ CKA_CLASS, NULL, sizeof(pubkey_class) } |
| 403 |
}; |
555 |
}; |
| 404 |
CK_ATTRIBUTE attribs[] = { |
|
|
| 405 |
{ CKA_ID, NULL, 0 }, |
| 406 |
{ CKA_MODULUS, NULL, 0 }, |
| 407 |
{ CKA_PUBLIC_EXPONENT, NULL, 0 } |
| 408 |
}; |
| 409 |
|
556 |
|
| 410 |
/* some compilers complain about non-constant initializer so we |
557 |
/* some compilers complain about non-constant initializer so we |
| 411 |
use NULL in CK_ATTRIBUTE above and set the value here */ |
558 |
use NULL in CK_ATTRIBUTE above and set the value here */ |
|
Lines 419-496
pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, Key ***keysp,
Link Here
|
| 419 |
return (-1); |
566 |
return (-1); |
| 420 |
} |
567 |
} |
| 421 |
while (1) { |
568 |
while (1) { |
| 422 |
/* XXX 3 attributes in attribs[] */ |
|
|
| 423 |
for (i = 0; i < 3; i++) { |
| 424 |
attribs[i].pValue = NULL; |
| 425 |
attribs[i].ulValueLen = 0; |
| 426 |
} |
| 427 |
if ((rv = f->C_FindObjects(session, &obj, 1, &nfound)) != CKR_OK |
569 |
if ((rv = f->C_FindObjects(session, &obj, 1, &nfound)) != CKR_OK |
| 428 |
|| nfound == 0) |
570 |
|| nfound == 0) |
| 429 |
break; |
571 |
break; |
| 430 |
/* found a key, so figure out size of the attributes */ |
572 |
|
| 431 |
if ((rv = f->C_GetAttributeValue(session, obj, attribs, 3)) |
573 |
/* found a key, extract details */ |
| 432 |
!= CKR_OK) { |
574 |
if ((key = extract_key(p, slotidx, obj)) != NULL) { |
| 433 |
error("C_GetAttributeValue failed: %lu", rv); |
575 |
/* expand key array and add key */ |
| 434 |
continue; |
576 |
*keysp = xrealloc(*keysp, *nkeys + 1, |
| 435 |
} |
577 |
sizeof(Key *)); |
| 436 |
/* check that none of the attributes are zero length */ |
578 |
(*keysp)[*nkeys] = key; |
| 437 |
if (attribs[0].ulValueLen == 0 || |
579 |
*nkeys = *nkeys + 1; |
| 438 |
attribs[1].ulValueLen == 0 || |
580 |
debug("have %d keys", *nkeys); |
| 439 |
attribs[2].ulValueLen == 0) { |
|
|
| 440 |
continue; |
| 441 |
} |
| 442 |
/* allocate buffers for attributes */ |
| 443 |
for (i = 0; i < 3; i++) |
| 444 |
attribs[i].pValue = xmalloc(attribs[i].ulValueLen); |
| 445 |
/* retrieve ID, modulus and public exponent of RSA key */ |
| 446 |
if ((rv = f->C_GetAttributeValue(session, obj, attribs, 3)) |
| 447 |
!= CKR_OK) { |
| 448 |
error("C_GetAttributeValue failed: %lu", rv); |
| 449 |
} else if ((rsa = RSA_new()) == NULL) { |
| 450 |
error("RSA_new failed"); |
| 451 |
} else { |
| 452 |
rsa->n = BN_bin2bn(attribs[1].pValue, |
| 453 |
attribs[1].ulValueLen, NULL); |
| 454 |
rsa->e = BN_bin2bn(attribs[2].pValue, |
| 455 |
attribs[2].ulValueLen, NULL); |
| 456 |
if (rsa->n && rsa->e && |
| 457 |
pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) { |
| 458 |
key = key_new(KEY_UNSPEC); |
| 459 |
key->rsa = rsa; |
| 460 |
key->type = KEY_RSA; |
| 461 |
key->flags |= KEY_FLAG_EXT; |
| 462 |
/* expand key array and add key */ |
| 463 |
*keysp = xrealloc(*keysp, *nkeys + 1, |
| 464 |
sizeof(Key *)); |
| 465 |
(*keysp)[*nkeys] = key; |
| 466 |
*nkeys = *nkeys + 1; |
| 467 |
debug("have %d keys", *nkeys); |
| 468 |
} else { |
| 469 |
RSA_free(rsa); |
| 470 |
} |
| 471 |
} |
581 |
} |
| 472 |
for (i = 0; i < 3; i++) |
|
|
| 473 |
xfree(attribs[i].pValue); |
| 474 |
} |
582 |
} |
| 475 |
if ((rv = f->C_FindObjectsFinal(session)) != CKR_OK) |
583 |
if ((rv = f->C_FindObjectsFinal(session)) != CKR_OK) |
| 476 |
error("C_FindObjectsFinal failed: %lu", rv); |
584 |
error("C_FindObjectsFinal failed: %lu", rv); |
| 477 |
return (0); |
585 |
return (0); |
| 478 |
} |
586 |
} |
| 479 |
|
587 |
|
| 480 |
/* register a new provider, fails if provider already exists */ |
588 |
/* initialize a new provider, fails if provider is already registered */ |
| 481 |
int |
589 |
static struct pkcs11_provider * |
| 482 |
pkcs11_add_provider(char *provider_id, char *pin, Key ***keyp) |
590 |
pkcs11_init_provider(char *provider_id, char *pin) |
| 483 |
{ |
591 |
{ |
| 484 |
int nkeys, need_finalize = 0; |
592 |
int need_finalize = 0; |
| 485 |
struct pkcs11_provider *p = NULL; |
593 |
struct pkcs11_provider *p = NULL; |
| 486 |
void *handle = NULL; |
594 |
void *handle = NULL; |
| 487 |
CK_RV (*getfunctionlist)(CK_FUNCTION_LIST **); |
595 |
CK_RV (*getfunctionlist)(CK_FUNCTION_LIST **); |
| 488 |
CK_RV rv; |
|
|
| 489 |
CK_FUNCTION_LIST *f = NULL; |
596 |
CK_FUNCTION_LIST *f = NULL; |
| 490 |
CK_TOKEN_INFO *token; |
597 |
CK_TOKEN_INFO *token; |
| 491 |
CK_ULONG i; |
598 |
CK_ULONG i; |
|
|
599 |
CK_RV rv; |
| 492 |
|
600 |
|
| 493 |
*keyp = NULL; |
|
|
| 494 |
if (pkcs11_provider_lookup(provider_id) != NULL) { |
601 |
if (pkcs11_provider_lookup(provider_id) != NULL) { |
| 495 |
error("provider already registered: %s", provider_id); |
602 |
error("provider already registered: %s", provider_id); |
| 496 |
goto fail; |
603 |
goto fail; |
|
Lines 542-558
pkcs11_add_provider(char *provider_id, char *pin, Key ***keyp)
Link Here
|
| 542 |
} |
649 |
} |
| 543 |
p->slotlist = xcalloc(p->nslots, sizeof(CK_SLOT_ID)); |
650 |
p->slotlist = xcalloc(p->nslots, sizeof(CK_SLOT_ID)); |
| 544 |
if ((rv = f->C_GetSlotList(CK_TRUE, p->slotlist, &p->nslots)) |
651 |
if ((rv = f->C_GetSlotList(CK_TRUE, p->slotlist, &p->nslots)) |
| 545 |
!= CKR_OK) { |
652 |
!= CKR_OK) { |
| 546 |
error("C_GetSlotList failed: %lu", rv); |
653 |
error("C_GetSlotList failed: %lu", rv); |
| 547 |
goto fail; |
654 |
goto fail; |
| 548 |
} |
655 |
} |
| 549 |
p->slotinfo = xcalloc(p->nslots, sizeof(struct pkcs11_slotinfo)); |
656 |
p->slotinfo = xcalloc(p->nslots, sizeof(struct pkcs11_slotinfo)); |
| 550 |
p->valid = 1; |
657 |
p->valid = 1; |
| 551 |
nkeys = 0; |
658 |
|
| 552 |
for (i = 0; i < p->nslots; i++) { |
659 |
for (i = 0; i < p->nslots; i++) { |
| 553 |
token = &p->slotinfo[i].token; |
660 |
token = &p->slotinfo[i].token; |
| 554 |
if ((rv = f->C_GetTokenInfo(p->slotlist[i], token)) |
661 |
if ((rv = p->function_list->C_GetTokenInfo(p->slotlist[i], token)) |
| 555 |
!= CKR_OK) { |
662 |
!= CKR_OK) { |
| 556 |
error("C_GetTokenInfo failed: %lu", rv); |
663 |
error("C_GetTokenInfo failed: %lu", rv); |
| 557 |
continue; |
664 |
continue; |
| 558 |
} |
665 |
} |
|
Lines 561-580
pkcs11_add_provider(char *provider_id, char *pin, Key ***keyp)
Link Here
|
| 561 |
rmspace(token->model, sizeof(token->model)); |
668 |
rmspace(token->model, sizeof(token->model)); |
| 562 |
rmspace(token->serialNumber, sizeof(token->serialNumber)); |
669 |
rmspace(token->serialNumber, sizeof(token->serialNumber)); |
| 563 |
debug("label <%s> manufacturerID <%s> model <%s> serial <%s>" |
670 |
debug("label <%s> manufacturerID <%s> model <%s> serial <%s>" |
| 564 |
" flags 0x%lx", |
671 |
" flags 0x%lx", |
| 565 |
token->label, token->manufacturerID, token->model, |
672 |
token->label, token->manufacturerID, token->model, |
| 566 |
token->serialNumber, token->flags); |
673 |
token->serialNumber, token->flags); |
| 567 |
/* open session, login with pin and retrieve public keys */ |
674 |
/* open session, login with pin */ |
| 568 |
if (pkcs11_open_session(p, i, pin) == 0) |
675 |
pkcs11_open_session(p, i, pin); |
| 569 |
pkcs11_fetch_keys(p, i, keyp, &nkeys); |
|
|
| 570 |
} |
676 |
} |
| 571 |
if (nkeys > 0) { |
677 |
|
| 572 |
TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); |
678 |
return p; |
| 573 |
p->refcount++; /* add to provider list */ |
679 |
|
| 574 |
return (nkeys); |
|
|
| 575 |
} |
| 576 |
error("no keys"); |
| 577 |
/* don't add the provider, since it does not have any keys */ |
| 578 |
fail: |
680 |
fail: |
| 579 |
if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) |
681 |
if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) |
| 580 |
error("C_Finalize failed: %lu", rv); |
682 |
error("C_Finalize failed: %lu", rv); |
|
Lines 587-593
fail:
Link Here
|
| 587 |
} |
689 |
} |
| 588 |
if (handle) |
690 |
if (handle) |
| 589 |
dlclose(handle); |
691 |
dlclose(handle); |
| 590 |
return (-1); |
692 |
return NULL; |
|
|
693 |
} |
| 694 |
|
| 695 |
/* register a new provider and get keys, fails if provider already exists or |
| 696 |
* contains no keys */ |
| 697 |
int |
| 698 |
pkcs11_add_provider(char *provider_id, char *pin, Key ***keyp) |
| 699 |
{ |
| 700 |
struct pkcs11_provider *p; |
| 701 |
int nkeys; |
| 702 |
CK_ULONG i; |
| 703 |
|
| 704 |
if (pkcs11_provider_lookup(provider_id) != NULL) { |
| 705 |
error("provider already registered: %s", provider_id); |
| 706 |
return (-1); |
| 707 |
} |
| 708 |
|
| 709 |
if ((p = pkcs11_init_provider(provider_id, pin)) == NULL) { |
| 710 |
return (-1); |
| 711 |
} |
| 712 |
|
| 713 |
*keyp = NULL; |
| 714 |
nkeys = 0; |
| 715 |
for (i = 0; i < p->nslots; i++) { |
| 716 |
/* Fetch keys for any slots with open sessions */ |
| 717 |
if (p->slotinfo[i].session) |
| 718 |
pkcs11_fetch_keys(p, i, keyp, &nkeys); |
| 719 |
} |
| 720 |
if (nkeys > 0) { |
| 721 |
TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); |
| 722 |
p->refcount++; /* add to provider list */ |
| 723 |
return (nkeys); |
| 724 |
} else { |
| 725 |
error("no keys"); |
| 726 |
/* don't add the provider, since it does not have any keys */ |
| 727 |
pkcs11_provider_finalize(p); |
| 728 |
pkcs11_provider_unref(p); |
| 729 |
return (-1); |
| 730 |
} |
| 731 |
} |
| 732 |
|
| 733 |
Key * |
| 734 |
pkcs11_key_generate(char *provider_id, char *pin, u_int slotidx, char *label, |
| 735 |
int type, u_int bits) |
| 736 |
{ |
| 737 |
Key *k = NULL; |
| 738 |
struct pkcs11_provider *p; |
| 739 |
|
| 740 |
if (((p = pkcs11_provider_lookup(provider_id)) == NULL) |
| 741 |
&& ((p = pkcs11_init_provider(provider_id, pin)) == NULL)) { |
| 742 |
fatal("pkcs11 provider initialization failed"); |
| 743 |
} |
| 744 |
|
| 745 |
switch (type) { |
| 746 |
case KEY_RSA: |
| 747 |
case KEY_RSA1: |
| 748 |
if ((k = pkcs11_rsa_generate_private_key(p, slotidx, label, bits)) == NULL) |
| 749 |
fatal("Error generating pkcs11 RSA key"); |
| 750 |
break; |
| 751 |
default: |
| 752 |
fatal("key_generate: unknown type %d", type); |
| 753 |
} |
| 754 |
|
| 755 |
if (k != NULL) { |
| 756 |
// Add to pkcs11 provider list |
| 757 |
TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); |
| 758 |
p->refcount++; |
| 759 |
} |
| 760 |
|
| 761 |
return k; |
| 591 |
} |
762 |
} |
| 592 |
|
763 |
|
| 593 |
#else |
764 |
#else |