diff options
Diffstat (limited to 'src/u2f.c')
-rw-r--r-- | src/u2f.c | 69 |
1 files changed, 41 insertions, 28 deletions
@@ -125,11 +125,10 @@ authdata_fake(const char *rp_id, uint8_t flags, uint32_t sigcount, | |||
125 | static int | 125 | static int |
126 | send_dummy_register(fido_dev_t *dev, int ms) | 126 | send_dummy_register(fido_dev_t *dev, int ms) |
127 | { | 127 | { |
128 | const uint8_t cmd = CTAP_FRAME_INIT | CTAP_CMD_MSG; | ||
129 | iso7816_apdu_t *apdu = NULL; | 128 | iso7816_apdu_t *apdu = NULL; |
130 | unsigned char challenge[SHA256_DIGEST_LENGTH]; | 129 | unsigned char challenge[SHA256_DIGEST_LENGTH]; |
131 | unsigned char application[SHA256_DIGEST_LENGTH]; | 130 | unsigned char application[SHA256_DIGEST_LENGTH]; |
132 | unsigned char reply[2048]; | 131 | unsigned char reply[FIDO_MAXMSG]; |
133 | int r; | 132 | int r; |
134 | 133 | ||
135 | #ifdef FIDO_FUZZ | 134 | #ifdef FIDO_FUZZ |
@@ -150,13 +149,13 @@ send_dummy_register(fido_dev_t *dev, int ms) | |||
150 | } | 149 | } |
151 | 150 | ||
152 | do { | 151 | do { |
153 | if (fido_tx(dev, cmd, iso7816_ptr(apdu), | 152 | if (fido_tx(dev, CTAP_CMD_MSG, iso7816_ptr(apdu), |
154 | iso7816_len(apdu)) < 0) { | 153 | iso7816_len(apdu)) < 0) { |
155 | fido_log_debug("%s: fido_tx", __func__); | 154 | fido_log_debug("%s: fido_tx", __func__); |
156 | r = FIDO_ERR_TX; | 155 | r = FIDO_ERR_TX; |
157 | goto fail; | 156 | goto fail; |
158 | } | 157 | } |
159 | if (fido_rx(dev, cmd, &reply, sizeof(reply), ms) < 2) { | 158 | if (fido_rx(dev, CTAP_CMD_MSG, &reply, sizeof(reply), ms) < 2) { |
160 | fido_log_debug("%s: fido_rx", __func__); | 159 | fido_log_debug("%s: fido_rx", __func__); |
161 | r = FIDO_ERR_RX; | 160 | r = FIDO_ERR_RX; |
162 | goto fail; | 161 | goto fail; |
@@ -179,11 +178,10 @@ static int | |||
179 | key_lookup(fido_dev_t *dev, const char *rp_id, const fido_blob_t *key_id, | 178 | key_lookup(fido_dev_t *dev, const char *rp_id, const fido_blob_t *key_id, |
180 | int *found, int ms) | 179 | int *found, int ms) |
181 | { | 180 | { |
182 | const uint8_t cmd = CTAP_FRAME_INIT | CTAP_CMD_MSG; | ||
183 | iso7816_apdu_t *apdu = NULL; | 181 | iso7816_apdu_t *apdu = NULL; |
184 | unsigned char challenge[SHA256_DIGEST_LENGTH]; | 182 | unsigned char challenge[SHA256_DIGEST_LENGTH]; |
185 | unsigned char rp_id_hash[SHA256_DIGEST_LENGTH]; | 183 | unsigned char rp_id_hash[SHA256_DIGEST_LENGTH]; |
186 | unsigned char reply[8]; | 184 | unsigned char reply[FIDO_MAXMSG]; |
187 | uint8_t key_id_len; | 185 | uint8_t key_id_len; |
188 | int r; | 186 | int r; |
189 | 187 | ||
@@ -217,12 +215,13 @@ key_lookup(fido_dev_t *dev, const char *rp_id, const fido_blob_t *key_id, | |||
217 | goto fail; | 215 | goto fail; |
218 | } | 216 | } |
219 | 217 | ||
220 | if (fido_tx(dev, cmd, iso7816_ptr(apdu), iso7816_len(apdu)) < 0) { | 218 | if (fido_tx(dev, CTAP_CMD_MSG, iso7816_ptr(apdu), |
219 | iso7816_len(apdu)) < 0) { | ||
221 | fido_log_debug("%s: fido_tx", __func__); | 220 | fido_log_debug("%s: fido_tx", __func__); |
222 | r = FIDO_ERR_TX; | 221 | r = FIDO_ERR_TX; |
223 | goto fail; | 222 | goto fail; |
224 | } | 223 | } |
225 | if (fido_rx(dev, cmd, &reply, sizeof(reply), ms) != 2) { | 224 | if (fido_rx(dev, CTAP_CMD_MSG, &reply, sizeof(reply), ms) != 2) { |
226 | fido_log_debug("%s: fido_rx", __func__); | 225 | fido_log_debug("%s: fido_rx", __func__); |
227 | r = FIDO_ERR_RX; | 226 | r = FIDO_ERR_RX; |
228 | goto fail; | 227 | goto fail; |
@@ -285,10 +284,9 @@ static int | |||
285 | do_auth(fido_dev_t *dev, const fido_blob_t *cdh, const char *rp_id, | 284 | do_auth(fido_dev_t *dev, const fido_blob_t *cdh, const char *rp_id, |
286 | const fido_blob_t *key_id, fido_blob_t *sig, fido_blob_t *ad, int ms) | 285 | const fido_blob_t *key_id, fido_blob_t *sig, fido_blob_t *ad, int ms) |
287 | { | 286 | { |
288 | const uint8_t cmd = CTAP_FRAME_INIT | CTAP_CMD_MSG; | ||
289 | iso7816_apdu_t *apdu = NULL; | 287 | iso7816_apdu_t *apdu = NULL; |
290 | unsigned char rp_id_hash[SHA256_DIGEST_LENGTH]; | 288 | unsigned char rp_id_hash[SHA256_DIGEST_LENGTH]; |
291 | unsigned char reply[128]; | 289 | unsigned char reply[FIDO_MAXMSG]; |
292 | int reply_len; | 290 | int reply_len; |
293 | uint8_t key_id_len; | 291 | uint8_t key_id_len; |
294 | int r; | 292 | int r; |
@@ -326,14 +324,14 @@ do_auth(fido_dev_t *dev, const fido_blob_t *cdh, const char *rp_id, | |||
326 | } | 324 | } |
327 | 325 | ||
328 | do { | 326 | do { |
329 | if (fido_tx(dev, cmd, iso7816_ptr(apdu), | 327 | if (fido_tx(dev, CTAP_CMD_MSG, iso7816_ptr(apdu), |
330 | iso7816_len(apdu)) < 0) { | 328 | iso7816_len(apdu)) < 0) { |
331 | fido_log_debug("%s: fido_tx", __func__); | 329 | fido_log_debug("%s: fido_tx", __func__); |
332 | r = FIDO_ERR_TX; | 330 | r = FIDO_ERR_TX; |
333 | goto fail; | 331 | goto fail; |
334 | } | 332 | } |
335 | if ((reply_len = fido_rx(dev, cmd, &reply, sizeof(reply), | 333 | if ((reply_len = fido_rx(dev, CTAP_CMD_MSG, &reply, |
336 | ms)) < 2) { | 334 | sizeof(reply), ms)) < 2) { |
337 | fido_log_debug("%s: fido_rx", __func__); | 335 | fido_log_debug("%s: fido_rx", __func__); |
338 | r = FIDO_ERR_RX; | 336 | r = FIDO_ERR_RX; |
339 | goto fail; | 337 | goto fail; |
@@ -575,10 +573,9 @@ fail: | |||
575 | int | 573 | int |
576 | u2f_register(fido_dev_t *dev, fido_cred_t *cred, int ms) | 574 | u2f_register(fido_dev_t *dev, fido_cred_t *cred, int ms) |
577 | { | 575 | { |
578 | const uint8_t cmd = CTAP_FRAME_INIT | CTAP_CMD_MSG; | ||
579 | iso7816_apdu_t *apdu = NULL; | 576 | iso7816_apdu_t *apdu = NULL; |
580 | unsigned char rp_id_hash[SHA256_DIGEST_LENGTH]; | 577 | unsigned char rp_id_hash[SHA256_DIGEST_LENGTH]; |
581 | unsigned char reply[2048]; | 578 | unsigned char reply[FIDO_MAXMSG]; |
582 | int reply_len; | 579 | int reply_len; |
583 | int found; | 580 | int found; |
584 | int r; | 581 | int r; |
@@ -634,14 +631,14 @@ u2f_register(fido_dev_t *dev, fido_cred_t *cred, int ms) | |||
634 | } | 631 | } |
635 | 632 | ||
636 | do { | 633 | do { |
637 | if (fido_tx(dev, cmd, iso7816_ptr(apdu), | 634 | if (fido_tx(dev, CTAP_CMD_MSG, iso7816_ptr(apdu), |
638 | iso7816_len(apdu)) < 0) { | 635 | iso7816_len(apdu)) < 0) { |
639 | fido_log_debug("%s: fido_tx", __func__); | 636 | fido_log_debug("%s: fido_tx", __func__); |
640 | r = FIDO_ERR_TX; | 637 | r = FIDO_ERR_TX; |
641 | goto fail; | 638 | goto fail; |
642 | } | 639 | } |
643 | if ((reply_len = fido_rx(dev, cmd, &reply, sizeof(reply), | 640 | if ((reply_len = fido_rx(dev, CTAP_CMD_MSG, &reply, |
644 | ms)) < 2) { | 641 | sizeof(reply), ms)) < 2) { |
645 | fido_log_debug("%s: fido_rx", __func__); | 642 | fido_log_debug("%s: fido_rx", __func__); |
646 | r = FIDO_ERR_RX; | 643 | r = FIDO_ERR_RX; |
647 | goto fail; | 644 | goto fail; |
@@ -687,6 +684,12 @@ u2f_authenticate_single(fido_dev_t *dev, const fido_blob_t *key_id, | |||
687 | goto fail; | 684 | goto fail; |
688 | } | 685 | } |
689 | 686 | ||
687 | if (fido_blob_set(&fa->stmt[idx].id, key_id->ptr, key_id->len) < 0) { | ||
688 | fido_log_debug("%s: fido_blob_set", __func__); | ||
689 | r = FIDO_ERR_INTERNAL; | ||
690 | goto fail; | ||
691 | } | ||
692 | |||
690 | if (fa->up == FIDO_OPT_FALSE) { | 693 | if (fa->up == FIDO_OPT_FALSE) { |
691 | fido_log_debug("%s: checking for key existence only", __func__); | 694 | fido_log_debug("%s: checking for key existence only", __func__); |
692 | r = FIDO_ERR_USER_PRESENCE_REQUIRED; | 695 | r = FIDO_ERR_USER_PRESENCE_REQUIRED; |
@@ -699,8 +702,7 @@ u2f_authenticate_single(fido_dev_t *dev, const fido_blob_t *key_id, | |||
699 | goto fail; | 702 | goto fail; |
700 | } | 703 | } |
701 | 704 | ||
702 | if (fido_blob_set(&fa->stmt[idx].id, key_id->ptr, key_id->len) < 0 || | 705 | if (fido_assert_set_authdata(fa, idx, ad.ptr, ad.len) != FIDO_OK || |
703 | fido_assert_set_authdata(fa, idx, ad.ptr, ad.len) != FIDO_OK || | ||
704 | fido_assert_set_sig(fa, idx, sig.ptr, sig.len) != FIDO_OK) { | 706 | fido_assert_set_sig(fa, idx, sig.ptr, sig.len) != FIDO_OK) { |
705 | fido_log_debug("%s: fido_assert_set", __func__); | 707 | fido_log_debug("%s: fido_assert_set", __func__); |
706 | r = FIDO_ERR_INTERNAL; | 708 | r = FIDO_ERR_INTERNAL; |
@@ -724,6 +726,7 @@ fail: | |||
724 | int | 726 | int |
725 | u2f_authenticate(fido_dev_t *dev, fido_assert_t *fa, int ms) | 727 | u2f_authenticate(fido_dev_t *dev, fido_assert_t *fa, int ms) |
726 | { | 728 | { |
729 | int nfound = 0; | ||
727 | int nauth_ok = 0; | 730 | int nauth_ok = 0; |
728 | int r; | 731 | int r; |
729 | 732 | ||
@@ -739,20 +742,30 @@ u2f_authenticate(fido_dev_t *dev, fido_assert_t *fa, int ms) | |||
739 | } | 742 | } |
740 | 743 | ||
741 | for (size_t i = 0; i < fa->allow_list.len; i++) { | 744 | for (size_t i = 0; i < fa->allow_list.len; i++) { |
742 | if ((r = u2f_authenticate_single(dev, &fa->allow_list.ptr[i], | 745 | switch ((r = u2f_authenticate_single(dev, |
743 | fa, nauth_ok, ms)) == FIDO_OK) { | 746 | &fa->allow_list.ptr[i], fa, nfound, ms))) { |
747 | case FIDO_OK: | ||
744 | nauth_ok++; | 748 | nauth_ok++; |
745 | } else if (r != FIDO_ERR_CREDENTIAL_EXCLUDED) { | 749 | /* FALLTHROUGH */ |
746 | fido_log_debug("%s: u2f_authenticate_single", __func__); | 750 | case FIDO_ERR_USER_PRESENCE_REQUIRED: |
747 | return (r); | 751 | nfound++; |
752 | break; | ||
753 | default: | ||
754 | if (r != FIDO_ERR_CREDENTIAL_EXCLUDED) { | ||
755 | fido_log_debug("%s: u2f_authenticate_single", | ||
756 | __func__); | ||
757 | return (r); | ||
758 | } | ||
759 | /* ignore credentials that don't exist */ | ||
748 | } | 760 | } |
749 | /* ignore credentials that don't exist */ | ||
750 | } | 761 | } |
751 | 762 | ||
752 | fa->stmt_len = nauth_ok; | 763 | fa->stmt_len = nfound; |
753 | 764 | ||
754 | if (nauth_ok == 0) | 765 | if (nfound == 0) |
755 | return (FIDO_ERR_NO_CREDENTIALS); | 766 | return (FIDO_ERR_NO_CREDENTIALS); |
767 | if (nauth_ok == 0) | ||
768 | return (FIDO_ERR_USER_PRESENCE_REQUIRED); | ||
756 | 769 | ||
757 | return (FIDO_OK); | 770 | return (FIDO_OK); |
758 | } | 771 | } |