summaryrefslogtreecommitdiff
path: root/sshkey.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2020-02-21 11:57:14 +0000
committerColin Watson <cjwatson@debian.org>2020-02-21 11:57:14 +0000
commitf0de78bd4f29fa688c5df116f3f9cd43543a76d0 (patch)
tree856b0dee3f2764c13a32dad5ffe2424fab7fef41 /sshkey.c
parent4213eec74e74de6310c27a40c3e9759a08a73996 (diff)
parent8aa3455b16fddea4c0144a7c4a1edb10ec67dcc8 (diff)
Import openssh_8.2p1.orig.tar.gz
Diffstat (limited to 'sshkey.c')
-rw-r--r--sshkey.c509
1 files changed, 414 insertions, 95 deletions
diff --git a/sshkey.c b/sshkey.c
index ef90563b3..57995ee68 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -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
223static int
224key_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
214int 236int
215sshkey_ecdsa_nid_from_name(const char *name) 237sshkey_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
378int
379sshkey_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 */
351int 393int
352sshkey_type_plain(int type) 394sshkey_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,
2596int 2728int
2597sshkey_sign(struct sshkey *key, 2729sshkey_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,
2652int 2792int
2653sshkey_verify(const struct sshkey *key, 2793sshkey_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. */
2734int 2891int
2735sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg, 2892sshkey_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,
2889static int 3058static int
2890default_key_sign(struct sshkey *key, u_char **sigp, size_t *lenp, 3059default_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
2899int 3069int
2900sshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg) 3070sshkey_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
2905int 3077int
@@ -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)
3456int 3778int
3457sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public) 3779sshkey_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)
3533int 3853int
3534sshkey_ec_validate_private(const EC_KEY *key) 3854sshkey_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
3572void 3887void
3573sshkey_dump_ec_point(const EC_GROUP *group, const EC_POINT *point) 3888sshkey_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
3611void 3921void
@@ -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
4116static int 4429static int
4117translate_libcrypto_error(unsigned long pem_err) 4430translate_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
4661void
4662sshkey_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