summaryrefslogtreecommitdiff
path: root/src/u2f.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/u2f.c')
-rw-r--r--src/u2f.c69
1 files changed, 41 insertions, 28 deletions
diff --git a/src/u2f.c b/src/u2f.c
index 82b289f..19a959d 100644
--- a/src/u2f.c
+++ b/src/u2f.c
@@ -125,11 +125,10 @@ authdata_fake(const char *rp_id, uint8_t flags, uint32_t sigcount,
125static int 125static int
126send_dummy_register(fido_dev_t *dev, int ms) 126send_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
179key_lookup(fido_dev_t *dev, const char *rp_id, const fido_blob_t *key_id, 178key_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
285do_auth(fido_dev_t *dev, const fido_blob_t *cdh, const char *rp_id, 284do_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:
575int 573int
576u2f_register(fido_dev_t *dev, fido_cred_t *cred, int ms) 574u2f_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:
724int 726int
725u2f_authenticate(fido_dev_t *dev, fido_assert_t *fa, int ms) 727u2f_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}