|
Lines 28-36
Link Here
|
| 28 |
|
28 |
|
| 29 |
#include <sys/types.h> |
29 |
#include <sys/types.h> |
| 30 |
|
30 |
|
| 31 |
#include <openssl/evp.h> |
|
|
| 32 |
#include <openssl/x509.h> |
| 33 |
|
| 34 |
#include <stdarg.h> |
31 |
#include <stdarg.h> |
| 35 |
#include <string.h> |
32 |
#include <string.h> |
| 36 |
|
33 |
|
|
Lines 65-71
Link Here
|
| 65 |
|
62 |
|
| 66 |
struct sc_priv_data |
63 |
struct sc_priv_data |
| 67 |
{ |
64 |
{ |
| 68 |
struct sc_pkcs15_id cert_id; |
65 |
struct sc_pkcs15_id pubkey_id; |
| 69 |
int ref_count; |
66 |
int ref_count; |
| 70 |
}; |
67 |
}; |
| 71 |
|
68 |
|
|
Lines 136-142
Link Here
|
| 136 |
goto err; |
133 |
goto err; |
| 137 |
} |
134 |
} |
| 138 |
} |
135 |
} |
| 139 |
r = sc_pkcs15_find_prkey_by_id_usage(p15card, &priv->cert_id, |
136 |
r = sc_pkcs15_find_prkey_by_id_usage(p15card, &priv->pubkey_id, |
| 140 |
usage, &key_obj); |
137 |
usage, &key_obj); |
| 141 |
if (r) { |
138 |
if (r) { |
| 142 |
error("Unable to find private key from SmartCard: %s", |
139 |
error("Unable to find private key from SmartCard: %s", |
|
Lines 343-394
Link Here
|
| 343 |
} |
340 |
} |
| 344 |
|
341 |
|
| 345 |
static int |
342 |
static int |
| 346 |
sc_read_pubkey(Key * k, const struct sc_pkcs15_object *cert_obj) |
343 |
sc_read_pubkey(Key * k, const struct sc_pkcs15_object *pubkey_obj) |
| 347 |
{ |
344 |
{ |
| 348 |
int r; |
345 |
int r; |
| 349 |
sc_pkcs15_cert_t *cert = NULL; |
346 |
sc_pkcs15_pubkey_t *pkey = NULL; |
| 350 |
struct sc_priv_data *priv = NULL; |
347 |
struct sc_priv_data *priv = NULL; |
| 351 |
sc_pkcs15_cert_info_t *cinfo = cert_obj->data; |
348 |
sc_pkcs15_pubkey_info_t *cinfo = pubkey_obj->data; |
| 352 |
|
349 |
|
| 353 |
X509 *x509 = NULL; |
|
|
| 354 |
EVP_PKEY *pubkey = NULL; |
| 355 |
u8 *p; |
| 356 |
char *tmp; |
350 |
char *tmp; |
| 357 |
|
351 |
|
| 358 |
debug("sc_read_pubkey() with cert id %02X", cinfo->id.value[0]); |
352 |
debug("sc_read_pubkey() with pubkey id %02X", cinfo->id.value[0]); |
| 359 |
r = sc_pkcs15_read_certificate(p15card, cinfo, &cert); |
353 |
r = sc_pkcs15_read_pubkey(p15card, pubkey_obj, &pkey); |
| 360 |
if (r) { |
354 |
if (r) { |
| 361 |
logit("Certificate read failed: %s", sc_strerror(r)); |
355 |
logit("Public key read failed: %s", sc_strerror(r)); |
| 362 |
goto err; |
|
|
| 363 |
} |
| 364 |
x509 = X509_new(); |
| 365 |
if (x509 == NULL) { |
| 366 |
r = -1; |
| 367 |
goto err; |
| 368 |
} |
| 369 |
p = cert->data; |
| 370 |
if (!d2i_X509(&x509, &p, cert->data_len)) { |
| 371 |
logit("Unable to parse X.509 certificate"); |
| 372 |
r = -1; |
| 373 |
goto err; |
356 |
goto err; |
| 374 |
} |
357 |
} |
| 375 |
sc_pkcs15_free_certificate(cert); |
358 |
|
| 376 |
cert = NULL; |
359 |
if (pkey->algorithm != SC_ALGORITHM_RSA) { |
| 377 |
pubkey = X509_get_pubkey(x509); |
360 |
logit("Smartcard key is not RSA"); |
| 378 |
X509_free(x509); |
|
|
| 379 |
x509 = NULL; |
| 380 |
if (pubkey->type != EVP_PKEY_RSA) { |
| 381 |
logit("Public key is of unknown type"); |
| 382 |
r = -1; |
361 |
r = -1; |
| 383 |
goto err; |
362 |
goto err; |
| 384 |
} |
363 |
} |
| 385 |
k->rsa = EVP_PKEY_get1_RSA(pubkey); |
364 |
|
| 386 |
EVP_PKEY_free(pubkey); |
365 |
k->rsa = RSA_new(); |
|
|
366 |
|
| 367 |
/* this is only a pubkey, so wipe secret values: */ |
| 368 |
k->rsa->d = NULL; |
| 369 |
k->rsa->p = NULL; |
| 370 |
k->rsa->q = NULL; |
| 371 |
k->rsa->dmp1 = NULL; |
| 372 |
k->rsa->dmq1 = NULL; |
| 373 |
k->rsa->iqmp = NULL; |
| 374 |
|
| 375 |
k->rsa->n = BN_bin2bn(pkey->u.rsa.modulus.data, pkey->u.rsa.modulus.len, NULL); |
| 376 |
k->rsa->e = BN_bin2bn(pkey->u.rsa.exponent.data, pkey->u.rsa.exponent.len, NULL); |
| 377 |
|
| 378 |
sc_pkcs15_free_pubkey(pkey); |
| 379 |
pkey = NULL; |
| 387 |
|
380 |
|
| 388 |
k->rsa->flags |= RSA_FLAG_SIGN_VER; |
381 |
k->rsa->flags |= RSA_FLAG_SIGN_VER; |
| 389 |
RSA_set_method(k->rsa, sc_get_rsa_method()); |
382 |
RSA_set_method(k->rsa, sc_get_rsa_method()); |
| 390 |
priv = xmalloc(sizeof(struct sc_priv_data)); |
383 |
priv = xmalloc(sizeof(struct sc_priv_data)); |
| 391 |
priv->cert_id = cinfo->id; |
384 |
priv->pubkey_id = cinfo->id; |
| 392 |
priv->ref_count = 1; |
385 |
priv->ref_count = 1; |
| 393 |
RSA_set_app_data(k->rsa, priv); |
386 |
RSA_set_app_data(k->rsa, priv); |
| 394 |
|
387 |
|
|
Lines 399-410
Link Here
|
| 399 |
|
392 |
|
| 400 |
return 0; |
393 |
return 0; |
| 401 |
err: |
394 |
err: |
| 402 |
if (cert) |
395 |
if (pkey) |
| 403 |
sc_pkcs15_free_certificate(cert); |
396 |
sc_pkcs15_free_pubkey(pkey); |
| 404 |
if (pubkey) |
|
|
| 405 |
EVP_PKEY_free(pubkey); |
| 406 |
if (x509) |
| 407 |
X509_free(x509); |
| 408 |
return r; |
397 |
return r; |
| 409 |
} |
398 |
} |
| 410 |
|
399 |
|
|
Lines 413-420
Link Here
|
| 413 |
{ |
402 |
{ |
| 414 |
Key *k, **keys; |
403 |
Key *k, **keys; |
| 415 |
int i, r, real_count = 0, key_count; |
404 |
int i, r, real_count = 0, key_count; |
| 416 |
sc_pkcs15_id_t cert_id; |
405 |
sc_pkcs15_id_t pubkey_id; |
| 417 |
sc_pkcs15_object_t *certs[32]; |
406 |
sc_pkcs15_object_t *pubkeys[32]; |
| 418 |
char *buf = xstrdup(id), *p; |
407 |
char *buf = xstrdup(id), *p; |
| 419 |
|
408 |
|
| 420 |
debug("sc_get_keys called: id = %s", id); |
409 |
debug("sc_get_keys called: id = %s", id); |
|
Lines 423-433
Link Here
|
| 423 |
xfree(sc_pin); |
412 |
xfree(sc_pin); |
| 424 |
sc_pin = (pin == NULL) ? NULL : xstrdup(pin); |
413 |
sc_pin = (pin == NULL) ? NULL : xstrdup(pin); |
| 425 |
|
414 |
|
| 426 |
cert_id.len = 0; |
415 |
pubkey_id.len = 0; |
| 427 |
if ((p = strchr(buf, ':')) != NULL) { |
416 |
if ((p = strchr(buf, ':')) != NULL) { |
| 428 |
*p = 0; |
417 |
*p = 0; |
| 429 |
p++; |
418 |
p++; |
| 430 |
sc_pkcs15_hex_string_to_id(p, &cert_id); |
419 |
sc_pkcs15_hex_string_to_id(p, &pubkey_id); |
| 431 |
} |
420 |
} |
| 432 |
r = sscanf(buf, "%d", &sc_reader_id); |
421 |
r = sscanf(buf, "%d", &sc_reader_id); |
| 433 |
xfree(buf); |
422 |
xfree(buf); |
|
Lines 441-460
Link Here
|
| 441 |
goto err; |
430 |
goto err; |
| 442 |
} |
431 |
} |
| 443 |
} |
432 |
} |
| 444 |
if (cert_id.len) { |
433 |
if (pubkey_id.len) { |
| 445 |
r = sc_pkcs15_find_cert_by_id(p15card, &cert_id, &certs[0]); |
434 |
r = sc_pkcs15_find_pubkey_by_id(p15card, &pubkey_id, &pubkeys[0]); |
| 446 |
if (r < 0) |
435 |
if (r < 0) |
| 447 |
goto err; |
436 |
goto err; |
| 448 |
key_count = 1; |
437 |
key_count = 1; |
| 449 |
} else { |
438 |
} else { |
| 450 |
r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_CERT_X509, |
439 |
r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PUBKEY, |
| 451 |
certs, 32); |
440 |
pubkeys, 32); |
| 452 |
if (r == 0) { |
441 |
if (r == 0) { |
| 453 |
logit("No certificates found on smartcard"); |
442 |
logit("No public keys found on smartcard"); |
| 454 |
r = -1; |
443 |
r = -1; |
| 455 |
goto err; |
444 |
goto err; |
| 456 |
} else if (r < 0) { |
445 |
} else if (r < 0) { |
| 457 |
error("Certificate enumeration failed: %s", |
446 |
error("Public key enumeration failed: %s", |
| 458 |
sc_strerror(r)); |
447 |
sc_strerror(r)); |
| 459 |
goto err; |
448 |
goto err; |
| 460 |
} |
449 |
} |
|
Lines 465-479
Link Here
|
| 465 |
keys = xcalloc(key_count * 2 + 1, sizeof(Key *)); |
454 |
keys = xcalloc(key_count * 2 + 1, sizeof(Key *)); |
| 466 |
for (i = 0; i < key_count; i++) { |
455 |
for (i = 0; i < key_count; i++) { |
| 467 |
sc_pkcs15_object_t *tmp_obj = NULL; |
456 |
sc_pkcs15_object_t *tmp_obj = NULL; |
| 468 |
cert_id = ((sc_pkcs15_cert_info_t *)(certs[i]->data))->id; |
457 |
pubkey_id = ((sc_pkcs15_pubkey_info_t *)(pubkeys[i]->data))->id; |
| 469 |
if (sc_pkcs15_find_prkey_by_id(p15card, &cert_id, &tmp_obj)) |
458 |
if (sc_pkcs15_find_prkey_by_id(p15card, &pubkey_id, &tmp_obj)) |
| 470 |
/* skip the public key (certificate) if no |
459 |
/* skip the public key if no |
| 471 |
* corresponding private key is present */ |
460 |
* corresponding private key is present */ |
| 472 |
continue; |
461 |
continue; |
| 473 |
k = key_new(KEY_RSA); |
462 |
k = key_new(KEY_RSA); |
| 474 |
if (k == NULL) |
463 |
if (k == NULL) |
| 475 |
break; |
464 |
break; |
| 476 |
r = sc_read_pubkey(k, certs[i]); |
465 |
r = sc_read_pubkey(k, pubkeys[i]); |
| 477 |
if (r) { |
466 |
if (r) { |
| 478 |
error("sc_read_pubkey failed: %s", sc_strerror(r)); |
467 |
error("sc_read_pubkey failed: %s", sc_strerror(r)); |
| 479 |
key_free(k); |
468 |
key_free(k); |
|
Lines 516-522
Link Here
|
| 516 |
/* internal error => return default label */ |
505 |
/* internal error => return default label */ |
| 517 |
return xstrdup("smartcard key"); |
506 |
return xstrdup("smartcard key"); |
| 518 |
} |
507 |
} |
| 519 |
r = sc_pkcs15_find_prkey_by_id(p15card, &priv->cert_id, &key_obj); |
508 |
r = sc_pkcs15_find_prkey_by_id(p15card, &priv->pubkey_id, &key_obj); |
| 520 |
if (r) { |
509 |
if (r) { |
| 521 |
logit("Unable to find private key from SmartCard: %s", |
510 |
logit("Unable to find private key from SmartCard: %s", |
| 522 |
sc_strerror(r)); |
511 |
sc_strerror(r)); |