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