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