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