summaryrefslogtreecommitdiff
path: root/sk-usbhid.c
diff options
context:
space:
mode:
Diffstat (limited to 'sk-usbhid.c')
-rw-r--r--sk-usbhid.c38
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. */
164static int 164static int
165try_device(fido_dev_t *dev, const uint8_t *message, size_t message_len, 165try_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 */
207static fido_dev_t * 208static fido_dev_t *
208find_device(const char *path, const uint8_t *message, size_t message_len, 209find_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 ||