diff options
author | Colin Watson <cjwatson@debian.org> | 2018-10-19 21:29:01 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2018-10-20 22:54:15 +0100 |
commit | d80ebbf028196b2478beebf5a290b97f35e1eed9 (patch) | |
tree | 6666a5484923a26738675ff27a6186cfe15d4cad /sshkey.c | |
parent | 4f5bbf3f11efeec65bbd56464b20a19bd250e5cc (diff) | |
parent | 1d2a55436d4b556269f42ad5f7e16608b5a8ed74 (diff) |
New upstream release (7.9p1)
Diffstat (limited to 'sshkey.c')
-rw-r--r-- | sshkey.c | 816 |
1 files changed, 467 insertions, 349 deletions
@@ -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); |
79 | static int sshkey_from_blob_internal(struct sshbuf *buf, | 81 | static int sshkey_from_blob_internal(struct sshbuf *buf, |
80 | struct sshkey **keyp, int allow_cert); | 82 | struct sshkey **keyp, int allow_cert); |
83 | static int get_sigtype(const u_char *sig, size_t siglen, char **sigtypep); | ||
81 | 84 | ||
82 | /* Supported key types */ | 85 | /* Supported key types */ |
83 | struct keytype { | 86 | struct 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) | |||
289 | u_int | 284 | u_int |
290 | sshkey_size(const struct sshkey *k) | 285 | sshkey_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 | ||
554 | int | ||
555 | sshkey_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 | |||
595 | struct sshkey * | ||
596 | sshkey_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 | |||
609 | void | 553 | void |
610 | sshkey_free(struct sshkey *k) | 554 | sshkey_free(struct sshkey *k) |
611 | { | 555 | { |
@@ -684,9 +628,15 @@ cert_compare(struct sshkey_cert *a, struct sshkey_cert *b) | |||
684 | int | 628 | int |
685 | sshkey_equal_public(const struct sshkey *a, const struct sshkey *b) | 629 | sshkey_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 | ||
1749 | int | 1727 | int |
1750 | sshkey_from_private(const struct sshkey *k, struct sshkey **pkp) | 1728 | sshkey_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 | ||
1847 | static int | 1871 | static 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 | ||
1997 | static int | ||
1998 | check_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 | |||
1970 | static int | 2009 | static int |
1971 | sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, | 2010 | sshkey_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 | */ | ||
2328 | int | ||
2329 | sshkey_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 | */ |
2248 | const char * | 2345 | const 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 */ | ||
2366 | int | ||
2367 | sshkey_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 */ |
2480 | int | 2463 | int |
2481 | sshkey_to_certified(struct sshkey *k) | 2464 | sshkey_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 | ||
3812 | static int | 3909 | static int |
3910 | pem_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 | |||
3923 | static int | ||
3813 | sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, | 3924 | sshkey_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; |