summaryrefslogtreecommitdiff
path: root/sshkey.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2018-09-13 02:08:33 +0000
committerDamien Miller <djm@mindrot.org>2018-09-13 12:12:33 +1000
commit482d23bcacdd3664f21cc82a5135f66fc598275f (patch)
tree362f697a94da0a765d1dabcfbf33370b2a4df121 /sshkey.c
parentd70d061828730a56636ab6f1f24fe4a8ccefcfc1 (diff)
upstream: hold our collective noses and use the openssl-1.1.x API in
OpenSSH; feedback and ok tb@ jsing@ markus@ OpenBSD-Commit-ID: cacbcac87ce5da0d3ca7ef1b38a6f7fb349e4417
Diffstat (limited to 'sshkey.c')
-rw-r--r--sshkey.c637
1 files changed, 342 insertions, 295 deletions
diff --git a/sshkey.c b/sshkey.c
index 50ebdc256..085f17079 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -289,14 +289,24 @@ sshkey_names_valid2(const char *names, int allow_wildcard)
289u_int 289u_int
290sshkey_size(const struct sshkey *k) 290sshkey_size(const struct sshkey *k)
291{ 291{
292#ifdef WITH_OPENSSL
293 const BIGNUM *rsa_n, *dsa_p;
294#endif /* WITH_OPENSSL */
295
292 switch (k->type) { 296 switch (k->type) {
293#ifdef WITH_OPENSSL 297#ifdef WITH_OPENSSL
294 case KEY_RSA: 298 case KEY_RSA:
295 case KEY_RSA_CERT: 299 case KEY_RSA_CERT:
296 return BN_num_bits(k->rsa->n); 300 if (k->rsa == NULL)
301 return 0;
302 RSA_get0_key(k->rsa, &rsa_n, NULL, NULL);
303 return BN_num_bits(rsa_n);
297 case KEY_DSA: 304 case KEY_DSA:
298 case KEY_DSA_CERT: 305 case KEY_DSA_CERT:
299 return BN_num_bits(k->dsa->p); 306 if (k->dsa == NULL)
307 return 0;
308 DSA_get0_pqg(k->dsa, &dsa_p, NULL, NULL);
309 return BN_num_bits(dsa_p);
300 case KEY_ECDSA: 310 case KEY_ECDSA:
301 case KEY_ECDSA_CERT: 311 case KEY_ECDSA_CERT:
302 return sshkey_curve_nid_to_bits(k->ecdsa_nid); 312 return sshkey_curve_nid_to_bits(k->ecdsa_nid);
@@ -503,10 +513,7 @@ sshkey_new(int type)
503#ifdef WITH_OPENSSL 513#ifdef WITH_OPENSSL
504 case KEY_RSA: 514 case KEY_RSA:
505 case KEY_RSA_CERT: 515 case KEY_RSA_CERT:
506 if ((rsa = RSA_new()) == NULL || 516 if ((rsa = RSA_new()) == NULL) {
507 (rsa->n = BN_new()) == NULL ||
508 (rsa->e = BN_new()) == NULL) {
509 RSA_free(rsa);
510 free(k); 517 free(k);
511 return NULL; 518 return NULL;
512 } 519 }
@@ -514,12 +521,7 @@ sshkey_new(int type)
514 break; 521 break;
515 case KEY_DSA: 522 case KEY_DSA:
516 case KEY_DSA_CERT: 523 case KEY_DSA_CERT:
517 if ((dsa = DSA_new()) == NULL || 524 if ((dsa = DSA_new()) == NULL) {
518 (dsa->p = BN_new()) == NULL ||
519 (dsa->q = BN_new()) == NULL ||
520 (dsa->g = BN_new()) == NULL ||
521 (dsa->pub_key = BN_new()) == NULL) {
522 DSA_free(dsa);
523 free(k); 525 free(k);
524 return NULL; 526 return NULL;
525 } 527 }
@@ -553,47 +555,7 @@ sshkey_new(int type)
553 return k; 555 return k;
554} 556}
555 557
556int 558/* XXX garbage-collect this API */
557sshkey_add_private(struct sshkey *k)
558{
559 switch (k->type) {
560#ifdef WITH_OPENSSL
561 case KEY_RSA:
562 case KEY_RSA_CERT:
563#define bn_maybe_alloc_failed(p) (p == NULL && (p = BN_new()) == NULL)
564 if (bn_maybe_alloc_failed(k->rsa->d) ||
565 bn_maybe_alloc_failed(k->rsa->iqmp) ||
566 bn_maybe_alloc_failed(k->rsa->q) ||
567 bn_maybe_alloc_failed(k->rsa->p) ||
568 bn_maybe_alloc_failed(k->rsa->dmq1) ||
569 bn_maybe_alloc_failed(k->rsa->dmp1))
570 return SSH_ERR_ALLOC_FAIL;
571 break;
572 case KEY_DSA:
573 case KEY_DSA_CERT:
574 if (bn_maybe_alloc_failed(k->dsa->priv_key))
575 return SSH_ERR_ALLOC_FAIL;
576 break;
577#undef bn_maybe_alloc_failed
578 case KEY_ECDSA:
579 case KEY_ECDSA_CERT:
580 /* Cannot do anything until we know the group */
581 break;
582#endif /* WITH_OPENSSL */
583 case KEY_ED25519:
584 case KEY_ED25519_CERT:
585 case KEY_XMSS:
586 case KEY_XMSS_CERT:
587 /* no need to prealloc */
588 break;
589 case KEY_UNSPEC:
590 break;
591 default:
592 return SSH_ERR_INVALID_ARGUMENT;
593 }
594 return 0;
595}
596
597struct sshkey * 559struct sshkey *
598sshkey_new_private(int type) 560sshkey_new_private(int type)
599{ 561{
@@ -601,10 +563,6 @@ sshkey_new_private(int type)
601 563
602 if (k == NULL) 564 if (k == NULL)
603 return NULL; 565 return NULL;
604 if (sshkey_add_private(k) != 0) {
605 sshkey_free(k);
606 return NULL;
607 }
608 return k; 566 return k;
609} 567}
610 568
@@ -686,9 +644,15 @@ cert_compare(struct sshkey_cert *a, struct sshkey_cert *b)
686int 644int
687sshkey_equal_public(const struct sshkey *a, const struct sshkey *b) 645sshkey_equal_public(const struct sshkey *a, const struct sshkey *b)
688{ 646{
689#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) 647#if defined(WITH_OPENSSL)
648 const BIGNUM *rsa_e_a, *rsa_n_a;
649 const BIGNUM *rsa_e_b, *rsa_n_b;
650 const BIGNUM *dsa_p_a, *dsa_q_a, *dsa_g_a, *dsa_pub_key_a;
651 const BIGNUM *dsa_p_b, *dsa_q_b, *dsa_g_b, *dsa_pub_key_b;
652# if defined(OPENSSL_HAS_ECC)
690 BN_CTX *bnctx; 653 BN_CTX *bnctx;
691#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ 654# endif /* OPENSSL_HAS_ECC */
655#endif /* WITH_OPENSSL */
692 656
693 if (a == NULL || b == NULL || 657 if (a == NULL || b == NULL ||
694 sshkey_type_plain(a->type) != sshkey_type_plain(b->type)) 658 sshkey_type_plain(a->type) != sshkey_type_plain(b->type))
@@ -698,16 +662,24 @@ sshkey_equal_public(const struct sshkey *a, const struct sshkey *b)
698#ifdef WITH_OPENSSL 662#ifdef WITH_OPENSSL
699 case KEY_RSA_CERT: 663 case KEY_RSA_CERT:
700 case KEY_RSA: 664 case KEY_RSA:
701 return a->rsa != NULL && b->rsa != NULL && 665 if (a->rsa == NULL || b->rsa == NULL)
702 BN_cmp(a->rsa->e, b->rsa->e) == 0 && 666 return 0;
703 BN_cmp(a->rsa->n, b->rsa->n) == 0; 667 RSA_get0_key(a->rsa, &rsa_n_a, &rsa_e_a, NULL);
668 RSA_get0_key(b->rsa, &rsa_n_b, &rsa_e_b, NULL);
669 return BN_cmp(rsa_e_a, rsa_e_b) == 0 &&
670 BN_cmp(rsa_n_a, rsa_n_b) == 0;
704 case KEY_DSA_CERT: 671 case KEY_DSA_CERT:
705 case KEY_DSA: 672 case KEY_DSA:
706 return a->dsa != NULL && b->dsa != NULL && 673 if (a->dsa == NULL || b->dsa == NULL)
707 BN_cmp(a->dsa->p, b->dsa->p) == 0 && 674 return 0;
708 BN_cmp(a->dsa->q, b->dsa->q) == 0 && 675 DSA_get0_pqg(a->dsa, &dsa_p_a, &dsa_q_a, &dsa_g_a);
709 BN_cmp(a->dsa->g, b->dsa->g) == 0 && 676 DSA_get0_pqg(b->dsa, &dsa_p_b, &dsa_q_b, &dsa_g_b);
710 BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0; 677 DSA_get0_key(a->dsa, &dsa_pub_key_a, NULL);
678 DSA_get0_key(b->dsa, &dsa_pub_key_b, NULL);
679 return BN_cmp(dsa_p_a, dsa_p_b) == 0 &&
680 BN_cmp(dsa_q_a, dsa_q_b) == 0 &&
681 BN_cmp(dsa_g_a, dsa_g_b) == 0 &&
682 BN_cmp(dsa_pub_key_a, dsa_pub_key_b) == 0;
711# ifdef OPENSSL_HAS_ECC 683# ifdef OPENSSL_HAS_ECC
712 case KEY_ECDSA_CERT: 684 case KEY_ECDSA_CERT:
713 case KEY_ECDSA: 685 case KEY_ECDSA:
@@ -764,6 +736,9 @@ to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain,
764{ 736{
765 int type, ret = SSH_ERR_INTERNAL_ERROR; 737 int type, ret = SSH_ERR_INTERNAL_ERROR;
766 const char *typename; 738 const char *typename;
739#ifdef WITH_OPENSSL
740 const BIGNUM *rsa_n, *rsa_e, *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key;
741#endif /* WITH_OPENSSL */
767 742
768 if (key == NULL) 743 if (key == NULL)
769 return SSH_ERR_INVALID_ARGUMENT; 744 return SSH_ERR_INVALID_ARGUMENT;
@@ -796,11 +771,13 @@ to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain,
796 case KEY_DSA: 771 case KEY_DSA:
797 if (key->dsa == NULL) 772 if (key->dsa == NULL)
798 return SSH_ERR_INVALID_ARGUMENT; 773 return SSH_ERR_INVALID_ARGUMENT;
774 DSA_get0_pqg(key->dsa, &dsa_p, &dsa_q, &dsa_g);
775 DSA_get0_key(key->dsa, &dsa_pub_key, NULL);
799 if ((ret = sshbuf_put_cstring(b, typename)) != 0 || 776 if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
800 (ret = sshbuf_put_bignum2(b, key->dsa->p)) != 0 || 777 (ret = sshbuf_put_bignum2(b, dsa_p)) != 0 ||
801 (ret = sshbuf_put_bignum2(b, key->dsa->q)) != 0 || 778 (ret = sshbuf_put_bignum2(b, dsa_q)) != 0 ||
802 (ret = sshbuf_put_bignum2(b, key->dsa->g)) != 0 || 779 (ret = sshbuf_put_bignum2(b, dsa_g)) != 0 ||
803 (ret = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0) 780 (ret = sshbuf_put_bignum2(b, dsa_pub_key)) != 0)
804 return ret; 781 return ret;
805 break; 782 break;
806# ifdef OPENSSL_HAS_ECC 783# ifdef OPENSSL_HAS_ECC
@@ -817,9 +794,10 @@ to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain,
817 case KEY_RSA: 794 case KEY_RSA:
818 if (key->rsa == NULL) 795 if (key->rsa == NULL)
819 return SSH_ERR_INVALID_ARGUMENT; 796 return SSH_ERR_INVALID_ARGUMENT;
797 RSA_get0_key(key->rsa, &rsa_n, &rsa_e, NULL);
820 if ((ret = sshbuf_put_cstring(b, typename)) != 0 || 798 if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
821 (ret = sshbuf_put_bignum2(b, key->rsa->e)) != 0 || 799 (ret = sshbuf_put_bignum2(b, rsa_e)) != 0 ||
822 (ret = sshbuf_put_bignum2(b, key->rsa->n)) != 0) 800 (ret = sshbuf_put_bignum2(b, rsa_n)) != 0)
823 return ret; 801 return ret;
824 break; 802 break;
825#endif /* WITH_OPENSSL */ 803#endif /* WITH_OPENSSL */
@@ -1767,59 +1745,95 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp)
1767{ 1745{
1768 struct sshkey *n = NULL; 1746 struct sshkey *n = NULL;
1769 int ret = SSH_ERR_INTERNAL_ERROR; 1747 int ret = SSH_ERR_INTERNAL_ERROR;
1748 int r = SSH_ERR_INTERNAL_ERROR;
1749#ifdef WITH_OPENSSL
1750 const BIGNUM *rsa_n, *rsa_e;
1751 BIGNUM *rsa_n_dup = NULL, *rsa_e_dup = NULL;
1752 const BIGNUM *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key;
1753 BIGNUM *dsa_p_dup = NULL, *dsa_q_dup = NULL, *dsa_g_dup = NULL;
1754 BIGNUM *dsa_pub_key_dup = NULL;
1755#endif /* WITH_OPENSSL */
1770 1756
1771 *pkp = NULL; 1757 *pkp = NULL;
1772 switch (k->type) { 1758 switch (k->type) {
1773#ifdef WITH_OPENSSL 1759#ifdef WITH_OPENSSL
1774 case KEY_DSA: 1760 case KEY_DSA:
1775 case KEY_DSA_CERT: 1761 case KEY_DSA_CERT:
1776 if ((n = sshkey_new(k->type)) == NULL) 1762 if ((n = sshkey_new(k->type)) == NULL) {
1777 return SSH_ERR_ALLOC_FAIL; 1763 r = SSH_ERR_ALLOC_FAIL;
1778 if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) || 1764 goto out;
1779 (BN_copy(n->dsa->q, k->dsa->q) == NULL) || 1765 }
1780 (BN_copy(n->dsa->g, k->dsa->g) == NULL) || 1766
1781 (BN_copy(n->dsa->pub_key, k->dsa->pub_key) == NULL)) { 1767 DSA_get0_pqg(k->dsa, &dsa_p, &dsa_q, &dsa_g);
1782 sshkey_free(n); 1768 DSA_get0_key(k->dsa, &dsa_pub_key, NULL);
1783 return SSH_ERR_ALLOC_FAIL; 1769 if ((dsa_p_dup = BN_dup(dsa_p)) == NULL ||
1770 (dsa_q_dup = BN_dup(dsa_q)) == NULL ||
1771 (dsa_g_dup = BN_dup(dsa_g)) == NULL ||
1772 (dsa_pub_key_dup = BN_dup(dsa_pub_key)) == NULL) {
1773 r = SSH_ERR_ALLOC_FAIL;
1774 goto out;
1784 } 1775 }
1776 if (!DSA_set0_pqg(n->dsa, dsa_p_dup, dsa_q_dup, dsa_g_dup)) {
1777 r = SSH_ERR_LIBCRYPTO_ERROR;
1778 goto out;
1779 }
1780 dsa_p_dup = dsa_q_dup = dsa_g_dup = NULL; /* transferred */
1781 if (!DSA_set0_key(n->dsa, dsa_pub_key_dup, NULL)) {
1782 r = SSH_ERR_LIBCRYPTO_ERROR;
1783 goto out;
1784 }
1785 dsa_pub_key_dup = NULL; /* transferred */
1786
1785 break; 1787 break;
1786# ifdef OPENSSL_HAS_ECC 1788# ifdef OPENSSL_HAS_ECC
1787 case KEY_ECDSA: 1789 case KEY_ECDSA:
1788 case KEY_ECDSA_CERT: 1790 case KEY_ECDSA_CERT:
1789 if ((n = sshkey_new(k->type)) == NULL) 1791 if ((n = sshkey_new(k->type)) == NULL) {
1790 return SSH_ERR_ALLOC_FAIL; 1792 r = SSH_ERR_ALLOC_FAIL;
1793 goto out;
1794 }
1791 n->ecdsa_nid = k->ecdsa_nid; 1795 n->ecdsa_nid = k->ecdsa_nid;
1792 n->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid); 1796 n->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid);
1793 if (n->ecdsa == NULL) { 1797 if (n->ecdsa == NULL) {
1794 sshkey_free(n); 1798 r = SSH_ERR_ALLOC_FAIL;
1795 return SSH_ERR_ALLOC_FAIL; 1799 goto out;
1796 } 1800 }
1797 if (EC_KEY_set_public_key(n->ecdsa, 1801 if (EC_KEY_set_public_key(n->ecdsa,
1798 EC_KEY_get0_public_key(k->ecdsa)) != 1) { 1802 EC_KEY_get0_public_key(k->ecdsa)) != 1) {
1799 sshkey_free(n); 1803 r = SSH_ERR_LIBCRYPTO_ERROR;
1800 return SSH_ERR_LIBCRYPTO_ERROR; 1804 goto out;
1801 } 1805 }
1802 break; 1806 break;
1803# endif /* OPENSSL_HAS_ECC */ 1807# endif /* OPENSSL_HAS_ECC */
1804 case KEY_RSA: 1808 case KEY_RSA:
1805 case KEY_RSA_CERT: 1809 case KEY_RSA_CERT:
1806 if ((n = sshkey_new(k->type)) == NULL) 1810 if ((n = sshkey_new(k->type)) == NULL) {
1807 return SSH_ERR_ALLOC_FAIL; 1811 r = SSH_ERR_ALLOC_FAIL;
1808 if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) || 1812 goto out;
1809 (BN_copy(n->rsa->e, k->rsa->e) == NULL)) {
1810 sshkey_free(n);
1811 return SSH_ERR_ALLOC_FAIL;
1812 } 1813 }
1814 RSA_get0_key(k->rsa, &rsa_n, &rsa_e, NULL);
1815 if ((rsa_n_dup = BN_dup(rsa_n)) == NULL ||
1816 (rsa_e_dup = BN_dup(rsa_e)) == NULL) {
1817 r = SSH_ERR_ALLOC_FAIL;
1818 goto out;
1819 }
1820 if (!RSA_set0_key(n->rsa, rsa_n_dup, rsa_e_dup, NULL)) {
1821 r = SSH_ERR_LIBCRYPTO_ERROR;
1822 goto out;
1823 }
1824 rsa_n_dup = rsa_e_dup = NULL; /* transferred */
1813 break; 1825 break;
1814#endif /* WITH_OPENSSL */ 1826#endif /* WITH_OPENSSL */
1815 case KEY_ED25519: 1827 case KEY_ED25519:
1816 case KEY_ED25519_CERT: 1828 case KEY_ED25519_CERT:
1817 if ((n = sshkey_new(k->type)) == NULL) 1829 if ((n = sshkey_new(k->type)) == NULL) {
1818 return SSH_ERR_ALLOC_FAIL; 1830 r = SSH_ERR_ALLOC_FAIL;
1831 goto out;
1832 }
1819 if (k->ed25519_pk != NULL) { 1833 if (k->ed25519_pk != NULL) {
1820 if ((n->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) { 1834 if ((n->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) {
1821 sshkey_free(n); 1835 r = SSH_ERR_ALLOC_FAIL;
1822 return SSH_ERR_ALLOC_FAIL; 1836 goto out;
1823 } 1837 }
1824 memcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ); 1838 memcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ);
1825 } 1839 }
@@ -1827,37 +1841,46 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp)
1827#ifdef WITH_XMSS 1841#ifdef WITH_XMSS
1828 case KEY_XMSS: 1842 case KEY_XMSS:
1829 case KEY_XMSS_CERT: 1843 case KEY_XMSS_CERT:
1830 if ((n = sshkey_new(k->type)) == NULL) 1844 if ((n = sshkey_new(k->type)) == NULL) {
1831 return SSH_ERR_ALLOC_FAIL; 1845 r = SSH_ERR_ALLOC_FAIL;
1832 if ((ret = sshkey_xmss_init(n, k->xmss_name)) != 0) { 1846 goto out;
1833 sshkey_free(n);
1834 return ret;
1835 } 1847 }
1848 if ((r = sshkey_xmss_init(n, k->xmss_name)) != 0)
1849 goto out;
1836 if (k->xmss_pk != NULL) { 1850 if (k->xmss_pk != NULL) {
1837 size_t pklen = sshkey_xmss_pklen(k); 1851 size_t pklen = sshkey_xmss_pklen(k);
1838 if (pklen == 0 || sshkey_xmss_pklen(n) != pklen) { 1852 if (pklen == 0 || sshkey_xmss_pklen(n) != pklen) {
1839 sshkey_free(n); 1853 r = SSH_ERR_INTERNAL_ERROR;
1840 return SSH_ERR_INTERNAL_ERROR; 1854 goto out;
1841 } 1855 }
1842 if ((n->xmss_pk = malloc(pklen)) == NULL) { 1856 if ((n->xmss_pk = malloc(pklen)) == NULL) {
1843 sshkey_free(n); 1857 r = SSH_ERR_ALLOC_FAIL;
1844 return SSH_ERR_ALLOC_FAIL; 1858 goto out;
1845 } 1859 }
1846 memcpy(n->xmss_pk, k->xmss_pk, pklen); 1860 memcpy(n->xmss_pk, k->xmss_pk, pklen);
1847 } 1861 }
1848 break; 1862 break;
1849#endif /* WITH_XMSS */ 1863#endif /* WITH_XMSS */
1850 default: 1864 default:
1851 return SSH_ERR_KEY_TYPE_UNKNOWN; 1865 r = SSH_ERR_KEY_TYPE_UNKNOWN;
1852 } 1866 goto out;
1853 if (sshkey_is_cert(k)) {
1854 if ((ret = sshkey_cert_copy(k, n)) != 0) {
1855 sshkey_free(n);
1856 return ret;
1857 }
1858 } 1867 }
1868 if (sshkey_is_cert(k) && (r = sshkey_cert_copy(k, n)) != 0)
1869 goto out;
1870 /* success */
1859 *pkp = n; 1871 *pkp = n;
1860 return 0; 1872 n = NULL;
1873 r = 0;
1874 out:
1875 sshkey_free(n);
1876 BN_clear_free(rsa_n_dup);
1877 BN_clear_free(rsa_e_dup);
1878 BN_clear_free(dsa_p_dup);
1879 BN_clear_free(dsa_q_dup);
1880 BN_clear_free(dsa_g_dup);
1881 BN_clear_free(dsa_pub_key_dup);
1882
1883 return r;
1861} 1884}
1862 1885
1863static int 1886static int
@@ -1986,6 +2009,17 @@ cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf)
1986} 2009}
1987 2010
1988static int 2011static int
2012check_rsa_length(const RSA *rsa)
2013{
2014 const BIGNUM *rsa_n;
2015
2016 RSA_get0_key(rsa, &rsa_n, NULL, NULL);
2017 if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
2018 return SSH_ERR_KEY_LENGTH;
2019 return 0;
2020}
2021
2022static int
1989sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, 2023sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
1990 int allow_cert) 2024 int allow_cert)
1991{ 2025{
@@ -1995,9 +2029,13 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
1995 size_t len; 2029 size_t len;
1996 u_char *pk = NULL; 2030 u_char *pk = NULL;
1997 struct sshbuf *copy; 2031 struct sshbuf *copy;
1998#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) 2032#if defined(WITH_OPENSSL)
2033 BIGNUM *rsa_n = NULL, *rsa_e = NULL;
2034 BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL, *dsa_pub_key = NULL;
2035# if defined(OPENSSL_HAS_ECC)
1999 EC_POINT *q = NULL; 2036 EC_POINT *q = NULL;
2000#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ 2037# endif /* OPENSSL_HAS_ECC */
2038#endif /* WITH_OPENSSL */
2001 2039
2002#ifdef DEBUG_PK /* XXX */ 2040#ifdef DEBUG_PK /* XXX */
2003 sshbuf_dump(b, stderr); 2041 sshbuf_dump(b, stderr);
@@ -2032,15 +2070,23 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
2032 ret = SSH_ERR_ALLOC_FAIL; 2070 ret = SSH_ERR_ALLOC_FAIL;
2033 goto out; 2071 goto out;
2034 } 2072 }
2035 if (sshbuf_get_bignum2(b, key->rsa->e) != 0 || 2073 if ((rsa_e = BN_new()) == NULL ||
2036 sshbuf_get_bignum2(b, key->rsa->n) != 0) { 2074 (rsa_n = BN_new()) == NULL) {
2075 ret = SSH_ERR_ALLOC_FAIL;
2076 goto out;
2077 }
2078 if (sshbuf_get_bignum2(b, rsa_e) != 0 ||
2079 sshbuf_get_bignum2(b, rsa_n) != 0) {
2037 ret = SSH_ERR_INVALID_FORMAT; 2080 ret = SSH_ERR_INVALID_FORMAT;
2038 goto out; 2081 goto out;
2039 } 2082 }
2040 if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { 2083 if (!RSA_set0_key(key->rsa, rsa_n, rsa_e, NULL)) {
2041 ret = SSH_ERR_KEY_LENGTH; 2084 ret = SSH_ERR_LIBCRYPTO_ERROR;
2042 goto out; 2085 goto out;
2043 } 2086 }
2087 rsa_n = rsa_e = NULL; /* transferred */
2088 if ((ret = check_rsa_length(key->rsa)) != 0)
2089 goto out;
2044#ifdef DEBUG_PK 2090#ifdef DEBUG_PK
2045 RSA_print_fp(stderr, key->rsa, 8); 2091 RSA_print_fp(stderr, key->rsa, 8);
2046#endif 2092#endif
@@ -2057,13 +2103,30 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
2057 ret = SSH_ERR_ALLOC_FAIL; 2103 ret = SSH_ERR_ALLOC_FAIL;
2058 goto out; 2104 goto out;
2059 } 2105 }
2060 if (sshbuf_get_bignum2(b, key->dsa->p) != 0 || 2106 if ((dsa_p = BN_new()) == NULL ||
2061 sshbuf_get_bignum2(b, key->dsa->q) != 0 || 2107 (dsa_q = BN_new()) == NULL ||
2062 sshbuf_get_bignum2(b, key->dsa->g) != 0 || 2108 (dsa_g = BN_new()) == NULL ||
2063 sshbuf_get_bignum2(b, key->dsa->pub_key) != 0) { 2109 (dsa_pub_key = BN_new()) == NULL) {
2110 ret = SSH_ERR_ALLOC_FAIL;
2111 goto out;
2112 }
2113 if (sshbuf_get_bignum2(b, dsa_p) != 0 ||
2114 sshbuf_get_bignum2(b, dsa_q) != 0 ||
2115 sshbuf_get_bignum2(b, dsa_g) != 0 ||
2116 sshbuf_get_bignum2(b, dsa_pub_key) != 0) {
2064 ret = SSH_ERR_INVALID_FORMAT; 2117 ret = SSH_ERR_INVALID_FORMAT;
2065 goto out; 2118 goto out;
2066 } 2119 }
2120 if (!DSA_set0_pqg(key->dsa, dsa_p, dsa_q, dsa_g)) {
2121 ret = SSH_ERR_LIBCRYPTO_ERROR;
2122 goto out;
2123 }
2124 dsa_p = dsa_q = dsa_g = NULL; /* transferred */
2125 if (!DSA_set0_key(key->dsa, dsa_pub_key, NULL)) {
2126 ret = SSH_ERR_LIBCRYPTO_ERROR;
2127 goto out;
2128 }
2129 dsa_pub_key = NULL; /* transferred */
2067#ifdef DEBUG_PK 2130#ifdef DEBUG_PK
2068 DSA_print_fp(stderr, key->dsa, 8); 2131 DSA_print_fp(stderr, key->dsa, 8);
2069#endif 2132#endif
@@ -2197,9 +2260,17 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
2197 free(ktype); 2260 free(ktype);
2198 free(curve); 2261 free(curve);
2199 free(pk); 2262 free(pk);
2200#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) 2263#if defined(WITH_OPENSSL)
2264 BN_clear_free(rsa_n);
2265 BN_clear_free(rsa_e);
2266 BN_clear_free(dsa_p);
2267 BN_clear_free(dsa_q);
2268 BN_clear_free(dsa_g);
2269 BN_clear_free(dsa_pub_key);
2270# if defined(OPENSSL_HAS_ECC)
2201 EC_POINT_free(q); 2271 EC_POINT_free(q);
2202#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ 2272# endif /* OPENSSL_HAS_ECC */
2273#endif /* WITH_OPENSSL */
2203 return ret; 2274 return ret;
2204} 2275}
2205 2276
@@ -2401,120 +2472,6 @@ sshkey_verify(const struct sshkey *key,
2401 } 2472 }
2402} 2473}
2403 2474
2404/* Converts a private to a public key */
2405int
2406sshkey_demote(const struct sshkey *k, struct sshkey **dkp)
2407{
2408 struct sshkey *pk;
2409 int ret = SSH_ERR_INTERNAL_ERROR;
2410
2411 *dkp = NULL;
2412 if ((pk = calloc(1, sizeof(*pk))) == NULL)
2413 return SSH_ERR_ALLOC_FAIL;
2414 pk->type = k->type;
2415 pk->flags = k->flags;
2416 pk->ecdsa_nid = k->ecdsa_nid;
2417 pk->dsa = NULL;
2418 pk->ecdsa = NULL;
2419 pk->rsa = NULL;
2420 pk->ed25519_pk = NULL;
2421 pk->ed25519_sk = NULL;
2422 pk->xmss_pk = NULL;
2423 pk->xmss_sk = NULL;
2424
2425 switch (k->type) {
2426#ifdef WITH_OPENSSL
2427 case KEY_RSA_CERT:
2428 if ((ret = sshkey_cert_copy(k, pk)) != 0)
2429 goto fail;
2430 /* FALLTHROUGH */
2431 case KEY_RSA:
2432 if ((pk->rsa = RSA_new()) == NULL ||
2433 (pk->rsa->e = BN_dup(k->rsa->e)) == NULL ||
2434 (pk->rsa->n = BN_dup(k->rsa->n)) == NULL) {
2435 ret = SSH_ERR_ALLOC_FAIL;
2436 goto fail;
2437 }
2438 break;
2439 case KEY_DSA_CERT:
2440 if ((ret = sshkey_cert_copy(k, pk)) != 0)
2441 goto fail;
2442 /* FALLTHROUGH */
2443 case KEY_DSA:
2444 if ((pk->dsa = DSA_new()) == NULL ||
2445 (pk->dsa->p = BN_dup(k->dsa->p)) == NULL ||
2446 (pk->dsa->q = BN_dup(k->dsa->q)) == NULL ||
2447 (pk->dsa->g = BN_dup(k->dsa->g)) == NULL ||
2448 (pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL) {
2449 ret = SSH_ERR_ALLOC_FAIL;
2450 goto fail;
2451 }
2452 break;
2453 case KEY_ECDSA_CERT:
2454 if ((ret = sshkey_cert_copy(k, pk)) != 0)
2455 goto fail;
2456 /* FALLTHROUGH */
2457# ifdef OPENSSL_HAS_ECC
2458 case KEY_ECDSA:
2459 pk->ecdsa = EC_KEY_new_by_curve_name(pk->ecdsa_nid);
2460 if (pk->ecdsa == NULL) {
2461 ret = SSH_ERR_ALLOC_FAIL;
2462 goto fail;
2463 }
2464 if (EC_KEY_set_public_key(pk->ecdsa,
2465 EC_KEY_get0_public_key(k->ecdsa)) != 1) {
2466 ret = SSH_ERR_LIBCRYPTO_ERROR;
2467 goto fail;
2468 }
2469 break;
2470# endif /* OPENSSL_HAS_ECC */
2471#endif /* WITH_OPENSSL */
2472 case KEY_ED25519_CERT:
2473 if ((ret = sshkey_cert_copy(k, pk)) != 0)
2474 goto fail;
2475 /* FALLTHROUGH */
2476 case KEY_ED25519:
2477 if (k->ed25519_pk != NULL) {
2478 if ((pk->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) {
2479 ret = SSH_ERR_ALLOC_FAIL;
2480 goto fail;
2481 }
2482 memcpy(pk->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ);
2483 }
2484 break;
2485#ifdef WITH_XMSS
2486 case KEY_XMSS_CERT:
2487 if ((ret = sshkey_cert_copy(k, pk)) != 0)
2488 goto fail;
2489 /* FALLTHROUGH */
2490 case KEY_XMSS:
2491 if ((ret = sshkey_xmss_init(pk, k->xmss_name)) != 0)
2492 goto fail;
2493 if (k->xmss_pk != NULL) {
2494 size_t pklen = sshkey_xmss_pklen(k);
2495
2496 if (pklen == 0 || sshkey_xmss_pklen(pk) != pklen) {
2497 ret = SSH_ERR_INTERNAL_ERROR;
2498 goto fail;
2499 }
2500 if ((pk->xmss_pk = malloc(pklen)) == NULL) {
2501 ret = SSH_ERR_ALLOC_FAIL;
2502 goto fail;
2503 }
2504 memcpy(pk->xmss_pk, k->xmss_pk, pklen);
2505 }
2506 break;
2507#endif /* WITH_XMSS */
2508 default:
2509 ret = SSH_ERR_KEY_TYPE_UNKNOWN;
2510 fail:
2511 sshkey_free(pk);
2512 return ret;
2513 }
2514 *dkp = pk;
2515 return 0;
2516}
2517
2518/* Convert a plain key to their _CERT equivalent */ 2475/* Convert a plain key to their _CERT equivalent */
2519int 2476int
2520sshkey_to_certified(struct sshkey *k) 2477sshkey_to_certified(struct sshkey *k)
@@ -2573,6 +2530,9 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg,
2573 int ret = SSH_ERR_INTERNAL_ERROR; 2530 int ret = SSH_ERR_INTERNAL_ERROR;
2574 struct sshbuf *cert = NULL; 2531 struct sshbuf *cert = NULL;
2575 char *sigtype = NULL; 2532 char *sigtype = NULL;
2533#ifdef WITH_OPENSSL
2534 const BIGNUM *rsa_n, *rsa_e, *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key;
2535#endif /* WITH_OPENSSL */
2576 2536
2577 if (k == NULL || k->cert == NULL || 2537 if (k == NULL || k->cert == NULL ||
2578 k->cert->certblob == NULL || ca == NULL) 2538 k->cert->certblob == NULL || ca == NULL)
@@ -2609,10 +2569,12 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg,
2609 switch (k->type) { 2569 switch (k->type) {
2610#ifdef WITH_OPENSSL 2570#ifdef WITH_OPENSSL
2611 case KEY_DSA_CERT: 2571 case KEY_DSA_CERT:
2612 if ((ret = sshbuf_put_bignum2(cert, k->dsa->p)) != 0 || 2572 DSA_get0_pqg(k->dsa, &dsa_p, &dsa_q, &dsa_g);
2613 (ret = sshbuf_put_bignum2(cert, k->dsa->q)) != 0 || 2573 DSA_get0_key(k->dsa, &dsa_pub_key, NULL);
2614 (ret = sshbuf_put_bignum2(cert, k->dsa->g)) != 0 || 2574 if ((ret = sshbuf_put_bignum2(cert, dsa_p)) != 0 ||
2615 (ret = sshbuf_put_bignum2(cert, k->dsa->pub_key)) != 0) 2575 (ret = sshbuf_put_bignum2(cert, dsa_q)) != 0 ||
2576 (ret = sshbuf_put_bignum2(cert, dsa_g)) != 0 ||
2577 (ret = sshbuf_put_bignum2(cert, dsa_pub_key)) != 0)
2616 goto out; 2578 goto out;
2617 break; 2579 break;
2618# ifdef OPENSSL_HAS_ECC 2580# ifdef OPENSSL_HAS_ECC
@@ -2626,8 +2588,9 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg,
2626 break; 2588 break;
2627# endif /* OPENSSL_HAS_ECC */ 2589# endif /* OPENSSL_HAS_ECC */
2628 case KEY_RSA_CERT: 2590 case KEY_RSA_CERT:
2629 if ((ret = sshbuf_put_bignum2(cert, k->rsa->e)) != 0 || 2591 RSA_get0_key(k->rsa, &rsa_n, &rsa_e, NULL);
2630 (ret = sshbuf_put_bignum2(cert, k->rsa->n)) != 0) 2592 if ((ret = sshbuf_put_bignum2(cert, rsa_e)) != 0 ||
2593 (ret = sshbuf_put_bignum2(cert, rsa_n)) != 0)
2631 goto out; 2594 goto out;
2632 break; 2595 break;
2633#endif /* WITH_OPENSSL */ 2596#endif /* WITH_OPENSSL */
@@ -2820,18 +2783,25 @@ sshkey_private_serialize_opt(const struct sshkey *key, struct sshbuf *b,
2820 enum sshkey_serialize_rep opts) 2783 enum sshkey_serialize_rep opts)
2821{ 2784{
2822 int r = SSH_ERR_INTERNAL_ERROR; 2785 int r = SSH_ERR_INTERNAL_ERROR;
2786#ifdef WITH_OPENSSL
2787 const BIGNUM *rsa_n, *rsa_e, *rsa_d, *rsa_iqmp, *rsa_p, *rsa_q;
2788 const BIGNUM *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key, *dsa_priv_key;
2789#endif /* WITH_OPENSSL */
2823 2790
2824 if ((r = sshbuf_put_cstring(b, sshkey_ssh_name(key))) != 0) 2791 if ((r = sshbuf_put_cstring(b, sshkey_ssh_name(key))) != 0)
2825 goto out; 2792 goto out;
2826 switch (key->type) { 2793 switch (key->type) {
2827#ifdef WITH_OPENSSL 2794#ifdef WITH_OPENSSL
2828 case KEY_RSA: 2795 case KEY_RSA:
2829 if ((r = sshbuf_put_bignum2(b, key->rsa->n)) != 0 || 2796 RSA_get0_key(key->rsa, &rsa_n, &rsa_e, &rsa_d);
2830 (r = sshbuf_put_bignum2(b, key->rsa->e)) != 0 || 2797 RSA_get0_factors(key->rsa, &rsa_p, &rsa_q);
2831 (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 || 2798 RSA_get0_crt_params(key->rsa, NULL, NULL, &rsa_iqmp);
2832 (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 || 2799 if ((r = sshbuf_put_bignum2(b, rsa_n)) != 0 ||
2833 (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 || 2800 (r = sshbuf_put_bignum2(b, rsa_e)) != 0 ||
2834 (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0) 2801 (r = sshbuf_put_bignum2(b, rsa_d)) != 0 ||
2802 (r = sshbuf_put_bignum2(b, rsa_iqmp)) != 0 ||
2803 (r = sshbuf_put_bignum2(b, rsa_p)) != 0 ||
2804 (r = sshbuf_put_bignum2(b, rsa_q)) != 0)
2835 goto out; 2805 goto out;
2836 break; 2806 break;
2837 case KEY_RSA_CERT: 2807 case KEY_RSA_CERT:
@@ -2839,19 +2809,24 @@ sshkey_private_serialize_opt(const struct sshkey *key, struct sshbuf *b,
2839 r = SSH_ERR_INVALID_ARGUMENT; 2809 r = SSH_ERR_INVALID_ARGUMENT;
2840 goto out; 2810 goto out;
2841 } 2811 }
2812 RSA_get0_key(key->rsa, NULL, NULL, &rsa_d);
2813 RSA_get0_factors(key->rsa, &rsa_p, &rsa_q);
2814 RSA_get0_crt_params(key->rsa, NULL, NULL, &rsa_iqmp);
2842 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || 2815 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
2843 (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 || 2816 (r = sshbuf_put_bignum2(b, rsa_d)) != 0 ||
2844 (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 || 2817 (r = sshbuf_put_bignum2(b, rsa_iqmp)) != 0 ||
2845 (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 || 2818 (r = sshbuf_put_bignum2(b, rsa_p)) != 0 ||
2846 (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0) 2819 (r = sshbuf_put_bignum2(b, rsa_q)) != 0)
2847 goto out; 2820 goto out;
2848 break; 2821 break;
2849 case KEY_DSA: 2822 case KEY_DSA:
2850 if ((r = sshbuf_put_bignum2(b, key->dsa->p)) != 0 || 2823 DSA_get0_pqg(key->dsa, &dsa_p, &dsa_q, &dsa_g);
2851 (r = sshbuf_put_bignum2(b, key->dsa->q)) != 0 || 2824 DSA_get0_key(key->dsa, &dsa_pub_key, &dsa_priv_key);
2852 (r = sshbuf_put_bignum2(b, key->dsa->g)) != 0 || 2825 if ((r = sshbuf_put_bignum2(b, dsa_p)) != 0 ||
2853 (r = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0 || 2826 (r = sshbuf_put_bignum2(b, dsa_q)) != 0 ||
2854 (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0) 2827 (r = sshbuf_put_bignum2(b, dsa_g)) != 0 ||
2828 (r = sshbuf_put_bignum2(b, dsa_pub_key)) != 0 ||
2829 (r = sshbuf_put_bignum2(b, dsa_priv_key)) != 0)
2855 goto out; 2830 goto out;
2856 break; 2831 break;
2857 case KEY_DSA_CERT: 2832 case KEY_DSA_CERT:
@@ -2859,8 +2834,9 @@ sshkey_private_serialize_opt(const struct sshkey *key, struct sshbuf *b,
2859 r = SSH_ERR_INVALID_ARGUMENT; 2834 r = SSH_ERR_INVALID_ARGUMENT;
2860 goto out; 2835 goto out;
2861 } 2836 }
2837 DSA_get0_key(key->dsa, NULL, &dsa_priv_key);
2862 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || 2838 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
2863 (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0) 2839 (r = sshbuf_put_bignum2(b, dsa_priv_key)) != 0)
2864 goto out; 2840 goto out;
2865 break; 2841 break;
2866# ifdef OPENSSL_HAS_ECC 2842# ifdef OPENSSL_HAS_ECC
@@ -2961,6 +2937,10 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
2961 u_char *xmss_pk = NULL, *xmss_sk = NULL; 2937 u_char *xmss_pk = NULL, *xmss_sk = NULL;
2962#ifdef WITH_OPENSSL 2938#ifdef WITH_OPENSSL
2963 BIGNUM *exponent = NULL; 2939 BIGNUM *exponent = NULL;
2940 BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL;
2941 BIGNUM *rsa_iqmp = NULL, *rsa_p = NULL, *rsa_q = NULL;
2942 BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL;
2943 BIGNUM *dsa_pub_key = NULL, *dsa_priv_key = NULL;
2964#endif /* WITH_OPENSSL */ 2944#endif /* WITH_OPENSSL */
2965 2945
2966 if (kp != NULL) 2946 if (kp != NULL)
@@ -2975,18 +2955,44 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
2975 r = SSH_ERR_ALLOC_FAIL; 2955 r = SSH_ERR_ALLOC_FAIL;
2976 goto out; 2956 goto out;
2977 } 2957 }
2978 if ((r = sshbuf_get_bignum2(buf, k->dsa->p)) != 0 || 2958 if ((dsa_p = BN_new()) == NULL ||
2979 (r = sshbuf_get_bignum2(buf, k->dsa->q)) != 0 || 2959 (dsa_q = BN_new()) == NULL ||
2980 (r = sshbuf_get_bignum2(buf, k->dsa->g)) != 0 || 2960 (dsa_g = BN_new()) == NULL ||
2981 (r = sshbuf_get_bignum2(buf, k->dsa->pub_key)) != 0 || 2961 (dsa_pub_key = BN_new()) == NULL ||
2982 (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0) 2962 (dsa_priv_key = BN_new()) == NULL) {
2963 r = SSH_ERR_ALLOC_FAIL;
2964 goto out;
2965 }
2966 if ((r = sshbuf_get_bignum2(buf, dsa_p)) != 0 ||
2967 (r = sshbuf_get_bignum2(buf, dsa_q)) != 0 ||
2968 (r = sshbuf_get_bignum2(buf, dsa_g)) != 0 ||
2969 (r = sshbuf_get_bignum2(buf, dsa_pub_key)) != 0 ||
2970 (r = sshbuf_get_bignum2(buf, dsa_priv_key)) != 0)
2983 goto out; 2971 goto out;
2972 if (!DSA_set0_pqg(k->dsa, dsa_p, dsa_q, dsa_g)) {
2973 r = SSH_ERR_LIBCRYPTO_ERROR;
2974 goto out;
2975 }
2976 dsa_p = dsa_q = dsa_g = NULL; /* transferred */
2977 if (!DSA_set0_key(k->dsa, dsa_pub_key, dsa_priv_key)) {
2978 r = SSH_ERR_LIBCRYPTO_ERROR;
2979 goto out;
2980 }
2981 dsa_pub_key = dsa_priv_key = NULL; /* transferred */
2984 break; 2982 break;
2985 case KEY_DSA_CERT: 2983 case KEY_DSA_CERT:
2984 if ((dsa_priv_key = BN_new()) == NULL) {
2985 r = SSH_ERR_ALLOC_FAIL;
2986 goto out;
2987 }
2986 if ((r = sshkey_froms(buf, &k)) != 0 || 2988 if ((r = sshkey_froms(buf, &k)) != 0 ||
2987 (r = sshkey_add_private(k)) != 0 || 2989 (r = sshbuf_get_bignum2(buf, dsa_priv_key)) != 0)
2988 (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0) 2990 goto out;
2991 if (!DSA_set0_key(k->dsa, NULL, dsa_priv_key)) {
2992 r = SSH_ERR_LIBCRYPTO_ERROR;
2989 goto out; 2993 goto out;
2994 }
2995 dsa_priv_key = NULL; /* transferred */
2990 break; 2996 break;
2991# ifdef OPENSSL_HAS_ECC 2997# ifdef OPENSSL_HAS_ECC
2992 case KEY_ECDSA: 2998 case KEY_ECDSA:
@@ -3027,7 +3033,6 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
3027 goto out; 3033 goto out;
3028 } 3034 }
3029 if ((r = sshkey_froms(buf, &k)) != 0 || 3035 if ((r = sshkey_froms(buf, &k)) != 0 ||
3030 (r = sshkey_add_private(k)) != 0 ||
3031 (r = sshbuf_get_bignum2(buf, exponent)) != 0) 3036 (r = sshbuf_get_bignum2(buf, exponent)) != 0)
3032 goto out; 3037 goto out;
3033 if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) { 3038 if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) {
@@ -3045,32 +3050,65 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
3045 r = SSH_ERR_ALLOC_FAIL; 3050 r = SSH_ERR_ALLOC_FAIL;
3046 goto out; 3051 goto out;
3047 } 3052 }
3048 if ((r = sshbuf_get_bignum2(buf, k->rsa->n)) != 0 || 3053 if ((rsa_n = BN_new()) == NULL ||
3049 (r = sshbuf_get_bignum2(buf, k->rsa->e)) != 0 || 3054 (rsa_e = BN_new()) == NULL ||
3050 (r = sshbuf_get_bignum2(buf, k->rsa->d)) != 0 || 3055 (rsa_d = BN_new()) == NULL ||
3051 (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 || 3056 (rsa_iqmp = BN_new()) == NULL ||
3052 (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 || 3057 (rsa_p = BN_new()) == NULL ||
3053 (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 || 3058 (rsa_q = BN_new()) == NULL) {
3054 (r = ssh_rsa_generate_additional_parameters(k)) != 0) 3059 r = SSH_ERR_ALLOC_FAIL;
3060 goto out;
3061 }
3062 if ((r = sshbuf_get_bignum2(buf, rsa_n)) != 0 ||
3063 (r = sshbuf_get_bignum2(buf, rsa_e)) != 0 ||
3064 (r = sshbuf_get_bignum2(buf, rsa_d)) != 0 ||
3065 (r = sshbuf_get_bignum2(buf, rsa_iqmp)) != 0 ||
3066 (r = sshbuf_get_bignum2(buf, rsa_p)) != 0 ||
3067 (r = sshbuf_get_bignum2(buf, rsa_q)) != 0)
3055 goto out; 3068 goto out;
3056 if (BN_num_bits(k->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { 3069 if (!RSA_set0_key(k->rsa, rsa_n, rsa_e, rsa_d)) {
3057 r = SSH_ERR_KEY_LENGTH; 3070 r = SSH_ERR_LIBCRYPTO_ERROR;
3071 goto out;
3072 }
3073 rsa_n = rsa_e = rsa_d = NULL; /* transferred */
3074 if (!RSA_set0_factors(k->rsa, rsa_p, rsa_q)) {
3075 r = SSH_ERR_LIBCRYPTO_ERROR;
3058 goto out; 3076 goto out;
3059 } 3077 }
3078 rsa_p = rsa_q = NULL; /* transferred */
3079 if ((r = check_rsa_length(k->rsa)) != 0)
3080 goto out;
3081 if ((r = ssh_rsa_complete_crt_parameters(k, rsa_iqmp)) != 0)
3082 goto out;
3060 break; 3083 break;
3061 case KEY_RSA_CERT: 3084 case KEY_RSA_CERT:
3085 if ((rsa_d = BN_new()) == NULL ||
3086 (rsa_iqmp = BN_new()) == NULL ||
3087 (rsa_p = BN_new()) == NULL ||
3088 (rsa_q = BN_new()) == NULL) {
3089 r = SSH_ERR_ALLOC_FAIL;
3090 goto out;
3091 }
3062 if ((r = sshkey_froms(buf, &k)) != 0 || 3092 if ((r = sshkey_froms(buf, &k)) != 0 ||
3063 (r = sshkey_add_private(k)) != 0 || 3093 (r = sshbuf_get_bignum2(buf, rsa_d)) != 0 ||
3064 (r = sshbuf_get_bignum2(buf, k->rsa->d)) != 0 || 3094 (r = sshbuf_get_bignum2(buf, rsa_iqmp)) != 0 ||
3065 (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 || 3095 (r = sshbuf_get_bignum2(buf, rsa_p)) != 0 ||
3066 (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 || 3096 (r = sshbuf_get_bignum2(buf, rsa_q)) != 0)
3067 (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 || 3097 goto out;
3068 (r = ssh_rsa_generate_additional_parameters(k)) != 0) 3098 if (!RSA_set0_key(k->rsa, NULL, NULL, rsa_d)) {
3099 r = SSH_ERR_LIBCRYPTO_ERROR;
3069 goto out; 3100 goto out;
3070 if (BN_num_bits(k->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { 3101 }
3071 r = SSH_ERR_KEY_LENGTH; 3102 rsa_d = NULL; /* transferred */
3103 if (!RSA_set0_factors(k->rsa, rsa_p, rsa_q)) {
3104 r = SSH_ERR_LIBCRYPTO_ERROR;
3072 goto out; 3105 goto out;
3073 } 3106 }
3107 rsa_p = rsa_q = NULL; /* transferred */
3108 if ((r = check_rsa_length(k->rsa)) != 0)
3109 goto out;
3110 if ((r = ssh_rsa_complete_crt_parameters(k, rsa_iqmp)) != 0)
3111 goto out;
3074 break; 3112 break;
3075#endif /* WITH_OPENSSL */ 3113#endif /* WITH_OPENSSL */
3076 case KEY_ED25519: 3114 case KEY_ED25519:
@@ -3091,7 +3129,6 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
3091 break; 3129 break;
3092 case KEY_ED25519_CERT: 3130 case KEY_ED25519_CERT:
3093 if ((r = sshkey_froms(buf, &k)) != 0 || 3131 if ((r = sshkey_froms(buf, &k)) != 0 ||
3094 (r = sshkey_add_private(k)) != 0 ||
3095 (r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 || 3132 (r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 ||
3096 (r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0) 3133 (r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0)
3097 goto out; 3134 goto out;
@@ -3128,7 +3165,6 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
3128 break; 3165 break;
3129 case KEY_XMSS_CERT: 3166 case KEY_XMSS_CERT:
3130 if ((r = sshkey_froms(buf, &k)) != 0 || 3167 if ((r = sshkey_froms(buf, &k)) != 0 ||
3131 (r = sshkey_add_private(k)) != 0 ||
3132 (r = sshbuf_get_cstring(buf, &xmss_name, NULL)) != 0 || 3168 (r = sshbuf_get_cstring(buf, &xmss_name, NULL)) != 0 ||
3133 (r = sshbuf_get_string(buf, &xmss_pk, &pklen)) != 0 || 3169 (r = sshbuf_get_string(buf, &xmss_pk, &pklen)) != 0 ||
3134 (r = sshbuf_get_string(buf, &xmss_sk, &sklen)) != 0) 3170 (r = sshbuf_get_string(buf, &xmss_sk, &sklen)) != 0)
@@ -3177,6 +3213,17 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
3177 free(curve); 3213 free(curve);
3178#ifdef WITH_OPENSSL 3214#ifdef WITH_OPENSSL
3179 BN_clear_free(exponent); 3215 BN_clear_free(exponent);
3216 BN_clear_free(dsa_p);
3217 BN_clear_free(dsa_q);
3218 BN_clear_free(dsa_g);
3219 BN_clear_free(dsa_pub_key);
3220 BN_clear_free(dsa_priv_key);
3221 BN_clear_free(rsa_n);
3222 BN_clear_free(rsa_e);
3223 BN_clear_free(rsa_d);
3224 BN_clear_free(rsa_p);
3225 BN_clear_free(rsa_q);
3226 BN_clear_free(rsa_iqmp);
3180#endif /* WITH_OPENSSL */ 3227#endif /* WITH_OPENSSL */
3181 sshkey_free(k); 3228 sshkey_free(k);
3182 freezero(ed25519_pk, pklen); 3229 freezero(ed25519_pk, pklen);
@@ -3831,7 +3878,9 @@ translate_libcrypto_error(unsigned long pem_err)
3831 switch (pem_reason) { 3878 switch (pem_reason) {
3832 case EVP_R_BAD_DECRYPT: 3879 case EVP_R_BAD_DECRYPT:
3833 return SSH_ERR_KEY_WRONG_PASSPHRASE; 3880 return SSH_ERR_KEY_WRONG_PASSPHRASE;
3881#ifdef EVP_R_BN_DECODE_ERROR
3834 case EVP_R_BN_DECODE_ERROR: 3882 case EVP_R_BN_DECODE_ERROR:
3883#endif
3835 case EVP_R_DECODE_ERROR: 3884 case EVP_R_DECODE_ERROR:
3836#ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR 3885#ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR
3837 case EVP_R_PRIVATE_KEY_DECODE_ERROR: 3886 case EVP_R_PRIVATE_KEY_DECODE_ERROR:
@@ -3896,7 +3945,7 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
3896 r = convert_libcrypto_error(); 3945 r = convert_libcrypto_error();
3897 goto out; 3946 goto out;
3898 } 3947 }
3899 if (pk->type == EVP_PKEY_RSA && 3948 if (EVP_PKEY_base_id(pk) == EVP_PKEY_RSA &&
3900 (type == KEY_UNSPEC || type == KEY_RSA)) { 3949 (type == KEY_UNSPEC || type == KEY_RSA)) {
3901 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { 3950 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
3902 r = SSH_ERR_ALLOC_FAIL; 3951 r = SSH_ERR_ALLOC_FAIL;
@@ -3911,11 +3960,9 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
3911 r = SSH_ERR_LIBCRYPTO_ERROR; 3960 r = SSH_ERR_LIBCRYPTO_ERROR;
3912 goto out; 3961 goto out;
3913 } 3962 }
3914 if (BN_num_bits(prv->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { 3963 if ((r = check_rsa_length(prv->rsa)) != 0)
3915 r = SSH_ERR_KEY_LENGTH;
3916 goto out; 3964 goto out;
3917 } 3965 } else if (EVP_PKEY_base_id(pk) == EVP_PKEY_DSA &&
3918 } else if (pk->type == EVP_PKEY_DSA &&
3919 (type == KEY_UNSPEC || type == KEY_DSA)) { 3966 (type == KEY_UNSPEC || type == KEY_DSA)) {
3920 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { 3967 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
3921 r = SSH_ERR_ALLOC_FAIL; 3968 r = SSH_ERR_ALLOC_FAIL;
@@ -3927,7 +3974,7 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
3927 DSA_print_fp(stderr, prv->dsa, 8); 3974 DSA_print_fp(stderr, prv->dsa, 8);
3928#endif 3975#endif
3929#ifdef OPENSSL_HAS_ECC 3976#ifdef OPENSSL_HAS_ECC
3930 } else if (pk->type == EVP_PKEY_EC && 3977 } else if (EVP_PKEY_base_id(pk) == EVP_PKEY_EC &&
3931 (type == KEY_UNSPEC || type == KEY_ECDSA)) { 3978 (type == KEY_UNSPEC || type == KEY_ECDSA)) {
3932 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { 3979 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
3933 r = SSH_ERR_ALLOC_FAIL; 3980 r = SSH_ERR_ALLOC_FAIL;