1 /* $OpenBSD: sshkey.c,v 1.64 2018/03/22 07:05:48 markus Exp $ */
3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
4 * Copyright (c) 2008 Alexander von Gernler. All rights reserved.
5 * Copyright (c) 2010,2011 Damien Miller. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #include <sys/types.h>
31 #include <netinet/in.h>
34 #include <openssl/evp.h>
35 #include <openssl/err.h>
36 #include <openssl/pem.h>
39 #include "crypto_api.h"
48 #endif /* HAVE_UTIL_H */
56 #define SSHKEY_INTERNAL
58 #include "sshkey-xmss.h"
61 #include "xmss_fast.h"
63 /* openssh private key file format */
64 #define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n"
65 #define MARK_END "-----END OPENSSH PRIVATE KEY-----\n"
66 #define MARK_BEGIN_LEN (sizeof(MARK_BEGIN) - 1)
67 #define MARK_END_LEN (sizeof(MARK_END) - 1)
68 #define KDFNAME "bcrypt"
69 #define AUTH_MAGIC "openssh-key-v1"
71 #define DEFAULT_CIPHERNAME "aes256-ctr"
72 #define DEFAULT_ROUNDS 16
74 /* Version identification string for SSH v1 identity files. */
75 #define LEGACY_BEGIN "SSH PRIVATE KEY FILE FORMAT 1.1\n"
77 int sshkey_private_serialize_opt(const struct sshkey *key,
78 struct sshbuf *buf, enum sshkey_serialize_rep);
79 static int sshkey_from_blob_internal(struct sshbuf *buf,
80 struct sshkey **keyp, int allow_cert);
82 /* Supported key types */
85 const char *shortname;
91 static const struct keytype keytypes[] = {
92 { "ssh-ed25519", "ED25519", KEY_ED25519, 0, 0, 0 },
93 { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT",
94 KEY_ED25519_CERT, 0, 1, 0 },
96 { "ssh-xmss@openssh.com", "XMSS", KEY_XMSS, 0, 0, 0 },
97 { "ssh-xmss-cert-v01@openssh.com", "XMSS-CERT",
98 KEY_XMSS_CERT, 0, 1, 0 },
99 #endif /* WITH_XMSS */
101 { "ssh-rsa", "RSA", KEY_RSA, 0, 0, 0 },
102 { "rsa-sha2-256", "RSA", KEY_RSA, 0, 0, 1 },
103 { "rsa-sha2-512", "RSA", KEY_RSA, 0, 0, 1 },
104 { "ssh-dss", "DSA", KEY_DSA, 0, 0, 0 },
105 # ifdef OPENSSL_HAS_ECC
106 { "ecdsa-sha2-nistp256", "ECDSA", KEY_ECDSA, NID_X9_62_prime256v1, 0, 0 },
107 { "ecdsa-sha2-nistp384", "ECDSA", KEY_ECDSA, NID_secp384r1, 0, 0 },
108 # ifdef OPENSSL_HAS_NISTP521
109 { "ecdsa-sha2-nistp521", "ECDSA", KEY_ECDSA, NID_secp521r1, 0, 0 },
110 # endif /* OPENSSL_HAS_NISTP521 */
111 # endif /* OPENSSL_HAS_ECC */
112 { "ssh-rsa-cert-v01@openssh.com", "RSA-CERT", KEY_RSA_CERT, 0, 1, 0 },
113 { "ssh-dss-cert-v01@openssh.com", "DSA-CERT", KEY_DSA_CERT, 0, 1, 0 },
114 # ifdef OPENSSL_HAS_ECC
115 { "ecdsa-sha2-nistp256-cert-v01@openssh.com", "ECDSA-CERT",
116 KEY_ECDSA_CERT, NID_X9_62_prime256v1, 1, 0 },
117 { "ecdsa-sha2-nistp384-cert-v01@openssh.com", "ECDSA-CERT",
118 KEY_ECDSA_CERT, NID_secp384r1, 1, 0 },
119 # ifdef OPENSSL_HAS_NISTP521
120 { "ecdsa-sha2-nistp521-cert-v01@openssh.com", "ECDSA-CERT",
121 KEY_ECDSA_CERT, NID_secp521r1, 1, 0 },
122 # endif /* OPENSSL_HAS_NISTP521 */
123 # endif /* OPENSSL_HAS_ECC */
124 #endif /* WITH_OPENSSL */
125 { NULL, NULL, -1, -1, 0, 0 }
129 sshkey_type(const struct sshkey *k)
131 const struct keytype *kt;
133 for (kt = keytypes; kt->type != -1; kt++) {
134 if (kt->type == k->type)
135 return kt->shortname;
141 sshkey_ssh_name_from_type_nid(int type, int nid)
143 const struct keytype *kt;
145 for (kt = keytypes; kt->type != -1; kt++) {
146 if (kt->type == type && (kt->nid == 0 || kt->nid == nid))
149 return "ssh-unknown";
153 sshkey_type_is_cert(int type)
155 const struct keytype *kt;
157 for (kt = keytypes; kt->type != -1; kt++) {
158 if (kt->type == type)
165 sshkey_ssh_name(const struct sshkey *k)
167 return sshkey_ssh_name_from_type_nid(k->type, k->ecdsa_nid);
171 sshkey_ssh_name_plain(const struct sshkey *k)
173 return sshkey_ssh_name_from_type_nid(sshkey_type_plain(k->type),
178 sshkey_type_from_name(const char *name)
180 const struct keytype *kt;
182 for (kt = keytypes; kt->type != -1; kt++) {
183 /* Only allow shortname matches for plain key types */
184 if ((kt->name != NULL && strcmp(name, kt->name) == 0) ||
185 (!kt->cert && strcasecmp(kt->shortname, name) == 0))
192 sshkey_ecdsa_nid_from_name(const char *name)
194 const struct keytype *kt;
196 for (kt = keytypes; kt->type != -1; kt++) {
197 if (kt->type != KEY_ECDSA && kt->type != KEY_ECDSA_CERT)
199 if (kt->name != NULL && strcmp(name, kt->name) == 0)
206 sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep)
208 char *tmp, *ret = NULL;
209 size_t nlen, rlen = 0;
210 const struct keytype *kt;
212 for (kt = keytypes; kt->type != -1; kt++) {
213 if (kt->name == NULL)
215 if (!include_sigonly && kt->sigonly)
217 if ((certs_only && !kt->cert) || (plain_only && kt->cert))
221 nlen = strlen(kt->name);
222 if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) {
227 memcpy(ret + rlen, kt->name, nlen + 1);
234 sshkey_names_valid2(const char *names, int allow_wildcard)
237 const struct keytype *kt;
240 if (names == NULL || strcmp(names, "") == 0)
242 if ((s = cp = strdup(names)) == NULL)
244 for ((p = strsep(&cp, ",")); p && *p != '\0';
245 (p = strsep(&cp, ","))) {
246 type = sshkey_type_from_name(p);
247 if (type == KEY_UNSPEC) {
248 if (allow_wildcard) {
250 * Try matching key types against the string.
251 * If any has a positive or negative match then
252 * the component is accepted.
254 for (kt = keytypes; kt->type != -1; kt++) {
255 if (match_pattern_list(kt->name,
271 sshkey_size(const struct sshkey *k)
277 #if OPENSSL_VERSION_NUMBER >= 0x10100000UL
278 return RSA_bits(k->rsa);
280 return RSA_bits(key->rsa);
284 #if OPENSSL_VERSION_NUMBER >= 0x10100000UL
285 return DSA_bits(k->dsa);
287 return BN_num_bits(k->dsa->p);
291 return sshkey_curve_nid_to_bits(k->ecdsa_nid);
292 #endif /* WITH_OPENSSL */
294 case KEY_ED25519_CERT:
297 return 256; /* XXX */
303 sshkey_type_is_valid_ca(int type)
318 sshkey_is_cert(const struct sshkey *k)
322 return sshkey_type_is_cert(k->type);
325 /* Return the cert-less equivalent to a certified key type */
327 sshkey_type_plain(int type)
336 case KEY_ED25519_CERT:
346 /* XXX: these are really begging for a table-driven approach */
348 sshkey_curve_name_to_nid(const char *name)
350 if (strcmp(name, "nistp256") == 0)
351 return NID_X9_62_prime256v1;
352 else if (strcmp(name, "nistp384") == 0)
353 return NID_secp384r1;
354 # ifdef OPENSSL_HAS_NISTP521
355 else if (strcmp(name, "nistp521") == 0)
356 return NID_secp521r1;
357 # endif /* OPENSSL_HAS_NISTP521 */
363 sshkey_curve_nid_to_bits(int nid)
366 case NID_X9_62_prime256v1:
370 # ifdef OPENSSL_HAS_NISTP521
373 # endif /* OPENSSL_HAS_NISTP521 */
380 sshkey_ecdsa_bits_to_nid(int bits)
384 return NID_X9_62_prime256v1;
386 return NID_secp384r1;
387 # ifdef OPENSSL_HAS_NISTP521
389 return NID_secp521r1;
390 # endif /* OPENSSL_HAS_NISTP521 */
397 sshkey_curve_nid_to_name(int nid)
400 case NID_X9_62_prime256v1:
404 # ifdef OPENSSL_HAS_NISTP521
407 # endif /* OPENSSL_HAS_NISTP521 */
414 sshkey_ec_nid_to_hash_alg(int nid)
416 int kbits = sshkey_curve_nid_to_bits(nid);
421 /* RFC5656 section 6.2.1 */
423 return SSH_DIGEST_SHA256;
424 else if (kbits <= 384)
425 return SSH_DIGEST_SHA384;
427 return SSH_DIGEST_SHA512;
429 #endif /* WITH_OPENSSL */
432 cert_free(struct sshkey_cert *cert)
438 sshbuf_free(cert->certblob);
439 sshbuf_free(cert->critical);
440 sshbuf_free(cert->extensions);
442 for (i = 0; i < cert->nprincipals; i++)
443 free(cert->principals[i]);
444 free(cert->principals);
445 sshkey_free(cert->signature_key);
446 freezero(cert, sizeof(*cert));
449 static struct sshkey_cert *
452 struct sshkey_cert *cert;
454 if ((cert = calloc(1, sizeof(*cert))) == NULL)
456 if ((cert->certblob = sshbuf_new()) == NULL ||
457 (cert->critical = sshbuf_new()) == NULL ||
458 (cert->extensions = sshbuf_new()) == NULL) {
463 cert->principals = NULL;
464 cert->signature_key = NULL;
475 #endif /* WITH_OPENSSL */
477 if ((k = calloc(1, sizeof(*k))) == NULL)
485 k->ed25519_sk = NULL;
486 k->ed25519_pk = NULL;
494 BIGNUM *n=NULL, *e=NULL; /* just allocate */
495 if ((rsa = RSA_new()) == NULL ||
496 (n = BN_new()) == NULL ||
497 (e = BN_new()) == NULL) {
504 BN_clear(n); BN_clear(e);
505 if (RSA_set0_key(rsa, n, e, NULL) == 0)
514 BIGNUM *p=NULL, *q=NULL, *g=NULL, *pubkey=NULL; /* just allocate */
515 if ((dsa = DSA_new()) == NULL ||
516 (p = BN_new()) == NULL ||
517 (q = BN_new()) == NULL ||
518 (g = BN_new()) == NULL ||
519 (pubkey = BN_new()) == NULL) {
528 if (DSA_set0_pqg(dsa, p, q, g) == 0) {
529 BN_free(p); BN_free(q); BN_free(g);
534 if (DSA_set0_key(dsa, pubkey, NULL) == 0) {
544 /* Cannot do anything until we know the group */
546 #endif /* WITH_OPENSSL */
548 case KEY_ED25519_CERT:
551 /* no need to prealloc */
560 if (sshkey_is_cert(k)) {
561 if ((k->cert = cert_new()) == NULL) {
571 sshkey_add_private(struct sshkey *k)
577 #if OPENSSL_VERSION_NUMBER >= 0x10100000UL
578 /* Allocate BIGNUM. This is a mess.
579 For OpenSSL 1.1.x API these shouldn't be mandatory,
580 but some regression tests for non-NULL pointer of
582 #define new_or_dup(bn, nbn) \
584 if ((nbn = BN_new()) == NULL) \
585 return SSH_ERR_ALLOC_FAIL; \
587 /* otherwise use-after-free will occur */ \
588 if ((nbn = BN_dup(bn)) == NULL) \
589 return SSH_ERR_ALLOC_FAIL; \
592 const BIGNUM *d, *iqmp, *q, *p, *dmq1, *dmp1; /* allocate if NULL */
593 BIGNUM *nd, *niqmp, *nq, *np, *ndmq1, *ndmp1;
595 RSA_get0_key(k->rsa, NULL, NULL, &d);
596 RSA_get0_factors(k->rsa, &p, &q);
597 RSA_get0_crt_params(k->rsa, &dmp1, &dmq1, &iqmp);
600 new_or_dup(iqmp, niqmp);
603 new_or_dup(dmq1, ndmq1);
604 new_or_dup(dmp1, ndmp1);
606 if (RSA_set0_key(k->rsa, NULL, NULL, nd) == 0)
609 if (RSA_set0_factors(k->rsa, np, nq) == 0)
612 if (RSA_set0_crt_params(k->rsa, ndmp1, ndmq1, niqmp) == 0) {
615 BN_free(np); BN_free(nq);
616 BN_free(ndmp1); BN_free(ndmq1); BN_free(niqmp);
617 return SSH_ERR_LIBCRYPTO_ERROR;
619 ndmp1 = ndmq1 = niqmp = NULL;
622 #define bn_maybe_alloc_failed(p) (p == NULL && (p = BN_new()) == NULL)
623 if (bn_maybe_alloc_failed(k->rsa->d) ||
624 bn_maybe_alloc_failed(k->rsa->iqmp) ||
625 bn_maybe_alloc_failed(k->rsa->q) ||
626 bn_maybe_alloc_failed(k->rsa->p) ||
627 bn_maybe_alloc_failed(k->rsa->dmq1) ||
628 bn_maybe_alloc_failed(k->rsa->dmp1))
629 return SSH_ERR_ALLOC_FAIL;
634 #if OPENSSL_VERSION_NUMBER >= 0x10100000UL
636 const BIGNUM *priv_key;
638 DSA_get0_key(k->dsa, NULL, &priv_key);
639 new_or_dup(priv_key, npriv_key);
640 if (DSA_set0_key(k->dsa, NULL, npriv_key) == 0) {
642 return SSH_ERR_LIBCRYPTO_ERROR;
646 if (bn_maybe_alloc_failed(k->dsa->priv_key))
647 return SSH_ERR_ALLOC_FAIL;
650 #undef bn_maybe_alloc_failed
654 /* Cannot do anything until we know the group */
656 #endif /* WITH_OPENSSL */
658 case KEY_ED25519_CERT:
661 /* no need to prealloc */
666 return SSH_ERR_INVALID_ARGUMENT;
672 sshkey_new_private(int type)
674 struct sshkey *k = sshkey_new(type);
678 if (sshkey_add_private(k) != 0) {
686 sshkey_free(struct sshkey *k)
702 # ifdef OPENSSL_HAS_ECC
705 EC_KEY_free(k->ecdsa);
708 # endif /* OPENSSL_HAS_ECC */
709 #endif /* WITH_OPENSSL */
711 case KEY_ED25519_CERT:
712 freezero(k->ed25519_pk, ED25519_PK_SZ);
713 k->ed25519_pk = NULL;
714 freezero(k->ed25519_sk, ED25519_SK_SZ);
715 k->ed25519_sk = NULL;
720 freezero(k->xmss_pk, sshkey_xmss_pklen(k));
722 freezero(k->xmss_sk, sshkey_xmss_sklen(k));
724 sshkey_xmss_free_state(k);
727 free(k->xmss_filename);
728 k->xmss_filename = NULL;
730 #endif /* WITH_XMSS */
736 if (sshkey_is_cert(k))
738 freezero(k, sizeof(*k));
742 cert_compare(struct sshkey_cert *a, struct sshkey_cert *b)
744 if (a == NULL && b == NULL)
746 if (a == NULL || b == NULL)
748 if (sshbuf_len(a->certblob) != sshbuf_len(b->certblob))
750 if (timingsafe_bcmp(sshbuf_ptr(a->certblob), sshbuf_ptr(b->certblob),
751 sshbuf_len(a->certblob)) != 0)
757 * Compare public portions of key only, allowing comparisons between
758 * certificates and plain keys too.
761 sshkey_equal_public(const struct sshkey *a, const struct sshkey *b)
763 #if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
765 #endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */
767 if (a == NULL || b == NULL ||
768 sshkey_type_plain(a->type) != sshkey_type_plain(b->type))
776 const BIGNUM *a_e, *b_e, *a_n, *b_n;
777 const BIGNUM *a_d, *b_d;
778 if (a->rsa == NULL) return 0;
779 if (b->rsa == NULL) return 0;
780 RSA_get0_key(a->rsa, &a_n, &a_e, &a_d);
781 RSA_get0_key(b->rsa, &b_n, &b_e, &b_d);
783 BN_cmp(a_e, b_e) == 0 &&
784 BN_cmp(a_n, b_n) == 0;
789 const BIGNUM *a_p, *a_q, *a_g, *a_pub_key;
790 const BIGNUM *b_p, *b_q, *b_g, *b_pub_key;
791 if (a->dsa == NULL) return 0;
792 if (b->dsa == NULL) return 0;
793 DSA_get0_pqg(a->dsa, &a_p, &a_q, &a_g);
794 DSA_get0_pqg(b->dsa, &b_p, &b_q, &b_g);
795 DSA_get0_key(a->dsa, &a_pub_key, NULL);
796 DSA_get0_key(b->dsa, &b_pub_key, NULL);
798 BN_cmp(a_p, b_p) == 0 &&
799 BN_cmp(a_q, b_q) == 0 &&
800 BN_cmp(a_g, b_g) == 0 &&
801 BN_cmp(a_pub_key, b_pub_key) == 0;
803 # ifdef OPENSSL_HAS_ECC
806 if (a->ecdsa == NULL || b->ecdsa == NULL ||
807 EC_KEY_get0_public_key(a->ecdsa) == NULL ||
808 EC_KEY_get0_public_key(b->ecdsa) == NULL)
810 if ((bnctx = BN_CTX_new()) == NULL)
812 if (EC_GROUP_cmp(EC_KEY_get0_group(a->ecdsa),
813 EC_KEY_get0_group(b->ecdsa), bnctx) != 0 ||
814 EC_POINT_cmp(EC_KEY_get0_group(a->ecdsa),
815 EC_KEY_get0_public_key(a->ecdsa),
816 EC_KEY_get0_public_key(b->ecdsa), bnctx) != 0) {
822 # endif /* OPENSSL_HAS_ECC */
823 #endif /* WITH_OPENSSL */
825 case KEY_ED25519_CERT:
826 return a->ed25519_pk != NULL && b->ed25519_pk != NULL &&
827 memcmp(a->ed25519_pk, b->ed25519_pk, ED25519_PK_SZ) == 0;
831 return a->xmss_pk != NULL && b->xmss_pk != NULL &&
832 sshkey_xmss_pklen(a) == sshkey_xmss_pklen(b) &&
833 memcmp(a->xmss_pk, b->xmss_pk, sshkey_xmss_pklen(a)) == 0;
834 #endif /* WITH_XMSS */
842 sshkey_equal(const struct sshkey *a, const struct sshkey *b)
844 if (a == NULL || b == NULL || a->type != b->type)
846 if (sshkey_is_cert(a)) {
847 if (!cert_compare(a->cert, b->cert))
850 return sshkey_equal_public(a, b);
854 to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain,
855 enum sshkey_serialize_rep opts)
857 int type, ret = SSH_ERR_INTERNAL_ERROR;
858 const char *typename;
861 return SSH_ERR_INVALID_ARGUMENT;
863 if (sshkey_is_cert(key)) {
864 if (key->cert == NULL)
865 return SSH_ERR_EXPECTED_CERT;
866 if (sshbuf_len(key->cert->certblob) == 0)
867 return SSH_ERR_KEY_LACKS_CERTBLOB;
869 type = force_plain ? sshkey_type_plain(key->type) : key->type;
870 typename = sshkey_ssh_name_from_type_nid(type, key->ecdsa_nid);
877 #endif /* WITH_OPENSSL */
878 case KEY_ED25519_CERT:
881 #endif /* WITH_XMSS */
882 /* Use the existing blob */
883 /* XXX modified flag? */
884 if ((ret = sshbuf_putb(b, key->cert->certblob)) != 0)
889 if (key->dsa == NULL)
890 return SSH_ERR_INVALID_ARGUMENT;
892 const BIGNUM *p, *q, *g, *pub_key;
893 DSA_get0_pqg(key->dsa, &p, &q, &g);
894 DSA_get0_key(key->dsa, &pub_key, NULL);
895 if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
896 (ret = sshbuf_put_bignum2(b, p)) != 0 ||
897 (ret = sshbuf_put_bignum2(b, q)) != 0 ||
898 (ret = sshbuf_put_bignum2(b, g)) != 0 ||
899 (ret = sshbuf_put_bignum2(b, pub_key)) != 0)
903 # ifdef OPENSSL_HAS_ECC
905 if (key->ecdsa == NULL)
906 return SSH_ERR_INVALID_ARGUMENT;
907 if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
908 (ret = sshbuf_put_cstring(b,
909 sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 ||
910 (ret = sshbuf_put_eckey(b, key->ecdsa)) != 0)
915 if (key->rsa == NULL)
916 return SSH_ERR_INVALID_ARGUMENT;
919 RSA_get0_key(key->rsa, &n, &e, NULL);
920 if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
921 (ret = sshbuf_put_bignum2(b, e)) != 0 ||
922 (ret = sshbuf_put_bignum2(b, n)) != 0)
926 #endif /* WITH_OPENSSL */
928 if (key->ed25519_pk == NULL)
929 return SSH_ERR_INVALID_ARGUMENT;
930 if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
931 (ret = sshbuf_put_string(b,
932 key->ed25519_pk, ED25519_PK_SZ)) != 0)
937 if (key->xmss_name == NULL || key->xmss_pk == NULL ||
938 sshkey_xmss_pklen(key) == 0)
939 return SSH_ERR_INVALID_ARGUMENT;
940 if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
941 (ret = sshbuf_put_cstring(b, key->xmss_name)) != 0 ||
942 (ret = sshbuf_put_string(b,
943 key->xmss_pk, sshkey_xmss_pklen(key))) != 0 ||
944 (ret = sshkey_xmss_serialize_pk_info(key, b, opts)) != 0)
947 #endif /* WITH_XMSS */
949 return SSH_ERR_KEY_TYPE_UNKNOWN;
955 sshkey_putb(const struct sshkey *key, struct sshbuf *b)
957 return to_blob_buf(key, b, 0, SSHKEY_SERIALIZE_DEFAULT);
961 sshkey_puts_opts(const struct sshkey *key, struct sshbuf *b,
962 enum sshkey_serialize_rep opts)
967 if ((tmp = sshbuf_new()) == NULL)
968 return SSH_ERR_ALLOC_FAIL;
969 r = to_blob_buf(key, tmp, 0, opts);
971 r = sshbuf_put_stringb(b, tmp);
977 sshkey_puts(const struct sshkey *key, struct sshbuf *b)
979 return sshkey_puts_opts(key, b, SSHKEY_SERIALIZE_DEFAULT);
983 sshkey_putb_plain(const struct sshkey *key, struct sshbuf *b)
985 return to_blob_buf(key, b, 1, SSHKEY_SERIALIZE_DEFAULT);
989 to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp, int force_plain,
990 enum sshkey_serialize_rep opts)
992 int ret = SSH_ERR_INTERNAL_ERROR;
994 struct sshbuf *b = NULL;
1000 if ((b = sshbuf_new()) == NULL)
1001 return SSH_ERR_ALLOC_FAIL;
1002 if ((ret = to_blob_buf(key, b, force_plain, opts)) != 0)
1004 len = sshbuf_len(b);
1007 if (blobp != NULL) {
1008 if ((*blobp = malloc(len)) == NULL) {
1009 ret = SSH_ERR_ALLOC_FAIL;
1012 memcpy(*blobp, sshbuf_ptr(b), len);
1021 sshkey_to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp)
1023 return to_blob(key, blobp, lenp, 0, SSHKEY_SERIALIZE_DEFAULT);
1027 sshkey_plain_to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp)
1029 return to_blob(key, blobp, lenp, 1, SSHKEY_SERIALIZE_DEFAULT);
1033 sshkey_fingerprint_raw(const struct sshkey *k, int dgst_alg,
1034 u_char **retp, size_t *lenp)
1036 u_char *blob = NULL, *ret = NULL;
1037 size_t blob_len = 0;
1038 int r = SSH_ERR_INTERNAL_ERROR;
1044 if (ssh_digest_bytes(dgst_alg) == 0) {
1045 r = SSH_ERR_INVALID_ARGUMENT;
1048 if ((r = to_blob(k, &blob, &blob_len, 1, SSHKEY_SERIALIZE_DEFAULT))
1051 if ((ret = calloc(1, SSH_DIGEST_MAX_LENGTH)) == NULL) {
1052 r = SSH_ERR_ALLOC_FAIL;
1055 if ((r = ssh_digest_memory(dgst_alg, blob, blob_len,
1056 ret, SSH_DIGEST_MAX_LENGTH)) != 0)
1064 *lenp = ssh_digest_bytes(dgst_alg);
1069 explicit_bzero(blob, blob_len);
1076 fingerprint_b64(const char *alg, u_char *dgst_raw, size_t dgst_raw_len)
1079 size_t plen = strlen(alg) + 1;
1080 size_t rlen = ((dgst_raw_len + 2) / 3) * 4 + plen + 1;
1083 if (dgst_raw_len > 65536 || (ret = calloc(1, rlen)) == NULL)
1085 strlcpy(ret, alg, rlen);
1086 strlcat(ret, ":", rlen);
1087 if (dgst_raw_len == 0)
1089 if ((r = b64_ntop(dgst_raw, dgst_raw_len,
1090 ret + plen, rlen - plen)) == -1) {
1091 freezero(ret, rlen);
1094 /* Trim padding characters from end */
1095 ret[strcspn(ret, "=")] = '\0';
1100 fingerprint_hex(const char *alg, u_char *dgst_raw, size_t dgst_raw_len)
1102 char *retval, hex[5];
1103 size_t i, rlen = dgst_raw_len * 3 + strlen(alg) + 2;
1105 if (dgst_raw_len > 65536 || (retval = calloc(1, rlen)) == NULL)
1107 strlcpy(retval, alg, rlen);
1108 strlcat(retval, ":", rlen);
1109 for (i = 0; i < dgst_raw_len; i++) {
1110 snprintf(hex, sizeof(hex), "%s%02x",
1111 i > 0 ? ":" : "", dgst_raw[i]);
1112 strlcat(retval, hex, rlen);
1118 fingerprint_bubblebabble(u_char *dgst_raw, size_t dgst_raw_len)
1120 char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' };
1121 char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm',
1122 'n', 'p', 'r', 's', 't', 'v', 'z', 'x' };
1123 u_int i, j = 0, rounds, seed = 1;
1126 rounds = (dgst_raw_len / 2) + 1;
1127 if ((retval = calloc(rounds, 6)) == NULL)
1130 for (i = 0; i < rounds; i++) {
1131 u_int idx0, idx1, idx2, idx3, idx4;
1132 if ((i + 1 < rounds) || (dgst_raw_len % 2 != 0)) {
1133 idx0 = (((((u_int)(dgst_raw[2 * i])) >> 6) & 3) +
1135 idx1 = (((u_int)(dgst_raw[2 * i])) >> 2) & 15;
1136 idx2 = ((((u_int)(dgst_raw[2 * i])) & 3) +
1138 retval[j++] = vowels[idx0];
1139 retval[j++] = consonants[idx1];
1140 retval[j++] = vowels[idx2];
1141 if ((i + 1) < rounds) {
1142 idx3 = (((u_int)(dgst_raw[(2 * i) + 1])) >> 4) & 15;
1143 idx4 = (((u_int)(dgst_raw[(2 * i) + 1]))) & 15;
1144 retval[j++] = consonants[idx3];
1146 retval[j++] = consonants[idx4];
1147 seed = ((seed * 5) +
1148 ((((u_int)(dgst_raw[2 * i])) * 7) +
1149 ((u_int)(dgst_raw[(2 * i) + 1])))) % 36;
1155 retval[j++] = vowels[idx0];
1156 retval[j++] = consonants[idx1];
1157 retval[j++] = vowels[idx2];
1166 * Draw an ASCII-Art representing the fingerprint so human brain can
1167 * profit from its built-in pattern recognition ability.
1168 * This technique is called "random art" and can be found in some
1169 * scientific publications like this original paper:
1171 * "Hash Visualization: a New Technique to improve Real-World Security",
1172 * Perrig A. and Song D., 1999, International Workshop on Cryptographic
1173 * Techniques and E-Commerce (CrypTEC '99)
1174 * sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf
1176 * The subject came up in a talk by Dan Kaminsky, too.
1178 * If you see the picture is different, the key is different.
1179 * If the picture looks the same, you still know nothing.
1181 * The algorithm used here is a worm crawling over a discrete plane,
1182 * leaving a trace (augmenting the field) everywhere it goes.
1183 * Movement is taken from dgst_raw 2bit-wise. Bumping into walls
1184 * makes the respective movement vector be ignored for this turn.
1185 * Graphs are not unambiguous, because circles in graphs can be
1186 * walked in either direction.
1190 * Field sizes for the random art. Have to be odd, so the starting point
1191 * can be in the exact middle of the picture, and FLDBASE should be >=8 .
1192 * Else pictures would be too dense, and drawing the frame would
1193 * fail, too, because the key type would not fit in anymore.
1196 #define FLDSIZE_Y (FLDBASE + 1)
1197 #define FLDSIZE_X (FLDBASE * 2 + 1)
1199 fingerprint_randomart(const char *alg, u_char *dgst_raw, size_t dgst_raw_len,
1200 const struct sshkey *k)
1203 * Chars to be used after each other every time the worm
1204 * intersects with itself. Matter of taste.
1206 char *augmentation_string = " .o+=*BOX@%&#/^SE";
1207 char *retval, *p, title[FLDSIZE_X], hash[FLDSIZE_X];
1208 u_char field[FLDSIZE_X][FLDSIZE_Y];
1209 size_t i, tlen, hlen;
1212 size_t len = strlen(augmentation_string) - 1;
1214 if ((retval = calloc((FLDSIZE_X + 3), (FLDSIZE_Y + 2))) == NULL)
1217 /* initialize field */
1218 memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char));
1222 /* process raw key */
1223 for (i = 0; i < dgst_raw_len; i++) {
1225 /* each byte conveys four 2-bit move commands */
1226 input = dgst_raw[i];
1227 for (b = 0; b < 4; b++) {
1228 /* evaluate 2 bit, rest is shifted later */
1229 x += (input & 0x1) ? 1 : -1;
1230 y += (input & 0x2) ? 1 : -1;
1232 /* assure we are still in bounds */
1235 x = MINIMUM(x, FLDSIZE_X - 1);
1236 y = MINIMUM(y, FLDSIZE_Y - 1);
1238 /* augment the field */
1239 if (field[x][y] < len - 2)
1245 /* mark starting point and end point*/
1246 field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1;
1249 /* assemble title */
1250 r = snprintf(title, sizeof(title), "[%s %u]",
1251 sshkey_type(k), sshkey_size(k));
1252 /* If [type size] won't fit, then try [type]; fits "[ED25519-CERT]" */
1253 if (r < 0 || r > (int)sizeof(title))
1254 r = snprintf(title, sizeof(title), "[%s]", sshkey_type(k));
1255 tlen = (r <= 0) ? 0 : strlen(title);
1257 /* assemble hash ID. */
1258 r = snprintf(hash, sizeof(hash), "[%s]", alg);
1259 hlen = (r <= 0) ? 0 : strlen(hash);
1261 /* output upper border */
1264 for (i = 0; i < (FLDSIZE_X - tlen) / 2; i++)
1266 memcpy(p, title, tlen);
1268 for (i += tlen; i < FLDSIZE_X; i++)
1273 /* output content */
1274 for (y = 0; y < FLDSIZE_Y; y++) {
1276 for (x = 0; x < FLDSIZE_X; x++)
1277 *p++ = augmentation_string[MINIMUM(field[x][y], len)];
1282 /* output lower border */
1284 for (i = 0; i < (FLDSIZE_X - hlen) / 2; i++)
1286 memcpy(p, hash, hlen);
1288 for (i += hlen; i < FLDSIZE_X; i++)
1296 sshkey_fingerprint(const struct sshkey *k, int dgst_alg,
1297 enum sshkey_fp_rep dgst_rep)
1299 char *retval = NULL;
1301 size_t dgst_raw_len;
1303 if (sshkey_fingerprint_raw(k, dgst_alg, &dgst_raw, &dgst_raw_len) != 0)
1306 case SSH_FP_DEFAULT:
1307 if (dgst_alg == SSH_DIGEST_MD5) {
1308 retval = fingerprint_hex(ssh_digest_alg_name(dgst_alg),
1309 dgst_raw, dgst_raw_len);
1311 retval = fingerprint_b64(ssh_digest_alg_name(dgst_alg),
1312 dgst_raw, dgst_raw_len);
1316 retval = fingerprint_hex(ssh_digest_alg_name(dgst_alg),
1317 dgst_raw, dgst_raw_len);
1320 retval = fingerprint_b64(ssh_digest_alg_name(dgst_alg),
1321 dgst_raw, dgst_raw_len);
1323 case SSH_FP_BUBBLEBABBLE:
1324 retval = fingerprint_bubblebabble(dgst_raw, dgst_raw_len);
1326 case SSH_FP_RANDOMART:
1327 retval = fingerprint_randomart(ssh_digest_alg_name(dgst_alg),
1328 dgst_raw, dgst_raw_len, k);
1331 explicit_bzero(dgst_raw, dgst_raw_len);
1335 explicit_bzero(dgst_raw, dgst_raw_len);
1341 peek_type_nid(const char *s, size_t l, int *nid)
1343 const struct keytype *kt;
1345 for (kt = keytypes; kt->type != -1; kt++) {
1346 if (kt->name == NULL || strlen(kt->name) != l)
1348 if (memcmp(s, kt->name, l) == 0) {
1350 if (kt->type == KEY_ECDSA || kt->type == KEY_ECDSA_CERT)
1358 /* XXX this can now be made const char * */
1360 sshkey_read(struct sshkey *ret, char **cpp)
1363 char *cp, *blobcopy;
1365 int r, type, curve_nid = -1;
1366 struct sshbuf *blob;
1369 return SSH_ERR_INVALID_ARGUMENT;
1371 switch (ret->type) {
1378 case KEY_ECDSA_CERT:
1380 case KEY_ED25519_CERT:
1384 #endif /* WITH_XMSS */
1387 return SSH_ERR_INVALID_ARGUMENT;
1392 space = strcspn(cp, " \t");
1393 if (space == strlen(cp))
1394 return SSH_ERR_INVALID_FORMAT;
1395 if ((type = peek_type_nid(cp, space, &curve_nid)) == KEY_UNSPEC)
1396 return SSH_ERR_INVALID_FORMAT;
1398 /* skip whitespace */
1399 for (cp += space; *cp == ' ' || *cp == '\t'; cp++)
1402 return SSH_ERR_INVALID_FORMAT;
1403 if (ret->type != KEY_UNSPEC && ret->type != type)
1404 return SSH_ERR_KEY_TYPE_MISMATCH;
1405 if ((blob = sshbuf_new()) == NULL)
1406 return SSH_ERR_ALLOC_FAIL;
1408 /* find end of keyblob and decode */
1409 space = strcspn(cp, " \t");
1410 if ((blobcopy = strndup(cp, space)) == NULL) {
1412 return SSH_ERR_ALLOC_FAIL;
1414 if ((r = sshbuf_b64tod(blob, blobcopy)) != 0) {
1420 if ((r = sshkey_fromb(blob, &k)) != 0) {
1426 /* skip whitespace and leave cp at start of comment */
1427 for (cp += space; *cp == ' ' || *cp == '\t'; cp++)
1430 /* ensure type of blob matches type at start of line */
1431 if (k->type != type) {
1433 return SSH_ERR_KEY_TYPE_MISMATCH;
1435 if (sshkey_type_plain(type) == KEY_ECDSA && curve_nid != k->ecdsa_nid) {
1437 return SSH_ERR_EC_CURVE_MISMATCH;
1440 /* Fill in ret from parsed key */
1442 if (sshkey_is_cert(ret)) {
1443 if (!sshkey_is_cert(k)) {
1445 return SSH_ERR_EXPECTED_CERT;
1447 if (ret->cert != NULL)
1448 cert_free(ret->cert);
1449 ret->cert = k->cert;
1452 switch (sshkey_type_plain(ret->type)) {
1459 RSA_print_fp(stderr, ret->rsa, 8);
1467 DSA_print_fp(stderr, ret->dsa, 8);
1470 # ifdef OPENSSL_HAS_ECC
1472 EC_KEY_free(ret->ecdsa);
1473 ret->ecdsa = k->ecdsa;
1474 ret->ecdsa_nid = k->ecdsa_nid;
1478 sshkey_dump_ec_key(ret->ecdsa);
1481 # endif /* OPENSSL_HAS_ECC */
1482 #endif /* WITH_OPENSSL */
1484 freezero(ret->ed25519_pk, ED25519_PK_SZ);
1485 ret->ed25519_pk = k->ed25519_pk;
1486 k->ed25519_pk = NULL;
1494 ret->xmss_pk = k->xmss_pk;
1496 free(ret->xmss_state);
1497 ret->xmss_state = k->xmss_state;
1498 k->xmss_state = NULL;
1499 free(ret->xmss_name);
1500 ret->xmss_name = k->xmss_name;
1501 k->xmss_name = NULL;
1502 free(ret->xmss_filename);
1503 ret->xmss_filename = k->xmss_filename;
1504 k->xmss_filename = NULL;
1509 #endif /* WITH_XMSS */
1512 return SSH_ERR_INTERNAL_ERROR;
1523 sshkey_to_base64(const struct sshkey *key, char **b64p)
1525 int r = SSH_ERR_INTERNAL_ERROR;
1526 struct sshbuf *b = NULL;
1531 if ((b = sshbuf_new()) == NULL)
1532 return SSH_ERR_ALLOC_FAIL;
1533 if ((r = sshkey_putb(key, b)) != 0)
1535 if ((uu = sshbuf_dtob64(b)) == NULL) {
1536 r = SSH_ERR_ALLOC_FAIL;
1552 sshkey_format_text(const struct sshkey *key, struct sshbuf *b)
1554 int r = SSH_ERR_INTERNAL_ERROR;
1557 if ((r = sshkey_to_base64(key, &uu)) != 0)
1559 if ((r = sshbuf_putf(b, "%s %s",
1560 sshkey_ssh_name(key), uu)) != 0)
1569 sshkey_write(const struct sshkey *key, FILE *f)
1571 struct sshbuf *b = NULL;
1572 int r = SSH_ERR_INTERNAL_ERROR;
1574 if ((b = sshbuf_new()) == NULL)
1575 return SSH_ERR_ALLOC_FAIL;
1576 if ((r = sshkey_format_text(key, b)) != 0)
1578 if (fwrite(sshbuf_ptr(b), sshbuf_len(b), 1, f) != 1) {
1581 r = SSH_ERR_SYSTEM_ERROR;
1592 sshkey_cert_type(const struct sshkey *k)
1594 switch (k->cert->type) {
1595 case SSH2_CERT_TYPE_USER:
1597 case SSH2_CERT_TYPE_HOST:
1606 rsa_generate_private_key(u_int bits, RSA **rsap)
1608 RSA *private = NULL;
1610 int ret = SSH_ERR_INTERNAL_ERROR;
1613 return SSH_ERR_INVALID_ARGUMENT;
1614 if (bits < SSH_RSA_MINIMUM_MODULUS_SIZE ||
1615 bits > SSHBUF_MAX_BIGNUM * 8)
1616 return SSH_ERR_KEY_LENGTH;
1618 if ((private = RSA_new()) == NULL || (f4 = BN_new()) == NULL) {
1619 ret = SSH_ERR_ALLOC_FAIL;
1622 if (!BN_set_word(f4, RSA_F4) ||
1623 !RSA_generate_key_ex(private, bits, f4, NULL)) {
1624 ret = SSH_ERR_LIBCRYPTO_ERROR;
1637 dsa_generate_private_key(u_int bits, DSA **dsap)
1640 int ret = SSH_ERR_INTERNAL_ERROR;
1643 return SSH_ERR_INVALID_ARGUMENT;
1645 return SSH_ERR_KEY_LENGTH;
1646 if ((private = DSA_new()) == NULL) {
1647 ret = SSH_ERR_ALLOC_FAIL;
1651 if (!DSA_generate_parameters_ex(private, bits, NULL, 0, NULL,
1652 NULL, NULL) || !DSA_generate_key(private)) {
1653 ret = SSH_ERR_LIBCRYPTO_ERROR;
1664 # ifdef OPENSSL_HAS_ECC
1666 sshkey_ecdsa_key_to_nid(EC_KEY *k)
1670 NID_X9_62_prime256v1,
1672 # ifdef OPENSSL_HAS_NISTP521
1674 # endif /* OPENSSL_HAS_NISTP521 */
1680 const EC_GROUP *g = EC_KEY_get0_group(k);
1683 * The group may be stored in a ASN.1 encoded private key in one of two
1684 * ways: as a "named group", which is reconstituted by ASN.1 object ID
1685 * or explicit group parameters encoded into the key blob. Only the
1686 * "named group" case sets the group NID for us, but we can figure
1687 * it out for the other case by comparing against all the groups that
1690 if ((nid = EC_GROUP_get_curve_name(g)) > 0)
1692 if ((bnctx = BN_CTX_new()) == NULL)
1694 for (i = 0; nids[i] != -1; i++) {
1695 if ((eg = EC_GROUP_new_by_curve_name(nids[i])) == NULL) {
1699 if (EC_GROUP_cmp(g, eg, bnctx) == 0)
1704 if (nids[i] != -1) {
1705 /* Use the group with the NID attached */
1706 EC_GROUP_set_asn1_flag(eg, OPENSSL_EC_NAMED_CURVE);
1707 if (EC_KEY_set_group(k, eg) != 1) {
1716 ecdsa_generate_private_key(u_int bits, int *nid, EC_KEY **ecdsap)
1719 int ret = SSH_ERR_INTERNAL_ERROR;
1721 if (nid == NULL || ecdsap == NULL)
1722 return SSH_ERR_INVALID_ARGUMENT;
1723 if ((*nid = sshkey_ecdsa_bits_to_nid(bits)) == -1)
1724 return SSH_ERR_KEY_LENGTH;
1726 if ((private = EC_KEY_new_by_curve_name(*nid)) == NULL) {
1727 ret = SSH_ERR_ALLOC_FAIL;
1730 if (EC_KEY_generate_key(private) != 1) {
1731 ret = SSH_ERR_LIBCRYPTO_ERROR;
1734 EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE);
1739 EC_KEY_free(private);
1742 # endif /* OPENSSL_HAS_ECC */
1743 #endif /* WITH_OPENSSL */
1746 sshkey_generate(int type, u_int bits, struct sshkey **keyp)
1749 int ret = SSH_ERR_INTERNAL_ERROR;
1752 return SSH_ERR_INVALID_ARGUMENT;
1754 if ((k = sshkey_new(KEY_UNSPEC)) == NULL)
1755 return SSH_ERR_ALLOC_FAIL;
1758 if ((k->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL ||
1759 (k->ed25519_sk = malloc(ED25519_SK_SZ)) == NULL) {
1760 ret = SSH_ERR_ALLOC_FAIL;
1763 crypto_sign_ed25519_keypair(k->ed25519_pk, k->ed25519_sk);
1768 ret = sshkey_xmss_generate_private_key(k, bits);
1770 #endif /* WITH_XMSS */
1773 ret = dsa_generate_private_key(bits, &k->dsa);
1775 # ifdef OPENSSL_HAS_ECC
1777 ret = ecdsa_generate_private_key(bits, &k->ecdsa_nid,
1780 # endif /* OPENSSL_HAS_ECC */
1782 ret = rsa_generate_private_key(bits, &k->rsa);
1784 #endif /* WITH_OPENSSL */
1786 ret = SSH_ERR_INVALID_ARGUMENT;
1797 sshkey_cert_copy(const struct sshkey *from_key, struct sshkey *to_key)
1800 const struct sshkey_cert *from;
1801 struct sshkey_cert *to;
1802 int ret = SSH_ERR_INTERNAL_ERROR;
1804 if (to_key->cert != NULL) {
1805 cert_free(to_key->cert);
1806 to_key->cert = NULL;
1809 if ((from = from_key->cert) == NULL)
1810 return SSH_ERR_INVALID_ARGUMENT;
1812 if ((to = to_key->cert = cert_new()) == NULL)
1813 return SSH_ERR_ALLOC_FAIL;
1815 if ((ret = sshbuf_putb(to->certblob, from->certblob)) != 0 ||
1816 (ret = sshbuf_putb(to->critical, from->critical)) != 0 ||
1817 (ret = sshbuf_putb(to->extensions, from->extensions)) != 0)
1820 to->serial = from->serial;
1821 to->type = from->type;
1822 if (from->key_id == NULL)
1824 else if ((to->key_id = strdup(from->key_id)) == NULL)
1825 return SSH_ERR_ALLOC_FAIL;
1826 to->valid_after = from->valid_after;
1827 to->valid_before = from->valid_before;
1828 if (from->signature_key == NULL)
1829 to->signature_key = NULL;
1830 else if ((ret = sshkey_from_private(from->signature_key,
1831 &to->signature_key)) != 0)
1834 if (from->nprincipals > SSHKEY_CERT_MAX_PRINCIPALS)
1835 return SSH_ERR_INVALID_ARGUMENT;
1836 if (from->nprincipals > 0) {
1837 if ((to->principals = calloc(from->nprincipals,
1838 sizeof(*to->principals))) == NULL)
1839 return SSH_ERR_ALLOC_FAIL;
1840 for (i = 0; i < from->nprincipals; i++) {
1841 to->principals[i] = strdup(from->principals[i]);
1842 if (to->principals[i] == NULL) {
1843 to->nprincipals = i;
1844 return SSH_ERR_ALLOC_FAIL;
1848 to->nprincipals = from->nprincipals;
1853 sshkey_from_private(const struct sshkey *k, struct sshkey **pkp)
1855 struct sshkey *n = NULL;
1856 int ret = SSH_ERR_INTERNAL_ERROR;
1863 if ((n = sshkey_new(k->type)) == NULL)
1864 return SSH_ERR_ALLOC_FAIL;
1866 const BIGNUM *p, *q, *g, *pub_key, *priv_key;
1867 BIGNUM *cp=NULL, *cq=NULL, *cg=NULL, *cpub_key=NULL;
1868 DSA_get0_pqg(k->dsa, &p, &q, &g);
1869 DSA_get0_key(k->dsa, &pub_key, &priv_key);
1870 if ((cp = BN_dup(p)) == NULL ||
1871 (cq = BN_dup(q)) == NULL ||
1872 (cg = BN_dup(g)) == NULL ||
1873 (cpub_key = BN_dup(pub_key)) == NULL) {
1874 BN_free(cp); BN_free(cq); BN_free(cg);
1877 return SSH_ERR_ALLOC_FAIL;
1879 if (DSA_set0_pqg(n->dsa, cp, cq, cg) == 0)
1881 cp = cq = cg = NULL;
1882 if (DSA_set0_key(n->dsa, cpub_key, NULL) == 0) {
1884 BN_free(cp); BN_free(cq); BN_free(cg);
1887 return SSH_ERR_LIBCRYPTO_ERROR;
1892 # ifdef OPENSSL_HAS_ECC
1894 case KEY_ECDSA_CERT:
1895 if ((n = sshkey_new(k->type)) == NULL)
1896 return SSH_ERR_ALLOC_FAIL;
1897 n->ecdsa_nid = k->ecdsa_nid;
1898 n->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid);
1899 if (n->ecdsa == NULL) {
1901 return SSH_ERR_ALLOC_FAIL;
1903 if (EC_KEY_set_public_key(n->ecdsa,
1904 EC_KEY_get0_public_key(k->ecdsa)) != 1) {
1906 return SSH_ERR_LIBCRYPTO_ERROR;
1909 # endif /* OPENSSL_HAS_ECC */
1912 if ((n = sshkey_new(k->type)) == NULL)
1913 return SSH_ERR_ALLOC_FAIL;
1915 const BIGNUM *nn, *e, *d;
1916 BIGNUM *cn=NULL, *ce=NULL;
1917 RSA_get0_key(k->rsa, &nn, &e, &d);
1918 if ((cn = BN_dup(nn)) == NULL ||
1919 (ce = BN_dup(e)) == NULL ) {
1920 BN_free(cn); BN_free(ce);
1922 return SSH_ERR_ALLOC_FAIL;
1924 if (RSA_set0_key(n->rsa, cn, ce, NULL) == 0) {
1925 BN_free(cn); BN_free(ce);
1927 return SSH_ERR_LIBCRYPTO_ERROR;
1932 #endif /* WITH_OPENSSL */
1934 case KEY_ED25519_CERT:
1935 if ((n = sshkey_new(k->type)) == NULL)
1936 return SSH_ERR_ALLOC_FAIL;
1937 if (k->ed25519_pk != NULL) {
1938 if ((n->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) {
1940 return SSH_ERR_ALLOC_FAIL;
1942 memcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ);
1948 if ((n = sshkey_new(k->type)) == NULL)
1949 return SSH_ERR_ALLOC_FAIL;
1950 if ((ret = sshkey_xmss_init(n, k->xmss_name)) != 0) {
1954 if (k->xmss_pk != NULL) {
1955 size_t pklen = sshkey_xmss_pklen(k);
1956 if (pklen == 0 || sshkey_xmss_pklen(n) != pklen) {
1958 return SSH_ERR_INTERNAL_ERROR;
1960 if ((n->xmss_pk = malloc(pklen)) == NULL) {
1962 return SSH_ERR_ALLOC_FAIL;
1964 memcpy(n->xmss_pk, k->xmss_pk, pklen);
1967 #endif /* WITH_XMSS */
1969 return SSH_ERR_KEY_TYPE_UNKNOWN;
1971 if (sshkey_is_cert(k)) {
1972 if ((ret = sshkey_cert_copy(k, n)) != 0) {
1982 cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf)
1984 struct sshbuf *principals = NULL, *crit = NULL;
1985 struct sshbuf *exts = NULL, *ca = NULL;
1987 size_t signed_len = 0, slen = 0, kidlen = 0;
1988 int ret = SSH_ERR_INTERNAL_ERROR;
1990 /* Copy the entire key blob for verification and later serialisation */
1991 if ((ret = sshbuf_putb(key->cert->certblob, certbuf)) != 0)
1994 /* Parse body of certificate up to signature */
1995 if ((ret = sshbuf_get_u64(b, &key->cert->serial)) != 0 ||
1996 (ret = sshbuf_get_u32(b, &key->cert->type)) != 0 ||
1997 (ret = sshbuf_get_cstring(b, &key->cert->key_id, &kidlen)) != 0 ||
1998 (ret = sshbuf_froms(b, &principals)) != 0 ||
1999 (ret = sshbuf_get_u64(b, &key->cert->valid_after)) != 0 ||
2000 (ret = sshbuf_get_u64(b, &key->cert->valid_before)) != 0 ||
2001 (ret = sshbuf_froms(b, &crit)) != 0 ||
2002 (ret = sshbuf_froms(b, &exts)) != 0 ||
2003 (ret = sshbuf_get_string_direct(b, NULL, NULL)) != 0 ||
2004 (ret = sshbuf_froms(b, &ca)) != 0) {
2005 /* XXX debug print error for ret */
2006 ret = SSH_ERR_INVALID_FORMAT;
2010 /* Signature is left in the buffer so we can calculate this length */
2011 signed_len = sshbuf_len(key->cert->certblob) - sshbuf_len(b);
2013 if ((ret = sshbuf_get_string(b, &sig, &slen)) != 0) {
2014 ret = SSH_ERR_INVALID_FORMAT;
2018 if (key->cert->type != SSH2_CERT_TYPE_USER &&
2019 key->cert->type != SSH2_CERT_TYPE_HOST) {
2020 ret = SSH_ERR_KEY_CERT_UNKNOWN_TYPE;
2024 /* Parse principals section */
2025 while (sshbuf_len(principals) > 0) {
2026 char *principal = NULL;
2027 char **oprincipals = NULL;
2029 if (key->cert->nprincipals >= SSHKEY_CERT_MAX_PRINCIPALS) {
2030 ret = SSH_ERR_INVALID_FORMAT;
2033 if ((ret = sshbuf_get_cstring(principals, &principal,
2035 ret = SSH_ERR_INVALID_FORMAT;
2038 oprincipals = key->cert->principals;
2039 key->cert->principals = recallocarray(key->cert->principals,
2040 key->cert->nprincipals, key->cert->nprincipals + 1,
2041 sizeof(*key->cert->principals));
2042 if (key->cert->principals == NULL) {
2044 key->cert->principals = oprincipals;
2045 ret = SSH_ERR_ALLOC_FAIL;
2048 key->cert->principals[key->cert->nprincipals++] = principal;
2052 * Stash a copies of the critical options and extensions sections
2055 if ((ret = sshbuf_putb(key->cert->critical, crit)) != 0 ||
2057 (ret = sshbuf_putb(key->cert->extensions, exts)) != 0))
2061 * Validate critical options and extensions sections format.
2063 while (sshbuf_len(crit) != 0) {
2064 if ((ret = sshbuf_get_string_direct(crit, NULL, NULL)) != 0 ||
2065 (ret = sshbuf_get_string_direct(crit, NULL, NULL)) != 0) {
2066 sshbuf_reset(key->cert->critical);
2067 ret = SSH_ERR_INVALID_FORMAT;
2071 while (exts != NULL && sshbuf_len(exts) != 0) {
2072 if ((ret = sshbuf_get_string_direct(exts, NULL, NULL)) != 0 ||
2073 (ret = sshbuf_get_string_direct(exts, NULL, NULL)) != 0) {
2074 sshbuf_reset(key->cert->extensions);
2075 ret = SSH_ERR_INVALID_FORMAT;
2080 /* Parse CA key and check signature */
2081 if (sshkey_from_blob_internal(ca, &key->cert->signature_key, 0) != 0) {
2082 ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
2085 if (!sshkey_type_is_valid_ca(key->cert->signature_key->type)) {
2086 ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
2089 if ((ret = sshkey_verify(key->cert->signature_key, sig, slen,
2090 sshbuf_ptr(key->cert->certblob), signed_len, NULL, 0)) != 0)
2099 sshbuf_free(principals);
2105 sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
2108 int type, ret = SSH_ERR_INTERNAL_ERROR;
2109 char *ktype = NULL, *curve = NULL, *xmss_name = NULL;
2110 struct sshkey *key = NULL;
2113 struct sshbuf *copy;
2114 #if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
2116 #endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */
2118 #ifdef DEBUG_PK /* XXX */
2119 sshbuf_dump(b, stderr);
2123 if ((copy = sshbuf_fromb(b)) == NULL) {
2124 ret = SSH_ERR_ALLOC_FAIL;
2127 if (sshbuf_get_cstring(b, &ktype, NULL) != 0) {
2128 ret = SSH_ERR_INVALID_FORMAT;
2132 type = sshkey_type_from_name(ktype);
2133 if (!allow_cert && sshkey_type_is_cert(type)) {
2134 ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
2141 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
2142 ret = SSH_ERR_INVALID_FORMAT;
2147 if ((key = sshkey_new(type)) == NULL) {
2148 ret = SSH_ERR_ALLOC_FAIL;
2152 BIGNUM *e=NULL, *n=NULL;
2153 if ((e = BN_new()) == NULL ||
2154 (n = BN_new()) == NULL ) {
2155 ret = SSH_ERR_ALLOC_FAIL;
2156 BN_free(e); BN_free(n);
2159 if (sshbuf_get_bignum2(b, e) != 0 ||
2160 sshbuf_get_bignum2(b, n) != 0) {
2161 ret = SSH_ERR_INVALID_FORMAT;
2162 BN_free(e); BN_free(n);
2165 if (RSA_set0_key(key->rsa, n, e, NULL) == 0) {
2166 BN_free(e); BN_free(n);
2167 return SSH_ERR_LIBCRYPTO_ERROR;
2171 if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
2172 ret = SSH_ERR_KEY_LENGTH;
2176 RSA_print_fp(stderr, key->rsa, 8);
2181 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
2182 ret = SSH_ERR_INVALID_FORMAT;
2187 if ((key = sshkey_new(type)) == NULL) {
2188 ret = SSH_ERR_ALLOC_FAIL;
2192 BIGNUM *p=NULL, *q=NULL, *g=NULL, *pub_key=NULL;
2193 if ((p = BN_new()) == NULL ||
2194 (q = BN_new()) == NULL ||
2195 (g = BN_new()) == NULL ||
2196 (pub_key = BN_new()) == NULL) {
2197 ret = SSH_ERR_ALLOC_FAIL;
2200 if (sshbuf_get_bignum2(b, p) != 0 ||
2201 sshbuf_get_bignum2(b, q) != 0 ||
2202 sshbuf_get_bignum2(b, g) != 0 ||
2203 sshbuf_get_bignum2(b, pub_key) != 0) {
2204 ret = SSH_ERR_INVALID_FORMAT;
2207 if (DSA_set0_pqg(key->dsa, p, q, g) == 0) {
2208 ret = SSH_ERR_LIBCRYPTO_ERROR;
2212 if (DSA_set0_key(key->dsa, pub_key, NULL) == 0) {
2213 ret = SSH_ERR_LIBCRYPTO_ERROR;
2215 BN_free(p); BN_free(q); BN_free(g);
2222 DSA_print_fp(stderr, key->dsa, 8);
2225 case KEY_ECDSA_CERT:
2227 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
2228 ret = SSH_ERR_INVALID_FORMAT;
2232 # ifdef OPENSSL_HAS_ECC
2234 if ((key = sshkey_new(type)) == NULL) {
2235 ret = SSH_ERR_ALLOC_FAIL;
2238 key->ecdsa_nid = sshkey_ecdsa_nid_from_name(ktype);
2239 if (sshbuf_get_cstring(b, &curve, NULL) != 0) {
2240 ret = SSH_ERR_INVALID_FORMAT;
2243 if (key->ecdsa_nid != sshkey_curve_name_to_nid(curve)) {
2244 ret = SSH_ERR_EC_CURVE_MISMATCH;
2247 EC_KEY_free(key->ecdsa);
2248 if ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid))
2250 ret = SSH_ERR_EC_CURVE_INVALID;
2253 if ((q = EC_POINT_new(EC_KEY_get0_group(key->ecdsa))) == NULL) {
2254 ret = SSH_ERR_ALLOC_FAIL;
2257 if (sshbuf_get_ec(b, q, EC_KEY_get0_group(key->ecdsa)) != 0) {
2258 ret = SSH_ERR_INVALID_FORMAT;
2261 if (sshkey_ec_validate_public(EC_KEY_get0_group(key->ecdsa),
2263 ret = SSH_ERR_KEY_INVALID_EC_VALUE;
2266 if (EC_KEY_set_public_key(key->ecdsa, q) != 1) {
2267 /* XXX assume it is a allocation error */
2268 ret = SSH_ERR_ALLOC_FAIL;
2272 sshkey_dump_ec_point(EC_KEY_get0_group(key->ecdsa), q);
2275 # endif /* OPENSSL_HAS_ECC */
2276 #endif /* WITH_OPENSSL */
2277 case KEY_ED25519_CERT:
2279 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
2280 ret = SSH_ERR_INVALID_FORMAT;
2285 if ((ret = sshbuf_get_string(b, &pk, &len)) != 0)
2287 if (len != ED25519_PK_SZ) {
2288 ret = SSH_ERR_INVALID_FORMAT;
2291 if ((key = sshkey_new(type)) == NULL) {
2292 ret = SSH_ERR_ALLOC_FAIL;
2295 key->ed25519_pk = pk;
2301 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
2302 ret = SSH_ERR_INVALID_FORMAT;
2307 if ((ret = sshbuf_get_cstring(b, &xmss_name, NULL)) != 0)
2309 if ((key = sshkey_new(type)) == NULL) {
2310 ret = SSH_ERR_ALLOC_FAIL;
2313 if ((ret = sshkey_xmss_init(key, xmss_name)) != 0)
2315 if ((ret = sshbuf_get_string(b, &pk, &len)) != 0)
2317 if (len == 0 || len != sshkey_xmss_pklen(key)) {
2318 ret = SSH_ERR_INVALID_FORMAT;
2323 if (type != KEY_XMSS_CERT &&
2324 (ret = sshkey_xmss_deserialize_pk_info(key, b)) != 0)
2327 #endif /* WITH_XMSS */
2330 ret = SSH_ERR_KEY_TYPE_UNKNOWN;
2334 /* Parse certificate potion */
2335 if (sshkey_is_cert(key) && (ret = cert_parse(b, key, copy)) != 0)
2338 if (key != NULL && sshbuf_len(b) != 0) {
2339 ret = SSH_ERR_INVALID_FORMAT;
2354 #if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
2356 #endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */
2361 sshkey_from_blob(const u_char *blob, size_t blen, struct sshkey **keyp)
2366 if ((b = sshbuf_from(blob, blen)) == NULL)
2367 return SSH_ERR_ALLOC_FAIL;
2368 r = sshkey_from_blob_internal(b, keyp, 1);
2374 sshkey_fromb(struct sshbuf *b, struct sshkey **keyp)
2376 return sshkey_from_blob_internal(b, keyp, 1);
2380 sshkey_froms(struct sshbuf *buf, struct sshkey **keyp)
2385 if ((r = sshbuf_froms(buf, &b)) != 0)
2387 r = sshkey_from_blob_internal(b, keyp, 1);
2393 sshkey_sigtype(const u_char *sig, size_t siglen, char **sigtypep)
2396 struct sshbuf *b = NULL;
2397 char *sigtype = NULL;
2399 if (sigtypep != NULL)
2401 if ((b = sshbuf_from(sig, siglen)) == NULL)
2402 return SSH_ERR_ALLOC_FAIL;
2403 if ((r = sshbuf_get_cstring(b, &sigtype, NULL)) != 0)
2406 if (sigtypep != NULL) {
2407 *sigtypep = sigtype;
2418 sshkey_sign(const struct sshkey *key,
2419 u_char **sigp, size_t *lenp,
2420 const u_char *data, size_t datalen, const char *alg, u_int compat)
2426 if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE)
2427 return SSH_ERR_INVALID_ARGUMENT;
2428 switch (key->type) {
2432 return ssh_dss_sign(key, sigp, lenp, data, datalen, compat);
2433 # ifdef OPENSSL_HAS_ECC
2434 case KEY_ECDSA_CERT:
2436 return ssh_ecdsa_sign(key, sigp, lenp, data, datalen, compat);
2437 # endif /* OPENSSL_HAS_ECC */
2440 return ssh_rsa_sign(key, sigp, lenp, data, datalen, alg);
2441 #endif /* WITH_OPENSSL */
2443 case KEY_ED25519_CERT:
2444 return ssh_ed25519_sign(key, sigp, lenp, data, datalen, compat);
2448 return ssh_xmss_sign(key, sigp, lenp, data, datalen, compat);
2449 #endif /* WITH_XMSS */
2451 return SSH_ERR_KEY_TYPE_UNKNOWN;
2456 * ssh_key_verify returns 0 for a correct signature and < 0 on error.
2457 * If "alg" specified, then the signature must use that algorithm.
2460 sshkey_verify(const struct sshkey *key,
2461 const u_char *sig, size_t siglen,
2462 const u_char *data, size_t dlen, const char *alg, u_int compat)
2464 if (siglen == 0 || dlen > SSH_KEY_MAX_SIGN_DATA_SIZE)
2465 return SSH_ERR_INVALID_ARGUMENT;
2466 switch (key->type) {
2470 return ssh_dss_verify(key, sig, siglen, data, dlen, compat);
2471 # ifdef OPENSSL_HAS_ECC
2472 case KEY_ECDSA_CERT:
2474 return ssh_ecdsa_verify(key, sig, siglen, data, dlen, compat);
2475 # endif /* OPENSSL_HAS_ECC */
2478 return ssh_rsa_verify(key, sig, siglen, data, dlen, alg);
2479 #endif /* WITH_OPENSSL */
2481 case KEY_ED25519_CERT:
2482 return ssh_ed25519_verify(key, sig, siglen, data, dlen, compat);
2486 return ssh_xmss_verify(key, sig, siglen, data, dlen, compat);
2487 #endif /* WITH_XMSS */
2489 return SSH_ERR_KEY_TYPE_UNKNOWN;
2493 /* Converts a private to a public key */
2495 sshkey_demote(const struct sshkey *k, struct sshkey **dkp)
2498 int ret = SSH_ERR_INTERNAL_ERROR;
2501 if ((pk = calloc(1, sizeof(*pk))) == NULL)
2502 return SSH_ERR_ALLOC_FAIL;
2504 pk->flags = k->flags;
2505 pk->ecdsa_nid = k->ecdsa_nid;
2509 pk->ed25519_pk = NULL;
2510 pk->ed25519_sk = NULL;
2517 if ((ret = sshkey_cert_copy(k, pk)) != 0)
2521 if ((pk->rsa = RSA_new()) == NULL ){
2522 ret = SSH_ERR_ALLOC_FAIL;
2526 const BIGNUM *ke, *kn;
2527 BIGNUM *pke=NULL, *pkn=NULL;
2528 RSA_get0_key(k->rsa, &kn, &ke, NULL);
2529 if ((pke = BN_dup(ke)) == NULL ||
2530 (pkn = BN_dup(kn)) == NULL) {
2531 ret = SSH_ERR_ALLOC_FAIL;
2532 BN_free(pke); BN_free(pkn);
2535 if (RSA_set0_key(pk->rsa, pkn, pke, NULL) == 0) {
2536 ret = SSH_ERR_LIBCRYPTO_ERROR;
2537 BN_free(pke); BN_free(pkn);
2544 if ((ret = sshkey_cert_copy(k, pk)) != 0)
2548 if ((pk->dsa = DSA_new()) == NULL ) {
2549 ret = SSH_ERR_ALLOC_FAIL;
2553 const BIGNUM *kp, *kq, *kg, *kpub_key;
2554 BIGNUM *pkp=NULL, *pkq=NULL, *pkg=NULL, *pkpub_key=NULL;
2555 DSA_get0_pqg(k->dsa, &kp, &kq, &kg);
2556 DSA_get0_key(k->dsa, &kpub_key, NULL);
2557 if ((pkp = BN_dup(kp)) == NULL ||
2558 (pkq = BN_dup(kq)) == NULL ||
2559 (pkg = BN_dup(kg)) == NULL ||
2560 (pkpub_key = BN_dup(kpub_key)) == NULL) {
2561 ret = SSH_ERR_ALLOC_FAIL;
2564 if (DSA_set0_pqg(pk->dsa, pkp, pkq, pkg) == 0) {
2565 ret = SSH_ERR_LIBCRYPTO_ERROR;
2568 pkp = pkq = pkg = NULL;
2569 if (DSA_set0_key(pk->dsa, pkpub_key, NULL) == 0) {
2570 ret = SSH_ERR_LIBCRYPTO_ERROR;
2572 BN_free(pkp); BN_free(pkq); BN_free(pkg);
2579 case KEY_ECDSA_CERT:
2580 if ((ret = sshkey_cert_copy(k, pk)) != 0)
2583 # ifdef OPENSSL_HAS_ECC
2585 pk->ecdsa = EC_KEY_new_by_curve_name(pk->ecdsa_nid);
2586 if (pk->ecdsa == NULL) {
2587 ret = SSH_ERR_ALLOC_FAIL;
2590 if (EC_KEY_set_public_key(pk->ecdsa,
2591 EC_KEY_get0_public_key(k->ecdsa)) != 1) {
2592 ret = SSH_ERR_LIBCRYPTO_ERROR;
2596 # endif /* OPENSSL_HAS_ECC */
2597 #endif /* WITH_OPENSSL */
2598 case KEY_ED25519_CERT:
2599 if ((ret = sshkey_cert_copy(k, pk)) != 0)
2603 if (k->ed25519_pk != NULL) {
2604 if ((pk->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) {
2605 ret = SSH_ERR_ALLOC_FAIL;
2608 memcpy(pk->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ);
2613 if ((ret = sshkey_cert_copy(k, pk)) != 0)
2617 if ((ret = sshkey_xmss_init(pk, k->xmss_name)) != 0)
2619 if (k->xmss_pk != NULL) {
2620 size_t pklen = sshkey_xmss_pklen(k);
2622 if (pklen == 0 || sshkey_xmss_pklen(pk) != pklen) {
2623 ret = SSH_ERR_INTERNAL_ERROR;
2626 if ((pk->xmss_pk = malloc(pklen)) == NULL) {
2627 ret = SSH_ERR_ALLOC_FAIL;
2630 memcpy(pk->xmss_pk, k->xmss_pk, pklen);
2633 #endif /* WITH_XMSS */
2635 ret = SSH_ERR_KEY_TYPE_UNKNOWN;
2644 /* Convert a plain key to their _CERT equivalent */
2646 sshkey_to_certified(struct sshkey *k)
2653 newtype = KEY_RSA_CERT;
2656 newtype = KEY_DSA_CERT;
2659 newtype = KEY_ECDSA_CERT;
2661 #endif /* WITH_OPENSSL */
2663 newtype = KEY_ED25519_CERT;
2667 newtype = KEY_XMSS_CERT;
2669 #endif /* WITH_XMSS */
2671 return SSH_ERR_INVALID_ARGUMENT;
2673 if ((k->cert = cert_new()) == NULL)
2674 return SSH_ERR_ALLOC_FAIL;
2679 /* Convert a certificate to its raw key equivalent */
2681 sshkey_drop_cert(struct sshkey *k)
2683 if (!sshkey_type_is_cert(k->type))
2684 return SSH_ERR_KEY_TYPE_UNKNOWN;
2687 k->type = sshkey_type_plain(k->type);
2691 /* Sign a certified key, (re-)generating the signed certblob. */
2693 sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg,
2694 sshkey_certify_signer *signer, void *signer_ctx)
2696 struct sshbuf *principals = NULL;
2697 u_char *ca_blob = NULL, *sig_blob = NULL, nonce[32];
2698 size_t i, ca_len, sig_len;
2699 int ret = SSH_ERR_INTERNAL_ERROR;
2700 struct sshbuf *cert;
2702 if (k == NULL || k->cert == NULL ||
2703 k->cert->certblob == NULL || ca == NULL)
2704 return SSH_ERR_INVALID_ARGUMENT;
2705 if (!sshkey_is_cert(k))
2706 return SSH_ERR_KEY_TYPE_UNKNOWN;
2707 if (!sshkey_type_is_valid_ca(ca->type))
2708 return SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
2710 if ((ret = sshkey_to_blob(ca, &ca_blob, &ca_len)) != 0)
2711 return SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
2713 cert = k->cert->certblob; /* for readability */
2715 if ((ret = sshbuf_put_cstring(cert, sshkey_ssh_name(k))) != 0)
2718 /* -v01 certs put nonce first */
2719 arc4random_buf(&nonce, sizeof(nonce));
2720 if ((ret = sshbuf_put_string(cert, nonce, sizeof(nonce))) != 0)
2723 /* XXX this substantially duplicates to_blob(); refactor */
2728 const BIGNUM *p, *q, *g, *pub_key;
2729 DSA_get0_pqg(k->dsa, &p, &q, &g);
2730 DSA_get0_key(k->dsa, &pub_key, NULL);
2731 if ((ret = sshbuf_put_bignum2(cert, p)) != 0 ||
2732 (ret = sshbuf_put_bignum2(cert, q)) != 0 ||
2733 (ret = sshbuf_put_bignum2(cert, g)) != 0 ||
2734 (ret = sshbuf_put_bignum2(cert, pub_key)) != 0) {
2739 # ifdef OPENSSL_HAS_ECC
2740 case KEY_ECDSA_CERT:
2741 if ((ret = sshbuf_put_cstring(cert,
2742 sshkey_curve_nid_to_name(k->ecdsa_nid))) != 0 ||
2743 (ret = sshbuf_put_ec(cert,
2744 EC_KEY_get0_public_key(k->ecdsa),
2745 EC_KEY_get0_group(k->ecdsa))) != 0)
2748 # endif /* OPENSSL_HAS_ECC */
2751 const BIGNUM *e, *n;
2752 RSA_get0_key(k->rsa, &n, &e, NULL);
2753 if (n == NULL || e == NULL ||
2754 (ret = sshbuf_put_bignum2(cert, e)) != 0 ||
2755 (ret = sshbuf_put_bignum2(cert, n)) != 0) {
2760 #endif /* WITH_OPENSSL */
2761 case KEY_ED25519_CERT:
2762 if ((ret = sshbuf_put_string(cert,
2763 k->ed25519_pk, ED25519_PK_SZ)) != 0)
2768 if (k->xmss_name == NULL) {
2769 ret = SSH_ERR_INVALID_ARGUMENT;
2772 if ((ret = sshbuf_put_cstring(cert, k->xmss_name)) ||
2773 (ret = sshbuf_put_string(cert,
2774 k->xmss_pk, sshkey_xmss_pklen(k))) != 0)
2777 #endif /* WITH_XMSS */
2779 ret = SSH_ERR_INVALID_ARGUMENT;
2783 if ((ret = sshbuf_put_u64(cert, k->cert->serial)) != 0 ||
2784 (ret = sshbuf_put_u32(cert, k->cert->type)) != 0 ||
2785 (ret = sshbuf_put_cstring(cert, k->cert->key_id)) != 0)
2788 if ((principals = sshbuf_new()) == NULL) {
2789 ret = SSH_ERR_ALLOC_FAIL;
2792 for (i = 0; i < k->cert->nprincipals; i++) {
2793 if ((ret = sshbuf_put_cstring(principals,
2794 k->cert->principals[i])) != 0)
2797 if ((ret = sshbuf_put_stringb(cert, principals)) != 0 ||
2798 (ret = sshbuf_put_u64(cert, k->cert->valid_after)) != 0 ||
2799 (ret = sshbuf_put_u64(cert, k->cert->valid_before)) != 0 ||
2800 (ret = sshbuf_put_stringb(cert, k->cert->critical)) != 0 ||
2801 (ret = sshbuf_put_stringb(cert, k->cert->extensions)) != 0 ||
2802 (ret = sshbuf_put_string(cert, NULL, 0)) != 0 || /* Reserved */
2803 (ret = sshbuf_put_string(cert, ca_blob, ca_len)) != 0)
2806 /* Sign the whole mess */
2807 if ((ret = signer(ca, &sig_blob, &sig_len, sshbuf_ptr(cert),
2808 sshbuf_len(cert), alg, 0, signer_ctx)) != 0)
2811 /* Append signature and we are done */
2812 if ((ret = sshbuf_put_string(cert, sig_blob, sig_len)) != 0)
2820 sshbuf_free(principals);
2825 default_key_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
2826 const u_char *data, size_t datalen,
2827 const char *alg, u_int compat, void *ctx)
2830 return SSH_ERR_INVALID_ARGUMENT;
2831 return sshkey_sign(key, sigp, lenp, data, datalen, alg, compat);
2835 sshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg)
2837 return sshkey_certify_custom(k, ca, alg, default_key_sign, NULL);
2841 sshkey_cert_check_authority(const struct sshkey *k,
2842 int want_host, int require_principal,
2843 const char *name, const char **reason)
2845 u_int i, principal_matches;
2846 time_t now = time(NULL);
2852 if (k->cert->type != SSH2_CERT_TYPE_HOST) {
2853 *reason = "Certificate invalid: not a host certificate";
2854 return SSH_ERR_KEY_CERT_INVALID;
2857 if (k->cert->type != SSH2_CERT_TYPE_USER) {
2858 *reason = "Certificate invalid: not a user certificate";
2859 return SSH_ERR_KEY_CERT_INVALID;
2863 /* yikes - system clock before epoch! */
2864 *reason = "Certificate invalid: not yet valid";
2865 return SSH_ERR_KEY_CERT_INVALID;
2867 if ((u_int64_t)now < k->cert->valid_after) {
2868 *reason = "Certificate invalid: not yet valid";
2869 return SSH_ERR_KEY_CERT_INVALID;
2871 if ((u_int64_t)now >= k->cert->valid_before) {
2872 *reason = "Certificate invalid: expired";
2873 return SSH_ERR_KEY_CERT_INVALID;
2875 if (k->cert->nprincipals == 0) {
2876 if (require_principal) {
2877 *reason = "Certificate lacks principal list";
2878 return SSH_ERR_KEY_CERT_INVALID;
2880 } else if (name != NULL) {
2881 principal_matches = 0;
2882 for (i = 0; i < k->cert->nprincipals; i++) {
2883 if (strcmp(name, k->cert->principals[i]) == 0) {
2884 principal_matches = 1;
2888 if (!principal_matches) {
2889 *reason = "Certificate invalid: name is not a listed "
2891 return SSH_ERR_KEY_CERT_INVALID;
2898 sshkey_format_cert_validity(const struct sshkey_cert *cert, char *s, size_t l)
2900 char from[32], to[32], ret[64];
2905 if (cert->valid_after == 0 &&
2906 cert->valid_before == 0xffffffffffffffffULL)
2907 return strlcpy(s, "forever", l);
2909 if (cert->valid_after != 0) {
2910 /* XXX revisit INT_MAX in 2038 :) */
2911 tt = cert->valid_after > INT_MAX ?
2912 INT_MAX : cert->valid_after;
2913 tm = localtime(&tt);
2914 strftime(from, sizeof(from), "%Y-%m-%dT%H:%M:%S", tm);
2916 if (cert->valid_before != 0xffffffffffffffffULL) {
2917 /* XXX revisit INT_MAX in 2038 :) */
2918 tt = cert->valid_before > INT_MAX ?
2919 INT_MAX : cert->valid_before;
2920 tm = localtime(&tt);
2921 strftime(to, sizeof(to), "%Y-%m-%dT%H:%M:%S", tm);
2924 if (cert->valid_after == 0)
2925 snprintf(ret, sizeof(ret), "before %s", to);
2926 else if (cert->valid_before == 0xffffffffffffffffULL)
2927 snprintf(ret, sizeof(ret), "after %s", from);
2929 snprintf(ret, sizeof(ret), "from %s to %s", from, to);
2931 return strlcpy(s, ret, l);
2935 sshkey_private_serialize_opt(const struct sshkey *key, struct sshbuf *b,
2936 enum sshkey_serialize_rep opts)
2938 int r = SSH_ERR_INTERNAL_ERROR;
2940 if ((r = sshbuf_put_cstring(b, sshkey_ssh_name(key))) != 0)
2942 switch (key->type) {
2946 const BIGNUM *n, *e, *d, *iqmp, *p, *q;
2947 RSA_get0_key(key->rsa, &n, &e, &d);
2948 RSA_get0_crt_params(key->rsa, NULL, NULL, &iqmp);
2949 RSA_get0_factors(key->rsa, &p, &q);
2950 if ((r = sshbuf_put_bignum2(b, n)) != 0 ||
2951 (r = sshbuf_put_bignum2(b, e)) != 0 ||
2952 (r = sshbuf_put_bignum2(b, d)) != 0 ||
2953 (r = sshbuf_put_bignum2(b, iqmp)) != 0 ||
2954 (r = sshbuf_put_bignum2(b, p)) != 0 ||
2955 (r = sshbuf_put_bignum2(b, q)) != 0) {
2961 if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
2962 r = SSH_ERR_INVALID_ARGUMENT;
2966 const BIGNUM *d, *iqmp, *p, *q;
2967 RSA_get0_key(key->rsa, NULL, NULL, &d);
2968 RSA_get0_crt_params(key->rsa, NULL, NULL, &iqmp);
2969 RSA_get0_factors(key->rsa, &p, &q);
2970 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
2971 (r = sshbuf_put_bignum2(b, d)) != 0 ||
2972 (r = sshbuf_put_bignum2(b, iqmp)) != 0 ||
2973 (r = sshbuf_put_bignum2(b, p)) != 0 ||
2974 (r = sshbuf_put_bignum2(b, q)) != 0) {
2981 const BIGNUM *p, *q, *g, *pub_key, *priv_key;
2982 DSA_get0_pqg(key->dsa, &p, &q, &g);
2983 DSA_get0_key(key->dsa, &pub_key, &priv_key);
2984 if ((r = sshbuf_put_bignum2(b, p)) != 0 ||
2985 (r = sshbuf_put_bignum2(b, q)) != 0 ||
2986 (r = sshbuf_put_bignum2(b, g)) != 0 ||
2987 (r = sshbuf_put_bignum2(b, pub_key)) != 0 ||
2988 (r = sshbuf_put_bignum2(b, priv_key)) != 0) {
2994 if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
2995 r = SSH_ERR_INVALID_ARGUMENT;
2999 const BIGNUM *priv_key;
3000 DSA_get0_key(key->dsa, NULL, &priv_key);
3001 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
3002 (r = sshbuf_put_bignum2(b, priv_key)) != 0) {
3007 # ifdef OPENSSL_HAS_ECC
3009 if ((r = sshbuf_put_cstring(b,
3010 sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 ||
3011 (r = sshbuf_put_eckey(b, key->ecdsa)) != 0 ||
3012 (r = sshbuf_put_bignum2(b,
3013 EC_KEY_get0_private_key(key->ecdsa))) != 0)
3016 case KEY_ECDSA_CERT:
3017 if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
3018 r = SSH_ERR_INVALID_ARGUMENT;
3021 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
3022 (r = sshbuf_put_bignum2(b,
3023 EC_KEY_get0_private_key(key->ecdsa))) != 0)
3026 # endif /* OPENSSL_HAS_ECC */
3027 #endif /* WITH_OPENSSL */
3029 if ((r = sshbuf_put_string(b, key->ed25519_pk,
3030 ED25519_PK_SZ)) != 0 ||
3031 (r = sshbuf_put_string(b, key->ed25519_sk,
3032 ED25519_SK_SZ)) != 0)
3035 case KEY_ED25519_CERT:
3036 if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
3037 r = SSH_ERR_INVALID_ARGUMENT;
3040 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
3041 (r = sshbuf_put_string(b, key->ed25519_pk,
3042 ED25519_PK_SZ)) != 0 ||
3043 (r = sshbuf_put_string(b, key->ed25519_sk,
3044 ED25519_SK_SZ)) != 0)
3049 if (key->xmss_name == NULL) {
3050 r = SSH_ERR_INVALID_ARGUMENT;
3053 if ((r = sshbuf_put_cstring(b, key->xmss_name)) != 0 ||
3054 (r = sshbuf_put_string(b, key->xmss_pk,
3055 sshkey_xmss_pklen(key))) != 0 ||
3056 (r = sshbuf_put_string(b, key->xmss_sk,
3057 sshkey_xmss_sklen(key))) != 0 ||
3058 (r = sshkey_xmss_serialize_state_opt(key, b, opts)) != 0)
3062 if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0 ||
3063 key->xmss_name == NULL) {
3064 r = SSH_ERR_INVALID_ARGUMENT;
3067 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
3068 (r = sshbuf_put_cstring(b, key->xmss_name)) != 0 ||
3069 (r = sshbuf_put_string(b, key->xmss_pk,
3070 sshkey_xmss_pklen(key))) != 0 ||
3071 (r = sshbuf_put_string(b, key->xmss_sk,
3072 sshkey_xmss_sklen(key))) != 0 ||
3073 (r = sshkey_xmss_serialize_state_opt(key, b, opts)) != 0)
3076 #endif /* WITH_XMSS */
3078 r = SSH_ERR_INVALID_ARGUMENT;
3088 sshkey_private_serialize(const struct sshkey *key, struct sshbuf *b)
3090 return sshkey_private_serialize_opt(key, b,
3091 SSHKEY_SERIALIZE_DEFAULT);
3095 sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
3097 char *tname = NULL, *curve = NULL, *xmss_name = NULL;
3098 struct sshkey *k = NULL;
3099 size_t pklen = 0, sklen = 0;
3100 int type, r = SSH_ERR_INTERNAL_ERROR;
3101 u_char *ed25519_pk = NULL, *ed25519_sk = NULL;
3102 u_char *xmss_pk = NULL, *xmss_sk = NULL;
3104 BIGNUM *exponent = NULL;
3105 #endif /* WITH_OPENSSL */
3109 if ((r = sshbuf_get_cstring(buf, &tname, NULL)) != 0)
3111 type = sshkey_type_from_name(tname);
3115 if ((k = sshkey_new_private(type)) == NULL) {
3116 r = SSH_ERR_ALLOC_FAIL;
3120 BIGNUM *p=NULL, *q=NULL, *g=NULL, *pub_key=NULL, *priv_key=NULL;
3121 if ((p = BN_new()) == NULL ||
3122 (q = BN_new()) == NULL ||
3123 (g = BN_new()) == NULL ||
3124 (pub_key = BN_new()) == NULL ||
3125 (priv_key = BN_new()) == NULL) {
3126 r = SSH_ERR_ALLOC_FAIL;
3129 if (p == NULL || q == NULL || g == NULL ||
3130 pub_key == NULL || priv_key == NULL ||
3131 (r = sshbuf_get_bignum2(buf, p)) != 0 ||
3132 (r = sshbuf_get_bignum2(buf, q)) != 0 ||
3133 (r = sshbuf_get_bignum2(buf, g)) != 0 ||
3134 (r = sshbuf_get_bignum2(buf, pub_key)) != 0 ||
3135 (r = sshbuf_get_bignum2(buf, priv_key)) != 0) {
3138 if (DSA_set0_pqg(k->dsa, p, q, g) == 0) {
3139 r = SSH_ERR_LIBCRYPTO_ERROR;
3143 if (DSA_set0_key(k->dsa, pub_key, priv_key) == 0) {
3144 r = SSH_ERR_LIBCRYPTO_ERROR;
3146 BN_free(p); BN_free(q); BN_free(g);
3147 BN_free(pub_key); BN_free(priv_key);
3150 pub_key = priv_key = NULL;
3155 BIGNUM *priv_key=NULL;
3156 if ((priv_key = BN_new()) == NULL) {
3157 r = SSH_ERR_ALLOC_FAIL;
3160 if (priv_key == NULL ||
3161 (r = sshkey_froms(buf, &k)) != 0 ||
3162 (r = sshkey_add_private(k)) != 0 ||
3163 (r = sshbuf_get_bignum2(buf, priv_key)) != 0) {
3167 if (DSA_set0_key(k->dsa, NULL, priv_key) == 0) {
3168 r = SSH_ERR_LIBCRYPTO_ERROR;
3175 # ifdef OPENSSL_HAS_ECC
3177 if ((k = sshkey_new_private(type)) == NULL) {
3178 r = SSH_ERR_ALLOC_FAIL;
3181 if ((k->ecdsa_nid = sshkey_ecdsa_nid_from_name(tname)) == -1) {
3182 r = SSH_ERR_INVALID_ARGUMENT;
3185 if ((r = sshbuf_get_cstring(buf, &curve, NULL)) != 0)
3187 if (k->ecdsa_nid != sshkey_curve_name_to_nid(curve)) {
3188 r = SSH_ERR_EC_CURVE_MISMATCH;
3191 k->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid);
3192 if (k->ecdsa == NULL || (exponent = BN_new()) == NULL) {
3193 r = SSH_ERR_LIBCRYPTO_ERROR;
3196 if ((r = sshbuf_get_eckey(buf, k->ecdsa)) != 0 ||
3197 (r = sshbuf_get_bignum2(buf, exponent)))
3199 if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) {
3200 r = SSH_ERR_LIBCRYPTO_ERROR;
3203 if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
3204 EC_KEY_get0_public_key(k->ecdsa))) != 0 ||
3205 (r = sshkey_ec_validate_private(k->ecdsa)) != 0)
3208 case KEY_ECDSA_CERT:
3209 if ((exponent = BN_new()) == NULL) {
3210 r = SSH_ERR_LIBCRYPTO_ERROR;
3213 if ((r = sshkey_froms(buf, &k)) != 0 ||
3214 (r = sshkey_add_private(k)) != 0 ||
3215 (r = sshbuf_get_bignum2(buf, exponent)) != 0)
3217 if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) {
3218 r = SSH_ERR_LIBCRYPTO_ERROR;
3221 if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
3222 EC_KEY_get0_public_key(k->ecdsa))) != 0 ||
3223 (r = sshkey_ec_validate_private(k->ecdsa)) != 0)
3226 # endif /* OPENSSL_HAS_ECC */
3228 if ((k = sshkey_new_private(type)) == NULL) {
3229 r = SSH_ERR_ALLOC_FAIL;
3233 BIGNUM *n=NULL, *e=NULL, *d=NULL, *iqmp=NULL, *p=NULL, *q=NULL;
3234 BIGNUM *dmp1=NULL, *dmq1=NULL; /* dummy for RSA_set0_crt_params */
3235 if ((n = BN_new()) == NULL ||
3236 (e = BN_new()) == NULL ||
3237 (d = BN_new()) == NULL ||
3238 (iqmp = BN_new()) == NULL ||
3239 (p = BN_new()) == NULL ||
3240 (q = BN_new()) == NULL ||
3241 (dmp1 = BN_new()) == NULL ||
3242 (dmq1 = BN_new()) == NULL) {
3243 r = SSH_ERR_ALLOC_FAIL;
3246 BN_clear(dmp1); BN_clear(dmq1);
3247 if ((r = sshbuf_get_bignum2(buf, n)) != 0 ||
3248 (r = sshbuf_get_bignum2(buf, e)) != 0 ||
3249 (r = sshbuf_get_bignum2(buf, d)) != 0 ||
3250 (r = sshbuf_get_bignum2(buf, iqmp)) != 0 ||
3251 (r = sshbuf_get_bignum2(buf, p)) != 0 ||
3252 (r = sshbuf_get_bignum2(buf, q)) != 0) {
3255 if (RSA_set0_key(k->rsa, n, e, d) == 0) {
3256 r = SSH_ERR_LIBCRYPTO_ERROR;
3260 /* dmp1,dmpq1 should be non NULL to set iqmp value */
3261 if (RSA_set0_crt_params(k->rsa, dmp1, dmq1, iqmp) == 0) {
3262 r = SSH_ERR_LIBCRYPTO_ERROR;
3265 dmp1 = dmq1 = iqmp = NULL;
3266 if (RSA_set0_factors(k->rsa, p, q) == 0) {
3267 r = SSH_ERR_LIBCRYPTO_ERROR;
3269 BN_free(n); BN_free(e); BN_free(d);
3271 BN_free(p); BN_free(q);
3272 BN_free(dmp1); BN_free(dmq1);
3276 if ((r = ssh_rsa_generate_additional_parameters(k)) != 0) {
3280 if (RSA_bits(k->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
3281 r = SSH_ERR_KEY_LENGTH;
3287 BIGNUM *d=NULL, *iqmp=NULL, *p=NULL, *q=NULL;
3288 BIGNUM *dmp1=NULL, *dmq1=NULL; /* dummy for RSA_set0_crt_params */
3289 if ((d = BN_new()) == NULL ||
3290 (iqmp = BN_new()) == NULL ||
3291 (p = BN_new()) == NULL ||
3292 (q = BN_new()) == NULL ||
3293 (dmp1 = BN_new()) == NULL ||
3294 (dmq1 = BN_new()) == NULL) {
3295 r = SSH_ERR_ALLOC_FAIL;
3298 BN_clear(dmp1); BN_clear(dmq1);
3299 if ((r = sshkey_froms(buf, &k)) != 0 ||
3300 (r = sshkey_add_private(k)) != 0 ||
3301 (r = sshbuf_get_bignum2(buf, d)) != 0 ||
3302 (r = sshbuf_get_bignum2(buf, iqmp)) != 0 ||
3303 (r = sshbuf_get_bignum2(buf, p)) != 0 ||
3304 (r = sshbuf_get_bignum2(buf, q)) != 0) {
3307 if (RSA_set0_key(k->rsa, NULL, NULL, d) == 0) {
3308 r = SSH_ERR_LIBCRYPTO_ERROR;
3311 /* dmp1,dmpq1 should be non NULL to set value */
3312 if (RSA_set0_crt_params(k->rsa, dmp1, dmq1, iqmp) == 0) {
3313 r = SSH_ERR_LIBCRYPTO_ERROR;
3316 dmp1 = dmq1 = iqmp = NULL;
3317 if (RSA_set0_factors(k->rsa, p, q) == 0) {
3318 r = SSH_ERR_LIBCRYPTO_ERROR;
3320 BN_free(d); BN_free(iqmp);
3321 BN_free(p); BN_free(q);
3322 BN_free(dmp1); BN_free(dmq1);
3326 if ((r = ssh_rsa_generate_additional_parameters(k)) != 0)
3329 if (RSA_bits(k->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
3330 r = SSH_ERR_KEY_LENGTH;
3334 #endif /* WITH_OPENSSL */
3336 if ((k = sshkey_new_private(type)) == NULL) {
3337 r = SSH_ERR_ALLOC_FAIL;
3340 if ((r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 ||
3341 (r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0)
3343 if (pklen != ED25519_PK_SZ || sklen != ED25519_SK_SZ) {
3344 r = SSH_ERR_INVALID_FORMAT;
3347 k->ed25519_pk = ed25519_pk;
3348 k->ed25519_sk = ed25519_sk;
3349 ed25519_pk = ed25519_sk = NULL;
3351 case KEY_ED25519_CERT:
3352 if ((r = sshkey_froms(buf, &k)) != 0 ||
3353 (r = sshkey_add_private(k)) != 0 ||
3354 (r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 ||
3355 (r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0)
3357 if (pklen != ED25519_PK_SZ || sklen != ED25519_SK_SZ) {
3358 r = SSH_ERR_INVALID_FORMAT;
3361 k->ed25519_pk = ed25519_pk;
3362 k->ed25519_sk = ed25519_sk;
3363 ed25519_pk = ed25519_sk = NULL;
3367 if ((k = sshkey_new_private(type)) == NULL) {
3368 r = SSH_ERR_ALLOC_FAIL;
3371 if ((r = sshbuf_get_cstring(buf, &xmss_name, NULL)) != 0 ||
3372 (r = sshkey_xmss_init(k, xmss_name)) != 0 ||
3373 (r = sshbuf_get_string(buf, &xmss_pk, &pklen)) != 0 ||
3374 (r = sshbuf_get_string(buf, &xmss_sk, &sklen)) != 0)
3376 if (pklen != sshkey_xmss_pklen(k) ||
3377 sklen != sshkey_xmss_sklen(k)) {
3378 r = SSH_ERR_INVALID_FORMAT;
3381 k->xmss_pk = xmss_pk;
3382 k->xmss_sk = xmss_sk;
3383 xmss_pk = xmss_sk = NULL;
3384 /* optional internal state */
3385 if ((r = sshkey_xmss_deserialize_state_opt(k, buf)) != 0)
3389 if ((r = sshkey_froms(buf, &k)) != 0 ||
3390 (r = sshkey_add_private(k)) != 0 ||
3391 (r = sshbuf_get_cstring(buf, &xmss_name, NULL)) != 0 ||
3392 (r = sshbuf_get_string(buf, &xmss_pk, &pklen)) != 0 ||
3393 (r = sshbuf_get_string(buf, &xmss_sk, &sklen)) != 0)
3395 if (strcmp(xmss_name, k->xmss_name)) {
3396 r = SSH_ERR_INVALID_FORMAT;
3399 if (pklen != sshkey_xmss_pklen(k) ||
3400 sklen != sshkey_xmss_sklen(k)) {
3401 r = SSH_ERR_INVALID_FORMAT;
3404 k->xmss_pk = xmss_pk;
3405 k->xmss_sk = xmss_sk;
3406 xmss_pk = xmss_sk = NULL;
3407 /* optional internal state */
3408 if ((r = sshkey_xmss_deserialize_state_opt(k, buf)) != 0)
3411 #endif /* WITH_XMSS */
3413 r = SSH_ERR_KEY_TYPE_UNKNOWN;
3417 /* enable blinding */
3421 if (RSA_blinding_on(k->rsa, NULL) != 1) {
3422 r = SSH_ERR_LIBCRYPTO_ERROR;
3427 #endif /* WITH_OPENSSL */
3438 BN_clear_free(exponent);
3439 #endif /* WITH_OPENSSL */
3441 freezero(ed25519_pk, pklen);
3442 freezero(ed25519_sk, sklen);
3444 freezero(xmss_pk, pklen);
3445 freezero(xmss_sk, sklen);
3449 #if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
3451 sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public)
3454 EC_POINT *nq = NULL;
3455 BIGNUM *order, *x, *y, *tmp;
3456 int ret = SSH_ERR_KEY_INVALID_EC_VALUE;
3459 * NB. This assumes OpenSSL has already verified that the public
3460 * point lies on the curve. This is done by EC_POINT_oct2point()
3461 * implicitly calling EC_POINT_is_on_curve(). If this code is ever
3462 * reachable with public points not unmarshalled using
3463 * EC_POINT_oct2point then the caller will need to explicitly check.
3466 if ((bnctx = BN_CTX_new()) == NULL)
3467 return SSH_ERR_ALLOC_FAIL;
3468 BN_CTX_start(bnctx);
3471 * We shouldn't ever hit this case because bignum_get_ecpoint()
3472 * refuses to load GF2m points.
3474 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
3475 NID_X9_62_prime_field)
3479 if (EC_POINT_is_at_infinity(group, public))
3482 if ((x = BN_CTX_get(bnctx)) == NULL ||
3483 (y = BN_CTX_get(bnctx)) == NULL ||
3484 (order = BN_CTX_get(bnctx)) == NULL ||
3485 (tmp = BN_CTX_get(bnctx)) == NULL) {
3486 ret = SSH_ERR_ALLOC_FAIL;
3490 /* log2(x) > log2(order)/2, log2(y) > log2(order)/2 */
3491 if (EC_GROUP_get_order(group, order, bnctx) != 1 ||
3492 EC_POINT_get_affine_coordinates_GFp(group, public,
3493 x, y, bnctx) != 1) {
3494 ret = SSH_ERR_LIBCRYPTO_ERROR;
3497 if (BN_num_bits(x) <= BN_num_bits(order) / 2 ||
3498 BN_num_bits(y) <= BN_num_bits(order) / 2)
3501 /* nQ == infinity (n == order of subgroup) */
3502 if ((nq = EC_POINT_new(group)) == NULL) {
3503 ret = SSH_ERR_ALLOC_FAIL;
3506 if (EC_POINT_mul(group, nq, NULL, public, order, bnctx) != 1) {
3507 ret = SSH_ERR_LIBCRYPTO_ERROR;
3510 if (EC_POINT_is_at_infinity(group, nq) != 1)
3513 /* x < order - 1, y < order - 1 */
3514 if (!BN_sub(tmp, order, BN_value_one())) {
3515 ret = SSH_ERR_LIBCRYPTO_ERROR;
3518 if (BN_cmp(x, tmp) >= 0 || BN_cmp(y, tmp) >= 0)
3528 sshkey_ec_validate_private(const EC_KEY *key)
3531 BIGNUM *order, *tmp;
3532 int ret = SSH_ERR_KEY_INVALID_EC_VALUE;
3534 if ((bnctx = BN_CTX_new()) == NULL)
3535 return SSH_ERR_ALLOC_FAIL;
3536 BN_CTX_start(bnctx);
3538 if ((order = BN_CTX_get(bnctx)) == NULL ||
3539 (tmp = BN_CTX_get(bnctx)) == NULL) {
3540 ret = SSH_ERR_ALLOC_FAIL;
3544 /* log2(private) > log2(order)/2 */
3545 if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, bnctx) != 1) {
3546 ret = SSH_ERR_LIBCRYPTO_ERROR;
3549 if (BN_num_bits(EC_KEY_get0_private_key(key)) <=
3550 BN_num_bits(order) / 2)
3553 /* private < order - 1 */
3554 if (!BN_sub(tmp, order, BN_value_one())) {
3555 ret = SSH_ERR_LIBCRYPTO_ERROR;
3558 if (BN_cmp(EC_KEY_get0_private_key(key), tmp) >= 0)
3567 sshkey_dump_ec_point(const EC_GROUP *group, const EC_POINT *point)
3572 if (point == NULL) {
3573 fputs("point=(NULL)\n", stderr);
3576 if ((bnctx = BN_CTX_new()) == NULL) {
3577 fprintf(stderr, "%s: BN_CTX_new failed\n", __func__);
3580 BN_CTX_start(bnctx);
3581 if ((x = BN_CTX_get(bnctx)) == NULL ||
3582 (y = BN_CTX_get(bnctx)) == NULL) {
3583 fprintf(stderr, "%s: BN_CTX_get failed\n", __func__);
3586 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
3587 NID_X9_62_prime_field) {
3588 fprintf(stderr, "%s: group is not a prime field\n", __func__);
3591 if (EC_POINT_get_affine_coordinates_GFp(group, point, x, y,
3593 fprintf(stderr, "%s: EC_POINT_get_affine_coordinates_GFp\n",
3597 fputs("x=", stderr);
3598 BN_print_fp(stderr, x);
3599 fputs("\ny=", stderr);
3600 BN_print_fp(stderr, y);
3601 fputs("\n", stderr);
3606 sshkey_dump_ec_key(const EC_KEY *key)
3608 const BIGNUM *exponent;
3610 sshkey_dump_ec_point(EC_KEY_get0_group(key),
3611 EC_KEY_get0_public_key(key));
3612 fputs("exponent=", stderr);
3613 if ((exponent = EC_KEY_get0_private_key(key)) == NULL)
3614 fputs("(NULL)", stderr);
3616 BN_print_fp(stderr, EC_KEY_get0_private_key(key));
3617 fputs("\n", stderr);
3619 #endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */
3622 sshkey_private_to_blob2(const struct sshkey *prv, struct sshbuf *blob,
3623 const char *passphrase, const char *comment, const char *ciphername,
3626 u_char *cp, *key = NULL, *pubkeyblob = NULL;
3627 u_char salt[SALT_LEN];
3629 size_t i, pubkeylen, keylen, ivlen, blocksize, authlen;
3631 int r = SSH_ERR_INTERNAL_ERROR;
3632 struct sshcipher_ctx *ciphercontext = NULL;
3633 const struct sshcipher *cipher;
3634 const char *kdfname = KDFNAME;
3635 struct sshbuf *encoded = NULL, *encrypted = NULL, *kdf = NULL;
3638 rounds = DEFAULT_ROUNDS;
3639 if (passphrase == NULL || !strlen(passphrase)) {
3640 ciphername = "none";
3642 } else if (ciphername == NULL)
3643 ciphername = DEFAULT_CIPHERNAME;
3644 if ((cipher = cipher_by_name(ciphername)) == NULL) {
3645 r = SSH_ERR_INVALID_ARGUMENT;
3649 if ((kdf = sshbuf_new()) == NULL ||
3650 (encoded = sshbuf_new()) == NULL ||
3651 (encrypted = sshbuf_new()) == NULL) {
3652 r = SSH_ERR_ALLOC_FAIL;
3655 blocksize = cipher_blocksize(cipher);
3656 keylen = cipher_keylen(cipher);
3657 ivlen = cipher_ivlen(cipher);
3658 authlen = cipher_authlen(cipher);
3659 if ((key = calloc(1, keylen + ivlen)) == NULL) {
3660 r = SSH_ERR_ALLOC_FAIL;
3663 if (strcmp(kdfname, "bcrypt") == 0) {
3664 arc4random_buf(salt, SALT_LEN);
3665 if (bcrypt_pbkdf(passphrase, strlen(passphrase),
3666 salt, SALT_LEN, key, keylen + ivlen, rounds) < 0) {
3667 r = SSH_ERR_INVALID_ARGUMENT;
3670 if ((r = sshbuf_put_string(kdf, salt, SALT_LEN)) != 0 ||
3671 (r = sshbuf_put_u32(kdf, rounds)) != 0)
3673 } else if (strcmp(kdfname, "none") != 0) {
3674 /* Unsupported KDF type */
3675 r = SSH_ERR_KEY_UNKNOWN_CIPHER;
3678 if ((r = cipher_init(&ciphercontext, cipher, key, keylen,
3679 key + keylen, ivlen, 1)) != 0)
3682 if ((r = sshbuf_put(encoded, AUTH_MAGIC, sizeof(AUTH_MAGIC))) != 0 ||
3683 (r = sshbuf_put_cstring(encoded, ciphername)) != 0 ||
3684 (r = sshbuf_put_cstring(encoded, kdfname)) != 0 ||
3685 (r = sshbuf_put_stringb(encoded, kdf)) != 0 ||
3686 (r = sshbuf_put_u32(encoded, 1)) != 0 || /* number of keys */
3687 (r = sshkey_to_blob(prv, &pubkeyblob, &pubkeylen)) != 0 ||
3688 (r = sshbuf_put_string(encoded, pubkeyblob, pubkeylen)) != 0)
3691 /* set up the buffer that will be encrypted */
3693 /* Random check bytes */
3694 check = arc4random();
3695 if ((r = sshbuf_put_u32(encrypted, check)) != 0 ||
3696 (r = sshbuf_put_u32(encrypted, check)) != 0)
3699 /* append private key and comment*/
3700 if ((r = sshkey_private_serialize_opt(prv, encrypted,
3701 SSHKEY_SERIALIZE_FULL)) != 0 ||
3702 (r = sshbuf_put_cstring(encrypted, comment)) != 0)
3707 while (sshbuf_len(encrypted) % blocksize) {
3708 if ((r = sshbuf_put_u8(encrypted, ++i & 0xff)) != 0)
3712 /* length in destination buffer */
3713 if ((r = sshbuf_put_u32(encoded, sshbuf_len(encrypted))) != 0)
3717 if ((r = sshbuf_reserve(encoded,
3718 sshbuf_len(encrypted) + authlen, &cp)) != 0)
3720 if ((r = cipher_crypt(ciphercontext, 0, cp,
3721 sshbuf_ptr(encrypted), sshbuf_len(encrypted), 0, authlen)) != 0)
3725 if ((b64 = sshbuf_dtob64(encoded)) == NULL) {
3726 r = SSH_ERR_ALLOC_FAIL;
3731 if ((r = sshbuf_put(blob, MARK_BEGIN, MARK_BEGIN_LEN)) != 0)
3733 for (i = 0; i < strlen(b64); i++) {
3734 if ((r = sshbuf_put_u8(blob, b64[i])) != 0)
3736 /* insert line breaks */
3737 if (i % 70 == 69 && (r = sshbuf_put_u8(blob, '\n')) != 0)
3740 if (i % 70 != 69 && (r = sshbuf_put_u8(blob, '\n')) != 0)
3742 if ((r = sshbuf_put(blob, MARK_END, MARK_END_LEN)) != 0)
3750 sshbuf_free(encoded);
3751 sshbuf_free(encrypted);
3752 cipher_free(ciphercontext);
3753 explicit_bzero(salt, sizeof(salt));
3755 explicit_bzero(key, keylen + ivlen);
3758 if (pubkeyblob != NULL) {
3759 explicit_bzero(pubkeyblob, pubkeylen);
3763 explicit_bzero(b64, strlen(b64));
3770 sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
3771 struct sshkey **keyp, char **commentp)
3773 char *comment = NULL, *ciphername = NULL, *kdfname = NULL;
3774 const struct sshcipher *cipher = NULL;
3776 int r = SSH_ERR_INTERNAL_ERROR;
3778 size_t i, keylen = 0, ivlen = 0, authlen = 0, slen = 0;
3779 struct sshbuf *encoded = NULL, *decoded = NULL;
3780 struct sshbuf *kdf = NULL, *decrypted = NULL;
3781 struct sshcipher_ctx *ciphercontext = NULL;
3782 struct sshkey *k = NULL;
3783 u_char *key = NULL, *salt = NULL, *dp, pad, last;
3784 u_int blocksize, rounds, nkeys, encrypted_len, check1, check2;
3788 if (commentp != NULL)
3791 if ((encoded = sshbuf_new()) == NULL ||
3792 (decoded = sshbuf_new()) == NULL ||
3793 (decrypted = sshbuf_new()) == NULL) {
3794 r = SSH_ERR_ALLOC_FAIL;
3798 /* check preamble */
3799 cp = sshbuf_ptr(blob);
3800 encoded_len = sshbuf_len(blob);
3801 if (encoded_len < (MARK_BEGIN_LEN + MARK_END_LEN) ||
3802 memcmp(cp, MARK_BEGIN, MARK_BEGIN_LEN) != 0) {
3803 r = SSH_ERR_INVALID_FORMAT;
3806 cp += MARK_BEGIN_LEN;
3807 encoded_len -= MARK_BEGIN_LEN;
3809 /* Look for end marker, removing whitespace as we go */
3810 while (encoded_len > 0) {
3811 if (*cp != '\n' && *cp != '\r') {
3812 if ((r = sshbuf_put_u8(encoded, *cp)) != 0)
3819 if (encoded_len >= MARK_END_LEN &&
3820 memcmp(cp, MARK_END, MARK_END_LEN) == 0) {
3822 if ((r = sshbuf_put_u8(encoded, 0)) != 0)
3828 if (encoded_len == 0) {
3829 r = SSH_ERR_INVALID_FORMAT;
3834 if ((r = sshbuf_b64tod(decoded, (char *)sshbuf_ptr(encoded))) != 0)
3838 if (sshbuf_len(decoded) < sizeof(AUTH_MAGIC) ||
3839 memcmp(sshbuf_ptr(decoded), AUTH_MAGIC, sizeof(AUTH_MAGIC))) {
3840 r = SSH_ERR_INVALID_FORMAT;
3843 /* parse public portion of key */
3844 if ((r = sshbuf_consume(decoded, sizeof(AUTH_MAGIC))) != 0 ||
3845 (r = sshbuf_get_cstring(decoded, &ciphername, NULL)) != 0 ||
3846 (r = sshbuf_get_cstring(decoded, &kdfname, NULL)) != 0 ||
3847 (r = sshbuf_froms(decoded, &kdf)) != 0 ||
3848 (r = sshbuf_get_u32(decoded, &nkeys)) != 0 ||
3849 (r = sshbuf_skip_string(decoded)) != 0 || /* pubkey */
3850 (r = sshbuf_get_u32(decoded, &encrypted_len)) != 0)
3853 if ((cipher = cipher_by_name(ciphername)) == NULL) {
3854 r = SSH_ERR_KEY_UNKNOWN_CIPHER;
3857 if ((passphrase == NULL || strlen(passphrase) == 0) &&
3858 strcmp(ciphername, "none") != 0) {
3859 /* passphrase required */
3860 r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3863 if (strcmp(kdfname, "none") != 0 && strcmp(kdfname, "bcrypt") != 0) {
3864 r = SSH_ERR_KEY_UNKNOWN_CIPHER;
3867 if (!strcmp(kdfname, "none") && strcmp(ciphername, "none") != 0) {
3868 r = SSH_ERR_INVALID_FORMAT;
3872 /* XXX only one key supported */
3873 r = SSH_ERR_INVALID_FORMAT;
3877 /* check size of encrypted key blob */
3878 blocksize = cipher_blocksize(cipher);
3879 if (encrypted_len < blocksize || (encrypted_len % blocksize) != 0) {
3880 r = SSH_ERR_INVALID_FORMAT;
3885 keylen = cipher_keylen(cipher);
3886 ivlen = cipher_ivlen(cipher);
3887 authlen = cipher_authlen(cipher);
3888 if ((key = calloc(1, keylen + ivlen)) == NULL) {
3889 r = SSH_ERR_ALLOC_FAIL;
3892 if (strcmp(kdfname, "bcrypt") == 0) {
3893 if ((r = sshbuf_get_string(kdf, &salt, &slen)) != 0 ||
3894 (r = sshbuf_get_u32(kdf, &rounds)) != 0)
3896 if (bcrypt_pbkdf(passphrase, strlen(passphrase), salt, slen,
3897 key, keylen + ivlen, rounds) < 0) {
3898 r = SSH_ERR_INVALID_FORMAT;
3903 /* check that an appropriate amount of auth data is present */
3904 if (sshbuf_len(decoded) < encrypted_len + authlen) {
3905 r = SSH_ERR_INVALID_FORMAT;
3909 /* decrypt private portion of key */
3910 if ((r = sshbuf_reserve(decrypted, encrypted_len, &dp)) != 0 ||
3911 (r = cipher_init(&ciphercontext, cipher, key, keylen,
3912 key + keylen, ivlen, 0)) != 0)
3914 if ((r = cipher_crypt(ciphercontext, 0, dp, sshbuf_ptr(decoded),
3915 encrypted_len, 0, authlen)) != 0) {
3916 /* an integrity error here indicates an incorrect passphrase */
3917 if (r == SSH_ERR_MAC_INVALID)
3918 r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3921 if ((r = sshbuf_consume(decoded, encrypted_len + authlen)) != 0)
3923 /* there should be no trailing data */
3924 if (sshbuf_len(decoded) != 0) {
3925 r = SSH_ERR_INVALID_FORMAT;
3929 /* check check bytes */
3930 if ((r = sshbuf_get_u32(decrypted, &check1)) != 0 ||
3931 (r = sshbuf_get_u32(decrypted, &check2)) != 0)
3933 if (check1 != check2) {
3934 r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3938 /* Load the private key and comment */
3939 if ((r = sshkey_private_deserialize(decrypted, &k)) != 0 ||
3940 (r = sshbuf_get_cstring(decrypted, &comment, NULL)) != 0)
3943 /* Check deterministic padding */
3945 while (sshbuf_len(decrypted)) {
3946 if ((r = sshbuf_get_u8(decrypted, &pad)) != 0)
3948 if (pad != (++i & 0xff)) {
3949 r = SSH_ERR_INVALID_FORMAT;
3954 /* XXX decode pubkey and check against private */
3962 if (commentp != NULL) {
3963 *commentp = comment;
3968 cipher_free(ciphercontext);
3973 explicit_bzero(salt, slen);
3977 explicit_bzero(key, keylen + ivlen);
3980 sshbuf_free(encoded);
3981 sshbuf_free(decoded);
3983 sshbuf_free(decrypted);
3990 /* convert SSH v2 key in OpenSSL PEM format */
3992 sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob,
3993 const char *_passphrase, const char *comment)
3996 int blen, len = strlen(_passphrase);
3997 u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL;
3998 const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL;
4002 if (len > 0 && len <= 4)
4003 return SSH_ERR_PASSPHRASE_TOO_SHORT;
4004 if ((bio = BIO_new(BIO_s_mem())) == NULL)
4005 return SSH_ERR_ALLOC_FAIL;
4007 switch (key->type) {
4009 success = PEM_write_bio_DSAPrivateKey(bio, key->dsa,
4010 cipher, passphrase, len, NULL, NULL);
4012 #ifdef OPENSSL_HAS_ECC
4014 success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa,
4015 cipher, passphrase, len, NULL, NULL);
4019 success = PEM_write_bio_RSAPrivateKey(bio, key->rsa,
4020 cipher, passphrase, len, NULL, NULL);
4027 r = SSH_ERR_LIBCRYPTO_ERROR;
4030 if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0) {
4031 r = SSH_ERR_INTERNAL_ERROR;
4034 if ((r = sshbuf_put(blob, bptr, blen)) != 0)
4041 #endif /* WITH_OPENSSL */
4043 /* Serialise "key" to buffer "blob" */
4045 sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob,
4046 const char *passphrase, const char *comment,
4047 int force_new_format, const char *new_format_cipher, int new_format_rounds)
4049 switch (key->type) {
4054 if (force_new_format) {
4055 return sshkey_private_to_blob2(key, blob, passphrase,
4056 comment, new_format_cipher, new_format_rounds);
4058 return sshkey_private_pem_to_blob(key, blob,
4059 passphrase, comment);
4060 #endif /* WITH_OPENSSL */
4064 #endif /* WITH_XMSS */
4065 return sshkey_private_to_blob2(key, blob, passphrase,
4066 comment, new_format_cipher, new_format_rounds);
4068 return SSH_ERR_KEY_TYPE_UNKNOWN;
4075 translate_libcrypto_error(unsigned long pem_err)
4077 int pem_reason = ERR_GET_REASON(pem_err);
4079 switch (ERR_GET_LIB(pem_err)) {
4081 switch (pem_reason) {
4082 case PEM_R_BAD_PASSWORD_READ:
4083 case PEM_R_PROBLEMS_GETTING_PASSWORD:
4084 case PEM_R_BAD_DECRYPT:
4085 return SSH_ERR_KEY_WRONG_PASSPHRASE;
4087 return SSH_ERR_INVALID_FORMAT;
4090 switch (pem_reason) {
4091 case EVP_R_BAD_DECRYPT:
4092 return SSH_ERR_KEY_WRONG_PASSPHRASE;
4093 case EVP_R_DECODE_ERROR:
4094 #ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR
4095 case EVP_R_PRIVATE_KEY_DECODE_ERROR:
4097 return SSH_ERR_INVALID_FORMAT;
4099 return SSH_ERR_LIBCRYPTO_ERROR;
4102 return SSH_ERR_INVALID_FORMAT;
4104 return SSH_ERR_LIBCRYPTO_ERROR;
4108 clear_libcrypto_errors(void)
4110 while (ERR_get_error() != 0)
4115 * Translate OpenSSL error codes to determine whether
4116 * passphrase is required/incorrect.
4119 convert_libcrypto_error(void)
4122 * Some password errors are reported at the beginning
4123 * of the error queue.
4125 if (translate_libcrypto_error(ERR_peek_error()) ==
4126 SSH_ERR_KEY_WRONG_PASSPHRASE)
4127 return SSH_ERR_KEY_WRONG_PASSPHRASE;
4128 return translate_libcrypto_error(ERR_peek_last_error());
4132 sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
4133 const char *passphrase, struct sshkey **keyp)
4135 EVP_PKEY *pk = NULL;
4136 struct sshkey *prv = NULL;
4143 if ((bio = BIO_new(BIO_s_mem())) == NULL || sshbuf_len(blob) > INT_MAX)
4144 return SSH_ERR_ALLOC_FAIL;
4145 if (BIO_write(bio, sshbuf_ptr(blob), sshbuf_len(blob)) !=
4146 (int)sshbuf_len(blob)) {
4147 r = SSH_ERR_ALLOC_FAIL;
4151 clear_libcrypto_errors();
4152 if ((pk = PEM_read_bio_PrivateKey(bio, NULL, NULL,
4153 (char *)passphrase)) == NULL) {
4154 r = convert_libcrypto_error();
4157 if (EVP_PKEY_id(pk) == EVP_PKEY_RSA &&
4158 (type == KEY_UNSPEC || type == KEY_RSA)) {
4159 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
4160 r = SSH_ERR_ALLOC_FAIL;
4163 prv->rsa = EVP_PKEY_get1_RSA(pk);
4164 prv->type = KEY_RSA;
4166 RSA_print_fp(stderr, prv->rsa, 8);
4168 if (RSA_blinding_on(prv->rsa, NULL) != 1) {
4169 r = SSH_ERR_LIBCRYPTO_ERROR;
4172 if (RSA_bits(prv->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
4173 r = SSH_ERR_KEY_LENGTH;
4176 } else if (EVP_PKEY_id(pk) == EVP_PKEY_DSA &&
4177 (type == KEY_UNSPEC || type == KEY_DSA)) {
4178 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
4179 r = SSH_ERR_ALLOC_FAIL;
4182 prv->dsa = EVP_PKEY_get1_DSA(pk);
4183 prv->type = KEY_DSA;
4185 DSA_print_fp(stderr, prv->dsa, 8);
4187 #ifdef OPENSSL_HAS_ECC
4188 } else if (EVP_PKEY_id(pk) == EVP_PKEY_EC &&
4189 (type == KEY_UNSPEC || type == KEY_ECDSA)) {
4190 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
4191 r = SSH_ERR_ALLOC_FAIL;
4194 prv->ecdsa = EVP_PKEY_get1_EC_KEY(pk);
4195 prv->type = KEY_ECDSA;
4196 prv->ecdsa_nid = sshkey_ecdsa_key_to_nid(prv->ecdsa);
4197 if (prv->ecdsa_nid == -1 ||
4198 sshkey_curve_nid_to_name(prv->ecdsa_nid) == NULL ||
4199 sshkey_ec_validate_public(EC_KEY_get0_group(prv->ecdsa),
4200 EC_KEY_get0_public_key(prv->ecdsa)) != 0 ||
4201 sshkey_ec_validate_private(prv->ecdsa) != 0) {
4202 r = SSH_ERR_INVALID_FORMAT;
4206 if (prv != NULL && prv->ecdsa != NULL)
4207 sshkey_dump_ec_key(prv->ecdsa);
4209 #endif /* OPENSSL_HAS_ECC */
4211 r = SSH_ERR_INVALID_FORMAT;
4225 #endif /* WITH_OPENSSL */
4228 sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
4229 const char *passphrase, struct sshkey **keyp, char **commentp)
4231 int r = SSH_ERR_INTERNAL_ERROR;
4235 if (commentp != NULL)
4243 return sshkey_parse_private_pem_fileblob(blob, type,
4245 #endif /* WITH_OPENSSL */
4249 #endif /* WITH_XMSS */
4250 return sshkey_parse_private2(blob, type, passphrase,
4253 r = sshkey_parse_private2(blob, type, passphrase, keyp,
4255 /* Do not fallback to PEM parser if only passphrase is wrong. */
4256 if (r == 0 || r == SSH_ERR_KEY_WRONG_PASSPHRASE)
4259 return sshkey_parse_private_pem_fileblob(blob, type,
4262 return SSH_ERR_INVALID_FORMAT;
4263 #endif /* WITH_OPENSSL */
4265 return SSH_ERR_KEY_TYPE_UNKNOWN;
4270 sshkey_parse_private_fileblob(struct sshbuf *buffer, const char *passphrase,
4271 struct sshkey **keyp, char **commentp)
4275 if (commentp != NULL)
4278 return sshkey_parse_private_fileblob_type(buffer, KEY_UNSPEC,
4279 passphrase, keyp, commentp);
4284 * serialize the key with the current state and forward the state
4288 sshkey_private_serialize_maxsign(const struct sshkey *k, struct sshbuf *b,
4289 u_int32_t maxsign, sshkey_printfn *pr)
4294 sshkey_type_plain(k->type) != KEY_XMSS)
4295 return sshkey_private_serialize_opt(k, b,
4296 SSHKEY_SERIALIZE_DEFAULT);
4297 if ((r = sshkey_xmss_get_state(k, pr)) != 0 ||
4298 (r = sshkey_private_serialize_opt(k, b,
4299 SSHKEY_SERIALIZE_STATE)) != 0 ||
4300 (r = sshkey_xmss_forward_state(k, maxsign)) != 0)
4304 if ((rupdate = sshkey_xmss_update_state(k, pr)) != 0) {
4312 sshkey_signatures_left(const struct sshkey *k)
4314 if (sshkey_type_plain(k->type) == KEY_XMSS)
4315 return sshkey_xmss_signatures_left(k);
4320 sshkey_enable_maxsign(struct sshkey *k, u_int32_t maxsign)
4322 if (sshkey_type_plain(k->type) != KEY_XMSS)
4323 return SSH_ERR_INVALID_ARGUMENT;
4324 return sshkey_xmss_enable_maxsign(k, maxsign);
4328 sshkey_set_filename(struct sshkey *k, const char *filename)
4331 return SSH_ERR_INVALID_ARGUMENT;
4332 if (sshkey_type_plain(k->type) != KEY_XMSS)
4334 if (filename == NULL)
4335 return SSH_ERR_INVALID_ARGUMENT;
4336 if ((k->xmss_filename = strdup(filename)) == NULL)
4337 return SSH_ERR_ALLOC_FAIL;
4342 sshkey_private_serialize_maxsign(const struct sshkey *k, struct sshbuf *b,
4343 u_int32_t maxsign, sshkey_printfn *pr)
4345 return sshkey_private_serialize_opt(k, b, SSHKEY_SERIALIZE_DEFAULT);
4349 sshkey_signatures_left(const struct sshkey *k)
4355 sshkey_enable_maxsign(struct sshkey *k, u_int32_t maxsign)
4357 return SSH_ERR_INVALID_ARGUMENT;
4361 sshkey_set_filename(struct sshkey *k, const char *filename)
4364 return SSH_ERR_INVALID_ARGUMENT;
4367 #endif /* WITH_XMSS */