diff options
Diffstat (limited to 'src/u2f.c')
-rw-r--r-- | src/u2f.c | 100 |
1 files changed, 91 insertions, 9 deletions
@@ -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 */ | ||
125 | static int | 126 | static int |
126 | send_dummy_register(fido_dev_t *dev, int ms) | 127 | send_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: | |||
726 | int | 727 | int |
727 | u2f_authenticate(fido_dev_t *dev, fido_assert_t *fa, int ms) | 728 | u2f_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 | |||
774 | int | ||
775 | u2f_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; | ||
817 | fail: | ||
818 | iso7816_free(&apdu); | ||
819 | |||
820 | return (r); | ||
821 | } | ||
822 | |||
823 | int | ||
824 | u2f_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 | } | ||