diff options
author | djm@openbsd.org <djm@openbsd.org> | 2019-12-30 09:24:45 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2019-12-30 21:01:51 +1100 |
commit | 43ce96427b76c4918e39af654e2fc9ee18d5d478 (patch) | |
tree | dfb3a5b32e02368f9739bb742e0aa858ced03701 /sk-usbhid.c | |
parent | d433596736a2cd4818f538be11fc94783f5c5236 (diff) |
upstream: translate and return error codes; retry on bad PIN
Define some well-known error codes in the SK API and pass
them back via ssh-sk-helper.
Use the new "wrong PIN" error code to retry PIN prompting during
ssh-keygen of resident keys.
feedback and ok markus@
OpenBSD-Commit-ID: 9663c6a2bb7a0bc8deaccc6c30d9a2983b481620
Diffstat (limited to 'sk-usbhid.c')
-rw-r--r-- | sk-usbhid.c | 49 |
1 files changed, 32 insertions, 17 deletions
diff --git a/sk-usbhid.c b/sk-usbhid.c index 54ce0bddf..22a4c5df5 100644 --- a/sk-usbhid.c +++ b/sk-usbhid.c | |||
@@ -65,6 +65,11 @@ | |||
65 | #define SK_ECDSA 0x00 | 65 | #define SK_ECDSA 0x00 |
66 | #define SK_ED25519 0x01 | 66 | #define SK_ED25519 0x01 |
67 | 67 | ||
68 | /* Error codes */ | ||
69 | #define SSH_SK_ERR_GENERAL -1 | ||
70 | #define SSH_SK_ERR_UNSUPPORTED -2 | ||
71 | #define SSH_SK_ERR_PIN_REQUIRED -3 | ||
72 | |||
68 | struct sk_enroll_response { | 73 | struct sk_enroll_response { |
69 | uint8_t *public_key; | 74 | uint8_t *public_key; |
70 | size_t public_key_len; | 75 | size_t public_key_len; |
@@ -412,6 +417,20 @@ pack_public_key(int alg, const fido_cred_t *cred, | |||
412 | } | 417 | } |
413 | } | 418 | } |
414 | 419 | ||
420 | static int | ||
421 | fidoerr_to_skerr(int fidoerr) | ||
422 | { | ||
423 | switch (fidoerr) { | ||
424 | case FIDO_ERR_UNSUPPORTED_OPTION: | ||
425 | return SSH_SK_ERR_UNSUPPORTED; | ||
426 | case FIDO_ERR_PIN_REQUIRED: | ||
427 | case FIDO_ERR_PIN_INVALID: | ||
428 | return SSH_SK_ERR_PIN_REQUIRED; | ||
429 | default: | ||
430 | return -1; | ||
431 | } | ||
432 | } | ||
433 | |||
415 | int | 434 | int |
416 | sk_enroll(int alg, const uint8_t *challenge, size_t challenge_len, | 435 | sk_enroll(int alg, const uint8_t *challenge, size_t challenge_len, |
417 | const char *application, uint8_t flags, const char *pin, | 436 | const char *application, uint8_t flags, const char *pin, |
@@ -424,7 +443,7 @@ sk_enroll(int alg, const uint8_t *challenge, size_t challenge_len, | |||
424 | struct sk_enroll_response *response = NULL; | 443 | struct sk_enroll_response *response = NULL; |
425 | size_t len; | 444 | size_t len; |
426 | int cose_alg; | 445 | int cose_alg; |
427 | int ret = -1; | 446 | int ret = SSH_SK_ERR_GENERAL; |
428 | int r; | 447 | int r; |
429 | char *device = NULL; | 448 | char *device = NULL; |
430 | 449 | ||
@@ -491,8 +510,9 @@ sk_enroll(int alg, const uint8_t *challenge, size_t challenge_len, | |||
491 | skdebug(__func__, "fido_dev_open: %s", fido_strerr(r)); | 510 | skdebug(__func__, "fido_dev_open: %s", fido_strerr(r)); |
492 | goto out; | 511 | goto out; |
493 | } | 512 | } |
494 | if ((r = fido_dev_make_cred(dev, cred, NULL)) != FIDO_OK) { | 513 | if ((r = fido_dev_make_cred(dev, cred, pin)) != FIDO_OK) { |
495 | skdebug(__func__, "fido_dev_make_cred: %s", fido_strerr(r)); | 514 | skdebug(__func__, "fido_dev_make_cred: %s", fido_strerr(r)); |
515 | ret = fidoerr_to_skerr(r); | ||
496 | goto out; | 516 | goto out; |
497 | } | 517 | } |
498 | if (fido_cred_x5c_ptr(cred) != NULL) { | 518 | if (fido_cred_x5c_ptr(cred) != NULL) { |
@@ -657,7 +677,7 @@ sk_sign(int alg, const uint8_t *message, size_t message_len, | |||
657 | fido_assert_t *assert = NULL; | 677 | fido_assert_t *assert = NULL; |
658 | fido_dev_t *dev = NULL; | 678 | fido_dev_t *dev = NULL; |
659 | struct sk_sign_response *response = NULL; | 679 | struct sk_sign_response *response = NULL; |
660 | int ret = -1; | 680 | int ret = SSH_SK_ERR_GENERAL; |
661 | int r; | 681 | int r; |
662 | 682 | ||
663 | #ifdef SK_DEBUG | 683 | #ifdef SK_DEBUG |
@@ -736,7 +756,7 @@ static int | |||
736 | read_rks(const char *devpath, const char *pin, | 756 | read_rks(const char *devpath, const char *pin, |
737 | struct sk_resident_key ***rksp, size_t *nrksp) | 757 | struct sk_resident_key ***rksp, size_t *nrksp) |
738 | { | 758 | { |
739 | int r = -1; | 759 | int ret = SSH_SK_ERR_GENERAL, r = -1; |
740 | fido_dev_t *dev = NULL; | 760 | fido_dev_t *dev = NULL; |
741 | fido_credman_metadata_t *metadata = NULL; | 761 | fido_credman_metadata_t *metadata = NULL; |
742 | fido_credman_rp_t *rp = NULL; | 762 | fido_credman_rp_t *rp = NULL; |
@@ -747,16 +767,15 @@ read_rks(const char *devpath, const char *pin, | |||
747 | 767 | ||
748 | if ((dev = fido_dev_new()) == NULL) { | 768 | if ((dev = fido_dev_new()) == NULL) { |
749 | skdebug(__func__, "fido_dev_new failed"); | 769 | skdebug(__func__, "fido_dev_new failed"); |
750 | return -1; | 770 | return ret; |
751 | } | 771 | } |
752 | if ((r = fido_dev_open(dev, devpath)) != FIDO_OK) { | 772 | if ((r = fido_dev_open(dev, devpath)) != FIDO_OK) { |
753 | skdebug(__func__, "fido_dev_open %s failed: %s", | 773 | skdebug(__func__, "fido_dev_open %s failed: %s", |
754 | devpath, fido_strerr(r)); | 774 | devpath, fido_strerr(r)); |
755 | fido_dev_free(&dev); | 775 | fido_dev_free(&dev); |
756 | return -1; | 776 | return ret; |
757 | } | 777 | } |
758 | if ((metadata = fido_credman_metadata_new()) == NULL) { | 778 | if ((metadata = fido_credman_metadata_new()) == NULL) { |
759 | r = -1; | ||
760 | skdebug(__func__, "alloc failed"); | 779 | skdebug(__func__, "alloc failed"); |
761 | goto out; | 780 | goto out; |
762 | } | 781 | } |
@@ -765,7 +784,7 @@ read_rks(const char *devpath, const char *pin, | |||
765 | if (r == FIDO_ERR_INVALID_COMMAND) { | 784 | if (r == FIDO_ERR_INVALID_COMMAND) { |
766 | skdebug(__func__, "device %s does not support " | 785 | skdebug(__func__, "device %s does not support " |
767 | "resident keys", devpath); | 786 | "resident keys", devpath); |
768 | r = 0; | 787 | ret = 0; |
769 | goto out; | 788 | goto out; |
770 | } | 789 | } |
771 | skdebug(__func__, "get metadata for %s failed: %s", | 790 | skdebug(__func__, "get metadata for %s failed: %s", |
@@ -776,7 +795,6 @@ read_rks(const char *devpath, const char *pin, | |||
776 | (unsigned long long)fido_credman_rk_existing(metadata), | 795 | (unsigned long long)fido_credman_rk_existing(metadata), |
777 | (unsigned long long)fido_credman_rk_remaining(metadata)); | 796 | (unsigned long long)fido_credman_rk_remaining(metadata)); |
778 | if ((rp = fido_credman_rp_new()) == NULL) { | 797 | if ((rp = fido_credman_rp_new()) == NULL) { |
779 | r = -1; | ||
780 | skdebug(__func__, "alloc rp failed"); | 798 | skdebug(__func__, "alloc rp failed"); |
781 | goto out; | 799 | goto out; |
782 | } | 800 | } |
@@ -801,7 +819,6 @@ read_rks(const char *devpath, const char *pin, | |||
801 | 819 | ||
802 | fido_credman_rk_free(&rk); | 820 | fido_credman_rk_free(&rk); |
803 | if ((rk = fido_credman_rk_new()) == NULL) { | 821 | if ((rk = fido_credman_rk_new()) == NULL) { |
804 | r = -1; | ||
805 | skdebug(__func__, "alloc rk failed"); | 822 | skdebug(__func__, "alloc rk failed"); |
806 | goto out; | 823 | goto out; |
807 | } | 824 | } |
@@ -831,7 +848,6 @@ read_rks(const char *devpath, const char *pin, | |||
831 | fido_cred_id_len(cred))) == NULL || | 848 | fido_cred_id_len(cred))) == NULL || |
832 | (srk->application = strdup(fido_credman_rp_id(rp, | 849 | (srk->application = strdup(fido_credman_rp_id(rp, |
833 | i))) == NULL) { | 850 | i))) == NULL) { |
834 | r = -1; | ||
835 | skdebug(__func__, "alloc sk_resident_key"); | 851 | skdebug(__func__, "alloc sk_resident_key"); |
836 | goto out; | 852 | goto out; |
837 | } | 853 | } |
@@ -862,7 +878,6 @@ read_rks(const char *devpath, const char *pin, | |||
862 | /* append */ | 878 | /* append */ |
863 | if ((tmp = recallocarray(*rksp, *nrksp, (*nrksp) + 1, | 879 | if ((tmp = recallocarray(*rksp, *nrksp, (*nrksp) + 1, |
864 | sizeof(**rksp))) == NULL) { | 880 | sizeof(**rksp))) == NULL) { |
865 | r = -1; | ||
866 | skdebug(__func__, "alloc rksp"); | 881 | skdebug(__func__, "alloc rksp"); |
867 | goto out; | 882 | goto out; |
868 | } | 883 | } |
@@ -872,7 +887,7 @@ read_rks(const char *devpath, const char *pin, | |||
872 | } | 887 | } |
873 | } | 888 | } |
874 | /* Success */ | 889 | /* Success */ |
875 | r = 0; | 890 | ret = 0; |
876 | out: | 891 | out: |
877 | if (srk != NULL) { | 892 | if (srk != NULL) { |
878 | free(srk->application); | 893 | free(srk->application); |
@@ -885,14 +900,14 @@ read_rks(const char *devpath, const char *pin, | |||
885 | fido_dev_close(dev); | 900 | fido_dev_close(dev); |
886 | fido_dev_free(&dev); | 901 | fido_dev_free(&dev); |
887 | fido_credman_metadata_free(&metadata); | 902 | fido_credman_metadata_free(&metadata); |
888 | return r; | 903 | return ret; |
889 | } | 904 | } |
890 | 905 | ||
891 | int | 906 | int |
892 | sk_load_resident_keys(const char *pin, | 907 | sk_load_resident_keys(const char *pin, |
893 | struct sk_resident_key ***rksp, size_t *nrksp) | 908 | struct sk_resident_key ***rksp, size_t *nrksp) |
894 | { | 909 | { |
895 | int r = -1; | 910 | int ret = SSH_SK_ERR_GENERAL, r = -1; |
896 | fido_dev_info_t *devlist = NULL; | 911 | fido_dev_info_t *devlist = NULL; |
897 | size_t i, ndev = 0, nrks = 0; | 912 | size_t i, ndev = 0, nrks = 0; |
898 | const fido_dev_info_t *di; | 913 | const fido_dev_info_t *di; |
@@ -924,7 +939,7 @@ sk_load_resident_keys(const char *pin, | |||
924 | } | 939 | } |
925 | } | 940 | } |
926 | /* success */ | 941 | /* success */ |
927 | r = 0; | 942 | ret = 0; |
928 | *rksp = rks; | 943 | *rksp = rks; |
929 | *nrksp = nrks; | 944 | *nrksp = nrks; |
930 | rks = NULL; | 945 | rks = NULL; |
@@ -938,7 +953,7 @@ sk_load_resident_keys(const char *pin, | |||
938 | } | 953 | } |
939 | free(rks); | 954 | free(rks); |
940 | fido_dev_info_free(&devlist, MAX_FIDO_DEVICES); | 955 | fido_dev_info_free(&devlist, MAX_FIDO_DEVICES); |
941 | return r; | 956 | return ret; |
942 | } | 957 | } |
943 | 958 | ||
944 | #endif /* ENABLE_SK_INTERNAL */ | 959 | #endif /* ENABLE_SK_INTERNAL */ |