diff options
author | djm@openbsd.org <djm@openbsd.org> | 2018-09-13 02:08:33 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2018-09-13 12:12:33 +1000 |
commit | 482d23bcacdd3664f21cc82a5135f66fc598275f (patch) | |
tree | 362f697a94da0a765d1dabcfbf33370b2a4df121 /sshkey.c | |
parent | d70d061828730a56636ab6f1f24fe4a8ccefcfc1 (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.c | 637 |
1 files changed, 342 insertions, 295 deletions
@@ -289,14 +289,24 @@ sshkey_names_valid2(const char *names, int allow_wildcard) | |||
289 | u_int | 289 | u_int |
290 | sshkey_size(const struct sshkey *k) | 290 | sshkey_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 | ||
556 | int | 558 | /* XXX garbage-collect this API */ |
557 | sshkey_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 | |||
597 | struct sshkey * | 559 | struct sshkey * |
598 | sshkey_new_private(int type) | 560 | sshkey_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) | |||
686 | int | 644 | int |
687 | sshkey_equal_public(const struct sshkey *a, const struct sshkey *b) | 645 | sshkey_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 | ||
1863 | static int | 1886 | static int |
@@ -1986,6 +2009,17 @@ cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf) | |||
1986 | } | 2009 | } |
1987 | 2010 | ||
1988 | static int | 2011 | static int |
2012 | check_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 | |||
2022 | static int | ||
1989 | sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, | 2023 | sshkey_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 */ | ||
2405 | int | ||
2406 | sshkey_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 */ |
2519 | int | 2476 | int |
2520 | sshkey_to_certified(struct sshkey *k) | 2477 | sshkey_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; |