xref: /netbsd-src/crypto/external/bsd/openssh/dist/sshkey.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /*	$NetBSD: sshkey.c,v 1.14 2018/04/06 18:59:00 christos Exp $	*/
2 /* $OpenBSD: sshkey.c,v 1.64 2018/03/22 07:05:48 markus Exp $ */
3 /*
4  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
5  * Copyright (c) 2008 Alexander von Gernler.  All rights reserved.
6  * Copyright (c) 2010,2011 Damien Miller.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 #include "includes.h"
29 __RCSID("$NetBSD: sshkey.c,v 1.14 2018/04/06 18:59:00 christos Exp $");
30 
31 #include <sys/types.h>
32 #include <netinet/in.h>
33 
34 #ifdef WITH_OPENSSL
35 #include <openssl/evp.h>
36 #include <openssl/err.h>
37 #include <openssl/pem.h>
38 #endif
39 
40 #include "crypto_api.h"
41 
42 #include <errno.h>
43 #include <stdio.h>
44 #include <string.h>
45 #include <util.h>
46 #include <limits.h>
47 #include <resolv.h>
48 
49 #include "ssh2.h"
50 #include "ssherr.h"
51 #include "misc.h"
52 #include "sshbuf.h"
53 #include "cipher.h"
54 #include "digest.h"
55 #define SSHKEY_INTERNAL
56 #include "sshkey.h"
57 #include "sshkey-xmss.h"
58 #include "match.h"
59 
60 #include "xmss_fast.h"
61 
62 /* openssh private key file format */
63 #define MARK_BEGIN		"-----BEGIN OPENSSH PRIVATE KEY-----\n"
64 #define MARK_END		"-----END OPENSSH PRIVATE KEY-----\n"
65 #define MARK_BEGIN_LEN		(sizeof(MARK_BEGIN) - 1)
66 #define MARK_END_LEN		(sizeof(MARK_END) - 1)
67 #define KDFNAME			"bcrypt"
68 #define AUTH_MAGIC		"openssh-key-v1"
69 #define SALT_LEN		16
70 #define DEFAULT_CIPHERNAME	"aes256-ctr"
71 #define	DEFAULT_ROUNDS		16
72 
73 /* Version identification string for SSH v1 identity files. */
74 #define LEGACY_BEGIN		"SSH PRIVATE KEY FILE FORMAT 1.1\n"
75 
76 int	sshkey_private_serialize_opt(const struct sshkey *key,
77     struct sshbuf *buf, enum sshkey_serialize_rep);
78 static int sshkey_from_blob_internal(struct sshbuf *buf,
79     struct sshkey **keyp, int allow_cert);
80 
81 /* Supported key types */
82 struct keytype {
83 	const char *name;
84 	const char *shortname;
85 	int type;
86 	int nid;
87 	int cert;
88 	int sigonly;
89 };
90 static const struct keytype keytypes[] = {
91 	{ "ssh-ed25519", "ED25519", KEY_ED25519, 0, 0, 0 },
92 	{ "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT",
93 	    KEY_ED25519_CERT, 0, 1, 0 },
94 #ifdef WITH_XMSS
95 	{ "ssh-xmss@openssh.com", "XMSS", KEY_XMSS, 0, 0, 0 },
96 	{ "ssh-xmss-cert-v01@openssh.com", "XMSS-CERT",
97 	    KEY_XMSS_CERT, 0, 1, 0 },
98 #endif /* WITH_XMSS */
99 #ifdef WITH_OPENSSL
100 	{ "ssh-rsa", "RSA", KEY_RSA, 0, 0, 0 },
101 	{ "rsa-sha2-256", "RSA", KEY_RSA, 0, 0, 1 },
102 	{ "rsa-sha2-512", "RSA", KEY_RSA, 0, 0, 1 },
103 	{ "ssh-dss", "DSA", KEY_DSA, 0, 0, 0 },
104 	{ "ecdsa-sha2-nistp256", "ECDSA", KEY_ECDSA, NID_X9_62_prime256v1, 0, 0 },
105 	{ "ecdsa-sha2-nistp384", "ECDSA", KEY_ECDSA, NID_secp384r1, 0, 0 },
106 	{ "ecdsa-sha2-nistp521", "ECDSA", KEY_ECDSA, NID_secp521r1, 0, 0 },
107 	{ "ssh-rsa-cert-v01@openssh.com", "RSA-CERT", KEY_RSA_CERT, 0, 1, 0 },
108 	{ "ssh-dss-cert-v01@openssh.com", "DSA-CERT", KEY_DSA_CERT, 0, 1, 0 },
109 	{ "ecdsa-sha2-nistp256-cert-v01@openssh.com", "ECDSA-CERT",
110 	    KEY_ECDSA_CERT, NID_X9_62_prime256v1, 1, 0 },
111 	{ "ecdsa-sha2-nistp384-cert-v01@openssh.com", "ECDSA-CERT",
112 	    KEY_ECDSA_CERT, NID_secp384r1, 1, 0 },
113 	{ "ecdsa-sha2-nistp521-cert-v01@openssh.com", "ECDSA-CERT",
114 	    KEY_ECDSA_CERT, NID_secp521r1, 1, 0 },
115 #endif /* WITH_OPENSSL */
116 	{ NULL, NULL, -1, -1, 0, 0 }
117 };
118 
119 const char *
120 sshkey_type(const struct sshkey *k)
121 {
122 	const struct keytype *kt;
123 
124 	for (kt = keytypes; kt->type != -1; kt++) {
125 		if (kt->type == k->type)
126 			return kt->shortname;
127 	}
128 	return "unknown";
129 }
130 
131 static const char *
132 sshkey_ssh_name_from_type_nid(int type, int nid)
133 {
134 	const struct keytype *kt;
135 
136 	for (kt = keytypes; kt->type != -1; kt++) {
137 		if (kt->type == type && (kt->nid == 0 || kt->nid == nid))
138 			return kt->name;
139 	}
140 	return "ssh-unknown";
141 }
142 
143 int
144 sshkey_type_is_cert(int type)
145 {
146 	const struct keytype *kt;
147 
148 	for (kt = keytypes; kt->type != -1; kt++) {
149 		if (kt->type == type)
150 			return kt->cert;
151 	}
152 	return 0;
153 }
154 
155 const char *
156 sshkey_ssh_name(const struct sshkey *k)
157 {
158 	return sshkey_ssh_name_from_type_nid(k->type, k->ecdsa_nid);
159 }
160 
161 const char *
162 sshkey_ssh_name_plain(const struct sshkey *k)
163 {
164 	return sshkey_ssh_name_from_type_nid(sshkey_type_plain(k->type),
165 	    k->ecdsa_nid);
166 }
167 
168 int
169 sshkey_type_from_name(const char *name)
170 {
171 	const struct keytype *kt;
172 
173 	for (kt = keytypes; kt->type != -1; kt++) {
174 		/* Only allow shortname matches for plain key types */
175 		if ((kt->name != NULL && strcmp(name, kt->name) == 0) ||
176 		    (!kt->cert && strcasecmp(kt->shortname, name) == 0))
177 			return kt->type;
178 	}
179 	return KEY_UNSPEC;
180 }
181 
182 int
183 sshkey_ecdsa_nid_from_name(const char *name)
184 {
185 	const struct keytype *kt;
186 
187 	for (kt = keytypes; kt->type != -1; kt++) {
188 		if (kt->type != KEY_ECDSA && kt->type != KEY_ECDSA_CERT)
189 			continue;
190 		if (kt->name != NULL && strcmp(name, kt->name) == 0)
191 			return kt->nid;
192 	}
193 	return -1;
194 }
195 
196 char *
197 sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep)
198 {
199 	char *tmp, *ret = NULL;
200 	size_t nlen, rlen = 0;
201 	const struct keytype *kt;
202 
203 	for (kt = keytypes; kt->type != -1; kt++) {
204 		if (kt->name == NULL)
205 			continue;
206 		if (!include_sigonly && kt->sigonly)
207 			continue;
208 		if ((certs_only && !kt->cert) || (plain_only && kt->cert))
209 			continue;
210 		if (ret != NULL)
211 			ret[rlen++] = sep;
212 		nlen = strlen(kt->name);
213 		if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) {
214 			free(ret);
215 			return NULL;
216 		}
217 		ret = tmp;
218 		memcpy(ret + rlen, kt->name, nlen + 1);
219 		rlen += nlen;
220 	}
221 	return ret;
222 }
223 
224 int
225 sshkey_names_valid2(const char *names, int allow_wildcard)
226 {
227 	char *s, *cp, *p;
228 	const struct keytype *kt;
229 	int type;
230 
231 	if (names == NULL || strcmp(names, "") == 0)
232 		return 0;
233 	if ((s = cp = strdup(names)) == NULL)
234 		return 0;
235 	for ((p = strsep(&cp, ",")); p && *p != '\0';
236 	    (p = strsep(&cp, ","))) {
237 		type = sshkey_type_from_name(p);
238 		if (type == KEY_UNSPEC) {
239 			if (allow_wildcard) {
240 				/*
241 				 * Try matching key types against the string.
242 				 * If any has a positive or negative match then
243 				 * the component is accepted.
244 				 */
245 				for (kt = keytypes; kt->type != -1; kt++) {
246 					if (match_pattern_list(kt->name,
247 					    p, 0) != 0)
248 						break;
249 				}
250 				if (kt->type != -1)
251 					continue;
252 			}
253 			free(s);
254 			return 0;
255 		}
256 	}
257 	free(s);
258 	return 1;
259 }
260 
261 u_int
262 sshkey_size(const struct sshkey *k)
263 {
264 	switch (k->type) {
265 #ifdef WITH_OPENSSL
266 	case KEY_RSA:
267 	case KEY_RSA_CERT:
268 #if OPENSSL_VERSION_NUMBER >= 0x10100000UL
269 		return RSA_bits(k->rsa);
270 #else
271 		return BN_num_bits(k->rsa->n);
272 #endif
273 	case KEY_DSA:
274 	case KEY_DSA_CERT:
275 #if OPENSSL_VERSION_NUMBER >= 0x10100000UL
276 		return DSA_bits(k->dsa);
277 #else
278 		return BN_num_bits(k->dsa->p);
279 #endif
280 	case KEY_ECDSA:
281 	case KEY_ECDSA_CERT:
282 		return sshkey_curve_nid_to_bits(k->ecdsa_nid);
283 #endif /* WITH_OPENSSL */
284 	case KEY_ED25519:
285 	case KEY_ED25519_CERT:
286 	case KEY_XMSS:
287 	case KEY_XMSS_CERT:
288 		return 256;	/* XXX */
289 	}
290 	return 0;
291 }
292 
293 static int
294 sshkey_type_is_valid_ca(int type)
295 {
296 	switch (type) {
297 	case KEY_RSA:
298 	case KEY_DSA:
299 	case KEY_ECDSA:
300 	case KEY_ED25519:
301 	case KEY_XMSS:
302 		return 1;
303 	default:
304 		return 0;
305 	}
306 }
307 
308 int
309 sshkey_is_cert(const struct sshkey *k)
310 {
311 	if (k == NULL)
312 		return 0;
313 	return sshkey_type_is_cert(k->type);
314 }
315 
316 /* Return the cert-less equivalent to a certified key type */
317 int
318 sshkey_type_plain(int type)
319 {
320 	switch (type) {
321 	case KEY_RSA_CERT:
322 		return KEY_RSA;
323 	case KEY_DSA_CERT:
324 		return KEY_DSA;
325 	case KEY_ECDSA_CERT:
326 		return KEY_ECDSA;
327 	case KEY_ED25519_CERT:
328 		return KEY_ED25519;
329 	case KEY_XMSS_CERT:
330 		return KEY_XMSS;
331 	default:
332 		return type;
333 	}
334 }
335 
336 #ifdef WITH_OPENSSL
337 /* XXX: these are really begging for a table-driven approach */
338 int
339 sshkey_curve_name_to_nid(const char *name)
340 {
341 	if (strcmp(name, "nistp256") == 0)
342 		return NID_X9_62_prime256v1;
343 	else if (strcmp(name, "nistp384") == 0)
344 		return NID_secp384r1;
345 	else if (strcmp(name, "nistp521") == 0)
346 		return NID_secp521r1;
347 	else
348 		return -1;
349 }
350 
351 u_int
352 sshkey_curve_nid_to_bits(int nid)
353 {
354 	switch (nid) {
355 	case NID_X9_62_prime256v1:
356 		return 256;
357 	case NID_secp384r1:
358 		return 384;
359 	case NID_secp521r1:
360 		return 521;
361 	default:
362 		return 0;
363 	}
364 }
365 
366 int
367 sshkey_ecdsa_bits_to_nid(int bits)
368 {
369 	switch (bits) {
370 	case 256:
371 		return NID_X9_62_prime256v1;
372 	case 384:
373 		return NID_secp384r1;
374 	case 521:
375 		return NID_secp521r1;
376 	default:
377 		return -1;
378 	}
379 }
380 
381 const char *
382 sshkey_curve_nid_to_name(int nid)
383 {
384 	switch (nid) {
385 	case NID_X9_62_prime256v1:
386 		return "nistp256";
387 	case NID_secp384r1:
388 		return "nistp384";
389 	case NID_secp521r1:
390 		return "nistp521";
391 	default:
392 		return NULL;
393 	}
394 }
395 
396 int
397 sshkey_ec_nid_to_hash_alg(int nid)
398 {
399 	int kbits = sshkey_curve_nid_to_bits(nid);
400 
401 	if (kbits <= 0)
402 		return -1;
403 
404 	/* RFC5656 section 6.2.1 */
405 	if (kbits <= 256)
406 		return SSH_DIGEST_SHA256;
407 	else if (kbits <= 384)
408 		return SSH_DIGEST_SHA384;
409 	else
410 		return SSH_DIGEST_SHA512;
411 }
412 #endif /* WITH_OPENSSL */
413 
414 static void
415 cert_free(struct sshkey_cert *cert)
416 {
417 	u_int i;
418 
419 	if (cert == NULL)
420 		return;
421 	sshbuf_free(cert->certblob);
422 	sshbuf_free(cert->critical);
423 	sshbuf_free(cert->extensions);
424 	free(cert->key_id);
425 	for (i = 0; i < cert->nprincipals; i++)
426 		free(cert->principals[i]);
427 	free(cert->principals);
428 	sshkey_free(cert->signature_key);
429 	freezero(cert, sizeof(*cert));
430 }
431 
432 static struct sshkey_cert *
433 cert_new(void)
434 {
435 	struct sshkey_cert *cert;
436 
437 	if ((cert = calloc(1, sizeof(*cert))) == NULL)
438 		return NULL;
439 	if ((cert->certblob = sshbuf_new()) == NULL ||
440 	    (cert->critical = sshbuf_new()) == NULL ||
441 	    (cert->extensions = sshbuf_new()) == NULL) {
442 		cert_free(cert);
443 		return NULL;
444 	}
445 	cert->key_id = NULL;
446 	cert->principals = NULL;
447 	cert->signature_key = NULL;
448 	return cert;
449 }
450 
451 struct sshkey *
452 sshkey_new(int type)
453 {
454 	struct sshkey *k;
455 #ifdef WITH_OPENSSL
456 	RSA *rsa;
457 	DSA *dsa;
458 #endif /* WITH_OPENSSL */
459 
460 	if ((k = calloc(1, sizeof(*k))) == NULL)
461 		return NULL;
462 	k->type = type;
463 	k->ecdsa = NULL;
464 	k->ecdsa_nid = -1;
465 	k->dsa = NULL;
466 	k->rsa = NULL;
467 	k->cert = NULL;
468 	k->ed25519_sk = NULL;
469 	k->ed25519_pk = NULL;
470 	k->xmss_sk = NULL;
471 	k->xmss_pk = NULL;
472 	switch (k->type) {
473 #ifdef WITH_OPENSSL
474 	case KEY_RSA:
475 	case KEY_RSA_CERT:
476 		{
477 		BIGNUM *n=NULL, *e=NULL; /* just allocate */
478 		if ((rsa = RSA_new()) == NULL ||
479 		    (n = BN_new()) == NULL ||
480 		    (e = BN_new()) == NULL) {
481 			BN_free(n);
482 			BN_free(e);
483 			if (rsa != NULL)
484 				RSA_free(rsa);
485 			free(k);
486 			return NULL;
487 		}
488 		BN_clear(n); BN_clear(e);
489 		if (RSA_set0_key(rsa, n, e, NULL) == 0)
490 			return NULL;
491 		n = e = NULL;
492 		}
493 		k->rsa = rsa;
494 		break;
495 	case KEY_DSA:
496 	case KEY_DSA_CERT:
497 		{
498 		BIGNUM *p=NULL, *q=NULL, *g=NULL, *pubkey=NULL; /* just allocate */
499 		if ((dsa = DSA_new()) == NULL ||
500 		    (p = BN_new()) == NULL ||
501 		    (q = BN_new()) == NULL ||
502 		    (g = BN_new()) == NULL ||
503 		    (pubkey = BN_new()) == NULL) {
504 			BN_free(p);
505 			BN_free(q);
506 			BN_free(g);
507 			BN_free(pubkey);
508 			if (dsa != NULL)
509 				DSA_free(dsa);
510 			free(k);
511 			return NULL;
512 		}
513 		if (DSA_set0_pqg(dsa, p, q, g) == 0) {
514 			BN_free(p); BN_free(q); BN_free(g);
515 			BN_free(pubkey);
516 			return NULL;
517 		}
518 		p = q = g = NULL;
519 		if (DSA_set0_key(dsa, pubkey, NULL) == 0) {
520 			BN_free(pubkey);
521 			return NULL;
522 		}
523 		pubkey = NULL;
524 		}
525 		k->dsa = dsa;
526 		break;
527 	case KEY_ECDSA:
528 	case KEY_ECDSA_CERT:
529 		/* Cannot do anything until we know the group */
530 		break;
531 #endif /* WITH_OPENSSL */
532 	case KEY_ED25519:
533 	case KEY_ED25519_CERT:
534 	case KEY_XMSS:
535 	case KEY_XMSS_CERT:
536 		/* no need to prealloc */
537 		break;
538 	case KEY_UNSPEC:
539 		break;
540 	default:
541 		free(k);
542 		return NULL;
543 	}
544 
545 	if (sshkey_is_cert(k)) {
546 		if ((k->cert = cert_new()) == NULL) {
547 			sshkey_free(k);
548 			return NULL;
549 		}
550 	}
551 
552 	return k;
553 }
554 
555 int
556 sshkey_add_private(struct sshkey *k)
557 {
558 	switch (k->type) {
559 #ifdef WITH_OPENSSL
560 	case KEY_RSA:
561 	case KEY_RSA_CERT:
562 #if OPENSSL_VERSION_NUMBER >= 0x10100000UL
563 		/* Allocate BIGNUM. This is a mess.
564 		   For OpenSSL 1.1.x API these shouldn't be mandatory,
565 		   but some regression tests for non-NULL pointer of
566 		   the data. */
567 #define new_or_dup(bn, nbn) \
568 		if (bn == NULL) { \
569 			if ((nbn = BN_new()) == NULL) \
570 				return SSH_ERR_ALLOC_FAIL; \
571 		} else { \
572 			/* otherwise use-after-free will occur */ \
573 			if ((nbn = BN_dup(bn)) == NULL) \
574 				return SSH_ERR_ALLOC_FAIL; \
575 		}
576 		{
577 		const BIGNUM *d, *iqmp, *q, *p, *dmq1, *dmp1; /* allocate if NULL */
578 		BIGNUM *nd, *niqmp, *nq, *np, *ndmq1, *ndmp1;
579 
580 		RSA_get0_key(k->rsa, NULL, NULL, &d);
581 		RSA_get0_factors(k->rsa, &p, &q);
582 		RSA_get0_crt_params(k->rsa, &dmp1, &dmq1, &iqmp);
583 
584 		new_or_dup(d, nd);
585 		new_or_dup(iqmp, niqmp);
586 		new_or_dup(q, nq);
587 		new_or_dup(p, np);
588 		new_or_dup(dmq1, ndmq1);
589 		new_or_dup(dmp1, ndmp1);
590 
591 		if (RSA_set0_key(k->rsa, NULL, NULL, nd) == 0)
592 			goto error1;
593 		nd = NULL;
594 		if (RSA_set0_factors(k->rsa, np, nq) == 0)
595 			goto error1;
596 		np = nq = NULL;
597 		if (RSA_set0_crt_params(k->rsa, ndmp1, ndmq1, niqmp) == 0) {
598 error1:
599 			BN_free(nd);
600 			BN_free(np); BN_free(nq);
601 			BN_free(ndmp1); BN_free(ndmq1); BN_free(niqmp);
602 			return SSH_ERR_LIBCRYPTO_ERROR;
603 		}
604 		ndmp1 = ndmq1 = niqmp = NULL;
605 		}
606 #else
607 #define bn_maybe_alloc_failed(p) (p == NULL && (p = BN_new()) == NULL)
608 		if (bn_maybe_alloc_failed(k->rsa->d) ||
609 		    bn_maybe_alloc_failed(k->rsa->iqmp) ||
610 		    bn_maybe_alloc_failed(k->rsa->q) ||
611 		    bn_maybe_alloc_failed(k->rsa->p) ||
612 		    bn_maybe_alloc_failed(k->rsa->dmq1) ||
613 		    bn_maybe_alloc_failed(k->rsa->dmp1))
614 			return SSH_ERR_ALLOC_FAIL;
615 #endif
616 		break;
617 	case KEY_DSA:
618 	case KEY_DSA_CERT:
619 #if OPENSSL_VERSION_NUMBER >= 0x10100000UL
620 		{
621 		const BIGNUM *priv_key;
622 		BIGNUM *npriv_key;
623 		DSA_get0_key(k->dsa, NULL, &priv_key);
624 		new_or_dup(priv_key, npriv_key);
625 		if (DSA_set0_key(k->dsa, NULL, npriv_key) == 0) {
626 			BN_free(npriv_key);
627 			return SSH_ERR_LIBCRYPTO_ERROR;
628 		}
629 		}
630 #else
631 		if (bn_maybe_alloc_failed(k->dsa->priv_key))
632 			return SSH_ERR_ALLOC_FAIL;
633 #endif
634 		break;
635 #undef bn_maybe_alloc_failed
636 #undef new_or_dup
637 	case KEY_ECDSA:
638 	case KEY_ECDSA_CERT:
639 		/* Cannot do anything until we know the group */
640 		break;
641 #endif /* WITH_OPENSSL */
642 	case KEY_ED25519:
643 	case KEY_ED25519_CERT:
644 	case KEY_XMSS:
645 	case KEY_XMSS_CERT:
646 		/* no need to prealloc */
647 		break;
648 	case KEY_UNSPEC:
649 		break;
650 	default:
651 		return SSH_ERR_INVALID_ARGUMENT;
652 	}
653 	return 0;
654 }
655 
656 struct sshkey *
657 sshkey_new_private(int type)
658 {
659 	struct sshkey *k = sshkey_new(type);
660 
661 	if (k == NULL)
662 		return NULL;
663 	if (sshkey_add_private(k) != 0) {
664 		sshkey_free(k);
665 		return NULL;
666 	}
667 	return k;
668 }
669 
670 void
671 sshkey_free(struct sshkey *k)
672 {
673 	if (k == NULL)
674 		return;
675 	switch (k->type) {
676 #ifdef WITH_OPENSSL
677 	case KEY_RSA:
678 	case KEY_RSA_CERT:
679 		RSA_free(k->rsa);
680 		k->rsa = NULL;
681 		break;
682 	case KEY_DSA:
683 	case KEY_DSA_CERT:
684 		DSA_free(k->dsa);
685 		k->dsa = NULL;
686 		break;
687 	case KEY_ECDSA:
688 	case KEY_ECDSA_CERT:
689 		EC_KEY_free(k->ecdsa);
690 		k->ecdsa = NULL;
691 		break;
692 #endif /* WITH_OPENSSL */
693 	case KEY_ED25519:
694 	case KEY_ED25519_CERT:
695 		freezero(k->ed25519_pk, ED25519_PK_SZ);
696 		k->ed25519_pk = NULL;
697 		freezero(k->ed25519_sk, ED25519_SK_SZ);
698 		k->ed25519_sk = NULL;
699 		break;
700 #ifdef WITH_XMSS
701 	case KEY_XMSS:
702 	case KEY_XMSS_CERT:
703 		freezero(k->xmss_pk, sshkey_xmss_pklen(k));
704 		k->xmss_pk = NULL;
705 		freezero(k->xmss_sk, sshkey_xmss_sklen(k));
706 		k->xmss_sk = NULL;
707 		sshkey_xmss_free_state(k);
708 		free(k->xmss_name);
709 		k->xmss_name = NULL;
710 		free(k->xmss_filename);
711 		k->xmss_filename = NULL;
712 		break;
713 #endif /* WITH_XMSS */
714 	case KEY_UNSPEC:
715 		break;
716 	default:
717 		break;
718 	}
719 	if (sshkey_is_cert(k))
720 		cert_free(k->cert);
721 	freezero(k, sizeof(*k));
722 }
723 
724 static int
725 cert_compare(struct sshkey_cert *a, struct sshkey_cert *b)
726 {
727 	if (a == NULL && b == NULL)
728 		return 1;
729 	if (a == NULL || b == NULL)
730 		return 0;
731 	if (sshbuf_len(a->certblob) != sshbuf_len(b->certblob))
732 		return 0;
733 	if (timingsafe_bcmp(sshbuf_ptr(a->certblob), sshbuf_ptr(b->certblob),
734 	    sshbuf_len(a->certblob)) != 0)
735 		return 0;
736 	return 1;
737 }
738 
739 /*
740  * Compare public portions of key only, allowing comparisons between
741  * certificates and plain keys too.
742  */
743 int
744 sshkey_equal_public(const struct sshkey *a, const struct sshkey *b)
745 {
746 #ifdef WITH_OPENSSL
747 	BN_CTX *bnctx;
748 #endif /* WITH_OPENSSL */
749 
750 	if (a == NULL || b == NULL ||
751 	    sshkey_type_plain(a->type) != sshkey_type_plain(b->type))
752 		return 0;
753 
754 	switch (a->type) {
755 #ifdef WITH_OPENSSL
756 	case KEY_RSA_CERT:
757 	case KEY_RSA:
758 		{
759 		const BIGNUM *a_e, *b_e, *a_n, *b_n;
760 		const BIGNUM *a_d, *b_d;
761 		if (a->rsa == NULL) return 0;
762 		if (b->rsa == NULL) return 0;
763 		RSA_get0_key(a->rsa, &a_n, &a_e, &a_d);
764 		RSA_get0_key(b->rsa, &b_n, &b_e, &b_d);
765 		return
766 		    BN_cmp(a_e, b_e) == 0 &&
767 		    BN_cmp(a_n, b_n) == 0;
768 		}
769 	case KEY_DSA_CERT:
770 	case KEY_DSA:
771 		{
772 		const BIGNUM *a_p, *a_q, *a_g, *a_pub_key;
773 		const BIGNUM *b_p, *b_q, *b_g, *b_pub_key;
774 		if (a->dsa == NULL) return 0;
775 		if (b->dsa == NULL) return 0;
776 		DSA_get0_pqg(a->dsa, &a_p, &a_q, &a_g);
777 		DSA_get0_pqg(b->dsa, &b_p, &b_q, &b_g);
778 		DSA_get0_key(a->dsa, &a_pub_key, NULL);
779 		DSA_get0_key(b->dsa, &b_pub_key, NULL);
780 		return
781 		    BN_cmp(a_p, b_p) == 0 &&
782 		    BN_cmp(a_q, b_q) == 0 &&
783 		    BN_cmp(a_g, b_g) == 0 &&
784 		    BN_cmp(a_pub_key, b_pub_key) == 0;
785 		}
786 	case KEY_ECDSA_CERT:
787 	case KEY_ECDSA:
788 		if (a->ecdsa == NULL || b->ecdsa == NULL ||
789 		    EC_KEY_get0_public_key(a->ecdsa) == NULL ||
790 		    EC_KEY_get0_public_key(b->ecdsa) == NULL)
791 			return 0;
792 		if ((bnctx = BN_CTX_new()) == NULL)
793 			return 0;
794 		if (EC_GROUP_cmp(EC_KEY_get0_group(a->ecdsa),
795 		    EC_KEY_get0_group(b->ecdsa), bnctx) != 0 ||
796 		    EC_POINT_cmp(EC_KEY_get0_group(a->ecdsa),
797 		    EC_KEY_get0_public_key(a->ecdsa),
798 		    EC_KEY_get0_public_key(b->ecdsa), bnctx) != 0) {
799 			BN_CTX_free(bnctx);
800 			return 0;
801 		}
802 		BN_CTX_free(bnctx);
803 		return 1;
804 #endif /* WITH_OPENSSL */
805 	case KEY_ED25519:
806 	case KEY_ED25519_CERT:
807 		return a->ed25519_pk != NULL && b->ed25519_pk != NULL &&
808 		    memcmp(a->ed25519_pk, b->ed25519_pk, ED25519_PK_SZ) == 0;
809 #ifdef WITH_XMSS
810 	case KEY_XMSS:
811 	case KEY_XMSS_CERT:
812 		return a->xmss_pk != NULL && b->xmss_pk != NULL &&
813 		    sshkey_xmss_pklen(a) == sshkey_xmss_pklen(b) &&
814 		    memcmp(a->xmss_pk, b->xmss_pk, sshkey_xmss_pklen(a)) == 0;
815 #endif /* WITH_XMSS */
816 	default:
817 		return 0;
818 	}
819 	/* NOTREACHED */
820 }
821 
822 int
823 sshkey_equal(const struct sshkey *a, const struct sshkey *b)
824 {
825 	if (a == NULL || b == NULL || a->type != b->type)
826 		return 0;
827 	if (sshkey_is_cert(a)) {
828 		if (!cert_compare(a->cert, b->cert))
829 			return 0;
830 	}
831 	return sshkey_equal_public(a, b);
832 }
833 
834 static int
835 to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain,
836   enum sshkey_serialize_rep opts)
837 {
838 	int type, ret = SSH_ERR_INTERNAL_ERROR;
839 	const char *typename;
840 
841 	if (key == NULL)
842 		return SSH_ERR_INVALID_ARGUMENT;
843 
844 	if (sshkey_is_cert(key)) {
845 		if (key->cert == NULL)
846 			return SSH_ERR_EXPECTED_CERT;
847 		if (sshbuf_len(key->cert->certblob) == 0)
848 			return SSH_ERR_KEY_LACKS_CERTBLOB;
849 	}
850 	type = force_plain ? sshkey_type_plain(key->type) : key->type;
851 	typename = sshkey_ssh_name_from_type_nid(type, key->ecdsa_nid);
852 
853 	switch (type) {
854 #ifdef WITH_OPENSSL
855 	case KEY_DSA_CERT:
856 	case KEY_ECDSA_CERT:
857 	case KEY_RSA_CERT:
858 #endif /* WITH_OPENSSL */
859 	case KEY_ED25519_CERT:
860 #ifdef WITH_XMSS
861 	case KEY_XMSS_CERT:
862 #endif /* WITH_XMSS */
863 		/* Use the existing blob */
864 		/* XXX modified flag? */
865 		if ((ret = sshbuf_putb(b, key->cert->certblob)) != 0)
866 			return ret;
867 		break;
868 #ifdef WITH_OPENSSL
869 	case KEY_DSA:
870 		if (key->dsa == NULL)
871 			return SSH_ERR_INVALID_ARGUMENT;
872 		{
873 		const BIGNUM *p, *q, *g, *pub_key;
874 		DSA_get0_pqg(key->dsa, &p, &q, &g);
875 		DSA_get0_key(key->dsa, &pub_key, NULL);
876 		if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
877 		    (ret = sshbuf_put_bignum2(b, p)) != 0 ||
878 		    (ret = sshbuf_put_bignum2(b, q)) != 0 ||
879 		    (ret = sshbuf_put_bignum2(b, g)) != 0 ||
880 		    (ret = sshbuf_put_bignum2(b, pub_key)) != 0)
881 			return ret;
882 		}
883 		break;
884 	case KEY_ECDSA:
885 		if (key->ecdsa == NULL)
886 			return SSH_ERR_INVALID_ARGUMENT;
887 		if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
888 		    (ret = sshbuf_put_cstring(b,
889 		    sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 ||
890 		    (ret = sshbuf_put_eckey(b, key->ecdsa)) != 0)
891 			return ret;
892 		break;
893 	case KEY_RSA:
894 		if (key->rsa == NULL)
895 			return SSH_ERR_INVALID_ARGUMENT;
896 		{
897 		const BIGNUM *e, *n;
898 		RSA_get0_key(key->rsa, &n, &e, NULL);
899 		if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
900 		    (ret = sshbuf_put_bignum2(b, e)) != 0 ||
901 		    (ret = sshbuf_put_bignum2(b, n)) != 0)
902 			return ret;
903 		}
904 		break;
905 #endif /* WITH_OPENSSL */
906 	case KEY_ED25519:
907 		if (key->ed25519_pk == NULL)
908 			return SSH_ERR_INVALID_ARGUMENT;
909 		if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
910 		    (ret = sshbuf_put_string(b,
911 		    key->ed25519_pk, ED25519_PK_SZ)) != 0)
912 			return ret;
913 		break;
914 #ifdef WITH_XMSS
915 	case KEY_XMSS:
916 		if (key->xmss_name == NULL || key->xmss_pk == NULL ||
917 		    sshkey_xmss_pklen(key) == 0)
918 			return SSH_ERR_INVALID_ARGUMENT;
919 		if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
920 		    (ret = sshbuf_put_cstring(b, key->xmss_name)) != 0 ||
921 		    (ret = sshbuf_put_string(b,
922 		    key->xmss_pk, sshkey_xmss_pklen(key))) != 0 ||
923 		    (ret = sshkey_xmss_serialize_pk_info(key, b, opts)) != 0)
924 			return ret;
925 		break;
926 #endif /* WITH_XMSS */
927 	default:
928 		return SSH_ERR_KEY_TYPE_UNKNOWN;
929 	}
930 	return 0;
931 }
932 
933 int
934 sshkey_putb(const struct sshkey *key, struct sshbuf *b)
935 {
936 	return to_blob_buf(key, b, 0, SSHKEY_SERIALIZE_DEFAULT);
937 }
938 
939 int
940 sshkey_puts_opts(const struct sshkey *key, struct sshbuf *b,
941     enum sshkey_serialize_rep opts)
942 {
943 	struct sshbuf *tmp;
944 	int r;
945 
946 	if ((tmp = sshbuf_new()) == NULL)
947 		return SSH_ERR_ALLOC_FAIL;
948 	r = to_blob_buf(key, tmp, 0, opts);
949 	if (r == 0)
950 		r = sshbuf_put_stringb(b, tmp);
951 	sshbuf_free(tmp);
952 	return r;
953 }
954 
955 int
956 sshkey_puts(const struct sshkey *key, struct sshbuf *b)
957 {
958 	return sshkey_puts_opts(key, b, SSHKEY_SERIALIZE_DEFAULT);
959 }
960 
961 int
962 sshkey_putb_plain(const struct sshkey *key, struct sshbuf *b)
963 {
964 	return to_blob_buf(key, b, 1, SSHKEY_SERIALIZE_DEFAULT);
965 }
966 
967 static int
968 to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp, int force_plain,
969     enum sshkey_serialize_rep opts)
970 {
971 	int ret = SSH_ERR_INTERNAL_ERROR;
972 	size_t len;
973 	struct sshbuf *b = NULL;
974 
975 	if (lenp != NULL)
976 		*lenp = 0;
977 	if (blobp != NULL)
978 		*blobp = NULL;
979 	if ((b = sshbuf_new()) == NULL)
980 		return SSH_ERR_ALLOC_FAIL;
981 	if ((ret = to_blob_buf(key, b, force_plain, opts)) != 0)
982 		goto out;
983 	len = sshbuf_len(b);
984 	if (lenp != NULL)
985 		*lenp = len;
986 	if (blobp != NULL) {
987 		if ((*blobp = malloc(len)) == NULL) {
988 			ret = SSH_ERR_ALLOC_FAIL;
989 			goto out;
990 		}
991 		memcpy(*blobp, sshbuf_ptr(b), len);
992 	}
993 	ret = 0;
994  out:
995 	sshbuf_free(b);
996 	return ret;
997 }
998 
999 int
1000 sshkey_to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp)
1001 {
1002 	return to_blob(key, blobp, lenp, 0, SSHKEY_SERIALIZE_DEFAULT);
1003 }
1004 
1005 int
1006 sshkey_plain_to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp)
1007 {
1008 	return to_blob(key, blobp, lenp, 1, SSHKEY_SERIALIZE_DEFAULT);
1009 }
1010 
1011 int
1012 sshkey_fingerprint_raw(const struct sshkey *k, int dgst_alg,
1013     u_char **retp, size_t *lenp)
1014 {
1015 	u_char *blob = NULL, *ret = NULL;
1016 	size_t blob_len = 0;
1017 	int r = SSH_ERR_INTERNAL_ERROR;
1018 
1019 	if (retp != NULL)
1020 		*retp = NULL;
1021 	if (lenp != NULL)
1022 		*lenp = 0;
1023 	if (ssh_digest_bytes(dgst_alg) == 0) {
1024 		r = SSH_ERR_INVALID_ARGUMENT;
1025 		goto out;
1026 	}
1027 	if ((r = to_blob(k, &blob, &blob_len, 1, SSHKEY_SERIALIZE_DEFAULT))
1028 	    != 0)
1029 		goto out;
1030 	if ((ret = calloc(1, SSH_DIGEST_MAX_LENGTH)) == NULL) {
1031 		r = SSH_ERR_ALLOC_FAIL;
1032 		goto out;
1033 	}
1034 	if ((r = ssh_digest_memory(dgst_alg, blob, blob_len,
1035 	    ret, SSH_DIGEST_MAX_LENGTH)) != 0)
1036 		goto out;
1037 	/* success */
1038 	if (retp != NULL) {
1039 		*retp = ret;
1040 		ret = NULL;
1041 	}
1042 	if (lenp != NULL)
1043 		*lenp = ssh_digest_bytes(dgst_alg);
1044 	r = 0;
1045  out:
1046 	free(ret);
1047 	if (blob != NULL) {
1048 		explicit_bzero(blob, blob_len);
1049 		free(blob);
1050 	}
1051 	return r;
1052 }
1053 
1054 static char *
1055 fingerprint_b64(const char *alg, u_char *dgst_raw, size_t dgst_raw_len)
1056 {
1057 	char *ret;
1058 	size_t plen = strlen(alg) + 1;
1059 	size_t rlen = ((dgst_raw_len + 2) / 3) * 4 + plen + 1;
1060 	int r;
1061 
1062 	if (dgst_raw_len > 65536 || (ret = calloc(1, rlen)) == NULL)
1063 		return NULL;
1064 	strlcpy(ret, alg, rlen);
1065 	strlcat(ret, ":", rlen);
1066 	if (dgst_raw_len == 0)
1067 		return ret;
1068 	if ((r = b64_ntop(dgst_raw, dgst_raw_len,
1069 	    ret + plen, rlen - plen)) == -1) {
1070 		freezero(ret, rlen);
1071 		return NULL;
1072 	}
1073 	/* Trim padding characters from end */
1074 	ret[strcspn(ret, "=")] = '\0';
1075 	return ret;
1076 }
1077 
1078 static char *
1079 fingerprint_hex(const char *alg, u_char *dgst_raw, size_t dgst_raw_len)
1080 {
1081 	char *retval, hex[5];
1082 	size_t i, rlen = dgst_raw_len * 3 + strlen(alg) + 2;
1083 
1084 	if (dgst_raw_len > 65536 || (retval = calloc(1, rlen)) == NULL)
1085 		return NULL;
1086 	strlcpy(retval, alg, rlen);
1087 	strlcat(retval, ":", rlen);
1088 	for (i = 0; i < dgst_raw_len; i++) {
1089 		snprintf(hex, sizeof(hex), "%s%02x",
1090 		    i > 0 ? ":" : "", dgst_raw[i]);
1091 		strlcat(retval, hex, rlen);
1092 	}
1093 	return retval;
1094 }
1095 
1096 static char *
1097 fingerprint_bubblebabble(u_char *dgst_raw, size_t dgst_raw_len)
1098 {
1099 	char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' };
1100 	char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm',
1101 	    'n', 'p', 'r', 's', 't', 'v', 'z', 'x' };
1102 	u_int i, j = 0, rounds, seed = 1;
1103 	char *retval;
1104 
1105 	rounds = (dgst_raw_len / 2) + 1;
1106 	if ((retval = calloc(rounds, 6)) == NULL)
1107 		return NULL;
1108 	retval[j++] = 'x';
1109 	for (i = 0; i < rounds; i++) {
1110 		u_int idx0, idx1, idx2, idx3, idx4;
1111 		if ((i + 1 < rounds) || (dgst_raw_len % 2 != 0)) {
1112 			idx0 = (((((u_int)(dgst_raw[2 * i])) >> 6) & 3) +
1113 			    seed) % 6;
1114 			idx1 = (((u_int)(dgst_raw[2 * i])) >> 2) & 15;
1115 			idx2 = ((((u_int)(dgst_raw[2 * i])) & 3) +
1116 			    (seed / 6)) % 6;
1117 			retval[j++] = vowels[idx0];
1118 			retval[j++] = consonants[idx1];
1119 			retval[j++] = vowels[idx2];
1120 			if ((i + 1) < rounds) {
1121 				idx3 = (((u_int)(dgst_raw[(2 * i) + 1])) >> 4) & 15;
1122 				idx4 = (((u_int)(dgst_raw[(2 * i) + 1]))) & 15;
1123 				retval[j++] = consonants[idx3];
1124 				retval[j++] = '-';
1125 				retval[j++] = consonants[idx4];
1126 				seed = ((seed * 5) +
1127 				    ((((u_int)(dgst_raw[2 * i])) * 7) +
1128 				    ((u_int)(dgst_raw[(2 * i) + 1])))) % 36;
1129 			}
1130 		} else {
1131 			idx0 = seed % 6;
1132 			idx1 = 16;
1133 			idx2 = seed / 6;
1134 			retval[j++] = vowels[idx0];
1135 			retval[j++] = consonants[idx1];
1136 			retval[j++] = vowels[idx2];
1137 		}
1138 	}
1139 	retval[j++] = 'x';
1140 	retval[j++] = '\0';
1141 	return retval;
1142 }
1143 
1144 /*
1145  * Draw an ASCII-Art representing the fingerprint so human brain can
1146  * profit from its built-in pattern recognition ability.
1147  * This technique is called "random art" and can be found in some
1148  * scientific publications like this original paper:
1149  *
1150  * "Hash Visualization: a New Technique to improve Real-World Security",
1151  * Perrig A. and Song D., 1999, International Workshop on Cryptographic
1152  * Techniques and E-Commerce (CrypTEC '99)
1153  * sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf
1154  *
1155  * The subject came up in a talk by Dan Kaminsky, too.
1156  *
1157  * If you see the picture is different, the key is different.
1158  * If the picture looks the same, you still know nothing.
1159  *
1160  * The algorithm used here is a worm crawling over a discrete plane,
1161  * leaving a trace (augmenting the field) everywhere it goes.
1162  * Movement is taken from dgst_raw 2bit-wise.  Bumping into walls
1163  * makes the respective movement vector be ignored for this turn.
1164  * Graphs are not unambiguous, because circles in graphs can be
1165  * walked in either direction.
1166  */
1167 
1168 /*
1169  * Field sizes for the random art.  Have to be odd, so the starting point
1170  * can be in the exact middle of the picture, and FLDBASE should be >=8 .
1171  * Else pictures would be too dense, and drawing the frame would
1172  * fail, too, because the key type would not fit in anymore.
1173  */
1174 #define	FLDBASE		8
1175 #define	FLDSIZE_Y	(FLDBASE + 1)
1176 #define	FLDSIZE_X	(FLDBASE * 2 + 1)
1177 static char *
1178 fingerprint_randomart(const char *alg, u_char *dgst_raw, size_t dgst_raw_len,
1179     const struct sshkey *k)
1180 {
1181 	/*
1182 	 * Chars to be used after each other every time the worm
1183 	 * intersects with itself.  Matter of taste.
1184 	 */
1185 	const char	*augmentation_string = " .o+=*BOX@%&#/^SE";
1186 	char	*retval, *p, title[FLDSIZE_X], hash[FLDSIZE_X];
1187 	u_char	 field[FLDSIZE_X][FLDSIZE_Y];
1188 	size_t	 i, tlen, hlen;
1189 	u_int	 b;
1190 	int	 x, y, r;
1191 	size_t	 len = strlen(augmentation_string) - 1;
1192 
1193 	if ((retval = calloc((FLDSIZE_X + 3), (FLDSIZE_Y + 2))) == NULL)
1194 		return NULL;
1195 
1196 	/* initialize field */
1197 	memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char));
1198 	x = FLDSIZE_X / 2;
1199 	y = FLDSIZE_Y / 2;
1200 
1201 	/* process raw key */
1202 	for (i = 0; i < dgst_raw_len; i++) {
1203 		int input;
1204 		/* each byte conveys four 2-bit move commands */
1205 		input = dgst_raw[i];
1206 		for (b = 0; b < 4; b++) {
1207 			/* evaluate 2 bit, rest is shifted later */
1208 			x += (input & 0x1) ? 1 : -1;
1209 			y += (input & 0x2) ? 1 : -1;
1210 
1211 			/* assure we are still in bounds */
1212 			x = MAXIMUM(x, 0);
1213 			y = MAXIMUM(y, 0);
1214 			x = MINIMUM(x, FLDSIZE_X - 1);
1215 			y = MINIMUM(y, FLDSIZE_Y - 1);
1216 
1217 			/* augment the field */
1218 			if (field[x][y] < len - 2)
1219 				field[x][y]++;
1220 			input = input >> 2;
1221 		}
1222 	}
1223 
1224 	/* mark starting point and end point*/
1225 	field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1;
1226 	field[x][y] = len;
1227 
1228 	/* assemble title */
1229 	r = snprintf(title, sizeof(title), "[%s %u]",
1230 		sshkey_type(k), sshkey_size(k));
1231 	/* If [type size] won't fit, then try [type]; fits "[ED25519-CERT]" */
1232 	if (r < 0 || r > (int)sizeof(title))
1233 		r = snprintf(title, sizeof(title), "[%s]", sshkey_type(k));
1234 	tlen = (r <= 0) ? 0 : strlen(title);
1235 
1236 	/* assemble hash ID. */
1237 	r = snprintf(hash, sizeof(hash), "[%s]", alg);
1238 	hlen = (r <= 0) ? 0 : strlen(hash);
1239 
1240 	/* output upper border */
1241 	p = retval;
1242 	*p++ = '+';
1243 	for (i = 0; i < (FLDSIZE_X - tlen) / 2; i++)
1244 		*p++ = '-';
1245 	memcpy(p, title, tlen);
1246 	p += tlen;
1247 	for (i += tlen; i < FLDSIZE_X; i++)
1248 		*p++ = '-';
1249 	*p++ = '+';
1250 	*p++ = '\n';
1251 
1252 	/* output content */
1253 	for (y = 0; y < FLDSIZE_Y; y++) {
1254 		*p++ = '|';
1255 		for (x = 0; x < FLDSIZE_X; x++)
1256 			*p++ = augmentation_string[MINIMUM(field[x][y], len)];
1257 		*p++ = '|';
1258 		*p++ = '\n';
1259 	}
1260 
1261 	/* output lower border */
1262 	*p++ = '+';
1263 	for (i = 0; i < (FLDSIZE_X - hlen) / 2; i++)
1264 		*p++ = '-';
1265 	memcpy(p, hash, hlen);
1266 	p += hlen;
1267 	for (i += hlen; i < FLDSIZE_X; i++)
1268 		*p++ = '-';
1269 	*p++ = '+';
1270 
1271 	return retval;
1272 }
1273 
1274 char *
1275 sshkey_fingerprint(const struct sshkey *k, int dgst_alg,
1276     enum sshkey_fp_rep dgst_rep)
1277 {
1278 	char *retval = NULL;
1279 	u_char *dgst_raw;
1280 	size_t dgst_raw_len;
1281 
1282 	if (sshkey_fingerprint_raw(k, dgst_alg, &dgst_raw, &dgst_raw_len) != 0)
1283 		return NULL;
1284 	switch (dgst_rep) {
1285 	case SSH_FP_DEFAULT:
1286 		if (dgst_alg == SSH_DIGEST_MD5) {
1287 			retval = fingerprint_hex(ssh_digest_alg_name(dgst_alg),
1288 			    dgst_raw, dgst_raw_len);
1289 		} else {
1290 			retval = fingerprint_b64(ssh_digest_alg_name(dgst_alg),
1291 			    dgst_raw, dgst_raw_len);
1292 		}
1293 		break;
1294 	case SSH_FP_HEX:
1295 		retval = fingerprint_hex(ssh_digest_alg_name(dgst_alg),
1296 		    dgst_raw, dgst_raw_len);
1297 		break;
1298 	case SSH_FP_BASE64:
1299 		retval = fingerprint_b64(ssh_digest_alg_name(dgst_alg),
1300 		    dgst_raw, dgst_raw_len);
1301 		break;
1302 	case SSH_FP_BUBBLEBABBLE:
1303 		retval = fingerprint_bubblebabble(dgst_raw, dgst_raw_len);
1304 		break;
1305 	case SSH_FP_RANDOMART:
1306 		retval = fingerprint_randomart(ssh_digest_alg_name(dgst_alg),
1307 		    dgst_raw, dgst_raw_len, k);
1308 		break;
1309 	default:
1310 		explicit_bzero(dgst_raw, dgst_raw_len);
1311 		free(dgst_raw);
1312 		return NULL;
1313 	}
1314 	explicit_bzero(dgst_raw, dgst_raw_len);
1315 	free(dgst_raw);
1316 	return retval;
1317 }
1318 
1319 static int
1320 peek_type_nid(const char *s, size_t l, int *nid)
1321 {
1322 	const struct keytype *kt;
1323 
1324 	for (kt = keytypes; kt->type != -1; kt++) {
1325 		if (kt->name == NULL || strlen(kt->name) != l)
1326 			continue;
1327 		if (memcmp(s, kt->name, l) == 0) {
1328 			*nid = -1;
1329 			if (kt->type == KEY_ECDSA || kt->type == KEY_ECDSA_CERT)
1330 				*nid = kt->nid;
1331 			return kt->type;
1332 		}
1333 	}
1334 	return KEY_UNSPEC;
1335 }
1336 
1337 
1338 /* XXX this can now be made const char * */
1339 int
1340 sshkey_read(struct sshkey *ret, char **cpp)
1341 {
1342 	struct sshkey *k;
1343 	char *cp, *blobcopy;
1344 	size_t space;
1345 	int r, type, curve_nid = -1;
1346 	struct sshbuf *blob;
1347 
1348 	if (ret == NULL)
1349 		return SSH_ERR_INVALID_ARGUMENT;
1350 
1351 	switch (ret->type) {
1352 	case KEY_UNSPEC:
1353 	case KEY_RSA:
1354 	case KEY_DSA:
1355 	case KEY_ECDSA:
1356 	case KEY_ED25519:
1357 	case KEY_DSA_CERT:
1358 	case KEY_ECDSA_CERT:
1359 	case KEY_RSA_CERT:
1360 	case KEY_ED25519_CERT:
1361 #ifdef WITH_XMSS
1362 	case KEY_XMSS:
1363 	case KEY_XMSS_CERT:
1364 #endif /* WITH_XMSS */
1365 		break; /* ok */
1366 	default:
1367 		return SSH_ERR_INVALID_ARGUMENT;
1368 	}
1369 
1370 	/* Decode type */
1371 	cp = *cpp;
1372 	space = strcspn(cp, " \t");
1373 	if (space == strlen(cp))
1374 		return SSH_ERR_INVALID_FORMAT;
1375 	if ((type = peek_type_nid(cp, space, &curve_nid)) == KEY_UNSPEC)
1376 		return SSH_ERR_INVALID_FORMAT;
1377 
1378 	/* skip whitespace */
1379 	for (cp += space; *cp == ' ' || *cp == '\t'; cp++)
1380 		;
1381 	if (*cp == '\0')
1382 		return SSH_ERR_INVALID_FORMAT;
1383 	if (ret->type != KEY_UNSPEC && ret->type != type)
1384 		return SSH_ERR_KEY_TYPE_MISMATCH;
1385 	if ((blob = sshbuf_new()) == NULL)
1386 		return SSH_ERR_ALLOC_FAIL;
1387 
1388 	/* find end of keyblob and decode */
1389 	space = strcspn(cp, " \t");
1390 	if ((blobcopy = strndup(cp, space)) == NULL) {
1391 		sshbuf_free(blob);
1392 		return SSH_ERR_ALLOC_FAIL;
1393 	}
1394 	if ((r = sshbuf_b64tod(blob, blobcopy)) != 0) {
1395 		free(blobcopy);
1396 		sshbuf_free(blob);
1397 		return r;
1398 	}
1399 	free(blobcopy);
1400 	if ((r = sshkey_fromb(blob, &k)) != 0) {
1401 		sshbuf_free(blob);
1402 		return r;
1403 	}
1404 	sshbuf_free(blob);
1405 
1406 	/* skip whitespace and leave cp at start of comment */
1407 	for (cp += space; *cp == ' ' || *cp == '\t'; cp++)
1408 		;
1409 
1410 	/* ensure type of blob matches type at start of line */
1411 	if (k->type != type) {
1412 		sshkey_free(k);
1413 		return SSH_ERR_KEY_TYPE_MISMATCH;
1414 	}
1415 	if (sshkey_type_plain(type) == KEY_ECDSA && curve_nid != k->ecdsa_nid) {
1416 		sshkey_free(k);
1417 		return SSH_ERR_EC_CURVE_MISMATCH;
1418 	}
1419 
1420 	/* Fill in ret from parsed key */
1421 	ret->type = type;
1422 	if (sshkey_is_cert(ret)) {
1423 		if (!sshkey_is_cert(k)) {
1424 			sshkey_free(k);
1425 			return SSH_ERR_EXPECTED_CERT;
1426 		}
1427 		if (ret->cert != NULL)
1428 			cert_free(ret->cert);
1429 		ret->cert = k->cert;
1430 		k->cert = NULL;
1431 	}
1432 	switch (sshkey_type_plain(ret->type)) {
1433 #ifdef WITH_OPENSSL
1434 	case KEY_RSA:
1435 		RSA_free(ret->rsa);
1436 		ret->rsa = k->rsa;
1437 		k->rsa = NULL;
1438 #ifdef DEBUG_PK
1439 		RSA_print_fp(stderr, ret->rsa, 8);
1440 #endif
1441 		break;
1442 	case KEY_DSA:
1443 		DSA_free(ret->dsa);
1444 		ret->dsa = k->dsa;
1445 		k->dsa = NULL;
1446 #ifdef DEBUG_PK
1447 		DSA_print_fp(stderr, ret->dsa, 8);
1448 #endif
1449 		break;
1450 	case KEY_ECDSA:
1451 		EC_KEY_free(ret->ecdsa);
1452 		ret->ecdsa = k->ecdsa;
1453 		ret->ecdsa_nid = k->ecdsa_nid;
1454 		k->ecdsa = NULL;
1455 		k->ecdsa_nid = -1;
1456 #ifdef DEBUG_PK
1457 		sshkey_dump_ec_key(ret->ecdsa);
1458 #endif
1459 		break;
1460 #endif /* WITH_OPENSSL */
1461 	case KEY_ED25519:
1462 		freezero(ret->ed25519_pk, ED25519_PK_SZ);
1463 		ret->ed25519_pk = k->ed25519_pk;
1464 		k->ed25519_pk = NULL;
1465 #ifdef DEBUG_PK
1466 		/* XXX */
1467 #endif
1468 		break;
1469 #ifdef WITH_XMSS
1470 	case KEY_XMSS:
1471 		free(ret->xmss_pk);
1472 		ret->xmss_pk = k->xmss_pk;
1473 		k->xmss_pk = NULL;
1474 		free(ret->xmss_state);
1475 		ret->xmss_state = k->xmss_state;
1476 		k->xmss_state = NULL;
1477 		free(ret->xmss_name);
1478 		ret->xmss_name = k->xmss_name;
1479 		k->xmss_name = NULL;
1480 		free(ret->xmss_filename);
1481 		ret->xmss_filename = k->xmss_filename;
1482 		k->xmss_filename = NULL;
1483 #ifdef DEBUG_PK
1484 		/* XXX */
1485 #endif
1486 		break;
1487 #endif /* WITH_XMSS */
1488 	default:
1489 		sshkey_free(k);
1490 		return SSH_ERR_INTERNAL_ERROR;
1491 	}
1492 	sshkey_free(k);
1493 
1494 	/* success */
1495 	*cpp = cp;
1496 	return 0;
1497 }
1498 
1499 int
1500 sshkey_to_base64(const struct sshkey *key, char **b64p)
1501 {
1502 	int r = SSH_ERR_INTERNAL_ERROR;
1503 	struct sshbuf *b = NULL;
1504 	char *uu = NULL;
1505 
1506 	if (b64p != NULL)
1507 		*b64p = NULL;
1508 	if ((b = sshbuf_new()) == NULL)
1509 		return SSH_ERR_ALLOC_FAIL;
1510 	if ((r = sshkey_putb(key, b)) != 0)
1511 		goto out;
1512 	if ((uu = sshbuf_dtob64(b)) == NULL) {
1513 		r = SSH_ERR_ALLOC_FAIL;
1514 		goto out;
1515 	}
1516 	/* Success */
1517 	if (b64p != NULL) {
1518 		*b64p = uu;
1519 		uu = NULL;
1520 	}
1521 	r = 0;
1522  out:
1523 	sshbuf_free(b);
1524 	free(uu);
1525 	return r;
1526 }
1527 
1528 int
1529 sshkey_format_text(const struct sshkey *key, struct sshbuf *b)
1530 {
1531 	int r = SSH_ERR_INTERNAL_ERROR;
1532 	char *uu = NULL;
1533 
1534 	if ((r = sshkey_to_base64(key, &uu)) != 0)
1535 		goto out;
1536 	if ((r = sshbuf_putf(b, "%s %s",
1537 	    sshkey_ssh_name(key), uu)) != 0)
1538 		goto out;
1539 	r = 0;
1540  out:
1541 	free(uu);
1542 	return r;
1543 }
1544 
1545 int
1546 sshkey_write(const struct sshkey *key, FILE *f)
1547 {
1548 	struct sshbuf *b = NULL;
1549 	int r = SSH_ERR_INTERNAL_ERROR;
1550 
1551 	if ((b = sshbuf_new()) == NULL)
1552 		return SSH_ERR_ALLOC_FAIL;
1553 	if ((r = sshkey_format_text(key, b)) != 0)
1554 		goto out;
1555 	if (fwrite(sshbuf_ptr(b), sshbuf_len(b), 1, f) != 1) {
1556 		if (feof(f))
1557 			errno = EPIPE;
1558 		r = SSH_ERR_SYSTEM_ERROR;
1559 		goto out;
1560 	}
1561 	/* Success */
1562 	r = 0;
1563  out:
1564 	sshbuf_free(b);
1565 	return r;
1566 }
1567 
1568 const char *
1569 sshkey_cert_type(const struct sshkey *k)
1570 {
1571 	switch (k->cert->type) {
1572 	case SSH2_CERT_TYPE_USER:
1573 		return "user";
1574 	case SSH2_CERT_TYPE_HOST:
1575 		return "host";
1576 	default:
1577 		return "unknown";
1578 	}
1579 }
1580 
1581 #ifdef WITH_OPENSSL
1582 static int
1583 rsa_generate_private_key(u_int bits, RSA **rsap)
1584 {
1585 	RSA *private = NULL;
1586 	BIGNUM *f4 = NULL;
1587 	int ret = SSH_ERR_INTERNAL_ERROR;
1588 
1589 	if (rsap == NULL)
1590 		return SSH_ERR_INVALID_ARGUMENT;
1591 	if (bits < SSH_RSA_MINIMUM_MODULUS_SIZE ||
1592 	    bits > SSHBUF_MAX_BIGNUM * 8)
1593 		return SSH_ERR_KEY_LENGTH;
1594 	*rsap = NULL;
1595 	if ((private = RSA_new()) == NULL || (f4 = BN_new()) == NULL) {
1596 		ret = SSH_ERR_ALLOC_FAIL;
1597 		goto out;
1598 	}
1599 	if (!BN_set_word(f4, RSA_F4) ||
1600 	    !RSA_generate_key_ex(private, bits, f4, NULL)) {
1601 		ret = SSH_ERR_LIBCRYPTO_ERROR;
1602 		goto out;
1603 	}
1604 	*rsap = private;
1605 	private = NULL;
1606 	ret = 0;
1607  out:
1608 	RSA_free(private);
1609 	BN_free(f4);
1610 	return ret;
1611 }
1612 
1613 static int
1614 dsa_generate_private_key(u_int bits, DSA **dsap)
1615 {
1616 	DSA *private;
1617 	int ret = SSH_ERR_INTERNAL_ERROR;
1618 
1619 	if (dsap == NULL)
1620 		return SSH_ERR_INVALID_ARGUMENT;
1621 	if (bits != 1024)
1622 		return SSH_ERR_KEY_LENGTH;
1623 	if ((private = DSA_new()) == NULL) {
1624 		ret = SSH_ERR_ALLOC_FAIL;
1625 		goto out;
1626 	}
1627 	*dsap = NULL;
1628 	if (!DSA_generate_parameters_ex(private, bits, NULL, 0, NULL,
1629 	    NULL, NULL) || !DSA_generate_key(private)) {
1630 		ret = SSH_ERR_LIBCRYPTO_ERROR;
1631 		goto out;
1632 	}
1633 	*dsap = private;
1634 	private = NULL;
1635 	ret = 0;
1636  out:
1637 	DSA_free(private);
1638 	return ret;
1639 }
1640 
1641 int
1642 sshkey_ecdsa_key_to_nid(EC_KEY *k)
1643 {
1644 	EC_GROUP *eg;
1645 	int nids[] = {
1646 		NID_X9_62_prime256v1,
1647 		NID_secp384r1,
1648 		NID_secp521r1,
1649 		-1
1650 	};
1651 	int nid;
1652 	u_int i;
1653 	BN_CTX *bnctx;
1654 	const EC_GROUP *g = EC_KEY_get0_group(k);
1655 
1656 	/*
1657 	 * The group may be stored in a ASN.1 encoded private key in one of two
1658 	 * ways: as a "named group", which is reconstituted by ASN.1 object ID
1659 	 * or explicit group parameters encoded into the key blob. Only the
1660 	 * "named group" case sets the group NID for us, but we can figure
1661 	 * it out for the other case by comparing against all the groups that
1662 	 * are supported.
1663 	 */
1664 	if ((nid = EC_GROUP_get_curve_name(g)) > 0)
1665 		return nid;
1666 	if ((bnctx = BN_CTX_new()) == NULL)
1667 		return -1;
1668 	for (i = 0; nids[i] != -1; i++) {
1669 		if ((eg = EC_GROUP_new_by_curve_name(nids[i])) == NULL) {
1670 			BN_CTX_free(bnctx);
1671 			return -1;
1672 		}
1673 		if (EC_GROUP_cmp(g, eg, bnctx) == 0)
1674 			break;
1675 		EC_GROUP_free(eg);
1676 	}
1677 	BN_CTX_free(bnctx);
1678 	if (nids[i] != -1) {
1679 		/* Use the group with the NID attached */
1680 		EC_GROUP_set_asn1_flag(eg, OPENSSL_EC_NAMED_CURVE);
1681 		if (EC_KEY_set_group(k, eg) != 1) {
1682 			EC_GROUP_free(eg);
1683 			return -1;
1684 		}
1685 	}
1686 	return nids[i];
1687 }
1688 
1689 static int
1690 ecdsa_generate_private_key(u_int bits, int *nid, EC_KEY **ecdsap)
1691 {
1692 	EC_KEY *private;
1693 	int ret = SSH_ERR_INTERNAL_ERROR;
1694 
1695 	if (nid == NULL || ecdsap == NULL)
1696 		return SSH_ERR_INVALID_ARGUMENT;
1697 	if ((*nid = sshkey_ecdsa_bits_to_nid(bits)) == -1)
1698 		return SSH_ERR_KEY_LENGTH;
1699 	*ecdsap = NULL;
1700 	if ((private = EC_KEY_new_by_curve_name(*nid)) == NULL) {
1701 		ret = SSH_ERR_ALLOC_FAIL;
1702 		goto out;
1703 	}
1704 	if (EC_KEY_generate_key(private) != 1) {
1705 		ret = SSH_ERR_LIBCRYPTO_ERROR;
1706 		goto out;
1707 	}
1708 	EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE);
1709 	*ecdsap = private;
1710 	private = NULL;
1711 	ret = 0;
1712  out:
1713 	EC_KEY_free(private);
1714 	return ret;
1715 }
1716 #endif /* WITH_OPENSSL */
1717 
1718 int
1719 sshkey_generate(int type, u_int bits, struct sshkey **keyp)
1720 {
1721 	struct sshkey *k;
1722 	int ret = SSH_ERR_INTERNAL_ERROR;
1723 
1724 	if (keyp == NULL)
1725 		return SSH_ERR_INVALID_ARGUMENT;
1726 	*keyp = NULL;
1727 	if ((k = sshkey_new(KEY_UNSPEC)) == NULL)
1728 		return SSH_ERR_ALLOC_FAIL;
1729 	switch (type) {
1730 	case KEY_ED25519:
1731 		if ((k->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL ||
1732 		    (k->ed25519_sk = malloc(ED25519_SK_SZ)) == NULL) {
1733 			ret = SSH_ERR_ALLOC_FAIL;
1734 			break;
1735 		}
1736 		crypto_sign_ed25519_keypair(k->ed25519_pk, k->ed25519_sk);
1737 		ret = 0;
1738 		break;
1739 #ifdef WITH_XMSS
1740 	case KEY_XMSS:
1741 		ret = sshkey_xmss_generate_private_key(k, bits);
1742 		break;
1743 #endif /* WITH_XMSS */
1744 #ifdef WITH_OPENSSL
1745 	case KEY_DSA:
1746 		ret = dsa_generate_private_key(bits, &k->dsa);
1747 		break;
1748 	case KEY_ECDSA:
1749 		ret = ecdsa_generate_private_key(bits, &k->ecdsa_nid,
1750 		    &k->ecdsa);
1751 		break;
1752 	case KEY_RSA:
1753 		ret = rsa_generate_private_key(bits, &k->rsa);
1754 		break;
1755 #endif /* WITH_OPENSSL */
1756 	default:
1757 		ret = SSH_ERR_INVALID_ARGUMENT;
1758 	}
1759 	if (ret == 0) {
1760 		k->type = type;
1761 		*keyp = k;
1762 	} else
1763 		sshkey_free(k);
1764 	return ret;
1765 }
1766 
1767 int
1768 sshkey_cert_copy(const struct sshkey *from_key, struct sshkey *to_key)
1769 {
1770 	u_int i;
1771 	const struct sshkey_cert *from;
1772 	struct sshkey_cert *to;
1773 	int ret = SSH_ERR_INTERNAL_ERROR;
1774 
1775 	if (to_key->cert != NULL) {
1776 		cert_free(to_key->cert);
1777 		to_key->cert = NULL;
1778 	}
1779 
1780 	if ((from = from_key->cert) == NULL)
1781 		return SSH_ERR_INVALID_ARGUMENT;
1782 
1783 	if ((to = to_key->cert = cert_new()) == NULL)
1784 		return SSH_ERR_ALLOC_FAIL;
1785 
1786 	if ((ret = sshbuf_putb(to->certblob, from->certblob)) != 0 ||
1787 	    (ret = sshbuf_putb(to->critical, from->critical)) != 0 ||
1788 	    (ret = sshbuf_putb(to->extensions, from->extensions)) != 0)
1789 		return ret;
1790 
1791 	to->serial = from->serial;
1792 	to->type = from->type;
1793 	if (from->key_id == NULL)
1794 		to->key_id = NULL;
1795 	else if ((to->key_id = strdup(from->key_id)) == NULL)
1796 		return SSH_ERR_ALLOC_FAIL;
1797 	to->valid_after = from->valid_after;
1798 	to->valid_before = from->valid_before;
1799 	if (from->signature_key == NULL)
1800 		to->signature_key = NULL;
1801 	else if ((ret = sshkey_from_private(from->signature_key,
1802 	    &to->signature_key)) != 0)
1803 		return ret;
1804 
1805 	if (from->nprincipals > SSHKEY_CERT_MAX_PRINCIPALS)
1806 		return SSH_ERR_INVALID_ARGUMENT;
1807 	if (from->nprincipals > 0) {
1808 		if ((to->principals = calloc(from->nprincipals,
1809 		    sizeof(*to->principals))) == NULL)
1810 			return SSH_ERR_ALLOC_FAIL;
1811 		for (i = 0; i < from->nprincipals; i++) {
1812 			to->principals[i] = strdup(from->principals[i]);
1813 			if (to->principals[i] == NULL) {
1814 				to->nprincipals = i;
1815 				return SSH_ERR_ALLOC_FAIL;
1816 			}
1817 		}
1818 	}
1819 	to->nprincipals = from->nprincipals;
1820 	return 0;
1821 }
1822 
1823 int
1824 sshkey_from_private(const struct sshkey *k, struct sshkey **pkp)
1825 {
1826 	struct sshkey *n = NULL;
1827 	int ret = SSH_ERR_INTERNAL_ERROR;
1828 
1829 	*pkp = NULL;
1830 	switch (k->type) {
1831 #ifdef WITH_OPENSSL
1832 	case KEY_DSA:
1833 	case KEY_DSA_CERT:
1834 		if ((n = sshkey_new(k->type)) == NULL)
1835 			return SSH_ERR_ALLOC_FAIL;
1836 		{
1837 		const BIGNUM *p, *q, *g, *pub_key, *priv_key;
1838 		BIGNUM *cp=NULL, *cq=NULL, *cg=NULL, *cpub_key=NULL;
1839 		DSA_get0_pqg(k->dsa, &p, &q, &g);
1840 		DSA_get0_key(k->dsa, &pub_key, &priv_key);
1841 		if ((cp = BN_dup(p)) == NULL ||
1842 		    (cq = BN_dup(q)) == NULL ||
1843 		    (cg = BN_dup(g)) == NULL ||
1844 		    (cpub_key = BN_dup(pub_key)) == NULL) {
1845 			BN_free(cp); BN_free(cq); BN_free(cg);
1846 			BN_free(cpub_key);
1847 			sshkey_free(n);
1848 			return SSH_ERR_ALLOC_FAIL;
1849 		}
1850 		if (DSA_set0_pqg(n->dsa, cp, cq, cg) == 0)
1851 			goto error1;
1852 		cp = cq = cg = NULL;
1853 		if (DSA_set0_key(n->dsa, cpub_key, NULL) == 0) {
1854 error1:
1855 			BN_free(cp); BN_free(cq); BN_free(cg);
1856 			BN_free(cpub_key);
1857 			sshkey_free(n);
1858 			return SSH_ERR_LIBCRYPTO_ERROR;
1859 		}
1860 		cpub_key = NULL;
1861 		}
1862 		break;
1863 	case KEY_ECDSA:
1864 	case KEY_ECDSA_CERT:
1865 		if ((n = sshkey_new(k->type)) == NULL)
1866 			return SSH_ERR_ALLOC_FAIL;
1867 		n->ecdsa_nid = k->ecdsa_nid;
1868 		n->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid);
1869 		if (n->ecdsa == NULL) {
1870 			sshkey_free(n);
1871 			return SSH_ERR_ALLOC_FAIL;
1872 		}
1873 		if (EC_KEY_set_public_key(n->ecdsa,
1874 		    EC_KEY_get0_public_key(k->ecdsa)) != 1) {
1875 			sshkey_free(n);
1876 			return SSH_ERR_LIBCRYPTO_ERROR;
1877 		}
1878 		break;
1879 	case KEY_RSA:
1880 	case KEY_RSA_CERT:
1881 		if ((n = sshkey_new(k->type)) == NULL)
1882 			return SSH_ERR_ALLOC_FAIL;
1883 		{
1884 		const BIGNUM *nn, *e, *d;
1885 		BIGNUM *cn=NULL, *ce=NULL;
1886 		RSA_get0_key(k->rsa, &nn, &e, &d);
1887 		if ((cn = BN_dup(nn)) == NULL ||
1888 		    (ce = BN_dup(e)) == NULL ) {
1889 			BN_free(cn); BN_free(ce);
1890 			sshkey_free(n);
1891 			return SSH_ERR_ALLOC_FAIL;
1892 		}
1893 		if (RSA_set0_key(n->rsa, cn, ce, NULL) == 0) {
1894 			BN_free(cn); BN_free(ce);
1895 			sshkey_free(n);
1896 			return SSH_ERR_LIBCRYPTO_ERROR;
1897 		}
1898 		cn = ce = NULL;
1899 		}
1900 		break;
1901 #endif /* WITH_OPENSSL */
1902 	case KEY_ED25519:
1903 	case KEY_ED25519_CERT:
1904 		if ((n = sshkey_new(k->type)) == NULL)
1905 			return SSH_ERR_ALLOC_FAIL;
1906 		if (k->ed25519_pk != NULL) {
1907 			if ((n->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) {
1908 				sshkey_free(n);
1909 				return SSH_ERR_ALLOC_FAIL;
1910 			}
1911 			memcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ);
1912 		}
1913 		break;
1914 #ifdef WITH_XMSS
1915 	case KEY_XMSS:
1916 	case KEY_XMSS_CERT:
1917 		if ((n = sshkey_new(k->type)) == NULL)
1918 			return SSH_ERR_ALLOC_FAIL;
1919 		if ((ret = sshkey_xmss_init(n, k->xmss_name)) != 0) {
1920 			sshkey_free(n);
1921 			return ret;
1922 		}
1923 		if (k->xmss_pk != NULL) {
1924 			size_t pklen = sshkey_xmss_pklen(k);
1925 			if (pklen == 0 || sshkey_xmss_pklen(n) != pklen) {
1926 				sshkey_free(n);
1927 				return SSH_ERR_INTERNAL_ERROR;
1928 			}
1929 			if ((n->xmss_pk = malloc(pklen)) == NULL) {
1930 				sshkey_free(n);
1931 				return SSH_ERR_ALLOC_FAIL;
1932 			}
1933 			memcpy(n->xmss_pk, k->xmss_pk, pklen);
1934 		}
1935 		break;
1936 #endif /* WITH_XMSS */
1937 	default:
1938 		return SSH_ERR_KEY_TYPE_UNKNOWN;
1939 	}
1940 	if (sshkey_is_cert(k)) {
1941 		if ((ret = sshkey_cert_copy(k, n)) != 0) {
1942 			sshkey_free(n);
1943 			return ret;
1944 		}
1945 	}
1946 	*pkp = n;
1947 	return 0;
1948 }
1949 
1950 static int
1951 cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf)
1952 {
1953 	struct sshbuf *principals = NULL, *crit = NULL;
1954 	struct sshbuf *exts = NULL, *ca = NULL;
1955 	u_char *sig = NULL;
1956 	size_t signed_len = 0, slen = 0, kidlen = 0;
1957 	int ret = SSH_ERR_INTERNAL_ERROR;
1958 
1959 	/* Copy the entire key blob for verification and later serialisation */
1960 	if ((ret = sshbuf_putb(key->cert->certblob, certbuf)) != 0)
1961 		return ret;
1962 
1963 	/* Parse body of certificate up to signature */
1964 	if ((ret = sshbuf_get_u64(b, &key->cert->serial)) != 0 ||
1965 	    (ret = sshbuf_get_u32(b, &key->cert->type)) != 0 ||
1966 	    (ret = sshbuf_get_cstring(b, &key->cert->key_id, &kidlen)) != 0 ||
1967 	    (ret = sshbuf_froms(b, &principals)) != 0 ||
1968 	    (ret = sshbuf_get_u64(b, &key->cert->valid_after)) != 0 ||
1969 	    (ret = sshbuf_get_u64(b, &key->cert->valid_before)) != 0 ||
1970 	    (ret = sshbuf_froms(b, &crit)) != 0 ||
1971 	    (ret = sshbuf_froms(b, &exts)) != 0 ||
1972 	    (ret = sshbuf_get_string_direct(b, NULL, NULL)) != 0 ||
1973 	    (ret = sshbuf_froms(b, &ca)) != 0) {
1974 		/* XXX debug print error for ret */
1975 		ret = SSH_ERR_INVALID_FORMAT;
1976 		goto out;
1977 	}
1978 
1979 	/* Signature is left in the buffer so we can calculate this length */
1980 	signed_len = sshbuf_len(key->cert->certblob) - sshbuf_len(b);
1981 
1982 	if ((ret = sshbuf_get_string(b, &sig, &slen)) != 0) {
1983 		ret = SSH_ERR_INVALID_FORMAT;
1984 		goto out;
1985 	}
1986 
1987 	if (key->cert->type != SSH2_CERT_TYPE_USER &&
1988 	    key->cert->type != SSH2_CERT_TYPE_HOST) {
1989 		ret = SSH_ERR_KEY_CERT_UNKNOWN_TYPE;
1990 		goto out;
1991 	}
1992 
1993 	/* Parse principals section */
1994 	while (sshbuf_len(principals) > 0) {
1995 		char *principal = NULL;
1996 		char **oprincipals = NULL;
1997 
1998 		if (key->cert->nprincipals >= SSHKEY_CERT_MAX_PRINCIPALS) {
1999 			ret = SSH_ERR_INVALID_FORMAT;
2000 			goto out;
2001 		}
2002 		if ((ret = sshbuf_get_cstring(principals, &principal,
2003 		    NULL)) != 0) {
2004 			ret = SSH_ERR_INVALID_FORMAT;
2005 			goto out;
2006 		}
2007 		oprincipals = key->cert->principals;
2008 		key->cert->principals = recallocarray(key->cert->principals,
2009 		    key->cert->nprincipals, key->cert->nprincipals + 1,
2010 		    sizeof(*key->cert->principals));
2011 		if (key->cert->principals == NULL) {
2012 			free(principal);
2013 			key->cert->principals = oprincipals;
2014 			ret = SSH_ERR_ALLOC_FAIL;
2015 			goto out;
2016 		}
2017 		key->cert->principals[key->cert->nprincipals++] = principal;
2018 	}
2019 
2020 	/*
2021 	 * Stash a copies of the critical options and extensions sections
2022 	 * for later use.
2023 	 */
2024 	if ((ret = sshbuf_putb(key->cert->critical, crit)) != 0 ||
2025 	    (exts != NULL &&
2026 	    (ret = sshbuf_putb(key->cert->extensions, exts)) != 0))
2027 		goto out;
2028 
2029 	/*
2030 	 * Validate critical options and extensions sections format.
2031 	 */
2032 	while (sshbuf_len(crit) != 0) {
2033 		if ((ret = sshbuf_get_string_direct(crit, NULL, NULL)) != 0 ||
2034 		    (ret = sshbuf_get_string_direct(crit, NULL, NULL)) != 0) {
2035 			sshbuf_reset(key->cert->critical);
2036 			ret = SSH_ERR_INVALID_FORMAT;
2037 			goto out;
2038 		}
2039 	}
2040 	while (exts != NULL && sshbuf_len(exts) != 0) {
2041 		if ((ret = sshbuf_get_string_direct(exts, NULL, NULL)) != 0 ||
2042 		    (ret = sshbuf_get_string_direct(exts, NULL, NULL)) != 0) {
2043 			sshbuf_reset(key->cert->extensions);
2044 			ret = SSH_ERR_INVALID_FORMAT;
2045 			goto out;
2046 		}
2047 	}
2048 
2049 	/* Parse CA key and check signature */
2050 	if (sshkey_from_blob_internal(ca, &key->cert->signature_key, 0) != 0) {
2051 		ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
2052 		goto out;
2053 	}
2054 	if (!sshkey_type_is_valid_ca(key->cert->signature_key->type)) {
2055 		ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
2056 		goto out;
2057 	}
2058 	if ((ret = sshkey_verify(key->cert->signature_key, sig, slen,
2059 	    sshbuf_ptr(key->cert->certblob), signed_len, NULL, 0)) != 0)
2060 		goto out;
2061 
2062 	/* Success */
2063 	ret = 0;
2064  out:
2065 	sshbuf_free(ca);
2066 	sshbuf_free(crit);
2067 	sshbuf_free(exts);
2068 	sshbuf_free(principals);
2069 	free(sig);
2070 	return ret;
2071 }
2072 
2073 static int
2074 sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
2075     int allow_cert)
2076 {
2077 	int type, ret = SSH_ERR_INTERNAL_ERROR;
2078 	char *ktype = NULL, *curve = NULL, *xmss_name = NULL;
2079 	struct sshkey *key = NULL;
2080 	size_t len;
2081 	u_char *pk = NULL;
2082 	struct sshbuf *copy;
2083 #ifdef WITH_OPENSSL
2084 	EC_POINT *qq = NULL;
2085 #endif /* WITH_OPENSSL */
2086 
2087 #ifdef DEBUG_PK /* XXX */
2088 	sshbuf_dump(b, stderr);
2089 #endif
2090 	if (keyp != NULL)
2091 		*keyp = NULL;
2092 	if ((copy = sshbuf_fromb(b)) == NULL) {
2093 		ret = SSH_ERR_ALLOC_FAIL;
2094 		goto out;
2095 	}
2096 	if (sshbuf_get_cstring(b, &ktype, NULL) != 0) {
2097 		ret = SSH_ERR_INVALID_FORMAT;
2098 		goto out;
2099 	}
2100 
2101 	type = sshkey_type_from_name(ktype);
2102 	if (!allow_cert && sshkey_type_is_cert(type)) {
2103 		ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
2104 		goto out;
2105 	}
2106 	switch (type) {
2107 #ifdef WITH_OPENSSL
2108 	case KEY_RSA_CERT:
2109 		/* Skip nonce */
2110 		if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
2111 			ret = SSH_ERR_INVALID_FORMAT;
2112 			goto out;
2113 		}
2114 		/* FALLTHROUGH */
2115 	case KEY_RSA:
2116 		if ((key = sshkey_new(type)) == NULL) {
2117 			ret = SSH_ERR_ALLOC_FAIL;
2118 			goto out;
2119 		}
2120 		{
2121 		BIGNUM *e=NULL, *n=NULL;
2122 		if ((e = BN_new()) == NULL ||
2123 		    (n = BN_new()) == NULL ) {
2124 			ret = SSH_ERR_ALLOC_FAIL;
2125 			BN_free(e); BN_free(n);
2126 			goto out;
2127 		}
2128 		if (sshbuf_get_bignum2(b, e) != 0 ||
2129 		    sshbuf_get_bignum2(b, n) != 0) {
2130 			ret = SSH_ERR_INVALID_FORMAT;
2131 			BN_free(e); BN_free(n);
2132 			goto out;
2133 		}
2134 		if (RSA_set0_key(key->rsa, n, e, NULL) == 0) {
2135 			BN_free(e); BN_free(n);
2136 			return SSH_ERR_LIBCRYPTO_ERROR;
2137 		}
2138 		n = e = NULL;
2139 		}
2140 		if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
2141 			ret = SSH_ERR_KEY_LENGTH;
2142 			goto out;
2143 		}
2144 #ifdef DEBUG_PK
2145 		RSA_print_fp(stderr, key->rsa, 8);
2146 #endif
2147 		break;
2148 	case KEY_DSA_CERT:
2149 		/* Skip nonce */
2150 		if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
2151 			ret = SSH_ERR_INVALID_FORMAT;
2152 			goto out;
2153 		}
2154 		/* FALLTHROUGH */
2155 	case KEY_DSA:
2156 		if ((key = sshkey_new(type)) == NULL) {
2157 			ret = SSH_ERR_ALLOC_FAIL;
2158 			goto out;
2159 		}
2160 		{
2161 		BIGNUM *p=NULL, *q=NULL, *g=NULL, *pub_key=NULL;
2162 		if ((p = BN_new()) == NULL ||
2163 		    (q = BN_new()) == NULL ||
2164 		    (g = BN_new()) == NULL ||
2165 		    (pub_key = BN_new()) == NULL) {
2166 			ret = SSH_ERR_ALLOC_FAIL;
2167 			goto error1;
2168 		}
2169 		if (sshbuf_get_bignum2(b, p) != 0 ||
2170 		    sshbuf_get_bignum2(b, q) != 0 ||
2171 		    sshbuf_get_bignum2(b, g) != 0 ||
2172 		    sshbuf_get_bignum2(b, pub_key) != 0) {
2173 			ret = SSH_ERR_INVALID_FORMAT;
2174 			goto error1;
2175 		}
2176 		if (DSA_set0_pqg(key->dsa, p, q, g) == 0) {
2177 			ret = SSH_ERR_LIBCRYPTO_ERROR;
2178 			goto error1;
2179 		}
2180 		p = q = g = NULL;
2181 		if (DSA_set0_key(key->dsa, pub_key, NULL) == 0) {
2182 			ret = SSH_ERR_LIBCRYPTO_ERROR;
2183 error1:
2184 			BN_free(p); BN_free(q); BN_free(g);
2185 			BN_free(pub_key);
2186 			goto out;
2187 		}
2188 		pub_key = NULL;
2189 		}
2190 #ifdef DEBUG_PK
2191 		DSA_print_fp(stderr, key->dsa, 8);
2192 #endif
2193 		break;
2194 	case KEY_ECDSA_CERT:
2195 		/* Skip nonce */
2196 		if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
2197 			ret = SSH_ERR_INVALID_FORMAT;
2198 			goto out;
2199 		}
2200 		/* FALLTHROUGH */
2201 	case KEY_ECDSA:
2202 		if ((key = sshkey_new(type)) == NULL) {
2203 			ret = SSH_ERR_ALLOC_FAIL;
2204 			goto out;
2205 		}
2206 		key->ecdsa_nid = sshkey_ecdsa_nid_from_name(ktype);
2207 		if (sshbuf_get_cstring(b, &curve, NULL) != 0) {
2208 			ret = SSH_ERR_INVALID_FORMAT;
2209 			goto out;
2210 		}
2211 		if (key->ecdsa_nid != sshkey_curve_name_to_nid(curve)) {
2212 			ret = SSH_ERR_EC_CURVE_MISMATCH;
2213 			goto out;
2214 		}
2215 		EC_KEY_free(key->ecdsa);
2216 		if ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid))
2217 		    == NULL) {
2218 			ret = SSH_ERR_EC_CURVE_INVALID;
2219 			goto out;
2220 		}
2221 		if ((qq = EC_POINT_new(EC_KEY_get0_group(key->ecdsa))) == NULL) {
2222 			ret = SSH_ERR_ALLOC_FAIL;
2223 			goto out;
2224 		}
2225 		if (sshbuf_get_ec(b, qq, EC_KEY_get0_group(key->ecdsa)) != 0) {
2226 			ret = SSH_ERR_INVALID_FORMAT;
2227 			goto out;
2228 		}
2229 		if (sshkey_ec_validate_public(EC_KEY_get0_group(key->ecdsa),
2230 		    qq) != 0) {
2231 			ret = SSH_ERR_KEY_INVALID_EC_VALUE;
2232 			goto out;
2233 		}
2234 		if (EC_KEY_set_public_key(key->ecdsa, qq) != 1) {
2235 			/* XXX assume it is a allocation error */
2236 			ret = SSH_ERR_ALLOC_FAIL;
2237 			goto out;
2238 		}
2239 #ifdef DEBUG_PK
2240 		sshkey_dump_ec_point(EC_KEY_get0_group(key->ecdsa), qq);
2241 #endif
2242 		break;
2243 #endif /* WITH_OPENSSL */
2244 	case KEY_ED25519_CERT:
2245 		/* Skip nonce */
2246 		if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
2247 			ret = SSH_ERR_INVALID_FORMAT;
2248 			goto out;
2249 		}
2250 		/* FALLTHROUGH */
2251 	case KEY_ED25519:
2252 		if ((ret = sshbuf_get_string(b, &pk, &len)) != 0)
2253 			goto out;
2254 		if (len != ED25519_PK_SZ) {
2255 			ret = SSH_ERR_INVALID_FORMAT;
2256 			goto out;
2257 		}
2258 		if ((key = sshkey_new(type)) == NULL) {
2259 			ret = SSH_ERR_ALLOC_FAIL;
2260 			goto out;
2261 		}
2262 		key->ed25519_pk = pk;
2263 		pk = NULL;
2264 		break;
2265 #ifdef WITH_XMSS
2266 	case KEY_XMSS_CERT:
2267 		/* Skip nonce */
2268 		if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
2269 			ret = SSH_ERR_INVALID_FORMAT;
2270 			goto out;
2271 		}
2272 		/* FALLTHROUGH */
2273 	case KEY_XMSS:
2274 		if ((ret = sshbuf_get_cstring(b, &xmss_name, NULL)) != 0)
2275 			goto out;
2276 		if ((key = sshkey_new(type)) == NULL) {
2277 			ret = SSH_ERR_ALLOC_FAIL;
2278 			goto out;
2279 		}
2280 		if ((ret = sshkey_xmss_init(key, xmss_name)) != 0)
2281 			goto out;
2282 		if ((ret = sshbuf_get_string(b, &pk, &len)) != 0)
2283 			goto out;
2284 		if (len == 0 || len != sshkey_xmss_pklen(key)) {
2285 			ret = SSH_ERR_INVALID_FORMAT;
2286 			goto out;
2287 		}
2288 		key->xmss_pk = pk;
2289 		pk = NULL;
2290 		if (type != KEY_XMSS_CERT &&
2291 		    (ret = sshkey_xmss_deserialize_pk_info(key, b)) != 0)
2292 			goto out;
2293 		break;
2294 #endif /* WITH_XMSS */
2295 	case KEY_UNSPEC:
2296 	default:
2297 		ret = SSH_ERR_KEY_TYPE_UNKNOWN;
2298 		goto out;
2299 	}
2300 
2301 	/* Parse certificate potion */
2302 	if (sshkey_is_cert(key) && (ret = cert_parse(b, key, copy)) != 0)
2303 		goto out;
2304 
2305 	if (key != NULL && sshbuf_len(b) != 0) {
2306 		ret = SSH_ERR_INVALID_FORMAT;
2307 		goto out;
2308 	}
2309 	ret = 0;
2310 	if (keyp != NULL) {
2311 		*keyp = key;
2312 		key = NULL;
2313 	}
2314  out:
2315 	sshbuf_free(copy);
2316 	sshkey_free(key);
2317 	free(xmss_name);
2318 	free(ktype);
2319 	free(curve);
2320 	free(pk);
2321 #ifdef WITH_OPENSSL
2322 	if (qq != NULL)
2323 		EC_POINT_free(qq);
2324 #endif /* WITH_OPENSSL */
2325 	return ret;
2326 }
2327 
2328 int
2329 sshkey_from_blob(const u_char *blob, size_t blen, struct sshkey **keyp)
2330 {
2331 	struct sshbuf *b;
2332 	int r;
2333 
2334 	if ((b = sshbuf_from(blob, blen)) == NULL)
2335 		return SSH_ERR_ALLOC_FAIL;
2336 	r = sshkey_from_blob_internal(b, keyp, 1);
2337 	sshbuf_free(b);
2338 	return r;
2339 }
2340 
2341 int
2342 sshkey_fromb(struct sshbuf *b, struct sshkey **keyp)
2343 {
2344 	return sshkey_from_blob_internal(b, keyp, 1);
2345 }
2346 
2347 int
2348 sshkey_froms(struct sshbuf *buf, struct sshkey **keyp)
2349 {
2350 	struct sshbuf *b;
2351 	int r;
2352 
2353 	if ((r = sshbuf_froms(buf, &b)) != 0)
2354 		return r;
2355 	r = sshkey_from_blob_internal(b, keyp, 1);
2356 	sshbuf_free(b);
2357 	return r;
2358 }
2359 
2360 int
2361 sshkey_sigtype(const u_char *sig, size_t siglen, char **sigtypep)
2362 {
2363 	int r;
2364 	struct sshbuf *b = NULL;
2365 	char *sigtype = NULL;
2366 
2367 	if (sigtypep != NULL)
2368 		*sigtypep = NULL;
2369 	if ((b = sshbuf_from(sig, siglen)) == NULL)
2370 		return SSH_ERR_ALLOC_FAIL;
2371 	if ((r = sshbuf_get_cstring(b, &sigtype, NULL)) != 0)
2372 		goto out;
2373 	/* success */
2374 	if (sigtypep != NULL) {
2375 		*sigtypep = sigtype;
2376 		sigtype = NULL;
2377 	}
2378 	r = 0;
2379  out:
2380 	free(sigtype);
2381 	sshbuf_free(b);
2382 	return r;
2383 }
2384 
2385 int
2386 sshkey_sign(const struct sshkey *key,
2387     u_char **sigp, size_t *lenp,
2388     const u_char *data, size_t datalen, const char *alg, u_int compat)
2389 {
2390 	if (sigp != NULL)
2391 		*sigp = NULL;
2392 	if (lenp != NULL)
2393 		*lenp = 0;
2394 	if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE)
2395 		return SSH_ERR_INVALID_ARGUMENT;
2396 	switch (key->type) {
2397 #ifdef WITH_OPENSSL
2398 	case KEY_DSA_CERT:
2399 	case KEY_DSA:
2400 		return ssh_dss_sign(key, sigp, lenp, data, datalen, compat);
2401 	case KEY_ECDSA_CERT:
2402 	case KEY_ECDSA:
2403 		return ssh_ecdsa_sign(key, sigp, lenp, data, datalen, compat);
2404 	case KEY_RSA_CERT:
2405 	case KEY_RSA:
2406 		return ssh_rsa_sign(key, sigp, lenp, data, datalen, alg);
2407 #endif /* WITH_OPENSSL */
2408 	case KEY_ED25519:
2409 	case KEY_ED25519_CERT:
2410 		return ssh_ed25519_sign(key, sigp, lenp, data, datalen, compat);
2411 #ifdef WITH_XMSS
2412 	case KEY_XMSS:
2413 	case KEY_XMSS_CERT:
2414 		return ssh_xmss_sign(key, sigp, lenp, data, datalen, compat);
2415 #endif /* WITH_XMSS */
2416 	default:
2417 		return SSH_ERR_KEY_TYPE_UNKNOWN;
2418 	}
2419 }
2420 
2421 /*
2422  * ssh_key_verify returns 0 for a correct signature  and < 0 on error.
2423  * If "alg" specified, then the signature must use that algorithm.
2424  */
2425 int
2426 sshkey_verify(const struct sshkey *key,
2427     const u_char *sig, size_t siglen,
2428     const u_char *data, size_t dlen, const char *alg, u_int compat)
2429 {
2430 	if (siglen == 0 || dlen > SSH_KEY_MAX_SIGN_DATA_SIZE)
2431 		return SSH_ERR_INVALID_ARGUMENT;
2432 	switch (key->type) {
2433 #ifdef WITH_OPENSSL
2434 	case KEY_DSA_CERT:
2435 	case KEY_DSA:
2436 		return ssh_dss_verify(key, sig, siglen, data, dlen, compat);
2437 	case KEY_ECDSA_CERT:
2438 	case KEY_ECDSA:
2439 		return ssh_ecdsa_verify(key, sig, siglen, data, dlen, compat);
2440 	case KEY_RSA_CERT:
2441 	case KEY_RSA:
2442 		return ssh_rsa_verify(key, sig, siglen, data, dlen, alg);
2443 #endif /* WITH_OPENSSL */
2444 	case KEY_ED25519:
2445 	case KEY_ED25519_CERT:
2446 		return ssh_ed25519_verify(key, sig, siglen, data, dlen, compat);
2447 #ifdef WITH_XMSS
2448 	case KEY_XMSS:
2449 	case KEY_XMSS_CERT:
2450 		return ssh_xmss_verify(key, sig, siglen, data, dlen, compat);
2451 #endif /* WITH_XMSS */
2452 	default:
2453 		return SSH_ERR_KEY_TYPE_UNKNOWN;
2454 	}
2455 }
2456 
2457 /* Converts a private to a public key */
2458 int
2459 sshkey_demote(const struct sshkey *k, struct sshkey **dkp)
2460 {
2461 	struct sshkey *pk;
2462 	int ret = SSH_ERR_INTERNAL_ERROR;
2463 
2464 	*dkp = NULL;
2465 	if ((pk = calloc(1, sizeof(*pk))) == NULL)
2466 		return SSH_ERR_ALLOC_FAIL;
2467 	pk->type = k->type;
2468 	pk->flags = k->flags;
2469 	pk->ecdsa_nid = k->ecdsa_nid;
2470 	pk->dsa = NULL;
2471 	pk->ecdsa = NULL;
2472 	pk->rsa = NULL;
2473 	pk->ed25519_pk = NULL;
2474 	pk->ed25519_sk = NULL;
2475 	pk->xmss_pk = NULL;
2476 	pk->xmss_sk = NULL;
2477 
2478 	switch (k->type) {
2479 #ifdef WITH_OPENSSL
2480 	case KEY_RSA_CERT:
2481 		if ((ret = sshkey_cert_copy(k, pk)) != 0)
2482 			goto fail;
2483 		/* FALLTHROUGH */
2484 	case KEY_RSA:
2485 		if ((pk->rsa = RSA_new()) == NULL ){
2486 			ret = SSH_ERR_ALLOC_FAIL;
2487 			goto fail;
2488 			}
2489 		{
2490 		const BIGNUM *ke, *kn;
2491 		BIGNUM *pke=NULL, *pkn=NULL;
2492 		RSA_get0_key(k->rsa, &kn, &ke, NULL);
2493 		 if ((pke = BN_dup(ke)) == NULL ||
2494 		     (pkn = BN_dup(kn)) == NULL) {
2495 			ret = SSH_ERR_ALLOC_FAIL;
2496 			BN_free(pke); BN_free(pkn);
2497 			goto fail;
2498 			}
2499 		if (RSA_set0_key(pk->rsa, pkn, pke, NULL) == 0) {
2500 			ret = SSH_ERR_LIBCRYPTO_ERROR;
2501 			BN_free(pke); BN_free(pkn);
2502 			goto fail;
2503 		}
2504 		pkn = pke = NULL;
2505 		}
2506 		break;
2507 	case KEY_DSA_CERT:
2508 		if ((ret = sshkey_cert_copy(k, pk)) != 0)
2509 			goto fail;
2510 		/* FALLTHROUGH */
2511 	case KEY_DSA:
2512 		if ((pk->dsa = DSA_new()) == NULL ) {
2513 			ret = SSH_ERR_ALLOC_FAIL;
2514 			goto fail;
2515 		}
2516 		{
2517 		const BIGNUM *kp, *kq, *kg, *kpub_key;
2518 		BIGNUM *pkp=NULL, *pkq=NULL, *pkg=NULL, *pkpub_key=NULL;
2519 		DSA_get0_pqg(k->dsa, &kp, &kq, &kg);
2520 		DSA_get0_key(k->dsa, &kpub_key, NULL);
2521 		if ((pkp = BN_dup(kp)) == NULL ||
2522 		    (pkq = BN_dup(kq)) == NULL ||
2523 		    (pkg = BN_dup(kg)) == NULL ||
2524 		    (pkpub_key = BN_dup(kpub_key)) == NULL) {
2525 			ret = SSH_ERR_ALLOC_FAIL;
2526 			goto error1;
2527 		}
2528 		if (DSA_set0_pqg(pk->dsa, pkp, pkq, pkg) == 0) {
2529 			ret = SSH_ERR_LIBCRYPTO_ERROR;
2530 			goto error1;
2531 		}
2532 		pkp = pkq = pkg = NULL;
2533 		if (DSA_set0_key(pk->dsa, pkpub_key, NULL) == 0) {
2534 			ret = SSH_ERR_LIBCRYPTO_ERROR;
2535 error1:
2536 			BN_free(pkp); BN_free(pkq); BN_free(pkg);
2537 			BN_free(pkpub_key);
2538 			goto fail;
2539 		}
2540 		pkpub_key = NULL;
2541 		}
2542 		break;
2543 	case KEY_ECDSA_CERT:
2544 		if ((ret = sshkey_cert_copy(k, pk)) != 0)
2545 			goto fail;
2546 		/* FALLTHROUGH */
2547 	case KEY_ECDSA:
2548 		pk->ecdsa = EC_KEY_new_by_curve_name(pk->ecdsa_nid);
2549 		if (pk->ecdsa == NULL) {
2550 			ret = SSH_ERR_ALLOC_FAIL;
2551 			goto fail;
2552 		}
2553 		if (EC_KEY_set_public_key(pk->ecdsa,
2554 		    EC_KEY_get0_public_key(k->ecdsa)) != 1) {
2555 			ret = SSH_ERR_LIBCRYPTO_ERROR;
2556 			goto fail;
2557 		}
2558 		break;
2559 #endif /* WITH_OPENSSL */
2560 	case KEY_ED25519_CERT:
2561 		if ((ret = sshkey_cert_copy(k, pk)) != 0)
2562 			goto fail;
2563 		/* FALLTHROUGH */
2564 	case KEY_ED25519:
2565 		if (k->ed25519_pk != NULL) {
2566 			if ((pk->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) {
2567 				ret = SSH_ERR_ALLOC_FAIL;
2568 				goto fail;
2569 			}
2570 			memcpy(pk->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ);
2571 		}
2572 		break;
2573 #ifdef WITH_XMSS
2574 	case KEY_XMSS_CERT:
2575 		if ((ret = sshkey_cert_copy(k, pk)) != 0)
2576 			goto fail;
2577 		/* FALLTHROUGH */
2578 	case KEY_XMSS:
2579 		if ((ret = sshkey_xmss_init(pk, k->xmss_name)) != 0)
2580 			goto fail;
2581 		if (k->xmss_pk != NULL) {
2582 			size_t pklen = sshkey_xmss_pklen(k);
2583 
2584 			if (pklen == 0 || sshkey_xmss_pklen(pk) != pklen) {
2585 				ret = SSH_ERR_INTERNAL_ERROR;
2586 				goto fail;
2587 			}
2588 			if ((pk->xmss_pk = malloc(pklen)) == NULL) {
2589 				ret = SSH_ERR_ALLOC_FAIL;
2590 				goto fail;
2591 			}
2592 			memcpy(pk->xmss_pk, k->xmss_pk, pklen);
2593 		}
2594 		break;
2595 #endif /* WITH_XMSS */
2596 	default:
2597 		ret = SSH_ERR_KEY_TYPE_UNKNOWN;
2598  fail:
2599 		sshkey_free(pk);
2600 		return ret;
2601 	}
2602 	*dkp = pk;
2603 	return 0;
2604 }
2605 
2606 /* Convert a plain key to their _CERT equivalent */
2607 int
2608 sshkey_to_certified(struct sshkey *k)
2609 {
2610 	int newtype;
2611 
2612 	switch (k->type) {
2613 #ifdef WITH_OPENSSL
2614 	case KEY_RSA:
2615 		newtype = KEY_RSA_CERT;
2616 		break;
2617 	case KEY_DSA:
2618 		newtype = KEY_DSA_CERT;
2619 		break;
2620 	case KEY_ECDSA:
2621 		newtype = KEY_ECDSA_CERT;
2622 		break;
2623 #endif /* WITH_OPENSSL */
2624 	case KEY_ED25519:
2625 		newtype = KEY_ED25519_CERT;
2626 		break;
2627 #ifdef WITH_XMSS
2628 	case KEY_XMSS:
2629 		newtype = KEY_XMSS_CERT;
2630 		break;
2631 #endif /* WITH_XMSS */
2632 	default:
2633 		return SSH_ERR_INVALID_ARGUMENT;
2634 	}
2635 	if ((k->cert = cert_new()) == NULL)
2636 		return SSH_ERR_ALLOC_FAIL;
2637 	k->type = newtype;
2638 	return 0;
2639 }
2640 
2641 /* Convert a certificate to its raw key equivalent */
2642 int
2643 sshkey_drop_cert(struct sshkey *k)
2644 {
2645 	if (!sshkey_type_is_cert(k->type))
2646 		return SSH_ERR_KEY_TYPE_UNKNOWN;
2647 	cert_free(k->cert);
2648 	k->cert = NULL;
2649 	k->type = sshkey_type_plain(k->type);
2650 	return 0;
2651 }
2652 
2653 /* Sign a certified key, (re-)generating the signed certblob. */
2654 int
2655 sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg,
2656     sshkey_certify_signer *signer, void *signer_ctx)
2657 {
2658 	struct sshbuf *principals = NULL;
2659 	u_char *ca_blob = NULL, *sig_blob = NULL, nonce[32];
2660 	size_t i, ca_len, sig_len;
2661 	int ret = SSH_ERR_INTERNAL_ERROR;
2662 	struct sshbuf *cert;
2663 
2664 	if (k == NULL || k->cert == NULL ||
2665 	    k->cert->certblob == NULL || ca == NULL)
2666 		return SSH_ERR_INVALID_ARGUMENT;
2667 	if (!sshkey_is_cert(k))
2668 		return SSH_ERR_KEY_TYPE_UNKNOWN;
2669 	if (!sshkey_type_is_valid_ca(ca->type))
2670 		return SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
2671 
2672 	if ((ret = sshkey_to_blob(ca, &ca_blob, &ca_len)) != 0)
2673 		return SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
2674 
2675 	cert = k->cert->certblob; /* for readability */
2676 	sshbuf_reset(cert);
2677 	if ((ret = sshbuf_put_cstring(cert, sshkey_ssh_name(k))) != 0)
2678 		goto out;
2679 
2680 	/* -v01 certs put nonce first */
2681 	arc4random_buf(&nonce, sizeof(nonce));
2682 	if ((ret = sshbuf_put_string(cert, nonce, sizeof(nonce))) != 0)
2683 		goto out;
2684 
2685 	/* XXX this substantially duplicates to_blob(); refactor */
2686 	switch (k->type) {
2687 #ifdef WITH_OPENSSL
2688 	case KEY_DSA_CERT:
2689 		{
2690 		const BIGNUM *p, *q, *g, *pub_key;
2691 		DSA_get0_pqg(k->dsa, &p, &q, &g);
2692 		DSA_get0_key(k->dsa, &pub_key, NULL);
2693 		if ((ret = sshbuf_put_bignum2(cert, p)) != 0 ||
2694 		    (ret = sshbuf_put_bignum2(cert, q)) != 0 ||
2695 		    (ret = sshbuf_put_bignum2(cert, g)) != 0 ||
2696 		    (ret = sshbuf_put_bignum2(cert, pub_key)) != 0) {
2697 			goto out;
2698 		}
2699 		}
2700 		break;
2701 	case KEY_ECDSA_CERT:
2702 		if ((ret = sshbuf_put_cstring(cert,
2703 		    sshkey_curve_nid_to_name(k->ecdsa_nid))) != 0 ||
2704 		    (ret = sshbuf_put_ec(cert,
2705 		    EC_KEY_get0_public_key(k->ecdsa),
2706 		    EC_KEY_get0_group(k->ecdsa))) != 0)
2707 			goto out;
2708 		break;
2709 	case KEY_RSA_CERT:
2710 		{
2711 		const BIGNUM *e, *n;
2712 		RSA_get0_key(k->rsa, &n, &e, NULL);
2713 		if (n == NULL || e == NULL ||
2714 		    (ret = sshbuf_put_bignum2(cert, e)) != 0 ||
2715 		    (ret = sshbuf_put_bignum2(cert, n)) != 0) {
2716 			goto out;
2717 		}
2718 		}
2719 		break;
2720 #endif /* WITH_OPENSSL */
2721 	case KEY_ED25519_CERT:
2722 		if ((ret = sshbuf_put_string(cert,
2723 		    k->ed25519_pk, ED25519_PK_SZ)) != 0)
2724 			goto out;
2725 		break;
2726 #ifdef WITH_XMSS
2727 	case KEY_XMSS_CERT:
2728 		if (k->xmss_name == NULL) {
2729 			ret = SSH_ERR_INVALID_ARGUMENT;
2730 			goto out;
2731 		}
2732 		if ((ret = sshbuf_put_cstring(cert, k->xmss_name)) ||
2733 		    (ret = sshbuf_put_string(cert,
2734 		    k->xmss_pk, sshkey_xmss_pklen(k))) != 0)
2735 			goto out;
2736 		break;
2737 #endif /* WITH_XMSS */
2738 	default:
2739 		ret = SSH_ERR_INVALID_ARGUMENT;
2740 		goto out;
2741 	}
2742 
2743 	if ((ret = sshbuf_put_u64(cert, k->cert->serial)) != 0 ||
2744 	    (ret = sshbuf_put_u32(cert, k->cert->type)) != 0 ||
2745 	    (ret = sshbuf_put_cstring(cert, k->cert->key_id)) != 0)
2746 		goto out;
2747 
2748 	if ((principals = sshbuf_new()) == NULL) {
2749 		ret = SSH_ERR_ALLOC_FAIL;
2750 		goto out;
2751 	}
2752 	for (i = 0; i < k->cert->nprincipals; i++) {
2753 		if ((ret = sshbuf_put_cstring(principals,
2754 		    k->cert->principals[i])) != 0)
2755 			goto out;
2756 	}
2757 	if ((ret = sshbuf_put_stringb(cert, principals)) != 0 ||
2758 	    (ret = sshbuf_put_u64(cert, k->cert->valid_after)) != 0 ||
2759 	    (ret = sshbuf_put_u64(cert, k->cert->valid_before)) != 0 ||
2760 	    (ret = sshbuf_put_stringb(cert, k->cert->critical)) != 0 ||
2761 	    (ret = sshbuf_put_stringb(cert, k->cert->extensions)) != 0 ||
2762 	    (ret = sshbuf_put_string(cert, NULL, 0)) != 0 || /* Reserved */
2763 	    (ret = sshbuf_put_string(cert, ca_blob, ca_len)) != 0)
2764 		goto out;
2765 
2766 	/* Sign the whole mess */
2767 	if ((ret = signer(ca, &sig_blob, &sig_len, sshbuf_ptr(cert),
2768 	    sshbuf_len(cert), alg, 0, signer_ctx)) != 0)
2769 		goto out;
2770 
2771 	/* Append signature and we are done */
2772 	if ((ret = sshbuf_put_string(cert, sig_blob, sig_len)) != 0)
2773 		goto out;
2774 	ret = 0;
2775  out:
2776 	if (ret != 0)
2777 		sshbuf_reset(cert);
2778 	free(sig_blob);
2779 	free(ca_blob);
2780 	sshbuf_free(principals);
2781 	return ret;
2782 }
2783 
2784 static int
2785 default_key_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
2786     const u_char *data, size_t datalen,
2787     const char *alg, u_int compat, void *ctx)
2788 {
2789 	if (ctx != NULL)
2790 		return SSH_ERR_INVALID_ARGUMENT;
2791 	return sshkey_sign(key, sigp, lenp, data, datalen, alg, compat);
2792 }
2793 
2794 int
2795 sshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg)
2796 {
2797 	return sshkey_certify_custom(k, ca, alg, default_key_sign, NULL);
2798 }
2799 
2800 int
2801 sshkey_cert_check_authority(const struct sshkey *k,
2802     int want_host, int require_principal,
2803     const char *name, const char **reason)
2804 {
2805 	u_int i, principal_matches;
2806 	time_t now = time(NULL);
2807 
2808 	if (reason != NULL)
2809 		*reason = NULL;
2810 
2811 	if (want_host) {
2812 		if (k->cert->type != SSH2_CERT_TYPE_HOST) {
2813 			*reason = "Certificate invalid: not a host certificate";
2814 			return SSH_ERR_KEY_CERT_INVALID;
2815 		}
2816 	} else {
2817 		if (k->cert->type != SSH2_CERT_TYPE_USER) {
2818 			*reason = "Certificate invalid: not a user certificate";
2819 			return SSH_ERR_KEY_CERT_INVALID;
2820 		}
2821 	}
2822 	if (now < 0) {
2823 		/* yikes - system clock before epoch! */
2824 		*reason = "Certificate invalid: not yet valid";
2825 		return SSH_ERR_KEY_CERT_INVALID;
2826 	}
2827 	if ((u_int64_t)now < k->cert->valid_after) {
2828 		*reason = "Certificate invalid: not yet valid";
2829 		return SSH_ERR_KEY_CERT_INVALID;
2830 	}
2831 	if ((u_int64_t)now >= k->cert->valid_before) {
2832 		*reason = "Certificate invalid: expired";
2833 		return SSH_ERR_KEY_CERT_INVALID;
2834 	}
2835 	if (k->cert->nprincipals == 0) {
2836 		if (require_principal) {
2837 			*reason = "Certificate lacks principal list";
2838 			return SSH_ERR_KEY_CERT_INVALID;
2839 		}
2840 	} else if (name != NULL) {
2841 		principal_matches = 0;
2842 		for (i = 0; i < k->cert->nprincipals; i++) {
2843 			if (strcmp(name, k->cert->principals[i]) == 0) {
2844 				principal_matches = 1;
2845 				break;
2846 			}
2847 		}
2848 		if (!principal_matches) {
2849 			*reason = "Certificate invalid: name is not a listed "
2850 			    "principal";
2851 			return SSH_ERR_KEY_CERT_INVALID;
2852 		}
2853 	}
2854 	return 0;
2855 }
2856 
2857 size_t
2858 sshkey_format_cert_validity(const struct sshkey_cert *cert, char *s, size_t l)
2859 {
2860 	char from[32], to[32], ret[64];
2861 	time_t tt;
2862 	struct tm *tm;
2863 
2864 	*from = *to = '\0';
2865 	if (cert->valid_after == 0 &&
2866 	    cert->valid_before == 0xffffffffffffffffULL)
2867 		return strlcpy(s, "forever", l);
2868 
2869 	if (cert->valid_after != 0) {
2870 		/* XXX revisit INT_MAX in 2038 :) */
2871 		tt = cert->valid_after > INT_MAX ?
2872 		    INT_MAX : cert->valid_after;
2873 		tm = localtime(&tt);
2874 		strftime(from, sizeof(from), "%Y-%m-%dT%H:%M:%S", tm);
2875 	}
2876 	if (cert->valid_before != 0xffffffffffffffffULL) {
2877 		/* XXX revisit INT_MAX in 2038 :) */
2878 		tt = cert->valid_before > INT_MAX ?
2879 		    INT_MAX : cert->valid_before;
2880 		tm = localtime(&tt);
2881 		strftime(to, sizeof(to), "%Y-%m-%dT%H:%M:%S", tm);
2882 	}
2883 
2884 	if (cert->valid_after == 0)
2885 		snprintf(ret, sizeof(ret), "before %s", to);
2886 	else if (cert->valid_before == 0xffffffffffffffffULL)
2887 		snprintf(ret, sizeof(ret), "after %s", from);
2888 	else
2889 		snprintf(ret, sizeof(ret), "from %s to %s", from, to);
2890 
2891 	return strlcpy(s, ret, l);
2892 }
2893 
2894 int
2895 sshkey_private_serialize_opt(const struct sshkey *key, struct sshbuf *b,
2896     enum sshkey_serialize_rep opts)
2897 {
2898 	int r = SSH_ERR_INTERNAL_ERROR;
2899 
2900 	if ((r = sshbuf_put_cstring(b, sshkey_ssh_name(key))) != 0)
2901 		goto out;
2902 	switch (key->type) {
2903 #ifdef WITH_OPENSSL
2904 	case KEY_RSA:
2905 		{
2906 		const BIGNUM *n, *e, *d, *iqmp, *p, *q;
2907 		RSA_get0_key(key->rsa, &n, &e, &d);
2908 		RSA_get0_crt_params(key->rsa, NULL, NULL, &iqmp);
2909 		RSA_get0_factors(key->rsa, &p, &q);
2910 		if ((r = sshbuf_put_bignum2(b, n)) != 0 ||
2911 		    (r = sshbuf_put_bignum2(b, e)) != 0 ||
2912 		    (r = sshbuf_put_bignum2(b, d)) != 0 ||
2913 		    (r = sshbuf_put_bignum2(b, iqmp)) != 0 ||
2914 		    (r = sshbuf_put_bignum2(b, p)) != 0 ||
2915 		    (r = sshbuf_put_bignum2(b, q)) != 0) {
2916 			goto out;
2917 		}
2918 		}
2919 		break;
2920 	case KEY_RSA_CERT:
2921 		if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
2922 			r = SSH_ERR_INVALID_ARGUMENT;
2923 			goto out;
2924 		}
2925 		{
2926 		const BIGNUM *d, *iqmp, *p, *q;
2927 		RSA_get0_key(key->rsa, NULL, NULL, &d);
2928 		RSA_get0_crt_params(key->rsa, NULL, NULL, &iqmp);
2929 		RSA_get0_factors(key->rsa, &p, &q);
2930 		if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
2931 		    (r = sshbuf_put_bignum2(b, d)) != 0 ||
2932 		    (r = sshbuf_put_bignum2(b, iqmp)) != 0 ||
2933 		    (r = sshbuf_put_bignum2(b, p)) != 0 ||
2934 		    (r = sshbuf_put_bignum2(b, q)) != 0) {
2935 			goto out;
2936 		}
2937 		}
2938 		break;
2939 	case KEY_DSA:
2940 		{
2941 		const BIGNUM *p, *q, *g, *pub_key, *priv_key;
2942 		DSA_get0_pqg(key->dsa, &p, &q, &g);
2943 		DSA_get0_key(key->dsa, &pub_key, &priv_key);
2944 		if ((r = sshbuf_put_bignum2(b, p)) != 0 ||
2945 		    (r = sshbuf_put_bignum2(b, q)) != 0 ||
2946 		    (r = sshbuf_put_bignum2(b, g)) != 0 ||
2947 		    (r = sshbuf_put_bignum2(b, pub_key)) != 0 ||
2948 		    (r = sshbuf_put_bignum2(b, priv_key)) != 0) {
2949 			goto out;
2950 		}
2951 		}
2952 		break;
2953 	case KEY_DSA_CERT:
2954 		if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
2955 			r = SSH_ERR_INVALID_ARGUMENT;
2956 			goto out;
2957 		}
2958 		{
2959 		const BIGNUM *priv_key;
2960 		DSA_get0_key(key->dsa, NULL, &priv_key);
2961 		if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
2962 		    (r = sshbuf_put_bignum2(b, priv_key)) != 0) {
2963 			goto out;
2964 		}
2965 		}
2966 		break;
2967 	case KEY_ECDSA:
2968 		if ((r = sshbuf_put_cstring(b,
2969 		    sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 ||
2970 		    (r = sshbuf_put_eckey(b, key->ecdsa)) != 0 ||
2971 		    (r = sshbuf_put_bignum2(b,
2972 		    EC_KEY_get0_private_key(key->ecdsa))) != 0)
2973 			goto out;
2974 		break;
2975 	case KEY_ECDSA_CERT:
2976 		if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
2977 			r = SSH_ERR_INVALID_ARGUMENT;
2978 			goto out;
2979 		}
2980 		if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
2981 		    (r = sshbuf_put_bignum2(b,
2982 		    EC_KEY_get0_private_key(key->ecdsa))) != 0)
2983 			goto out;
2984 		break;
2985 #endif /* WITH_OPENSSL */
2986 	case KEY_ED25519:
2987 		if ((r = sshbuf_put_string(b, key->ed25519_pk,
2988 		    ED25519_PK_SZ)) != 0 ||
2989 		    (r = sshbuf_put_string(b, key->ed25519_sk,
2990 		    ED25519_SK_SZ)) != 0)
2991 			goto out;
2992 		break;
2993 	case KEY_ED25519_CERT:
2994 		if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
2995 			r = SSH_ERR_INVALID_ARGUMENT;
2996 			goto out;
2997 		}
2998 		if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
2999 		    (r = sshbuf_put_string(b, key->ed25519_pk,
3000 		    ED25519_PK_SZ)) != 0 ||
3001 		    (r = sshbuf_put_string(b, key->ed25519_sk,
3002 		    ED25519_SK_SZ)) != 0)
3003 			goto out;
3004 		break;
3005 #ifdef WITH_XMSS
3006 	case KEY_XMSS:
3007 		if (key->xmss_name == NULL) {
3008 			r = SSH_ERR_INVALID_ARGUMENT;
3009 			goto out;
3010 		}
3011 		if ((r = sshbuf_put_cstring(b, key->xmss_name)) != 0 ||
3012 		    (r = sshbuf_put_string(b, key->xmss_pk,
3013 		    sshkey_xmss_pklen(key))) != 0 ||
3014 		    (r = sshbuf_put_string(b, key->xmss_sk,
3015 		    sshkey_xmss_sklen(key))) != 0 ||
3016 		    (r = sshkey_xmss_serialize_state_opt(key, b, opts)) != 0)
3017 			goto out;
3018 		break;
3019 	case KEY_XMSS_CERT:
3020 		if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0 ||
3021 		    key->xmss_name == NULL) {
3022 			r = SSH_ERR_INVALID_ARGUMENT;
3023 			goto out;
3024 		}
3025 		if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
3026 		    (r = sshbuf_put_cstring(b, key->xmss_name)) != 0 ||
3027 		    (r = sshbuf_put_string(b, key->xmss_pk,
3028 		    sshkey_xmss_pklen(key))) != 0 ||
3029 		    (r = sshbuf_put_string(b, key->xmss_sk,
3030 		    sshkey_xmss_sklen(key))) != 0 ||
3031 		    (r = sshkey_xmss_serialize_state_opt(key, b, opts)) != 0)
3032 			goto out;
3033 		break;
3034 #endif /* WITH_XMSS */
3035 	default:
3036 		r = SSH_ERR_INVALID_ARGUMENT;
3037 		goto out;
3038 	}
3039 	/* success */
3040 	r = 0;
3041  out:
3042 	return r;
3043 }
3044 
3045 int
3046 sshkey_private_serialize(const struct sshkey *key, struct sshbuf *b)
3047 {
3048 	return sshkey_private_serialize_opt(key, b,
3049 	    SSHKEY_SERIALIZE_DEFAULT);
3050 }
3051 
3052 int
3053 sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
3054 {
3055 	char *tname = NULL, *curve = NULL, *xmss_name = NULL;
3056 	struct sshkey *k = NULL;
3057 	size_t pklen = 0, sklen = 0;
3058 	int type, r = SSH_ERR_INTERNAL_ERROR;
3059 	u_char *ed25519_pk = NULL, *ed25519_sk = NULL;
3060 	u_char *xmss_pk = NULL, *xmss_sk = NULL;
3061 #ifdef WITH_OPENSSL
3062 	BIGNUM *exponent = NULL;
3063 #endif /* WITH_OPENSSL */
3064 
3065 	if (kp != NULL)
3066 		*kp = NULL;
3067 	if ((r = sshbuf_get_cstring(buf, &tname, NULL)) != 0)
3068 		goto out;
3069 	type = sshkey_type_from_name(tname);
3070 	switch (type) {
3071 #ifdef WITH_OPENSSL
3072 	case KEY_DSA:
3073 		if ((k = sshkey_new_private(type)) == NULL) {
3074 			r = SSH_ERR_ALLOC_FAIL;
3075 			goto out;
3076 		}
3077 		{
3078 		BIGNUM *p=NULL, *q=NULL, *g=NULL, *pub_key=NULL, *priv_key=NULL;
3079 		if ((p = BN_new()) == NULL ||
3080 		    (q = BN_new()) == NULL ||
3081 		    (g = BN_new()) == NULL ||
3082 		    (pub_key = BN_new()) == NULL ||
3083 		    (priv_key = BN_new()) == NULL) {
3084 			r = SSH_ERR_ALLOC_FAIL;
3085 			goto error1;
3086 		}
3087 		if (p == NULL || q == NULL || g == NULL ||
3088 		    pub_key == NULL || priv_key == NULL ||
3089 		    (r = sshbuf_get_bignum2(buf, p)) != 0 ||
3090 		    (r = sshbuf_get_bignum2(buf, q)) != 0 ||
3091 		    (r = sshbuf_get_bignum2(buf, g)) != 0 ||
3092 		    (r = sshbuf_get_bignum2(buf, pub_key)) != 0 ||
3093 		    (r = sshbuf_get_bignum2(buf, priv_key)) != 0) {
3094 			goto error1;
3095 		}
3096 		if (DSA_set0_pqg(k->dsa, p, q, g) == 0) {
3097 			r = SSH_ERR_LIBCRYPTO_ERROR;
3098 			goto error1;
3099 		}
3100 		p = q = g = NULL;
3101 		if (DSA_set0_key(k->dsa, pub_key, priv_key) == 0) {
3102 			r = SSH_ERR_LIBCRYPTO_ERROR;
3103 error1:
3104 			BN_free(p); BN_free(q); BN_free(g);
3105 			BN_free(pub_key); BN_free(priv_key);
3106 			goto out;
3107 		}
3108 		pub_key = priv_key = NULL;
3109 		}
3110 		break;
3111 	case KEY_DSA_CERT:
3112 		{
3113 		BIGNUM *priv_key=NULL;
3114 		if ((priv_key = BN_new()) == NULL) {
3115 			r = SSH_ERR_ALLOC_FAIL;
3116 			goto out;
3117 		}
3118 		if (priv_key == NULL ||
3119 		    (r = sshkey_froms(buf, &k)) != 0 ||
3120 		    (r = sshkey_add_private(k)) != 0 ||
3121 		    (r = sshbuf_get_bignum2(buf, priv_key)) != 0) {
3122 			BN_free(priv_key);
3123 			goto out;
3124 		}
3125 		if (DSA_set0_key(k->dsa, NULL, priv_key) == 0) {
3126 			r = SSH_ERR_LIBCRYPTO_ERROR;
3127 			BN_free(priv_key);
3128 			goto out;
3129 		}
3130 		priv_key = NULL;
3131 		}
3132 		break;
3133 	case KEY_ECDSA:
3134 		if ((k = sshkey_new_private(type)) == NULL) {
3135 			r = SSH_ERR_ALLOC_FAIL;
3136 			goto out;
3137 		}
3138 		if ((k->ecdsa_nid = sshkey_ecdsa_nid_from_name(tname)) == -1) {
3139 			r = SSH_ERR_INVALID_ARGUMENT;
3140 			goto out;
3141 		}
3142 		if ((r = sshbuf_get_cstring(buf, &curve, NULL)) != 0)
3143 			goto out;
3144 		if (k->ecdsa_nid != sshkey_curve_name_to_nid(curve)) {
3145 			r = SSH_ERR_EC_CURVE_MISMATCH;
3146 			goto out;
3147 		}
3148 		k->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid);
3149 		if (k->ecdsa  == NULL || (exponent = BN_new()) == NULL) {
3150 			r = SSH_ERR_LIBCRYPTO_ERROR;
3151 			goto out;
3152 		}
3153 		if ((r = sshbuf_get_eckey(buf, k->ecdsa)) != 0 ||
3154 		    (r = sshbuf_get_bignum2(buf, exponent)))
3155 			goto out;
3156 		if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) {
3157 			r = SSH_ERR_LIBCRYPTO_ERROR;
3158 			goto out;
3159 		}
3160 		if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
3161 		    EC_KEY_get0_public_key(k->ecdsa))) != 0 ||
3162 		    (r = sshkey_ec_validate_private(k->ecdsa)) != 0)
3163 			goto out;
3164 		break;
3165 	case KEY_ECDSA_CERT:
3166 		if ((exponent = BN_new()) == NULL) {
3167 			r = SSH_ERR_LIBCRYPTO_ERROR;
3168 			goto out;
3169 		}
3170 		if ((r = sshkey_froms(buf, &k)) != 0 ||
3171 		    (r = sshkey_add_private(k)) != 0 ||
3172 		    (r = sshbuf_get_bignum2(buf, exponent)) != 0)
3173 			goto out;
3174 		if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) {
3175 			r = SSH_ERR_LIBCRYPTO_ERROR;
3176 			goto out;
3177 		}
3178 		if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
3179 		    EC_KEY_get0_public_key(k->ecdsa))) != 0 ||
3180 		    (r = sshkey_ec_validate_private(k->ecdsa)) != 0)
3181 			goto out;
3182 		break;
3183 	case KEY_RSA:
3184 		if ((k = sshkey_new_private(type)) == NULL) {
3185 			r = SSH_ERR_ALLOC_FAIL;
3186 			goto out;
3187 		}
3188 		{
3189 		BIGNUM *n=NULL, *e=NULL, *d=NULL, *iqmp=NULL, *p=NULL, *q=NULL;
3190 		BIGNUM *dmp1=NULL, *dmq1=NULL; /* dummy for RSA_set0_crt_params */
3191 		if ((n = BN_new()) == NULL ||
3192 		    (e = BN_new()) == NULL ||
3193 		    (d = BN_new()) == NULL ||
3194 		    (iqmp = BN_new()) == NULL ||
3195 		    (p = BN_new()) == NULL ||
3196 		    (q = BN_new()) == NULL ||
3197 		    (dmp1 = BN_new()) == NULL ||
3198 		    (dmq1 = BN_new()) == NULL) {
3199 			r = SSH_ERR_ALLOC_FAIL;
3200 			goto error2;
3201 		}
3202 		BN_clear(dmp1); BN_clear(dmq1);
3203 		if ((r = sshbuf_get_bignum2(buf, n)) != 0 ||
3204 		    (r = sshbuf_get_bignum2(buf, e)) != 0 ||
3205 		    (r = sshbuf_get_bignum2(buf, d)) != 0 ||
3206 		    (r = sshbuf_get_bignum2(buf, iqmp)) != 0 ||
3207 		    (r = sshbuf_get_bignum2(buf, p)) != 0 ||
3208 		    (r = sshbuf_get_bignum2(buf, q)) != 0) {
3209 			goto error2;
3210 		}
3211 		if (RSA_set0_key(k->rsa, n, e, d) == 0) {
3212 			r = SSH_ERR_LIBCRYPTO_ERROR;
3213 			goto error2;
3214 		}
3215 		n = e = d = NULL;
3216 		/* dmp1,dmpq1 should be non NULL to set iqmp value */
3217 		if (RSA_set0_crt_params(k->rsa, dmp1, dmq1, iqmp) == 0) {
3218 			r = SSH_ERR_LIBCRYPTO_ERROR;
3219 			goto error2;
3220 		}
3221 		dmp1 = dmq1 = iqmp = NULL;
3222 		if (RSA_set0_factors(k->rsa, p, q) == 0) {
3223 			r = SSH_ERR_LIBCRYPTO_ERROR;
3224  error2:
3225 			BN_free(n); BN_free(e); BN_free(d);
3226 			BN_free(iqmp);
3227 			BN_free(p); BN_free(q);
3228 			BN_free(dmp1); BN_free(dmq1);
3229 			goto out;
3230 		}
3231 		p = q = NULL;
3232 		if ((r = ssh_rsa_generate_additional_parameters(k)) != 0) {
3233 			goto out;
3234 		}
3235 		}
3236 		if (RSA_bits(k->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
3237 			r = SSH_ERR_KEY_LENGTH;
3238 			goto out;
3239 		}
3240 		break;
3241 	case KEY_RSA_CERT:
3242 		{
3243 		BIGNUM *d=NULL, *iqmp=NULL, *p=NULL, *q=NULL;
3244 		BIGNUM *dmp1=NULL, *dmq1=NULL; /* dummy for RSA_set0_crt_params */
3245 		if ((d = BN_new()) == NULL ||
3246 		    (iqmp = BN_new()) == NULL ||
3247 		    (p = BN_new()) == NULL ||
3248 		    (q = BN_new()) == NULL ||
3249 		    (dmp1 = BN_new()) == NULL ||
3250 		    (dmq1 = BN_new()) == NULL) {
3251 			r = SSH_ERR_ALLOC_FAIL;
3252 			goto error3;
3253 		}
3254 		BN_clear(dmp1); BN_clear(dmq1);
3255 		if ((r = sshkey_froms(buf, &k)) != 0 ||
3256 		    (r = sshkey_add_private(k)) != 0 ||
3257 		    (r = sshbuf_get_bignum2(buf, d)) != 0 ||
3258 		    (r = sshbuf_get_bignum2(buf, iqmp)) != 0 ||
3259 		    (r = sshbuf_get_bignum2(buf, p)) != 0 ||
3260 		    (r = sshbuf_get_bignum2(buf, q)) != 0) {
3261 			goto error3;
3262 		}
3263 		if (RSA_set0_key(k->rsa, NULL, NULL, d) == 0) {
3264 			r = SSH_ERR_LIBCRYPTO_ERROR;
3265 			goto error3;
3266 		}
3267 		/* dmp1,dmpq1 should be non NULL to set value */
3268 		if (RSA_set0_crt_params(k->rsa, dmp1, dmq1, iqmp) == 0) {
3269 			r = SSH_ERR_LIBCRYPTO_ERROR;
3270 			goto error3;
3271 		}
3272 		dmp1 = dmq1 = iqmp = NULL;
3273 		if (RSA_set0_factors(k->rsa, p, q) == 0) {
3274 			r = SSH_ERR_LIBCRYPTO_ERROR;
3275  error3:
3276 			BN_free(d); BN_free(iqmp);
3277 			BN_free(p); BN_free(q);
3278 			BN_free(dmp1); BN_free(dmq1);
3279 			goto out;
3280 		}
3281 		p = q = NULL;
3282 		if ((r = ssh_rsa_generate_additional_parameters(k)) != 0)
3283 			goto out;
3284 		}
3285 		if (RSA_bits(k->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
3286 			r = SSH_ERR_KEY_LENGTH;
3287 			goto out;
3288 		}
3289 		break;
3290 #endif /* WITH_OPENSSL */
3291 	case KEY_ED25519:
3292 		if ((k = sshkey_new_private(type)) == NULL) {
3293 			r = SSH_ERR_ALLOC_FAIL;
3294 			goto out;
3295 		}
3296 		if ((r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 ||
3297 		    (r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0)
3298 			goto out;
3299 		if (pklen != ED25519_PK_SZ || sklen != ED25519_SK_SZ) {
3300 			r = SSH_ERR_INVALID_FORMAT;
3301 			goto out;
3302 		}
3303 		k->ed25519_pk = ed25519_pk;
3304 		k->ed25519_sk = ed25519_sk;
3305 		ed25519_pk = ed25519_sk = NULL;
3306 		break;
3307 	case KEY_ED25519_CERT:
3308 		if ((r = sshkey_froms(buf, &k)) != 0 ||
3309 		    (r = sshkey_add_private(k)) != 0 ||
3310 		    (r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 ||
3311 		    (r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0)
3312 			goto out;
3313 		if (pklen != ED25519_PK_SZ || sklen != ED25519_SK_SZ) {
3314 			r = SSH_ERR_INVALID_FORMAT;
3315 			goto out;
3316 		}
3317 		k->ed25519_pk = ed25519_pk;
3318 		k->ed25519_sk = ed25519_sk;
3319 		ed25519_pk = ed25519_sk = NULL;
3320 		break;
3321 #ifdef WITH_XMSS
3322 	case KEY_XMSS:
3323 		if ((k = sshkey_new_private(type)) == NULL) {
3324 			r = SSH_ERR_ALLOC_FAIL;
3325 			goto out;
3326 		}
3327 		if ((r = sshbuf_get_cstring(buf, &xmss_name, NULL)) != 0 ||
3328 		    (r = sshkey_xmss_init(k, xmss_name)) != 0 ||
3329 		    (r = sshbuf_get_string(buf, &xmss_pk, &pklen)) != 0 ||
3330 		    (r = sshbuf_get_string(buf, &xmss_sk, &sklen)) != 0)
3331 			goto out;
3332 		if (pklen != sshkey_xmss_pklen(k) ||
3333 		    sklen != sshkey_xmss_sklen(k)) {
3334 			r = SSH_ERR_INVALID_FORMAT;
3335 			goto out;
3336 		}
3337 		k->xmss_pk = xmss_pk;
3338 		k->xmss_sk = xmss_sk;
3339 		xmss_pk = xmss_sk = NULL;
3340 		/* optional internal state */
3341 		if ((r = sshkey_xmss_deserialize_state_opt(k, buf)) != 0)
3342 			goto out;
3343 		break;
3344 	case KEY_XMSS_CERT:
3345 		if ((r = sshkey_froms(buf, &k)) != 0 ||
3346 		    (r = sshkey_add_private(k)) != 0 ||
3347 		    (r = sshbuf_get_cstring(buf, &xmss_name, NULL)) != 0 ||
3348 		    (r = sshbuf_get_string(buf, &xmss_pk, &pklen)) != 0 ||
3349 		    (r = sshbuf_get_string(buf, &xmss_sk, &sklen)) != 0)
3350 			goto out;
3351 		if (strcmp(xmss_name, k->xmss_name)) {
3352 			r = SSH_ERR_INVALID_FORMAT;
3353 			goto out;
3354 		}
3355 		if (pklen != sshkey_xmss_pklen(k) ||
3356 		    sklen != sshkey_xmss_sklen(k)) {
3357 			r = SSH_ERR_INVALID_FORMAT;
3358 			goto out;
3359 		}
3360 		k->xmss_pk = xmss_pk;
3361 		k->xmss_sk = xmss_sk;
3362 		xmss_pk = xmss_sk = NULL;
3363 		/* optional internal state */
3364 		if ((r = sshkey_xmss_deserialize_state_opt(k, buf)) != 0)
3365 			goto out;
3366 		break;
3367 #endif /* WITH_XMSS */
3368 	default:
3369 		r = SSH_ERR_KEY_TYPE_UNKNOWN;
3370 		goto out;
3371 	}
3372 #ifdef WITH_OPENSSL
3373 	/* enable blinding */
3374 	switch (k->type) {
3375 	case KEY_RSA:
3376 	case KEY_RSA_CERT:
3377 		if (RSA_blinding_on(k->rsa, NULL) != 1) {
3378 			r = SSH_ERR_LIBCRYPTO_ERROR;
3379 			goto out;
3380 		}
3381 		break;
3382 	}
3383 #endif /* WITH_OPENSSL */
3384 	/* success */
3385 	r = 0;
3386 	if (kp != NULL) {
3387 		*kp = k;
3388 		k = NULL;
3389 	}
3390  out:
3391 	free(tname);
3392 	free(curve);
3393 #ifdef WITH_OPENSSL
3394 	BN_clear_free(exponent);
3395 #endif /* WITH_OPENSSL */
3396 	sshkey_free(k);
3397 	freezero(ed25519_pk, pklen);
3398 	freezero(ed25519_sk, sklen);
3399 	free(xmss_name);
3400 	freezero(xmss_pk, pklen);
3401 	freezero(xmss_sk, sklen);
3402 	return r;
3403 }
3404 
3405 #ifdef WITH_OPENSSL
3406 int
3407 sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public)
3408 {
3409 	BN_CTX *bnctx;
3410 	EC_POINT *nq = NULL;
3411 	BIGNUM *order, *x, *y, *tmp;
3412 	int ret = SSH_ERR_KEY_INVALID_EC_VALUE;
3413 
3414 	/*
3415 	 * NB. This assumes OpenSSL has already verified that the public
3416 	 * point lies on the curve. This is done by EC_POINT_oct2point()
3417 	 * implicitly calling EC_POINT_is_on_curve(). If this code is ever
3418 	 * reachable with public points not unmarshalled using
3419 	 * EC_POINT_oct2point then the caller will need to explicitly check.
3420 	 */
3421 
3422 	if ((bnctx = BN_CTX_new()) == NULL)
3423 		return SSH_ERR_ALLOC_FAIL;
3424 	BN_CTX_start(bnctx);
3425 
3426 	/*
3427 	 * We shouldn't ever hit this case because bignum_get_ecpoint()
3428 	 * refuses to load GF2m points.
3429 	 */
3430 	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
3431 	    NID_X9_62_prime_field)
3432 		goto out;
3433 
3434 	/* Q != infinity */
3435 	if (EC_POINT_is_at_infinity(group, public))
3436 		goto out;
3437 
3438 	if ((x = BN_CTX_get(bnctx)) == NULL ||
3439 	    (y = BN_CTX_get(bnctx)) == NULL ||
3440 	    (order = BN_CTX_get(bnctx)) == NULL ||
3441 	    (tmp = BN_CTX_get(bnctx)) == NULL) {
3442 		ret = SSH_ERR_ALLOC_FAIL;
3443 		goto out;
3444 	}
3445 
3446 	/* log2(x) > log2(order)/2, log2(y) > log2(order)/2 */
3447 	if (EC_GROUP_get_order(group, order, bnctx) != 1 ||
3448 	    EC_POINT_get_affine_coordinates_GFp(group, public,
3449 	    x, y, bnctx) != 1) {
3450 		ret = SSH_ERR_LIBCRYPTO_ERROR;
3451 		goto out;
3452 	}
3453 	if (BN_num_bits(x) <= BN_num_bits(order) / 2 ||
3454 	    BN_num_bits(y) <= BN_num_bits(order) / 2)
3455 		goto out;
3456 
3457 	/* nQ == infinity (n == order of subgroup) */
3458 	if ((nq = EC_POINT_new(group)) == NULL) {
3459 		ret = SSH_ERR_ALLOC_FAIL;
3460 		goto out;
3461 	}
3462 	if (EC_POINT_mul(group, nq, NULL, public, order, bnctx) != 1) {
3463 		ret = SSH_ERR_LIBCRYPTO_ERROR;
3464 		goto out;
3465 	}
3466 	if (EC_POINT_is_at_infinity(group, nq) != 1)
3467 		goto out;
3468 
3469 	/* x < order - 1, y < order - 1 */
3470 	if (!BN_sub(tmp, order, BN_value_one())) {
3471 		ret = SSH_ERR_LIBCRYPTO_ERROR;
3472 		goto out;
3473 	}
3474 	if (BN_cmp(x, tmp) >= 0 || BN_cmp(y, tmp) >= 0)
3475 		goto out;
3476 	ret = 0;
3477  out:
3478 	BN_CTX_free(bnctx);
3479 	EC_POINT_free(nq);
3480 	return ret;
3481 }
3482 
3483 int
3484 sshkey_ec_validate_private(const EC_KEY *key)
3485 {
3486 	BN_CTX *bnctx;
3487 	BIGNUM *order, *tmp;
3488 	int ret = SSH_ERR_KEY_INVALID_EC_VALUE;
3489 
3490 	if ((bnctx = BN_CTX_new()) == NULL)
3491 		return SSH_ERR_ALLOC_FAIL;
3492 	BN_CTX_start(bnctx);
3493 
3494 	if ((order = BN_CTX_get(bnctx)) == NULL ||
3495 	    (tmp = BN_CTX_get(bnctx)) == NULL) {
3496 		ret = SSH_ERR_ALLOC_FAIL;
3497 		goto out;
3498 	}
3499 
3500 	/* log2(private) > log2(order)/2 */
3501 	if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, bnctx) != 1) {
3502 		ret = SSH_ERR_LIBCRYPTO_ERROR;
3503 		goto out;
3504 	}
3505 	if (BN_num_bits(EC_KEY_get0_private_key(key)) <=
3506 	    BN_num_bits(order) / 2)
3507 		goto out;
3508 
3509 	/* private < order - 1 */
3510 	if (!BN_sub(tmp, order, BN_value_one())) {
3511 		ret = SSH_ERR_LIBCRYPTO_ERROR;
3512 		goto out;
3513 	}
3514 	if (BN_cmp(EC_KEY_get0_private_key(key), tmp) >= 0)
3515 		goto out;
3516 	ret = 0;
3517  out:
3518 	BN_CTX_free(bnctx);
3519 	return ret;
3520 }
3521 
3522 void
3523 sshkey_dump_ec_point(const EC_GROUP *group, const EC_POINT *point)
3524 {
3525 	BIGNUM *x, *y;
3526 	BN_CTX *bnctx;
3527 
3528 	if (point == NULL) {
3529 		fputs("point=(NULL)\n", stderr);
3530 		return;
3531 	}
3532 	if ((bnctx = BN_CTX_new()) == NULL) {
3533 		fprintf(stderr, "%s: BN_CTX_new failed\n", __func__);
3534 		return;
3535 	}
3536 	BN_CTX_start(bnctx);
3537 	if ((x = BN_CTX_get(bnctx)) == NULL ||
3538 	    (y = BN_CTX_get(bnctx)) == NULL) {
3539 		fprintf(stderr, "%s: BN_CTX_get failed\n", __func__);
3540 		return;
3541 	}
3542 	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
3543 	    NID_X9_62_prime_field) {
3544 		fprintf(stderr, "%s: group is not a prime field\n", __func__);
3545 		return;
3546 	}
3547 	if (EC_POINT_get_affine_coordinates_GFp(group, point, x, y,
3548 	    bnctx) != 1) {
3549 		fprintf(stderr, "%s: EC_POINT_get_affine_coordinates_GFp\n",
3550 		    __func__);
3551 		return;
3552 	}
3553 	fputs("x=", stderr);
3554 	BN_print_fp(stderr, x);
3555 	fputs("\ny=", stderr);
3556 	BN_print_fp(stderr, y);
3557 	fputs("\n", stderr);
3558 	BN_CTX_free(bnctx);
3559 }
3560 
3561 void
3562 sshkey_dump_ec_key(const EC_KEY *key)
3563 {
3564 	const BIGNUM *exponent;
3565 
3566 	sshkey_dump_ec_point(EC_KEY_get0_group(key),
3567 	    EC_KEY_get0_public_key(key));
3568 	fputs("exponent=", stderr);
3569 	if ((exponent = EC_KEY_get0_private_key(key)) == NULL)
3570 		fputs("(NULL)", stderr);
3571 	else
3572 		BN_print_fp(stderr, EC_KEY_get0_private_key(key));
3573 	fputs("\n", stderr);
3574 }
3575 #endif /* WITH_OPENSSL */
3576 
3577 static int
3578 sshkey_private_to_blob2(const struct sshkey *prv, struct sshbuf *blob,
3579     const char *passphrase, const char *comment, const char *ciphername,
3580     int rounds)
3581 {
3582 	u_char *cp, *key = NULL, *pubkeyblob = NULL;
3583 	u_char salt[SALT_LEN];
3584 	char *b64 = NULL;
3585 	size_t i, pubkeylen, keylen, ivlen, blocksize, authlen;
3586 	u_int check;
3587 	int r = SSH_ERR_INTERNAL_ERROR;
3588 	struct sshcipher_ctx *ciphercontext = NULL;
3589 	const struct sshcipher *cipher;
3590 	const char *kdfname = KDFNAME;
3591 	struct sshbuf *encoded = NULL, *encrypted = NULL, *kdf = NULL;
3592 
3593 	if (rounds <= 0)
3594 		rounds = DEFAULT_ROUNDS;
3595 	if (passphrase == NULL || !strlen(passphrase)) {
3596 		ciphername = "none";
3597 		kdfname = "none";
3598 	} else if (ciphername == NULL)
3599 		ciphername = DEFAULT_CIPHERNAME;
3600 	if ((cipher = cipher_by_name(ciphername)) == NULL) {
3601 		r = SSH_ERR_INVALID_ARGUMENT;
3602 		goto out;
3603 	}
3604 
3605 	if ((kdf = sshbuf_new()) == NULL ||
3606 	    (encoded = sshbuf_new()) == NULL ||
3607 	    (encrypted = sshbuf_new()) == NULL) {
3608 		r = SSH_ERR_ALLOC_FAIL;
3609 		goto out;
3610 	}
3611 	blocksize = cipher_blocksize(cipher);
3612 	keylen = cipher_keylen(cipher);
3613 	ivlen = cipher_ivlen(cipher);
3614 	authlen = cipher_authlen(cipher);
3615 	if ((key = calloc(1, keylen + ivlen)) == NULL) {
3616 		r = SSH_ERR_ALLOC_FAIL;
3617 		goto out;
3618 	}
3619 	if (strcmp(kdfname, "bcrypt") == 0) {
3620 		arc4random_buf(salt, SALT_LEN);
3621 		if (bcrypt_pbkdf(passphrase, strlen(passphrase),
3622 		    salt, SALT_LEN, key, keylen + ivlen, rounds) < 0) {
3623 			r = SSH_ERR_INVALID_ARGUMENT;
3624 			goto out;
3625 		}
3626 		if ((r = sshbuf_put_string(kdf, salt, SALT_LEN)) != 0 ||
3627 		    (r = sshbuf_put_u32(kdf, rounds)) != 0)
3628 			goto out;
3629 	} else if (strcmp(kdfname, "none") != 0) {
3630 		/* Unsupported KDF type */
3631 		r = SSH_ERR_KEY_UNKNOWN_CIPHER;
3632 		goto out;
3633 	}
3634 	if ((r = cipher_init(&ciphercontext, cipher, key, keylen,
3635 	    key + keylen, ivlen, 1)) != 0)
3636 		goto out;
3637 
3638 	if ((r = sshbuf_put(encoded, AUTH_MAGIC, sizeof(AUTH_MAGIC))) != 0 ||
3639 	    (r = sshbuf_put_cstring(encoded, ciphername)) != 0 ||
3640 	    (r = sshbuf_put_cstring(encoded, kdfname)) != 0 ||
3641 	    (r = sshbuf_put_stringb(encoded, kdf)) != 0 ||
3642 	    (r = sshbuf_put_u32(encoded, 1)) != 0 ||	/* number of keys */
3643 	    (r = sshkey_to_blob(prv, &pubkeyblob, &pubkeylen)) != 0 ||
3644 	    (r = sshbuf_put_string(encoded, pubkeyblob, pubkeylen)) != 0)
3645 		goto out;
3646 
3647 	/* set up the buffer that will be encrypted */
3648 
3649 	/* Random check bytes */
3650 	check = arc4random();
3651 	if ((r = sshbuf_put_u32(encrypted, check)) != 0 ||
3652 	    (r = sshbuf_put_u32(encrypted, check)) != 0)
3653 		goto out;
3654 
3655 	/* append private key and comment*/
3656 	if ((r = sshkey_private_serialize_opt(prv, encrypted,
3657 	     SSHKEY_SERIALIZE_FULL)) != 0 ||
3658 	    (r = sshbuf_put_cstring(encrypted, comment)) != 0)
3659 		goto out;
3660 
3661 	/* padding */
3662 	i = 0;
3663 	while (sshbuf_len(encrypted) % blocksize) {
3664 		if ((r = sshbuf_put_u8(encrypted, ++i & 0xff)) != 0)
3665 			goto out;
3666 	}
3667 
3668 	/* length in destination buffer */
3669 	if ((r = sshbuf_put_u32(encoded, sshbuf_len(encrypted))) != 0)
3670 		goto out;
3671 
3672 	/* encrypt */
3673 	if ((r = sshbuf_reserve(encoded,
3674 	    sshbuf_len(encrypted) + authlen, &cp)) != 0)
3675 		goto out;
3676 	if ((r = cipher_crypt(ciphercontext, 0, cp,
3677 	    sshbuf_ptr(encrypted), sshbuf_len(encrypted), 0, authlen)) != 0)
3678 		goto out;
3679 
3680 	/* uuencode */
3681 	if ((b64 = sshbuf_dtob64(encoded)) == NULL) {
3682 		r = SSH_ERR_ALLOC_FAIL;
3683 		goto out;
3684 	}
3685 
3686 	sshbuf_reset(blob);
3687 	if ((r = sshbuf_put(blob, MARK_BEGIN, MARK_BEGIN_LEN)) != 0)
3688 		goto out;
3689 	for (i = 0; i < strlen(b64); i++) {
3690 		if ((r = sshbuf_put_u8(blob, b64[i])) != 0)
3691 			goto out;
3692 		/* insert line breaks */
3693 		if (i % 70 == 69 && (r = sshbuf_put_u8(blob, '\n')) != 0)
3694 			goto out;
3695 	}
3696 	if (i % 70 != 69 && (r = sshbuf_put_u8(blob, '\n')) != 0)
3697 		goto out;
3698 	if ((r = sshbuf_put(blob, MARK_END, MARK_END_LEN)) != 0)
3699 		goto out;
3700 
3701 	/* success */
3702 	r = 0;
3703 
3704  out:
3705 	sshbuf_free(kdf);
3706 	sshbuf_free(encoded);
3707 	sshbuf_free(encrypted);
3708 	cipher_free(ciphercontext);
3709 	explicit_bzero(salt, sizeof(salt));
3710 	if (key != NULL) {
3711 		explicit_bzero(key, keylen + ivlen);
3712 		free(key);
3713 	}
3714 	if (pubkeyblob != NULL) {
3715 		explicit_bzero(pubkeyblob, pubkeylen);
3716 		free(pubkeyblob);
3717 	}
3718 	if (b64 != NULL) {
3719 		explicit_bzero(b64, strlen(b64));
3720 		free(b64);
3721 	}
3722 	return r;
3723 }
3724 
3725 static int
3726 sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
3727     struct sshkey **keyp, char **commentp)
3728 {
3729 	char *comment = NULL, *ciphername = NULL, *kdfname = NULL;
3730 	const struct sshcipher *cipher = NULL;
3731 	const u_char *cp;
3732 	int r = SSH_ERR_INTERNAL_ERROR;
3733 	size_t encoded_len;
3734 	size_t i, keylen = 0, ivlen = 0, authlen = 0, slen = 0;
3735 	struct sshbuf *encoded = NULL, *decoded = NULL;
3736 	struct sshbuf *kdf = NULL, *decrypted = NULL;
3737 	struct sshcipher_ctx *ciphercontext = NULL;
3738 	struct sshkey *k = NULL;
3739 	u_char *key = NULL, *salt = NULL, *dp, pad, last;
3740 	u_int blocksize, rounds, nkeys, encrypted_len, check1, check2;
3741 
3742 	if (keyp != NULL)
3743 		*keyp = NULL;
3744 	if (commentp != NULL)
3745 		*commentp = NULL;
3746 
3747 	if ((encoded = sshbuf_new()) == NULL ||
3748 	    (decoded = sshbuf_new()) == NULL ||
3749 	    (decrypted = sshbuf_new()) == NULL) {
3750 		r = SSH_ERR_ALLOC_FAIL;
3751 		goto out;
3752 	}
3753 
3754 	/* check preamble */
3755 	cp = sshbuf_ptr(blob);
3756 	encoded_len = sshbuf_len(blob);
3757 	if (encoded_len < (MARK_BEGIN_LEN + MARK_END_LEN) ||
3758 	    memcmp(cp, MARK_BEGIN, MARK_BEGIN_LEN) != 0) {
3759 		r = SSH_ERR_INVALID_FORMAT;
3760 		goto out;
3761 	}
3762 	cp += MARK_BEGIN_LEN;
3763 	encoded_len -= MARK_BEGIN_LEN;
3764 
3765 	/* Look for end marker, removing whitespace as we go */
3766 	while (encoded_len > 0) {
3767 		if (*cp != '\n' && *cp != '\r') {
3768 			if ((r = sshbuf_put_u8(encoded, *cp)) != 0)
3769 				goto out;
3770 		}
3771 		last = *cp;
3772 		encoded_len--;
3773 		cp++;
3774 		if (last == '\n') {
3775 			if (encoded_len >= MARK_END_LEN &&
3776 			    memcmp(cp, MARK_END, MARK_END_LEN) == 0) {
3777 				/* \0 terminate */
3778 				if ((r = sshbuf_put_u8(encoded, 0)) != 0)
3779 					goto out;
3780 				break;
3781 			}
3782 		}
3783 	}
3784 	if (encoded_len == 0) {
3785 		r = SSH_ERR_INVALID_FORMAT;
3786 		goto out;
3787 	}
3788 
3789 	/* decode base64 */
3790 	if ((r = sshbuf_b64tod(decoded, (const char *)sshbuf_ptr(encoded))) != 0)
3791 		goto out;
3792 
3793 	/* check magic */
3794 	if (sshbuf_len(decoded) < sizeof(AUTH_MAGIC) ||
3795 	    memcmp(sshbuf_ptr(decoded), AUTH_MAGIC, sizeof(AUTH_MAGIC))) {
3796 		r = SSH_ERR_INVALID_FORMAT;
3797 		goto out;
3798 	}
3799 	/* parse public portion of key */
3800 	if ((r = sshbuf_consume(decoded, sizeof(AUTH_MAGIC))) != 0 ||
3801 	    (r = sshbuf_get_cstring(decoded, &ciphername, NULL)) != 0 ||
3802 	    (r = sshbuf_get_cstring(decoded, &kdfname, NULL)) != 0 ||
3803 	    (r = sshbuf_froms(decoded, &kdf)) != 0 ||
3804 	    (r = sshbuf_get_u32(decoded, &nkeys)) != 0 ||
3805 	    (r = sshbuf_skip_string(decoded)) != 0 || /* pubkey */
3806 	    (r = sshbuf_get_u32(decoded, &encrypted_len)) != 0)
3807 		goto out;
3808 
3809 	if ((cipher = cipher_by_name(ciphername)) == NULL) {
3810 		r = SSH_ERR_KEY_UNKNOWN_CIPHER;
3811 		goto out;
3812 	}
3813 	if ((passphrase == NULL || strlen(passphrase) == 0) &&
3814 	    strcmp(ciphername, "none") != 0) {
3815 		/* passphrase required */
3816 		r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3817 		goto out;
3818 	}
3819 	if (strcmp(kdfname, "none") != 0 && strcmp(kdfname, "bcrypt") != 0) {
3820 		r = SSH_ERR_KEY_UNKNOWN_CIPHER;
3821 		goto out;
3822 	}
3823 	if (!strcmp(kdfname, "none") && strcmp(ciphername, "none") != 0) {
3824 		r = SSH_ERR_INVALID_FORMAT;
3825 		goto out;
3826 	}
3827 	if (nkeys != 1) {
3828 		/* XXX only one key supported */
3829 		r = SSH_ERR_INVALID_FORMAT;
3830 		goto out;
3831 	}
3832 
3833 	/* check size of encrypted key blob */
3834 	blocksize = cipher_blocksize(cipher);
3835 	if (encrypted_len < blocksize || (encrypted_len % blocksize) != 0) {
3836 		r = SSH_ERR_INVALID_FORMAT;
3837 		goto out;
3838 	}
3839 
3840 	/* setup key */
3841 	keylen = cipher_keylen(cipher);
3842 	ivlen = cipher_ivlen(cipher);
3843 	authlen = cipher_authlen(cipher);
3844 	if ((key = calloc(1, keylen + ivlen)) == NULL) {
3845 		r = SSH_ERR_ALLOC_FAIL;
3846 		goto out;
3847 	}
3848 	if (strcmp(kdfname, "bcrypt") == 0) {
3849 		if ((r = sshbuf_get_string(kdf, &salt, &slen)) != 0 ||
3850 		    (r = sshbuf_get_u32(kdf, &rounds)) != 0)
3851 			goto out;
3852 		if (bcrypt_pbkdf(passphrase, strlen(passphrase), salt, slen,
3853 		    key, keylen + ivlen, rounds) < 0) {
3854 			r = SSH_ERR_INVALID_FORMAT;
3855 			goto out;
3856 		}
3857 	}
3858 
3859 	/* check that an appropriate amount of auth data is present */
3860 	if (sshbuf_len(decoded) < encrypted_len + authlen) {
3861 		r = SSH_ERR_INVALID_FORMAT;
3862 		goto out;
3863 	}
3864 
3865 	/* decrypt private portion of key */
3866 	if ((r = sshbuf_reserve(decrypted, encrypted_len, &dp)) != 0 ||
3867 	    (r = cipher_init(&ciphercontext, cipher, key, keylen,
3868 	    key + keylen, ivlen, 0)) != 0)
3869 		goto out;
3870 	if ((r = cipher_crypt(ciphercontext, 0, dp, sshbuf_ptr(decoded),
3871 	    encrypted_len, 0, authlen)) != 0) {
3872 		/* an integrity error here indicates an incorrect passphrase */
3873 		if (r == SSH_ERR_MAC_INVALID)
3874 			r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3875 		goto out;
3876 	}
3877 	if ((r = sshbuf_consume(decoded, encrypted_len + authlen)) != 0)
3878 		goto out;
3879 	/* there should be no trailing data */
3880 	if (sshbuf_len(decoded) != 0) {
3881 		r = SSH_ERR_INVALID_FORMAT;
3882 		goto out;
3883 	}
3884 
3885 	/* check check bytes */
3886 	if ((r = sshbuf_get_u32(decrypted, &check1)) != 0 ||
3887 	    (r = sshbuf_get_u32(decrypted, &check2)) != 0)
3888 		goto out;
3889 	if (check1 != check2) {
3890 		r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3891 		goto out;
3892 	}
3893 
3894 	/* Load the private key and comment */
3895 	if ((r = sshkey_private_deserialize(decrypted, &k)) != 0 ||
3896 	    (r = sshbuf_get_cstring(decrypted, &comment, NULL)) != 0)
3897 		goto out;
3898 
3899 	/* Check deterministic padding */
3900 	i = 0;
3901 	while (sshbuf_len(decrypted)) {
3902 		if ((r = sshbuf_get_u8(decrypted, &pad)) != 0)
3903 			goto out;
3904 		if (pad != (++i & 0xff)) {
3905 			r = SSH_ERR_INVALID_FORMAT;
3906 			goto out;
3907 		}
3908 	}
3909 
3910 	/* XXX decode pubkey and check against private */
3911 
3912 	/* success */
3913 	r = 0;
3914 	if (keyp != NULL) {
3915 		*keyp = k;
3916 		k = NULL;
3917 	}
3918 	if (commentp != NULL) {
3919 		*commentp = comment;
3920 		comment = NULL;
3921 	}
3922  out:
3923 	pad = 0;
3924 	cipher_free(ciphercontext);
3925 	free(ciphername);
3926 	free(kdfname);
3927 	free(comment);
3928 	if (salt != NULL) {
3929 		explicit_bzero(salt, slen);
3930 		free(salt);
3931 	}
3932 	if (key != NULL) {
3933 		explicit_bzero(key, keylen + ivlen);
3934 		free(key);
3935 	}
3936 	sshbuf_free(encoded);
3937 	sshbuf_free(decoded);
3938 	sshbuf_free(kdf);
3939 	sshbuf_free(decrypted);
3940 	sshkey_free(k);
3941 	return r;
3942 }
3943 
3944 
3945 #ifdef WITH_OPENSSL
3946 /* convert SSH v2 key in OpenSSL PEM format */
3947 static int
3948 sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob,
3949     const char *_passphrase, const char *comment)
3950 {
3951 	int success, r;
3952 	int blen, len = strlen(_passphrase);
3953 	u_char *passphrase = (len > 0) ? __UNCONST(_passphrase) : NULL;
3954 	const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL;
3955 	char *bptr;
3956 	BIO *bio = NULL;
3957 
3958 	if (len > 0 && len <= 4)
3959 		return SSH_ERR_PASSPHRASE_TOO_SHORT;
3960 	if ((bio = BIO_new(BIO_s_mem())) == NULL)
3961 		return SSH_ERR_ALLOC_FAIL;
3962 
3963 	switch (key->type) {
3964 	case KEY_DSA:
3965 		success = PEM_write_bio_DSAPrivateKey(bio, key->dsa,
3966 		    cipher, passphrase, len, NULL, NULL);
3967 		break;
3968 	case KEY_ECDSA:
3969 		success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa,
3970 		    cipher, passphrase, len, NULL, NULL);
3971 		break;
3972 	case KEY_RSA:
3973 		success = PEM_write_bio_RSAPrivateKey(bio, key->rsa,
3974 		    cipher, passphrase, len, NULL, NULL);
3975 		break;
3976 	default:
3977 		success = 0;
3978 		break;
3979 	}
3980 	if (success == 0) {
3981 		r = SSH_ERR_LIBCRYPTO_ERROR;
3982 		goto out;
3983 	}
3984 	if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0) {
3985 		r = SSH_ERR_INTERNAL_ERROR;
3986 		goto out;
3987 	}
3988 	if ((r = sshbuf_put(blob, bptr, blen)) != 0)
3989 		goto out;
3990 	r = 0;
3991  out:
3992 	BIO_free(bio);
3993 	return r;
3994 }
3995 #endif /* WITH_OPENSSL */
3996 
3997 /* Serialise "key" to buffer "blob" */
3998 int
3999 sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob,
4000     const char *passphrase, const char *comment,
4001     int force_new_format, const char *new_format_cipher, int new_format_rounds)
4002 {
4003 	switch (key->type) {
4004 #ifdef WITH_OPENSSL
4005 	case KEY_DSA:
4006 	case KEY_ECDSA:
4007 	case KEY_RSA:
4008 		if (force_new_format) {
4009 			return sshkey_private_to_blob2(key, blob, passphrase,
4010 			    comment, new_format_cipher, new_format_rounds);
4011 		}
4012 		return sshkey_private_pem_to_blob(key, blob,
4013 		    passphrase, comment);
4014 #endif /* WITH_OPENSSL */
4015 	case KEY_ED25519:
4016 #ifdef WITH_XMSS
4017 	case KEY_XMSS:
4018 #endif /* WITH_XMSS */
4019 		return sshkey_private_to_blob2(key, blob, passphrase,
4020 		    comment, new_format_cipher, new_format_rounds);
4021 	default:
4022 		return SSH_ERR_KEY_TYPE_UNKNOWN;
4023 	}
4024 }
4025 
4026 
4027 #ifdef WITH_OPENSSL
4028 static int
4029 translate_libcrypto_error(unsigned long pem_err)
4030 {
4031 	int pem_reason = ERR_GET_REASON(pem_err);
4032 
4033 	switch (ERR_GET_LIB(pem_err)) {
4034 	case ERR_LIB_PEM:
4035 		switch (pem_reason) {
4036 		case PEM_R_BAD_PASSWORD_READ:
4037 		case PEM_R_PROBLEMS_GETTING_PASSWORD:
4038 		case PEM_R_BAD_DECRYPT:
4039 			return SSH_ERR_KEY_WRONG_PASSPHRASE;
4040 		default:
4041 			return SSH_ERR_INVALID_FORMAT;
4042 		}
4043 	case ERR_LIB_EVP:
4044 		switch (pem_reason) {
4045 		case EVP_R_BAD_DECRYPT:
4046 			return SSH_ERR_KEY_WRONG_PASSPHRASE;
4047 		case EVP_R_DECODE_ERROR:
4048 #ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR
4049 		case EVP_R_PRIVATE_KEY_DECODE_ERROR:
4050 #endif
4051 			return SSH_ERR_INVALID_FORMAT;
4052 		default:
4053 			return SSH_ERR_LIBCRYPTO_ERROR;
4054 		}
4055 	case ERR_LIB_ASN1:
4056 		return SSH_ERR_INVALID_FORMAT;
4057 	}
4058 	return SSH_ERR_LIBCRYPTO_ERROR;
4059 }
4060 
4061 static void
4062 clear_libcrypto_errors(void)
4063 {
4064 	while (ERR_get_error() != 0)
4065 		;
4066 }
4067 
4068 /*
4069  * Translate OpenSSL error codes to determine whether
4070  * passphrase is required/incorrect.
4071  */
4072 static int
4073 convert_libcrypto_error(void)
4074 {
4075 	/*
4076 	 * Some password errors are reported at the beginning
4077 	 * of the error queue.
4078 	 */
4079 	if (translate_libcrypto_error(ERR_peek_error()) ==
4080 	    SSH_ERR_KEY_WRONG_PASSPHRASE)
4081 		return SSH_ERR_KEY_WRONG_PASSPHRASE;
4082 	return translate_libcrypto_error(ERR_peek_last_error());
4083 }
4084 
4085 static int
4086 sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
4087     const char *passphrase, struct sshkey **keyp)
4088 {
4089 	EVP_PKEY *pk = NULL;
4090 	struct sshkey *prv = NULL;
4091 	BIO *bio = NULL;
4092 	int r;
4093 
4094 	if (keyp != NULL)
4095 		*keyp = NULL;
4096 
4097 	if ((bio = BIO_new(BIO_s_mem())) == NULL || sshbuf_len(blob) > INT_MAX)
4098 		return SSH_ERR_ALLOC_FAIL;
4099 	if (BIO_write(bio, sshbuf_ptr(blob), sshbuf_len(blob)) !=
4100 	    (int)sshbuf_len(blob)) {
4101 		r = SSH_ERR_ALLOC_FAIL;
4102 		goto out;
4103 	}
4104 
4105 	clear_libcrypto_errors();
4106 	if ((pk = PEM_read_bio_PrivateKey(bio, NULL, NULL,
4107 	    __UNCONST(passphrase))) == NULL) {
4108 		r = convert_libcrypto_error();
4109 		goto out;
4110 	}
4111 	if (EVP_PKEY_id(pk) == EVP_PKEY_RSA &&
4112 	    (type == KEY_UNSPEC || type == KEY_RSA)) {
4113 		if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
4114 			r = SSH_ERR_ALLOC_FAIL;
4115 			goto out;
4116 		}
4117 		prv->rsa = EVP_PKEY_get1_RSA(pk);
4118 		prv->type = KEY_RSA;
4119 #ifdef DEBUG_PK
4120 		RSA_print_fp(stderr, prv->rsa, 8);
4121 #endif
4122 		if (RSA_blinding_on(prv->rsa, NULL) != 1) {
4123 			r = SSH_ERR_LIBCRYPTO_ERROR;
4124 			goto out;
4125 		}
4126 		if (RSA_bits(prv->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
4127 			r = SSH_ERR_KEY_LENGTH;
4128 			goto out;
4129 		}
4130 	} else if (EVP_PKEY_id(pk) == EVP_PKEY_DSA &&
4131 	    (type == KEY_UNSPEC || type == KEY_DSA)) {
4132 		if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
4133 			r = SSH_ERR_ALLOC_FAIL;
4134 			goto out;
4135 		}
4136 		prv->dsa = EVP_PKEY_get1_DSA(pk);
4137 		prv->type = KEY_DSA;
4138 #ifdef DEBUG_PK
4139 		DSA_print_fp(stderr, prv->dsa, 8);
4140 #endif
4141 	} else if (EVP_PKEY_id(pk) == EVP_PKEY_EC &&
4142 	    (type == KEY_UNSPEC || type == KEY_ECDSA)) {
4143 		if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
4144 			r = SSH_ERR_ALLOC_FAIL;
4145 			goto out;
4146 		}
4147 		prv->ecdsa = EVP_PKEY_get1_EC_KEY(pk);
4148 		prv->type = KEY_ECDSA;
4149 		prv->ecdsa_nid = sshkey_ecdsa_key_to_nid(prv->ecdsa);
4150 		if (prv->ecdsa_nid == -1 ||
4151 		    sshkey_curve_nid_to_name(prv->ecdsa_nid) == NULL ||
4152 		    sshkey_ec_validate_public(EC_KEY_get0_group(prv->ecdsa),
4153 		    EC_KEY_get0_public_key(prv->ecdsa)) != 0 ||
4154 		    sshkey_ec_validate_private(prv->ecdsa) != 0) {
4155 			r = SSH_ERR_INVALID_FORMAT;
4156 			goto out;
4157 		}
4158 #ifdef DEBUG_PK
4159 		if (prv != NULL && prv->ecdsa != NULL)
4160 			sshkey_dump_ec_key(prv->ecdsa);
4161 #endif
4162 	} else {
4163 		r = SSH_ERR_INVALID_FORMAT;
4164 		goto out;
4165 	}
4166 	r = 0;
4167 	if (keyp != NULL) {
4168 		*keyp = prv;
4169 		prv = NULL;
4170 	}
4171  out:
4172 	BIO_free(bio);
4173 	EVP_PKEY_free(pk);
4174 	sshkey_free(prv);
4175 	return r;
4176 }
4177 #endif /* WITH_OPENSSL */
4178 
4179 int
4180 sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
4181     const char *passphrase, struct sshkey **keyp, char **commentp)
4182 {
4183 	int r = SSH_ERR_INTERNAL_ERROR;
4184 
4185 	if (keyp != NULL)
4186 		*keyp = NULL;
4187 	if (commentp != NULL)
4188 		*commentp = NULL;
4189 
4190 	switch (type) {
4191 #ifdef WITH_OPENSSL
4192 	case KEY_DSA:
4193 	case KEY_ECDSA:
4194 	case KEY_RSA:
4195 		return sshkey_parse_private_pem_fileblob(blob, type,
4196 		    passphrase, keyp);
4197 #endif /* WITH_OPENSSL */
4198 	case KEY_ED25519:
4199 #ifdef WITH_XMSS
4200 	case KEY_XMSS:
4201 #endif /* WITH_XMSS */
4202 		return sshkey_parse_private2(blob, type, passphrase,
4203 		    keyp, commentp);
4204 	case KEY_UNSPEC:
4205 		r = sshkey_parse_private2(blob, type, passphrase, keyp,
4206 		    commentp);
4207 		/* Do not fallback to PEM parser if only passphrase is wrong. */
4208 		if (r == 0 || r == SSH_ERR_KEY_WRONG_PASSPHRASE)
4209 			return r;
4210 #ifdef WITH_OPENSSL
4211 		return sshkey_parse_private_pem_fileblob(blob, type,
4212 		    passphrase, keyp);
4213 #else
4214 		return SSH_ERR_INVALID_FORMAT;
4215 #endif /* WITH_OPENSSL */
4216 	default:
4217 		return SSH_ERR_KEY_TYPE_UNKNOWN;
4218 	}
4219 }
4220 
4221 int
4222 sshkey_parse_private_fileblob(struct sshbuf *buffer, const char *passphrase,
4223     struct sshkey **keyp, char **commentp)
4224 {
4225 	if (keyp != NULL)
4226 		*keyp = NULL;
4227 	if (commentp != NULL)
4228 		*commentp = NULL;
4229 
4230 	return sshkey_parse_private_fileblob_type(buffer, KEY_UNSPEC,
4231 	    passphrase, keyp, commentp);
4232 }
4233 
4234 #ifdef WITH_XMSS
4235 /*
4236  * serialize the key with the current state and forward the state
4237  * maxsign times.
4238  */
4239 int
4240 sshkey_private_serialize_maxsign(const struct sshkey *k, struct sshbuf *b,
4241     u_int32_t maxsign, sshkey_printfn *pr)
4242 {
4243 	int r, rupdate;
4244 
4245 	if (maxsign == 0 ||
4246 	    sshkey_type_plain(k->type) != KEY_XMSS)
4247 		return sshkey_private_serialize_opt(k, b,
4248 		    SSHKEY_SERIALIZE_DEFAULT);
4249 	if ((r = sshkey_xmss_get_state(k, pr)) != 0 ||
4250 	    (r = sshkey_private_serialize_opt(k, b,
4251 	    SSHKEY_SERIALIZE_STATE)) != 0 ||
4252 	    (r = sshkey_xmss_forward_state(k, maxsign)) != 0)
4253 		goto out;
4254 	r = 0;
4255 out:
4256 	if ((rupdate = sshkey_xmss_update_state(k, pr)) != 0) {
4257 		if (r == 0)
4258 			r = rupdate;
4259 	}
4260 	return r;
4261 }
4262 
4263 u_int32_t
4264 sshkey_signatures_left(const struct sshkey *k)
4265 {
4266 	if (sshkey_type_plain(k->type) == KEY_XMSS)
4267 		return sshkey_xmss_signatures_left(k);
4268 	return 0;
4269 }
4270 
4271 int
4272 sshkey_enable_maxsign(struct sshkey *k, u_int32_t maxsign)
4273 {
4274 	if (sshkey_type_plain(k->type) != KEY_XMSS)
4275 		return SSH_ERR_INVALID_ARGUMENT;
4276 	return sshkey_xmss_enable_maxsign(k, maxsign);
4277 }
4278 
4279 int
4280 sshkey_set_filename(struct sshkey *k, const char *filename)
4281 {
4282 	if (k == NULL)
4283 		return SSH_ERR_INVALID_ARGUMENT;
4284 	if (sshkey_type_plain(k->type) != KEY_XMSS)
4285 		return 0;
4286 	if (filename == NULL)
4287 		return SSH_ERR_INVALID_ARGUMENT;
4288 	if ((k->xmss_filename = strdup(filename)) == NULL)
4289 		return SSH_ERR_ALLOC_FAIL;
4290 	return 0;
4291 }
4292 #else
4293 int
4294 sshkey_private_serialize_maxsign(const struct sshkey *k, struct sshbuf *b,
4295     u_int32_t maxsign, sshkey_printfn *pr)
4296 {
4297 	return sshkey_private_serialize_opt(k, b, SSHKEY_SERIALIZE_DEFAULT);
4298 }
4299 
4300 u_int32_t
4301 sshkey_signatures_left(const struct sshkey *k)
4302 {
4303 	return 0;
4304 }
4305 
4306 int
4307 sshkey_enable_maxsign(struct sshkey *k, u_int32_t maxsign)
4308 {
4309 	return SSH_ERR_INVALID_ARGUMENT;
4310 }
4311 
4312 int
4313 sshkey_set_filename(struct sshkey *k, const char *filename)
4314 {
4315 	if (k == NULL)
4316 		return SSH_ERR_INVALID_ARGUMENT;
4317 	return 0;
4318 }
4319 #endif /* WITH_XMSS */
4320