diff options
author | Colin Watson <cjwatson@debian.org> | 2020-02-21 11:57:14 +0000 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2020-02-21 11:57:14 +0000 |
commit | f0de78bd4f29fa688c5df116f3f9cd43543a76d0 (patch) | |
tree | 856b0dee3f2764c13a32dad5ffe2424fab7fef41 /sshkey.c | |
parent | 4213eec74e74de6310c27a40c3e9759a08a73996 (diff) | |
parent | 8aa3455b16fddea4c0144a7c4a1edb10ec67dcc8 (diff) |
Import openssh_8.2p1.orig.tar.gz
Diffstat (limited to 'sshkey.c')
-rw-r--r-- | sshkey.c | 509 |
1 files changed, 414 insertions, 95 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshkey.c,v 1.84 2019/10/09 00:04:42 djm Exp $ */ | 1 | /* $OpenBSD: sshkey.c,v 1.99 2020/01/21 05:56:56 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2008 Alexander von Gernler. All rights reserved. | 4 | * Copyright (c) 2008 Alexander von Gernler. All rights reserved. |
@@ -57,6 +57,7 @@ | |||
57 | #define SSHKEY_INTERNAL | 57 | #define SSHKEY_INTERNAL |
58 | #include "sshkey.h" | 58 | #include "sshkey.h" |
59 | #include "match.h" | 59 | #include "match.h" |
60 | #include "ssh-sk.h" | ||
60 | 61 | ||
61 | #ifdef WITH_XMSS | 62 | #ifdef WITH_XMSS |
62 | #include "sshkey-xmss.h" | 63 | #include "sshkey-xmss.h" |
@@ -106,6 +107,10 @@ static const struct keytype keytypes[] = { | |||
106 | { "ssh-ed25519", "ED25519", NULL, KEY_ED25519, 0, 0, 0 }, | 107 | { "ssh-ed25519", "ED25519", NULL, KEY_ED25519, 0, 0, 0 }, |
107 | { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT", NULL, | 108 | { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT", NULL, |
108 | KEY_ED25519_CERT, 0, 1, 0 }, | 109 | KEY_ED25519_CERT, 0, 1, 0 }, |
110 | { "sk-ssh-ed25519@openssh.com", "ED25519-SK", NULL, | ||
111 | KEY_ED25519_SK, 0, 0, 0 }, | ||
112 | { "sk-ssh-ed25519-cert-v01@openssh.com", "ED25519-SK-CERT", NULL, | ||
113 | KEY_ED25519_SK_CERT, 0, 1, 0 }, | ||
109 | #ifdef WITH_XMSS | 114 | #ifdef WITH_XMSS |
110 | { "ssh-xmss@openssh.com", "XMSS", NULL, KEY_XMSS, 0, 0, 0 }, | 115 | { "ssh-xmss@openssh.com", "XMSS", NULL, KEY_XMSS, 0, 0, 0 }, |
111 | { "ssh-xmss-cert-v01@openssh.com", "XMSS-CERT", NULL, | 116 | { "ssh-xmss-cert-v01@openssh.com", "XMSS-CERT", NULL, |
@@ -125,6 +130,8 @@ static const struct keytype keytypes[] = { | |||
125 | { "ecdsa-sha2-nistp521", "ECDSA", NULL, | 130 | { "ecdsa-sha2-nistp521", "ECDSA", NULL, |
126 | KEY_ECDSA, NID_secp521r1, 0, 0 }, | 131 | KEY_ECDSA, NID_secp521r1, 0, 0 }, |
127 | # endif /* OPENSSL_HAS_NISTP521 */ | 132 | # endif /* OPENSSL_HAS_NISTP521 */ |
133 | { "sk-ecdsa-sha2-nistp256@openssh.com", "ECDSA-SK", NULL, | ||
134 | KEY_ECDSA_SK, NID_X9_62_prime256v1, 0, 0 }, | ||
128 | # endif /* OPENSSL_HAS_ECC */ | 135 | # endif /* OPENSSL_HAS_ECC */ |
129 | { "ssh-rsa-cert-v01@openssh.com", "RSA-CERT", NULL, | 136 | { "ssh-rsa-cert-v01@openssh.com", "RSA-CERT", NULL, |
130 | KEY_RSA_CERT, 0, 1, 0 }, | 137 | KEY_RSA_CERT, 0, 1, 0 }, |
@@ -143,6 +150,8 @@ static const struct keytype keytypes[] = { | |||
143 | { "ecdsa-sha2-nistp521-cert-v01@openssh.com", "ECDSA-CERT", NULL, | 150 | { "ecdsa-sha2-nistp521-cert-v01@openssh.com", "ECDSA-CERT", NULL, |
144 | KEY_ECDSA_CERT, NID_secp521r1, 1, 0 }, | 151 | KEY_ECDSA_CERT, NID_secp521r1, 1, 0 }, |
145 | # endif /* OPENSSL_HAS_NISTP521 */ | 152 | # endif /* OPENSSL_HAS_NISTP521 */ |
153 | { "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com", "ECDSA-SK-CERT", NULL, | ||
154 | KEY_ECDSA_SK_CERT, NID_X9_62_prime256v1, 1, 0 }, | ||
146 | # endif /* OPENSSL_HAS_ECC */ | 155 | # endif /* OPENSSL_HAS_ECC */ |
147 | #endif /* WITH_OPENSSL */ | 156 | #endif /* WITH_OPENSSL */ |
148 | { NULL, NULL, NULL, -1, -1, 0, 0 } | 157 | { NULL, NULL, NULL, -1, -1, 0, 0 } |
@@ -211,13 +220,26 @@ sshkey_type_from_name(const char *name) | |||
211 | return KEY_UNSPEC; | 220 | return KEY_UNSPEC; |
212 | } | 221 | } |
213 | 222 | ||
223 | static int | ||
224 | key_type_is_ecdsa_variant(int type) | ||
225 | { | ||
226 | switch (type) { | ||
227 | case KEY_ECDSA: | ||
228 | case KEY_ECDSA_CERT: | ||
229 | case KEY_ECDSA_SK: | ||
230 | case KEY_ECDSA_SK_CERT: | ||
231 | return 1; | ||
232 | } | ||
233 | return 0; | ||
234 | } | ||
235 | |||
214 | int | 236 | int |
215 | sshkey_ecdsa_nid_from_name(const char *name) | 237 | sshkey_ecdsa_nid_from_name(const char *name) |
216 | { | 238 | { |
217 | const struct keytype *kt; | 239 | const struct keytype *kt; |
218 | 240 | ||
219 | for (kt = keytypes; kt->type != -1; kt++) { | 241 | for (kt = keytypes; kt->type != -1; kt++) { |
220 | if (kt->type != KEY_ECDSA && kt->type != KEY_ECDSA_CERT) | 242 | if (!key_type_is_ecdsa_variant(kt->type)) |
221 | continue; | 243 | continue; |
222 | if (kt->name != NULL && strcmp(name, kt->name) == 0) | 244 | if (kt->name != NULL && strcmp(name, kt->name) == 0) |
223 | return kt->nid; | 245 | return kt->nid; |
@@ -313,10 +335,14 @@ sshkey_size(const struct sshkey *k) | |||
313 | return BN_num_bits(dsa_p); | 335 | return BN_num_bits(dsa_p); |
314 | case KEY_ECDSA: | 336 | case KEY_ECDSA: |
315 | case KEY_ECDSA_CERT: | 337 | case KEY_ECDSA_CERT: |
338 | case KEY_ECDSA_SK: | ||
339 | case KEY_ECDSA_SK_CERT: | ||
316 | return sshkey_curve_nid_to_bits(k->ecdsa_nid); | 340 | return sshkey_curve_nid_to_bits(k->ecdsa_nid); |
317 | #endif /* WITH_OPENSSL */ | 341 | #endif /* WITH_OPENSSL */ |
318 | case KEY_ED25519: | 342 | case KEY_ED25519: |
319 | case KEY_ED25519_CERT: | 343 | case KEY_ED25519_CERT: |
344 | case KEY_ED25519_SK: | ||
345 | case KEY_ED25519_SK_CERT: | ||
320 | case KEY_XMSS: | 346 | case KEY_XMSS: |
321 | case KEY_XMSS_CERT: | 347 | case KEY_XMSS_CERT: |
322 | return 256; /* XXX */ | 348 | return 256; /* XXX */ |
@@ -331,7 +357,9 @@ sshkey_type_is_valid_ca(int type) | |||
331 | case KEY_RSA: | 357 | case KEY_RSA: |
332 | case KEY_DSA: | 358 | case KEY_DSA: |
333 | case KEY_ECDSA: | 359 | case KEY_ECDSA: |
360 | case KEY_ECDSA_SK: | ||
334 | case KEY_ED25519: | 361 | case KEY_ED25519: |
362 | case KEY_ED25519_SK: | ||
335 | case KEY_XMSS: | 363 | case KEY_XMSS: |
336 | return 1; | 364 | return 1; |
337 | default: | 365 | default: |
@@ -347,6 +375,20 @@ sshkey_is_cert(const struct sshkey *k) | |||
347 | return sshkey_type_is_cert(k->type); | 375 | return sshkey_type_is_cert(k->type); |
348 | } | 376 | } |
349 | 377 | ||
378 | int | ||
379 | sshkey_is_sk(const struct sshkey *k) | ||
380 | { | ||
381 | if (k == NULL) | ||
382 | return 0; | ||
383 | switch (sshkey_type_plain(k->type)) { | ||
384 | case KEY_ECDSA_SK: | ||
385 | case KEY_ED25519_SK: | ||
386 | return 1; | ||
387 | default: | ||
388 | return 0; | ||
389 | } | ||
390 | } | ||
391 | |||
350 | /* Return the cert-less equivalent to a certified key type */ | 392 | /* Return the cert-less equivalent to a certified key type */ |
351 | int | 393 | int |
352 | sshkey_type_plain(int type) | 394 | sshkey_type_plain(int type) |
@@ -358,8 +400,12 @@ sshkey_type_plain(int type) | |||
358 | return KEY_DSA; | 400 | return KEY_DSA; |
359 | case KEY_ECDSA_CERT: | 401 | case KEY_ECDSA_CERT: |
360 | return KEY_ECDSA; | 402 | return KEY_ECDSA; |
403 | case KEY_ECDSA_SK_CERT: | ||
404 | return KEY_ECDSA_SK; | ||
361 | case KEY_ED25519_CERT: | 405 | case KEY_ED25519_CERT: |
362 | return KEY_ED25519; | 406 | return KEY_ED25519; |
407 | case KEY_ED25519_SK_CERT: | ||
408 | return KEY_ED25519_SK; | ||
363 | case KEY_XMSS_CERT: | 409 | case KEY_XMSS_CERT: |
364 | return KEY_XMSS; | 410 | return KEY_XMSS; |
365 | default: | 411 | default: |
@@ -533,11 +579,15 @@ sshkey_new(int type) | |||
533 | break; | 579 | break; |
534 | case KEY_ECDSA: | 580 | case KEY_ECDSA: |
535 | case KEY_ECDSA_CERT: | 581 | case KEY_ECDSA_CERT: |
582 | case KEY_ECDSA_SK: | ||
583 | case KEY_ECDSA_SK_CERT: | ||
536 | /* Cannot do anything until we know the group */ | 584 | /* Cannot do anything until we know the group */ |
537 | break; | 585 | break; |
538 | #endif /* WITH_OPENSSL */ | 586 | #endif /* WITH_OPENSSL */ |
539 | case KEY_ED25519: | 587 | case KEY_ED25519: |
540 | case KEY_ED25519_CERT: | 588 | case KEY_ED25519_CERT: |
589 | case KEY_ED25519_SK: | ||
590 | case KEY_ED25519_SK_CERT: | ||
541 | case KEY_XMSS: | 591 | case KEY_XMSS: |
542 | case KEY_XMSS_CERT: | 592 | case KEY_XMSS_CERT: |
543 | /* no need to prealloc */ | 593 | /* no need to prealloc */ |
@@ -577,6 +627,12 @@ sshkey_free(struct sshkey *k) | |||
577 | k->dsa = NULL; | 627 | k->dsa = NULL; |
578 | break; | 628 | break; |
579 | # ifdef OPENSSL_HAS_ECC | 629 | # ifdef OPENSSL_HAS_ECC |
630 | case KEY_ECDSA_SK: | ||
631 | case KEY_ECDSA_SK_CERT: | ||
632 | free(k->sk_application); | ||
633 | sshbuf_free(k->sk_key_handle); | ||
634 | sshbuf_free(k->sk_reserved); | ||
635 | /* FALLTHROUGH */ | ||
580 | case KEY_ECDSA: | 636 | case KEY_ECDSA: |
581 | case KEY_ECDSA_CERT: | 637 | case KEY_ECDSA_CERT: |
582 | EC_KEY_free(k->ecdsa); | 638 | EC_KEY_free(k->ecdsa); |
@@ -584,6 +640,12 @@ sshkey_free(struct sshkey *k) | |||
584 | break; | 640 | break; |
585 | # endif /* OPENSSL_HAS_ECC */ | 641 | # endif /* OPENSSL_HAS_ECC */ |
586 | #endif /* WITH_OPENSSL */ | 642 | #endif /* WITH_OPENSSL */ |
643 | case KEY_ED25519_SK: | ||
644 | case KEY_ED25519_SK_CERT: | ||
645 | free(k->sk_application); | ||
646 | sshbuf_free(k->sk_key_handle); | ||
647 | sshbuf_free(k->sk_reserved); | ||
648 | /* FALLTHROUGH */ | ||
587 | case KEY_ED25519: | 649 | case KEY_ED25519: |
588 | case KEY_ED25519_CERT: | 650 | case KEY_ED25519_CERT: |
589 | freezero(k->ed25519_pk, ED25519_PK_SZ); | 651 | freezero(k->ed25519_pk, ED25519_PK_SZ); |
@@ -644,9 +706,6 @@ sshkey_equal_public(const struct sshkey *a, const struct sshkey *b) | |||
644 | const BIGNUM *rsa_e_b, *rsa_n_b; | 706 | const BIGNUM *rsa_e_b, *rsa_n_b; |
645 | const BIGNUM *dsa_p_a, *dsa_q_a, *dsa_g_a, *dsa_pub_key_a; | 707 | const BIGNUM *dsa_p_a, *dsa_q_a, *dsa_g_a, *dsa_pub_key_a; |
646 | const BIGNUM *dsa_p_b, *dsa_q_b, *dsa_g_b, *dsa_pub_key_b; | 708 | const BIGNUM *dsa_p_b, *dsa_q_b, *dsa_g_b, *dsa_pub_key_b; |
647 | # if defined(OPENSSL_HAS_ECC) | ||
648 | BN_CTX *bnctx; | ||
649 | # endif /* OPENSSL_HAS_ECC */ | ||
650 | #endif /* WITH_OPENSSL */ | 709 | #endif /* WITH_OPENSSL */ |
651 | 710 | ||
652 | if (a == NULL || b == NULL || | 711 | if (a == NULL || b == NULL || |
@@ -676,26 +735,35 @@ sshkey_equal_public(const struct sshkey *a, const struct sshkey *b) | |||
676 | BN_cmp(dsa_g_a, dsa_g_b) == 0 && | 735 | BN_cmp(dsa_g_a, dsa_g_b) == 0 && |
677 | BN_cmp(dsa_pub_key_a, dsa_pub_key_b) == 0; | 736 | BN_cmp(dsa_pub_key_a, dsa_pub_key_b) == 0; |
678 | # ifdef OPENSSL_HAS_ECC | 737 | # ifdef OPENSSL_HAS_ECC |
738 | case KEY_ECDSA_SK: | ||
739 | case KEY_ECDSA_SK_CERT: | ||
740 | if (a->sk_application == NULL || b->sk_application == NULL) | ||
741 | return 0; | ||
742 | if (strcmp(a->sk_application, b->sk_application) != 0) | ||
743 | return 0; | ||
744 | /* FALLTHROUGH */ | ||
679 | case KEY_ECDSA_CERT: | 745 | case KEY_ECDSA_CERT: |
680 | case KEY_ECDSA: | 746 | case KEY_ECDSA: |
681 | if (a->ecdsa == NULL || b->ecdsa == NULL || | 747 | if (a->ecdsa == NULL || b->ecdsa == NULL || |
682 | EC_KEY_get0_public_key(a->ecdsa) == NULL || | 748 | EC_KEY_get0_public_key(a->ecdsa) == NULL || |
683 | EC_KEY_get0_public_key(b->ecdsa) == NULL) | 749 | EC_KEY_get0_public_key(b->ecdsa) == NULL) |
684 | return 0; | 750 | return 0; |
685 | if ((bnctx = BN_CTX_new()) == NULL) | ||
686 | return 0; | ||
687 | if (EC_GROUP_cmp(EC_KEY_get0_group(a->ecdsa), | 751 | if (EC_GROUP_cmp(EC_KEY_get0_group(a->ecdsa), |
688 | EC_KEY_get0_group(b->ecdsa), bnctx) != 0 || | 752 | EC_KEY_get0_group(b->ecdsa), NULL) != 0 || |
689 | EC_POINT_cmp(EC_KEY_get0_group(a->ecdsa), | 753 | EC_POINT_cmp(EC_KEY_get0_group(a->ecdsa), |
690 | EC_KEY_get0_public_key(a->ecdsa), | 754 | EC_KEY_get0_public_key(a->ecdsa), |
691 | EC_KEY_get0_public_key(b->ecdsa), bnctx) != 0) { | 755 | EC_KEY_get0_public_key(b->ecdsa), NULL) != 0) |
692 | BN_CTX_free(bnctx); | ||
693 | return 0; | 756 | return 0; |
694 | } | ||
695 | BN_CTX_free(bnctx); | ||
696 | return 1; | 757 | return 1; |
697 | # endif /* OPENSSL_HAS_ECC */ | 758 | # endif /* OPENSSL_HAS_ECC */ |
698 | #endif /* WITH_OPENSSL */ | 759 | #endif /* WITH_OPENSSL */ |
760 | case KEY_ED25519_SK: | ||
761 | case KEY_ED25519_SK_CERT: | ||
762 | if (a->sk_application == NULL || b->sk_application == NULL) | ||
763 | return 0; | ||
764 | if (strcmp(a->sk_application, b->sk_application) != 0) | ||
765 | return 0; | ||
766 | /* FALLTHROUGH */ | ||
699 | case KEY_ED25519: | 767 | case KEY_ED25519: |
700 | case KEY_ED25519_CERT: | 768 | case KEY_ED25519_CERT: |
701 | return a->ed25519_pk != NULL && b->ed25519_pk != NULL && | 769 | return a->ed25519_pk != NULL && b->ed25519_pk != NULL && |
@@ -751,9 +819,11 @@ to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain, | |||
751 | #ifdef WITH_OPENSSL | 819 | #ifdef WITH_OPENSSL |
752 | case KEY_DSA_CERT: | 820 | case KEY_DSA_CERT: |
753 | case KEY_ECDSA_CERT: | 821 | case KEY_ECDSA_CERT: |
822 | case KEY_ECDSA_SK_CERT: | ||
754 | case KEY_RSA_CERT: | 823 | case KEY_RSA_CERT: |
755 | #endif /* WITH_OPENSSL */ | 824 | #endif /* WITH_OPENSSL */ |
756 | case KEY_ED25519_CERT: | 825 | case KEY_ED25519_CERT: |
826 | case KEY_ED25519_SK_CERT: | ||
757 | #ifdef WITH_XMSS | 827 | #ifdef WITH_XMSS |
758 | case KEY_XMSS_CERT: | 828 | case KEY_XMSS_CERT: |
759 | #endif /* WITH_XMSS */ | 829 | #endif /* WITH_XMSS */ |
@@ -777,6 +847,7 @@ to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain, | |||
777 | break; | 847 | break; |
778 | # ifdef OPENSSL_HAS_ECC | 848 | # ifdef OPENSSL_HAS_ECC |
779 | case KEY_ECDSA: | 849 | case KEY_ECDSA: |
850 | case KEY_ECDSA_SK: | ||
780 | if (key->ecdsa == NULL) | 851 | if (key->ecdsa == NULL) |
781 | return SSH_ERR_INVALID_ARGUMENT; | 852 | return SSH_ERR_INVALID_ARGUMENT; |
782 | if ((ret = sshbuf_put_cstring(b, typename)) != 0 || | 853 | if ((ret = sshbuf_put_cstring(b, typename)) != 0 || |
@@ -784,6 +855,11 @@ to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain, | |||
784 | sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 || | 855 | sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 || |
785 | (ret = sshbuf_put_eckey(b, key->ecdsa)) != 0) | 856 | (ret = sshbuf_put_eckey(b, key->ecdsa)) != 0) |
786 | return ret; | 857 | return ret; |
858 | if (type == KEY_ECDSA_SK) { | ||
859 | if ((ret = sshbuf_put_cstring(b, | ||
860 | key->sk_application)) != 0) | ||
861 | return ret; | ||
862 | } | ||
787 | break; | 863 | break; |
788 | # endif | 864 | # endif |
789 | case KEY_RSA: | 865 | case KEY_RSA: |
@@ -797,12 +873,18 @@ to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain, | |||
797 | break; | 873 | break; |
798 | #endif /* WITH_OPENSSL */ | 874 | #endif /* WITH_OPENSSL */ |
799 | case KEY_ED25519: | 875 | case KEY_ED25519: |
876 | case KEY_ED25519_SK: | ||
800 | if (key->ed25519_pk == NULL) | 877 | if (key->ed25519_pk == NULL) |
801 | return SSH_ERR_INVALID_ARGUMENT; | 878 | return SSH_ERR_INVALID_ARGUMENT; |
802 | if ((ret = sshbuf_put_cstring(b, typename)) != 0 || | 879 | if ((ret = sshbuf_put_cstring(b, typename)) != 0 || |
803 | (ret = sshbuf_put_string(b, | 880 | (ret = sshbuf_put_string(b, |
804 | key->ed25519_pk, ED25519_PK_SZ)) != 0) | 881 | key->ed25519_pk, ED25519_PK_SZ)) != 0) |
805 | return ret; | 882 | return ret; |
883 | if (type == KEY_ED25519_SK) { | ||
884 | if ((ret = sshbuf_put_cstring(b, | ||
885 | key->sk_application)) != 0) | ||
886 | return ret; | ||
887 | } | ||
806 | break; | 888 | break; |
807 | #ifdef WITH_XMSS | 889 | #ifdef WITH_XMSS |
808 | case KEY_XMSS: | 890 | case KEY_XMSS: |
@@ -1217,7 +1299,7 @@ peek_type_nid(const char *s, size_t l, int *nid) | |||
1217 | continue; | 1299 | continue; |
1218 | if (memcmp(s, kt->name, l) == 0) { | 1300 | if (memcmp(s, kt->name, l) == 0) { |
1219 | *nid = -1; | 1301 | *nid = -1; |
1220 | if (kt->type == KEY_ECDSA || kt->type == KEY_ECDSA_CERT) | 1302 | if (key_type_is_ecdsa_variant(kt->type)) |
1221 | *nid = kt->nid; | 1303 | *nid = kt->nid; |
1222 | return kt->type; | 1304 | return kt->type; |
1223 | } | 1305 | } |
@@ -1243,11 +1325,15 @@ sshkey_read(struct sshkey *ret, char **cpp) | |||
1243 | case KEY_RSA: | 1325 | case KEY_RSA: |
1244 | case KEY_DSA: | 1326 | case KEY_DSA: |
1245 | case KEY_ECDSA: | 1327 | case KEY_ECDSA: |
1328 | case KEY_ECDSA_SK: | ||
1246 | case KEY_ED25519: | 1329 | case KEY_ED25519: |
1330 | case KEY_ED25519_SK: | ||
1247 | case KEY_DSA_CERT: | 1331 | case KEY_DSA_CERT: |
1248 | case KEY_ECDSA_CERT: | 1332 | case KEY_ECDSA_CERT: |
1333 | case KEY_ECDSA_SK_CERT: | ||
1249 | case KEY_RSA_CERT: | 1334 | case KEY_RSA_CERT: |
1250 | case KEY_ED25519_CERT: | 1335 | case KEY_ED25519_CERT: |
1336 | case KEY_ED25519_SK_CERT: | ||
1251 | #ifdef WITH_XMSS | 1337 | #ifdef WITH_XMSS |
1252 | case KEY_XMSS: | 1338 | case KEY_XMSS: |
1253 | case KEY_XMSS_CERT: | 1339 | case KEY_XMSS_CERT: |
@@ -1302,7 +1388,7 @@ sshkey_read(struct sshkey *ret, char **cpp) | |||
1302 | sshkey_free(k); | 1388 | sshkey_free(k); |
1303 | return SSH_ERR_KEY_TYPE_MISMATCH; | 1389 | return SSH_ERR_KEY_TYPE_MISMATCH; |
1304 | } | 1390 | } |
1305 | if (sshkey_type_plain(type) == KEY_ECDSA && curve_nid != k->ecdsa_nid) { | 1391 | if (key_type_is_ecdsa_variant(type) && curve_nid != k->ecdsa_nid) { |
1306 | sshkey_free(k); | 1392 | sshkey_free(k); |
1307 | return SSH_ERR_EC_CURVE_MISMATCH; | 1393 | return SSH_ERR_EC_CURVE_MISMATCH; |
1308 | } | 1394 | } |
@@ -1348,6 +1434,19 @@ sshkey_read(struct sshkey *ret, char **cpp) | |||
1348 | sshkey_dump_ec_key(ret->ecdsa); | 1434 | sshkey_dump_ec_key(ret->ecdsa); |
1349 | #endif | 1435 | #endif |
1350 | break; | 1436 | break; |
1437 | case KEY_ECDSA_SK: | ||
1438 | EC_KEY_free(ret->ecdsa); | ||
1439 | ret->ecdsa = k->ecdsa; | ||
1440 | ret->ecdsa_nid = k->ecdsa_nid; | ||
1441 | ret->sk_application = k->sk_application; | ||
1442 | k->ecdsa = NULL; | ||
1443 | k->ecdsa_nid = -1; | ||
1444 | k->sk_application = NULL; | ||
1445 | #ifdef DEBUG_PK | ||
1446 | sshkey_dump_ec_key(ret->ecdsa); | ||
1447 | fprintf(stderr, "App: %s\n", ret->sk_application); | ||
1448 | #endif | ||
1449 | break; | ||
1351 | # endif /* OPENSSL_HAS_ECC */ | 1450 | # endif /* OPENSSL_HAS_ECC */ |
1352 | #endif /* WITH_OPENSSL */ | 1451 | #endif /* WITH_OPENSSL */ |
1353 | case KEY_ED25519: | 1452 | case KEY_ED25519: |
@@ -1358,6 +1457,13 @@ sshkey_read(struct sshkey *ret, char **cpp) | |||
1358 | /* XXX */ | 1457 | /* XXX */ |
1359 | #endif | 1458 | #endif |
1360 | break; | 1459 | break; |
1460 | case KEY_ED25519_SK: | ||
1461 | freezero(ret->ed25519_pk, ED25519_PK_SZ); | ||
1462 | ret->ed25519_pk = k->ed25519_pk; | ||
1463 | ret->sk_application = k->sk_application; | ||
1464 | k->ed25519_pk = NULL; | ||
1465 | k->sk_application = NULL; | ||
1466 | break; | ||
1361 | #ifdef WITH_XMSS | 1467 | #ifdef WITH_XMSS |
1362 | case KEY_XMSS: | 1468 | case KEY_XMSS: |
1363 | free(ret->xmss_pk); | 1469 | free(ret->xmss_pk); |
@@ -1546,7 +1652,6 @@ sshkey_ecdsa_key_to_nid(EC_KEY *k) | |||
1546 | }; | 1652 | }; |
1547 | int nid; | 1653 | int nid; |
1548 | u_int i; | 1654 | u_int i; |
1549 | BN_CTX *bnctx; | ||
1550 | const EC_GROUP *g = EC_KEY_get0_group(k); | 1655 | const EC_GROUP *g = EC_KEY_get0_group(k); |
1551 | 1656 | ||
1552 | /* | 1657 | /* |
@@ -1559,18 +1664,13 @@ sshkey_ecdsa_key_to_nid(EC_KEY *k) | |||
1559 | */ | 1664 | */ |
1560 | if ((nid = EC_GROUP_get_curve_name(g)) > 0) | 1665 | if ((nid = EC_GROUP_get_curve_name(g)) > 0) |
1561 | return nid; | 1666 | return nid; |
1562 | if ((bnctx = BN_CTX_new()) == NULL) | ||
1563 | return -1; | ||
1564 | for (i = 0; nids[i] != -1; i++) { | 1667 | for (i = 0; nids[i] != -1; i++) { |
1565 | if ((eg = EC_GROUP_new_by_curve_name(nids[i])) == NULL) { | 1668 | if ((eg = EC_GROUP_new_by_curve_name(nids[i])) == NULL) |
1566 | BN_CTX_free(bnctx); | ||
1567 | return -1; | 1669 | return -1; |
1568 | } | 1670 | if (EC_GROUP_cmp(g, eg, NULL) == 0) |
1569 | if (EC_GROUP_cmp(g, eg, bnctx) == 0) | ||
1570 | break; | 1671 | break; |
1571 | EC_GROUP_free(eg); | 1672 | EC_GROUP_free(eg); |
1572 | } | 1673 | } |
1573 | BN_CTX_free(bnctx); | ||
1574 | if (nids[i] != -1) { | 1674 | if (nids[i] != -1) { |
1575 | /* Use the group with the NID attached */ | 1675 | /* Use the group with the NID attached */ |
1576 | EC_GROUP_set_asn1_flag(eg, OPENSSL_EC_NAMED_CURVE); | 1676 | EC_GROUP_set_asn1_flag(eg, OPENSSL_EC_NAMED_CURVE); |
@@ -1747,15 +1847,14 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp) | |||
1747 | #endif /* WITH_OPENSSL */ | 1847 | #endif /* WITH_OPENSSL */ |
1748 | 1848 | ||
1749 | *pkp = NULL; | 1849 | *pkp = NULL; |
1850 | if ((n = sshkey_new(k->type)) == NULL) { | ||
1851 | r = SSH_ERR_ALLOC_FAIL; | ||
1852 | goto out; | ||
1853 | } | ||
1750 | switch (k->type) { | 1854 | switch (k->type) { |
1751 | #ifdef WITH_OPENSSL | 1855 | #ifdef WITH_OPENSSL |
1752 | case KEY_DSA: | 1856 | case KEY_DSA: |
1753 | case KEY_DSA_CERT: | 1857 | case KEY_DSA_CERT: |
1754 | if ((n = sshkey_new(k->type)) == NULL) { | ||
1755 | r = SSH_ERR_ALLOC_FAIL; | ||
1756 | goto out; | ||
1757 | } | ||
1758 | |||
1759 | DSA_get0_pqg(k->dsa, &dsa_p, &dsa_q, &dsa_g); | 1858 | DSA_get0_pqg(k->dsa, &dsa_p, &dsa_q, &dsa_g); |
1760 | DSA_get0_key(k->dsa, &dsa_pub_key, NULL); | 1859 | DSA_get0_key(k->dsa, &dsa_pub_key, NULL); |
1761 | if ((dsa_p_dup = BN_dup(dsa_p)) == NULL || | 1860 | if ((dsa_p_dup = BN_dup(dsa_p)) == NULL || |
@@ -1780,10 +1879,8 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp) | |||
1780 | # ifdef OPENSSL_HAS_ECC | 1879 | # ifdef OPENSSL_HAS_ECC |
1781 | case KEY_ECDSA: | 1880 | case KEY_ECDSA: |
1782 | case KEY_ECDSA_CERT: | 1881 | case KEY_ECDSA_CERT: |
1783 | if ((n = sshkey_new(k->type)) == NULL) { | 1882 | case KEY_ECDSA_SK: |
1784 | r = SSH_ERR_ALLOC_FAIL; | 1883 | case KEY_ECDSA_SK_CERT: |
1785 | goto out; | ||
1786 | } | ||
1787 | n->ecdsa_nid = k->ecdsa_nid; | 1884 | n->ecdsa_nid = k->ecdsa_nid; |
1788 | n->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid); | 1885 | n->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid); |
1789 | if (n->ecdsa == NULL) { | 1886 | if (n->ecdsa == NULL) { |
@@ -1795,14 +1892,15 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp) | |||
1795 | r = SSH_ERR_LIBCRYPTO_ERROR; | 1892 | r = SSH_ERR_LIBCRYPTO_ERROR; |
1796 | goto out; | 1893 | goto out; |
1797 | } | 1894 | } |
1895 | if (k->type != KEY_ECDSA_SK && k->type != KEY_ECDSA_SK_CERT) | ||
1896 | break; | ||
1897 | /* Append security-key application string */ | ||
1898 | if ((n->sk_application = strdup(k->sk_application)) == NULL) | ||
1899 | goto out; | ||
1798 | break; | 1900 | break; |
1799 | # endif /* OPENSSL_HAS_ECC */ | 1901 | # endif /* OPENSSL_HAS_ECC */ |
1800 | case KEY_RSA: | 1902 | case KEY_RSA: |
1801 | case KEY_RSA_CERT: | 1903 | case KEY_RSA_CERT: |
1802 | if ((n = sshkey_new(k->type)) == NULL) { | ||
1803 | r = SSH_ERR_ALLOC_FAIL; | ||
1804 | goto out; | ||
1805 | } | ||
1806 | RSA_get0_key(k->rsa, &rsa_n, &rsa_e, NULL); | 1904 | RSA_get0_key(k->rsa, &rsa_n, &rsa_e, NULL); |
1807 | if ((rsa_n_dup = BN_dup(rsa_n)) == NULL || | 1905 | if ((rsa_n_dup = BN_dup(rsa_n)) == NULL || |
1808 | (rsa_e_dup = BN_dup(rsa_e)) == NULL) { | 1906 | (rsa_e_dup = BN_dup(rsa_e)) == NULL) { |
@@ -1818,10 +1916,8 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp) | |||
1818 | #endif /* WITH_OPENSSL */ | 1916 | #endif /* WITH_OPENSSL */ |
1819 | case KEY_ED25519: | 1917 | case KEY_ED25519: |
1820 | case KEY_ED25519_CERT: | 1918 | case KEY_ED25519_CERT: |
1821 | if ((n = sshkey_new(k->type)) == NULL) { | 1919 | case KEY_ED25519_SK: |
1822 | r = SSH_ERR_ALLOC_FAIL; | 1920 | case KEY_ED25519_SK_CERT: |
1823 | goto out; | ||
1824 | } | ||
1825 | if (k->ed25519_pk != NULL) { | 1921 | if (k->ed25519_pk != NULL) { |
1826 | if ((n->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) { | 1922 | if ((n->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) { |
1827 | r = SSH_ERR_ALLOC_FAIL; | 1923 | r = SSH_ERR_ALLOC_FAIL; |
@@ -1829,17 +1925,20 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp) | |||
1829 | } | 1925 | } |
1830 | memcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ); | 1926 | memcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ); |
1831 | } | 1927 | } |
1928 | if (k->type != KEY_ED25519_SK && | ||
1929 | k->type != KEY_ED25519_SK_CERT) | ||
1930 | break; | ||
1931 | /* Append security-key application string */ | ||
1932 | if ((n->sk_application = strdup(k->sk_application)) == NULL) | ||
1933 | goto out; | ||
1832 | break; | 1934 | break; |
1833 | #ifdef WITH_XMSS | 1935 | #ifdef WITH_XMSS |
1834 | case KEY_XMSS: | 1936 | case KEY_XMSS: |
1835 | case KEY_XMSS_CERT: | 1937 | case KEY_XMSS_CERT: |
1836 | if ((n = sshkey_new(k->type)) == NULL) { | ||
1837 | r = SSH_ERR_ALLOC_FAIL; | ||
1838 | goto out; | ||
1839 | } | ||
1840 | if ((r = sshkey_xmss_init(n, k->xmss_name)) != 0) | 1938 | if ((r = sshkey_xmss_init(n, k->xmss_name)) != 0) |
1841 | goto out; | 1939 | goto out; |
1842 | if (k->xmss_pk != NULL) { | 1940 | if (k->xmss_pk != NULL) { |
1941 | u_int32_t left; | ||
1843 | size_t pklen = sshkey_xmss_pklen(k); | 1942 | size_t pklen = sshkey_xmss_pklen(k); |
1844 | if (pklen == 0 || sshkey_xmss_pklen(n) != pklen) { | 1943 | if (pklen == 0 || sshkey_xmss_pklen(n) != pklen) { |
1845 | r = SSH_ERR_INTERNAL_ERROR; | 1944 | r = SSH_ERR_INTERNAL_ERROR; |
@@ -1850,6 +1949,10 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp) | |||
1850 | goto out; | 1949 | goto out; |
1851 | } | 1950 | } |
1852 | memcpy(n->xmss_pk, k->xmss_pk, pklen); | 1951 | memcpy(n->xmss_pk, k->xmss_pk, pklen); |
1952 | /* simulate number of signatures left on pubkey */ | ||
1953 | left = sshkey_xmss_signatures_left(k); | ||
1954 | if (left) | ||
1955 | sshkey_xmss_enable_maxsign(n, left); | ||
1853 | } | 1956 | } |
1854 | break; | 1957 | break; |
1855 | #endif /* WITH_XMSS */ | 1958 | #endif /* WITH_XMSS */ |
@@ -1934,7 +2037,7 @@ sshkey_shield_private(struct sshkey *k) | |||
1934 | if (sshkey_is_shielded(k) && (r = sshkey_unshield_private(k)) != 0) | 2037 | if (sshkey_is_shielded(k) && (r = sshkey_unshield_private(k)) != 0) |
1935 | goto out; | 2038 | goto out; |
1936 | if ((r = sshkey_private_serialize_opt(k, prvbuf, | 2039 | if ((r = sshkey_private_serialize_opt(k, prvbuf, |
1937 | SSHKEY_SERIALIZE_FULL)) != 0) | 2040 | SSHKEY_SERIALIZE_SHIELD)) != 0) |
1938 | goto out; | 2041 | goto out; |
1939 | /* pad to cipher blocksize */ | 2042 | /* pad to cipher blocksize */ |
1940 | i = 0; | 2043 | i = 0; |
@@ -1977,6 +2080,9 @@ sshkey_shield_private(struct sshkey *k) | |||
1977 | enc = prekey = NULL; /* transferred */ | 2080 | enc = prekey = NULL; /* transferred */ |
1978 | enclen = 0; | 2081 | enclen = 0; |
1979 | 2082 | ||
2083 | /* preserve key fields that are required for correct operation */ | ||
2084 | k->sk_flags = kswap->sk_flags; | ||
2085 | |||
1980 | /* success */ | 2086 | /* success */ |
1981 | r = 0; | 2087 | r = 0; |
1982 | 2088 | ||
@@ -2198,7 +2304,7 @@ cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf) | |||
2198 | goto out; | 2304 | goto out; |
2199 | } | 2305 | } |
2200 | if ((ret = sshkey_verify(key->cert->signature_key, sig, slen, | 2306 | if ((ret = sshkey_verify(key->cert->signature_key, sig, slen, |
2201 | sshbuf_ptr(key->cert->certblob), signed_len, NULL, 0)) != 0) | 2307 | sshbuf_ptr(key->cert->certblob), signed_len, NULL, 0, NULL)) != 0) |
2202 | goto out; | 2308 | goto out; |
2203 | if ((ret = sshkey_get_sigtype(sig, slen, | 2309 | if ((ret = sshkey_get_sigtype(sig, slen, |
2204 | &key->cert->signature_type)) != 0) | 2310 | &key->cert->signature_type)) != 0) |
@@ -2328,15 +2434,17 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, | |||
2328 | DSA_print_fp(stderr, key->dsa, 8); | 2434 | DSA_print_fp(stderr, key->dsa, 8); |
2329 | #endif | 2435 | #endif |
2330 | break; | 2436 | break; |
2437 | # ifdef OPENSSL_HAS_ECC | ||
2331 | case KEY_ECDSA_CERT: | 2438 | case KEY_ECDSA_CERT: |
2439 | case KEY_ECDSA_SK_CERT: | ||
2332 | /* Skip nonce */ | 2440 | /* Skip nonce */ |
2333 | if (sshbuf_get_string_direct(b, NULL, NULL) != 0) { | 2441 | if (sshbuf_get_string_direct(b, NULL, NULL) != 0) { |
2334 | ret = SSH_ERR_INVALID_FORMAT; | 2442 | ret = SSH_ERR_INVALID_FORMAT; |
2335 | goto out; | 2443 | goto out; |
2336 | } | 2444 | } |
2337 | /* FALLTHROUGH */ | 2445 | /* FALLTHROUGH */ |
2338 | # ifdef OPENSSL_HAS_ECC | ||
2339 | case KEY_ECDSA: | 2446 | case KEY_ECDSA: |
2447 | case KEY_ECDSA_SK: | ||
2340 | if ((key = sshkey_new(type)) == NULL) { | 2448 | if ((key = sshkey_new(type)) == NULL) { |
2341 | ret = SSH_ERR_ALLOC_FAIL; | 2449 | ret = SSH_ERR_ALLOC_FAIL; |
2342 | goto out; | 2450 | goto out; |
@@ -2377,10 +2485,22 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, | |||
2377 | #ifdef DEBUG_PK | 2485 | #ifdef DEBUG_PK |
2378 | sshkey_dump_ec_point(EC_KEY_get0_group(key->ecdsa), q); | 2486 | sshkey_dump_ec_point(EC_KEY_get0_group(key->ecdsa), q); |
2379 | #endif | 2487 | #endif |
2488 | if (type == KEY_ECDSA_SK || type == KEY_ECDSA_SK_CERT) { | ||
2489 | /* Parse additional security-key application string */ | ||
2490 | if (sshbuf_get_cstring(b, &key->sk_application, | ||
2491 | NULL) != 0) { | ||
2492 | ret = SSH_ERR_INVALID_FORMAT; | ||
2493 | goto out; | ||
2494 | } | ||
2495 | #ifdef DEBUG_PK | ||
2496 | fprintf(stderr, "App: %s\n", key->sk_application); | ||
2497 | #endif | ||
2498 | } | ||
2380 | break; | 2499 | break; |
2381 | # endif /* OPENSSL_HAS_ECC */ | 2500 | # endif /* OPENSSL_HAS_ECC */ |
2382 | #endif /* WITH_OPENSSL */ | 2501 | #endif /* WITH_OPENSSL */ |
2383 | case KEY_ED25519_CERT: | 2502 | case KEY_ED25519_CERT: |
2503 | case KEY_ED25519_SK_CERT: | ||
2384 | /* Skip nonce */ | 2504 | /* Skip nonce */ |
2385 | if (sshbuf_get_string_direct(b, NULL, NULL) != 0) { | 2505 | if (sshbuf_get_string_direct(b, NULL, NULL) != 0) { |
2386 | ret = SSH_ERR_INVALID_FORMAT; | 2506 | ret = SSH_ERR_INVALID_FORMAT; |
@@ -2388,6 +2508,7 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, | |||
2388 | } | 2508 | } |
2389 | /* FALLTHROUGH */ | 2509 | /* FALLTHROUGH */ |
2390 | case KEY_ED25519: | 2510 | case KEY_ED25519: |
2511 | case KEY_ED25519_SK: | ||
2391 | if ((ret = sshbuf_get_string(b, &pk, &len)) != 0) | 2512 | if ((ret = sshbuf_get_string(b, &pk, &len)) != 0) |
2392 | goto out; | 2513 | goto out; |
2393 | if (len != ED25519_PK_SZ) { | 2514 | if (len != ED25519_PK_SZ) { |
@@ -2398,6 +2519,17 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, | |||
2398 | ret = SSH_ERR_ALLOC_FAIL; | 2519 | ret = SSH_ERR_ALLOC_FAIL; |
2399 | goto out; | 2520 | goto out; |
2400 | } | 2521 | } |
2522 | if (type == KEY_ED25519_SK || type == KEY_ED25519_SK_CERT) { | ||
2523 | /* Parse additional security-key application string */ | ||
2524 | if (sshbuf_get_cstring(b, &key->sk_application, | ||
2525 | NULL) != 0) { | ||
2526 | ret = SSH_ERR_INVALID_FORMAT; | ||
2527 | goto out; | ||
2528 | } | ||
2529 | #ifdef DEBUG_PK | ||
2530 | fprintf(stderr, "App: %s\n", key->sk_application); | ||
2531 | #endif | ||
2532 | } | ||
2401 | key->ed25519_pk = pk; | 2533 | key->ed25519_pk = pk; |
2402 | pk = NULL; | 2534 | pk = NULL; |
2403 | break; | 2535 | break; |
@@ -2596,7 +2728,8 @@ sshkey_check_sigtype(const u_char *sig, size_t siglen, | |||
2596 | int | 2728 | int |
2597 | sshkey_sign(struct sshkey *key, | 2729 | sshkey_sign(struct sshkey *key, |
2598 | u_char **sigp, size_t *lenp, | 2730 | u_char **sigp, size_t *lenp, |
2599 | const u_char *data, size_t datalen, const char *alg, u_int compat) | 2731 | const u_char *data, size_t datalen, |
2732 | const char *alg, const char *sk_provider, u_int compat) | ||
2600 | { | 2733 | { |
2601 | int was_shielded = sshkey_is_shielded(key); | 2734 | int was_shielded = sshkey_is_shielded(key); |
2602 | int r2, r = SSH_ERR_INTERNAL_ERROR; | 2735 | int r2, r = SSH_ERR_INTERNAL_ERROR; |
@@ -2630,6 +2763,13 @@ sshkey_sign(struct sshkey *key, | |||
2630 | case KEY_ED25519_CERT: | 2763 | case KEY_ED25519_CERT: |
2631 | r = ssh_ed25519_sign(key, sigp, lenp, data, datalen, compat); | 2764 | r = ssh_ed25519_sign(key, sigp, lenp, data, datalen, compat); |
2632 | break; | 2765 | break; |
2766 | case KEY_ED25519_SK: | ||
2767 | case KEY_ED25519_SK_CERT: | ||
2768 | case KEY_ECDSA_SK_CERT: | ||
2769 | case KEY_ECDSA_SK: | ||
2770 | r = sshsk_sign(sk_provider, key, sigp, lenp, data, | ||
2771 | datalen, compat, /* XXX PIN */ NULL); | ||
2772 | break; | ||
2633 | #ifdef WITH_XMSS | 2773 | #ifdef WITH_XMSS |
2634 | case KEY_XMSS: | 2774 | case KEY_XMSS: |
2635 | case KEY_XMSS_CERT: | 2775 | case KEY_XMSS_CERT: |
@@ -2652,8 +2792,11 @@ sshkey_sign(struct sshkey *key, | |||
2652 | int | 2792 | int |
2653 | sshkey_verify(const struct sshkey *key, | 2793 | sshkey_verify(const struct sshkey *key, |
2654 | const u_char *sig, size_t siglen, | 2794 | const u_char *sig, size_t siglen, |
2655 | const u_char *data, size_t dlen, const char *alg, u_int compat) | 2795 | const u_char *data, size_t dlen, const char *alg, u_int compat, |
2796 | struct sshkey_sig_details **detailsp) | ||
2656 | { | 2797 | { |
2798 | if (detailsp != NULL) | ||
2799 | *detailsp = NULL; | ||
2657 | if (siglen == 0 || dlen > SSH_KEY_MAX_SIGN_DATA_SIZE) | 2800 | if (siglen == 0 || dlen > SSH_KEY_MAX_SIGN_DATA_SIZE) |
2658 | return SSH_ERR_INVALID_ARGUMENT; | 2801 | return SSH_ERR_INVALID_ARGUMENT; |
2659 | switch (key->type) { | 2802 | switch (key->type) { |
@@ -2665,6 +2808,10 @@ sshkey_verify(const struct sshkey *key, | |||
2665 | case KEY_ECDSA_CERT: | 2808 | case KEY_ECDSA_CERT: |
2666 | case KEY_ECDSA: | 2809 | case KEY_ECDSA: |
2667 | return ssh_ecdsa_verify(key, sig, siglen, data, dlen, compat); | 2810 | return ssh_ecdsa_verify(key, sig, siglen, data, dlen, compat); |
2811 | case KEY_ECDSA_SK_CERT: | ||
2812 | case KEY_ECDSA_SK: | ||
2813 | return ssh_ecdsa_sk_verify(key, sig, siglen, data, dlen, | ||
2814 | compat, detailsp); | ||
2668 | # endif /* OPENSSL_HAS_ECC */ | 2815 | # endif /* OPENSSL_HAS_ECC */ |
2669 | case KEY_RSA_CERT: | 2816 | case KEY_RSA_CERT: |
2670 | case KEY_RSA: | 2817 | case KEY_RSA: |
@@ -2673,6 +2820,10 @@ sshkey_verify(const struct sshkey *key, | |||
2673 | case KEY_ED25519: | 2820 | case KEY_ED25519: |
2674 | case KEY_ED25519_CERT: | 2821 | case KEY_ED25519_CERT: |
2675 | return ssh_ed25519_verify(key, sig, siglen, data, dlen, compat); | 2822 | return ssh_ed25519_verify(key, sig, siglen, data, dlen, compat); |
2823 | case KEY_ED25519_SK: | ||
2824 | case KEY_ED25519_SK_CERT: | ||
2825 | return ssh_ed25519_sk_verify(key, sig, siglen, data, dlen, | ||
2826 | compat, detailsp); | ||
2676 | #ifdef WITH_XMSS | 2827 | #ifdef WITH_XMSS |
2677 | case KEY_XMSS: | 2828 | case KEY_XMSS: |
2678 | case KEY_XMSS_CERT: | 2829 | case KEY_XMSS_CERT: |
@@ -2700,7 +2851,13 @@ sshkey_to_certified(struct sshkey *k) | |||
2700 | case KEY_ECDSA: | 2851 | case KEY_ECDSA: |
2701 | newtype = KEY_ECDSA_CERT; | 2852 | newtype = KEY_ECDSA_CERT; |
2702 | break; | 2853 | break; |
2854 | case KEY_ECDSA_SK: | ||
2855 | newtype = KEY_ECDSA_SK_CERT; | ||
2856 | break; | ||
2703 | #endif /* WITH_OPENSSL */ | 2857 | #endif /* WITH_OPENSSL */ |
2858 | case KEY_ED25519_SK: | ||
2859 | newtype = KEY_ED25519_SK_CERT; | ||
2860 | break; | ||
2704 | case KEY_ED25519: | 2861 | case KEY_ED25519: |
2705 | newtype = KEY_ED25519_CERT; | 2862 | newtype = KEY_ED25519_CERT; |
2706 | break; | 2863 | break; |
@@ -2733,7 +2890,7 @@ sshkey_drop_cert(struct sshkey *k) | |||
2733 | /* Sign a certified key, (re-)generating the signed certblob. */ | 2890 | /* Sign a certified key, (re-)generating the signed certblob. */ |
2734 | int | 2891 | int |
2735 | sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg, | 2892 | sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg, |
2736 | sshkey_certify_signer *signer, void *signer_ctx) | 2893 | const char *sk_provider, sshkey_certify_signer *signer, void *signer_ctx) |
2737 | { | 2894 | { |
2738 | struct sshbuf *principals = NULL; | 2895 | struct sshbuf *principals = NULL; |
2739 | u_char *ca_blob = NULL, *sig_blob = NULL, nonce[32]; | 2896 | u_char *ca_blob = NULL, *sig_blob = NULL, nonce[32]; |
@@ -2797,12 +2954,18 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg, | |||
2797 | break; | 2954 | break; |
2798 | # ifdef OPENSSL_HAS_ECC | 2955 | # ifdef OPENSSL_HAS_ECC |
2799 | case KEY_ECDSA_CERT: | 2956 | case KEY_ECDSA_CERT: |
2957 | case KEY_ECDSA_SK_CERT: | ||
2800 | if ((ret = sshbuf_put_cstring(cert, | 2958 | if ((ret = sshbuf_put_cstring(cert, |
2801 | sshkey_curve_nid_to_name(k->ecdsa_nid))) != 0 || | 2959 | sshkey_curve_nid_to_name(k->ecdsa_nid))) != 0 || |
2802 | (ret = sshbuf_put_ec(cert, | 2960 | (ret = sshbuf_put_ec(cert, |
2803 | EC_KEY_get0_public_key(k->ecdsa), | 2961 | EC_KEY_get0_public_key(k->ecdsa), |
2804 | EC_KEY_get0_group(k->ecdsa))) != 0) | 2962 | EC_KEY_get0_group(k->ecdsa))) != 0) |
2805 | goto out; | 2963 | goto out; |
2964 | if (k->type == KEY_ECDSA_SK_CERT) { | ||
2965 | if ((ret = sshbuf_put_cstring(cert, | ||
2966 | k->sk_application)) != 0) | ||
2967 | goto out; | ||
2968 | } | ||
2806 | break; | 2969 | break; |
2807 | # endif /* OPENSSL_HAS_ECC */ | 2970 | # endif /* OPENSSL_HAS_ECC */ |
2808 | case KEY_RSA_CERT: | 2971 | case KEY_RSA_CERT: |
@@ -2813,9 +2976,15 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg, | |||
2813 | break; | 2976 | break; |
2814 | #endif /* WITH_OPENSSL */ | 2977 | #endif /* WITH_OPENSSL */ |
2815 | case KEY_ED25519_CERT: | 2978 | case KEY_ED25519_CERT: |
2979 | case KEY_ED25519_SK_CERT: | ||
2816 | if ((ret = sshbuf_put_string(cert, | 2980 | if ((ret = sshbuf_put_string(cert, |
2817 | k->ed25519_pk, ED25519_PK_SZ)) != 0) | 2981 | k->ed25519_pk, ED25519_PK_SZ)) != 0) |
2818 | goto out; | 2982 | goto out; |
2983 | if (k->type == KEY_ED25519_SK_CERT) { | ||
2984 | if ((ret = sshbuf_put_cstring(cert, | ||
2985 | k->sk_application)) != 0) | ||
2986 | goto out; | ||
2987 | } | ||
2819 | break; | 2988 | break; |
2820 | #ifdef WITH_XMSS | 2989 | #ifdef WITH_XMSS |
2821 | case KEY_XMSS_CERT: | 2990 | case KEY_XMSS_CERT: |
@@ -2859,7 +3028,7 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg, | |||
2859 | 3028 | ||
2860 | /* Sign the whole mess */ | 3029 | /* Sign the whole mess */ |
2861 | if ((ret = signer(ca, &sig_blob, &sig_len, sshbuf_ptr(cert), | 3030 | if ((ret = signer(ca, &sig_blob, &sig_len, sshbuf_ptr(cert), |
2862 | sshbuf_len(cert), alg, 0, signer_ctx)) != 0) | 3031 | sshbuf_len(cert), alg, sk_provider, 0, signer_ctx)) != 0) |
2863 | goto out; | 3032 | goto out; |
2864 | /* Check and update signature_type against what was actually used */ | 3033 | /* Check and update signature_type against what was actually used */ |
2865 | if ((ret = sshkey_get_sigtype(sig_blob, sig_len, &sigtype)) != 0) | 3034 | if ((ret = sshkey_get_sigtype(sig_blob, sig_len, &sigtype)) != 0) |
@@ -2889,17 +3058,20 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg, | |||
2889 | static int | 3058 | static int |
2890 | default_key_sign(struct sshkey *key, u_char **sigp, size_t *lenp, | 3059 | default_key_sign(struct sshkey *key, u_char **sigp, size_t *lenp, |
2891 | const u_char *data, size_t datalen, | 3060 | const u_char *data, size_t datalen, |
2892 | const char *alg, u_int compat, void *ctx) | 3061 | const char *alg, const char *sk_provider, u_int compat, void *ctx) |
2893 | { | 3062 | { |
2894 | if (ctx != NULL) | 3063 | if (ctx != NULL) |
2895 | return SSH_ERR_INVALID_ARGUMENT; | 3064 | return SSH_ERR_INVALID_ARGUMENT; |
2896 | return sshkey_sign(key, sigp, lenp, data, datalen, alg, compat); | 3065 | return sshkey_sign(key, sigp, lenp, data, datalen, alg, |
3066 | sk_provider, compat); | ||
2897 | } | 3067 | } |
2898 | 3068 | ||
2899 | int | 3069 | int |
2900 | sshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg) | 3070 | sshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg, |
3071 | const char *sk_provider) | ||
2901 | { | 3072 | { |
2902 | return sshkey_certify_custom(k, ca, alg, default_key_sign, NULL); | 3073 | return sshkey_certify_custom(k, ca, alg, sk_provider, |
3074 | default_key_sign, NULL); | ||
2903 | } | 3075 | } |
2904 | 3076 | ||
2905 | int | 3077 | int |
@@ -3082,6 +3254,28 @@ sshkey_private_serialize_opt(struct sshkey *key, struct sshbuf *buf, | |||
3082 | EC_KEY_get0_private_key(key->ecdsa))) != 0) | 3254 | EC_KEY_get0_private_key(key->ecdsa))) != 0) |
3083 | goto out; | 3255 | goto out; |
3084 | break; | 3256 | break; |
3257 | case KEY_ECDSA_SK: | ||
3258 | if ((r = sshbuf_put_cstring(b, | ||
3259 | sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 || | ||
3260 | (r = sshbuf_put_eckey(b, key->ecdsa)) != 0 || | ||
3261 | (r = sshbuf_put_cstring(b, key->sk_application)) != 0 || | ||
3262 | (r = sshbuf_put_u8(b, key->sk_flags)) != 0 || | ||
3263 | (r = sshbuf_put_stringb(b, key->sk_key_handle)) != 0 || | ||
3264 | (r = sshbuf_put_stringb(b, key->sk_reserved)) != 0) | ||
3265 | goto out; | ||
3266 | break; | ||
3267 | case KEY_ECDSA_SK_CERT: | ||
3268 | if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) { | ||
3269 | r = SSH_ERR_INVALID_ARGUMENT; | ||
3270 | goto out; | ||
3271 | } | ||
3272 | if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || | ||
3273 | (r = sshbuf_put_cstring(b, key->sk_application)) != 0 || | ||
3274 | (r = sshbuf_put_u8(b, key->sk_flags)) != 0 || | ||
3275 | (r = sshbuf_put_stringb(b, key->sk_key_handle)) != 0 || | ||
3276 | (r = sshbuf_put_stringb(b, key->sk_reserved)) != 0) | ||
3277 | goto out; | ||
3278 | break; | ||
3085 | # endif /* OPENSSL_HAS_ECC */ | 3279 | # endif /* OPENSSL_HAS_ECC */ |
3086 | #endif /* WITH_OPENSSL */ | 3280 | #endif /* WITH_OPENSSL */ |
3087 | case KEY_ED25519: | 3281 | case KEY_ED25519: |
@@ -3103,6 +3297,29 @@ sshkey_private_serialize_opt(struct sshkey *key, struct sshbuf *buf, | |||
3103 | ED25519_SK_SZ)) != 0) | 3297 | ED25519_SK_SZ)) != 0) |
3104 | goto out; | 3298 | goto out; |
3105 | break; | 3299 | break; |
3300 | case KEY_ED25519_SK: | ||
3301 | if ((r = sshbuf_put_string(b, key->ed25519_pk, | ||
3302 | ED25519_PK_SZ)) != 0 || | ||
3303 | (r = sshbuf_put_cstring(b, key->sk_application)) != 0 || | ||
3304 | (r = sshbuf_put_u8(b, key->sk_flags)) != 0 || | ||
3305 | (r = sshbuf_put_stringb(b, key->sk_key_handle)) != 0 || | ||
3306 | (r = sshbuf_put_stringb(b, key->sk_reserved)) != 0) | ||
3307 | goto out; | ||
3308 | break; | ||
3309 | case KEY_ED25519_SK_CERT: | ||
3310 | if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) { | ||
3311 | r = SSH_ERR_INVALID_ARGUMENT; | ||
3312 | goto out; | ||
3313 | } | ||
3314 | if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || | ||
3315 | (r = sshbuf_put_string(b, key->ed25519_pk, | ||
3316 | ED25519_PK_SZ)) != 0 || | ||
3317 | (r = sshbuf_put_cstring(b, key->sk_application)) != 0 || | ||
3318 | (r = sshbuf_put_u8(b, key->sk_flags)) != 0 || | ||
3319 | (r = sshbuf_put_stringb(b, key->sk_key_handle)) != 0 || | ||
3320 | (r = sshbuf_put_stringb(b, key->sk_reserved)) != 0) | ||
3321 | goto out; | ||
3322 | break; | ||
3106 | #ifdef WITH_XMSS | 3323 | #ifdef WITH_XMSS |
3107 | case KEY_XMSS: | 3324 | case KEY_XMSS: |
3108 | if (key->xmss_name == NULL) { | 3325 | if (key->xmss_name == NULL) { |
@@ -3270,6 +3487,60 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) | |||
3270 | (r = sshkey_ec_validate_private(k->ecdsa)) != 0) | 3487 | (r = sshkey_ec_validate_private(k->ecdsa)) != 0) |
3271 | goto out; | 3488 | goto out; |
3272 | break; | 3489 | break; |
3490 | case KEY_ECDSA_SK: | ||
3491 | if ((k = sshkey_new(type)) == NULL) { | ||
3492 | r = SSH_ERR_ALLOC_FAIL; | ||
3493 | goto out; | ||
3494 | } | ||
3495 | if ((k->ecdsa_nid = sshkey_ecdsa_nid_from_name(tname)) == -1) { | ||
3496 | r = SSH_ERR_INVALID_ARGUMENT; | ||
3497 | goto out; | ||
3498 | } | ||
3499 | if ((r = sshbuf_get_cstring(buf, &curve, NULL)) != 0) | ||
3500 | goto out; | ||
3501 | if (k->ecdsa_nid != sshkey_curve_name_to_nid(curve)) { | ||
3502 | r = SSH_ERR_EC_CURVE_MISMATCH; | ||
3503 | goto out; | ||
3504 | } | ||
3505 | if ((k->sk_key_handle = sshbuf_new()) == NULL || | ||
3506 | (k->sk_reserved = sshbuf_new()) == NULL) { | ||
3507 | r = SSH_ERR_ALLOC_FAIL; | ||
3508 | goto out; | ||
3509 | } | ||
3510 | k->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid); | ||
3511 | if (k->ecdsa == NULL) { | ||
3512 | r = SSH_ERR_LIBCRYPTO_ERROR; | ||
3513 | goto out; | ||
3514 | } | ||
3515 | if ((r = sshbuf_get_eckey(buf, k->ecdsa)) != 0 || | ||
3516 | (r = sshbuf_get_cstring(buf, &k->sk_application, | ||
3517 | NULL)) != 0 || | ||
3518 | (r = sshbuf_get_u8(buf, &k->sk_flags)) != 0 || | ||
3519 | (r = sshbuf_get_stringb(buf, k->sk_key_handle)) != 0 || | ||
3520 | (r = sshbuf_get_stringb(buf, k->sk_reserved)) != 0) | ||
3521 | goto out; | ||
3522 | if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(k->ecdsa), | ||
3523 | EC_KEY_get0_public_key(k->ecdsa))) != 0) | ||
3524 | goto out; | ||
3525 | break; | ||
3526 | case KEY_ECDSA_SK_CERT: | ||
3527 | if ((r = sshkey_froms(buf, &k)) != 0) | ||
3528 | goto out; | ||
3529 | if ((k->sk_key_handle = sshbuf_new()) == NULL || | ||
3530 | (k->sk_reserved = sshbuf_new()) == NULL) { | ||
3531 | r = SSH_ERR_ALLOC_FAIL; | ||
3532 | goto out; | ||
3533 | } | ||
3534 | if ((r = sshbuf_get_cstring(buf, &k->sk_application, | ||
3535 | NULL)) != 0 || | ||
3536 | (r = sshbuf_get_u8(buf, &k->sk_flags)) != 0 || | ||
3537 | (r = sshbuf_get_stringb(buf, k->sk_key_handle)) != 0 || | ||
3538 | (r = sshbuf_get_stringb(buf, k->sk_reserved)) != 0) | ||
3539 | goto out; | ||
3540 | if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(k->ecdsa), | ||
3541 | EC_KEY_get0_public_key(k->ecdsa))) != 0) | ||
3542 | goto out; | ||
3543 | break; | ||
3273 | # endif /* OPENSSL_HAS_ECC */ | 3544 | # endif /* OPENSSL_HAS_ECC */ |
3274 | case KEY_RSA: | 3545 | case KEY_RSA: |
3275 | if ((k = sshkey_new(type)) == NULL) { | 3546 | if ((k = sshkey_new(type)) == NULL) { |
@@ -3358,6 +3629,57 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) | |||
3358 | k->ed25519_sk = ed25519_sk; | 3629 | k->ed25519_sk = ed25519_sk; |
3359 | ed25519_pk = ed25519_sk = NULL; /* transferred */ | 3630 | ed25519_pk = ed25519_sk = NULL; /* transferred */ |
3360 | break; | 3631 | break; |
3632 | case KEY_ED25519_SK: | ||
3633 | if ((k = sshkey_new(type)) == NULL) { | ||
3634 | r = SSH_ERR_ALLOC_FAIL; | ||
3635 | goto out; | ||
3636 | } | ||
3637 | if ((r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0) | ||
3638 | goto out; | ||
3639 | if (pklen != ED25519_PK_SZ) { | ||
3640 | r = SSH_ERR_INVALID_FORMAT; | ||
3641 | goto out; | ||
3642 | } | ||
3643 | if ((k->sk_key_handle = sshbuf_new()) == NULL || | ||
3644 | (k->sk_reserved = sshbuf_new()) == NULL) { | ||
3645 | r = SSH_ERR_ALLOC_FAIL; | ||
3646 | goto out; | ||
3647 | } | ||
3648 | if ((r = sshbuf_get_cstring(buf, &k->sk_application, | ||
3649 | NULL)) != 0 || | ||
3650 | (r = sshbuf_get_u8(buf, &k->sk_flags)) != 0 || | ||
3651 | (r = sshbuf_get_stringb(buf, k->sk_key_handle)) != 0 || | ||
3652 | (r = sshbuf_get_stringb(buf, k->sk_reserved)) != 0) | ||
3653 | goto out; | ||
3654 | k->ed25519_pk = ed25519_pk; | ||
3655 | ed25519_pk = NULL; | ||
3656 | break; | ||
3657 | case KEY_ED25519_SK_CERT: | ||
3658 | if ((r = sshkey_froms(buf, &k)) != 0 || | ||
3659 | (r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0) | ||
3660 | goto out; | ||
3661 | if (k->type != type) { | ||
3662 | r = SSH_ERR_INVALID_FORMAT; | ||
3663 | goto out; | ||
3664 | } | ||
3665 | if (pklen != ED25519_PK_SZ) { | ||
3666 | r = SSH_ERR_INVALID_FORMAT; | ||
3667 | goto out; | ||
3668 | } | ||
3669 | if ((k->sk_key_handle = sshbuf_new()) == NULL || | ||
3670 | (k->sk_reserved = sshbuf_new()) == NULL) { | ||
3671 | r = SSH_ERR_ALLOC_FAIL; | ||
3672 | goto out; | ||
3673 | } | ||
3674 | if ((r = sshbuf_get_cstring(buf, &k->sk_application, | ||
3675 | NULL)) != 0 || | ||
3676 | (r = sshbuf_get_u8(buf, &k->sk_flags)) != 0 || | ||
3677 | (r = sshbuf_get_stringb(buf, k->sk_key_handle)) != 0 || | ||
3678 | (r = sshbuf_get_stringb(buf, k->sk_reserved)) != 0) | ||
3679 | goto out; | ||
3680 | k->ed25519_pk = ed25519_pk; | ||
3681 | ed25519_pk = NULL; /* transferred */ | ||
3682 | break; | ||
3361 | #ifdef WITH_XMSS | 3683 | #ifdef WITH_XMSS |
3362 | case KEY_XMSS: | 3684 | case KEY_XMSS: |
3363 | if ((k = sshkey_new(type)) == NULL) { | 3685 | if ((k = sshkey_new(type)) == NULL) { |
@@ -3456,9 +3778,8 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) | |||
3456 | int | 3778 | int |
3457 | sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public) | 3779 | sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public) |
3458 | { | 3780 | { |
3459 | BN_CTX *bnctx; | ||
3460 | EC_POINT *nq = NULL; | 3781 | EC_POINT *nq = NULL; |
3461 | BIGNUM *order, *x, *y, *tmp; | 3782 | BIGNUM *order = NULL, *x = NULL, *y = NULL, *tmp = NULL; |
3462 | int ret = SSH_ERR_KEY_INVALID_EC_VALUE; | 3783 | int ret = SSH_ERR_KEY_INVALID_EC_VALUE; |
3463 | 3784 | ||
3464 | /* | 3785 | /* |
@@ -3469,10 +3790,6 @@ sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public) | |||
3469 | * EC_POINT_oct2point then the caller will need to explicitly check. | 3790 | * EC_POINT_oct2point then the caller will need to explicitly check. |
3470 | */ | 3791 | */ |
3471 | 3792 | ||
3472 | if ((bnctx = BN_CTX_new()) == NULL) | ||
3473 | return SSH_ERR_ALLOC_FAIL; | ||
3474 | BN_CTX_start(bnctx); | ||
3475 | |||
3476 | /* | 3793 | /* |
3477 | * We shouldn't ever hit this case because bignum_get_ecpoint() | 3794 | * We shouldn't ever hit this case because bignum_get_ecpoint() |
3478 | * refuses to load GF2m points. | 3795 | * refuses to load GF2m points. |
@@ -3485,18 +3802,18 @@ sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public) | |||
3485 | if (EC_POINT_is_at_infinity(group, public)) | 3802 | if (EC_POINT_is_at_infinity(group, public)) |
3486 | goto out; | 3803 | goto out; |
3487 | 3804 | ||
3488 | if ((x = BN_CTX_get(bnctx)) == NULL || | 3805 | if ((x = BN_new()) == NULL || |
3489 | (y = BN_CTX_get(bnctx)) == NULL || | 3806 | (y = BN_new()) == NULL || |
3490 | (order = BN_CTX_get(bnctx)) == NULL || | 3807 | (order = BN_new()) == NULL || |
3491 | (tmp = BN_CTX_get(bnctx)) == NULL) { | 3808 | (tmp = BN_new()) == NULL) { |
3492 | ret = SSH_ERR_ALLOC_FAIL; | 3809 | ret = SSH_ERR_ALLOC_FAIL; |
3493 | goto out; | 3810 | goto out; |
3494 | } | 3811 | } |
3495 | 3812 | ||
3496 | /* log2(x) > log2(order)/2, log2(y) > log2(order)/2 */ | 3813 | /* log2(x) > log2(order)/2, log2(y) > log2(order)/2 */ |
3497 | if (EC_GROUP_get_order(group, order, bnctx) != 1 || | 3814 | if (EC_GROUP_get_order(group, order, NULL) != 1 || |
3498 | EC_POINT_get_affine_coordinates_GFp(group, public, | 3815 | EC_POINT_get_affine_coordinates_GFp(group, public, |
3499 | x, y, bnctx) != 1) { | 3816 | x, y, NULL) != 1) { |
3500 | ret = SSH_ERR_LIBCRYPTO_ERROR; | 3817 | ret = SSH_ERR_LIBCRYPTO_ERROR; |
3501 | goto out; | 3818 | goto out; |
3502 | } | 3819 | } |
@@ -3509,7 +3826,7 @@ sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public) | |||
3509 | ret = SSH_ERR_ALLOC_FAIL; | 3826 | ret = SSH_ERR_ALLOC_FAIL; |
3510 | goto out; | 3827 | goto out; |
3511 | } | 3828 | } |
3512 | if (EC_POINT_mul(group, nq, NULL, public, order, bnctx) != 1) { | 3829 | if (EC_POINT_mul(group, nq, NULL, public, order, NULL) != 1) { |
3513 | ret = SSH_ERR_LIBCRYPTO_ERROR; | 3830 | ret = SSH_ERR_LIBCRYPTO_ERROR; |
3514 | goto out; | 3831 | goto out; |
3515 | } | 3832 | } |
@@ -3525,7 +3842,10 @@ sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public) | |||
3525 | goto out; | 3842 | goto out; |
3526 | ret = 0; | 3843 | ret = 0; |
3527 | out: | 3844 | out: |
3528 | BN_CTX_free(bnctx); | 3845 | BN_clear_free(x); |
3846 | BN_clear_free(y); | ||
3847 | BN_clear_free(order); | ||
3848 | BN_clear_free(tmp); | ||
3529 | EC_POINT_free(nq); | 3849 | EC_POINT_free(nq); |
3530 | return ret; | 3850 | return ret; |
3531 | } | 3851 | } |
@@ -3533,22 +3853,16 @@ sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public) | |||
3533 | int | 3853 | int |
3534 | sshkey_ec_validate_private(const EC_KEY *key) | 3854 | sshkey_ec_validate_private(const EC_KEY *key) |
3535 | { | 3855 | { |
3536 | BN_CTX *bnctx; | 3856 | BIGNUM *order = NULL, *tmp = NULL; |
3537 | BIGNUM *order, *tmp; | ||
3538 | int ret = SSH_ERR_KEY_INVALID_EC_VALUE; | 3857 | int ret = SSH_ERR_KEY_INVALID_EC_VALUE; |
3539 | 3858 | ||
3540 | if ((bnctx = BN_CTX_new()) == NULL) | 3859 | if ((order = BN_new()) == NULL || (tmp = BN_new()) == NULL) { |
3541 | return SSH_ERR_ALLOC_FAIL; | ||
3542 | BN_CTX_start(bnctx); | ||
3543 | |||
3544 | if ((order = BN_CTX_get(bnctx)) == NULL || | ||
3545 | (tmp = BN_CTX_get(bnctx)) == NULL) { | ||
3546 | ret = SSH_ERR_ALLOC_FAIL; | 3860 | ret = SSH_ERR_ALLOC_FAIL; |
3547 | goto out; | 3861 | goto out; |
3548 | } | 3862 | } |
3549 | 3863 | ||
3550 | /* log2(private) > log2(order)/2 */ | 3864 | /* log2(private) > log2(order)/2 */ |
3551 | if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, bnctx) != 1) { | 3865 | if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, NULL) != 1) { |
3552 | ret = SSH_ERR_LIBCRYPTO_ERROR; | 3866 | ret = SSH_ERR_LIBCRYPTO_ERROR; |
3553 | goto out; | 3867 | goto out; |
3554 | } | 3868 | } |
@@ -3565,47 +3879,43 @@ sshkey_ec_validate_private(const EC_KEY *key) | |||
3565 | goto out; | 3879 | goto out; |
3566 | ret = 0; | 3880 | ret = 0; |
3567 | out: | 3881 | out: |
3568 | BN_CTX_free(bnctx); | 3882 | BN_clear_free(order); |
3883 | BN_clear_free(tmp); | ||
3569 | return ret; | 3884 | return ret; |
3570 | } | 3885 | } |
3571 | 3886 | ||
3572 | void | 3887 | void |
3573 | sshkey_dump_ec_point(const EC_GROUP *group, const EC_POINT *point) | 3888 | sshkey_dump_ec_point(const EC_GROUP *group, const EC_POINT *point) |
3574 | { | 3889 | { |
3575 | BIGNUM *x, *y; | 3890 | BIGNUM *x = NULL, *y = NULL; |
3576 | BN_CTX *bnctx; | ||
3577 | 3891 | ||
3578 | if (point == NULL) { | 3892 | if (point == NULL) { |
3579 | fputs("point=(NULL)\n", stderr); | 3893 | fputs("point=(NULL)\n", stderr); |
3580 | return; | 3894 | return; |
3581 | } | 3895 | } |
3582 | if ((bnctx = BN_CTX_new()) == NULL) { | 3896 | if ((x = BN_new()) == NULL || (y = BN_new()) == NULL) { |
3583 | fprintf(stderr, "%s: BN_CTX_new failed\n", __func__); | 3897 | fprintf(stderr, "%s: BN_new failed\n", __func__); |
3584 | return; | 3898 | goto out; |
3585 | } | ||
3586 | BN_CTX_start(bnctx); | ||
3587 | if ((x = BN_CTX_get(bnctx)) == NULL || | ||
3588 | (y = BN_CTX_get(bnctx)) == NULL) { | ||
3589 | fprintf(stderr, "%s: BN_CTX_get failed\n", __func__); | ||
3590 | return; | ||
3591 | } | 3899 | } |
3592 | if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != | 3900 | if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != |
3593 | NID_X9_62_prime_field) { | 3901 | NID_X9_62_prime_field) { |
3594 | fprintf(stderr, "%s: group is not a prime field\n", __func__); | 3902 | fprintf(stderr, "%s: group is not a prime field\n", __func__); |
3595 | return; | 3903 | goto out; |
3596 | } | 3904 | } |
3597 | if (EC_POINT_get_affine_coordinates_GFp(group, point, x, y, | 3905 | if (EC_POINT_get_affine_coordinates_GFp(group, point, |
3598 | bnctx) != 1) { | 3906 | x, y, NULL) != 1) { |
3599 | fprintf(stderr, "%s: EC_POINT_get_affine_coordinates_GFp\n", | 3907 | fprintf(stderr, "%s: EC_POINT_get_affine_coordinates_GFp\n", |
3600 | __func__); | 3908 | __func__); |
3601 | return; | 3909 | goto out; |
3602 | } | 3910 | } |
3603 | fputs("x=", stderr); | 3911 | fputs("x=", stderr); |
3604 | BN_print_fp(stderr, x); | 3912 | BN_print_fp(stderr, x); |
3605 | fputs("\ny=", stderr); | 3913 | fputs("\ny=", stderr); |
3606 | BN_print_fp(stderr, y); | 3914 | BN_print_fp(stderr, y); |
3607 | fputs("\n", stderr); | 3915 | fputs("\n", stderr); |
3608 | BN_CTX_free(bnctx); | 3916 | out: |
3917 | BN_clear_free(x); | ||
3918 | BN_clear_free(y); | ||
3609 | } | 3919 | } |
3610 | 3920 | ||
3611 | void | 3921 | void |
@@ -4087,9 +4397,13 @@ sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob, | |||
4087 | break; /* see below */ | 4397 | break; /* see below */ |
4088 | #endif /* WITH_OPENSSL */ | 4398 | #endif /* WITH_OPENSSL */ |
4089 | case KEY_ED25519: | 4399 | case KEY_ED25519: |
4400 | case KEY_ED25519_SK: | ||
4090 | #ifdef WITH_XMSS | 4401 | #ifdef WITH_XMSS |
4091 | case KEY_XMSS: | 4402 | case KEY_XMSS: |
4092 | #endif /* WITH_XMSS */ | 4403 | #endif /* WITH_XMSS */ |
4404 | #ifdef WITH_OPENSSL | ||
4405 | case KEY_ECDSA_SK: | ||
4406 | #endif /* WITH_OPENSSL */ | ||
4093 | return sshkey_private_to_blob2(key, blob, passphrase, | 4407 | return sshkey_private_to_blob2(key, blob, passphrase, |
4094 | comment, openssh_format_cipher, openssh_format_rounds); | 4408 | comment, openssh_format_cipher, openssh_format_rounds); |
4095 | default: | 4409 | default: |
@@ -4111,7 +4425,6 @@ sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob, | |||
4111 | #endif /* WITH_OPENSSL */ | 4425 | #endif /* WITH_OPENSSL */ |
4112 | } | 4426 | } |
4113 | 4427 | ||
4114 | |||
4115 | #ifdef WITH_OPENSSL | 4428 | #ifdef WITH_OPENSSL |
4116 | static int | 4429 | static int |
4117 | translate_libcrypto_error(unsigned long pem_err) | 4430 | translate_libcrypto_error(unsigned long pem_err) |
@@ -4345,6 +4658,12 @@ sshkey_parse_private_fileblob(struct sshbuf *buffer, const char *passphrase, | |||
4345 | passphrase, keyp, commentp); | 4658 | passphrase, keyp, commentp); |
4346 | } | 4659 | } |
4347 | 4660 | ||
4661 | void | ||
4662 | sshkey_sig_details_free(struct sshkey_sig_details *details) | ||
4663 | { | ||
4664 | freezero(details, sizeof(*details)); | ||
4665 | } | ||
4666 | |||
4348 | #ifdef WITH_XMSS | 4667 | #ifdef WITH_XMSS |
4349 | /* | 4668 | /* |
4350 | * serialize the key with the current state and forward the state | 4669 | * serialize the key with the current state and forward the state |