summaryrefslogtreecommitdiff
path: root/sk-usbhid.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2019-12-30 09:24:45 +0000
committerDamien Miller <djm@mindrot.org>2019-12-30 21:01:51 +1100
commit43ce96427b76c4918e39af654e2fc9ee18d5d478 (patch)
treedfb3a5b32e02368f9739bb742e0aa858ced03701 /sk-usbhid.c
parentd433596736a2cd4818f538be11fc94783f5c5236 (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.c49
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
68struct sk_enroll_response { 73struct 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
420static int
421fidoerr_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
415int 434int
416sk_enroll(int alg, const uint8_t *challenge, size_t challenge_len, 435sk_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
736read_rks(const char *devpath, const char *pin, 756read_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
891int 906int
892sk_load_resident_keys(const char *pin, 907sk_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 */