summaryrefslogtreecommitdiff
path: root/sshkey.c
diff options
context:
space:
mode:
Diffstat (limited to 'sshkey.c')
-rw-r--r--sshkey.c816
1 files changed, 467 insertions, 349 deletions
diff --git a/sshkey.c b/sshkey.c
index 72c08c7e0..6555c5ef8 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshkey.c,v 1.66 2018/07/03 13:20:25 djm Exp $ */ 1/* $OpenBSD: sshkey.c,v 1.72 2018/10/11 00:52:46 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.
@@ -60,6 +60,8 @@
60 60
61#include "xmss_fast.h" 61#include "xmss_fast.h"
62 62
63#include "openbsd-compat/openssl-compat.h"
64
63/* openssh private key file format */ 65/* openssh private key file format */
64#define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n" 66#define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n"
65#define MARK_END "-----END OPENSSH PRIVATE KEY-----\n" 67#define MARK_END "-----END OPENSSH PRIVATE KEY-----\n"
@@ -78,6 +80,7 @@ int sshkey_private_serialize_opt(const struct sshkey *key,
78 struct sshbuf *buf, enum sshkey_serialize_rep); 80 struct sshbuf *buf, enum sshkey_serialize_rep);
79static int sshkey_from_blob_internal(struct sshbuf *buf, 81static int sshkey_from_blob_internal(struct sshbuf *buf,
80 struct sshkey **keyp, int allow_cert); 82 struct sshkey **keyp, int allow_cert);
83static int get_sigtype(const u_char *sig, size_t siglen, char **sigtypep);
81 84
82/* Supported key types */ 85/* Supported key types */
83struct keytype { 86struct keytype {
@@ -116,17 +119,9 @@ static const struct keytype keytypes[] = {
116 { "ssh-rsa-cert-v01@openssh.com", "RSA-CERT", NULL, 119 { "ssh-rsa-cert-v01@openssh.com", "RSA-CERT", NULL,
117 KEY_RSA_CERT, 0, 1, 0 }, 120 KEY_RSA_CERT, 0, 1, 0 },
118 { "rsa-sha2-256-cert-v01@openssh.com", "RSA-CERT", 121 { "rsa-sha2-256-cert-v01@openssh.com", "RSA-CERT",
119 "ssh-rsa-sha2-256", KEY_RSA_CERT, 0, 1, 1 }, 122 "rsa-sha2-256", KEY_RSA_CERT, 0, 1, 1 },
120 { "rsa-sha2-512-cert-v01@openssh.com", "RSA-CERT",
121 "ssh-rsa-sha2-512", KEY_RSA_CERT, 0, 1, 1 },
122 { "ssh-dss-cert-v01@openssh.com", "DSA-CERT", NULL,
123 KEY_DSA_CERT, 0, 1, 0 },
124 { "ssh-rsa-cert-v01@openssh.com", "RSA-CERT", NULL,
125 KEY_RSA_CERT, 0, 1, 0 },
126 { "rsa-sha2-256-cert-v01@openssh.com", "RSA-CERT",
127 "ssh-rsa-sha2-256", KEY_RSA_CERT, 0, 1, 1 },
128 { "rsa-sha2-512-cert-v01@openssh.com", "RSA-CERT", 123 { "rsa-sha2-512-cert-v01@openssh.com", "RSA-CERT",
129 "ssh-rsa-sha2-512", KEY_RSA_CERT, 0, 1, 1 }, 124 "rsa-sha2-512", KEY_RSA_CERT, 0, 1, 1 },
130 { "ssh-dss-cert-v01@openssh.com", "DSA-CERT", NULL, 125 { "ssh-dss-cert-v01@openssh.com", "DSA-CERT", NULL,
131 KEY_DSA_CERT, 0, 1, 0 }, 126 KEY_DSA_CERT, 0, 1, 0 },
132# ifdef OPENSSL_HAS_ECC 127# ifdef OPENSSL_HAS_ECC
@@ -288,14 +283,24 @@ sshkey_names_valid2(const char *names, int allow_wildcard)
288u_int 283u_int
289sshkey_size(const struct sshkey *k) 284sshkey_size(const struct sshkey *k)
290{ 285{
286#ifdef WITH_OPENSSL
287 const BIGNUM *rsa_n, *dsa_p;
288#endif /* WITH_OPENSSL */
289
291 switch (k->type) { 290 switch (k->type) {
292#ifdef WITH_OPENSSL 291#ifdef WITH_OPENSSL
293 case KEY_RSA: 292 case KEY_RSA:
294 case KEY_RSA_CERT: 293 case KEY_RSA_CERT:
295 return BN_num_bits(k->rsa->n); 294 if (k->rsa == NULL)
295 return 0;
296 RSA_get0_key(k->rsa, &rsa_n, NULL, NULL);
297 return BN_num_bits(rsa_n);
296 case KEY_DSA: 298 case KEY_DSA:
297 case KEY_DSA_CERT: 299 case KEY_DSA_CERT:
298 return BN_num_bits(k->dsa->p); 300 if (k->dsa == NULL)
301 return 0;
302 DSA_get0_pqg(k->dsa, &dsa_p, NULL, NULL);
303 return BN_num_bits(dsa_p);
299 case KEY_ECDSA: 304 case KEY_ECDSA:
300 case KEY_ECDSA_CERT: 305 case KEY_ECDSA_CERT:
301 return sshkey_curve_nid_to_bits(k->ecdsa_nid); 306 return sshkey_curve_nid_to_bits(k->ecdsa_nid);
@@ -453,6 +458,7 @@ cert_free(struct sshkey_cert *cert)
453 free(cert->principals[i]); 458 free(cert->principals[i]);
454 free(cert->principals); 459 free(cert->principals);
455 sshkey_free(cert->signature_key); 460 sshkey_free(cert->signature_key);
461 free(cert->signature_type);
456 freezero(cert, sizeof(*cert)); 462 freezero(cert, sizeof(*cert));
457} 463}
458 464
@@ -472,6 +478,7 @@ cert_new(void)
472 cert->key_id = NULL; 478 cert->key_id = NULL;
473 cert->principals = NULL; 479 cert->principals = NULL;
474 cert->signature_key = NULL; 480 cert->signature_key = NULL;
481 cert->signature_type = NULL;
475 return cert; 482 return cert;
476} 483}
477 484
@@ -500,10 +507,7 @@ sshkey_new(int type)
500#ifdef WITH_OPENSSL 507#ifdef WITH_OPENSSL
501 case KEY_RSA: 508 case KEY_RSA:
502 case KEY_RSA_CERT: 509 case KEY_RSA_CERT:
503 if ((rsa = RSA_new()) == NULL || 510 if ((rsa = RSA_new()) == NULL) {
504 (rsa->n = BN_new()) == NULL ||
505 (rsa->e = BN_new()) == NULL) {
506 RSA_free(rsa);
507 free(k); 511 free(k);
508 return NULL; 512 return NULL;
509 } 513 }
@@ -511,12 +515,7 @@ sshkey_new(int type)
511 break; 515 break;
512 case KEY_DSA: 516 case KEY_DSA:
513 case KEY_DSA_CERT: 517 case KEY_DSA_CERT:
514 if ((dsa = DSA_new()) == NULL || 518 if ((dsa = DSA_new()) == NULL) {
515 (dsa->p = BN_new()) == NULL ||
516 (dsa->q = BN_new()) == NULL ||
517 (dsa->g = BN_new()) == NULL ||
518 (dsa->pub_key = BN_new()) == NULL) {
519 DSA_free(dsa);
520 free(k); 519 free(k);
521 return NULL; 520 return NULL;
522 } 521 }
@@ -550,61 +549,6 @@ sshkey_new(int type)
550 return k; 549 return k;
551} 550}
552 551
553int
554sshkey_add_private(struct sshkey *k)
555{
556 switch (k->type) {
557#ifdef WITH_OPENSSL
558 case KEY_RSA:
559 case KEY_RSA_CERT:
560#define bn_maybe_alloc_failed(p) (p == NULL && (p = BN_new()) == NULL)
561 if (bn_maybe_alloc_failed(k->rsa->d) ||
562 bn_maybe_alloc_failed(k->rsa->iqmp) ||
563 bn_maybe_alloc_failed(k->rsa->q) ||
564 bn_maybe_alloc_failed(k->rsa->p) ||
565 bn_maybe_alloc_failed(k->rsa->dmq1) ||
566 bn_maybe_alloc_failed(k->rsa->dmp1))
567 return SSH_ERR_ALLOC_FAIL;
568 break;
569 case KEY_DSA:
570 case KEY_DSA_CERT:
571 if (bn_maybe_alloc_failed(k->dsa->priv_key))
572 return SSH_ERR_ALLOC_FAIL;
573 break;
574#undef bn_maybe_alloc_failed
575 case KEY_ECDSA:
576 case KEY_ECDSA_CERT:
577 /* Cannot do anything until we know the group */
578 break;
579#endif /* WITH_OPENSSL */
580 case KEY_ED25519:
581 case KEY_ED25519_CERT:
582 case KEY_XMSS:
583 case KEY_XMSS_CERT:
584 /* no need to prealloc */
585 break;
586 case KEY_UNSPEC:
587 break;
588 default:
589 return SSH_ERR_INVALID_ARGUMENT;
590 }
591 return 0;
592}
593
594struct sshkey *
595sshkey_new_private(int type)
596{
597 struct sshkey *k = sshkey_new(type);
598
599 if (k == NULL)
600 return NULL;
601 if (sshkey_add_private(k) != 0) {
602 sshkey_free(k);
603 return NULL;
604 }
605 return k;
606}
607
608void 552void
609sshkey_free(struct sshkey *k) 553sshkey_free(struct sshkey *k)
610{ 554{
@@ -683,9 +627,15 @@ cert_compare(struct sshkey_cert *a, struct sshkey_cert *b)
683int 627int
684sshkey_equal_public(const struct sshkey *a, const struct sshkey *b) 628sshkey_equal_public(const struct sshkey *a, const struct sshkey *b)
685{ 629{
686#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) 630#if defined(WITH_OPENSSL)
631 const BIGNUM *rsa_e_a, *rsa_n_a;
632 const BIGNUM *rsa_e_b, *rsa_n_b;
633 const BIGNUM *dsa_p_a, *dsa_q_a, *dsa_g_a, *dsa_pub_key_a;
634 const BIGNUM *dsa_p_b, *dsa_q_b, *dsa_g_b, *dsa_pub_key_b;
635# if defined(OPENSSL_HAS_ECC)
687 BN_CTX *bnctx; 636 BN_CTX *bnctx;
688#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ 637# endif /* OPENSSL_HAS_ECC */
638#endif /* WITH_OPENSSL */
689 639
690 if (a == NULL || b == NULL || 640 if (a == NULL || b == NULL ||
691 sshkey_type_plain(a->type) != sshkey_type_plain(b->type)) 641 sshkey_type_plain(a->type) != sshkey_type_plain(b->type))
@@ -695,16 +645,24 @@ sshkey_equal_public(const struct sshkey *a, const struct sshkey *b)
695#ifdef WITH_OPENSSL 645#ifdef WITH_OPENSSL
696 case KEY_RSA_CERT: 646 case KEY_RSA_CERT:
697 case KEY_RSA: 647 case KEY_RSA:
698 return a->rsa != NULL && b->rsa != NULL && 648 if (a->rsa == NULL || b->rsa == NULL)
699 BN_cmp(a->rsa->e, b->rsa->e) == 0 && 649 return 0;
700 BN_cmp(a->rsa->n, b->rsa->n) == 0; 650 RSA_get0_key(a->rsa, &rsa_n_a, &rsa_e_a, NULL);
651 RSA_get0_key(b->rsa, &rsa_n_b, &rsa_e_b, NULL);
652 return BN_cmp(rsa_e_a, rsa_e_b) == 0 &&
653 BN_cmp(rsa_n_a, rsa_n_b) == 0;
701 case KEY_DSA_CERT: 654 case KEY_DSA_CERT:
702 case KEY_DSA: 655 case KEY_DSA:
703 return a->dsa != NULL && b->dsa != NULL && 656 if (a->dsa == NULL || b->dsa == NULL)
704 BN_cmp(a->dsa->p, b->dsa->p) == 0 && 657 return 0;
705 BN_cmp(a->dsa->q, b->dsa->q) == 0 && 658 DSA_get0_pqg(a->dsa, &dsa_p_a, &dsa_q_a, &dsa_g_a);
706 BN_cmp(a->dsa->g, b->dsa->g) == 0 && 659 DSA_get0_pqg(b->dsa, &dsa_p_b, &dsa_q_b, &dsa_g_b);
707 BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0; 660 DSA_get0_key(a->dsa, &dsa_pub_key_a, NULL);
661 DSA_get0_key(b->dsa, &dsa_pub_key_b, NULL);
662 return BN_cmp(dsa_p_a, dsa_p_b) == 0 &&
663 BN_cmp(dsa_q_a, dsa_q_b) == 0 &&
664 BN_cmp(dsa_g_a, dsa_g_b) == 0 &&
665 BN_cmp(dsa_pub_key_a, dsa_pub_key_b) == 0;
708# ifdef OPENSSL_HAS_ECC 666# ifdef OPENSSL_HAS_ECC
709 case KEY_ECDSA_CERT: 667 case KEY_ECDSA_CERT:
710 case KEY_ECDSA: 668 case KEY_ECDSA:
@@ -761,6 +719,9 @@ to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain,
761{ 719{
762 int type, ret = SSH_ERR_INTERNAL_ERROR; 720 int type, ret = SSH_ERR_INTERNAL_ERROR;
763 const char *typename; 721 const char *typename;
722#ifdef WITH_OPENSSL
723 const BIGNUM *rsa_n, *rsa_e, *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key;
724#endif /* WITH_OPENSSL */
764 725
765 if (key == NULL) 726 if (key == NULL)
766 return SSH_ERR_INVALID_ARGUMENT; 727 return SSH_ERR_INVALID_ARGUMENT;
@@ -793,11 +754,13 @@ to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain,
793 case KEY_DSA: 754 case KEY_DSA:
794 if (key->dsa == NULL) 755 if (key->dsa == NULL)
795 return SSH_ERR_INVALID_ARGUMENT; 756 return SSH_ERR_INVALID_ARGUMENT;
757 DSA_get0_pqg(key->dsa, &dsa_p, &dsa_q, &dsa_g);
758 DSA_get0_key(key->dsa, &dsa_pub_key, NULL);
796 if ((ret = sshbuf_put_cstring(b, typename)) != 0 || 759 if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
797 (ret = sshbuf_put_bignum2(b, key->dsa->p)) != 0 || 760 (ret = sshbuf_put_bignum2(b, dsa_p)) != 0 ||
798 (ret = sshbuf_put_bignum2(b, key->dsa->q)) != 0 || 761 (ret = sshbuf_put_bignum2(b, dsa_q)) != 0 ||
799 (ret = sshbuf_put_bignum2(b, key->dsa->g)) != 0 || 762 (ret = sshbuf_put_bignum2(b, dsa_g)) != 0 ||
800 (ret = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0) 763 (ret = sshbuf_put_bignum2(b, dsa_pub_key)) != 0)
801 return ret; 764 return ret;
802 break; 765 break;
803# ifdef OPENSSL_HAS_ECC 766# ifdef OPENSSL_HAS_ECC
@@ -814,9 +777,10 @@ to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain,
814 case KEY_RSA: 777 case KEY_RSA:
815 if (key->rsa == NULL) 778 if (key->rsa == NULL)
816 return SSH_ERR_INVALID_ARGUMENT; 779 return SSH_ERR_INVALID_ARGUMENT;
780 RSA_get0_key(key->rsa, &rsa_n, &rsa_e, NULL);
817 if ((ret = sshbuf_put_cstring(b, typename)) != 0 || 781 if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
818 (ret = sshbuf_put_bignum2(b, key->rsa->e)) != 0 || 782 (ret = sshbuf_put_bignum2(b, rsa_e)) != 0 ||
819 (ret = sshbuf_put_bignum2(b, key->rsa->n)) != 0) 783 (ret = sshbuf_put_bignum2(b, rsa_n)) != 0)
820 return ret; 784 return ret;
821 break; 785 break;
822#endif /* WITH_OPENSSL */ 786#endif /* WITH_OPENSSL */
@@ -1695,114 +1659,163 @@ sshkey_cert_copy(const struct sshkey *from_key, struct sshkey *to_key)
1695 u_int i; 1659 u_int i;
1696 const struct sshkey_cert *from; 1660 const struct sshkey_cert *from;
1697 struct sshkey_cert *to; 1661 struct sshkey_cert *to;
1698 int ret = SSH_ERR_INTERNAL_ERROR; 1662 int r = SSH_ERR_INTERNAL_ERROR;
1699
1700 if (to_key->cert != NULL) {
1701 cert_free(to_key->cert);
1702 to_key->cert = NULL;
1703 }
1704 1663
1705 if ((from = from_key->cert) == NULL) 1664 if (to_key == NULL || (from = from_key->cert) == NULL)
1706 return SSH_ERR_INVALID_ARGUMENT; 1665 return SSH_ERR_INVALID_ARGUMENT;
1707 1666
1708 if ((to = to_key->cert = cert_new()) == NULL) 1667 if ((to = cert_new()) == NULL)
1709 return SSH_ERR_ALLOC_FAIL; 1668 return SSH_ERR_ALLOC_FAIL;
1710 1669
1711 if ((ret = sshbuf_putb(to->certblob, from->certblob)) != 0 || 1670 if ((r = sshbuf_putb(to->certblob, from->certblob)) != 0 ||
1712 (ret = sshbuf_putb(to->critical, from->critical)) != 0 || 1671 (r = sshbuf_putb(to->critical, from->critical)) != 0 ||
1713 (ret = sshbuf_putb(to->extensions, from->extensions)) != 0) 1672 (r = sshbuf_putb(to->extensions, from->extensions)) != 0)
1714 return ret; 1673 goto out;
1715 1674
1716 to->serial = from->serial; 1675 to->serial = from->serial;
1717 to->type = from->type; 1676 to->type = from->type;
1718 if (from->key_id == NULL) 1677 if (from->key_id == NULL)
1719 to->key_id = NULL; 1678 to->key_id = NULL;
1720 else if ((to->key_id = strdup(from->key_id)) == NULL) 1679 else if ((to->key_id = strdup(from->key_id)) == NULL) {
1721 return SSH_ERR_ALLOC_FAIL; 1680 r = SSH_ERR_ALLOC_FAIL;
1681 goto out;
1682 }
1722 to->valid_after = from->valid_after; 1683 to->valid_after = from->valid_after;
1723 to->valid_before = from->valid_before; 1684 to->valid_before = from->valid_before;
1724 if (from->signature_key == NULL) 1685 if (from->signature_key == NULL)
1725 to->signature_key = NULL; 1686 to->signature_key = NULL;
1726 else if ((ret = sshkey_from_private(from->signature_key, 1687 else if ((r = sshkey_from_private(from->signature_key,
1727 &to->signature_key)) != 0) 1688 &to->signature_key)) != 0)
1728 return ret; 1689 goto out;
1729 1690 if (from->signature_type != NULL &&
1730 if (from->nprincipals > SSHKEY_CERT_MAX_PRINCIPALS) 1691 (to->signature_type = strdup(from->signature_type)) == NULL) {
1731 return SSH_ERR_INVALID_ARGUMENT; 1692 r = SSH_ERR_ALLOC_FAIL;
1693 goto out;
1694 }
1695 if (from->nprincipals > SSHKEY_CERT_MAX_PRINCIPALS) {
1696 r = SSH_ERR_INVALID_ARGUMENT;
1697 goto out;
1698 }
1732 if (from->nprincipals > 0) { 1699 if (from->nprincipals > 0) {
1733 if ((to->principals = calloc(from->nprincipals, 1700 if ((to->principals = calloc(from->nprincipals,
1734 sizeof(*to->principals))) == NULL) 1701 sizeof(*to->principals))) == NULL) {
1735 return SSH_ERR_ALLOC_FAIL; 1702 r = SSH_ERR_ALLOC_FAIL;
1703 goto out;
1704 }
1736 for (i = 0; i < from->nprincipals; i++) { 1705 for (i = 0; i < from->nprincipals; i++) {
1737 to->principals[i] = strdup(from->principals[i]); 1706 to->principals[i] = strdup(from->principals[i]);
1738 if (to->principals[i] == NULL) { 1707 if (to->principals[i] == NULL) {
1739 to->nprincipals = i; 1708 to->nprincipals = i;
1740 return SSH_ERR_ALLOC_FAIL; 1709 r = SSH_ERR_ALLOC_FAIL;
1710 goto out;
1741 } 1711 }
1742 } 1712 }
1743 } 1713 }
1744 to->nprincipals = from->nprincipals; 1714 to->nprincipals = from->nprincipals;
1745 return 0; 1715
1716 /* success */
1717 cert_free(to_key->cert);
1718 to_key->cert = to;
1719 to = NULL;
1720 r = 0;
1721 out:
1722 cert_free(to);
1723 return r;
1746} 1724}
1747 1725
1748int 1726int
1749sshkey_from_private(const struct sshkey *k, struct sshkey **pkp) 1727sshkey_from_private(const struct sshkey *k, struct sshkey **pkp)
1750{ 1728{
1751 struct sshkey *n = NULL; 1729 struct sshkey *n = NULL;
1752 int ret = SSH_ERR_INTERNAL_ERROR; 1730 int r = SSH_ERR_INTERNAL_ERROR;
1731#ifdef WITH_OPENSSL
1732 const BIGNUM *rsa_n, *rsa_e;
1733 BIGNUM *rsa_n_dup = NULL, *rsa_e_dup = NULL;
1734 const BIGNUM *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key;
1735 BIGNUM *dsa_p_dup = NULL, *dsa_q_dup = NULL, *dsa_g_dup = NULL;
1736 BIGNUM *dsa_pub_key_dup = NULL;
1737#endif /* WITH_OPENSSL */
1753 1738
1754 *pkp = NULL; 1739 *pkp = NULL;
1755 switch (k->type) { 1740 switch (k->type) {
1756#ifdef WITH_OPENSSL 1741#ifdef WITH_OPENSSL
1757 case KEY_DSA: 1742 case KEY_DSA:
1758 case KEY_DSA_CERT: 1743 case KEY_DSA_CERT:
1759 if ((n = sshkey_new(k->type)) == NULL) 1744 if ((n = sshkey_new(k->type)) == NULL) {
1760 return SSH_ERR_ALLOC_FAIL; 1745 r = SSH_ERR_ALLOC_FAIL;
1761 if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) || 1746 goto out;
1762 (BN_copy(n->dsa->q, k->dsa->q) == NULL) ||
1763 (BN_copy(n->dsa->g, k->dsa->g) == NULL) ||
1764 (BN_copy(n->dsa->pub_key, k->dsa->pub_key) == NULL)) {
1765 sshkey_free(n);
1766 return SSH_ERR_ALLOC_FAIL;
1767 } 1747 }
1748
1749 DSA_get0_pqg(k->dsa, &dsa_p, &dsa_q, &dsa_g);
1750 DSA_get0_key(k->dsa, &dsa_pub_key, NULL);
1751 if ((dsa_p_dup = BN_dup(dsa_p)) == NULL ||
1752 (dsa_q_dup = BN_dup(dsa_q)) == NULL ||
1753 (dsa_g_dup = BN_dup(dsa_g)) == NULL ||
1754 (dsa_pub_key_dup = BN_dup(dsa_pub_key)) == NULL) {
1755 r = SSH_ERR_ALLOC_FAIL;
1756 goto out;
1757 }
1758 if (!DSA_set0_pqg(n->dsa, dsa_p_dup, dsa_q_dup, dsa_g_dup)) {
1759 r = SSH_ERR_LIBCRYPTO_ERROR;
1760 goto out;
1761 }
1762 dsa_p_dup = dsa_q_dup = dsa_g_dup = NULL; /* transferred */
1763 if (!DSA_set0_key(n->dsa, dsa_pub_key_dup, NULL)) {
1764 r = SSH_ERR_LIBCRYPTO_ERROR;
1765 goto out;
1766 }
1767 dsa_pub_key_dup = NULL; /* transferred */
1768
1768 break; 1769 break;
1769# ifdef OPENSSL_HAS_ECC 1770# ifdef OPENSSL_HAS_ECC
1770 case KEY_ECDSA: 1771 case KEY_ECDSA:
1771 case KEY_ECDSA_CERT: 1772 case KEY_ECDSA_CERT:
1772 if ((n = sshkey_new(k->type)) == NULL) 1773 if ((n = sshkey_new(k->type)) == NULL) {
1773 return SSH_ERR_ALLOC_FAIL; 1774 r = SSH_ERR_ALLOC_FAIL;
1775 goto out;
1776 }
1774 n->ecdsa_nid = k->ecdsa_nid; 1777 n->ecdsa_nid = k->ecdsa_nid;
1775 n->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid); 1778 n->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid);
1776 if (n->ecdsa == NULL) { 1779 if (n->ecdsa == NULL) {
1777 sshkey_free(n); 1780 r = SSH_ERR_ALLOC_FAIL;
1778 return SSH_ERR_ALLOC_FAIL; 1781 goto out;
1779 } 1782 }
1780 if (EC_KEY_set_public_key(n->ecdsa, 1783 if (EC_KEY_set_public_key(n->ecdsa,
1781 EC_KEY_get0_public_key(k->ecdsa)) != 1) { 1784 EC_KEY_get0_public_key(k->ecdsa)) != 1) {
1782 sshkey_free(n); 1785 r = SSH_ERR_LIBCRYPTO_ERROR;
1783 return SSH_ERR_LIBCRYPTO_ERROR; 1786 goto out;
1784 } 1787 }
1785 break; 1788 break;
1786# endif /* OPENSSL_HAS_ECC */ 1789# endif /* OPENSSL_HAS_ECC */
1787 case KEY_RSA: 1790 case KEY_RSA:
1788 case KEY_RSA_CERT: 1791 case KEY_RSA_CERT:
1789 if ((n = sshkey_new(k->type)) == NULL) 1792 if ((n = sshkey_new(k->type)) == NULL) {
1790 return SSH_ERR_ALLOC_FAIL; 1793 r = SSH_ERR_ALLOC_FAIL;
1791 if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) || 1794 goto out;
1792 (BN_copy(n->rsa->e, k->rsa->e) == NULL)) {
1793 sshkey_free(n);
1794 return SSH_ERR_ALLOC_FAIL;
1795 } 1795 }
1796 RSA_get0_key(k->rsa, &rsa_n, &rsa_e, NULL);
1797 if ((rsa_n_dup = BN_dup(rsa_n)) == NULL ||
1798 (rsa_e_dup = BN_dup(rsa_e)) == NULL) {
1799 r = SSH_ERR_ALLOC_FAIL;
1800 goto out;
1801 }
1802 if (!RSA_set0_key(n->rsa, rsa_n_dup, rsa_e_dup, NULL)) {
1803 r = SSH_ERR_LIBCRYPTO_ERROR;
1804 goto out;
1805 }
1806 rsa_n_dup = rsa_e_dup = NULL; /* transferred */
1796 break; 1807 break;
1797#endif /* WITH_OPENSSL */ 1808#endif /* WITH_OPENSSL */
1798 case KEY_ED25519: 1809 case KEY_ED25519:
1799 case KEY_ED25519_CERT: 1810 case KEY_ED25519_CERT:
1800 if ((n = sshkey_new(k->type)) == NULL) 1811 if ((n = sshkey_new(k->type)) == NULL) {
1801 return SSH_ERR_ALLOC_FAIL; 1812 r = SSH_ERR_ALLOC_FAIL;
1813 goto out;
1814 }
1802 if (k->ed25519_pk != NULL) { 1815 if (k->ed25519_pk != NULL) {
1803 if ((n->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) { 1816 if ((n->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) {
1804 sshkey_free(n); 1817 r = SSH_ERR_ALLOC_FAIL;
1805 return SSH_ERR_ALLOC_FAIL; 1818 goto out;
1806 } 1819 }
1807 memcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ); 1820 memcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ);
1808 } 1821 }
@@ -1810,37 +1823,48 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp)
1810#ifdef WITH_XMSS 1823#ifdef WITH_XMSS
1811 case KEY_XMSS: 1824 case KEY_XMSS:
1812 case KEY_XMSS_CERT: 1825 case KEY_XMSS_CERT:
1813 if ((n = sshkey_new(k->type)) == NULL) 1826 if ((n = sshkey_new(k->type)) == NULL) {
1814 return SSH_ERR_ALLOC_FAIL; 1827 r = SSH_ERR_ALLOC_FAIL;
1815 if ((ret = sshkey_xmss_init(n, k->xmss_name)) != 0) { 1828 goto out;
1816 sshkey_free(n);
1817 return ret;
1818 } 1829 }
1830 if ((r = sshkey_xmss_init(n, k->xmss_name)) != 0)
1831 goto out;
1819 if (k->xmss_pk != NULL) { 1832 if (k->xmss_pk != NULL) {
1820 size_t pklen = sshkey_xmss_pklen(k); 1833 size_t pklen = sshkey_xmss_pklen(k);
1821 if (pklen == 0 || sshkey_xmss_pklen(n) != pklen) { 1834 if (pklen == 0 || sshkey_xmss_pklen(n) != pklen) {
1822 sshkey_free(n); 1835 r = SSH_ERR_INTERNAL_ERROR;
1823 return SSH_ERR_INTERNAL_ERROR; 1836 goto out;
1824 } 1837 }
1825 if ((n->xmss_pk = malloc(pklen)) == NULL) { 1838 if ((n->xmss_pk = malloc(pklen)) == NULL) {
1826 sshkey_free(n); 1839 r = SSH_ERR_ALLOC_FAIL;
1827 return SSH_ERR_ALLOC_FAIL; 1840 goto out;
1828 } 1841 }
1829 memcpy(n->xmss_pk, k->xmss_pk, pklen); 1842 memcpy(n->xmss_pk, k->xmss_pk, pklen);
1830 } 1843 }
1831 break; 1844 break;
1832#endif /* WITH_XMSS */ 1845#endif /* WITH_XMSS */
1833 default: 1846 default:
1834 return SSH_ERR_KEY_TYPE_UNKNOWN; 1847 r = SSH_ERR_KEY_TYPE_UNKNOWN;
1835 } 1848 goto out;
1836 if (sshkey_is_cert(k)) {
1837 if ((ret = sshkey_cert_copy(k, n)) != 0) {
1838 sshkey_free(n);
1839 return ret;
1840 }
1841 } 1849 }
1850 if (sshkey_is_cert(k) && (r = sshkey_cert_copy(k, n)) != 0)
1851 goto out;
1852 /* success */
1842 *pkp = n; 1853 *pkp = n;
1843 return 0; 1854 n = NULL;
1855 r = 0;
1856 out:
1857 sshkey_free(n);
1858#ifdef WITH_OPENSSL
1859 BN_clear_free(rsa_n_dup);
1860 BN_clear_free(rsa_e_dup);
1861 BN_clear_free(dsa_p_dup);
1862 BN_clear_free(dsa_q_dup);
1863 BN_clear_free(dsa_g_dup);
1864 BN_clear_free(dsa_pub_key_dup);
1865#endif
1866
1867 return r;
1844} 1868}
1845 1869
1846static int 1870static int
@@ -1954,6 +1978,8 @@ cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf)
1954 if ((ret = sshkey_verify(key->cert->signature_key, sig, slen, 1978 if ((ret = sshkey_verify(key->cert->signature_key, sig, slen,
1955 sshbuf_ptr(key->cert->certblob), signed_len, NULL, 0)) != 0) 1979 sshbuf_ptr(key->cert->certblob), signed_len, NULL, 0)) != 0)
1956 goto out; 1980 goto out;
1981 if ((ret = get_sigtype(sig, slen, &key->cert->signature_type)) != 0)
1982 goto out;
1957 1983
1958 /* Success */ 1984 /* Success */
1959 ret = 0; 1985 ret = 0;
@@ -1966,6 +1992,19 @@ cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf)
1966 return ret; 1992 return ret;
1967} 1993}
1968 1994
1995#ifdef WITH_OPENSSL
1996static int
1997check_rsa_length(const RSA *rsa)
1998{
1999 const BIGNUM *rsa_n;
2000
2001 RSA_get0_key(rsa, &rsa_n, NULL, NULL);
2002 if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
2003 return SSH_ERR_KEY_LENGTH;
2004 return 0;
2005}
2006#endif
2007
1969static int 2008static int
1970sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, 2009sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
1971 int allow_cert) 2010 int allow_cert)
@@ -1976,9 +2015,13 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
1976 size_t len; 2015 size_t len;
1977 u_char *pk = NULL; 2016 u_char *pk = NULL;
1978 struct sshbuf *copy; 2017 struct sshbuf *copy;
1979#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) 2018#if defined(WITH_OPENSSL)
2019 BIGNUM *rsa_n = NULL, *rsa_e = NULL;
2020 BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL, *dsa_pub_key = NULL;
2021# if defined(OPENSSL_HAS_ECC)
1980 EC_POINT *q = NULL; 2022 EC_POINT *q = NULL;
1981#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ 2023# endif /* OPENSSL_HAS_ECC */
2024#endif /* WITH_OPENSSL */
1982 2025
1983#ifdef DEBUG_PK /* XXX */ 2026#ifdef DEBUG_PK /* XXX */
1984 sshbuf_dump(b, stderr); 2027 sshbuf_dump(b, stderr);
@@ -2013,15 +2056,23 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
2013 ret = SSH_ERR_ALLOC_FAIL; 2056 ret = SSH_ERR_ALLOC_FAIL;
2014 goto out; 2057 goto out;
2015 } 2058 }
2016 if (sshbuf_get_bignum2(b, key->rsa->e) != 0 || 2059 if ((rsa_e = BN_new()) == NULL ||
2017 sshbuf_get_bignum2(b, key->rsa->n) != 0) { 2060 (rsa_n = BN_new()) == NULL) {
2061 ret = SSH_ERR_ALLOC_FAIL;
2062 goto out;
2063 }
2064 if (sshbuf_get_bignum2(b, rsa_e) != 0 ||
2065 sshbuf_get_bignum2(b, rsa_n) != 0) {
2018 ret = SSH_ERR_INVALID_FORMAT; 2066 ret = SSH_ERR_INVALID_FORMAT;
2019 goto out; 2067 goto out;
2020 } 2068 }
2021 if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { 2069 if (!RSA_set0_key(key->rsa, rsa_n, rsa_e, NULL)) {
2022 ret = SSH_ERR_KEY_LENGTH; 2070 ret = SSH_ERR_LIBCRYPTO_ERROR;
2023 goto out; 2071 goto out;
2024 } 2072 }
2073 rsa_n = rsa_e = NULL; /* transferred */
2074 if ((ret = check_rsa_length(key->rsa)) != 0)
2075 goto out;
2025#ifdef DEBUG_PK 2076#ifdef DEBUG_PK
2026 RSA_print_fp(stderr, key->rsa, 8); 2077 RSA_print_fp(stderr, key->rsa, 8);
2027#endif 2078#endif
@@ -2038,13 +2089,30 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
2038 ret = SSH_ERR_ALLOC_FAIL; 2089 ret = SSH_ERR_ALLOC_FAIL;
2039 goto out; 2090 goto out;
2040 } 2091 }
2041 if (sshbuf_get_bignum2(b, key->dsa->p) != 0 || 2092 if ((dsa_p = BN_new()) == NULL ||
2042 sshbuf_get_bignum2(b, key->dsa->q) != 0 || 2093 (dsa_q = BN_new()) == NULL ||
2043 sshbuf_get_bignum2(b, key->dsa->g) != 0 || 2094 (dsa_g = BN_new()) == NULL ||
2044 sshbuf_get_bignum2(b, key->dsa->pub_key) != 0) { 2095 (dsa_pub_key = BN_new()) == NULL) {
2096 ret = SSH_ERR_ALLOC_FAIL;
2097 goto out;
2098 }
2099 if (sshbuf_get_bignum2(b, dsa_p) != 0 ||
2100 sshbuf_get_bignum2(b, dsa_q) != 0 ||
2101 sshbuf_get_bignum2(b, dsa_g) != 0 ||
2102 sshbuf_get_bignum2(b, dsa_pub_key) != 0) {
2045 ret = SSH_ERR_INVALID_FORMAT; 2103 ret = SSH_ERR_INVALID_FORMAT;
2046 goto out; 2104 goto out;
2047 } 2105 }
2106 if (!DSA_set0_pqg(key->dsa, dsa_p, dsa_q, dsa_g)) {
2107 ret = SSH_ERR_LIBCRYPTO_ERROR;
2108 goto out;
2109 }
2110 dsa_p = dsa_q = dsa_g = NULL; /* transferred */
2111 if (!DSA_set0_key(key->dsa, dsa_pub_key, NULL)) {
2112 ret = SSH_ERR_LIBCRYPTO_ERROR;
2113 goto out;
2114 }
2115 dsa_pub_key = NULL; /* transferred */
2048#ifdef DEBUG_PK 2116#ifdef DEBUG_PK
2049 DSA_print_fp(stderr, key->dsa, 8); 2117 DSA_print_fp(stderr, key->dsa, 8);
2050#endif 2118#endif
@@ -2178,9 +2246,17 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
2178 free(ktype); 2246 free(ktype);
2179 free(curve); 2247 free(curve);
2180 free(pk); 2248 free(pk);
2181#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) 2249#if defined(WITH_OPENSSL)
2250 BN_clear_free(rsa_n);
2251 BN_clear_free(rsa_e);
2252 BN_clear_free(dsa_p);
2253 BN_clear_free(dsa_q);
2254 BN_clear_free(dsa_g);
2255 BN_clear_free(dsa_pub_key);
2256# if defined(OPENSSL_HAS_ECC)
2182 EC_POINT_free(q); 2257 EC_POINT_free(q);
2183#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ 2258# endif /* OPENSSL_HAS_ECC */
2259#endif /* WITH_OPENSSL */
2184 return ret; 2260 return ret;
2185} 2261}
2186 2262
@@ -2242,6 +2318,27 @@ get_sigtype(const u_char *sig, size_t siglen, char **sigtypep)
2242} 2318}
2243 2319
2244/* 2320/*
2321 *
2322 * Checks whether a certificate's signature type is allowed.
2323 * Returns 0 (success) if the certificate signature type appears in the
2324 * "allowed" pattern-list, or the key is not a certificate to begin with.
2325 * Otherwise returns a ssherr.h code.
2326 */
2327int
2328sshkey_check_cert_sigtype(const struct sshkey *key, const char *allowed)
2329{
2330 if (key == NULL || allowed == NULL)
2331 return SSH_ERR_INVALID_ARGUMENT;
2332 if (!sshkey_type_is_cert(key->type))
2333 return 0;
2334 if (key->cert == NULL || key->cert->signature_type == NULL)
2335 return SSH_ERR_INVALID_ARGUMENT;
2336 if (match_pattern_list(key->cert->signature_type, allowed, 0) != 1)
2337 return SSH_ERR_SIGN_ALG_UNSUPPORTED;
2338 return 0;
2339}
2340
2341/*
2245 * Returns the expected signature algorithm for a given public key algorithm. 2342 * Returns the expected signature algorithm for a given public key algorithm.
2246 */ 2343 */
2247const char * 2344const char *
@@ -2361,120 +2458,6 @@ sshkey_verify(const struct sshkey *key,
2361 } 2458 }
2362} 2459}
2363 2460
2364/* Converts a private to a public key */
2365int
2366sshkey_demote(const struct sshkey *k, struct sshkey **dkp)
2367{
2368 struct sshkey *pk;
2369 int ret = SSH_ERR_INTERNAL_ERROR;
2370
2371 *dkp = NULL;
2372 if ((pk = calloc(1, sizeof(*pk))) == NULL)
2373 return SSH_ERR_ALLOC_FAIL;
2374 pk->type = k->type;
2375 pk->flags = k->flags;
2376 pk->ecdsa_nid = k->ecdsa_nid;
2377 pk->dsa = NULL;
2378 pk->ecdsa = NULL;
2379 pk->rsa = NULL;
2380 pk->ed25519_pk = NULL;
2381 pk->ed25519_sk = NULL;
2382 pk->xmss_pk = NULL;
2383 pk->xmss_sk = NULL;
2384
2385 switch (k->type) {
2386#ifdef WITH_OPENSSL
2387 case KEY_RSA_CERT:
2388 if ((ret = sshkey_cert_copy(k, pk)) != 0)
2389 goto fail;
2390 /* FALLTHROUGH */
2391 case KEY_RSA:
2392 if ((pk->rsa = RSA_new()) == NULL ||
2393 (pk->rsa->e = BN_dup(k->rsa->e)) == NULL ||
2394 (pk->rsa->n = BN_dup(k->rsa->n)) == NULL) {
2395 ret = SSH_ERR_ALLOC_FAIL;
2396 goto fail;
2397 }
2398 break;
2399 case KEY_DSA_CERT:
2400 if ((ret = sshkey_cert_copy(k, pk)) != 0)
2401 goto fail;
2402 /* FALLTHROUGH */
2403 case KEY_DSA:
2404 if ((pk->dsa = DSA_new()) == NULL ||
2405 (pk->dsa->p = BN_dup(k->dsa->p)) == NULL ||
2406 (pk->dsa->q = BN_dup(k->dsa->q)) == NULL ||
2407 (pk->dsa->g = BN_dup(k->dsa->g)) == NULL ||
2408 (pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL) {
2409 ret = SSH_ERR_ALLOC_FAIL;
2410 goto fail;
2411 }
2412 break;
2413 case KEY_ECDSA_CERT:
2414 if ((ret = sshkey_cert_copy(k, pk)) != 0)
2415 goto fail;
2416 /* FALLTHROUGH */
2417# ifdef OPENSSL_HAS_ECC
2418 case KEY_ECDSA:
2419 pk->ecdsa = EC_KEY_new_by_curve_name(pk->ecdsa_nid);
2420 if (pk->ecdsa == NULL) {
2421 ret = SSH_ERR_ALLOC_FAIL;
2422 goto fail;
2423 }
2424 if (EC_KEY_set_public_key(pk->ecdsa,
2425 EC_KEY_get0_public_key(k->ecdsa)) != 1) {
2426 ret = SSH_ERR_LIBCRYPTO_ERROR;
2427 goto fail;
2428 }
2429 break;
2430# endif /* OPENSSL_HAS_ECC */
2431#endif /* WITH_OPENSSL */
2432 case KEY_ED25519_CERT:
2433 if ((ret = sshkey_cert_copy(k, pk)) != 0)
2434 goto fail;
2435 /* FALLTHROUGH */
2436 case KEY_ED25519:
2437 if (k->ed25519_pk != NULL) {
2438 if ((pk->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) {
2439 ret = SSH_ERR_ALLOC_FAIL;
2440 goto fail;
2441 }
2442 memcpy(pk->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ);
2443 }
2444 break;
2445#ifdef WITH_XMSS
2446 case KEY_XMSS_CERT:
2447 if ((ret = sshkey_cert_copy(k, pk)) != 0)
2448 goto fail;
2449 /* FALLTHROUGH */
2450 case KEY_XMSS:
2451 if ((ret = sshkey_xmss_init(pk, k->xmss_name)) != 0)
2452 goto fail;
2453 if (k->xmss_pk != NULL) {
2454 size_t pklen = sshkey_xmss_pklen(k);
2455
2456 if (pklen == 0 || sshkey_xmss_pklen(pk) != pklen) {
2457 ret = SSH_ERR_INTERNAL_ERROR;
2458 goto fail;
2459 }
2460 if ((pk->xmss_pk = malloc(pklen)) == NULL) {
2461 ret = SSH_ERR_ALLOC_FAIL;
2462 goto fail;
2463 }
2464 memcpy(pk->xmss_pk, k->xmss_pk, pklen);
2465 }
2466 break;
2467#endif /* WITH_XMSS */
2468 default:
2469 ret = SSH_ERR_KEY_TYPE_UNKNOWN;
2470 fail:
2471 sshkey_free(pk);
2472 return ret;
2473 }
2474 *dkp = pk;
2475 return 0;
2476}
2477
2478/* Convert a plain key to their _CERT equivalent */ 2461/* Convert a plain key to their _CERT equivalent */
2479int 2462int
2480sshkey_to_certified(struct sshkey *k) 2463sshkey_to_certified(struct sshkey *k)
@@ -2531,7 +2514,11 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg,
2531 u_char *ca_blob = NULL, *sig_blob = NULL, nonce[32]; 2514 u_char *ca_blob = NULL, *sig_blob = NULL, nonce[32];
2532 size_t i, ca_len, sig_len; 2515 size_t i, ca_len, sig_len;
2533 int ret = SSH_ERR_INTERNAL_ERROR; 2516 int ret = SSH_ERR_INTERNAL_ERROR;
2534 struct sshbuf *cert; 2517 struct sshbuf *cert = NULL;
2518 char *sigtype = NULL;
2519#ifdef WITH_OPENSSL
2520 const BIGNUM *rsa_n, *rsa_e, *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key;
2521#endif /* WITH_OPENSSL */
2535 2522
2536 if (k == NULL || k->cert == NULL || 2523 if (k == NULL || k->cert == NULL ||
2537 k->cert->certblob == NULL || ca == NULL) 2524 k->cert->certblob == NULL || ca == NULL)
@@ -2541,6 +2528,16 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg,
2541 if (!sshkey_type_is_valid_ca(ca->type)) 2528 if (!sshkey_type_is_valid_ca(ca->type))
2542 return SSH_ERR_KEY_CERT_INVALID_SIGN_KEY; 2529 return SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
2543 2530
2531 /*
2532 * If no alg specified as argument but a signature_type was set,
2533 * then prefer that. If both were specified, then they must match.
2534 */
2535 if (alg == NULL)
2536 alg = k->cert->signature_type;
2537 else if (k->cert->signature_type != NULL &&
2538 strcmp(alg, k->cert->signature_type) != 0)
2539 return SSH_ERR_INVALID_ARGUMENT;
2540
2544 if ((ret = sshkey_to_blob(ca, &ca_blob, &ca_len)) != 0) 2541 if ((ret = sshkey_to_blob(ca, &ca_blob, &ca_len)) != 0)
2545 return SSH_ERR_KEY_CERT_INVALID_SIGN_KEY; 2542 return SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
2546 2543
@@ -2558,10 +2555,12 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg,
2558 switch (k->type) { 2555 switch (k->type) {
2559#ifdef WITH_OPENSSL 2556#ifdef WITH_OPENSSL
2560 case KEY_DSA_CERT: 2557 case KEY_DSA_CERT:
2561 if ((ret = sshbuf_put_bignum2(cert, k->dsa->p)) != 0 || 2558 DSA_get0_pqg(k->dsa, &dsa_p, &dsa_q, &dsa_g);
2562 (ret = sshbuf_put_bignum2(cert, k->dsa->q)) != 0 || 2559 DSA_get0_key(k->dsa, &dsa_pub_key, NULL);
2563 (ret = sshbuf_put_bignum2(cert, k->dsa->g)) != 0 || 2560 if ((ret = sshbuf_put_bignum2(cert, dsa_p)) != 0 ||
2564 (ret = sshbuf_put_bignum2(cert, k->dsa->pub_key)) != 0) 2561 (ret = sshbuf_put_bignum2(cert, dsa_q)) != 0 ||
2562 (ret = sshbuf_put_bignum2(cert, dsa_g)) != 0 ||
2563 (ret = sshbuf_put_bignum2(cert, dsa_pub_key)) != 0)
2565 goto out; 2564 goto out;
2566 break; 2565 break;
2567# ifdef OPENSSL_HAS_ECC 2566# ifdef OPENSSL_HAS_ECC
@@ -2575,8 +2574,9 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg,
2575 break; 2574 break;
2576# endif /* OPENSSL_HAS_ECC */ 2575# endif /* OPENSSL_HAS_ECC */
2577 case KEY_RSA_CERT: 2576 case KEY_RSA_CERT:
2578 if ((ret = sshbuf_put_bignum2(cert, k->rsa->e)) != 0 || 2577 RSA_get0_key(k->rsa, &rsa_n, &rsa_e, NULL);
2579 (ret = sshbuf_put_bignum2(cert, k->rsa->n)) != 0) 2578 if ((ret = sshbuf_put_bignum2(cert, rsa_e)) != 0 ||
2579 (ret = sshbuf_put_bignum2(cert, rsa_n)) != 0)
2580 goto out; 2580 goto out;
2581 break; 2581 break;
2582#endif /* WITH_OPENSSL */ 2582#endif /* WITH_OPENSSL */
@@ -2629,7 +2629,17 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg,
2629 if ((ret = signer(ca, &sig_blob, &sig_len, sshbuf_ptr(cert), 2629 if ((ret = signer(ca, &sig_blob, &sig_len, sshbuf_ptr(cert),
2630 sshbuf_len(cert), alg, 0, signer_ctx)) != 0) 2630 sshbuf_len(cert), alg, 0, signer_ctx)) != 0)
2631 goto out; 2631 goto out;
2632 2632 /* Check and update signature_type against what was actually used */
2633 if ((ret = get_sigtype(sig_blob, sig_len, &sigtype)) != 0)
2634 goto out;
2635 if (alg != NULL && strcmp(alg, sigtype) != 0) {
2636 ret = SSH_ERR_SIGN_ALG_UNSUPPORTED;
2637 goto out;
2638 }
2639 if (k->cert->signature_type == NULL) {
2640 k->cert->signature_type = sigtype;
2641 sigtype = NULL;
2642 }
2633 /* Append signature and we are done */ 2643 /* Append signature and we are done */
2634 if ((ret = sshbuf_put_string(cert, sig_blob, sig_len)) != 0) 2644 if ((ret = sshbuf_put_string(cert, sig_blob, sig_len)) != 0)
2635 goto out; 2645 goto out;
@@ -2639,6 +2649,7 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg,
2639 sshbuf_reset(cert); 2649 sshbuf_reset(cert);
2640 free(sig_blob); 2650 free(sig_blob);
2641 free(ca_blob); 2651 free(ca_blob);
2652 free(sigtype);
2642 sshbuf_free(principals); 2653 sshbuf_free(principals);
2643 return ret; 2654 return ret;
2644} 2655}
@@ -2758,18 +2769,25 @@ sshkey_private_serialize_opt(const struct sshkey *key, struct sshbuf *b,
2758 enum sshkey_serialize_rep opts) 2769 enum sshkey_serialize_rep opts)
2759{ 2770{
2760 int r = SSH_ERR_INTERNAL_ERROR; 2771 int r = SSH_ERR_INTERNAL_ERROR;
2772#ifdef WITH_OPENSSL
2773 const BIGNUM *rsa_n, *rsa_e, *rsa_d, *rsa_iqmp, *rsa_p, *rsa_q;
2774 const BIGNUM *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key, *dsa_priv_key;
2775#endif /* WITH_OPENSSL */
2761 2776
2762 if ((r = sshbuf_put_cstring(b, sshkey_ssh_name(key))) != 0) 2777 if ((r = sshbuf_put_cstring(b, sshkey_ssh_name(key))) != 0)
2763 goto out; 2778 goto out;
2764 switch (key->type) { 2779 switch (key->type) {
2765#ifdef WITH_OPENSSL 2780#ifdef WITH_OPENSSL
2766 case KEY_RSA: 2781 case KEY_RSA:
2767 if ((r = sshbuf_put_bignum2(b, key->rsa->n)) != 0 || 2782 RSA_get0_key(key->rsa, &rsa_n, &rsa_e, &rsa_d);
2768 (r = sshbuf_put_bignum2(b, key->rsa->e)) != 0 || 2783 RSA_get0_factors(key->rsa, &rsa_p, &rsa_q);
2769 (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 || 2784 RSA_get0_crt_params(key->rsa, NULL, NULL, &rsa_iqmp);
2770 (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 || 2785 if ((r = sshbuf_put_bignum2(b, rsa_n)) != 0 ||
2771 (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 || 2786 (r = sshbuf_put_bignum2(b, rsa_e)) != 0 ||
2772 (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0) 2787 (r = sshbuf_put_bignum2(b, rsa_d)) != 0 ||
2788 (r = sshbuf_put_bignum2(b, rsa_iqmp)) != 0 ||
2789 (r = sshbuf_put_bignum2(b, rsa_p)) != 0 ||
2790 (r = sshbuf_put_bignum2(b, rsa_q)) != 0)
2773 goto out; 2791 goto out;
2774 break; 2792 break;
2775 case KEY_RSA_CERT: 2793 case KEY_RSA_CERT:
@@ -2777,19 +2795,24 @@ sshkey_private_serialize_opt(const struct sshkey *key, struct sshbuf *b,
2777 r = SSH_ERR_INVALID_ARGUMENT; 2795 r = SSH_ERR_INVALID_ARGUMENT;
2778 goto out; 2796 goto out;
2779 } 2797 }
2798 RSA_get0_key(key->rsa, NULL, NULL, &rsa_d);
2799 RSA_get0_factors(key->rsa, &rsa_p, &rsa_q);
2800 RSA_get0_crt_params(key->rsa, NULL, NULL, &rsa_iqmp);
2780 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || 2801 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
2781 (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 || 2802 (r = sshbuf_put_bignum2(b, rsa_d)) != 0 ||
2782 (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 || 2803 (r = sshbuf_put_bignum2(b, rsa_iqmp)) != 0 ||
2783 (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 || 2804 (r = sshbuf_put_bignum2(b, rsa_p)) != 0 ||
2784 (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0) 2805 (r = sshbuf_put_bignum2(b, rsa_q)) != 0)
2785 goto out; 2806 goto out;
2786 break; 2807 break;
2787 case KEY_DSA: 2808 case KEY_DSA:
2788 if ((r = sshbuf_put_bignum2(b, key->dsa->p)) != 0 || 2809 DSA_get0_pqg(key->dsa, &dsa_p, &dsa_q, &dsa_g);
2789 (r = sshbuf_put_bignum2(b, key->dsa->q)) != 0 || 2810 DSA_get0_key(key->dsa, &dsa_pub_key, &dsa_priv_key);
2790 (r = sshbuf_put_bignum2(b, key->dsa->g)) != 0 || 2811 if ((r = sshbuf_put_bignum2(b, dsa_p)) != 0 ||
2791 (r = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0 || 2812 (r = sshbuf_put_bignum2(b, dsa_q)) != 0 ||
2792 (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0) 2813 (r = sshbuf_put_bignum2(b, dsa_g)) != 0 ||
2814 (r = sshbuf_put_bignum2(b, dsa_pub_key)) != 0 ||
2815 (r = sshbuf_put_bignum2(b, dsa_priv_key)) != 0)
2793 goto out; 2816 goto out;
2794 break; 2817 break;
2795 case KEY_DSA_CERT: 2818 case KEY_DSA_CERT:
@@ -2797,8 +2820,9 @@ sshkey_private_serialize_opt(const struct sshkey *key, struct sshbuf *b,
2797 r = SSH_ERR_INVALID_ARGUMENT; 2820 r = SSH_ERR_INVALID_ARGUMENT;
2798 goto out; 2821 goto out;
2799 } 2822 }
2823 DSA_get0_key(key->dsa, NULL, &dsa_priv_key);
2800 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || 2824 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
2801 (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0) 2825 (r = sshbuf_put_bignum2(b, dsa_priv_key)) != 0)
2802 goto out; 2826 goto out;
2803 break; 2827 break;
2804# ifdef OPENSSL_HAS_ECC 2828# ifdef OPENSSL_HAS_ECC
@@ -2899,6 +2923,10 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
2899 u_char *xmss_pk = NULL, *xmss_sk = NULL; 2923 u_char *xmss_pk = NULL, *xmss_sk = NULL;
2900#ifdef WITH_OPENSSL 2924#ifdef WITH_OPENSSL
2901 BIGNUM *exponent = NULL; 2925 BIGNUM *exponent = NULL;
2926 BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL;
2927 BIGNUM *rsa_iqmp = NULL, *rsa_p = NULL, *rsa_q = NULL;
2928 BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL;
2929 BIGNUM *dsa_pub_key = NULL, *dsa_priv_key = NULL;
2902#endif /* WITH_OPENSSL */ 2930#endif /* WITH_OPENSSL */
2903 2931
2904 if (kp != NULL) 2932 if (kp != NULL)
@@ -2909,26 +2937,52 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
2909 switch (type) { 2937 switch (type) {
2910#ifdef WITH_OPENSSL 2938#ifdef WITH_OPENSSL
2911 case KEY_DSA: 2939 case KEY_DSA:
2912 if ((k = sshkey_new_private(type)) == NULL) { 2940 if ((k = sshkey_new(type)) == NULL) {
2913 r = SSH_ERR_ALLOC_FAIL; 2941 r = SSH_ERR_ALLOC_FAIL;
2914 goto out; 2942 goto out;
2915 } 2943 }
2916 if ((r = sshbuf_get_bignum2(buf, k->dsa->p)) != 0 || 2944 if ((dsa_p = BN_new()) == NULL ||
2917 (r = sshbuf_get_bignum2(buf, k->dsa->q)) != 0 || 2945 (dsa_q = BN_new()) == NULL ||
2918 (r = sshbuf_get_bignum2(buf, k->dsa->g)) != 0 || 2946 (dsa_g = BN_new()) == NULL ||
2919 (r = sshbuf_get_bignum2(buf, k->dsa->pub_key)) != 0 || 2947 (dsa_pub_key = BN_new()) == NULL ||
2920 (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0) 2948 (dsa_priv_key = BN_new()) == NULL) {
2949 r = SSH_ERR_ALLOC_FAIL;
2921 goto out; 2950 goto out;
2951 }
2952 if ((r = sshbuf_get_bignum2(buf, dsa_p)) != 0 ||
2953 (r = sshbuf_get_bignum2(buf, dsa_q)) != 0 ||
2954 (r = sshbuf_get_bignum2(buf, dsa_g)) != 0 ||
2955 (r = sshbuf_get_bignum2(buf, dsa_pub_key)) != 0 ||
2956 (r = sshbuf_get_bignum2(buf, dsa_priv_key)) != 0)
2957 goto out;
2958 if (!DSA_set0_pqg(k->dsa, dsa_p, dsa_q, dsa_g)) {
2959 r = SSH_ERR_LIBCRYPTO_ERROR;
2960 goto out;
2961 }
2962 dsa_p = dsa_q = dsa_g = NULL; /* transferred */
2963 if (!DSA_set0_key(k->dsa, dsa_pub_key, dsa_priv_key)) {
2964 r = SSH_ERR_LIBCRYPTO_ERROR;
2965 goto out;
2966 }
2967 dsa_pub_key = dsa_priv_key = NULL; /* transferred */
2922 break; 2968 break;
2923 case KEY_DSA_CERT: 2969 case KEY_DSA_CERT:
2970 if ((dsa_priv_key = BN_new()) == NULL) {
2971 r = SSH_ERR_ALLOC_FAIL;
2972 goto out;
2973 }
2924 if ((r = sshkey_froms(buf, &k)) != 0 || 2974 if ((r = sshkey_froms(buf, &k)) != 0 ||
2925 (r = sshkey_add_private(k)) != 0 || 2975 (r = sshbuf_get_bignum2(buf, dsa_priv_key)) != 0)
2926 (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0) 2976 goto out;
2977 if (!DSA_set0_key(k->dsa, NULL, dsa_priv_key)) {
2978 r = SSH_ERR_LIBCRYPTO_ERROR;
2927 goto out; 2979 goto out;
2980 }
2981 dsa_priv_key = NULL; /* transferred */
2928 break; 2982 break;
2929# ifdef OPENSSL_HAS_ECC 2983# ifdef OPENSSL_HAS_ECC
2930 case KEY_ECDSA: 2984 case KEY_ECDSA:
2931 if ((k = sshkey_new_private(type)) == NULL) { 2985 if ((k = sshkey_new(type)) == NULL) {
2932 r = SSH_ERR_ALLOC_FAIL; 2986 r = SSH_ERR_ALLOC_FAIL;
2933 goto out; 2987 goto out;
2934 } 2988 }
@@ -2965,7 +3019,6 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
2965 goto out; 3019 goto out;
2966 } 3020 }
2967 if ((r = sshkey_froms(buf, &k)) != 0 || 3021 if ((r = sshkey_froms(buf, &k)) != 0 ||
2968 (r = sshkey_add_private(k)) != 0 ||
2969 (r = sshbuf_get_bignum2(buf, exponent)) != 0) 3022 (r = sshbuf_get_bignum2(buf, exponent)) != 0)
2970 goto out; 3023 goto out;
2971 if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) { 3024 if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) {
@@ -2979,40 +3032,73 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
2979 break; 3032 break;
2980# endif /* OPENSSL_HAS_ECC */ 3033# endif /* OPENSSL_HAS_ECC */
2981 case KEY_RSA: 3034 case KEY_RSA:
2982 if ((k = sshkey_new_private(type)) == NULL) { 3035 if ((k = sshkey_new(type)) == NULL) {
2983 r = SSH_ERR_ALLOC_FAIL; 3036 r = SSH_ERR_ALLOC_FAIL;
2984 goto out; 3037 goto out;
2985 } 3038 }
2986 if ((r = sshbuf_get_bignum2(buf, k->rsa->n)) != 0 || 3039 if ((rsa_n = BN_new()) == NULL ||
2987 (r = sshbuf_get_bignum2(buf, k->rsa->e)) != 0 || 3040 (rsa_e = BN_new()) == NULL ||
2988 (r = sshbuf_get_bignum2(buf, k->rsa->d)) != 0 || 3041 (rsa_d = BN_new()) == NULL ||
2989 (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 || 3042 (rsa_iqmp = BN_new()) == NULL ||
2990 (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 || 3043 (rsa_p = BN_new()) == NULL ||
2991 (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 || 3044 (rsa_q = BN_new()) == NULL) {
2992 (r = ssh_rsa_generate_additional_parameters(k)) != 0) 3045 r = SSH_ERR_ALLOC_FAIL;
2993 goto out; 3046 goto out;
2994 if (BN_num_bits(k->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { 3047 }
2995 r = SSH_ERR_KEY_LENGTH; 3048 if ((r = sshbuf_get_bignum2(buf, rsa_n)) != 0 ||
3049 (r = sshbuf_get_bignum2(buf, rsa_e)) != 0 ||
3050 (r = sshbuf_get_bignum2(buf, rsa_d)) != 0 ||
3051 (r = sshbuf_get_bignum2(buf, rsa_iqmp)) != 0 ||
3052 (r = sshbuf_get_bignum2(buf, rsa_p)) != 0 ||
3053 (r = sshbuf_get_bignum2(buf, rsa_q)) != 0)
3054 goto out;
3055 if (!RSA_set0_key(k->rsa, rsa_n, rsa_e, rsa_d)) {
3056 r = SSH_ERR_LIBCRYPTO_ERROR;
2996 goto out; 3057 goto out;
2997 } 3058 }
3059 rsa_n = rsa_e = rsa_d = NULL; /* transferred */
3060 if (!RSA_set0_factors(k->rsa, rsa_p, rsa_q)) {
3061 r = SSH_ERR_LIBCRYPTO_ERROR;
3062 goto out;
3063 }
3064 rsa_p = rsa_q = NULL; /* transferred */
3065 if ((r = check_rsa_length(k->rsa)) != 0)
3066 goto out;
3067 if ((r = ssh_rsa_complete_crt_parameters(k, rsa_iqmp)) != 0)
3068 goto out;
2998 break; 3069 break;
2999 case KEY_RSA_CERT: 3070 case KEY_RSA_CERT:
3071 if ((rsa_d = BN_new()) == NULL ||
3072 (rsa_iqmp = BN_new()) == NULL ||
3073 (rsa_p = BN_new()) == NULL ||
3074 (rsa_q = BN_new()) == NULL) {
3075 r = SSH_ERR_ALLOC_FAIL;
3076 goto out;
3077 }
3000 if ((r = sshkey_froms(buf, &k)) != 0 || 3078 if ((r = sshkey_froms(buf, &k)) != 0 ||
3001 (r = sshkey_add_private(k)) != 0 || 3079 (r = sshbuf_get_bignum2(buf, rsa_d)) != 0 ||
3002 (r = sshbuf_get_bignum2(buf, k->rsa->d)) != 0 || 3080 (r = sshbuf_get_bignum2(buf, rsa_iqmp)) != 0 ||
3003 (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 || 3081 (r = sshbuf_get_bignum2(buf, rsa_p)) != 0 ||
3004 (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 || 3082 (r = sshbuf_get_bignum2(buf, rsa_q)) != 0)
3005 (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 ||
3006 (r = ssh_rsa_generate_additional_parameters(k)) != 0)
3007 goto out; 3083 goto out;
3008 if (BN_num_bits(k->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { 3084 if (!RSA_set0_key(k->rsa, NULL, NULL, rsa_d)) {
3009 r = SSH_ERR_KEY_LENGTH; 3085 r = SSH_ERR_LIBCRYPTO_ERROR;
3086 goto out;
3087 }
3088 rsa_d = NULL; /* transferred */
3089 if (!RSA_set0_factors(k->rsa, rsa_p, rsa_q)) {
3090 r = SSH_ERR_LIBCRYPTO_ERROR;
3010 goto out; 3091 goto out;
3011 } 3092 }
3093 rsa_p = rsa_q = NULL; /* transferred */
3094 if ((r = check_rsa_length(k->rsa)) != 0)
3095 goto out;
3096 if ((r = ssh_rsa_complete_crt_parameters(k, rsa_iqmp)) != 0)
3097 goto out;
3012 break; 3098 break;
3013#endif /* WITH_OPENSSL */ 3099#endif /* WITH_OPENSSL */
3014 case KEY_ED25519: 3100 case KEY_ED25519:
3015 if ((k = sshkey_new_private(type)) == NULL) { 3101 if ((k = sshkey_new(type)) == NULL) {
3016 r = SSH_ERR_ALLOC_FAIL; 3102 r = SSH_ERR_ALLOC_FAIL;
3017 goto out; 3103 goto out;
3018 } 3104 }
@@ -3029,7 +3115,6 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
3029 break; 3115 break;
3030 case KEY_ED25519_CERT: 3116 case KEY_ED25519_CERT:
3031 if ((r = sshkey_froms(buf, &k)) != 0 || 3117 if ((r = sshkey_froms(buf, &k)) != 0 ||
3032 (r = sshkey_add_private(k)) != 0 ||
3033 (r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 || 3118 (r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 ||
3034 (r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0) 3119 (r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0)
3035 goto out; 3120 goto out;
@@ -3043,7 +3128,7 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
3043 break; 3128 break;
3044#ifdef WITH_XMSS 3129#ifdef WITH_XMSS
3045 case KEY_XMSS: 3130 case KEY_XMSS:
3046 if ((k = sshkey_new_private(type)) == NULL) { 3131 if ((k = sshkey_new(type)) == NULL) {
3047 r = SSH_ERR_ALLOC_FAIL; 3132 r = SSH_ERR_ALLOC_FAIL;
3048 goto out; 3133 goto out;
3049 } 3134 }
@@ -3066,7 +3151,6 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
3066 break; 3151 break;
3067 case KEY_XMSS_CERT: 3152 case KEY_XMSS_CERT:
3068 if ((r = sshkey_froms(buf, &k)) != 0 || 3153 if ((r = sshkey_froms(buf, &k)) != 0 ||
3069 (r = sshkey_add_private(k)) != 0 ||
3070 (r = sshbuf_get_cstring(buf, &xmss_name, NULL)) != 0 || 3154 (r = sshbuf_get_cstring(buf, &xmss_name, NULL)) != 0 ||
3071 (r = sshbuf_get_string(buf, &xmss_pk, &pklen)) != 0 || 3155 (r = sshbuf_get_string(buf, &xmss_pk, &pklen)) != 0 ||
3072 (r = sshbuf_get_string(buf, &xmss_sk, &sklen)) != 0) 3156 (r = sshbuf_get_string(buf, &xmss_sk, &sklen)) != 0)
@@ -3115,6 +3199,17 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
3115 free(curve); 3199 free(curve);
3116#ifdef WITH_OPENSSL 3200#ifdef WITH_OPENSSL
3117 BN_clear_free(exponent); 3201 BN_clear_free(exponent);
3202 BN_clear_free(dsa_p);
3203 BN_clear_free(dsa_q);
3204 BN_clear_free(dsa_g);
3205 BN_clear_free(dsa_pub_key);
3206 BN_clear_free(dsa_priv_key);
3207 BN_clear_free(rsa_n);
3208 BN_clear_free(rsa_e);
3209 BN_clear_free(rsa_d);
3210 BN_clear_free(rsa_p);
3211 BN_clear_free(rsa_q);
3212 BN_clear_free(rsa_iqmp);
3118#endif /* WITH_OPENSSL */ 3213#endif /* WITH_OPENSSL */
3119 sshkey_free(k); 3214 sshkey_free(k);
3120 freezero(ed25519_pk, pklen); 3215 freezero(ed25519_pk, pklen);
@@ -3769,7 +3864,9 @@ translate_libcrypto_error(unsigned long pem_err)
3769 switch (pem_reason) { 3864 switch (pem_reason) {
3770 case EVP_R_BAD_DECRYPT: 3865 case EVP_R_BAD_DECRYPT:
3771 return SSH_ERR_KEY_WRONG_PASSPHRASE; 3866 return SSH_ERR_KEY_WRONG_PASSPHRASE;
3867#ifdef EVP_R_BN_DECODE_ERROR
3772 case EVP_R_BN_DECODE_ERROR: 3868 case EVP_R_BN_DECODE_ERROR:
3869#endif
3773 case EVP_R_DECODE_ERROR: 3870 case EVP_R_DECODE_ERROR:
3774#ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR 3871#ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR
3775 case EVP_R_PRIVATE_KEY_DECODE_ERROR: 3872 case EVP_R_PRIVATE_KEY_DECODE_ERROR:
@@ -3809,6 +3906,20 @@ convert_libcrypto_error(void)
3809} 3906}
3810 3907
3811static int 3908static int
3909pem_passphrase_cb(char *buf, int size, int rwflag, void *u)
3910{
3911 char *p = (char *)u;
3912 size_t len;
3913
3914 if (p == NULL || (len = strlen(p)) == 0)
3915 return -1;
3916 if (size < 0 || len > (size_t)size)
3917 return -1;
3918 memcpy(buf, p, len);
3919 return (int)len;
3920}
3921
3922static int
3812sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, 3923sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
3813 const char *passphrase, struct sshkey **keyp) 3924 const char *passphrase, struct sshkey **keyp)
3814{ 3925{
@@ -3829,12 +3940,21 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
3829 } 3940 }
3830 3941
3831 clear_libcrypto_errors(); 3942 clear_libcrypto_errors();
3832 if ((pk = PEM_read_bio_PrivateKey(bio, NULL, NULL, 3943 if ((pk = PEM_read_bio_PrivateKey(bio, NULL, pem_passphrase_cb,
3833 (char *)passphrase)) == NULL) { 3944 (char *)passphrase)) == NULL) {
3834 r = convert_libcrypto_error(); 3945 /*
3946 * libcrypto may return various ASN.1 errors when attempting
3947 * to parse a key with an incorrect passphrase.
3948 * Treat all format errors as "incorrect passphrase" if a
3949 * passphrase was supplied.
3950 */
3951 if (passphrase != NULL && *passphrase != '\0')
3952 r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3953 else
3954 r = convert_libcrypto_error();
3835 goto out; 3955 goto out;
3836 } 3956 }
3837 if (pk->type == EVP_PKEY_RSA && 3957 if (EVP_PKEY_base_id(pk) == EVP_PKEY_RSA &&
3838 (type == KEY_UNSPEC || type == KEY_RSA)) { 3958 (type == KEY_UNSPEC || type == KEY_RSA)) {
3839 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { 3959 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
3840 r = SSH_ERR_ALLOC_FAIL; 3960 r = SSH_ERR_ALLOC_FAIL;
@@ -3849,11 +3969,9 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
3849 r = SSH_ERR_LIBCRYPTO_ERROR; 3969 r = SSH_ERR_LIBCRYPTO_ERROR;
3850 goto out; 3970 goto out;
3851 } 3971 }
3852 if (BN_num_bits(prv->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { 3972 if ((r = check_rsa_length(prv->rsa)) != 0)
3853 r = SSH_ERR_KEY_LENGTH;
3854 goto out; 3973 goto out;
3855 } 3974 } else if (EVP_PKEY_base_id(pk) == EVP_PKEY_DSA &&
3856 } else if (pk->type == EVP_PKEY_DSA &&
3857 (type == KEY_UNSPEC || type == KEY_DSA)) { 3975 (type == KEY_UNSPEC || type == KEY_DSA)) {
3858 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { 3976 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
3859 r = SSH_ERR_ALLOC_FAIL; 3977 r = SSH_ERR_ALLOC_FAIL;
@@ -3865,7 +3983,7 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
3865 DSA_print_fp(stderr, prv->dsa, 8); 3983 DSA_print_fp(stderr, prv->dsa, 8);
3866#endif 3984#endif
3867#ifdef OPENSSL_HAS_ECC 3985#ifdef OPENSSL_HAS_ECC
3868 } else if (pk->type == EVP_PKEY_EC && 3986 } else if (EVP_PKEY_base_id(pk) == EVP_PKEY_EC &&
3869 (type == KEY_UNSPEC || type == KEY_ECDSA)) { 3987 (type == KEY_UNSPEC || type == KEY_ECDSA)) {
3870 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { 3988 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
3871 r = SSH_ERR_ALLOC_FAIL; 3989 r = SSH_ERR_ALLOC_FAIL;