diff options
author | djm@openbsd.org <djm@openbsd.org> | 2020-05-13 10:08:02 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2020-05-27 10:09:19 +1000 |
commit | 2ad7b7e46408dbebf2a4efc4efd75a9544197d57 (patch) | |
tree | 5d24a7a78d9ff23c4471d9104892fd6d77ec4764 /sk-usbhid.c | |
parent | 1e70dc3285fc9b4f6454975acb81e8702c23dd89 (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.c | 57 |
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 | ||
452 | static int | ||
453 | check_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 | |||
452 | int | 489 | int |
453 | sk_enroll(uint32_t alg, const uint8_t *challenge, size_t challenge_len, | 490 | sk_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); |