xref: /freebsd/crypto/openssh/sshkey.c (revision 96f262dcacdbfb56e94c60985b07f9f8ee2d046b)
1 /* $OpenBSD: sshkey.c,v 1.155 2025/10/03 00:08:02 djm Exp $ */
2 /*
3  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
4  * Copyright (c) 2008 Alexander von Gernler.  All rights reserved.
5  * Copyright (c) 2010,2011 Damien Miller.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include "includes.h"
29 
30 #include <sys/types.h>
31 #include <sys/mman.h>
32 #include <netinet/in.h>
33 
34 #ifdef WITH_OPENSSL
35 #include <openssl/bn.h>
36 #include <openssl/evp.h>
37 #include <openssl/err.h>
38 #include <openssl/pem.h>
39 #endif
40 
41 #include "crypto_api.h"
42 
43 #include <errno.h>
44 #include <limits.h>
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #include <resolv.h>
49 #include <time.h>
50 #include <util.h>
51 
52 #include "ssh2.h"
53 #include "ssherr.h"
54 #include "misc.h"
55 #include "sshbuf.h"
56 #include "cipher.h"
57 #include "digest.h"
58 #define SSHKEY_INTERNAL
59 #include "sshkey.h"
60 #include "match.h"
61 #include "ssh-sk.h"
62 #include "ssh-pkcs11.h"
63 
64 #include "openbsd-compat/openssl-compat.h"
65 
66 /* openssh private key file format */
67 #define MARK_BEGIN		"-----BEGIN OPENSSH PRIVATE KEY-----\n"
68 #define MARK_END		"-----END OPENSSH PRIVATE KEY-----\n"
69 #define MARK_BEGIN_LEN		(sizeof(MARK_BEGIN) - 1)
70 #define MARK_END_LEN		(sizeof(MARK_END) - 1)
71 #define KDFNAME			"bcrypt"
72 #define AUTH_MAGIC		"openssh-key-v1"
73 #define SALT_LEN		16
74 #define DEFAULT_CIPHERNAME	"aes256-ctr"
75 #define	DEFAULT_ROUNDS		24
76 
77 /*
78  * Constants relating to "shielding" support; protection of keys expected
79  * to remain in memory for long durations
80  */
81 #define SSHKEY_SHIELD_PREKEY_LEN	(16 * 1024)
82 #define SSHKEY_SHIELD_CIPHER		"aes256-ctr" /* XXX want AES-EME* */
83 #define SSHKEY_SHIELD_PREKEY_HASH	SSH_DIGEST_SHA512
84 
85 static int sshkey_from_blob_internal(struct sshbuf *buf,
86     struct sshkey **keyp, int allow_cert);
87 
88 /* Supported key types */
89 extern const struct sshkey_impl sshkey_ed25519_impl;
90 extern const struct sshkey_impl sshkey_ed25519_cert_impl;
91 extern const struct sshkey_impl sshkey_ed25519_sk_impl;
92 extern const struct sshkey_impl sshkey_ed25519_sk_cert_impl;
93 #ifdef WITH_OPENSSL
94 # ifdef OPENSSL_HAS_ECC
95 #  ifdef ENABLE_SK
96 extern const struct sshkey_impl sshkey_ecdsa_sk_impl;
97 extern const struct sshkey_impl sshkey_ecdsa_sk_cert_impl;
98 extern const struct sshkey_impl sshkey_ecdsa_sk_webauthn_impl;
99 #  endif /* ENABLE_SK */
100 extern const struct sshkey_impl sshkey_ecdsa_nistp256_impl;
101 extern const struct sshkey_impl sshkey_ecdsa_nistp256_cert_impl;
102 extern const struct sshkey_impl sshkey_ecdsa_nistp384_impl;
103 extern const struct sshkey_impl sshkey_ecdsa_nistp384_cert_impl;
104 #  ifdef OPENSSL_HAS_NISTP521
105 extern const struct sshkey_impl sshkey_ecdsa_nistp521_impl;
106 extern const struct sshkey_impl sshkey_ecdsa_nistp521_cert_impl;
107 #  endif /* OPENSSL_HAS_NISTP521 */
108 # endif /* OPENSSL_HAS_ECC */
109 extern const struct sshkey_impl sshkey_rsa_impl;
110 extern const struct sshkey_impl sshkey_rsa_cert_impl;
111 extern const struct sshkey_impl sshkey_rsa_sha256_impl;
112 extern const struct sshkey_impl sshkey_rsa_sha256_cert_impl;
113 extern const struct sshkey_impl sshkey_rsa_sha512_impl;
114 extern const struct sshkey_impl sshkey_rsa_sha512_cert_impl;
115 #endif /* WITH_OPENSSL */
116 
117 const struct sshkey_impl * const keyimpls[] = {
118 	&sshkey_ed25519_impl,
119 	&sshkey_ed25519_cert_impl,
120 #ifdef ENABLE_SK
121 	&sshkey_ed25519_sk_impl,
122 	&sshkey_ed25519_sk_cert_impl,
123 #endif
124 #ifdef WITH_OPENSSL
125 # ifdef OPENSSL_HAS_ECC
126 	&sshkey_ecdsa_nistp256_impl,
127 	&sshkey_ecdsa_nistp256_cert_impl,
128 	&sshkey_ecdsa_nistp384_impl,
129 	&sshkey_ecdsa_nistp384_cert_impl,
130 #  ifdef OPENSSL_HAS_NISTP521
131 	&sshkey_ecdsa_nistp521_impl,
132 	&sshkey_ecdsa_nistp521_cert_impl,
133 #  endif /* OPENSSL_HAS_NISTP521 */
134 #  ifdef ENABLE_SK
135 	&sshkey_ecdsa_sk_impl,
136 	&sshkey_ecdsa_sk_cert_impl,
137 	&sshkey_ecdsa_sk_webauthn_impl,
138 #  endif /* ENABLE_SK */
139 # endif /* OPENSSL_HAS_ECC */
140 	&sshkey_rsa_impl,
141 	&sshkey_rsa_cert_impl,
142 	&sshkey_rsa_sha256_impl,
143 	&sshkey_rsa_sha256_cert_impl,
144 	&sshkey_rsa_sha512_impl,
145 	&sshkey_rsa_sha512_cert_impl,
146 #endif /* WITH_OPENSSL */
147 	NULL
148 };
149 
150 static const struct sshkey_impl *
151 sshkey_impl_from_type(int type)
152 {
153 	int i;
154 
155 	for (i = 0; keyimpls[i] != NULL; i++) {
156 		if (keyimpls[i]->type == type)
157 			return keyimpls[i];
158 	}
159 	return NULL;
160 }
161 
162 static const struct sshkey_impl *
163 sshkey_impl_from_type_nid(int type, int nid)
164 {
165 	int i;
166 
167 	for (i = 0; keyimpls[i] != NULL; i++) {
168 		if (keyimpls[i]->type == type &&
169 		    (keyimpls[i]->nid == 0 || keyimpls[i]->nid == nid))
170 			return keyimpls[i];
171 	}
172 	return NULL;
173 }
174 
175 static const struct sshkey_impl *
176 sshkey_impl_from_key(const struct sshkey *k)
177 {
178 	if (k == NULL)
179 		return NULL;
180 	return sshkey_impl_from_type_nid(k->type, k->ecdsa_nid);
181 }
182 
183 const char *
184 sshkey_type(const struct sshkey *k)
185 {
186 	const struct sshkey_impl *impl;
187 
188 	if ((impl = sshkey_impl_from_key(k)) == NULL)
189 		return "unknown";
190 	return impl->shortname;
191 }
192 
193 static const char *
194 sshkey_ssh_name_from_type_nid(int type, int nid)
195 {
196 	const struct sshkey_impl *impl;
197 
198 	if ((impl = sshkey_impl_from_type_nid(type, nid)) == NULL)
199 		return "ssh-unknown";
200 	return impl->name;
201 }
202 
203 int
204 sshkey_type_is_cert(int type)
205 {
206 	const struct sshkey_impl *impl;
207 
208 	if ((impl = sshkey_impl_from_type(type)) == NULL)
209 		return 0;
210 	return impl->cert;
211 }
212 
213 const char *
214 sshkey_ssh_name(const struct sshkey *k)
215 {
216 	return sshkey_ssh_name_from_type_nid(k->type, k->ecdsa_nid);
217 }
218 
219 const char *
220 sshkey_ssh_name_plain(const struct sshkey *k)
221 {
222 	return sshkey_ssh_name_from_type_nid(sshkey_type_plain(k->type),
223 	    k->ecdsa_nid);
224 }
225 
226 static int
227 type_from_name(const char *name, int allow_short)
228 {
229 	int i;
230 	const struct sshkey_impl *impl;
231 
232 	for (i = 0; keyimpls[i] != NULL; i++) {
233 		impl = keyimpls[i];
234 		if (impl->name != NULL && strcmp(name, impl->name) == 0)
235 			return impl->type;
236 		/* Only allow shortname matches for plain key types */
237 		if (allow_short && !impl->cert && impl->shortname != NULL &&
238 		    strcasecmp(impl->shortname, name) == 0)
239 			return impl->type;
240 	}
241 	return KEY_UNSPEC;
242 }
243 
244 int
245 sshkey_type_from_name(const char *name)
246 {
247 	return type_from_name(name, 0);
248 }
249 
250 int
251 sshkey_type_from_shortname(const char *name)
252 {
253 	return type_from_name(name, 1);
254 }
255 
256 static int
257 key_type_is_ecdsa_variant(int type)
258 {
259 	switch (type) {
260 	case KEY_ECDSA:
261 	case KEY_ECDSA_CERT:
262 	case KEY_ECDSA_SK:
263 	case KEY_ECDSA_SK_CERT:
264 		return 1;
265 	}
266 	return 0;
267 }
268 
269 int
270 sshkey_ecdsa_nid_from_name(const char *name)
271 {
272 	int i;
273 
274 	for (i = 0; keyimpls[i] != NULL; i++) {
275 		if (!key_type_is_ecdsa_variant(keyimpls[i]->type))
276 			continue;
277 		if (keyimpls[i]->name != NULL &&
278 		    strcmp(name, keyimpls[i]->name) == 0)
279 			return keyimpls[i]->nid;
280 	}
281 	return -1;
282 }
283 
284 int
285 sshkey_match_keyname_to_sigalgs(const char *keyname, const char *sigalgs)
286 {
287 	int ktype;
288 
289 	if (sigalgs == NULL || *sigalgs == '\0' ||
290 	    (ktype = sshkey_type_from_name(keyname)) == KEY_UNSPEC)
291 		return 0;
292 	else if (ktype == KEY_RSA) {
293 		return match_pattern_list("ssh-rsa", sigalgs, 0) == 1 ||
294 		    match_pattern_list("rsa-sha2-256", sigalgs, 0) == 1 ||
295 		    match_pattern_list("rsa-sha2-512", sigalgs, 0) == 1;
296 	} else if (ktype == KEY_RSA_CERT) {
297 		return match_pattern_list("ssh-rsa-cert-v01@openssh.com",
298 		    sigalgs, 0) == 1 ||
299 		    match_pattern_list("rsa-sha2-256-cert-v01@openssh.com",
300 		    sigalgs, 0) == 1 ||
301 		    match_pattern_list("rsa-sha2-512-cert-v01@openssh.com",
302 		    sigalgs, 0) == 1;
303 	} else
304 		return match_pattern_list(keyname, sigalgs, 0) == 1;
305 }
306 
307 char *
308 sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep)
309 {
310 	char *ret = NULL;
311 	size_t i;
312 	const struct sshkey_impl *impl;
313 	char sep_str[2] = {sep, '\0'};
314 
315 	for (i = 0; keyimpls[i] != NULL; i++) {
316 		impl = keyimpls[i];
317 		if (impl->name == NULL)
318 			continue;
319 		if (!include_sigonly && impl->sigonly)
320 			continue;
321 		if ((certs_only && !impl->cert) || (plain_only && impl->cert))
322 			continue;
323 		xextendf(&ret, sep_str, "%s", impl->name);
324 	}
325 	return ret;
326 }
327 
328 int
329 sshkey_names_valid2(const char *names, int allow_wildcard, int plain_only)
330 {
331 	char *s, *cp, *p;
332 	const struct sshkey_impl *impl;
333 	int i, type;
334 
335 	if (names == NULL || strcmp(names, "") == 0)
336 		return 0;
337 	if ((s = cp = strdup(names)) == NULL)
338 		return 0;
339 	for ((p = strsep(&cp, ",")); p && *p != '\0';
340 	    (p = strsep(&cp, ","))) {
341 		type = sshkey_type_from_name(p);
342 		if (type == KEY_UNSPEC) {
343 			if (allow_wildcard) {
344 				/*
345 				 * Try matching key types against the string.
346 				 * If any has a positive or negative match then
347 				 * the component is accepted.
348 				 */
349 				impl = NULL;
350 				for (i = 0; keyimpls[i] != NULL; i++) {
351 					if (match_pattern_list(
352 					    keyimpls[i]->name, p, 0) != 0) {
353 						impl = keyimpls[i];
354 						break;
355 					}
356 				}
357 				if (impl != NULL)
358 					continue;
359 			}
360 			free(s);
361 			return 0;
362 		} else if (plain_only && sshkey_type_is_cert(type)) {
363 			free(s);
364 			return 0;
365 		}
366 	}
367 	free(s);
368 	return 1;
369 }
370 
371 u_int
372 sshkey_size(const struct sshkey *k)
373 {
374 	const struct sshkey_impl *impl;
375 
376 	if ((impl = sshkey_impl_from_key(k)) == NULL)
377 		return 0;
378 	if (impl->funcs->size != NULL)
379 		return impl->funcs->size(k);
380 	return impl->keybits;
381 }
382 
383 static int
384 sshkey_type_is_valid_ca(int type)
385 {
386 	const struct sshkey_impl *impl;
387 
388 	if ((impl = sshkey_impl_from_type(type)) == NULL)
389 		return 0;
390 	/* All non-certificate types may act as CAs */
391 	return !impl->cert;
392 }
393 
394 int
395 sshkey_is_cert(const struct sshkey *k)
396 {
397 	if (k == NULL)
398 		return 0;
399 	return sshkey_type_is_cert(k->type);
400 }
401 
402 int
403 sshkey_is_sk(const struct sshkey *k)
404 {
405 	if (k == NULL)
406 		return 0;
407 	switch (sshkey_type_plain(k->type)) {
408 	case KEY_ECDSA_SK:
409 	case KEY_ED25519_SK:
410 		return 1;
411 	default:
412 		return 0;
413 	}
414 }
415 
416 /* Return the cert-less equivalent to a certified key type */
417 int
418 sshkey_type_plain(int type)
419 {
420 	switch (type) {
421 	case KEY_RSA_CERT:
422 		return KEY_RSA;
423 	case KEY_ECDSA_CERT:
424 		return KEY_ECDSA;
425 	case KEY_ECDSA_SK_CERT:
426 		return KEY_ECDSA_SK;
427 	case KEY_ED25519_CERT:
428 		return KEY_ED25519;
429 	case KEY_ED25519_SK_CERT:
430 		return KEY_ED25519_SK;
431 	default:
432 		return type;
433 	}
434 }
435 
436 /* Return the cert equivalent to a plain key type */
437 static int
438 sshkey_type_certified(int type)
439 {
440 	switch (type) {
441 	case KEY_RSA:
442 		return KEY_RSA_CERT;
443 	case KEY_ECDSA:
444 		return KEY_ECDSA_CERT;
445 	case KEY_ECDSA_SK:
446 		return KEY_ECDSA_SK_CERT;
447 	case KEY_ED25519:
448 		return KEY_ED25519_CERT;
449 	case KEY_ED25519_SK:
450 		return KEY_ED25519_SK_CERT;
451 	default:
452 		return -1;
453 	}
454 }
455 
456 #ifdef WITH_OPENSSL
457 static const EVP_MD *
458 ssh_digest_to_md(int hash_alg)
459 {
460 	switch (hash_alg) {
461 	case SSH_DIGEST_SHA1:
462 		return EVP_sha1();
463 	case SSH_DIGEST_SHA256:
464 		return EVP_sha256();
465 	case SSH_DIGEST_SHA384:
466 		return EVP_sha384();
467 	case SSH_DIGEST_SHA512:
468 		return EVP_sha512();
469 	}
470 	return NULL;
471 }
472 
473 int
474 sshkey_pkey_digest_sign(EVP_PKEY *pkey, int hash_alg, u_char **sigp,
475     size_t *lenp, const u_char *data, size_t datalen)
476 {
477 	EVP_MD_CTX *ctx = NULL;
478 	u_char *sig = NULL;
479 	int ret;
480 	size_t slen;
481 	const EVP_MD *evpmd;
482 
483 	*sigp = NULL;
484 	*lenp = 0;
485 
486 	slen = EVP_PKEY_size(pkey);
487 	if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM ||
488 	   (evpmd = ssh_digest_to_md(hash_alg)) == NULL)
489 		return SSH_ERR_INVALID_ARGUMENT;
490 
491 	if ((sig = malloc(slen)) == NULL)
492 		return SSH_ERR_ALLOC_FAIL;
493 
494 	if ((ctx = EVP_MD_CTX_new()) == NULL) {
495 		ret = SSH_ERR_ALLOC_FAIL;
496 		goto out;
497 	}
498 	if (EVP_DigestSignInit(ctx, NULL, evpmd, NULL, pkey) != 1 ||
499 	    EVP_DigestSign(ctx, sig, &slen, data, datalen) != 1) {
500 		ret = SSH_ERR_LIBCRYPTO_ERROR;
501 		goto out;
502 	}
503 
504 	*sigp = sig;
505 	*lenp = slen;
506 	/* Now owned by the caller */
507 	sig = NULL;
508 	ret = 0;
509 
510  out:
511 	EVP_MD_CTX_free(ctx);
512 	free(sig);
513 	return ret;
514 }
515 
516 int
517 sshkey_pkey_digest_verify(EVP_PKEY *pkey, int hash_alg, const u_char *data,
518     size_t datalen, u_char *sigbuf, size_t siglen)
519 {
520 	EVP_MD_CTX *ctx = NULL;
521 	int ret = SSH_ERR_INTERNAL_ERROR;
522 	const EVP_MD *evpmd;
523 
524 	if ((evpmd = ssh_digest_to_md(hash_alg)) == NULL)
525 		return SSH_ERR_INVALID_ARGUMENT;
526 	if ((ctx = EVP_MD_CTX_new()) == NULL)
527 		return SSH_ERR_ALLOC_FAIL;
528 	if (EVP_DigestVerifyInit(ctx, NULL, evpmd, NULL, pkey) != 1) {
529 		ret = SSH_ERR_LIBCRYPTO_ERROR;
530 		goto out;
531 	}
532 	switch (EVP_DigestVerify(ctx, sigbuf, siglen, data, datalen)) {
533 	case 1:
534 		ret = 0;
535 		break;
536 	case 0:
537 		ret = SSH_ERR_SIGNATURE_INVALID;
538 		break;
539 	default:
540 		ret = SSH_ERR_LIBCRYPTO_ERROR;
541 		break;
542 	}
543 
544  out:
545 	EVP_MD_CTX_free(ctx);
546 	return ret;
547 }
548 
549 /* XXX: these are really begging for a table-driven approach */
550 int
551 sshkey_curve_name_to_nid(const char *name)
552 {
553 	if (strcmp(name, "nistp256") == 0)
554 		return NID_X9_62_prime256v1;
555 	else if (strcmp(name, "nistp384") == 0)
556 		return NID_secp384r1;
557 # ifdef OPENSSL_HAS_NISTP521
558 	else if (strcmp(name, "nistp521") == 0)
559 		return NID_secp521r1;
560 # endif /* OPENSSL_HAS_NISTP521 */
561 	else
562 		return -1;
563 }
564 
565 u_int
566 sshkey_curve_nid_to_bits(int nid)
567 {
568 	switch (nid) {
569 	case NID_X9_62_prime256v1:
570 		return 256;
571 	case NID_secp384r1:
572 		return 384;
573 # ifdef OPENSSL_HAS_NISTP521
574 	case NID_secp521r1:
575 		return 521;
576 # endif /* OPENSSL_HAS_NISTP521 */
577 	default:
578 		return 0;
579 	}
580 }
581 
582 int
583 sshkey_ecdsa_bits_to_nid(int bits)
584 {
585 	switch (bits) {
586 	case 256:
587 		return NID_X9_62_prime256v1;
588 	case 384:
589 		return NID_secp384r1;
590 # ifdef OPENSSL_HAS_NISTP521
591 	case 521:
592 		return NID_secp521r1;
593 # endif /* OPENSSL_HAS_NISTP521 */
594 	default:
595 		return -1;
596 	}
597 }
598 
599 const char *
600 sshkey_curve_nid_to_name(int nid)
601 {
602 	switch (nid) {
603 	case NID_X9_62_prime256v1:
604 		return "nistp256";
605 	case NID_secp384r1:
606 		return "nistp384";
607 # ifdef OPENSSL_HAS_NISTP521
608 	case NID_secp521r1:
609 		return "nistp521";
610 # endif /* OPENSSL_HAS_NISTP521 */
611 	default:
612 		return NULL;
613 	}
614 }
615 
616 int
617 sshkey_ec_nid_to_hash_alg(int nid)
618 {
619 	int kbits = sshkey_curve_nid_to_bits(nid);
620 
621 	if (kbits <= 0)
622 		return -1;
623 
624 	/* RFC5656 section 6.2.1 */
625 	if (kbits <= 256)
626 		return SSH_DIGEST_SHA256;
627 	else if (kbits <= 384)
628 		return SSH_DIGEST_SHA384;
629 	else
630 		return SSH_DIGEST_SHA512;
631 }
632 #endif /* WITH_OPENSSL */
633 
634 static void
635 cert_free(struct sshkey_cert *cert)
636 {
637 	u_int i;
638 
639 	if (cert == NULL)
640 		return;
641 	sshbuf_free(cert->certblob);
642 	sshbuf_free(cert->critical);
643 	sshbuf_free(cert->extensions);
644 	free(cert->key_id);
645 	for (i = 0; i < cert->nprincipals; i++)
646 		free(cert->principals[i]);
647 	free(cert->principals);
648 	sshkey_free(cert->signature_key);
649 	free(cert->signature_type);
650 	freezero(cert, sizeof(*cert));
651 }
652 
653 static struct sshkey_cert *
654 cert_new(void)
655 {
656 	struct sshkey_cert *cert;
657 
658 	if ((cert = calloc(1, sizeof(*cert))) == NULL)
659 		return NULL;
660 	if ((cert->certblob = sshbuf_new()) == NULL ||
661 	    (cert->critical = sshbuf_new()) == NULL ||
662 	    (cert->extensions = sshbuf_new()) == NULL) {
663 		cert_free(cert);
664 		return NULL;
665 	}
666 	cert->key_id = NULL;
667 	cert->principals = NULL;
668 	cert->signature_key = NULL;
669 	cert->signature_type = NULL;
670 	return cert;
671 }
672 
673 struct sshkey *
674 sshkey_new(int type)
675 {
676 	struct sshkey *k;
677 	const struct sshkey_impl *impl = NULL;
678 
679 	if (type != KEY_UNSPEC &&
680 	    (impl = sshkey_impl_from_type(type)) == NULL)
681 		return NULL;
682 
683 	/* All non-certificate types may act as CAs */
684 	if ((k = calloc(1, sizeof(*k))) == NULL)
685 		return NULL;
686 	k->type = type;
687 	k->ecdsa_nid = -1;
688 	if (impl != NULL && impl->funcs->alloc != NULL) {
689 		if (impl->funcs->alloc(k) != 0) {
690 			free(k);
691 			return NULL;
692 		}
693 	}
694 	if (sshkey_is_cert(k)) {
695 		if ((k->cert = cert_new()) == NULL) {
696 			sshkey_free(k);
697 			return NULL;
698 		}
699 	}
700 
701 	return k;
702 }
703 
704 /* Frees common FIDO fields */
705 void
706 sshkey_sk_cleanup(struct sshkey *k)
707 {
708 	free(k->sk_application);
709 	sshbuf_free(k->sk_key_handle);
710 	sshbuf_free(k->sk_reserved);
711 	k->sk_application = NULL;
712 	k->sk_key_handle = k->sk_reserved = NULL;
713 }
714 
715 #if defined(MAP_CONCEAL)
716 # define PREKEY_MMAP_FLAG	MAP_CONCEAL
717 #elif defined(MAP_NOCORE)
718 # define PREKEY_MMAP_FLAG	MAP_NOCORE
719 #else
720 # define PREKEY_MMAP_FLAG	0
721 #endif
722 
723 static int
724 sshkey_prekey_alloc(u_char **prekeyp, size_t len)
725 {
726 #if defined(HAVE_MMAP) && defined(MAP_ANON) && defined(MAP_PRIVATE)
727 	u_char *prekey;
728 
729 	*prekeyp = NULL;
730 	if ((prekey = mmap(NULL, len, PROT_READ|PROT_WRITE,
731 	    MAP_ANON|MAP_PRIVATE|PREKEY_MMAP_FLAG, -1, 0)) == MAP_FAILED)
732 		return SSH_ERR_SYSTEM_ERROR;
733 #if defined(MADV_DONTDUMP) && !defined(MAP_CONCEAL) && !defined(MAP_NOCORE)
734 	(void)madvise(prekey, len, MADV_DONTDUMP);
735 #endif
736 	*prekeyp = prekey;
737 #else
738 	*prekeyp = calloc(1, len);
739 #endif /* HAVE_MMAP et al */
740 	return 0;
741 }
742 
743 static void
744 sshkey_prekey_free(void *prekey, size_t len)
745 {
746 #if defined(HAVE_MMAP) && defined(MAP_ANON) && defined(MAP_PRIVATE)
747 	if (prekey == NULL)
748 		return;
749 	munmap(prekey, len);
750 #else
751 	free(prekey);
752 #endif /* HAVE_MMAP et al */
753 }
754 
755 static void
756 sshkey_free_contents(struct sshkey *k)
757 {
758 	const struct sshkey_impl *impl;
759 
760 	if (k == NULL)
761 		return;
762 	if ((k->flags & SSHKEY_FLAG_EXT) != 0)
763 		pkcs11_key_free(k);
764 	if ((impl = sshkey_impl_from_type(k->type)) != NULL &&
765 	    impl->funcs->cleanup != NULL)
766 		impl->funcs->cleanup(k);
767 	if (sshkey_is_cert(k))
768 		cert_free(k->cert);
769 	freezero(k->shielded_private, k->shielded_len);
770 	sshkey_prekey_free(k->shield_prekey, k->shield_prekey_len);
771 }
772 
773 void
774 sshkey_free(struct sshkey *k)
775 {
776 	sshkey_free_contents(k);
777 	freezero(k, sizeof(*k));
778 }
779 
780 static int
781 cert_compare(struct sshkey_cert *a, struct sshkey_cert *b)
782 {
783 	if (a == NULL && b == NULL)
784 		return 1;
785 	if (a == NULL || b == NULL)
786 		return 0;
787 	if (sshbuf_len(a->certblob) != sshbuf_len(b->certblob))
788 		return 0;
789 	if (timingsafe_bcmp(sshbuf_ptr(a->certblob), sshbuf_ptr(b->certblob),
790 	    sshbuf_len(a->certblob)) != 0)
791 		return 0;
792 	return 1;
793 }
794 
795 /* Compares FIDO-specific pubkey fields only */
796 int
797 sshkey_sk_fields_equal(const struct sshkey *a, const struct sshkey *b)
798 {
799 	if (a->sk_application == NULL || b->sk_application == NULL)
800 		return 0;
801 	if (strcmp(a->sk_application, b->sk_application) != 0)
802 		return 0;
803 	return 1;
804 }
805 
806 /*
807  * Compare public portions of key only, allowing comparisons between
808  * certificates and plain keys too.
809  */
810 int
811 sshkey_equal_public(const struct sshkey *a, const struct sshkey *b)
812 {
813 	const struct sshkey_impl *impl;
814 
815 	if (a == NULL || b == NULL ||
816 	    sshkey_type_plain(a->type) != sshkey_type_plain(b->type))
817 		return 0;
818 	if ((impl = sshkey_impl_from_type(a->type)) == NULL)
819 		return 0;
820 	return impl->funcs->equal(a, b);
821 }
822 
823 int
824 sshkey_equal(const struct sshkey *a, const struct sshkey *b)
825 {
826 	if (a == NULL || b == NULL || a->type != b->type)
827 		return 0;
828 	if (sshkey_is_cert(a)) {
829 		if (!cert_compare(a->cert, b->cert))
830 			return 0;
831 	}
832 	return sshkey_equal_public(a, b);
833 }
834 
835 
836 /* Serialise common FIDO key parts */
837 int
838 sshkey_serialize_sk(const struct sshkey *key, struct sshbuf *b)
839 {
840 	int r;
841 
842 	if ((r = sshbuf_put_cstring(b, key->sk_application)) != 0)
843 		return r;
844 
845 	return 0;
846 }
847 
848 static int
849 to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain,
850   enum sshkey_serialize_rep opts)
851 {
852 	int type, ret = SSH_ERR_INTERNAL_ERROR;
853 	const char *typename;
854 	const struct sshkey_impl *impl;
855 
856 	if (key == NULL)
857 		return SSH_ERR_INVALID_ARGUMENT;
858 
859 	type = force_plain ? sshkey_type_plain(key->type) : key->type;
860 
861 	if (sshkey_type_is_cert(type)) {
862 		if (key->cert == NULL)
863 			return SSH_ERR_EXPECTED_CERT;
864 		if (sshbuf_len(key->cert->certblob) == 0)
865 			return SSH_ERR_KEY_LACKS_CERTBLOB;
866 		/* Use the existing blob */
867 		if ((ret = sshbuf_putb(b, key->cert->certblob)) != 0)
868 			return ret;
869 		return 0;
870 	}
871 	if ((impl = sshkey_impl_from_type(type)) == NULL)
872 		return SSH_ERR_KEY_TYPE_UNKNOWN;
873 
874 	typename = sshkey_ssh_name_from_type_nid(type, key->ecdsa_nid);
875 	if ((ret = sshbuf_put_cstring(b, typename)) != 0)
876 		return ret;
877 	return impl->funcs->serialize_public(key, b, opts);
878 }
879 
880 int
881 sshkey_putb(const struct sshkey *key, struct sshbuf *b)
882 {
883 	return to_blob_buf(key, b, 0, SSHKEY_SERIALIZE_DEFAULT);
884 }
885 
886 static int
887 sshkey_puts_opts_internal(const struct sshkey *key, struct sshbuf *b,
888     enum sshkey_serialize_rep opts, int force_plain)
889 {
890 	struct sshbuf *tmp;
891 	int r;
892 
893 	if ((tmp = sshbuf_new()) == NULL)
894 		return SSH_ERR_ALLOC_FAIL;
895 	r = to_blob_buf(key, tmp, force_plain, opts);
896 	if (r == 0)
897 		r = sshbuf_put_stringb(b, tmp);
898 	sshbuf_free(tmp);
899 	return r;
900 }
901 
902 int
903 sshkey_puts(const struct sshkey *key, struct sshbuf *b)
904 {
905 	return sshkey_puts_opts_internal(key, b, SSHKEY_SERIALIZE_DEFAULT, 0);
906 }
907 
908 int
909 sshkey_putb_plain(const struct sshkey *key, struct sshbuf *b)
910 {
911 	return to_blob_buf(key, b, 1, SSHKEY_SERIALIZE_DEFAULT);
912 }
913 
914 int
915 sshkey_puts_plain(const struct sshkey *key, struct sshbuf *b)
916 {
917 	return sshkey_puts_opts_internal(key, b, SSHKEY_SERIALIZE_DEFAULT, 1);
918 }
919 
920 static int
921 to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp, int force_plain,
922     enum sshkey_serialize_rep opts)
923 {
924 	int ret = SSH_ERR_INTERNAL_ERROR;
925 	size_t len;
926 	struct sshbuf *b = NULL;
927 
928 	if (lenp != NULL)
929 		*lenp = 0;
930 	if (blobp != NULL)
931 		*blobp = NULL;
932 	if ((b = sshbuf_new()) == NULL)
933 		return SSH_ERR_ALLOC_FAIL;
934 	if ((ret = to_blob_buf(key, b, force_plain, opts)) != 0)
935 		goto out;
936 	len = sshbuf_len(b);
937 	if (lenp != NULL)
938 		*lenp = len;
939 	if (blobp != NULL) {
940 		if ((*blobp = malloc(len)) == NULL) {
941 			ret = SSH_ERR_ALLOC_FAIL;
942 			goto out;
943 		}
944 		memcpy(*blobp, sshbuf_ptr(b), len);
945 	}
946 	ret = 0;
947  out:
948 	sshbuf_free(b);
949 	return ret;
950 }
951 
952 int
953 sshkey_to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp)
954 {
955 	return to_blob(key, blobp, lenp, 0, SSHKEY_SERIALIZE_DEFAULT);
956 }
957 
958 int
959 sshkey_plain_to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp)
960 {
961 	return to_blob(key, blobp, lenp, 1, SSHKEY_SERIALIZE_DEFAULT);
962 }
963 
964 int
965 sshkey_fingerprint_raw(const struct sshkey *k, int dgst_alg,
966     u_char **retp, size_t *lenp)
967 {
968 	u_char *blob = NULL, *ret = NULL;
969 	size_t blob_len = 0;
970 	int r = SSH_ERR_INTERNAL_ERROR;
971 
972 	if (retp != NULL)
973 		*retp = NULL;
974 	if (lenp != NULL)
975 		*lenp = 0;
976 	if (ssh_digest_bytes(dgst_alg) == 0) {
977 		r = SSH_ERR_INVALID_ARGUMENT;
978 		goto out;
979 	}
980 	if ((r = to_blob(k, &blob, &blob_len, 1, SSHKEY_SERIALIZE_DEFAULT))
981 	    != 0)
982 		goto out;
983 	if ((ret = calloc(1, SSH_DIGEST_MAX_LENGTH)) == NULL) {
984 		r = SSH_ERR_ALLOC_FAIL;
985 		goto out;
986 	}
987 	if ((r = ssh_digest_memory(dgst_alg, blob, blob_len,
988 	    ret, SSH_DIGEST_MAX_LENGTH)) != 0)
989 		goto out;
990 	/* success */
991 	if (retp != NULL) {
992 		*retp = ret;
993 		ret = NULL;
994 	}
995 	if (lenp != NULL)
996 		*lenp = ssh_digest_bytes(dgst_alg);
997 	r = 0;
998  out:
999 	free(ret);
1000 	if (blob != NULL)
1001 		freezero(blob, blob_len);
1002 	return r;
1003 }
1004 
1005 static char *
1006 fingerprint_b64(const char *alg, u_char *dgst_raw, size_t dgst_raw_len)
1007 {
1008 	char *ret;
1009 	size_t plen = strlen(alg) + 1;
1010 	size_t rlen = ((dgst_raw_len + 2) / 3) * 4 + plen + 1;
1011 
1012 	if (dgst_raw_len > 65536 || (ret = calloc(1, rlen)) == NULL)
1013 		return NULL;
1014 	strlcpy(ret, alg, rlen);
1015 	strlcat(ret, ":", rlen);
1016 	if (dgst_raw_len == 0)
1017 		return ret;
1018 	if (b64_ntop(dgst_raw, dgst_raw_len, ret + plen, rlen - plen) == -1) {
1019 		freezero(ret, rlen);
1020 		return NULL;
1021 	}
1022 	/* Trim padding characters from end */
1023 	ret[strcspn(ret, "=")] = '\0';
1024 	return ret;
1025 }
1026 
1027 static char *
1028 fingerprint_hex(const char *alg, u_char *dgst_raw, size_t dgst_raw_len)
1029 {
1030 	char *retval, hex[5];
1031 	size_t i, rlen = dgst_raw_len * 3 + strlen(alg) + 2;
1032 
1033 	if (dgst_raw_len > 65536 || (retval = calloc(1, rlen)) == NULL)
1034 		return NULL;
1035 	strlcpy(retval, alg, rlen);
1036 	strlcat(retval, ":", rlen);
1037 	for (i = 0; i < dgst_raw_len; i++) {
1038 		snprintf(hex, sizeof(hex), "%s%02x",
1039 		    i > 0 ? ":" : "", dgst_raw[i]);
1040 		strlcat(retval, hex, rlen);
1041 	}
1042 	return retval;
1043 }
1044 
1045 static char *
1046 fingerprint_bubblebabble(u_char *dgst_raw, size_t dgst_raw_len)
1047 {
1048 	char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' };
1049 	char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm',
1050 	    'n', 'p', 'r', 's', 't', 'v', 'z', 'x' };
1051 	u_int i, j = 0, rounds, seed = 1;
1052 	char *retval;
1053 
1054 	rounds = (dgst_raw_len / 2) + 1;
1055 	if ((retval = calloc(rounds, 6)) == NULL)
1056 		return NULL;
1057 	retval[j++] = 'x';
1058 	for (i = 0; i < rounds; i++) {
1059 		u_int idx0, idx1, idx2, idx3, idx4;
1060 		if ((i + 1 < rounds) || (dgst_raw_len % 2 != 0)) {
1061 			idx0 = (((((u_int)(dgst_raw[2 * i])) >> 6) & 3) +
1062 			    seed) % 6;
1063 			idx1 = (((u_int)(dgst_raw[2 * i])) >> 2) & 15;
1064 			idx2 = ((((u_int)(dgst_raw[2 * i])) & 3) +
1065 			    (seed / 6)) % 6;
1066 			retval[j++] = vowels[idx0];
1067 			retval[j++] = consonants[idx1];
1068 			retval[j++] = vowels[idx2];
1069 			if ((i + 1) < rounds) {
1070 				idx3 = (((u_int)(dgst_raw[(2 * i) + 1])) >> 4) & 15;
1071 				idx4 = (((u_int)(dgst_raw[(2 * i) + 1]))) & 15;
1072 				retval[j++] = consonants[idx3];
1073 				retval[j++] = '-';
1074 				retval[j++] = consonants[idx4];
1075 				seed = ((seed * 5) +
1076 				    ((((u_int)(dgst_raw[2 * i])) * 7) +
1077 				    ((u_int)(dgst_raw[(2 * i) + 1])))) % 36;
1078 			}
1079 		} else {
1080 			idx0 = seed % 6;
1081 			idx1 = 16;
1082 			idx2 = seed / 6;
1083 			retval[j++] = vowels[idx0];
1084 			retval[j++] = consonants[idx1];
1085 			retval[j++] = vowels[idx2];
1086 		}
1087 	}
1088 	retval[j++] = 'x';
1089 	retval[j++] = '\0';
1090 	return retval;
1091 }
1092 
1093 /*
1094  * Draw an ASCII-Art representing the fingerprint so human brain can
1095  * profit from its built-in pattern recognition ability.
1096  * This technique is called "random art" and can be found in some
1097  * scientific publications like this original paper:
1098  *
1099  * "Hash Visualization: a New Technique to improve Real-World Security",
1100  * Perrig A. and Song D., 1999, International Workshop on Cryptographic
1101  * Techniques and E-Commerce (CrypTEC '99)
1102  * sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf
1103  *
1104  * The subject came up in a talk by Dan Kaminsky, too.
1105  *
1106  * If you see the picture is different, the key is different.
1107  * If the picture looks the same, you still know nothing.
1108  *
1109  * The algorithm used here is a worm crawling over a discrete plane,
1110  * leaving a trace (augmenting the field) everywhere it goes.
1111  * Movement is taken from dgst_raw 2bit-wise.  Bumping into walls
1112  * makes the respective movement vector be ignored for this turn.
1113  * Graphs are not unambiguous, because circles in graphs can be
1114  * walked in either direction.
1115  */
1116 
1117 /*
1118  * Field sizes for the random art.  Have to be odd, so the starting point
1119  * can be in the exact middle of the picture, and FLDBASE should be >=8 .
1120  * Else pictures would be too dense, and drawing the frame would
1121  * fail, too, because the key type would not fit in anymore.
1122  */
1123 #define	FLDBASE		8
1124 #define	FLDSIZE_Y	(FLDBASE + 1)
1125 #define	FLDSIZE_X	(FLDBASE * 2 + 1)
1126 static char *
1127 fingerprint_randomart(const char *alg, u_char *dgst_raw, size_t dgst_raw_len,
1128     const struct sshkey *k)
1129 {
1130 	/*
1131 	 * Chars to be used after each other every time the worm
1132 	 * intersects with itself.  Matter of taste.
1133 	 */
1134 	char	*augmentation_string = " .o+=*BOX@%&#/^SE";
1135 	char	*retval, *p, title[FLDSIZE_X], hash[FLDSIZE_X];
1136 	u_char	 field[FLDSIZE_X][FLDSIZE_Y];
1137 	size_t	 i, tlen, hlen;
1138 	u_int	 b;
1139 	int	 x, y, r;
1140 	size_t	 len = strlen(augmentation_string) - 1;
1141 
1142 	if ((retval = calloc((FLDSIZE_X + 3), (FLDSIZE_Y + 2))) == NULL)
1143 		return NULL;
1144 
1145 	/* initialize field */
1146 	memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char));
1147 	x = FLDSIZE_X / 2;
1148 	y = FLDSIZE_Y / 2;
1149 
1150 	/* process raw key */
1151 	for (i = 0; i < dgst_raw_len; i++) {
1152 		int input;
1153 		/* each byte conveys four 2-bit move commands */
1154 		input = dgst_raw[i];
1155 		for (b = 0; b < 4; b++) {
1156 			/* evaluate 2 bit, rest is shifted later */
1157 			x += (input & 0x1) ? 1 : -1;
1158 			y += (input & 0x2) ? 1 : -1;
1159 
1160 			/* assure we are still in bounds */
1161 			x = MAXIMUM(x, 0);
1162 			y = MAXIMUM(y, 0);
1163 			x = MINIMUM(x, FLDSIZE_X - 1);
1164 			y = MINIMUM(y, FLDSIZE_Y - 1);
1165 
1166 			/* augment the field */
1167 			if (field[x][y] < len - 2)
1168 				field[x][y]++;
1169 			input = input >> 2;
1170 		}
1171 	}
1172 
1173 	/* mark starting point and end point*/
1174 	field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1;
1175 	field[x][y] = len;
1176 
1177 	/* assemble title */
1178 	r = snprintf(title, sizeof(title), "[%s %u]",
1179 		sshkey_type(k), sshkey_size(k));
1180 	/* If [type size] won't fit, then try [type]; fits "[ED25519-CERT]" */
1181 	if (r < 0 || r > (int)sizeof(title))
1182 		r = snprintf(title, sizeof(title), "[%s]", sshkey_type(k));
1183 	tlen = (r <= 0) ? 0 : strlen(title);
1184 
1185 	/* assemble hash ID. */
1186 	r = snprintf(hash, sizeof(hash), "[%s]", alg);
1187 	hlen = (r <= 0) ? 0 : strlen(hash);
1188 
1189 	/* output upper border */
1190 	p = retval;
1191 	*p++ = '+';
1192 	for (i = 0; i < (FLDSIZE_X - tlen) / 2; i++)
1193 		*p++ = '-';
1194 	memcpy(p, title, tlen);
1195 	p += tlen;
1196 	for (i += tlen; i < FLDSIZE_X; i++)
1197 		*p++ = '-';
1198 	*p++ = '+';
1199 	*p++ = '\n';
1200 
1201 	/* output content */
1202 	for (y = 0; y < FLDSIZE_Y; y++) {
1203 		*p++ = '|';
1204 		for (x = 0; x < FLDSIZE_X; x++)
1205 			*p++ = augmentation_string[MINIMUM(field[x][y], len)];
1206 		*p++ = '|';
1207 		*p++ = '\n';
1208 	}
1209 
1210 	/* output lower border */
1211 	*p++ = '+';
1212 	for (i = 0; i < (FLDSIZE_X - hlen) / 2; i++)
1213 		*p++ = '-';
1214 	memcpy(p, hash, hlen);
1215 	p += hlen;
1216 	for (i += hlen; i < FLDSIZE_X; i++)
1217 		*p++ = '-';
1218 	*p++ = '+';
1219 
1220 	return retval;
1221 }
1222 
1223 char *
1224 sshkey_fingerprint(const struct sshkey *k, int dgst_alg,
1225     enum sshkey_fp_rep dgst_rep)
1226 {
1227 	char *retval = NULL;
1228 	u_char *dgst_raw;
1229 	size_t dgst_raw_len;
1230 
1231 	if (sshkey_fingerprint_raw(k, dgst_alg, &dgst_raw, &dgst_raw_len) != 0)
1232 		return NULL;
1233 	switch (dgst_rep) {
1234 	case SSH_FP_DEFAULT:
1235 		if (dgst_alg == SSH_DIGEST_MD5) {
1236 			retval = fingerprint_hex(ssh_digest_alg_name(dgst_alg),
1237 			    dgst_raw, dgst_raw_len);
1238 		} else {
1239 			retval = fingerprint_b64(ssh_digest_alg_name(dgst_alg),
1240 			    dgst_raw, dgst_raw_len);
1241 		}
1242 		break;
1243 	case SSH_FP_HEX:
1244 		retval = fingerprint_hex(ssh_digest_alg_name(dgst_alg),
1245 		    dgst_raw, dgst_raw_len);
1246 		break;
1247 	case SSH_FP_BASE64:
1248 		retval = fingerprint_b64(ssh_digest_alg_name(dgst_alg),
1249 		    dgst_raw, dgst_raw_len);
1250 		break;
1251 	case SSH_FP_BUBBLEBABBLE:
1252 		retval = fingerprint_bubblebabble(dgst_raw, dgst_raw_len);
1253 		break;
1254 	case SSH_FP_RANDOMART:
1255 		retval = fingerprint_randomart(ssh_digest_alg_name(dgst_alg),
1256 		    dgst_raw, dgst_raw_len, k);
1257 		break;
1258 	default:
1259 		freezero(dgst_raw, dgst_raw_len);
1260 		return NULL;
1261 	}
1262 	freezero(dgst_raw, dgst_raw_len);
1263 	return retval;
1264 }
1265 
1266 static int
1267 peek_type_nid(const char *s, size_t l, int *nid)
1268 {
1269 	const struct sshkey_impl *impl;
1270 	int i;
1271 
1272 	for (i = 0; keyimpls[i] != NULL; i++) {
1273 		impl = keyimpls[i];
1274 		if (impl->name == NULL || strlen(impl->name) != l)
1275 			continue;
1276 		if (memcmp(s, impl->name, l) == 0) {
1277 			*nid = -1;
1278 			if (key_type_is_ecdsa_variant(impl->type))
1279 				*nid = impl->nid;
1280 			return impl->type;
1281 		}
1282 	}
1283 	return KEY_UNSPEC;
1284 }
1285 
1286 /* XXX this can now be made const char * */
1287 int
1288 sshkey_read(struct sshkey *ret, char **cpp)
1289 {
1290 	struct sshkey *k;
1291 	char *cp, *blobcopy;
1292 	size_t space;
1293 	int r, type, curve_nid = -1;
1294 	struct sshbuf *blob;
1295 
1296 	if (ret == NULL)
1297 		return SSH_ERR_INVALID_ARGUMENT;
1298 	if (ret->type != KEY_UNSPEC && sshkey_impl_from_type(ret->type) == NULL)
1299 		return SSH_ERR_INVALID_ARGUMENT;
1300 
1301 	/* Decode type */
1302 	cp = *cpp;
1303 	space = strcspn(cp, " \t");
1304 	if (space == strlen(cp))
1305 		return SSH_ERR_INVALID_FORMAT;
1306 	if ((type = peek_type_nid(cp, space, &curve_nid)) == KEY_UNSPEC)
1307 		return SSH_ERR_INVALID_FORMAT;
1308 
1309 	/* skip whitespace */
1310 	for (cp += space; *cp == ' ' || *cp == '\t'; cp++)
1311 		;
1312 	if (*cp == '\0')
1313 		return SSH_ERR_INVALID_FORMAT;
1314 	if (ret->type != KEY_UNSPEC && ret->type != type)
1315 		return SSH_ERR_KEY_TYPE_MISMATCH;
1316 	if ((blob = sshbuf_new()) == NULL)
1317 		return SSH_ERR_ALLOC_FAIL;
1318 
1319 	/* find end of keyblob and decode */
1320 	space = strcspn(cp, " \t");
1321 	if ((blobcopy = strndup(cp, space)) == NULL) {
1322 		sshbuf_free(blob);
1323 		return SSH_ERR_ALLOC_FAIL;
1324 	}
1325 	if ((r = sshbuf_b64tod(blob, blobcopy)) != 0) {
1326 		free(blobcopy);
1327 		sshbuf_free(blob);
1328 		return r;
1329 	}
1330 	free(blobcopy);
1331 	if ((r = sshkey_fromb(blob, &k)) != 0) {
1332 		sshbuf_free(blob);
1333 		return r;
1334 	}
1335 	sshbuf_free(blob);
1336 
1337 	/* skip whitespace and leave cp at start of comment */
1338 	for (cp += space; *cp == ' ' || *cp == '\t'; cp++)
1339 		;
1340 
1341 	/* ensure type of blob matches type at start of line */
1342 	if (k->type != type) {
1343 		sshkey_free(k);
1344 		return SSH_ERR_KEY_TYPE_MISMATCH;
1345 	}
1346 	if (key_type_is_ecdsa_variant(type) && curve_nid != k->ecdsa_nid) {
1347 		sshkey_free(k);
1348 		return SSH_ERR_EC_CURVE_MISMATCH;
1349 	}
1350 
1351 	/* Fill in ret from parsed key */
1352 	sshkey_free_contents(ret);
1353 	*ret = *k;
1354 	freezero(k, sizeof(*k));
1355 
1356 	/* success */
1357 	*cpp = cp;
1358 	return 0;
1359 }
1360 
1361 int
1362 sshkey_to_base64(const struct sshkey *key, char **b64p)
1363 {
1364 	int r = SSH_ERR_INTERNAL_ERROR;
1365 	struct sshbuf *b = NULL;
1366 	char *uu = NULL;
1367 
1368 	if (b64p != NULL)
1369 		*b64p = NULL;
1370 	if ((b = sshbuf_new()) == NULL)
1371 		return SSH_ERR_ALLOC_FAIL;
1372 	if ((r = sshkey_putb(key, b)) != 0)
1373 		goto out;
1374 	if ((uu = sshbuf_dtob64_string(b, 0)) == NULL) {
1375 		r = SSH_ERR_ALLOC_FAIL;
1376 		goto out;
1377 	}
1378 	/* Success */
1379 	if (b64p != NULL) {
1380 		*b64p = uu;
1381 		uu = NULL;
1382 	}
1383 	r = 0;
1384  out:
1385 	sshbuf_free(b);
1386 	free(uu);
1387 	return r;
1388 }
1389 
1390 int
1391 sshkey_format_text(const struct sshkey *key, struct sshbuf *b)
1392 {
1393 	int r = SSH_ERR_INTERNAL_ERROR;
1394 	char *uu = NULL;
1395 
1396 	if ((r = sshkey_to_base64(key, &uu)) != 0)
1397 		goto out;
1398 	if ((r = sshbuf_putf(b, "%s %s",
1399 	    sshkey_ssh_name(key), uu)) != 0)
1400 		goto out;
1401 	r = 0;
1402  out:
1403 	free(uu);
1404 	return r;
1405 }
1406 
1407 int
1408 sshkey_write(const struct sshkey *key, FILE *f)
1409 {
1410 	struct sshbuf *b = NULL;
1411 	int r = SSH_ERR_INTERNAL_ERROR;
1412 
1413 	if ((b = sshbuf_new()) == NULL)
1414 		return SSH_ERR_ALLOC_FAIL;
1415 	if ((r = sshkey_format_text(key, b)) != 0)
1416 		goto out;
1417 	if (fwrite(sshbuf_ptr(b), sshbuf_len(b), 1, f) != 1) {
1418 		if (feof(f))
1419 			errno = EPIPE;
1420 		r = SSH_ERR_SYSTEM_ERROR;
1421 		goto out;
1422 	}
1423 	/* Success */
1424 	r = 0;
1425  out:
1426 	sshbuf_free(b);
1427 	return r;
1428 }
1429 
1430 const char *
1431 sshkey_cert_type(const struct sshkey *k)
1432 {
1433 	switch (k->cert->type) {
1434 	case SSH2_CERT_TYPE_USER:
1435 		return "user";
1436 	case SSH2_CERT_TYPE_HOST:
1437 		return "host";
1438 	default:
1439 		return "unknown";
1440 	}
1441 }
1442 
1443 int
1444 sshkey_check_rsa_length(const struct sshkey *k, int min_size)
1445 {
1446 #ifdef WITH_OPENSSL
1447 	int nbits;
1448 
1449 	if (k == NULL || k->pkey == NULL ||
1450 	    (k->type != KEY_RSA && k->type != KEY_RSA_CERT))
1451 		return 0;
1452 	nbits = EVP_PKEY_bits(k->pkey);
1453 	if (nbits < SSH_RSA_MINIMUM_MODULUS_SIZE ||
1454 	    (min_size > 0 && nbits < min_size))
1455 		return SSH_ERR_KEY_LENGTH;
1456 #endif /* WITH_OPENSSL */
1457 	return 0;
1458 }
1459 
1460 #if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
1461 int
1462 sshkey_ecdsa_key_to_nid(const EC_KEY *k)
1463 {
1464 	const EC_GROUP *g;
1465 	int nid;
1466 
1467 	if (k == NULL || (g = EC_KEY_get0_group(k)) == NULL)
1468 		return -1;
1469 	if ((nid = EC_GROUP_get_curve_name(g)) <= 0)
1470 		return -1;
1471 	return nid;
1472 }
1473 
1474 int
1475 sshkey_ecdsa_pkey_to_nid(EVP_PKEY *pkey)
1476 {
1477 	return sshkey_ecdsa_key_to_nid(EVP_PKEY_get0_EC_KEY(pkey));
1478 }
1479 #endif /* defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) */
1480 
1481 int
1482 sshkey_generate(int type, u_int bits, struct sshkey **keyp)
1483 {
1484 	struct sshkey *k;
1485 	int ret = SSH_ERR_INTERNAL_ERROR;
1486 	const struct sshkey_impl *impl;
1487 
1488 	if (keyp == NULL || sshkey_type_is_cert(type))
1489 		return SSH_ERR_INVALID_ARGUMENT;
1490 	*keyp = NULL;
1491 	if ((impl = sshkey_impl_from_type(type)) == NULL)
1492 		return SSH_ERR_KEY_TYPE_UNKNOWN;
1493 	if (impl->funcs->generate == NULL)
1494 		return SSH_ERR_FEATURE_UNSUPPORTED;
1495 	if ((k = sshkey_new(KEY_UNSPEC)) == NULL)
1496 		return SSH_ERR_ALLOC_FAIL;
1497 	k->type = type;
1498 	if ((ret = impl->funcs->generate(k, bits)) != 0) {
1499 		sshkey_free(k);
1500 		return ret;
1501 	}
1502 	/* success */
1503 	*keyp = k;
1504 	return 0;
1505 }
1506 
1507 int
1508 sshkey_cert_copy(const struct sshkey *from_key, struct sshkey *to_key)
1509 {
1510 	u_int i;
1511 	const struct sshkey_cert *from;
1512 	struct sshkey_cert *to;
1513 	int r = SSH_ERR_INTERNAL_ERROR;
1514 
1515 	if (to_key == NULL || (from = from_key->cert) == NULL)
1516 		return SSH_ERR_INVALID_ARGUMENT;
1517 
1518 	if ((to = cert_new()) == NULL)
1519 		return SSH_ERR_ALLOC_FAIL;
1520 
1521 	if ((r = sshbuf_putb(to->certblob, from->certblob)) != 0 ||
1522 	    (r = sshbuf_putb(to->critical, from->critical)) != 0 ||
1523 	    (r = sshbuf_putb(to->extensions, from->extensions)) != 0)
1524 		goto out;
1525 
1526 	to->serial = from->serial;
1527 	to->type = from->type;
1528 	if (from->key_id == NULL)
1529 		to->key_id = NULL;
1530 	else if ((to->key_id = strdup(from->key_id)) == NULL) {
1531 		r = SSH_ERR_ALLOC_FAIL;
1532 		goto out;
1533 	}
1534 	to->valid_after = from->valid_after;
1535 	to->valid_before = from->valid_before;
1536 	if (from->signature_key == NULL)
1537 		to->signature_key = NULL;
1538 	else if ((r = sshkey_from_private(from->signature_key,
1539 	    &to->signature_key)) != 0)
1540 		goto out;
1541 	if (from->signature_type != NULL &&
1542 	    (to->signature_type = strdup(from->signature_type)) == NULL) {
1543 		r = SSH_ERR_ALLOC_FAIL;
1544 		goto out;
1545 	}
1546 	if (from->nprincipals > SSHKEY_CERT_MAX_PRINCIPALS) {
1547 		r = SSH_ERR_INVALID_ARGUMENT;
1548 		goto out;
1549 	}
1550 	if (from->nprincipals > 0) {
1551 		if ((to->principals = calloc(from->nprincipals,
1552 		    sizeof(*to->principals))) == NULL) {
1553 			r = SSH_ERR_ALLOC_FAIL;
1554 			goto out;
1555 		}
1556 		for (i = 0; i < from->nprincipals; i++) {
1557 			to->principals[i] = strdup(from->principals[i]);
1558 			if (to->principals[i] == NULL) {
1559 				to->nprincipals = i;
1560 				r = SSH_ERR_ALLOC_FAIL;
1561 				goto out;
1562 			}
1563 		}
1564 	}
1565 	to->nprincipals = from->nprincipals;
1566 
1567 	/* success */
1568 	cert_free(to_key->cert);
1569 	to_key->cert = to;
1570 	to = NULL;
1571 	r = 0;
1572  out:
1573 	cert_free(to);
1574 	return r;
1575 }
1576 
1577 int
1578 sshkey_copy_public_sk(const struct sshkey *from, struct sshkey *to)
1579 {
1580 	/* Append security-key application string */
1581 	if ((to->sk_application = strdup(from->sk_application)) == NULL)
1582 		return SSH_ERR_ALLOC_FAIL;
1583 	return 0;
1584 }
1585 
1586 int
1587 sshkey_from_private(const struct sshkey *k, struct sshkey **pkp)
1588 {
1589 	struct sshkey *n = NULL;
1590 	int r = SSH_ERR_INTERNAL_ERROR;
1591 	const struct sshkey_impl *impl;
1592 
1593 	*pkp = NULL;
1594 	if ((impl = sshkey_impl_from_key(k)) == NULL)
1595 		return SSH_ERR_KEY_TYPE_UNKNOWN;
1596 	if ((n = sshkey_new(k->type)) == NULL) {
1597 		r = SSH_ERR_ALLOC_FAIL;
1598 		goto out;
1599 	}
1600 	if ((r = impl->funcs->copy_public(k, n)) != 0)
1601 		goto out;
1602 	if (sshkey_is_cert(k) && (r = sshkey_cert_copy(k, n)) != 0)
1603 		goto out;
1604 	/* success */
1605 	*pkp = n;
1606 	n = NULL;
1607 	r = 0;
1608  out:
1609 	sshkey_free(n);
1610 	return r;
1611 }
1612 
1613 int
1614 sshkey_is_shielded(struct sshkey *k)
1615 {
1616 	return k != NULL && k->shielded_private != NULL;
1617 }
1618 
1619 int
1620 sshkey_shield_private(struct sshkey *k)
1621 {
1622 	struct sshbuf *prvbuf = NULL;
1623 	u_char *prekey = NULL, *enc = NULL, keyiv[SSH_DIGEST_MAX_LENGTH];
1624 	struct sshcipher_ctx *cctx = NULL;
1625 	const struct sshcipher *cipher;
1626 	size_t i, enclen = 0;
1627 	struct sshkey *kswap = NULL, tmp;
1628 	int r = SSH_ERR_INTERNAL_ERROR;
1629 
1630 #ifdef DEBUG_PK
1631 	fprintf(stderr, "%s: entering for %s\n", __func__, sshkey_ssh_name(k));
1632 #endif
1633 	if ((cipher = cipher_by_name(SSHKEY_SHIELD_CIPHER)) == NULL) {
1634 		r = SSH_ERR_INVALID_ARGUMENT;
1635 		goto out;
1636 	}
1637 	if (cipher_keylen(cipher) + cipher_ivlen(cipher) >
1638 	    ssh_digest_bytes(SSHKEY_SHIELD_PREKEY_HASH)) {
1639 		r = SSH_ERR_INTERNAL_ERROR;
1640 		goto out;
1641 	}
1642 
1643 	/* Prepare a random pre-key, and from it an ephemeral key */
1644 	if ((r = sshkey_prekey_alloc(&prekey, SSHKEY_SHIELD_PREKEY_LEN)) != 0)
1645 		goto out;
1646 	arc4random_buf(prekey, SSHKEY_SHIELD_PREKEY_LEN);
1647 	if ((r = ssh_digest_memory(SSHKEY_SHIELD_PREKEY_HASH,
1648 	    prekey, SSHKEY_SHIELD_PREKEY_LEN,
1649 	    keyiv, SSH_DIGEST_MAX_LENGTH)) != 0)
1650 		goto out;
1651 #ifdef DEBUG_PK
1652 	fprintf(stderr, "%s: key+iv\n", __func__);
1653 	sshbuf_dump_data(keyiv, ssh_digest_bytes(SSHKEY_SHIELD_PREKEY_HASH),
1654 	    stderr);
1655 #endif
1656 	if ((r = cipher_init(&cctx, cipher, keyiv, cipher_keylen(cipher),
1657 	    keyiv + cipher_keylen(cipher), cipher_ivlen(cipher), 1)) != 0)
1658 		goto out;
1659 
1660 	/* Serialise and encrypt the private key using the ephemeral key */
1661 	if ((prvbuf = sshbuf_new()) == NULL) {
1662 		r = SSH_ERR_ALLOC_FAIL;
1663 		goto out;
1664 	}
1665 	if (sshkey_is_shielded(k) && (r = sshkey_unshield_private(k)) != 0)
1666 		goto out;
1667 	if ((r = sshkey_private_serialize(k, prvbuf)) != 0)
1668 		goto out;
1669 	/* pad to cipher blocksize */
1670 	i = 0;
1671 	while (sshbuf_len(prvbuf) % cipher_blocksize(cipher)) {
1672 		if ((r = sshbuf_put_u8(prvbuf, ++i & 0xff)) != 0)
1673 			goto out;
1674 	}
1675 #ifdef DEBUG_PK
1676 	fprintf(stderr, "%s: serialised\n", __func__);
1677 	sshbuf_dump(prvbuf, stderr);
1678 #endif
1679 	/* encrypt */
1680 	enclen = sshbuf_len(prvbuf);
1681 	if ((enc = malloc(enclen)) == NULL) {
1682 		r = SSH_ERR_ALLOC_FAIL;
1683 		goto out;
1684 	}
1685 	if ((r = cipher_crypt(cctx, 0, enc,
1686 	    sshbuf_ptr(prvbuf), sshbuf_len(prvbuf), 0, 0)) != 0)
1687 		goto out;
1688 #ifdef DEBUG_PK
1689 	fprintf(stderr, "%s: encrypted\n", __func__);
1690 	sshbuf_dump_data(enc, enclen, stderr);
1691 #endif
1692 
1693 	/* Make a scrubbed, public-only copy of our private key argument */
1694 	if ((r = sshkey_from_private(k, &kswap)) != 0)
1695 		goto out;
1696 
1697 	/* Swap the private key out (it will be destroyed below) */
1698 	tmp = *kswap;
1699 	*kswap = *k;
1700 	*k = tmp;
1701 
1702 	/* Insert the shielded key into our argument */
1703 	k->shielded_private = enc;
1704 	k->shielded_len = enclen;
1705 	k->shield_prekey = prekey;
1706 	k->shield_prekey_len = SSHKEY_SHIELD_PREKEY_LEN;
1707 	enc = prekey = NULL; /* transferred */
1708 	enclen = 0;
1709 
1710 	/* preserve key fields that are required for correct operation */
1711 	k->sk_flags = kswap->sk_flags;
1712 
1713 	/* success */
1714 	r = 0;
1715 
1716  out:
1717 	/* XXX behaviour on error - invalidate original private key? */
1718 	cipher_free(cctx);
1719 	explicit_bzero(keyiv, sizeof(keyiv));
1720 	explicit_bzero(&tmp, sizeof(tmp));
1721 	freezero(enc, enclen);
1722 	sshkey_prekey_free(prekey, SSHKEY_SHIELD_PREKEY_LEN);
1723 	sshkey_free(kswap);
1724 	sshbuf_free(prvbuf);
1725 	return r;
1726 }
1727 
1728 /* Check deterministic padding after private key */
1729 static int
1730 private2_check_padding(struct sshbuf *decrypted)
1731 {
1732 	u_char pad;
1733 	size_t i;
1734 	int r;
1735 
1736 	i = 0;
1737 	while (sshbuf_len(decrypted)) {
1738 		if ((r = sshbuf_get_u8(decrypted, &pad)) != 0)
1739 			goto out;
1740 		if (pad != (++i & 0xff)) {
1741 			r = SSH_ERR_INVALID_FORMAT;
1742 			goto out;
1743 		}
1744 	}
1745 	/* success */
1746 	r = 0;
1747  out:
1748 	explicit_bzero(&pad, sizeof(pad));
1749 	explicit_bzero(&i, sizeof(i));
1750 	return r;
1751 }
1752 
1753 int
1754 sshkey_unshield_private(struct sshkey *k)
1755 {
1756 	struct sshbuf *prvbuf = NULL;
1757 	u_char *cp, keyiv[SSH_DIGEST_MAX_LENGTH];
1758 	struct sshcipher_ctx *cctx = NULL;
1759 	const struct sshcipher *cipher;
1760 	struct sshkey *kswap = NULL, tmp;
1761 	int r = SSH_ERR_INTERNAL_ERROR;
1762 
1763 #ifdef DEBUG_PK
1764 	fprintf(stderr, "%s: entering for %s\n", __func__, sshkey_ssh_name(k));
1765 #endif
1766 	if (!sshkey_is_shielded(k))
1767 		return 0; /* nothing to do */
1768 
1769 	if ((cipher = cipher_by_name(SSHKEY_SHIELD_CIPHER)) == NULL) {
1770 		r = SSH_ERR_INVALID_ARGUMENT;
1771 		goto out;
1772 	}
1773 	if (cipher_keylen(cipher) + cipher_ivlen(cipher) >
1774 	    ssh_digest_bytes(SSHKEY_SHIELD_PREKEY_HASH)) {
1775 		r = SSH_ERR_INTERNAL_ERROR;
1776 		goto out;
1777 	}
1778 	/* check size of shielded key blob */
1779 	if (k->shielded_len < cipher_blocksize(cipher) ||
1780 	    (k->shielded_len % cipher_blocksize(cipher)) != 0) {
1781 		r = SSH_ERR_INVALID_FORMAT;
1782 		goto out;
1783 	}
1784 
1785 	/* Calculate the ephemeral key from the prekey */
1786 	if ((r = ssh_digest_memory(SSHKEY_SHIELD_PREKEY_HASH,
1787 	    k->shield_prekey, k->shield_prekey_len,
1788 	    keyiv, SSH_DIGEST_MAX_LENGTH)) != 0)
1789 		goto out;
1790 	if ((r = cipher_init(&cctx, cipher, keyiv, cipher_keylen(cipher),
1791 	    keyiv + cipher_keylen(cipher), cipher_ivlen(cipher), 0)) != 0)
1792 		goto out;
1793 #ifdef DEBUG_PK
1794 	fprintf(stderr, "%s: key+iv\n", __func__);
1795 	sshbuf_dump_data(keyiv, ssh_digest_bytes(SSHKEY_SHIELD_PREKEY_HASH),
1796 	    stderr);
1797 #endif
1798 
1799 	/* Decrypt and parse the shielded private key using the ephemeral key */
1800 	if ((prvbuf = sshbuf_new()) == NULL) {
1801 		r = SSH_ERR_ALLOC_FAIL;
1802 		goto out;
1803 	}
1804 	if ((r = sshbuf_reserve(prvbuf, k->shielded_len, &cp)) != 0)
1805 		goto out;
1806 	/* decrypt */
1807 #ifdef DEBUG_PK
1808 	fprintf(stderr, "%s: encrypted\n", __func__);
1809 	sshbuf_dump_data(k->shielded_private, k->shielded_len, stderr);
1810 #endif
1811 	if ((r = cipher_crypt(cctx, 0, cp,
1812 	    k->shielded_private, k->shielded_len, 0, 0)) != 0)
1813 		goto out;
1814 #ifdef DEBUG_PK
1815 	fprintf(stderr, "%s: serialised\n", __func__);
1816 	sshbuf_dump(prvbuf, stderr);
1817 #endif
1818 	/* Parse private key */
1819 	if ((r = sshkey_private_deserialize(prvbuf, &kswap)) != 0)
1820 		goto out;
1821 
1822 	if ((r = private2_check_padding(prvbuf)) != 0)
1823 		goto out;
1824 
1825 	/* Swap the parsed key back into place */
1826 	tmp = *kswap;
1827 	*kswap = *k;
1828 	*k = tmp;
1829 
1830 	/* success */
1831 	r = 0;
1832 
1833  out:
1834 	cipher_free(cctx);
1835 	explicit_bzero(keyiv, sizeof(keyiv));
1836 	explicit_bzero(&tmp, sizeof(tmp));
1837 	sshkey_free(kswap);
1838 	sshbuf_free(prvbuf);
1839 	return r;
1840 }
1841 
1842 static int
1843 cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf)
1844 {
1845 	struct sshbuf *principals = NULL, *crit = NULL;
1846 	struct sshbuf *exts = NULL, *ca = NULL;
1847 	u_char *sig = NULL;
1848 	size_t signed_len = 0, slen = 0, kidlen = 0;
1849 	int ret = SSH_ERR_INTERNAL_ERROR;
1850 
1851 	/* Copy the entire key blob for verification and later serialisation */
1852 	if ((ret = sshbuf_putb(key->cert->certblob, certbuf)) != 0)
1853 		return ret;
1854 
1855 	/* Parse body of certificate up to signature */
1856 	if ((ret = sshbuf_get_u64(b, &key->cert->serial)) != 0 ||
1857 	    (ret = sshbuf_get_u32(b, &key->cert->type)) != 0 ||
1858 	    (ret = sshbuf_get_cstring(b, &key->cert->key_id, &kidlen)) != 0 ||
1859 	    (ret = sshbuf_froms(b, &principals)) != 0 ||
1860 	    (ret = sshbuf_get_u64(b, &key->cert->valid_after)) != 0 ||
1861 	    (ret = sshbuf_get_u64(b, &key->cert->valid_before)) != 0 ||
1862 	    (ret = sshbuf_froms(b, &crit)) != 0 ||
1863 	    (ret = sshbuf_froms(b, &exts)) != 0 ||
1864 	    (ret = sshbuf_get_string_direct(b, NULL, NULL)) != 0 ||
1865 	    (ret = sshbuf_froms(b, &ca)) != 0) {
1866 		/* XXX debug print error for ret */
1867 		ret = SSH_ERR_INVALID_FORMAT;
1868 		goto out;
1869 	}
1870 
1871 	/* Signature is left in the buffer so we can calculate this length */
1872 	signed_len = sshbuf_len(key->cert->certblob) - sshbuf_len(b);
1873 
1874 	if ((ret = sshbuf_get_string(b, &sig, &slen)) != 0) {
1875 		ret = SSH_ERR_INVALID_FORMAT;
1876 		goto out;
1877 	}
1878 
1879 	if (key->cert->type != SSH2_CERT_TYPE_USER &&
1880 	    key->cert->type != SSH2_CERT_TYPE_HOST) {
1881 		ret = SSH_ERR_KEY_CERT_UNKNOWN_TYPE;
1882 		goto out;
1883 	}
1884 
1885 	/* Parse principals section */
1886 	while (sshbuf_len(principals) > 0) {
1887 		char *principal = NULL;
1888 		char **oprincipals = NULL;
1889 
1890 		if (key->cert->nprincipals >= SSHKEY_CERT_MAX_PRINCIPALS) {
1891 			ret = SSH_ERR_INVALID_FORMAT;
1892 			goto out;
1893 		}
1894 		if ((ret = sshbuf_get_cstring(principals, &principal,
1895 		    NULL)) != 0) {
1896 			ret = SSH_ERR_INVALID_FORMAT;
1897 			goto out;
1898 		}
1899 		oprincipals = key->cert->principals;
1900 		key->cert->principals = recallocarray(key->cert->principals,
1901 		    key->cert->nprincipals, key->cert->nprincipals + 1,
1902 		    sizeof(*key->cert->principals));
1903 		if (key->cert->principals == NULL) {
1904 			free(principal);
1905 			key->cert->principals = oprincipals;
1906 			ret = SSH_ERR_ALLOC_FAIL;
1907 			goto out;
1908 		}
1909 		key->cert->principals[key->cert->nprincipals++] = principal;
1910 	}
1911 
1912 	/*
1913 	 * Stash a copies of the critical options and extensions sections
1914 	 * for later use.
1915 	 */
1916 	if ((ret = sshbuf_putb(key->cert->critical, crit)) != 0 ||
1917 	    (exts != NULL &&
1918 	    (ret = sshbuf_putb(key->cert->extensions, exts)) != 0))
1919 		goto out;
1920 
1921 	/*
1922 	 * Validate critical options and extensions sections format.
1923 	 */
1924 	while (sshbuf_len(crit) != 0) {
1925 		if ((ret = sshbuf_get_string_direct(crit, NULL, NULL)) != 0 ||
1926 		    (ret = sshbuf_get_string_direct(crit, NULL, NULL)) != 0) {
1927 			sshbuf_reset(key->cert->critical);
1928 			ret = SSH_ERR_INVALID_FORMAT;
1929 			goto out;
1930 		}
1931 	}
1932 	while (exts != NULL && sshbuf_len(exts) != 0) {
1933 		if ((ret = sshbuf_get_string_direct(exts, NULL, NULL)) != 0 ||
1934 		    (ret = sshbuf_get_string_direct(exts, NULL, NULL)) != 0) {
1935 			sshbuf_reset(key->cert->extensions);
1936 			ret = SSH_ERR_INVALID_FORMAT;
1937 			goto out;
1938 		}
1939 	}
1940 
1941 	/* Parse CA key and check signature */
1942 	if (sshkey_from_blob_internal(ca, &key->cert->signature_key, 0) != 0) {
1943 		ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
1944 		goto out;
1945 	}
1946 	if (!sshkey_type_is_valid_ca(key->cert->signature_key->type)) {
1947 		ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
1948 		goto out;
1949 	}
1950 	if ((ret = sshkey_verify(key->cert->signature_key, sig, slen,
1951 	    sshbuf_ptr(key->cert->certblob), signed_len, NULL, 0, NULL)) != 0)
1952 		goto out;
1953 	if ((ret = sshkey_get_sigtype(sig, slen,
1954 	    &key->cert->signature_type)) != 0)
1955 		goto out;
1956 
1957 	/* Success */
1958 	ret = 0;
1959  out:
1960 	sshbuf_free(ca);
1961 	sshbuf_free(crit);
1962 	sshbuf_free(exts);
1963 	sshbuf_free(principals);
1964 	free(sig);
1965 	return ret;
1966 }
1967 
1968 int
1969 sshkey_deserialize_sk(struct sshbuf *b, struct sshkey *key)
1970 {
1971 	/* Parse additional security-key application string */
1972 	if (sshbuf_get_cstring(b, &key->sk_application, NULL) != 0)
1973 		return SSH_ERR_INVALID_FORMAT;
1974 	return 0;
1975 }
1976 
1977 static int
1978 sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
1979     int allow_cert)
1980 {
1981 	int type, ret = SSH_ERR_INTERNAL_ERROR;
1982 	char *ktype = NULL;
1983 	struct sshkey *key = NULL;
1984 	struct sshbuf *copy;
1985 	const struct sshkey_impl *impl;
1986 
1987 #ifdef DEBUG_PK /* XXX */
1988 	sshbuf_dump(b, stderr);
1989 #endif
1990 	if (keyp != NULL)
1991 		*keyp = NULL;
1992 	if ((copy = sshbuf_fromb(b)) == NULL) {
1993 		ret = SSH_ERR_ALLOC_FAIL;
1994 		goto out;
1995 	}
1996 	if (sshbuf_get_cstring(b, &ktype, NULL) != 0) {
1997 		ret = SSH_ERR_INVALID_FORMAT;
1998 		goto out;
1999 	}
2000 
2001 	type = sshkey_type_from_name(ktype);
2002 	if (!allow_cert && sshkey_type_is_cert(type)) {
2003 		ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
2004 		goto out;
2005 	}
2006 	if ((impl = sshkey_impl_from_type(type)) == NULL) {
2007 		ret = SSH_ERR_KEY_TYPE_UNKNOWN;
2008 		goto out;
2009 	}
2010 	if ((key = sshkey_new(type)) == NULL) {
2011 		ret = SSH_ERR_ALLOC_FAIL;
2012 		goto out;
2013 	}
2014 	if (sshkey_type_is_cert(type)) {
2015 		/* Skip nonce that precedes all certificates */
2016 		if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
2017 			ret = SSH_ERR_INVALID_FORMAT;
2018 			goto out;
2019 		}
2020 	}
2021 	if ((ret = impl->funcs->deserialize_public(ktype, b, key)) != 0)
2022 		goto out;
2023 
2024 	/* Parse certificate potion */
2025 	if (sshkey_is_cert(key) && (ret = cert_parse(b, key, copy)) != 0)
2026 		goto out;
2027 
2028 	if (key != NULL && sshbuf_len(b) != 0) {
2029 		ret = SSH_ERR_INVALID_FORMAT;
2030 		goto out;
2031 	}
2032 	ret = 0;
2033 	if (keyp != NULL) {
2034 		*keyp = key;
2035 		key = NULL;
2036 	}
2037  out:
2038 	sshbuf_free(copy);
2039 	sshkey_free(key);
2040 	free(ktype);
2041 	return ret;
2042 }
2043 
2044 int
2045 sshkey_from_blob(const u_char *blob, size_t blen, struct sshkey **keyp)
2046 {
2047 	struct sshbuf *b;
2048 	int r;
2049 
2050 	if ((b = sshbuf_from(blob, blen)) == NULL)
2051 		return SSH_ERR_ALLOC_FAIL;
2052 	r = sshkey_from_blob_internal(b, keyp, 1);
2053 	sshbuf_free(b);
2054 	return r;
2055 }
2056 
2057 int
2058 sshkey_fromb(struct sshbuf *b, struct sshkey **keyp)
2059 {
2060 	return sshkey_from_blob_internal(b, keyp, 1);
2061 }
2062 
2063 int
2064 sshkey_froms(struct sshbuf *buf, struct sshkey **keyp)
2065 {
2066 	struct sshbuf *b;
2067 	int r;
2068 
2069 	if ((r = sshbuf_froms(buf, &b)) != 0)
2070 		return r;
2071 	r = sshkey_from_blob_internal(b, keyp, 1);
2072 	sshbuf_free(b);
2073 	return r;
2074 }
2075 
2076 int
2077 sshkey_get_sigtype(const u_char *sig, size_t siglen, char **sigtypep)
2078 {
2079 	int r;
2080 	struct sshbuf *b = NULL;
2081 	char *sigtype = NULL;
2082 
2083 	if (sigtypep != NULL)
2084 		*sigtypep = NULL;
2085 	if ((b = sshbuf_from(sig, siglen)) == NULL)
2086 		return SSH_ERR_ALLOC_FAIL;
2087 	if ((r = sshbuf_get_cstring(b, &sigtype, NULL)) != 0)
2088 		goto out;
2089 	/* success */
2090 	if (sigtypep != NULL) {
2091 		*sigtypep = sigtype;
2092 		sigtype = NULL;
2093 	}
2094 	r = 0;
2095  out:
2096 	free(sigtype);
2097 	sshbuf_free(b);
2098 	return r;
2099 }
2100 
2101 /*
2102  *
2103  * Checks whether a certificate's signature type is allowed.
2104  * Returns 0 (success) if the certificate signature type appears in the
2105  * "allowed" pattern-list, or the key is not a certificate to begin with.
2106  * Otherwise returns a ssherr.h code.
2107  */
2108 int
2109 sshkey_check_cert_sigtype(const struct sshkey *key, const char *allowed)
2110 {
2111 	if (key == NULL || allowed == NULL)
2112 		return SSH_ERR_INVALID_ARGUMENT;
2113 	if (!sshkey_type_is_cert(key->type))
2114 		return 0;
2115 	if (key->cert == NULL || key->cert->signature_type == NULL)
2116 		return SSH_ERR_INVALID_ARGUMENT;
2117 	if (match_pattern_list(key->cert->signature_type, allowed, 0) != 1)
2118 		return SSH_ERR_SIGN_ALG_UNSUPPORTED;
2119 	return 0;
2120 }
2121 
2122 /*
2123  * Returns the expected signature algorithm for a given public key algorithm.
2124  */
2125 const char *
2126 sshkey_sigalg_by_name(const char *name)
2127 {
2128 	const struct sshkey_impl *impl;
2129 	int i;
2130 
2131 	for (i = 0; keyimpls[i] != NULL; i++) {
2132 		impl = keyimpls[i];
2133 		if (strcmp(impl->name, name) != 0)
2134 			continue;
2135 		if (impl->sigalg != NULL)
2136 			return impl->sigalg;
2137 		if (!impl->cert)
2138 			return impl->name;
2139 		return sshkey_ssh_name_from_type_nid(
2140 		    sshkey_type_plain(impl->type), impl->nid);
2141 	}
2142 	return NULL;
2143 }
2144 
2145 /*
2146  * Verifies that the signature algorithm appearing inside the signature blob
2147  * matches that which was requested.
2148  */
2149 int
2150 sshkey_check_sigtype(const u_char *sig, size_t siglen,
2151     const char *requested_alg)
2152 {
2153 	const char *expected_alg;
2154 	char *sigtype = NULL;
2155 	int r;
2156 
2157 	if (requested_alg == NULL)
2158 		return 0;
2159 	if ((expected_alg = sshkey_sigalg_by_name(requested_alg)) == NULL)
2160 		return SSH_ERR_INVALID_ARGUMENT;
2161 	if ((r = sshkey_get_sigtype(sig, siglen, &sigtype)) != 0)
2162 		return r;
2163 	r = strcmp(expected_alg, sigtype) == 0;
2164 	free(sigtype);
2165 	return r ? 0 : SSH_ERR_SIGN_ALG_UNSUPPORTED;
2166 }
2167 
2168 int
2169 sshkey_sign(struct sshkey *key,
2170     u_char **sigp, size_t *lenp,
2171     const u_char *data, size_t datalen,
2172     const char *alg, const char *sk_provider, const char *sk_pin, u_int compat)
2173 {
2174 	int was_shielded = sshkey_is_shielded(key);
2175 	int r2, r = SSH_ERR_INTERNAL_ERROR;
2176 	const struct sshkey_impl *impl;
2177 
2178 	if (sigp != NULL)
2179 		*sigp = NULL;
2180 	if (lenp != NULL)
2181 		*lenp = 0;
2182 	if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE)
2183 		return SSH_ERR_INVALID_ARGUMENT;
2184 	if ((impl = sshkey_impl_from_key(key)) == NULL)
2185 		return SSH_ERR_KEY_TYPE_UNKNOWN;
2186 	if ((r = sshkey_unshield_private(key)) != 0)
2187 		return r;
2188 	if (sshkey_is_sk(key)) {
2189 		r = sshsk_sign(sk_provider, key, sigp, lenp, data,
2190 		    datalen, compat, sk_pin);
2191 	} else if ((key->flags & SSHKEY_FLAG_EXT) != 0) {
2192 		r = pkcs11_sign(key, sigp, lenp, data, datalen,
2193 		    alg, sk_provider, sk_pin, compat);
2194 	} else {
2195 		if (impl->funcs->sign == NULL)
2196 			r = SSH_ERR_SIGN_ALG_UNSUPPORTED;
2197 		else {
2198 			r = impl->funcs->sign(key, sigp, lenp, data, datalen,
2199 			    alg, sk_provider, sk_pin, compat);
2200 		 }
2201 	}
2202 	if (was_shielded && (r2 = sshkey_shield_private(key)) != 0)
2203 		return r2;
2204 	return r;
2205 }
2206 
2207 /*
2208  * ssh_key_verify returns 0 for a correct signature  and < 0 on error.
2209  * If "alg" specified, then the signature must use that algorithm.
2210  */
2211 int
2212 sshkey_verify(const struct sshkey *key,
2213     const u_char *sig, size_t siglen,
2214     const u_char *data, size_t dlen, const char *alg, u_int compat,
2215     struct sshkey_sig_details **detailsp)
2216 {
2217 	const struct sshkey_impl *impl;
2218 
2219 	if (detailsp != NULL)
2220 		*detailsp = NULL;
2221 	if (siglen == 0 || dlen > SSH_KEY_MAX_SIGN_DATA_SIZE)
2222 		return SSH_ERR_INVALID_ARGUMENT;
2223 	if ((impl = sshkey_impl_from_key(key)) == NULL)
2224 		return SSH_ERR_KEY_TYPE_UNKNOWN;
2225 	return impl->funcs->verify(key, sig, siglen, data, dlen,
2226 	    alg, compat, detailsp);
2227 }
2228 
2229 /* Convert a plain key to their _CERT equivalent */
2230 int
2231 sshkey_to_certified(struct sshkey *k)
2232 {
2233 	int newtype;
2234 
2235 	if ((newtype = sshkey_type_certified(k->type)) == -1)
2236 		return SSH_ERR_INVALID_ARGUMENT;
2237 	if ((k->cert = cert_new()) == NULL)
2238 		return SSH_ERR_ALLOC_FAIL;
2239 	k->type = newtype;
2240 	return 0;
2241 }
2242 
2243 /* Convert a certificate to its raw key equivalent */
2244 int
2245 sshkey_drop_cert(struct sshkey *k)
2246 {
2247 	if (!sshkey_type_is_cert(k->type))
2248 		return SSH_ERR_KEY_TYPE_UNKNOWN;
2249 	cert_free(k->cert);
2250 	k->cert = NULL;
2251 	k->type = sshkey_type_plain(k->type);
2252 	return 0;
2253 }
2254 
2255 /* Sign a certified key, (re-)generating the signed certblob. */
2256 int
2257 sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg,
2258     const char *sk_provider, const char *sk_pin,
2259     sshkey_certify_signer *signer, void *signer_ctx)
2260 {
2261 	const struct sshkey_impl *impl;
2262 	struct sshbuf *principals = NULL;
2263 	u_char *ca_blob = NULL, *sig_blob = NULL, nonce[32];
2264 	size_t i, ca_len, sig_len;
2265 	int ret = SSH_ERR_INTERNAL_ERROR;
2266 	struct sshbuf *cert = NULL;
2267 	char *sigtype = NULL;
2268 
2269 	if (k == NULL || k->cert == NULL ||
2270 	    k->cert->certblob == NULL || ca == NULL)
2271 		return SSH_ERR_INVALID_ARGUMENT;
2272 	if (!sshkey_is_cert(k))
2273 		return SSH_ERR_KEY_TYPE_UNKNOWN;
2274 	if (!sshkey_type_is_valid_ca(ca->type))
2275 		return SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
2276 	if ((impl = sshkey_impl_from_key(k)) == NULL)
2277 		return SSH_ERR_INTERNAL_ERROR;
2278 
2279 	/*
2280 	 * If no alg specified as argument but a signature_type was set,
2281 	 * then prefer that. If both were specified, then they must match.
2282 	 */
2283 	if (alg == NULL)
2284 		alg = k->cert->signature_type;
2285 	else if (k->cert->signature_type != NULL &&
2286 	    strcmp(alg, k->cert->signature_type) != 0)
2287 		return SSH_ERR_INVALID_ARGUMENT;
2288 
2289 	/*
2290 	 * If no signing algorithm or signature_type was specified and we're
2291 	 * using a RSA key, then default to a good signature algorithm.
2292 	 */
2293 	if (alg == NULL && ca->type == KEY_RSA)
2294 		alg = "rsa-sha2-512";
2295 
2296 	if ((ret = sshkey_to_blob(ca, &ca_blob, &ca_len)) != 0)
2297 		return SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
2298 
2299 	cert = k->cert->certblob; /* for readability */
2300 	sshbuf_reset(cert);
2301 	if ((ret = sshbuf_put_cstring(cert, sshkey_ssh_name(k))) != 0)
2302 		goto out;
2303 
2304 	/* -v01 certs put nonce first */
2305 	arc4random_buf(&nonce, sizeof(nonce));
2306 	if ((ret = sshbuf_put_string(cert, nonce, sizeof(nonce))) != 0)
2307 		goto out;
2308 
2309 	/* Public key next */
2310 	if ((ret = impl->funcs->serialize_public(k, cert,
2311 	    SSHKEY_SERIALIZE_DEFAULT)) != 0)
2312 		goto out;
2313 
2314 	/* Then remaining cert fields */
2315 	if ((ret = sshbuf_put_u64(cert, k->cert->serial)) != 0 ||
2316 	    (ret = sshbuf_put_u32(cert, k->cert->type)) != 0 ||
2317 	    (ret = sshbuf_put_cstring(cert, k->cert->key_id)) != 0)
2318 		goto out;
2319 
2320 	if ((principals = sshbuf_new()) == NULL) {
2321 		ret = SSH_ERR_ALLOC_FAIL;
2322 		goto out;
2323 	}
2324 	for (i = 0; i < k->cert->nprincipals; i++) {
2325 		if ((ret = sshbuf_put_cstring(principals,
2326 		    k->cert->principals[i])) != 0)
2327 			goto out;
2328 	}
2329 	if ((ret = sshbuf_put_stringb(cert, principals)) != 0 ||
2330 	    (ret = sshbuf_put_u64(cert, k->cert->valid_after)) != 0 ||
2331 	    (ret = sshbuf_put_u64(cert, k->cert->valid_before)) != 0 ||
2332 	    (ret = sshbuf_put_stringb(cert, k->cert->critical)) != 0 ||
2333 	    (ret = sshbuf_put_stringb(cert, k->cert->extensions)) != 0 ||
2334 	    (ret = sshbuf_put_string(cert, NULL, 0)) != 0 || /* Reserved */
2335 	    (ret = sshbuf_put_string(cert, ca_blob, ca_len)) != 0)
2336 		goto out;
2337 
2338 	/* Sign the whole mess */
2339 	if ((ret = signer(ca, &sig_blob, &sig_len, sshbuf_ptr(cert),
2340 	    sshbuf_len(cert), alg, sk_provider, sk_pin, 0, signer_ctx)) != 0)
2341 		goto out;
2342 	/* Check and update signature_type against what was actually used */
2343 	if ((ret = sshkey_get_sigtype(sig_blob, sig_len, &sigtype)) != 0)
2344 		goto out;
2345 	if (alg != NULL && strcmp(alg, sigtype) != 0) {
2346 		ret = SSH_ERR_SIGN_ALG_UNSUPPORTED;
2347 		goto out;
2348 	}
2349 	if (k->cert->signature_type == NULL) {
2350 		k->cert->signature_type = sigtype;
2351 		sigtype = NULL;
2352 	}
2353 	/* Append signature and we are done */
2354 	if ((ret = sshbuf_put_string(cert, sig_blob, sig_len)) != 0)
2355 		goto out;
2356 	ret = 0;
2357  out:
2358 	if (ret != 0)
2359 		sshbuf_reset(cert);
2360 	free(sig_blob);
2361 	free(ca_blob);
2362 	free(sigtype);
2363 	sshbuf_free(principals);
2364 	return ret;
2365 }
2366 
2367 static int
2368 default_key_sign(struct sshkey *key, u_char **sigp, size_t *lenp,
2369     const u_char *data, size_t datalen,
2370     const char *alg, const char *sk_provider, const char *sk_pin,
2371     u_int compat, void *ctx)
2372 {
2373 	if (ctx != NULL)
2374 		return SSH_ERR_INVALID_ARGUMENT;
2375 	return sshkey_sign(key, sigp, lenp, data, datalen, alg,
2376 	    sk_provider, sk_pin, compat);
2377 }
2378 
2379 int
2380 sshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg,
2381     const char *sk_provider, const char *sk_pin)
2382 {
2383 	return sshkey_certify_custom(k, ca, alg, sk_provider, sk_pin,
2384 	    default_key_sign, NULL);
2385 }
2386 
2387 int
2388 sshkey_cert_check_authority(const struct sshkey *k,
2389     int want_host, int require_principal, int wildcard_pattern,
2390     uint64_t verify_time, const char *name, const char **reason)
2391 {
2392 	u_int i, principal_matches;
2393 
2394 	if (reason == NULL)
2395 		return SSH_ERR_INVALID_ARGUMENT;
2396 	if (!sshkey_is_cert(k)) {
2397 		*reason = "Key is not a certificate";
2398 		return SSH_ERR_KEY_CERT_INVALID;
2399 	}
2400 	if (want_host) {
2401 		if (k->cert->type != SSH2_CERT_TYPE_HOST) {
2402 			*reason = "Certificate invalid: not a host certificate";
2403 			return SSH_ERR_KEY_CERT_INVALID;
2404 		}
2405 	} else {
2406 		if (k->cert->type != SSH2_CERT_TYPE_USER) {
2407 			*reason = "Certificate invalid: not a user certificate";
2408 			return SSH_ERR_KEY_CERT_INVALID;
2409 		}
2410 	}
2411 	if (verify_time < k->cert->valid_after) {
2412 		*reason = "Certificate invalid: not yet valid";
2413 		return SSH_ERR_KEY_CERT_INVALID;
2414 	}
2415 	if (verify_time >= k->cert->valid_before) {
2416 		*reason = "Certificate invalid: expired";
2417 		return SSH_ERR_KEY_CERT_INVALID;
2418 	}
2419 	if (k->cert->nprincipals == 0) {
2420 		if (require_principal) {
2421 			*reason = "Certificate lacks principal list";
2422 			return SSH_ERR_KEY_CERT_INVALID;
2423 		}
2424 	} else if (name != NULL) {
2425 		principal_matches = 0;
2426 		for (i = 0; i < k->cert->nprincipals; i++) {
2427 			if (wildcard_pattern) {
2428 				if (match_pattern(k->cert->principals[i],
2429 				    name)) {
2430 					principal_matches = 1;
2431 					break;
2432 				}
2433 			} else if (strcmp(name, k->cert->principals[i]) == 0) {
2434 				principal_matches = 1;
2435 				break;
2436 			}
2437 		}
2438 		if (!principal_matches) {
2439 			*reason = "Certificate invalid: name is not a listed "
2440 			    "principal";
2441 			return SSH_ERR_KEY_CERT_INVALID;
2442 		}
2443 	}
2444 	return 0;
2445 }
2446 
2447 int
2448 sshkey_cert_check_authority_now(const struct sshkey *k,
2449     int want_host, int require_principal, int wildcard_pattern,
2450     const char *name, const char **reason)
2451 {
2452 	time_t now;
2453 
2454 	if ((now = time(NULL)) < 0) {
2455 		/* yikes - system clock before epoch! */
2456 		*reason = "Certificate invalid: not yet valid";
2457 		return SSH_ERR_KEY_CERT_INVALID;
2458 	}
2459 	return sshkey_cert_check_authority(k, want_host, require_principal,
2460 	    wildcard_pattern, (uint64_t)now, name, reason);
2461 }
2462 
2463 int
2464 sshkey_cert_check_host(const struct sshkey *key, const char *host,
2465     int wildcard_principals, const char *ca_sign_algorithms,
2466     const char **reason)
2467 {
2468 	int r;
2469 
2470 	if ((r = sshkey_cert_check_authority_now(key, 1, 0, wildcard_principals,
2471 	    host, reason)) != 0)
2472 		return r;
2473 	if (sshbuf_len(key->cert->critical) != 0) {
2474 		*reason = "Certificate contains unsupported critical options";
2475 		return SSH_ERR_KEY_CERT_INVALID;
2476 	}
2477 	if (ca_sign_algorithms != NULL &&
2478 	    (r = sshkey_check_cert_sigtype(key, ca_sign_algorithms)) != 0) {
2479 		*reason = "Certificate signed with disallowed algorithm";
2480 		return SSH_ERR_KEY_CERT_INVALID;
2481 	}
2482 	return 0;
2483 }
2484 
2485 size_t
2486 sshkey_format_cert_validity(const struct sshkey_cert *cert, char *s, size_t l)
2487 {
2488 	char from[32], to[32], ret[128];
2489 
2490 	*from = *to = '\0';
2491 	if (cert->valid_after == 0 &&
2492 	    cert->valid_before == 0xffffffffffffffffULL)
2493 		return strlcpy(s, "forever", l);
2494 
2495 	if (cert->valid_after != 0)
2496 		format_absolute_time(cert->valid_after, from, sizeof(from));
2497 	if (cert->valid_before != 0xffffffffffffffffULL)
2498 		format_absolute_time(cert->valid_before, to, sizeof(to));
2499 
2500 	if (cert->valid_after == 0)
2501 		snprintf(ret, sizeof(ret), "before %s", to);
2502 	else if (cert->valid_before == 0xffffffffffffffffULL)
2503 		snprintf(ret, sizeof(ret), "after %s", from);
2504 	else
2505 		snprintf(ret, sizeof(ret), "from %s to %s", from, to);
2506 
2507 	return strlcpy(s, ret, l);
2508 }
2509 
2510 /* Common serialization for FIDO private keys */
2511 int
2512 sshkey_serialize_private_sk(const struct sshkey *key, struct sshbuf *b)
2513 {
2514 	int r;
2515 
2516 	if ((r = sshbuf_put_cstring(b, key->sk_application)) != 0 ||
2517 	    (r = sshbuf_put_u8(b, key->sk_flags)) != 0 ||
2518 	    (r = sshbuf_put_stringb(b, key->sk_key_handle)) != 0 ||
2519 	    (r = sshbuf_put_stringb(b, key->sk_reserved)) != 0)
2520 		return r;
2521 
2522 	return 0;
2523 }
2524 
2525 static int
2526 sshkey_private_serialize_opt(struct sshkey *key, struct sshbuf *buf,
2527     enum sshkey_serialize_rep opts)
2528 {
2529 	int r = SSH_ERR_INTERNAL_ERROR;
2530 	int was_shielded = sshkey_is_shielded(key);
2531 	struct sshbuf *b = NULL;
2532 	const struct sshkey_impl *impl;
2533 
2534 	if ((impl = sshkey_impl_from_key(key)) == NULL)
2535 		return SSH_ERR_INTERNAL_ERROR;
2536 	if ((r = sshkey_unshield_private(key)) != 0)
2537 		return r;
2538 	if ((b = sshbuf_new()) == NULL)
2539 		return SSH_ERR_ALLOC_FAIL;
2540 	if ((r = sshbuf_put_cstring(b, sshkey_ssh_name(key))) != 0)
2541 		goto out;
2542 	if (sshkey_is_cert(key)) {
2543 		if (key->cert == NULL ||
2544 		    sshbuf_len(key->cert->certblob) == 0) {
2545 			r = SSH_ERR_INVALID_ARGUMENT;
2546 			goto out;
2547 		}
2548 		if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0)
2549 			goto out;
2550 	}
2551 	if ((r = impl->funcs->serialize_private(key, b, opts)) != 0)
2552 		goto out;
2553 
2554 	/*
2555 	 * success (but we still need to append the output to buf after
2556 	 * possibly re-shielding the private key)
2557 	 */
2558 	r = 0;
2559  out:
2560 	if (was_shielded)
2561 		r = sshkey_shield_private(key);
2562 	if (r == 0)
2563 		r = sshbuf_putb(buf, b);
2564 	sshbuf_free(b);
2565 
2566 	return r;
2567 }
2568 
2569 int
2570 sshkey_private_serialize(struct sshkey *key, struct sshbuf *b)
2571 {
2572 	return sshkey_private_serialize_opt(key, b,
2573 	    SSHKEY_SERIALIZE_DEFAULT);
2574 }
2575 
2576 
2577 /* Shared deserialization of FIDO private key components */
2578 int
2579 sshkey_private_deserialize_sk(struct sshbuf *buf, struct sshkey *k)
2580 {
2581 	int r;
2582 
2583 	if ((k->sk_key_handle = sshbuf_new()) == NULL ||
2584 	    (k->sk_reserved = sshbuf_new()) == NULL)
2585 		return SSH_ERR_ALLOC_FAIL;
2586 	if ((r = sshbuf_get_cstring(buf, &k->sk_application, NULL)) != 0 ||
2587 	    (r = sshbuf_get_u8(buf, &k->sk_flags)) != 0 ||
2588 	    (r = sshbuf_get_stringb(buf, k->sk_key_handle)) != 0 ||
2589 	    (r = sshbuf_get_stringb(buf, k->sk_reserved)) != 0)
2590 		return r;
2591 
2592 	return 0;
2593 }
2594 
2595 int
2596 sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
2597 {
2598 	const struct sshkey_impl *impl;
2599 	char *tname = NULL;
2600 	char *expect_sk_application = NULL;
2601 	u_char *expect_ed25519_pk = NULL;
2602 	struct sshkey *k = NULL;
2603 	int type, r = SSH_ERR_INTERNAL_ERROR;
2604 
2605 	if (kp != NULL)
2606 		*kp = NULL;
2607 	if ((r = sshbuf_get_cstring(buf, &tname, NULL)) != 0)
2608 		goto out;
2609 	type = sshkey_type_from_name(tname);
2610 	if (sshkey_type_is_cert(type)) {
2611 		/*
2612 		 * Certificate key private keys begin with the certificate
2613 		 * itself. Make sure this matches the type of the enclosing
2614 		 * private key.
2615 		 */
2616 		if ((r = sshkey_froms(buf, &k)) != 0)
2617 			goto out;
2618 		if (k->type != type) {
2619 			r = SSH_ERR_KEY_CERT_MISMATCH;
2620 			goto out;
2621 		}
2622 		/* For ECDSA keys, the group must match too */
2623 		if (k->type == KEY_ECDSA &&
2624 		    k->ecdsa_nid != sshkey_ecdsa_nid_from_name(tname)) {
2625 			r = SSH_ERR_KEY_CERT_MISMATCH;
2626 			goto out;
2627 		}
2628 		/*
2629 		 * Several fields are redundant between certificate and
2630 		 * private key body, we require these to match.
2631 		 */
2632 		expect_sk_application = k->sk_application;
2633 		expect_ed25519_pk = k->ed25519_pk;
2634 		k->sk_application = NULL;
2635 		k->ed25519_pk = NULL;
2636 	} else {
2637 		if ((k = sshkey_new(type)) == NULL) {
2638 			r = SSH_ERR_ALLOC_FAIL;
2639 			goto out;
2640 		}
2641 	}
2642 	if ((impl = sshkey_impl_from_type(type)) == NULL) {
2643 		r = SSH_ERR_INTERNAL_ERROR;
2644 		goto out;
2645 	}
2646 	if ((r = impl->funcs->deserialize_private(tname, buf, k)) != 0)
2647 		goto out;
2648 
2649 	if ((expect_sk_application != NULL && (k->sk_application == NULL ||
2650 	    strcmp(expect_sk_application, k->sk_application) != 0)) ||
2651 	    (expect_ed25519_pk != NULL && (k->ed25519_pk == NULL ||
2652 	    memcmp(expect_ed25519_pk, k->ed25519_pk, ED25519_PK_SZ) != 0))) {
2653 		r = SSH_ERR_KEY_CERT_MISMATCH;
2654 		goto out;
2655 	}
2656 	/* success */
2657 	r = 0;
2658 	if (kp != NULL) {
2659 		*kp = k;
2660 		k = NULL;
2661 	}
2662  out:
2663 	free(tname);
2664 	sshkey_free(k);
2665 	free(expect_sk_application);
2666 	free(expect_ed25519_pk);
2667 	return r;
2668 }
2669 
2670 #if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
2671 int
2672 sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public)
2673 {
2674 	EC_POINT *nq = NULL;
2675 	BIGNUM *order = NULL, *x = NULL, *y = NULL, *tmp = NULL;
2676 	int ret = SSH_ERR_KEY_INVALID_EC_VALUE;
2677 
2678 	/*
2679 	 * NB. This assumes OpenSSL has already verified that the public
2680 	 * point lies on the curve. This is done by EC_POINT_oct2point()
2681 	 * implicitly calling EC_POINT_is_on_curve(). If this code is ever
2682 	 * reachable with public points not unmarshalled using
2683 	 * EC_POINT_oct2point then the caller will need to explicitly check.
2684 	 */
2685 
2686 	/* Q != infinity */
2687 	if (EC_POINT_is_at_infinity(group, public))
2688 		goto out;
2689 
2690 	if ((x = BN_new()) == NULL ||
2691 	    (y = BN_new()) == NULL ||
2692 	    (order = BN_new()) == NULL ||
2693 	    (tmp = BN_new()) == NULL) {
2694 		ret = SSH_ERR_ALLOC_FAIL;
2695 		goto out;
2696 	}
2697 
2698 	/* log2(x) > log2(order)/2, log2(y) > log2(order)/2 */
2699 	if (EC_GROUP_get_order(group, order, NULL) != 1 ||
2700 	    EC_POINT_get_affine_coordinates(group, public, x, y, NULL) != 1) {
2701 		ret = SSH_ERR_LIBCRYPTO_ERROR;
2702 		goto out;
2703 	}
2704 	if (BN_num_bits(x) <= BN_num_bits(order) / 2 ||
2705 	    BN_num_bits(y) <= BN_num_bits(order) / 2)
2706 		goto out;
2707 
2708 	/* nQ == infinity (n == order of subgroup) */
2709 	if ((nq = EC_POINT_new(group)) == NULL) {
2710 		ret = SSH_ERR_ALLOC_FAIL;
2711 		goto out;
2712 	}
2713 	if (EC_POINT_mul(group, nq, NULL, public, order, NULL) != 1) {
2714 		ret = SSH_ERR_LIBCRYPTO_ERROR;
2715 		goto out;
2716 	}
2717 	if (EC_POINT_is_at_infinity(group, nq) != 1)
2718 		goto out;
2719 
2720 	/* x < order - 1, y < order - 1 */
2721 	if (!BN_sub(tmp, order, BN_value_one())) {
2722 		ret = SSH_ERR_LIBCRYPTO_ERROR;
2723 		goto out;
2724 	}
2725 	if (BN_cmp(x, tmp) >= 0 || BN_cmp(y, tmp) >= 0)
2726 		goto out;
2727 	ret = 0;
2728  out:
2729 	BN_clear_free(x);
2730 	BN_clear_free(y);
2731 	BN_clear_free(order);
2732 	BN_clear_free(tmp);
2733 	EC_POINT_free(nq);
2734 	return ret;
2735 }
2736 
2737 int
2738 sshkey_ec_validate_private(const EC_KEY *key)
2739 {
2740 	BIGNUM *order = NULL, *tmp = NULL;
2741 	int ret = SSH_ERR_KEY_INVALID_EC_VALUE;
2742 
2743 	if ((order = BN_new()) == NULL || (tmp = BN_new()) == NULL) {
2744 		ret = SSH_ERR_ALLOC_FAIL;
2745 		goto out;
2746 	}
2747 
2748 	/* log2(private) > log2(order)/2 */
2749 	if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, NULL) != 1) {
2750 		ret = SSH_ERR_LIBCRYPTO_ERROR;
2751 		goto out;
2752 	}
2753 	if (BN_num_bits(EC_KEY_get0_private_key(key)) <=
2754 	    BN_num_bits(order) / 2)
2755 		goto out;
2756 
2757 	/* private < order - 1 */
2758 	if (!BN_sub(tmp, order, BN_value_one())) {
2759 		ret = SSH_ERR_LIBCRYPTO_ERROR;
2760 		goto out;
2761 	}
2762 	if (BN_cmp(EC_KEY_get0_private_key(key), tmp) >= 0)
2763 		goto out;
2764 	ret = 0;
2765  out:
2766 	BN_clear_free(order);
2767 	BN_clear_free(tmp);
2768 	return ret;
2769 }
2770 
2771 void
2772 sshkey_dump_ec_point(const EC_GROUP *group, const EC_POINT *point)
2773 {
2774 	BIGNUM *x = NULL, *y = NULL;
2775 
2776 	if (point == NULL) {
2777 		fputs("point=(NULL)\n", stderr);
2778 		return;
2779 	}
2780 	if ((x = BN_new()) == NULL || (y = BN_new()) == NULL) {
2781 		fprintf(stderr, "%s: BN_new failed\n", __func__);
2782 		goto out;
2783 	}
2784 	if (EC_POINT_get_affine_coordinates(group, point, x, y, NULL) != 1) {
2785 		fprintf(stderr, "%s: EC_POINT_get_affine_coordinates\n",
2786 		    __func__);
2787 		goto out;
2788 	}
2789 	fputs("x=", stderr);
2790 	BN_print_fp(stderr, x);
2791 	fputs("\ny=", stderr);
2792 	BN_print_fp(stderr, y);
2793 	fputs("\n", stderr);
2794  out:
2795 	BN_clear_free(x);
2796 	BN_clear_free(y);
2797 }
2798 
2799 void
2800 sshkey_dump_ec_key(const EC_KEY *key)
2801 {
2802 	const BIGNUM *exponent;
2803 
2804 	sshkey_dump_ec_point(EC_KEY_get0_group(key),
2805 	    EC_KEY_get0_public_key(key));
2806 	fputs("exponent=", stderr);
2807 	if ((exponent = EC_KEY_get0_private_key(key)) == NULL)
2808 		fputs("(NULL)", stderr);
2809 	else
2810 		BN_print_fp(stderr, EC_KEY_get0_private_key(key));
2811 	fputs("\n", stderr);
2812 }
2813 #endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */
2814 
2815 static int
2816 sshkey_private_to_blob2(struct sshkey *prv, struct sshbuf *blob,
2817     const char *passphrase, const char *comment, const char *ciphername,
2818     int rounds)
2819 {
2820 	u_char *cp, *key = NULL, *pubkeyblob = NULL;
2821 	u_char salt[SALT_LEN];
2822 	size_t i, pubkeylen, keylen, ivlen, blocksize, authlen;
2823 	u_int check;
2824 	int r = SSH_ERR_INTERNAL_ERROR;
2825 	struct sshcipher_ctx *ciphercontext = NULL;
2826 	const struct sshcipher *cipher;
2827 	const char *kdfname = KDFNAME;
2828 	struct sshbuf *encoded = NULL, *encrypted = NULL, *kdf = NULL;
2829 
2830 	if (rounds <= 0)
2831 		rounds = DEFAULT_ROUNDS;
2832 	if (passphrase == NULL || !strlen(passphrase)) {
2833 		ciphername = "none";
2834 		kdfname = "none";
2835 	} else if (ciphername == NULL)
2836 		ciphername = DEFAULT_CIPHERNAME;
2837 	if ((cipher = cipher_by_name(ciphername)) == NULL) {
2838 		r = SSH_ERR_INVALID_ARGUMENT;
2839 		goto out;
2840 	}
2841 
2842 	if ((kdf = sshbuf_new()) == NULL ||
2843 	    (encoded = sshbuf_new()) == NULL ||
2844 	    (encrypted = sshbuf_new()) == NULL) {
2845 		r = SSH_ERR_ALLOC_FAIL;
2846 		goto out;
2847 	}
2848 	blocksize = cipher_blocksize(cipher);
2849 	keylen = cipher_keylen(cipher);
2850 	ivlen = cipher_ivlen(cipher);
2851 	authlen = cipher_authlen(cipher);
2852 	if ((key = calloc(1, keylen + ivlen)) == NULL) {
2853 		r = SSH_ERR_ALLOC_FAIL;
2854 		goto out;
2855 	}
2856 	if (strcmp(kdfname, "bcrypt") == 0) {
2857 		arc4random_buf(salt, SALT_LEN);
2858 		if (bcrypt_pbkdf(passphrase, strlen(passphrase),
2859 		    salt, SALT_LEN, key, keylen + ivlen, rounds) < 0) {
2860 			r = SSH_ERR_INVALID_ARGUMENT;
2861 			goto out;
2862 		}
2863 		if ((r = sshbuf_put_string(kdf, salt, SALT_LEN)) != 0 ||
2864 		    (r = sshbuf_put_u32(kdf, rounds)) != 0)
2865 			goto out;
2866 	} else if (strcmp(kdfname, "none") != 0) {
2867 		/* Unsupported KDF type */
2868 		r = SSH_ERR_KEY_UNKNOWN_CIPHER;
2869 		goto out;
2870 	}
2871 	if ((r = cipher_init(&ciphercontext, cipher, key, keylen,
2872 	    key + keylen, ivlen, 1)) != 0)
2873 		goto out;
2874 
2875 	if ((r = sshbuf_put(encoded, AUTH_MAGIC, sizeof(AUTH_MAGIC))) != 0 ||
2876 	    (r = sshbuf_put_cstring(encoded, ciphername)) != 0 ||
2877 	    (r = sshbuf_put_cstring(encoded, kdfname)) != 0 ||
2878 	    (r = sshbuf_put_stringb(encoded, kdf)) != 0 ||
2879 	    (r = sshbuf_put_u32(encoded, 1)) != 0 ||	/* number of keys */
2880 	    (r = sshkey_to_blob(prv, &pubkeyblob, &pubkeylen)) != 0 ||
2881 	    (r = sshbuf_put_string(encoded, pubkeyblob, pubkeylen)) != 0)
2882 		goto out;
2883 
2884 	/* set up the buffer that will be encrypted */
2885 
2886 	/* Random check bytes */
2887 	check = arc4random();
2888 	if ((r = sshbuf_put_u32(encrypted, check)) != 0 ||
2889 	    (r = sshbuf_put_u32(encrypted, check)) != 0)
2890 		goto out;
2891 
2892 	/* append private key and comment*/
2893 	if ((r = sshkey_private_serialize(prv, encrypted)) != 0 ||
2894 	    (r = sshbuf_put_cstring(encrypted, comment)) != 0)
2895 		goto out;
2896 
2897 	/* padding */
2898 	i = 0;
2899 	while (sshbuf_len(encrypted) % blocksize) {
2900 		if ((r = sshbuf_put_u8(encrypted, ++i & 0xff)) != 0)
2901 			goto out;
2902 	}
2903 
2904 	/* length in destination buffer */
2905 	if ((r = sshbuf_put_u32(encoded, sshbuf_len(encrypted))) != 0)
2906 		goto out;
2907 
2908 	/* encrypt */
2909 	if ((r = sshbuf_reserve(encoded,
2910 	    sshbuf_len(encrypted) + authlen, &cp)) != 0)
2911 		goto out;
2912 	if ((r = cipher_crypt(ciphercontext, 0, cp,
2913 	    sshbuf_ptr(encrypted), sshbuf_len(encrypted), 0, authlen)) != 0)
2914 		goto out;
2915 
2916 	sshbuf_reset(blob);
2917 
2918 	/* assemble uuencoded key */
2919 	if ((r = sshbuf_put(blob, MARK_BEGIN, MARK_BEGIN_LEN)) != 0 ||
2920 	    (r = sshbuf_dtob64(encoded, blob, 1)) != 0 ||
2921 	    (r = sshbuf_put(blob, MARK_END, MARK_END_LEN)) != 0)
2922 		goto out;
2923 
2924 	/* success */
2925 	r = 0;
2926 
2927  out:
2928 	sshbuf_free(kdf);
2929 	sshbuf_free(encoded);
2930 	sshbuf_free(encrypted);
2931 	cipher_free(ciphercontext);
2932 	explicit_bzero(salt, sizeof(salt));
2933 	if (key != NULL)
2934 		freezero(key, keylen + ivlen);
2935 	if (pubkeyblob != NULL)
2936 		freezero(pubkeyblob, pubkeylen);
2937 	return r;
2938 }
2939 
2940 static int
2941 private2_uudecode(struct sshbuf *blob, struct sshbuf **decodedp)
2942 {
2943 	const u_char *cp;
2944 	size_t encoded_len;
2945 	int r;
2946 	u_char last;
2947 	struct sshbuf *encoded = NULL, *decoded = NULL;
2948 
2949 	if (blob == NULL || decodedp == NULL)
2950 		return SSH_ERR_INVALID_ARGUMENT;
2951 
2952 	*decodedp = NULL;
2953 
2954 	if ((encoded = sshbuf_new()) == NULL ||
2955 	    (decoded = sshbuf_new()) == NULL) {
2956 		r = SSH_ERR_ALLOC_FAIL;
2957 		goto out;
2958 	}
2959 
2960 	/* check preamble */
2961 	cp = sshbuf_ptr(blob);
2962 	encoded_len = sshbuf_len(blob);
2963 	if (encoded_len < (MARK_BEGIN_LEN + MARK_END_LEN) ||
2964 	    memcmp(cp, MARK_BEGIN, MARK_BEGIN_LEN) != 0) {
2965 		r = SSH_ERR_INVALID_FORMAT;
2966 		goto out;
2967 	}
2968 	cp += MARK_BEGIN_LEN;
2969 	encoded_len -= MARK_BEGIN_LEN;
2970 
2971 	/* Look for end marker, removing whitespace as we go */
2972 	while (encoded_len > 0) {
2973 		if (*cp != '\n' && *cp != '\r') {
2974 			if ((r = sshbuf_put_u8(encoded, *cp)) != 0)
2975 				goto out;
2976 		}
2977 		last = *cp;
2978 		encoded_len--;
2979 		cp++;
2980 		if (last == '\n') {
2981 			if (encoded_len >= MARK_END_LEN &&
2982 			    memcmp(cp, MARK_END, MARK_END_LEN) == 0) {
2983 				/* \0 terminate */
2984 				if ((r = sshbuf_put_u8(encoded, 0)) != 0)
2985 					goto out;
2986 				break;
2987 			}
2988 		}
2989 	}
2990 	if (encoded_len == 0) {
2991 		r = SSH_ERR_INVALID_FORMAT;
2992 		goto out;
2993 	}
2994 
2995 	/* decode base64 */
2996 	if ((r = sshbuf_b64tod(decoded, (char *)sshbuf_ptr(encoded))) != 0)
2997 		goto out;
2998 
2999 	/* check magic */
3000 	if (sshbuf_len(decoded) < sizeof(AUTH_MAGIC) ||
3001 	    memcmp(sshbuf_ptr(decoded), AUTH_MAGIC, sizeof(AUTH_MAGIC))) {
3002 		r = SSH_ERR_INVALID_FORMAT;
3003 		goto out;
3004 	}
3005 	/* success */
3006 	*decodedp = decoded;
3007 	decoded = NULL;
3008 	r = 0;
3009  out:
3010 	sshbuf_free(encoded);
3011 	sshbuf_free(decoded);
3012 	return r;
3013 }
3014 
3015 static int
3016 private2_decrypt(struct sshbuf *decoded, const char *passphrase,
3017     struct sshbuf **decryptedp, struct sshkey **pubkeyp)
3018 {
3019 	char *ciphername = NULL, *kdfname = NULL;
3020 	const struct sshcipher *cipher = NULL;
3021 	int r = SSH_ERR_INTERNAL_ERROR;
3022 	size_t keylen = 0, ivlen = 0, authlen = 0, slen = 0;
3023 	struct sshbuf *kdf = NULL, *decrypted = NULL;
3024 	struct sshcipher_ctx *ciphercontext = NULL;
3025 	struct sshkey *pubkey = NULL;
3026 	u_char *key = NULL, *salt = NULL, *dp;
3027 	u_int blocksize, rounds, nkeys, encrypted_len, check1, check2;
3028 
3029 	if (decoded == NULL || decryptedp == NULL || pubkeyp == NULL)
3030 		return SSH_ERR_INVALID_ARGUMENT;
3031 
3032 	*decryptedp = NULL;
3033 	*pubkeyp = NULL;
3034 
3035 	if ((decrypted = sshbuf_new()) == NULL) {
3036 		r = SSH_ERR_ALLOC_FAIL;
3037 		goto out;
3038 	}
3039 
3040 	/* parse public portion of key */
3041 	if ((r = sshbuf_consume(decoded, sizeof(AUTH_MAGIC))) != 0 ||
3042 	    (r = sshbuf_get_cstring(decoded, &ciphername, NULL)) != 0 ||
3043 	    (r = sshbuf_get_cstring(decoded, &kdfname, NULL)) != 0 ||
3044 	    (r = sshbuf_froms(decoded, &kdf)) != 0 ||
3045 	    (r = sshbuf_get_u32(decoded, &nkeys)) != 0)
3046 		goto out;
3047 
3048 	if (nkeys != 1) {
3049 		/* XXX only one key supported at present */
3050 		r = SSH_ERR_INVALID_FORMAT;
3051 		goto out;
3052 	}
3053 
3054 	if ((r = sshkey_froms(decoded, &pubkey)) != 0 ||
3055 	    (r = sshbuf_get_u32(decoded, &encrypted_len)) != 0)
3056 		goto out;
3057 
3058 	if ((cipher = cipher_by_name(ciphername)) == NULL) {
3059 		r = SSH_ERR_KEY_UNKNOWN_CIPHER;
3060 		goto out;
3061 	}
3062 	if (strcmp(kdfname, "none") != 0 && strcmp(kdfname, "bcrypt") != 0) {
3063 		r = SSH_ERR_KEY_UNKNOWN_CIPHER;
3064 		goto out;
3065 	}
3066 	if (strcmp(kdfname, "none") == 0 && strcmp(ciphername, "none") != 0) {
3067 		r = SSH_ERR_INVALID_FORMAT;
3068 		goto out;
3069 	}
3070 	if ((passphrase == NULL || strlen(passphrase) == 0) &&
3071 	    strcmp(kdfname, "none") != 0) {
3072 		/* passphrase required */
3073 		r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3074 		goto out;
3075 	}
3076 
3077 	/* check size of encrypted key blob */
3078 	blocksize = cipher_blocksize(cipher);
3079 	if (encrypted_len < blocksize || (encrypted_len % blocksize) != 0) {
3080 		r = SSH_ERR_INVALID_FORMAT;
3081 		goto out;
3082 	}
3083 
3084 	/* setup key */
3085 	keylen = cipher_keylen(cipher);
3086 	ivlen = cipher_ivlen(cipher);
3087 	authlen = cipher_authlen(cipher);
3088 	if ((key = calloc(1, keylen + ivlen)) == NULL) {
3089 		r = SSH_ERR_ALLOC_FAIL;
3090 		goto out;
3091 	}
3092 	if (strcmp(kdfname, "bcrypt") == 0) {
3093 		if ((r = sshbuf_get_string(kdf, &salt, &slen)) != 0 ||
3094 		    (r = sshbuf_get_u32(kdf, &rounds)) != 0)
3095 			goto out;
3096 		if (bcrypt_pbkdf(passphrase, strlen(passphrase), salt, slen,
3097 		    key, keylen + ivlen, rounds) < 0) {
3098 			r = SSH_ERR_INVALID_FORMAT;
3099 			goto out;
3100 		}
3101 	}
3102 
3103 	/* check that an appropriate amount of auth data is present */
3104 	if (sshbuf_len(decoded) < authlen ||
3105 	    sshbuf_len(decoded) - authlen < encrypted_len) {
3106 		r = SSH_ERR_INVALID_FORMAT;
3107 		goto out;
3108 	}
3109 
3110 	/* decrypt private portion of key */
3111 	if ((r = sshbuf_reserve(decrypted, encrypted_len, &dp)) != 0 ||
3112 	    (r = cipher_init(&ciphercontext, cipher, key, keylen,
3113 	    key + keylen, ivlen, 0)) != 0)
3114 		goto out;
3115 	if ((r = cipher_crypt(ciphercontext, 0, dp, sshbuf_ptr(decoded),
3116 	    encrypted_len, 0, authlen)) != 0) {
3117 		/* an integrity error here indicates an incorrect passphrase */
3118 		if (r == SSH_ERR_MAC_INVALID)
3119 			r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3120 		goto out;
3121 	}
3122 	if ((r = sshbuf_consume(decoded, encrypted_len + authlen)) != 0)
3123 		goto out;
3124 	/* there should be no trailing data */
3125 	if (sshbuf_len(decoded) != 0) {
3126 		r = SSH_ERR_INVALID_FORMAT;
3127 		goto out;
3128 	}
3129 
3130 	/* check check bytes */
3131 	if ((r = sshbuf_get_u32(decrypted, &check1)) != 0 ||
3132 	    (r = sshbuf_get_u32(decrypted, &check2)) != 0)
3133 		goto out;
3134 	if (check1 != check2) {
3135 		r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3136 		goto out;
3137 	}
3138 	/* success */
3139 	*decryptedp = decrypted;
3140 	decrypted = NULL;
3141 	*pubkeyp = pubkey;
3142 	pubkey = NULL;
3143 	r = 0;
3144  out:
3145 	cipher_free(ciphercontext);
3146 	free(ciphername);
3147 	free(kdfname);
3148 	sshkey_free(pubkey);
3149 	if (salt != NULL) {
3150 		explicit_bzero(salt, slen);
3151 		free(salt);
3152 	}
3153 	if (key != NULL) {
3154 		explicit_bzero(key, keylen + ivlen);
3155 		free(key);
3156 	}
3157 	sshbuf_free(kdf);
3158 	sshbuf_free(decrypted);
3159 	return r;
3160 }
3161 
3162 static int
3163 sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
3164     struct sshkey **keyp, char **commentp)
3165 {
3166 	char *comment = NULL;
3167 	int r = SSH_ERR_INTERNAL_ERROR;
3168 	struct sshbuf *decoded = NULL, *decrypted = NULL;
3169 	struct sshkey *k = NULL, *pubkey = NULL;
3170 
3171 	if (keyp != NULL)
3172 		*keyp = NULL;
3173 	if (commentp != NULL)
3174 		*commentp = NULL;
3175 
3176 	/* Undo base64 encoding and decrypt the private section */
3177 	if ((r = private2_uudecode(blob, &decoded)) != 0 ||
3178 	    (r = private2_decrypt(decoded, passphrase,
3179 	    &decrypted, &pubkey)) != 0)
3180 		goto out;
3181 
3182 	if (type != KEY_UNSPEC &&
3183 	    sshkey_type_plain(type) != sshkey_type_plain(pubkey->type)) {
3184 		r = SSH_ERR_KEY_TYPE_MISMATCH;
3185 		goto out;
3186 	}
3187 
3188 	/* Load the private key and comment */
3189 	if ((r = sshkey_private_deserialize(decrypted, &k)) != 0 ||
3190 	    (r = sshbuf_get_cstring(decrypted, &comment, NULL)) != 0)
3191 		goto out;
3192 
3193 	/* Check deterministic padding after private section */
3194 	if ((r = private2_check_padding(decrypted)) != 0)
3195 		goto out;
3196 
3197 	/* Check that the public key in the envelope matches the private key */
3198 	if (!sshkey_equal(pubkey, k)) {
3199 		r = SSH_ERR_INVALID_FORMAT;
3200 		goto out;
3201 	}
3202 
3203 	/* success */
3204 	r = 0;
3205 	if (keyp != NULL) {
3206 		*keyp = k;
3207 		k = NULL;
3208 	}
3209 	if (commentp != NULL) {
3210 		*commentp = comment;
3211 		comment = NULL;
3212 	}
3213  out:
3214 	free(comment);
3215 	sshbuf_free(decoded);
3216 	sshbuf_free(decrypted);
3217 	sshkey_free(k);
3218 	sshkey_free(pubkey);
3219 	return r;
3220 }
3221 
3222 static int
3223 sshkey_parse_private2_pubkey(struct sshbuf *blob, int type,
3224     struct sshkey **keyp)
3225 {
3226 	int r = SSH_ERR_INTERNAL_ERROR;
3227 	struct sshbuf *decoded = NULL;
3228 	struct sshkey *pubkey = NULL;
3229 	u_int nkeys = 0;
3230 
3231 	if (keyp != NULL)
3232 		*keyp = NULL;
3233 
3234 	if ((r = private2_uudecode(blob, &decoded)) != 0)
3235 		goto out;
3236 	/* parse public key from unencrypted envelope */
3237 	if ((r = sshbuf_consume(decoded, sizeof(AUTH_MAGIC))) != 0 ||
3238 	    (r = sshbuf_skip_string(decoded)) != 0 || /* cipher */
3239 	    (r = sshbuf_skip_string(decoded)) != 0 || /* KDF alg */
3240 	    (r = sshbuf_skip_string(decoded)) != 0 || /* KDF hint */
3241 	    (r = sshbuf_get_u32(decoded, &nkeys)) != 0)
3242 		goto out;
3243 
3244 	if (nkeys != 1) {
3245 		/* XXX only one key supported at present */
3246 		r = SSH_ERR_INVALID_FORMAT;
3247 		goto out;
3248 	}
3249 
3250 	/* Parse the public key */
3251 	if ((r = sshkey_froms(decoded, &pubkey)) != 0)
3252 		goto out;
3253 
3254 	if (type != KEY_UNSPEC &&
3255 	    sshkey_type_plain(type) != sshkey_type_plain(pubkey->type)) {
3256 		r = SSH_ERR_KEY_TYPE_MISMATCH;
3257 		goto out;
3258 	}
3259 
3260 	/* success */
3261 	r = 0;
3262 	if (keyp != NULL) {
3263 		*keyp = pubkey;
3264 		pubkey = NULL;
3265 	}
3266  out:
3267 	sshbuf_free(decoded);
3268 	sshkey_free(pubkey);
3269 	return r;
3270 }
3271 
3272 #ifdef WITH_OPENSSL
3273 /* convert SSH v2 key to PEM or PKCS#8 format */
3274 static int
3275 sshkey_private_to_blob_pem_pkcs8(struct sshkey *key, struct sshbuf *buf,
3276     int format, const char *_passphrase, const char *comment)
3277 {
3278 	int was_shielded = sshkey_is_shielded(key);
3279 	int success, r;
3280 	int blen, len = strlen(_passphrase);
3281 	u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL;
3282 	const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL;
3283 	char *bptr;
3284 	BIO *bio = NULL;
3285 	struct sshbuf *blob;
3286 	EVP_PKEY *pkey = NULL;
3287 
3288 	if (len > 0 && len <= 4)
3289 		return SSH_ERR_PASSPHRASE_TOO_SHORT;
3290 	if ((blob = sshbuf_new()) == NULL)
3291 		return SSH_ERR_ALLOC_FAIL;
3292 	if ((bio = BIO_new(BIO_s_mem())) == NULL) {
3293 		r = SSH_ERR_ALLOC_FAIL;
3294 		goto out;
3295 	}
3296 	if ((r = sshkey_unshield_private(key)) != 0)
3297 		goto out;
3298 
3299 	switch (key->type) {
3300 #ifdef OPENSSL_HAS_ECC
3301 	case KEY_ECDSA:
3302 		if (format == SSHKEY_PRIVATE_PEM) {
3303 			success = PEM_write_bio_ECPrivateKey(bio,
3304 			    EVP_PKEY_get0_EC_KEY(key->pkey),
3305 			    cipher, passphrase, len, NULL, NULL);
3306 		} else {
3307 			pkey = key->pkey;
3308 			EVP_PKEY_up_ref(key->pkey);
3309 			success = 1;
3310 		}
3311 		break;
3312 #endif
3313 	case KEY_RSA:
3314 		if (format == SSHKEY_PRIVATE_PEM) {
3315 			success = PEM_write_bio_RSAPrivateKey(bio,
3316 			    EVP_PKEY_get0_RSA(key->pkey),
3317 			    cipher, passphrase, len, NULL, NULL);
3318 		} else {
3319 			pkey = key->pkey;
3320 			EVP_PKEY_up_ref(key->pkey);
3321 			success = 1;
3322 		}
3323 		break;
3324 	default:
3325 		success = 0;
3326 		break;
3327 	}
3328 	if (success == 0) {
3329 		r = SSH_ERR_LIBCRYPTO_ERROR;
3330 		goto out;
3331 	}
3332 	if (format == SSHKEY_PRIVATE_PKCS8) {
3333 		if ((success = PEM_write_bio_PrivateKey(bio, pkey, cipher,
3334 		    passphrase, len, NULL, NULL)) == 0) {
3335 			r = SSH_ERR_LIBCRYPTO_ERROR;
3336 			goto out;
3337 		}
3338 	}
3339 	if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0) {
3340 		r = SSH_ERR_INTERNAL_ERROR;
3341 		goto out;
3342 	}
3343 	if ((r = sshbuf_put(blob, bptr, blen)) != 0)
3344 		goto out;
3345 	r = 0;
3346  out:
3347 	if (was_shielded)
3348 		r = sshkey_shield_private(key);
3349 	if (r == 0)
3350 		r = sshbuf_putb(buf, blob);
3351 
3352 	EVP_PKEY_free(pkey);
3353 	sshbuf_free(blob);
3354 	BIO_free(bio);
3355 	return r;
3356 }
3357 #endif /* WITH_OPENSSL */
3358 
3359 /* Serialise "key" to buffer "blob" */
3360 int
3361 sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob,
3362     const char *passphrase, const char *comment,
3363     int format, const char *openssh_format_cipher, int openssh_format_rounds)
3364 {
3365 	switch (key->type) {
3366 #ifdef WITH_OPENSSL
3367 	case KEY_ECDSA:
3368 	case KEY_RSA:
3369 		break; /* see below */
3370 #endif /* WITH_OPENSSL */
3371 	case KEY_ED25519:
3372 	case KEY_ED25519_SK:
3373 #ifdef WITH_OPENSSL
3374 	case KEY_ECDSA_SK:
3375 #endif /* WITH_OPENSSL */
3376 		return sshkey_private_to_blob2(key, blob, passphrase,
3377 		    comment, openssh_format_cipher, openssh_format_rounds);
3378 	default:
3379 		return SSH_ERR_KEY_TYPE_UNKNOWN;
3380 	}
3381 
3382 #ifdef WITH_OPENSSL
3383 	switch (format) {
3384 	case SSHKEY_PRIVATE_OPENSSH:
3385 		return sshkey_private_to_blob2(key, blob, passphrase,
3386 		    comment, openssh_format_cipher, openssh_format_rounds);
3387 	case SSHKEY_PRIVATE_PEM:
3388 	case SSHKEY_PRIVATE_PKCS8:
3389 		return sshkey_private_to_blob_pem_pkcs8(key, blob,
3390 		    format, passphrase, comment);
3391 	default:
3392 		return SSH_ERR_INVALID_ARGUMENT;
3393 	}
3394 #endif /* WITH_OPENSSL */
3395 }
3396 
3397 #ifdef WITH_OPENSSL
3398 static int
3399 translate_libcrypto_error(unsigned long pem_err)
3400 {
3401 	int pem_reason = ERR_GET_REASON(pem_err);
3402 
3403 	switch (ERR_GET_LIB(pem_err)) {
3404 	case ERR_LIB_PEM:
3405 		switch (pem_reason) {
3406 		case PEM_R_BAD_PASSWORD_READ:
3407 #ifdef PEM_R_PROBLEMS_GETTING_PASSWORD
3408 		case PEM_R_PROBLEMS_GETTING_PASSWORD:
3409 #endif
3410 #ifdef PEM_R_BAD_DECRYPT
3411 		case PEM_R_BAD_DECRYPT:
3412 #endif
3413 			return SSH_ERR_KEY_WRONG_PASSPHRASE;
3414 		default:
3415 			return SSH_ERR_INVALID_FORMAT;
3416 		}
3417 	case ERR_LIB_EVP:
3418 		switch (pem_reason) {
3419 #ifdef EVP_R_BAD_DECRYPT
3420 		case EVP_R_BAD_DECRYPT:
3421 			return SSH_ERR_KEY_WRONG_PASSPHRASE;
3422 #endif
3423 #ifdef EVP_R_BN_DECODE_ERROR
3424 		case EVP_R_BN_DECODE_ERROR:
3425 #endif
3426 		case EVP_R_DECODE_ERROR:
3427 #ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR
3428 		case EVP_R_PRIVATE_KEY_DECODE_ERROR:
3429 #endif
3430 			return SSH_ERR_INVALID_FORMAT;
3431 		default:
3432 			return SSH_ERR_LIBCRYPTO_ERROR;
3433 		}
3434 	case ERR_LIB_ASN1:
3435 		return SSH_ERR_INVALID_FORMAT;
3436 	}
3437 	return SSH_ERR_LIBCRYPTO_ERROR;
3438 }
3439 
3440 static void
3441 clear_libcrypto_errors(void)
3442 {
3443 	while (ERR_get_error() != 0)
3444 		;
3445 }
3446 
3447 /*
3448  * Translate OpenSSL error codes to determine whether
3449  * passphrase is required/incorrect.
3450  */
3451 static int
3452 convert_libcrypto_error(void)
3453 {
3454 	/*
3455 	 * Some password errors are reported at the beginning
3456 	 * of the error queue.
3457 	 */
3458 	if (translate_libcrypto_error(ERR_peek_error()) ==
3459 	    SSH_ERR_KEY_WRONG_PASSPHRASE)
3460 		return SSH_ERR_KEY_WRONG_PASSPHRASE;
3461 	return translate_libcrypto_error(ERR_peek_last_error());
3462 }
3463 
3464 static int
3465 pem_passphrase_cb(char *buf, int size, int rwflag, void *u)
3466 {
3467 	char *p = (char *)u;
3468 	size_t len;
3469 
3470 	if (p == NULL || (len = strlen(p)) == 0)
3471 		return -1;
3472 	if (size < 0 || len > (size_t)size)
3473 		return -1;
3474 	memcpy(buf, p, len);
3475 	return (int)len;
3476 }
3477 
3478 static int
3479 sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
3480     const char *passphrase, struct sshkey **keyp)
3481 {
3482 	EVP_PKEY *pk = NULL;
3483 	struct sshkey *prv = NULL;
3484 	BIO *bio = NULL;
3485 	int r;
3486 	RSA *rsa = NULL;
3487 	EC_KEY *ecdsa = NULL;
3488 
3489 	if (keyp != NULL)
3490 		*keyp = NULL;
3491 
3492 	if ((bio = BIO_new(BIO_s_mem())) == NULL || sshbuf_len(blob) > INT_MAX)
3493 		return SSH_ERR_ALLOC_FAIL;
3494 	if (BIO_write(bio, sshbuf_ptr(blob), sshbuf_len(blob)) !=
3495 	    (int)sshbuf_len(blob)) {
3496 		r = SSH_ERR_ALLOC_FAIL;
3497 		goto out;
3498 	}
3499 
3500 	clear_libcrypto_errors();
3501 	if ((pk = PEM_read_bio_PrivateKey(bio, NULL, pem_passphrase_cb,
3502 	    (char *)passphrase)) == NULL) {
3503 		/*
3504 		 * libcrypto may return various ASN.1 errors when attempting
3505 		 * to parse a key with an incorrect passphrase.
3506 		 * Treat all format errors as "incorrect passphrase" if a
3507 		 * passphrase was supplied.
3508 		 */
3509 		if (passphrase != NULL && *passphrase != '\0')
3510 			r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3511 		else
3512 			r = convert_libcrypto_error();
3513 		goto out;
3514 	}
3515 	if (EVP_PKEY_base_id(pk) == EVP_PKEY_RSA &&
3516 	    (type == KEY_UNSPEC || type == KEY_RSA)) {
3517 		if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
3518 			r = SSH_ERR_ALLOC_FAIL;
3519 			goto out;
3520 		}
3521 		if ((rsa = EVP_PKEY_get1_RSA(pk)) == NULL) {
3522 			r = SSH_ERR_LIBCRYPTO_ERROR;
3523 			goto out;
3524 		}
3525 		prv->type = KEY_RSA;
3526 #ifdef DEBUG_PK
3527 		RSA_print_fp(stderr, rsa, 8);
3528 #endif
3529 		if (RSA_blinding_on(rsa, NULL) != 1 ||
3530 		    EVP_PKEY_set1_RSA(pk, rsa) != 1) {
3531 			r = SSH_ERR_LIBCRYPTO_ERROR;
3532 			goto out;
3533 		}
3534 		EVP_PKEY_up_ref(pk);
3535 		prv->pkey = pk;
3536 		if ((r = sshkey_check_rsa_length(prv, 0)) != 0)
3537 			goto out;
3538 #ifdef OPENSSL_HAS_ECC
3539 	} else if (EVP_PKEY_base_id(pk) == EVP_PKEY_EC &&
3540 	    (type == KEY_UNSPEC || type == KEY_ECDSA)) {
3541 		if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
3542 			r = SSH_ERR_ALLOC_FAIL;
3543 			goto out;
3544 		}
3545 		if ((prv->ecdsa_nid = sshkey_ecdsa_fixup_group(pk)) == -1 ||
3546 		    (ecdsa = EVP_PKEY_get1_EC_KEY(pk)) == NULL) {
3547 			r = SSH_ERR_LIBCRYPTO_ERROR;
3548 			goto out;
3549 		}
3550 		prv->type = KEY_ECDSA;
3551 		if (sshkey_curve_nid_to_name(prv->ecdsa_nid) == NULL ||
3552 		    sshkey_ec_validate_public(EC_KEY_get0_group(ecdsa),
3553 		    EC_KEY_get0_public_key(ecdsa)) != 0 ||
3554 		    sshkey_ec_validate_private(ecdsa) != 0) {
3555 			r = SSH_ERR_INVALID_FORMAT;
3556 			goto out;
3557 		}
3558 		EVP_PKEY_up_ref(pk);
3559 		prv->pkey = pk;
3560 #ifdef DEBUG_PK
3561 		if (prv != NULL && prv->pkey != NULL)
3562 			sshkey_dump_ec_key(EVP_PKEY_get0_EC_KEY(prv->pkey));
3563 #endif
3564 #endif /* OPENSSL_HAS_ECC */
3565 #ifdef OPENSSL_HAS_ED25519
3566 	} else if (EVP_PKEY_base_id(pk) == EVP_PKEY_ED25519 &&
3567 	    (type == KEY_UNSPEC || type == KEY_ED25519)) {
3568 		size_t len;
3569 
3570 		if ((prv = sshkey_new(KEY_UNSPEC)) == NULL ||
3571 		    (prv->ed25519_sk = calloc(1, ED25519_SK_SZ)) == NULL ||
3572 		    (prv->ed25519_pk = calloc(1, ED25519_PK_SZ)) == NULL) {
3573 			r = SSH_ERR_ALLOC_FAIL;
3574 			goto out;
3575 		}
3576 		prv->type = KEY_ED25519;
3577 		len = ED25519_PK_SZ;
3578 		if (!EVP_PKEY_get_raw_public_key(pk, prv->ed25519_pk, &len)) {
3579 			r = SSH_ERR_LIBCRYPTO_ERROR;
3580 			goto out;
3581 		}
3582 		if (len != ED25519_PK_SZ) {
3583 			r = SSH_ERR_INVALID_FORMAT;
3584 			goto out;
3585 		}
3586 		len = ED25519_SK_SZ - ED25519_PK_SZ;
3587 		if (!EVP_PKEY_get_raw_private_key(pk, prv->ed25519_sk, &len)) {
3588 			r = SSH_ERR_LIBCRYPTO_ERROR;
3589 			goto out;
3590 		}
3591 		if (len != ED25519_SK_SZ - ED25519_PK_SZ) {
3592 			r = SSH_ERR_INVALID_FORMAT;
3593 			goto out;
3594 		}
3595 		/* Append the public key to our private key */
3596 		memcpy(prv->ed25519_sk + (ED25519_SK_SZ - ED25519_PK_SZ),
3597 		    prv->ed25519_pk, ED25519_PK_SZ);
3598 #ifdef DEBUG_PK
3599 		sshbuf_dump_data(prv->ed25519_sk, ED25519_SK_SZ, stderr);
3600 #endif
3601 #endif /* OPENSSL_HAS_ED25519 */
3602 	} else {
3603 		r = SSH_ERR_INVALID_FORMAT;
3604 		goto out;
3605 	}
3606 	r = 0;
3607 	if (keyp != NULL) {
3608 		*keyp = prv;
3609 		prv = NULL;
3610 	}
3611  out:
3612 	BIO_free(bio);
3613 	EVP_PKEY_free(pk);
3614 	RSA_free(rsa);
3615 #ifdef OPENSSL_HAS_ECC
3616 	EC_KEY_free(ecdsa);
3617 #endif
3618 	sshkey_free(prv);
3619 	return r;
3620 }
3621 #endif /* WITH_OPENSSL */
3622 
3623 int
3624 sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
3625     const char *passphrase, struct sshkey **keyp, char **commentp)
3626 {
3627 	int r = SSH_ERR_INTERNAL_ERROR;
3628 
3629 	if (keyp != NULL)
3630 		*keyp = NULL;
3631 	if (commentp != NULL)
3632 		*commentp = NULL;
3633 
3634 	r = sshkey_parse_private2(blob, type, passphrase, keyp, commentp);
3635 	/* Only fallback to PEM parser if a format error occurred. */
3636 	if (r != SSH_ERR_INVALID_FORMAT)
3637 		return r;
3638 #ifdef WITH_OPENSSL
3639 	return sshkey_parse_private_pem_fileblob(blob, type,
3640 	    passphrase, keyp);
3641 #else
3642 	return SSH_ERR_INVALID_FORMAT;
3643 #endif /* WITH_OPENSSL */
3644 }
3645 
3646 int
3647 sshkey_parse_private_fileblob(struct sshbuf *buffer, const char *passphrase,
3648     struct sshkey **keyp, char **commentp)
3649 {
3650 	if (keyp != NULL)
3651 		*keyp = NULL;
3652 	if (commentp != NULL)
3653 		*commentp = NULL;
3654 
3655 	return sshkey_parse_private_fileblob_type(buffer, KEY_UNSPEC,
3656 	    passphrase, keyp, commentp);
3657 }
3658 
3659 void
3660 sshkey_sig_details_free(struct sshkey_sig_details *details)
3661 {
3662 	freezero(details, sizeof(*details));
3663 }
3664 
3665 int
3666 sshkey_parse_pubkey_from_private_fileblob_type(struct sshbuf *blob, int type,
3667     struct sshkey **pubkeyp)
3668 {
3669 	int r = SSH_ERR_INTERNAL_ERROR;
3670 
3671 	if (pubkeyp != NULL)
3672 		*pubkeyp = NULL;
3673 	/* only new-format private keys bundle a public key inside */
3674 	if ((r = sshkey_parse_private2_pubkey(blob, type, pubkeyp)) != 0)
3675 		return r;
3676 	return 0;
3677 }
3678