diff options
Diffstat (limited to 'sk-usbhid.c')
-rw-r--r-- | sk-usbhid.c | 38 |
1 files changed, 26 insertions, 12 deletions
diff --git a/sk-usbhid.c b/sk-usbhid.c index 2a573caa2..1dd834883 100644 --- a/sk-usbhid.c +++ b/sk-usbhid.c | |||
@@ -163,7 +163,8 @@ pick_first_device(void) | |||
163 | /* Check if the specified key handle exists on a given device. */ | 163 | /* Check if the specified key handle exists on a given device. */ |
164 | static int | 164 | static int |
165 | try_device(fido_dev_t *dev, const uint8_t *message, size_t message_len, | 165 | try_device(fido_dev_t *dev, const uint8_t *message, size_t message_len, |
166 | const char *application, const uint8_t *key_handle, size_t key_handle_len) | 166 | const char *application, const uint8_t *key_handle, size_t key_handle_len, |
167 | uint8_t flags, const char *pin) | ||
167 | { | 168 | { |
168 | fido_assert_t *assert = NULL; | 169 | fido_assert_t *assert = NULL; |
169 | int r = FIDO_ERR_INTERNAL; | 170 | int r = FIDO_ERR_INTERNAL; |
@@ -191,7 +192,7 @@ try_device(fido_dev_t *dev, const uint8_t *message, size_t message_len, | |||
191 | skdebug(__func__, "fido_assert_up: %s", fido_strerr(r)); | 192 | skdebug(__func__, "fido_assert_up: %s", fido_strerr(r)); |
192 | goto out; | 193 | goto out; |
193 | } | 194 | } |
194 | r = fido_dev_get_assert(dev, assert, NULL); | 195 | r = fido_dev_get_assert(dev, assert, pin); |
195 | skdebug(__func__, "fido_dev_get_assert: %s", fido_strerr(r)); | 196 | skdebug(__func__, "fido_dev_get_assert: %s", fido_strerr(r)); |
196 | if (r == FIDO_ERR_USER_PRESENCE_REQUIRED) { | 197 | if (r == FIDO_ERR_USER_PRESENCE_REQUIRED) { |
197 | /* U2F tokens may return this */ | 198 | /* U2F tokens may return this */ |
@@ -206,7 +207,8 @@ try_device(fido_dev_t *dev, const uint8_t *message, size_t message_len, | |||
206 | /* Iterate over configured devices looking for a specific key handle */ | 207 | /* Iterate over configured devices looking for a specific key handle */ |
207 | static fido_dev_t * | 208 | static fido_dev_t * |
208 | find_device(const char *path, const uint8_t *message, size_t message_len, | 209 | find_device(const char *path, const uint8_t *message, size_t message_len, |
209 | const char *application, const uint8_t *key_handle, size_t key_handle_len) | 210 | const char *application, const uint8_t *key_handle, size_t key_handle_len, |
211 | uint8_t flags, const char *pin) | ||
210 | { | 212 | { |
211 | fido_dev_info_t *devlist = NULL; | 213 | fido_dev_info_t *devlist = NULL; |
212 | fido_dev_t *dev = NULL; | 214 | fido_dev_t *dev = NULL; |
@@ -260,7 +262,7 @@ find_device(const char *path, const uint8_t *message, size_t message_len, | |||
260 | continue; | 262 | continue; |
261 | } | 263 | } |
262 | if (try_device(dev, message, message_len, application, | 264 | if (try_device(dev, message, message_len, application, |
263 | key_handle, key_handle_len) == 0) { | 265 | key_handle, key_handle_len, flags, pin) == 0) { |
264 | skdebug(__func__, "found key"); | 266 | skdebug(__func__, "found key"); |
265 | break; | 267 | break; |
266 | } | 268 | } |
@@ -570,19 +572,23 @@ sk_enroll(uint32_t alg, const uint8_t *challenge, size_t challenge_len, | |||
570 | skdebug(__func__, "fido_dev_open: %s", fido_strerr(r)); | 572 | skdebug(__func__, "fido_dev_open: %s", fido_strerr(r)); |
571 | goto out; | 573 | goto out; |
572 | } | 574 | } |
573 | if ((flags & SSH_SK_RESIDENT_KEY) != 0) { | 575 | if ((flags & (SSH_SK_RESIDENT_KEY|SSH_SK_USER_VERIFICATION_REQD)) != 0) { |
574 | if (check_sk_extensions(dev, "credProtect", &credprot) < 0) { | 576 | if (check_sk_extensions(dev, "credProtect", &credprot) < 0) { |
575 | skdebug(__func__, "check_sk_extensions failed"); | 577 | skdebug(__func__, "check_sk_extensions failed"); |
576 | goto out; | 578 | goto out; |
577 | } | 579 | } |
578 | if (credprot == 0) { | 580 | if (credprot == 0) { |
579 | skdebug(__func__, "refusing to create unprotected " | 581 | skdebug(__func__, "refusing to create unprotected " |
580 | "resident key"); | 582 | "resident/verify-required key"); |
581 | ret = SSH_SK_ERR_UNSUPPORTED; | 583 | ret = SSH_SK_ERR_UNSUPPORTED; |
582 | goto out; | 584 | goto out; |
583 | } | 585 | } |
584 | if ((r = fido_cred_set_prot(cred, | 586 | if ((flags & SSH_SK_USER_VERIFICATION_REQD)) |
585 | FIDO_CRED_PROT_UV_OPTIONAL_WITH_ID)) != FIDO_OK) { | 587 | credprot = FIDO_CRED_PROT_UV_REQUIRED; |
588 | else | ||
589 | credprot = FIDO_CRED_PROT_UV_OPTIONAL_WITH_ID; | ||
590 | |||
591 | if ((r = fido_cred_set_prot(cred, credprot)) != FIDO_OK) { | ||
586 | skdebug(__func__, "fido_cred_set_prot: %s", | 592 | skdebug(__func__, "fido_cred_set_prot: %s", |
587 | fido_strerr(r)); | 593 | fido_strerr(r)); |
588 | ret = fidoerr_to_skerr(r); | 594 | ret = fidoerr_to_skerr(r); |
@@ -826,7 +832,7 @@ sk_sign(uint32_t alg, const uint8_t *data, size_t datalen, | |||
826 | goto out; | 832 | goto out; |
827 | } | 833 | } |
828 | if ((dev = find_device(device, message, sizeof(message), | 834 | if ((dev = find_device(device, message, sizeof(message), |
829 | application, key_handle, key_handle_len)) == NULL) { | 835 | application, key_handle, key_handle_len, flags, pin)) == NULL) { |
830 | skdebug(__func__, "couldn't find device for key handle"); | 836 | skdebug(__func__, "couldn't find device for key handle"); |
831 | goto out; | 837 | goto out; |
832 | } | 838 | } |
@@ -855,8 +861,15 @@ sk_sign(uint32_t alg, const uint8_t *data, size_t datalen, | |||
855 | skdebug(__func__, "fido_assert_set_up: %s", fido_strerr(r)); | 861 | skdebug(__func__, "fido_assert_set_up: %s", fido_strerr(r)); |
856 | goto out; | 862 | goto out; |
857 | } | 863 | } |
858 | if ((r = fido_dev_get_assert(dev, assert, NULL)) != FIDO_OK) { | 864 | if (pin == NULL && (flags & SSH_SK_USER_VERIFICATION_REQD) && |
865 | (r = fido_assert_set_uv(assert, FIDO_OPT_TRUE)) != FIDO_OK) { | ||
866 | skdebug(__func__, "fido_assert_set_uv: %s", fido_strerr(r)); | ||
867 | ret = FIDO_ERR_PIN_REQUIRED; | ||
868 | goto out; | ||
869 | } | ||
870 | if ((r = fido_dev_get_assert(dev, assert, pin)) != FIDO_OK) { | ||
859 | skdebug(__func__, "fido_dev_get_assert: %s", fido_strerr(r)); | 871 | skdebug(__func__, "fido_dev_get_assert: %s", fido_strerr(r)); |
872 | ret = fidoerr_to_skerr(r); | ||
860 | goto out; | 873 | goto out; |
861 | } | 874 | } |
862 | if ((response = calloc(1, sizeof(*response))) == NULL) { | 875 | if ((response = calloc(1, sizeof(*response))) == NULL) { |
@@ -978,8 +991,9 @@ read_rks(const char *devpath, const char *pin, | |||
978 | continue; | 991 | continue; |
979 | } | 992 | } |
980 | skdebug(__func__, "Device %s RP \"%s\" slot %zu: " | 993 | skdebug(__func__, "Device %s RP \"%s\" slot %zu: " |
981 | "type %d", devpath, fido_credman_rp_id(rp, i), j, | 994 | "type %d flags 0x%02x prot 0x%02x", devpath, |
982 | fido_cred_type(cred)); | 995 | fido_credman_rp_id(rp, i), j, fido_cred_type(cred), |
996 | fido_cred_flags(cred), fido_cred_prot(cred)); | ||
983 | 997 | ||
984 | /* build response entry */ | 998 | /* build response entry */ |
985 | if ((srk = calloc(1, sizeof(*srk))) == NULL || | 999 | if ((srk = calloc(1, sizeof(*srk))) == NULL || |