summaryrefslogtreecommitdiff
path: root/sshkey.c
diff options
context:
space:
mode:
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 4d2048b6a..fd5b77246 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, 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
224static int
225key_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
215int 237int
216sshkey_ecdsa_nid_from_name(const char *name) 238sshkey_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
379int
380sshkey_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 */
352int 394int
353sshkey_type_plain(int type) 395sshkey_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,
2597int 2729int
2598sshkey_sign(struct sshkey *key, 2730sshkey_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,
2653int 2793int
2654sshkey_verify(const struct sshkey *key, 2794sshkey_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. */
2735int 2892int
2736sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg, 2893sshkey_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,
2890static int 3059static int
2891default_key_sign(struct sshkey *key, u_char **sigp, size_t *lenp, 3060default_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
2900int 3070int
2901sshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg) 3071sshkey_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
2906int 3078int
@@ -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)
3457int 3779int
3458sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public) 3780sshkey_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)
3534int 3854int
3535sshkey_ec_validate_private(const EC_KEY *key) 3855sshkey_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
3573void 3888void
3574sshkey_dump_ec_point(const EC_GROUP *group, const EC_POINT *point) 3889sshkey_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
3612void 3922void
@@ -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
4117static int 4430static int
4118translate_libcrypto_error(unsigned long pem_err) 4431translate_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
4662void
4663sshkey_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