summaryrefslogtreecommitdiff
path: root/src/u2f.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/u2f.c')
-rw-r--r--src/u2f.c100
1 files changed, 91 insertions, 9 deletions
diff --git a/src/u2f.c b/src/u2f.c
index 19a959d..3c6ea82 100644
--- a/src/u2f.c
+++ b/src/u2f.c
@@ -122,6 +122,7 @@ authdata_fake(const char *rp_id, uint8_t flags, uint32_t sigcount,
122 return (0); 122 return (0);
123} 123}
124 124
125/* TODO: use u2f_get_touch_begin & u2f_get_touch_status instead */
125static int 126static int
126send_dummy_register(fido_dev_t *dev, int ms) 127send_dummy_register(fido_dev_t *dev, int ms)
127{ 128{
@@ -160,7 +161,7 @@ send_dummy_register(fido_dev_t *dev, int ms)
160 r = FIDO_ERR_RX; 161 r = FIDO_ERR_RX;
161 goto fail; 162 goto fail;
162 } 163 }
163 if (usleep((ms == -1 ? 100 : ms) * 1000) < 0) { 164 if (usleep((unsigned)(ms == -1 ? 100 : ms) * 1000) < 0) {
164 fido_log_debug("%s: usleep", __func__); 165 fido_log_debug("%s: usleep", __func__);
165 r = FIDO_ERR_RX; 166 r = FIDO_ERR_RX;
166 goto fail; 167 goto fail;
@@ -204,8 +205,8 @@ key_lookup(fido_dev_t *dev, const char *rp_id, const fido_blob_t *key_id,
204 205
205 key_id_len = (uint8_t)key_id->len; 206 key_id_len = (uint8_t)key_id->len;
206 207
207 if ((apdu = iso7816_new(U2F_CMD_AUTH, U2F_AUTH_CHECK, 2 * 208 if ((apdu = iso7816_new(U2F_CMD_AUTH, U2F_AUTH_CHECK, (uint16_t)(2 *
208 SHA256_DIGEST_LENGTH + sizeof(key_id_len) + key_id_len)) == NULL || 209 SHA256_DIGEST_LENGTH + sizeof(key_id_len) + key_id_len))) == NULL ||
209 iso7816_add(apdu, &challenge, sizeof(challenge)) < 0 || 210 iso7816_add(apdu, &challenge, sizeof(challenge)) < 0 ||
210 iso7816_add(apdu, &rp_id_hash, sizeof(rp_id_hash)) < 0 || 211 iso7816_add(apdu, &rp_id_hash, sizeof(rp_id_hash)) < 0 ||
211 iso7816_add(apdu, &key_id_len, sizeof(key_id_len)) < 0 || 212 iso7816_add(apdu, &key_id_len, sizeof(key_id_len)) < 0 ||
@@ -312,8 +313,8 @@ do_auth(fido_dev_t *dev, const fido_blob_t *cdh, const char *rp_id,
312 313
313 key_id_len = (uint8_t)key_id->len; 314 key_id_len = (uint8_t)key_id->len;
314 315
315 if ((apdu = iso7816_new(U2F_CMD_AUTH, U2F_AUTH_SIGN, 2 * 316 if ((apdu = iso7816_new(U2F_CMD_AUTH, U2F_AUTH_SIGN, (uint16_t)(2 *
316 SHA256_DIGEST_LENGTH + sizeof(key_id_len) + key_id_len)) == NULL || 317 SHA256_DIGEST_LENGTH + sizeof(key_id_len) + key_id_len))) == NULL ||
317 iso7816_add(apdu, cdh->ptr, cdh->len) < 0 || 318 iso7816_add(apdu, cdh->ptr, cdh->len) < 0 ||
318 iso7816_add(apdu, &rp_id_hash, sizeof(rp_id_hash)) < 0 || 319 iso7816_add(apdu, &rp_id_hash, sizeof(rp_id_hash)) < 0 ||
319 iso7816_add(apdu, &key_id_len, sizeof(key_id_len)) < 0 || 320 iso7816_add(apdu, &key_id_len, sizeof(key_id_len)) < 0 ||
@@ -336,7 +337,7 @@ do_auth(fido_dev_t *dev, const fido_blob_t *cdh, const char *rp_id,
336 r = FIDO_ERR_RX; 337 r = FIDO_ERR_RX;
337 goto fail; 338 goto fail;
338 } 339 }
339 if (usleep((ms == -1 ? 100 : ms) * 1000) < 0) { 340 if (usleep((unsigned)(ms == -1 ? 100 : ms) * 1000) < 0) {
340 fido_log_debug("%s: usleep", __func__); 341 fido_log_debug("%s: usleep", __func__);
341 r = FIDO_ERR_RX; 342 r = FIDO_ERR_RX;
342 goto fail; 343 goto fail;
@@ -643,7 +644,7 @@ u2f_register(fido_dev_t *dev, fido_cred_t *cred, int ms)
643 r = FIDO_ERR_RX; 644 r = FIDO_ERR_RX;
644 goto fail; 645 goto fail;
645 } 646 }
646 if (usleep((ms == -1 ? 100 : ms) * 1000) < 0) { 647 if (usleep((unsigned)(ms == -1 ? 100 : ms) * 1000) < 0) {
647 fido_log_debug("%s: usleep", __func__); 648 fido_log_debug("%s: usleep", __func__);
648 r = FIDO_ERR_RX; 649 r = FIDO_ERR_RX;
649 goto fail; 650 goto fail;
@@ -726,8 +727,8 @@ fail:
726int 727int
727u2f_authenticate(fido_dev_t *dev, fido_assert_t *fa, int ms) 728u2f_authenticate(fido_dev_t *dev, fido_assert_t *fa, int ms)
728{ 729{
729 int nfound = 0; 730 size_t nfound = 0;
730 int nauth_ok = 0; 731 size_t nauth_ok = 0;
731 int r; 732 int r;
732 733
733 if (fa->uv == FIDO_OPT_TRUE || fa->allow_list.ptr == NULL) { 734 if (fa->uv == FIDO_OPT_TRUE || fa->allow_list.ptr == NULL) {
@@ -769,3 +770,84 @@ u2f_authenticate(fido_dev_t *dev, fido_assert_t *fa, int ms)
769 770
770 return (FIDO_OK); 771 return (FIDO_OK);
771} 772}
773
774int
775u2f_get_touch_begin(fido_dev_t *dev)
776{
777 iso7816_apdu_t *apdu = NULL;
778 const char *clientdata = FIDO_DUMMY_CLIENTDATA;
779 const char *rp_id = FIDO_DUMMY_RP_ID;
780 unsigned char clientdata_hash[SHA256_DIGEST_LENGTH];
781 unsigned char rp_id_hash[SHA256_DIGEST_LENGTH];
782 unsigned char reply[FIDO_MAXMSG];
783 int r;
784
785 memset(&clientdata_hash, 0, sizeof(clientdata_hash));
786 memset(&rp_id_hash, 0, sizeof(rp_id_hash));
787
788 if (SHA256((const void *)clientdata, strlen(clientdata),
789 clientdata_hash) != clientdata_hash || SHA256((const void *)rp_id,
790 strlen(rp_id), rp_id_hash) != rp_id_hash) {
791 fido_log_debug("%s: sha256", __func__);
792 return (FIDO_ERR_INTERNAL);
793 }
794
795 if ((apdu = iso7816_new(U2F_CMD_REGISTER, 0, 2 *
796 SHA256_DIGEST_LENGTH)) == NULL ||
797 iso7816_add(apdu, clientdata_hash, sizeof(clientdata_hash)) < 0 ||
798 iso7816_add(apdu, rp_id_hash, sizeof(rp_id_hash)) < 0) {
799 fido_log_debug("%s: iso7816", __func__);
800 r = FIDO_ERR_INTERNAL;
801 goto fail;
802 }
803
804 if (dev->attr.flags & FIDO_CAP_WINK) {
805 fido_tx(dev, CTAP_CMD_WINK, NULL, 0);
806 fido_rx(dev, CTAP_CMD_WINK, &reply, sizeof(reply), 200);
807 }
808
809 if (fido_tx(dev, CTAP_CMD_MSG, iso7816_ptr(apdu),
810 iso7816_len(apdu)) < 0) {
811 fido_log_debug("%s: fido_tx", __func__);
812 r = FIDO_ERR_TX;
813 goto fail;
814 }
815
816 r = FIDO_OK;
817fail:
818 iso7816_free(&apdu);
819
820 return (r);
821}
822
823int
824u2f_get_touch_status(fido_dev_t *dev, int *touched, int ms)
825{
826 unsigned char reply[FIDO_MAXMSG];
827 int reply_len;
828 int r;
829
830 if ((reply_len = fido_rx(dev, CTAP_CMD_MSG, &reply, sizeof(reply),
831 ms)) < 2) {
832 fido_log_debug("%s: fido_rx", __func__);
833 return (FIDO_OK); /* ignore */
834 }
835
836 switch ((reply[reply_len - 2] << 8) | reply[reply_len - 1]) {
837 case SW_CONDITIONS_NOT_SATISFIED:
838 if ((r = u2f_get_touch_begin(dev)) != FIDO_OK) {
839 fido_log_debug("%s: u2f_get_touch_begin", __func__);
840 return (r);
841 }
842 *touched = 0;
843 break;
844 case SW_NO_ERROR:
845 *touched = 1;
846 break;
847 default:
848 fido_log_debug("%s: unexpected sw", __func__);
849 return (FIDO_ERR_RX);
850 }
851
852 return (FIDO_OK);
853}