summaryrefslogtreecommitdiff
path: root/sk-usbhid.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2020-05-13 10:08:02 +0000
committerDamien Miller <djm@mindrot.org>2020-05-27 10:09:19 +1000
commit2ad7b7e46408dbebf2a4efc4efd75a9544197d57 (patch)
tree5d24a7a78d9ff23c4471d9104892fd6d77ec4764 /sk-usbhid.c
parent1e70dc3285fc9b4f6454975acb81e8702c23dd89 (diff)
upstream: Enable credProtect extension when generating a resident
key. The FIDO 2.1 Client to Authenticator Protocol introduced a "credProtect" feature to better protect resident keys. This option allows (amone other possibilities) requiring a PIN prior to all operations that may retrieve the key handle. Patch by Pedro Martelletto; ok djm and markus OpenBSD-Commit-ID: 013bc06a577dcaa66be3913b7f183eb8cad87e73
Diffstat (limited to 'sk-usbhid.c')
-rw-r--r--sk-usbhid.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/sk-usbhid.c b/sk-usbhid.c
index 8097cc7f4..4d64550c9 100644
--- a/sk-usbhid.c
+++ b/sk-usbhid.c
@@ -449,6 +449,43 @@ check_enroll_options(struct sk_option **options, char **devicep,
449 return 0; 449 return 0;
450} 450}
451 451
452static int
453check_sk_extensions(fido_dev_t *dev, const char *ext, int *ret)
454{
455 fido_cbor_info_t *info;
456 char * const *ptr;
457 size_t len;
458 int r;
459
460 *ret = 0;
461
462 if (!fido_dev_is_fido2(dev)) {
463 skdebug(__func__, "device is not fido2");
464 return 0;
465 }
466 if ((info = fido_cbor_info_new()) == NULL) {
467 skdebug(__func__, "fido_cbor_info_new failed");
468 return -1;
469 }
470 if ((r = fido_dev_get_cbor_info(dev, info)) != FIDO_OK) {
471 skdebug(__func__, "fido_dev_get_cbor_info: %s", fido_strerr(r));
472 fido_cbor_info_free(&info);
473 return -1;
474 }
475 ptr = fido_cbor_info_extensions_ptr(info);
476 len = fido_cbor_info_extensions_len(info);
477 for (size_t i = 0; i < len; i++) {
478 if (!strcmp(ptr[i], ext)) {
479 *ret = 1;
480 break;
481 }
482 }
483 fido_cbor_info_free(&info);
484 skdebug(__func__, "extension %s %s", ext, *ret ? "present" : "absent");
485
486 return 0;
487}
488
452int 489int
453sk_enroll(uint32_t alg, const uint8_t *challenge, size_t challenge_len, 490sk_enroll(uint32_t alg, const uint8_t *challenge, size_t challenge_len,
454 const char *application, uint8_t flags, const char *pin, 491 const char *application, uint8_t flags, const char *pin,
@@ -460,6 +497,7 @@ sk_enroll(uint32_t alg, const uint8_t *challenge, size_t challenge_len,
460 uint8_t user_id[32]; 497 uint8_t user_id[32];
461 struct sk_enroll_response *response = NULL; 498 struct sk_enroll_response *response = NULL;
462 size_t len; 499 size_t len;
500 int credprot;
463 int cose_alg; 501 int cose_alg;
464 int ret = SSH_SK_ERR_GENERAL; 502 int ret = SSH_SK_ERR_GENERAL;
465 int r; 503 int r;
@@ -532,6 +570,25 @@ sk_enroll(uint32_t alg, const uint8_t *challenge, size_t challenge_len,
532 skdebug(__func__, "fido_dev_open: %s", fido_strerr(r)); 570 skdebug(__func__, "fido_dev_open: %s", fido_strerr(r));
533 goto out; 571 goto out;
534 } 572 }
573 if ((flags & SSH_SK_RESIDENT_KEY) != 0) {
574 if (check_sk_extensions(dev, "credProtect", &credprot) < 0) {
575 skdebug(__func__, "check_sk_extensions failed");
576 goto out;
577 }
578 if (credprot == 0) {
579 skdebug(__func__, "refusing to create unprotected "
580 "resident key");
581 ret = SSH_SK_ERR_UNSUPPORTED;
582 goto out;
583 }
584 if ((r = fido_cred_set_prot(cred,
585 FIDO_CRED_PROT_UV_OPTIONAL_WITH_ID)) != FIDO_OK) {
586 skdebug(__func__, "fido_cred_set_prot: %s",
587 fido_strerr(r));
588 ret = fidoerr_to_skerr(r);
589 goto out;
590 }
591 }
535 if ((r = fido_dev_make_cred(dev, cred, pin)) != FIDO_OK) { 592 if ((r = fido_dev_make_cred(dev, cred, pin)) != FIDO_OK) {
536 skdebug(__func__, "fido_dev_make_cred: %s", fido_strerr(r)); 593 skdebug(__func__, "fido_dev_make_cred: %s", fido_strerr(r));
537 ret = fidoerr_to_skerr(r); 594 ret = fidoerr_to_skerr(r);