1/*	$NetBSD: ssh-keygen.c,v 1.46 2023/10/25 20:19:57 christos Exp $	*/
2/* $OpenBSD: ssh-keygen.c,v 1.471 2023/09/04 10:29:58 job Exp $ */
3
4/*
5 * Author: Tatu Ylonen <ylo@cs.hut.fi>
6 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
7 *                    All rights reserved
8 * Identity and host key generation and maintenance.
9 *
10 * As far as I am concerned, the code I have written for this software
11 * can be used freely for any purpose.  Any derived versions of this
12 * software must be clearly marked as such, and if the derived work is
13 * incompatible with the protocol description in the RFC file, it must be
14 * called by a name other than "ssh" or "Secure Shell".
15 */
16
17#include "includes.h"
18__RCSID("$NetBSD: ssh-keygen.c,v 1.46 2023/10/25 20:19:57 christos Exp $");
19#include <sys/types.h>
20#include <sys/socket.h>
21#include <sys/stat.h>
22
23#ifdef WITH_OPENSSL
24#include <openssl/evp.h>
25#include <openssl/pem.h>
26#endif
27
28#include <stdint.h>
29#include <errno.h>
30#include <fcntl.h>
31#include <netdb.h>
32#include <pwd.h>
33#include <stdarg.h>
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37#include <unistd.h>
38#include <limits.h>
39#include <locale.h>
40
41#include "xmalloc.h"
42#include "sshkey.h"
43#include "authfile.h"
44#include "sshbuf.h"
45#include "pathnames.h"
46#include "log.h"
47#include "misc.h"
48#include "match.h"
49#include "hostfile.h"
50#include "dns.h"
51#include "ssh.h"
52#include "ssh2.h"
53#include "ssherr.h"
54#include "atomicio.h"
55#include "krl.h"
56#include "digest.h"
57#include "utf8.h"
58#include "authfd.h"
59#include "sshsig.h"
60#include "ssh-sk.h"
61#include "sk-api.h" /* XXX for SSH_SK_USER_PRESENCE_REQD; remove */
62#include "cipher.h"
63
64#ifdef ENABLE_PKCS11
65#include "ssh-pkcs11.h"
66#endif
67
68#define DEFAULT_KEY_TYPE_NAME "ed25519"
69
70/*
71 * Default number of bits in the RSA, DSA and ECDSA keys.  These value can be
72 * overridden on the command line.
73 *
74 * These values, with the exception of DSA, provide security equivalent to at
75 * least 128 bits of security according to NIST Special Publication 800-57:
76 * Recommendation for Key Management Part 1 rev 4 section 5.6.1.
77 * For DSA it (and FIPS-186-4 section 4.2) specifies that the only size for
78 * which a 160bit hash is acceptable is 1kbit, and since ssh-dss specifies only
79 * SHA1 we limit the DSA key size 1k bits.
80 */
81#define DEFAULT_BITS		3072
82#define DEFAULT_BITS_DSA	1024
83#define DEFAULT_BITS_ECDSA	256
84
85static int quiet = 0;
86
87/* Flag indicating that we just want to see the key fingerprint */
88static int print_fingerprint = 0;
89static int print_bubblebabble = 0;
90
91/* Hash algorithm to use for fingerprints. */
92static int fingerprint_hash = SSH_FP_HASH_DEFAULT;
93
94/* The identity file name, given on the command line or entered by the user. */
95static char identity_file[PATH_MAX];
96static int have_identity = 0;
97
98/* This is set to the passphrase if given on the command line. */
99static char *identity_passphrase = NULL;
100
101/* This is set to the new passphrase if given on the command line. */
102static char *identity_new_passphrase = NULL;
103
104/* Key type when certifying */
105static u_int cert_key_type = SSH2_CERT_TYPE_USER;
106
107/* "key ID" of signed key */
108static char *cert_key_id = NULL;
109
110/* Comma-separated list of principal names for certifying keys */
111static char *cert_principals = NULL;
112
113/* Validity period for certificates */
114static u_int64_t cert_valid_from = 0;
115static u_int64_t cert_valid_to = ~0ULL;
116
117/* Certificate options */
118#define CERTOPT_X_FWD				(1)
119#define CERTOPT_AGENT_FWD			(1<<1)
120#define CERTOPT_PORT_FWD			(1<<2)
121#define CERTOPT_PTY				(1<<3)
122#define CERTOPT_USER_RC				(1<<4)
123#define CERTOPT_NO_REQUIRE_USER_PRESENCE	(1<<5)
124#define CERTOPT_REQUIRE_VERIFY			(1<<6)
125#define CERTOPT_DEFAULT	(CERTOPT_X_FWD|CERTOPT_AGENT_FWD| \
126			 CERTOPT_PORT_FWD|CERTOPT_PTY|CERTOPT_USER_RC)
127static u_int32_t certflags_flags = CERTOPT_DEFAULT;
128static char *certflags_command = NULL;
129static char *certflags_src_addr = NULL;
130
131/* Arbitrary extensions specified by user */
132struct cert_ext {
133	char *key;
134	char *val;
135	int crit;
136};
137static struct cert_ext *cert_ext;
138static size_t ncert_ext;
139
140/* Conversion to/from various formats */
141enum {
142	FMT_RFC4716,
143	FMT_PKCS8,
144	FMT_PEM
145} convert_format = FMT_RFC4716;
146
147static const char *key_type_name = NULL;
148
149/* Load key from this PKCS#11 provider */
150static char *pkcs11provider = NULL;
151
152/* FIDO/U2F provider to use */
153static const char *sk_provider = NULL;
154
155/* Format for writing private keys */
156static int private_key_format = SSHKEY_PRIVATE_OPENSSH;
157
158/* Cipher for new-format private keys */
159static char *openssh_format_cipher = NULL;
160
161/* Number of KDF rounds to derive new format keys. */
162static int rounds = 0;
163
164/* argv0 */
165extern char *__progname;
166
167static char hostname[NI_MAXHOST];
168
169#ifdef WITH_OPENSSL
170/* moduli.c */
171int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *);
172int prime_test(FILE *, FILE *, u_int32_t, u_int32_t, char *, unsigned long,
173    unsigned long);
174#endif
175
176static void
177type_bits_valid(int type, const char *name, u_int32_t *bitsp)
178{
179	if (type == KEY_UNSPEC)
180		fatal("unknown key type %s", key_type_name);
181	if (*bitsp == 0) {
182#ifdef WITH_OPENSSL
183		int nid;
184
185		switch(type) {
186		case KEY_DSA:
187			*bitsp = DEFAULT_BITS_DSA;
188			break;
189		case KEY_ECDSA:
190			if (name != NULL &&
191			    (nid = sshkey_ecdsa_nid_from_name(name)) > 0)
192				*bitsp = sshkey_curve_nid_to_bits(nid);
193			if (*bitsp == 0)
194				*bitsp = DEFAULT_BITS_ECDSA;
195			break;
196		case KEY_RSA:
197			*bitsp = DEFAULT_BITS;
198			break;
199		}
200#endif
201	}
202#ifdef WITH_OPENSSL
203	switch (type) {
204	case KEY_DSA:
205		if (*bitsp != 1024)
206			fatal("Invalid DSA key length: must be 1024 bits");
207		break;
208	case KEY_RSA:
209		if (*bitsp < SSH_RSA_MINIMUM_MODULUS_SIZE)
210			fatal("Invalid RSA key length: minimum is %d bits",
211			    SSH_RSA_MINIMUM_MODULUS_SIZE);
212		else if (*bitsp > OPENSSL_RSA_MAX_MODULUS_BITS)
213			fatal("Invalid RSA key length: maximum is %d bits",
214			    OPENSSL_RSA_MAX_MODULUS_BITS);
215		break;
216	case KEY_ECDSA:
217		if (sshkey_ecdsa_bits_to_nid(*bitsp) == -1)
218			fatal("Invalid ECDSA key length: valid lengths are "
219			    "256, 384 or 521 bits");
220	}
221#endif
222}
223
224/*
225 * Checks whether a file exists and, if so, asks the user whether they wish
226 * to overwrite it.
227 * Returns nonzero if the file does not already exist or if the user agrees to
228 * overwrite, or zero otherwise.
229 */
230static int
231confirm_overwrite(const char *filename)
232{
233	char yesno[3];
234	struct stat st;
235
236	if (stat(filename, &st) != 0)
237		return 1;
238	printf("%s already exists.\n", filename);
239	printf("Overwrite (y/n)? ");
240	fflush(stdout);
241	if (fgets(yesno, sizeof(yesno), stdin) == NULL)
242		return 0;
243	if (yesno[0] != 'y' && yesno[0] != 'Y')
244		return 0;
245	return 1;
246}
247
248static void
249ask_filename(struct passwd *pw, const char *prompt)
250{
251	char buf[1024];
252	const char *name = NULL;
253
254	if (key_type_name == NULL)
255		name = _PATH_SSH_CLIENT_ID_ED25519;
256	else {
257		switch (sshkey_type_from_name(key_type_name)) {
258		case KEY_DSA_CERT:
259		case KEY_DSA:
260			name = _PATH_SSH_CLIENT_ID_DSA;
261			break;
262		case KEY_ECDSA_CERT:
263		case KEY_ECDSA:
264			name = _PATH_SSH_CLIENT_ID_ECDSA;
265			break;
266		case KEY_ECDSA_SK_CERT:
267		case KEY_ECDSA_SK:
268			name = _PATH_SSH_CLIENT_ID_ECDSA_SK;
269			break;
270		case KEY_RSA_CERT:
271		case KEY_RSA:
272			name = _PATH_SSH_CLIENT_ID_RSA;
273			break;
274		case KEY_ED25519:
275		case KEY_ED25519_CERT:
276			name = _PATH_SSH_CLIENT_ID_ED25519;
277			break;
278		case KEY_ED25519_SK:
279		case KEY_ED25519_SK_CERT:
280			name = _PATH_SSH_CLIENT_ID_ED25519_SK;
281			break;
282		case KEY_XMSS:
283		case KEY_XMSS_CERT:
284			name = _PATH_SSH_CLIENT_ID_XMSS;
285			break;
286		default:
287			fatal("bad key type");
288		}
289	}
290	snprintf(identity_file, sizeof(identity_file),
291	    "%s/%s", pw->pw_dir, name);
292	printf("%s (%s): ", prompt, identity_file);
293	fflush(stdout);
294	if (fgets(buf, sizeof(buf), stdin) == NULL)
295		exit(1);
296	buf[strcspn(buf, "\n")] = '\0';
297	if (strcmp(buf, "") != 0)
298		strlcpy(identity_file, buf, sizeof(identity_file));
299	have_identity = 1;
300}
301
302static struct sshkey *
303load_identity(const char *filename, char **commentp)
304{
305	char *pass;
306	struct sshkey *prv;
307	int r;
308
309	if (commentp != NULL)
310		*commentp = NULL;
311	if ((r = sshkey_load_private(filename, "", &prv, commentp)) == 0)
312		return prv;
313	if (r != SSH_ERR_KEY_WRONG_PASSPHRASE)
314		fatal_r(r, "Load key \"%s\"", filename);
315	if (identity_passphrase)
316		pass = xstrdup(identity_passphrase);
317	else
318		pass = read_passphrase("Enter passphrase: ", RP_ALLOW_STDIN);
319	r = sshkey_load_private(filename, pass, &prv, commentp);
320	freezero(pass, strlen(pass));
321	if (r != 0)
322		fatal_r(r, "Load key \"%s\"", filename);
323	return prv;
324}
325
326#define SSH_COM_PUBLIC_BEGIN		"---- BEGIN SSH2 PUBLIC KEY ----"
327#define SSH_COM_PUBLIC_END		"---- END SSH2 PUBLIC KEY ----"
328#define SSH_COM_PRIVATE_BEGIN		"---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----"
329#define	SSH_COM_PRIVATE_KEY_MAGIC	0x3f6ff9eb
330
331#ifdef WITH_OPENSSL
332__dead static void
333do_convert_to_ssh2(struct passwd *pw, struct sshkey *k)
334{
335	struct sshbuf *b;
336	char comment[61], *b64;
337	int r;
338
339	if ((b = sshbuf_new()) == NULL)
340		fatal_f("sshbuf_new failed");
341	if ((r = sshkey_putb(k, b)) != 0)
342		fatal_fr(r, "put key");
343	if ((b64 = sshbuf_dtob64_string(b, 1)) == NULL)
344		fatal_f("sshbuf_dtob64_string failed");
345
346	/* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */
347	snprintf(comment, sizeof(comment),
348	    "%u-bit %s, converted by %s@%s from OpenSSH",
349	    sshkey_size(k), sshkey_type(k),
350	    pw->pw_name, hostname);
351
352	sshkey_free(k);
353	sshbuf_free(b);
354
355	fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN);
356	fprintf(stdout, "Comment: \"%s\"\n%s", comment, b64);
357	fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END);
358	free(b64);
359	exit(0);
360}
361
362__dead static void
363do_convert_to_pkcs8(struct sshkey *k)
364{
365	switch (sshkey_type_plain(k->type)) {
366	case KEY_RSA:
367		if (!PEM_write_RSA_PUBKEY(stdout, k->rsa))
368			fatal("PEM_write_RSA_PUBKEY failed");
369		break;
370	case KEY_DSA:
371		if (!PEM_write_DSA_PUBKEY(stdout, k->dsa))
372			fatal("PEM_write_DSA_PUBKEY failed");
373		break;
374	case KEY_ECDSA:
375		if (!PEM_write_EC_PUBKEY(stdout, k->ecdsa))
376			fatal("PEM_write_EC_PUBKEY failed");
377		break;
378	default:
379		fatal_f("unsupported key type %s", sshkey_type(k));
380	}
381	exit(0);
382}
383
384__dead static void
385do_convert_to_pem(struct sshkey *k)
386{
387	switch (sshkey_type_plain(k->type)) {
388	case KEY_RSA:
389		if (!PEM_write_RSAPublicKey(stdout, k->rsa))
390			fatal("PEM_write_RSAPublicKey failed");
391		break;
392	case KEY_DSA:
393		if (!PEM_write_DSA_PUBKEY(stdout, k->dsa))
394			fatal("PEM_write_DSA_PUBKEY failed");
395		break;
396	case KEY_ECDSA:
397		if (!PEM_write_EC_PUBKEY(stdout, k->ecdsa))
398			fatal("PEM_write_EC_PUBKEY failed");
399		break;
400	default:
401		fatal_f("unsupported key type %s", sshkey_type(k));
402	}
403	exit(0);
404}
405
406__dead static void
407do_convert_to(struct passwd *pw)
408{
409	struct sshkey *k;
410	struct stat st;
411	int r;
412
413	if (!have_identity)
414		ask_filename(pw, "Enter file in which the key is");
415	if (stat(identity_file, &st) == -1)
416		fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
417	if ((r = sshkey_load_public(identity_file, &k, NULL)) != 0)
418		k = load_identity(identity_file, NULL);
419	switch (convert_format) {
420	case FMT_RFC4716:
421		do_convert_to_ssh2(pw, k);
422		break;
423	case FMT_PKCS8:
424		do_convert_to_pkcs8(k);
425		break;
426	case FMT_PEM:
427		do_convert_to_pem(k);
428		break;
429	default:
430		fatal_f("unknown key format %d", convert_format);
431	}
432	exit(0);
433}
434
435/*
436 * This is almost exactly the bignum1 encoding, but with 32 bit for length
437 * instead of 16.
438 */
439static void
440buffer_get_bignum_bits(struct sshbuf *b, BIGNUM *value)
441{
442	u_int bytes, bignum_bits;
443	int r;
444
445	if ((r = sshbuf_get_u32(b, &bignum_bits)) != 0)
446		fatal_fr(r, "parse");
447	bytes = (bignum_bits + 7) / 8;
448	if (sshbuf_len(b) < bytes)
449		fatal_f("input buffer too small: need %d have %zu",
450		    bytes, sshbuf_len(b));
451	if (BN_bin2bn(sshbuf_ptr(b), bytes, value) == NULL)
452		fatal_f("BN_bin2bn failed");
453	if ((r = sshbuf_consume(b, bytes)) != 0)
454		fatal_fr(r, "consume");
455}
456
457static struct sshkey *
458do_convert_private_ssh2(struct sshbuf *b)
459{
460	struct sshkey *key = NULL;
461	char *type, *cipher;
462	const char *alg = NULL;
463	u_char e1, e2, e3, *sig = NULL, data[] = "abcde12345";
464	int r, rlen, ktype;
465	u_int magic, i1, i2, i3, i4;
466	size_t slen;
467	u_long e;
468	BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL;
469	BIGNUM *dsa_pub_key = NULL, *dsa_priv_key = NULL;
470	BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL;
471	BIGNUM *rsa_p = NULL, *rsa_q = NULL, *rsa_iqmp = NULL;
472
473	if ((r = sshbuf_get_u32(b, &magic)) != 0)
474		fatal_fr(r, "parse magic");
475
476	if (magic != SSH_COM_PRIVATE_KEY_MAGIC) {
477		error("bad magic 0x%x != 0x%x", magic,
478		    SSH_COM_PRIVATE_KEY_MAGIC);
479		return NULL;
480	}
481	if ((r = sshbuf_get_u32(b, &i1)) != 0 ||
482	    (r = sshbuf_get_cstring(b, &type, NULL)) != 0 ||
483	    (r = sshbuf_get_cstring(b, &cipher, NULL)) != 0 ||
484	    (r = sshbuf_get_u32(b, &i2)) != 0 ||
485	    (r = sshbuf_get_u32(b, &i3)) != 0 ||
486	    (r = sshbuf_get_u32(b, &i4)) != 0)
487		fatal_fr(r, "parse");
488	debug("ignore (%d %d %d %d)", i1, i2, i3, i4);
489	if (strcmp(cipher, "none") != 0) {
490		error("unsupported cipher %s", cipher);
491		free(cipher);
492		free(type);
493		return NULL;
494	}
495	free(cipher);
496
497	if (strstr(type, "dsa")) {
498		ktype = KEY_DSA;
499	} else if (strstr(type, "rsa")) {
500		ktype = KEY_RSA;
501	} else {
502		free(type);
503		return NULL;
504	}
505	if ((key = sshkey_new(ktype)) == NULL)
506		fatal("sshkey_new failed");
507	free(type);
508
509	switch (key->type) {
510	case KEY_DSA:
511		if ((dsa_p = BN_new()) == NULL ||
512		    (dsa_q = BN_new()) == NULL ||
513		    (dsa_g = BN_new()) == NULL ||
514		    (dsa_pub_key = BN_new()) == NULL ||
515		    (dsa_priv_key = BN_new()) == NULL)
516			fatal_f("BN_new");
517		buffer_get_bignum_bits(b, dsa_p);
518		buffer_get_bignum_bits(b, dsa_g);
519		buffer_get_bignum_bits(b, dsa_q);
520		buffer_get_bignum_bits(b, dsa_pub_key);
521		buffer_get_bignum_bits(b, dsa_priv_key);
522		if (!DSA_set0_pqg(key->dsa, dsa_p, dsa_q, dsa_g))
523			fatal_f("DSA_set0_pqg failed");
524		dsa_p = dsa_q = dsa_g = NULL; /* transferred */
525		if (!DSA_set0_key(key->dsa, dsa_pub_key, dsa_priv_key))
526			fatal_f("DSA_set0_key failed");
527		dsa_pub_key = dsa_priv_key = NULL; /* transferred */
528		break;
529	case KEY_RSA:
530		if ((r = sshbuf_get_u8(b, &e1)) != 0 ||
531		    (e1 < 30 && (r = sshbuf_get_u8(b, &e2)) != 0) ||
532		    (e1 < 30 && (r = sshbuf_get_u8(b, &e3)) != 0))
533			fatal_fr(r, "parse RSA");
534		e = e1;
535		debug("e %lx", e);
536		if (e < 30) {
537			e <<= 8;
538			e += e2;
539			debug("e %lx", e);
540			e <<= 8;
541			e += e3;
542			debug("e %lx", e);
543		}
544		if ((rsa_e = BN_new()) == NULL)
545			fatal_f("BN_new");
546		if (!BN_set_word(rsa_e, e)) {
547			BN_clear_free(rsa_e);
548			sshkey_free(key);
549			return NULL;
550		}
551		if ((rsa_n = BN_new()) == NULL ||
552		    (rsa_d = BN_new()) == NULL ||
553		    (rsa_p = BN_new()) == NULL ||
554		    (rsa_q = BN_new()) == NULL ||
555		    (rsa_iqmp = BN_new()) == NULL)
556			fatal_f("BN_new");
557		buffer_get_bignum_bits(b, rsa_d);
558		buffer_get_bignum_bits(b, rsa_n);
559		buffer_get_bignum_bits(b, rsa_iqmp);
560		buffer_get_bignum_bits(b, rsa_q);
561		buffer_get_bignum_bits(b, rsa_p);
562		if (!RSA_set0_key(key->rsa, rsa_n, rsa_e, rsa_d))
563			fatal_f("RSA_set0_key failed");
564		rsa_n = rsa_e = rsa_d = NULL; /* transferred */
565		if (!RSA_set0_factors(key->rsa, rsa_p, rsa_q))
566			fatal_f("RSA_set0_factors failed");
567		rsa_p = rsa_q = NULL; /* transferred */
568		if ((r = ssh_rsa_complete_crt_parameters(key, rsa_iqmp)) != 0)
569			fatal_fr(r, "generate RSA parameters");
570		BN_clear_free(rsa_iqmp);
571		alg = "rsa-sha2-256";
572		break;
573	}
574	rlen = sshbuf_len(b);
575	if (rlen != 0)
576		error_f("remaining bytes in key blob %d", rlen);
577
578	/* try the key */
579	if ((r = sshkey_sign(key, &sig, &slen, data, sizeof(data),
580	    alg, NULL, NULL, 0)) != 0)
581		error_fr(r, "signing with converted key failed");
582	else if ((r = sshkey_verify(key, sig, slen, data, sizeof(data),
583	    alg, 0, NULL)) != 0)
584		error_fr(r, "verification with converted key failed");
585	if (r != 0) {
586		sshkey_free(key);
587		free(sig);
588		return NULL;
589	}
590	free(sig);
591	return key;
592}
593
594static int
595get_line(FILE *fp, char *line, size_t len)
596{
597	int c;
598	size_t pos = 0;
599
600	line[0] = '\0';
601	while ((c = fgetc(fp)) != EOF) {
602		if (pos >= len - 1)
603			fatal("input line too long.");
604		switch (c) {
605		case '\r':
606			c = fgetc(fp);
607			if (c != EOF && c != '\n' && ungetc(c, fp) == EOF)
608				fatal("unget: %s", strerror(errno));
609			return pos;
610		case '\n':
611			return pos;
612		}
613		line[pos++] = c;
614		line[pos] = '\0';
615	}
616	/* We reached EOF */
617	return -1;
618}
619
620static void
621do_convert_from_ssh2(struct passwd *pw, struct sshkey **k, int *private)
622{
623	int r, blen, escaped = 0;
624	u_int len;
625	char line[1024];
626	struct sshbuf *buf;
627	char encoded[8096];
628	FILE *fp;
629
630	if ((buf = sshbuf_new()) == NULL)
631		fatal("sshbuf_new failed");
632	if ((fp = fopen(identity_file, "r")) == NULL)
633		fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
634	encoded[0] = '\0';
635	while ((blen = get_line(fp, line, sizeof(line))) != -1) {
636		if (blen > 0 && line[blen - 1] == '\\')
637			escaped++;
638		if (strncmp(line, "----", 4) == 0 ||
639		    strstr(line, ": ") != NULL) {
640			if (strstr(line, SSH_COM_PRIVATE_BEGIN) != NULL)
641				*private = 1;
642			if (strstr(line, " END ") != NULL) {
643				break;
644			}
645			/* fprintf(stderr, "ignore: %s", line); */
646			continue;
647		}
648		if (escaped) {
649			escaped--;
650			/* fprintf(stderr, "escaped: %s", line); */
651			continue;
652		}
653		strlcat(encoded, line, sizeof(encoded));
654	}
655	len = strlen(encoded);
656	if (((len % 4) == 3) &&
657	    (encoded[len-1] == '=') &&
658	    (encoded[len-2] == '=') &&
659	    (encoded[len-3] == '='))
660		encoded[len-3] = '\0';
661	if ((r = sshbuf_b64tod(buf, encoded)) != 0)
662		fatal_fr(r, "base64 decode");
663	if (*private) {
664		if ((*k = do_convert_private_ssh2(buf)) == NULL)
665			fatal_f("private key conversion failed");
666	} else if ((r = sshkey_fromb(buf, k)) != 0)
667		fatal_fr(r, "parse key");
668	sshbuf_free(buf);
669	fclose(fp);
670}
671
672static void
673do_convert_from_pkcs8(struct sshkey **k, int *private)
674{
675	EVP_PKEY *pubkey;
676	FILE *fp;
677
678	if ((fp = fopen(identity_file, "r")) == NULL)
679		fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
680	if ((pubkey = PEM_read_PUBKEY(fp, NULL, NULL, NULL)) == NULL) {
681		fatal_f("%s is not a recognised public key format",
682		    identity_file);
683	}
684	fclose(fp);
685	switch (EVP_PKEY_base_id(pubkey)) {
686	case EVP_PKEY_RSA:
687		if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)
688			fatal("sshkey_new failed");
689		(*k)->type = KEY_RSA;
690		(*k)->rsa = EVP_PKEY_get1_RSA(pubkey);
691		break;
692	case EVP_PKEY_DSA:
693		if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)
694			fatal("sshkey_new failed");
695		(*k)->type = KEY_DSA;
696		(*k)->dsa = EVP_PKEY_get1_DSA(pubkey);
697		break;
698	case EVP_PKEY_EC:
699		if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)
700			fatal("sshkey_new failed");
701		(*k)->type = KEY_ECDSA;
702		(*k)->ecdsa = EVP_PKEY_get1_EC_KEY(pubkey);
703		(*k)->ecdsa_nid = sshkey_ecdsa_key_to_nid((*k)->ecdsa);
704		break;
705	default:
706		fatal_f("unsupported pubkey type %d",
707		    EVP_PKEY_base_id(pubkey));
708	}
709	EVP_PKEY_free(pubkey);
710	return;
711}
712
713static void
714do_convert_from_pem(struct sshkey **k, int *private)
715{
716	FILE *fp;
717	RSA *rsa;
718
719	if ((fp = fopen(identity_file, "r")) == NULL)
720		fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
721	if ((rsa = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL)) != NULL) {
722		if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)
723			fatal("sshkey_new failed");
724		(*k)->type = KEY_RSA;
725		(*k)->rsa = rsa;
726		fclose(fp);
727		return;
728	}
729	fatal_f("unrecognised raw private key format");
730}
731
732__dead static void
733do_convert_from(struct passwd *pw)
734{
735	struct sshkey *k = NULL;
736	int r, private = 0, ok = 0;
737	struct stat st;
738
739	if (!have_identity)
740		ask_filename(pw, "Enter file in which the key is");
741	if (stat(identity_file, &st) == -1)
742		fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
743
744	switch (convert_format) {
745	case FMT_RFC4716:
746		do_convert_from_ssh2(pw, &k, &private);
747		break;
748	case FMT_PKCS8:
749		do_convert_from_pkcs8(&k, &private);
750		break;
751	case FMT_PEM:
752		do_convert_from_pem(&k, &private);
753		break;
754	default:
755		fatal_f("unknown key format %d", convert_format);
756	}
757
758	if (!private) {
759		if ((r = sshkey_write(k, stdout)) == 0)
760			ok = 1;
761		if (ok)
762			fprintf(stdout, "\n");
763	} else {
764		switch (k->type) {
765		case KEY_DSA:
766			ok = PEM_write_DSAPrivateKey(stdout, k->dsa, NULL,
767			    NULL, 0, NULL, NULL);
768			break;
769		case KEY_ECDSA:
770			ok = PEM_write_ECPrivateKey(stdout, k->ecdsa, NULL,
771			    NULL, 0, NULL, NULL);
772			break;
773		case KEY_RSA:
774			ok = PEM_write_RSAPrivateKey(stdout, k->rsa, NULL,
775			    NULL, 0, NULL, NULL);
776			break;
777		default:
778			fatal_f("unsupported key type %s", sshkey_type(k));
779		}
780	}
781
782	if (!ok)
783		fatal("key write failed");
784	sshkey_free(k);
785	exit(0);
786}
787#endif
788
789__dead static void
790do_print_public(struct passwd *pw)
791{
792	struct sshkey *prv;
793	struct stat st;
794	int r;
795	char *comment = NULL;
796
797	if (!have_identity)
798		ask_filename(pw, "Enter file in which the key is");
799	if (stat(identity_file, &st) == -1)
800		fatal("%s: %s", identity_file, strerror(errno));
801	prv = load_identity(identity_file, &comment);
802	if ((r = sshkey_write(prv, stdout)) != 0)
803		fatal_fr(r, "write key");
804	if (comment != NULL && *comment != '\0')
805		fprintf(stdout, " %s", comment);
806	fprintf(stdout, "\n");
807	if (sshkey_is_sk(prv)) {
808		debug("sk_application: \"%s\", sk_flags 0x%02x",
809			prv->sk_application, prv->sk_flags);
810	}
811	sshkey_free(prv);
812	free(comment);
813	exit(0);
814}
815
816__dead static void
817do_download(struct passwd *pw)
818{
819#ifdef ENABLE_PKCS11
820	struct sshkey **keys = NULL;
821	int i, nkeys;
822	enum sshkey_fp_rep rep;
823	int fptype;
824	char *fp, *ra, **comments = NULL;
825
826	fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash;
827	rep =    print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT;
828
829	pkcs11_init(1);
830	nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys, &comments);
831	if (nkeys <= 0)
832		fatal("cannot read public key from pkcs11");
833	for (i = 0; i < nkeys; i++) {
834		if (print_fingerprint) {
835			fp = sshkey_fingerprint(keys[i], fptype, rep);
836			ra = sshkey_fingerprint(keys[i], fingerprint_hash,
837			    SSH_FP_RANDOMART);
838			if (fp == NULL || ra == NULL)
839				fatal_f("sshkey_fingerprint fail");
840			printf("%u %s %s (PKCS11 key)\n", sshkey_size(keys[i]),
841			    fp, sshkey_type(keys[i]));
842			if (log_level_get() >= SYSLOG_LEVEL_VERBOSE)
843				printf("%s\n", ra);
844			free(ra);
845			free(fp);
846		} else {
847			(void) sshkey_write(keys[i], stdout); /* XXX check */
848			fprintf(stdout, "%s%s\n",
849			    *(comments[i]) == '\0' ? "" : " ", comments[i]);
850		}
851		free(comments[i]);
852		sshkey_free(keys[i]);
853	}
854	free(comments);
855	free(keys);
856	pkcs11_terminate();
857	exit(0);
858#else
859	fatal("no pkcs11 support");
860#endif /* ENABLE_PKCS11 */
861}
862
863static struct sshkey *
864try_read_key(char **cpp)
865{
866	struct sshkey *ret;
867	int r;
868
869	if ((ret = sshkey_new(KEY_UNSPEC)) == NULL)
870		fatal("sshkey_new failed");
871	if ((r = sshkey_read(ret, cpp)) == 0)
872		return ret;
873	/* Not a key */
874	sshkey_free(ret);
875	return NULL;
876}
877
878static void
879fingerprint_one_key(const struct sshkey *public, const char *comment)
880{
881	char *fp = NULL, *ra = NULL;
882	enum sshkey_fp_rep rep;
883	int fptype;
884
885	fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash;
886	rep =    print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT;
887	fp = sshkey_fingerprint(public, fptype, rep);
888	ra = sshkey_fingerprint(public, fingerprint_hash, SSH_FP_RANDOMART);
889	if (fp == NULL || ra == NULL)
890		fatal_f("sshkey_fingerprint failed");
891	mprintf("%u %s %s (%s)\n", sshkey_size(public), fp,
892	    comment ? comment : "no comment", sshkey_type(public));
893	if (log_level_get() >= SYSLOG_LEVEL_VERBOSE)
894		printf("%s\n", ra);
895	free(ra);
896	free(fp);
897}
898
899static void
900fingerprint_private(const char *path)
901{
902	struct stat st;
903	char *comment = NULL;
904	struct sshkey *privkey = NULL, *pubkey = NULL;
905	int r;
906
907	if (stat(identity_file, &st) == -1)
908		fatal("%s: %s", path, strerror(errno));
909	if ((r = sshkey_load_public(path, &pubkey, &comment)) != 0)
910		debug_r(r, "load public \"%s\"", path);
911	if (pubkey == NULL || comment == NULL || *comment == '\0') {
912		free(comment);
913		if ((r = sshkey_load_private(path, NULL,
914		    &privkey, &comment)) != 0)
915			debug_r(r, "load private \"%s\"", path);
916	}
917	if (pubkey == NULL && privkey == NULL)
918		fatal("%s is not a key file.", path);
919
920	fingerprint_one_key(pubkey == NULL ? privkey : pubkey, comment);
921	sshkey_free(pubkey);
922	sshkey_free(privkey);
923	free(comment);
924}
925
926__dead static void
927do_fingerprint(struct passwd *pw)
928{
929	FILE *f;
930	struct sshkey *public = NULL;
931	char *comment = NULL, *cp, *ep, *line = NULL;
932	size_t linesize = 0;
933	int i, invalid = 1;
934	const char *path;
935	u_long lnum = 0;
936
937	if (!have_identity)
938		ask_filename(pw, "Enter file in which the key is");
939	path = identity_file;
940
941	if (strcmp(identity_file, "-") == 0) {
942		f = stdin;
943		path = "(stdin)";
944	} else if ((f = fopen(path, "r")) == NULL)
945		fatal("%s: %s: %s", __progname, path, strerror(errno));
946
947	while (getline(&line, &linesize, f) != -1) {
948		lnum++;
949		cp = line;
950		cp[strcspn(cp, "\n")] = '\0';
951		/* Trim leading space and comments */
952		cp = line + strspn(line, " \t");
953		if (*cp == '#' || *cp == '\0')
954			continue;
955
956		/*
957		 * Input may be plain keys, private keys, authorized_keys
958		 * or known_hosts.
959		 */
960
961		/*
962		 * Try private keys first. Assume a key is private if
963		 * "SSH PRIVATE KEY" appears on the first line and we're
964		 * not reading from stdin (XXX support private keys on stdin).
965		 */
966		if (lnum == 1 && strcmp(identity_file, "-") != 0 &&
967		    strstr(cp, "PRIVATE KEY") != NULL) {
968			free(line);
969			fclose(f);
970			fingerprint_private(path);
971			exit(0);
972		}
973
974		/*
975		 * If it's not a private key, then this must be prepared to
976		 * accept a public key prefixed with a hostname or options.
977		 * Try a bare key first, otherwise skip the leading stuff.
978		 */
979		comment = NULL;
980		if ((public = try_read_key(&cp)) == NULL) {
981			i = strtol(cp, &ep, 10);
982			if (i == 0 || ep == NULL ||
983			    (*ep != ' ' && *ep != '\t')) {
984				int quoted = 0;
985
986				comment = cp;
987				for (; *cp && (quoted || (*cp != ' ' &&
988				    *cp != '\t')); cp++) {
989					if (*cp == '\\' && cp[1] == '"')
990						cp++;	/* Skip both */
991					else if (*cp == '"')
992						quoted = !quoted;
993				}
994				if (!*cp)
995					continue;
996				*cp++ = '\0';
997			}
998		}
999		/* Retry after parsing leading hostname/key options */
1000		if (public == NULL && (public = try_read_key(&cp)) == NULL) {
1001			debug("%s:%lu: not a public key", path, lnum);
1002			continue;
1003		}
1004
1005		/* Find trailing comment, if any */
1006		for (; *cp == ' ' || *cp == '\t'; cp++)
1007			;
1008		if (*cp != '\0' && *cp != '#')
1009			comment = cp;
1010
1011		fingerprint_one_key(public, comment);
1012		sshkey_free(public);
1013		invalid = 0; /* One good key in the file is sufficient */
1014	}
1015	fclose(f);
1016	free(line);
1017
1018	if (invalid)
1019		fatal("%s is not a public key file.", path);
1020	exit(0);
1021}
1022
1023static void
1024do_gen_all_hostkeys(struct passwd *pw)
1025{
1026	struct {
1027		const char *key_type;
1028		const char *key_type_display;
1029		const char *path;
1030	} key_types[] = {
1031#ifdef WITH_OPENSSL
1032		{ "rsa", "RSA" ,_PATH_HOST_RSA_KEY_FILE },
1033		{ "ecdsa", "ECDSA",_PATH_HOST_ECDSA_KEY_FILE },
1034#endif /* WITH_OPENSSL */
1035		{ "ed25519", "ED25519",_PATH_HOST_ED25519_KEY_FILE },
1036#ifdef WITH_XMSS
1037		{ "xmss", "XMSS",_PATH_HOST_XMSS_KEY_FILE },
1038#endif /* WITH_XMSS */
1039		{ NULL, NULL, NULL }
1040	};
1041
1042	u_int32_t bits = 0;
1043	int first = 0;
1044	struct stat st;
1045	struct sshkey *private, *public;
1046	char comment[1024], *prv_tmp, *pub_tmp, *prv_file, *pub_file;
1047	int i, type, fd, r;
1048
1049	for (i = 0; key_types[i].key_type; i++) {
1050		public = private = NULL;
1051		prv_tmp = pub_tmp = prv_file = pub_file = NULL;
1052
1053		xasprintf(&prv_file, "%s%s",
1054		    identity_file, key_types[i].path);
1055
1056		/* Check whether private key exists and is not zero-length */
1057		if (stat(prv_file, &st) == 0) {
1058			if (st.st_size != 0)
1059				goto next;
1060		} else if (errno != ENOENT) {
1061			error("Could not stat %s: %s", key_types[i].path,
1062			    strerror(errno));
1063			goto failnext;
1064		}
1065
1066		/*
1067		 * Private key doesn't exist or is invalid; proceed with
1068		 * key generation.
1069		 */
1070		xasprintf(&prv_tmp, "%s%s.XXXXXXXXXX",
1071		    identity_file, key_types[i].path);
1072		xasprintf(&pub_tmp, "%s%s.pub.XXXXXXXXXX",
1073		    identity_file, key_types[i].path);
1074		xasprintf(&pub_file, "%s%s.pub",
1075		    identity_file, key_types[i].path);
1076
1077		if (first == 0) {
1078			first = 1;
1079			printf("%s: generating new host keys: ", __progname);
1080		}
1081		printf("%s ", key_types[i].key_type_display);
1082		fflush(stdout);
1083		type = sshkey_type_from_name(key_types[i].key_type);
1084		if ((fd = mkstemp(prv_tmp)) == -1) {
1085			error("Could not save your private key in %s: %s",
1086			    prv_tmp, strerror(errno));
1087			goto failnext;
1088		}
1089		(void)close(fd); /* just using mkstemp() to reserve a name */
1090		bits = 0;
1091		type_bits_valid(type, NULL, &bits);
1092		if ((r = sshkey_generate(type, bits, &private)) != 0) {
1093			error_r(r, "sshkey_generate failed");
1094			goto failnext;
1095		}
1096		if ((r = sshkey_from_private(private, &public)) != 0)
1097			fatal_fr(r, "sshkey_from_private");
1098		snprintf(comment, sizeof comment, "%s@%s", pw->pw_name,
1099		    hostname);
1100		if ((r = sshkey_save_private(private, prv_tmp, "",
1101		    comment, private_key_format, openssh_format_cipher,
1102		    rounds)) != 0) {
1103			error_r(r, "Saving key \"%s\" failed", prv_tmp);
1104			goto failnext;
1105		}
1106		if ((fd = mkstemp(pub_tmp)) == -1) {
1107			error("Could not save your public key in %s: %s",
1108			    pub_tmp, strerror(errno));
1109			goto failnext;
1110		}
1111		(void)fchmod(fd, 0644);
1112		(void)close(fd);
1113		if ((r = sshkey_save_public(public, pub_tmp, comment)) != 0) {
1114			error_r(r, "Unable to save public key to %s",
1115			    identity_file);
1116			goto failnext;
1117		}
1118
1119		/* Rename temporary files to their permanent locations. */
1120		if (rename(pub_tmp, pub_file) != 0) {
1121			error("Unable to move %s into position: %s",
1122			    pub_file, strerror(errno));
1123			goto failnext;
1124		}
1125		if (rename(prv_tmp, prv_file) != 0) {
1126			error("Unable to move %s into position: %s",
1127			    key_types[i].path, strerror(errno));
1128 failnext:
1129			first = 0;
1130			goto next;
1131		}
1132 next:
1133		sshkey_free(private);
1134		sshkey_free(public);
1135		free(prv_tmp);
1136		free(pub_tmp);
1137		free(prv_file);
1138		free(pub_file);
1139	}
1140	if (first != 0)
1141		printf("\n");
1142}
1143
1144struct known_hosts_ctx {
1145	const char *host;	/* Hostname searched for in find/delete case */
1146	FILE *out;		/* Output file, stdout for find_hosts case */
1147	int has_unhashed;	/* When hashing, original had unhashed hosts */
1148	int found_key;		/* For find/delete, host was found */
1149	int invalid;		/* File contained invalid items; don't delete */
1150	int hash_hosts;		/* Hash hostnames as we go */
1151	int find_host;		/* Search for specific hostname */
1152	int delete_host;	/* Delete host from known_hosts */
1153};
1154
1155static int
1156known_hosts_hash(struct hostkey_foreach_line *l, void *_ctx)
1157{
1158	struct known_hosts_ctx *ctx = (struct known_hosts_ctx *)_ctx;
1159	char *hashed, *cp, *hosts, *ohosts;
1160	int has_wild = l->hosts && strcspn(l->hosts, "*?!") != strlen(l->hosts);
1161	int was_hashed = l->hosts && l->hosts[0] == HASH_DELIM;
1162
1163	switch (l->status) {
1164	case HKF_STATUS_OK:
1165	case HKF_STATUS_MATCHED:
1166		/*
1167		 * Don't hash hosts already hashed, with wildcard
1168		 * characters or a CA/revocation marker.
1169		 */
1170		if (was_hashed || has_wild || l->marker != MRK_NONE) {
1171			fprintf(ctx->out, "%s\n", l->line);
1172			if (has_wild && !ctx->find_host) {
1173				logit("%s:%lu: ignoring host name "
1174				    "with wildcard: %.64s", l->path,
1175				    l->linenum, l->hosts);
1176			}
1177			return 0;
1178		}
1179		/*
1180		 * Split any comma-separated hostnames from the host list,
1181		 * hash and store separately.
1182		 */
1183		ohosts = hosts = xstrdup(l->hosts);
1184		while ((cp = strsep(&hosts, ",")) != NULL && *cp != '\0') {
1185			lowercase(cp);
1186			if ((hashed = host_hash(cp, NULL, 0)) == NULL)
1187				fatal("hash_host failed");
1188			fprintf(ctx->out, "%s %s\n", hashed, l->rawkey);
1189			free(hashed);
1190			ctx->has_unhashed = 1;
1191		}
1192		free(ohosts);
1193		return 0;
1194	case HKF_STATUS_INVALID:
1195		/* Retain invalid lines, but mark file as invalid. */
1196		ctx->invalid = 1;
1197		logit("%s:%lu: invalid line", l->path, l->linenum);
1198		/* FALLTHROUGH */
1199	default:
1200		fprintf(ctx->out, "%s\n", l->line);
1201		return 0;
1202	}
1203	/* NOTREACHED */
1204	return -1;
1205}
1206
1207static int
1208known_hosts_find_delete(struct hostkey_foreach_line *l, void *_ctx)
1209{
1210	struct known_hosts_ctx *ctx = (struct known_hosts_ctx *)_ctx;
1211	enum sshkey_fp_rep rep;
1212	int fptype;
1213	char *fp = NULL, *ra = NULL;
1214
1215	fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash;
1216	rep =    print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT;
1217
1218	if (l->status == HKF_STATUS_MATCHED) {
1219		if (ctx->delete_host) {
1220			if (l->marker != MRK_NONE) {
1221				/* Don't remove CA and revocation lines */
1222				fprintf(ctx->out, "%s\n", l->line);
1223			} else {
1224				/*
1225				 * Hostname matches and has no CA/revoke
1226				 * marker, delete it by *not* writing the
1227				 * line to ctx->out.
1228				 */
1229				ctx->found_key = 1;
1230				if (!quiet)
1231					printf("# Host %s found: line %lu\n",
1232					    ctx->host, l->linenum);
1233			}
1234			return 0;
1235		} else if (ctx->find_host) {
1236			ctx->found_key = 1;
1237			if (!quiet) {
1238				printf("# Host %s found: line %lu %s\n",
1239				    ctx->host,
1240				    l->linenum, l->marker == MRK_CA ? "CA" :
1241				    (l->marker == MRK_REVOKE ? "REVOKED" : ""));
1242			}
1243			if (ctx->hash_hosts)
1244				known_hosts_hash(l, ctx);
1245			else if (print_fingerprint) {
1246				fp = sshkey_fingerprint(l->key, fptype, rep);
1247				ra = sshkey_fingerprint(l->key,
1248				    fingerprint_hash, SSH_FP_RANDOMART);
1249				if (fp == NULL || ra == NULL)
1250					fatal_f("sshkey_fingerprint failed");
1251				mprintf("%s %s %s%s%s\n", ctx->host,
1252				    sshkey_type(l->key), fp,
1253				    l->comment[0] ? " " : "",
1254				    l->comment);
1255				if (log_level_get() >= SYSLOG_LEVEL_VERBOSE)
1256					printf("%s\n", ra);
1257				free(ra);
1258				free(fp);
1259			} else
1260				fprintf(ctx->out, "%s\n", l->line);
1261			return 0;
1262		}
1263	} else if (ctx->delete_host) {
1264		/* Retain non-matching hosts when deleting */
1265		if (l->status == HKF_STATUS_INVALID) {
1266			ctx->invalid = 1;
1267			logit("%s:%lu: invalid line", l->path, l->linenum);
1268		}
1269		fprintf(ctx->out, "%s\n", l->line);
1270	}
1271	return 0;
1272}
1273
1274__dead static void
1275do_known_hosts(struct passwd *pw, const char *name, int find_host,
1276    int delete_host, int hash_hosts)
1277{
1278	char *cp, tmp[PATH_MAX], old[PATH_MAX];
1279	int r, fd, oerrno, inplace = 0;
1280	struct known_hosts_ctx ctx;
1281	u_int foreach_options;
1282	struct stat sb;
1283
1284	if (!have_identity) {
1285		cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid);
1286		if (strlcpy(identity_file, cp, sizeof(identity_file)) >=
1287		    sizeof(identity_file))
1288			fatal("Specified known hosts path too long");
1289		free(cp);
1290		have_identity = 1;
1291	}
1292	if (stat(identity_file, &sb) != 0)
1293		fatal("Cannot stat %s: %s", identity_file, strerror(errno));
1294
1295	memset(&ctx, 0, sizeof(ctx));
1296	ctx.out = stdout;
1297	ctx.host = name;
1298	ctx.hash_hosts = hash_hosts;
1299	ctx.find_host = find_host;
1300	ctx.delete_host = delete_host;
1301
1302	/*
1303	 * Find hosts goes to stdout, hash and deletions happen in-place
1304	 * A corner case is ssh-keygen -HF foo, which should go to stdout
1305	 */
1306	if (!find_host && (hash_hosts || delete_host)) {
1307		if (strlcpy(tmp, identity_file, sizeof(tmp)) >= sizeof(tmp) ||
1308		    strlcat(tmp, ".XXXXXXXXXX", sizeof(tmp)) >= sizeof(tmp) ||
1309		    strlcpy(old, identity_file, sizeof(old)) >= sizeof(old) ||
1310		    strlcat(old, ".old", sizeof(old)) >= sizeof(old))
1311			fatal("known_hosts path too long");
1312		umask(077);
1313		if ((fd = mkstemp(tmp)) == -1)
1314			fatal("mkstemp: %s", strerror(errno));
1315		if ((ctx.out = fdopen(fd, "w")) == NULL) {
1316			oerrno = errno;
1317			unlink(tmp);
1318			fatal("fdopen: %s", strerror(oerrno));
1319		}
1320		(void)fchmod(fd, sb.st_mode & 0644);
1321		inplace = 1;
1322	}
1323	/* XXX support identity_file == "-" for stdin */
1324	foreach_options = find_host ? HKF_WANT_MATCH : 0;
1325	foreach_options |= print_fingerprint ? HKF_WANT_PARSE_KEY : 0;
1326	if ((r = hostkeys_foreach(identity_file, (find_host || !hash_hosts) ?
1327	    known_hosts_find_delete : known_hosts_hash, &ctx, name, NULL,
1328	    foreach_options, 0)) != 0) {
1329		if (inplace)
1330			unlink(tmp);
1331		fatal_fr(r, "hostkeys_foreach");
1332	}
1333
1334	if (inplace)
1335		fclose(ctx.out);
1336
1337	if (ctx.invalid) {
1338		error("%s is not a valid known_hosts file.", identity_file);
1339		if (inplace) {
1340			error("Not replacing existing known_hosts "
1341			    "file because of errors");
1342			unlink(tmp);
1343		}
1344		exit(1);
1345	} else if (delete_host && !ctx.found_key) {
1346		logit("Host %s not found in %s", name, identity_file);
1347		if (inplace)
1348			unlink(tmp);
1349	} else if (inplace) {
1350		/* Backup existing file */
1351		if (unlink(old) == -1 && errno != ENOENT)
1352			fatal("unlink %.100s: %s", old, strerror(errno));
1353		if (link(identity_file, old) == -1)
1354			fatal("link %.100s to %.100s: %s", identity_file, old,
1355			    strerror(errno));
1356		/* Move new one into place */
1357		if (rename(tmp, identity_file) == -1) {
1358			error("rename\"%s\" to \"%s\": %s", tmp, identity_file,
1359			    strerror(errno));
1360			unlink(tmp);
1361			unlink(old);
1362			exit(1);
1363		}
1364
1365		printf("%s updated.\n", identity_file);
1366		printf("Original contents retained as %s\n", old);
1367		if (ctx.has_unhashed) {
1368			logit("WARNING: %s contains unhashed entries", old);
1369			logit("Delete this file to ensure privacy "
1370			    "of hostnames");
1371		}
1372	}
1373
1374	exit (find_host && !ctx.found_key);
1375}
1376
1377/*
1378 * Perform changing a passphrase.  The argument is the passwd structure
1379 * for the current user.
1380 */
1381__dead static void
1382do_change_passphrase(struct passwd *pw)
1383{
1384	char *comment;
1385	char *old_passphrase, *passphrase1, *passphrase2;
1386	struct stat st;
1387	struct sshkey *private;
1388	int r;
1389
1390	if (!have_identity)
1391		ask_filename(pw, "Enter file in which the key is");
1392	if (stat(identity_file, &st) == -1)
1393		fatal("%s: %s", identity_file, strerror(errno));
1394	/* Try to load the file with empty passphrase. */
1395	r = sshkey_load_private(identity_file, "", &private, &comment);
1396	if (r == SSH_ERR_KEY_WRONG_PASSPHRASE) {
1397		if (identity_passphrase)
1398			old_passphrase = xstrdup(identity_passphrase);
1399		else
1400			old_passphrase =
1401			    read_passphrase("Enter old passphrase: ",
1402			    RP_ALLOW_STDIN);
1403		r = sshkey_load_private(identity_file, old_passphrase,
1404		    &private, &comment);
1405		freezero(old_passphrase, strlen(old_passphrase));
1406		if (r != 0)
1407			goto badkey;
1408	} else if (r != 0) {
1409 badkey:
1410		fatal_r(r, "Failed to load key %s", identity_file);
1411	}
1412	if (comment)
1413		mprintf("Key has comment '%s'\n", comment);
1414
1415	/* Ask the new passphrase (twice). */
1416	if (identity_new_passphrase) {
1417		passphrase1 = xstrdup(identity_new_passphrase);
1418		passphrase2 = NULL;
1419	} else {
1420		passphrase1 =
1421			read_passphrase("Enter new passphrase (empty for no "
1422			    "passphrase): ", RP_ALLOW_STDIN);
1423		passphrase2 = read_passphrase("Enter same passphrase again: ",
1424		    RP_ALLOW_STDIN);
1425
1426		/* Verify that they are the same. */
1427		if (strcmp(passphrase1, passphrase2) != 0) {
1428			explicit_bzero(passphrase1, strlen(passphrase1));
1429			explicit_bzero(passphrase2, strlen(passphrase2));
1430			free(passphrase1);
1431			free(passphrase2);
1432			printf("Pass phrases do not match.  Try again.\n");
1433			exit(1);
1434		}
1435		/* Destroy the other copy. */
1436		freezero(passphrase2, strlen(passphrase2));
1437	}
1438
1439	/* Save the file using the new passphrase. */
1440	if ((r = sshkey_save_private(private, identity_file, passphrase1,
1441	    comment, private_key_format, openssh_format_cipher, rounds)) != 0) {
1442		error_r(r, "Saving key \"%s\" failed", identity_file);
1443		freezero(passphrase1, strlen(passphrase1));
1444		sshkey_free(private);
1445		free(comment);
1446		exit(1);
1447	}
1448	/* Destroy the passphrase and the copy of the key in memory. */
1449	freezero(passphrase1, strlen(passphrase1));
1450	sshkey_free(private);		 /* Destroys contents */
1451	free(comment);
1452
1453	printf("Your identification has been saved with the new passphrase.\n");
1454	exit(0);
1455}
1456
1457/*
1458 * Print the SSHFP RR.
1459 */
1460static int
1461do_print_resource_record(struct passwd *pw, const char *fname,
1462    const char *hname,
1463    int print_generic, char * const *opts, size_t nopts)
1464{
1465	struct sshkey *public;
1466	char *comment = NULL;
1467	struct stat st;
1468	int r, hash = -1;
1469	size_t i;
1470
1471	for (i = 0; i < nopts; i++) {
1472		if (strncasecmp(opts[i], "hashalg=", 8) == 0) {
1473			if ((hash = ssh_digest_alg_by_name(opts[i] + 8)) == -1)
1474				fatal("Unsupported hash algorithm");
1475		} else {
1476			error("Invalid option \"%s\"", opts[i]);
1477			return SSH_ERR_INVALID_ARGUMENT;
1478		}
1479	}
1480	if (fname == NULL)
1481		fatal_f("no filename");
1482	if (stat(fname, &st) == -1) {
1483		if (errno == ENOENT)
1484			return 0;
1485		fatal("%s: %s", fname, strerror(errno));
1486	}
1487	if ((r = sshkey_load_public(fname, &public, &comment)) != 0)
1488		fatal_r(r, "Failed to read v2 public key from \"%s\"", fname);
1489	export_dns_rr(hname, public, stdout, print_generic, hash);
1490	sshkey_free(public);
1491	free(comment);
1492	return 1;
1493}
1494
1495/*
1496 * Change the comment of a private key file.
1497 */
1498__dead static void
1499do_change_comment(struct passwd *pw, const char *identity_comment)
1500{
1501	char new_comment[1024], *comment, *passphrase;
1502	struct sshkey *private;
1503	struct sshkey *public;
1504	struct stat st;
1505	int r;
1506
1507	if (!have_identity)
1508		ask_filename(pw, "Enter file in which the key is");
1509	if (stat(identity_file, &st) == -1)
1510		fatal("%s: %s", identity_file, strerror(errno));
1511	if ((r = sshkey_load_private(identity_file, "",
1512	    &private, &comment)) == 0)
1513		passphrase = xstrdup("");
1514	else if (r != SSH_ERR_KEY_WRONG_PASSPHRASE)
1515		fatal_r(r, "Cannot load private key \"%s\"", identity_file);
1516	else {
1517		if (identity_passphrase)
1518			passphrase = xstrdup(identity_passphrase);
1519		else if (identity_new_passphrase)
1520			passphrase = xstrdup(identity_new_passphrase);
1521		else
1522			passphrase = read_passphrase("Enter passphrase: ",
1523			    RP_ALLOW_STDIN);
1524		/* Try to load using the passphrase. */
1525		if ((r = sshkey_load_private(identity_file, passphrase,
1526		    &private, &comment)) != 0) {
1527			freezero(passphrase, strlen(passphrase));
1528			fatal_r(r, "Cannot load private key \"%s\"",
1529			    identity_file);
1530		}
1531	}
1532
1533	if (private->type != KEY_ED25519 && private->type != KEY_XMSS &&
1534	    private_key_format != SSHKEY_PRIVATE_OPENSSH) {
1535		error("Comments are only supported for keys stored in "
1536		    "the new format (-o).");
1537		explicit_bzero(passphrase, strlen(passphrase));
1538		sshkey_free(private);
1539		exit(1);
1540	}
1541	if (comment)
1542		printf("Old comment: %s\n", comment);
1543	else
1544		printf("No existing comment\n");
1545
1546	if (identity_comment) {
1547		strlcpy(new_comment, identity_comment, sizeof(new_comment));
1548	} else {
1549		printf("New comment: ");
1550		fflush(stdout);
1551		if (!fgets(new_comment, sizeof(new_comment), stdin)) {
1552			explicit_bzero(passphrase, strlen(passphrase));
1553			sshkey_free(private);
1554			exit(1);
1555		}
1556		new_comment[strcspn(new_comment, "\n")] = '\0';
1557	}
1558	if (comment != NULL && strcmp(comment, new_comment) == 0) {
1559		printf("No change to comment\n");
1560		free(passphrase);
1561		sshkey_free(private);
1562		free(comment);
1563		exit(0);
1564	}
1565
1566	/* Save the file using the new passphrase. */
1567	if ((r = sshkey_save_private(private, identity_file, passphrase,
1568	    new_comment, private_key_format, openssh_format_cipher,
1569	    rounds)) != 0) {
1570		error_r(r, "Saving key \"%s\" failed", identity_file);
1571		freezero(passphrase, strlen(passphrase));
1572		sshkey_free(private);
1573		free(comment);
1574		exit(1);
1575	}
1576	freezero(passphrase, strlen(passphrase));
1577	if ((r = sshkey_from_private(private, &public)) != 0)
1578		fatal_fr(r, "sshkey_from_private");
1579	sshkey_free(private);
1580
1581	strlcat(identity_file, ".pub", sizeof(identity_file));
1582	if ((r = sshkey_save_public(public, identity_file, new_comment)) != 0)
1583		fatal_r(r, "Unable to save public key to %s", identity_file);
1584	sshkey_free(public);
1585	free(comment);
1586
1587	if (strlen(new_comment) > 0)
1588		printf("Comment '%s' applied\n", new_comment);
1589	else
1590		printf("Comment removed\n");
1591
1592	exit(0);
1593}
1594
1595static void
1596cert_ext_add(const char *key, const char *value, int iscrit)
1597{
1598	cert_ext = xreallocarray(cert_ext, ncert_ext + 1, sizeof(*cert_ext));
1599	cert_ext[ncert_ext].key = xstrdup(key);
1600	cert_ext[ncert_ext].val = value == NULL ? NULL : xstrdup(value);
1601	cert_ext[ncert_ext].crit = iscrit;
1602	ncert_ext++;
1603}
1604
1605/* qsort(3) comparison function for certificate extensions */
1606static int
1607cert_ext_cmp(const void *_a, const void *_b)
1608{
1609	const struct cert_ext *a = (const struct cert_ext *)_a;
1610	const struct cert_ext *b = (const struct cert_ext *)_b;
1611	int r;
1612
1613	if (a->crit != b->crit)
1614		return (a->crit < b->crit) ? -1 : 1;
1615	if ((r = strcmp(a->key, b->key)) != 0)
1616		return r;
1617	if ((a->val == NULL) != (b->val == NULL))
1618		return (a->val == NULL) ? -1 : 1;
1619	if (a->val != NULL && (r = strcmp(a->val, b->val)) != 0)
1620		return r;
1621	return 0;
1622}
1623
1624#define OPTIONS_CRITICAL	1
1625#define OPTIONS_EXTENSIONS	2
1626static void
1627prepare_options_buf(struct sshbuf *c, int which)
1628{
1629	struct sshbuf *b;
1630	size_t i;
1631	int r;
1632	const struct cert_ext *ext;
1633
1634	if ((b = sshbuf_new()) == NULL)
1635		fatal_f("sshbuf_new failed");
1636	sshbuf_reset(c);
1637	for (i = 0; i < ncert_ext; i++) {
1638		ext = &cert_ext[i];
1639		if ((ext->crit && (which & OPTIONS_EXTENSIONS)) ||
1640		    (!ext->crit && (which & OPTIONS_CRITICAL)))
1641			continue;
1642		if (ext->val == NULL) {
1643			/* flag option */
1644			debug3_f("%s", ext->key);
1645			if ((r = sshbuf_put_cstring(c, ext->key)) != 0 ||
1646			    (r = sshbuf_put_string(c, NULL, 0)) != 0)
1647				fatal_fr(r, "prepare flag");
1648		} else {
1649			/* key/value option */
1650			debug3_f("%s=%s", ext->key, ext->val);
1651			sshbuf_reset(b);
1652			if ((r = sshbuf_put_cstring(c, ext->key)) != 0 ||
1653			    (r = sshbuf_put_cstring(b, ext->val)) != 0 ||
1654			    (r = sshbuf_put_stringb(c, b)) != 0)
1655				fatal_fr(r, "prepare k/v");
1656		}
1657	}
1658	sshbuf_free(b);
1659}
1660
1661static void
1662finalise_cert_exts(void)
1663{
1664	/* critical options */
1665	if (certflags_command != NULL)
1666		cert_ext_add("force-command", certflags_command, 1);
1667	if (certflags_src_addr != NULL)
1668		cert_ext_add("source-address", certflags_src_addr, 1);
1669	if ((certflags_flags & CERTOPT_REQUIRE_VERIFY) != 0)
1670		cert_ext_add("verify-required", NULL, 1);
1671	/* extensions */
1672	if ((certflags_flags & CERTOPT_X_FWD) != 0)
1673		cert_ext_add("permit-X11-forwarding", NULL, 0);
1674	if ((certflags_flags & CERTOPT_AGENT_FWD) != 0)
1675		cert_ext_add("permit-agent-forwarding", NULL, 0);
1676	if ((certflags_flags & CERTOPT_PORT_FWD) != 0)
1677		cert_ext_add("permit-port-forwarding", NULL, 0);
1678	if ((certflags_flags & CERTOPT_PTY) != 0)
1679		cert_ext_add("permit-pty", NULL, 0);
1680	if ((certflags_flags & CERTOPT_USER_RC) != 0)
1681		cert_ext_add("permit-user-rc", NULL, 0);
1682	if ((certflags_flags & CERTOPT_NO_REQUIRE_USER_PRESENCE) != 0)
1683		cert_ext_add("no-touch-required", NULL, 0);
1684	/* order lexically by key */
1685	if (ncert_ext > 0)
1686		qsort(cert_ext, ncert_ext, sizeof(*cert_ext), cert_ext_cmp);
1687}
1688
1689static struct sshkey *
1690load_pkcs11_key(char *path)
1691{
1692#ifdef ENABLE_PKCS11
1693	struct sshkey **keys = NULL, *public, *private = NULL;
1694	int r, i, nkeys;
1695
1696	if ((r = sshkey_load_public(path, &public, NULL)) != 0)
1697		fatal_r(r, "Couldn't load CA public key \"%s\"", path);
1698
1699	nkeys = pkcs11_add_provider(pkcs11provider, identity_passphrase,
1700	    &keys, NULL);
1701	debug3_f("%d keys", nkeys);
1702	if (nkeys <= 0)
1703		fatal("cannot read public key from pkcs11");
1704	for (i = 0; i < nkeys; i++) {
1705		if (sshkey_equal_public(public, keys[i])) {
1706			private = keys[i];
1707			continue;
1708		}
1709		sshkey_free(keys[i]);
1710	}
1711	free(keys);
1712	sshkey_free(public);
1713	return private;
1714#else
1715	fatal("no pkcs11 support");
1716#endif /* ENABLE_PKCS11 */
1717}
1718
1719/* Signer for sshkey_certify_custom that uses the agent */
1720static int
1721agent_signer(struct sshkey *key, u_char **sigp, size_t *lenp,
1722    const u_char *data, size_t datalen,
1723    const char *alg, const char *provider, const char *pin,
1724    u_int compat, void *ctx)
1725{
1726	int *agent_fdp = (int *)ctx;
1727
1728	return ssh_agent_sign(*agent_fdp, key, sigp, lenp,
1729	    data, datalen, alg, compat);
1730}
1731
1732__dead static void
1733do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent,
1734    unsigned long long cert_serial, int cert_serial_autoinc,
1735    int argc, char **argv)
1736{
1737	int r, i, found, agent_fd = -1;
1738	u_int n;
1739	struct sshkey *ca, *public;
1740	char valid[64], *otmp, *tmp, *cp, *out, *comment;
1741	char *ca_fp = NULL, **plist = NULL, *pin = NULL;
1742	struct ssh_identitylist *agent_ids;
1743	size_t j;
1744	struct notifier_ctx *notifier = NULL;
1745
1746#ifdef ENABLE_PKCS11
1747	pkcs11_init(1);
1748#endif
1749	tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
1750	if (pkcs11provider != NULL) {
1751		/* If a PKCS#11 token was specified then try to use it */
1752		if ((ca = load_pkcs11_key(tmp)) == NULL)
1753			fatal("No PKCS#11 key matching %s found", ca_key_path);
1754	} else if (prefer_agent) {
1755		/*
1756		 * Agent signature requested. Try to use agent after making
1757		 * sure the public key specified is actually present in the
1758		 * agent.
1759		 */
1760		if ((r = sshkey_load_public(tmp, &ca, NULL)) != 0)
1761			fatal_r(r, "Cannot load CA public key %s", tmp);
1762		if ((r = ssh_get_authentication_socket(&agent_fd)) != 0)
1763			fatal_r(r, "Cannot use public key for CA signature");
1764		if ((r = ssh_fetch_identitylist(agent_fd, &agent_ids)) != 0)
1765			fatal_r(r, "Retrieve agent key list");
1766		found = 0;
1767		for (j = 0; j < agent_ids->nkeys; j++) {
1768			if (sshkey_equal(ca, agent_ids->keys[j])) {
1769				found = 1;
1770				break;
1771			}
1772		}
1773		if (!found)
1774			fatal("CA key %s not found in agent", tmp);
1775		ssh_free_identitylist(agent_ids);
1776		ca->flags |= SSHKEY_FLAG_EXT;
1777	} else {
1778		/* CA key is assumed to be a private key on the filesystem */
1779		ca = load_identity(tmp, NULL);
1780		if (sshkey_is_sk(ca) &&
1781		    (ca->sk_flags & SSH_SK_USER_VERIFICATION_REQD)) {
1782			if ((pin = read_passphrase("Enter PIN for CA key: ",
1783			    RP_ALLOW_STDIN)) == NULL)
1784				fatal_f("couldn't read PIN");
1785		}
1786	}
1787	free(tmp);
1788
1789	if (key_type_name != NULL) {
1790		if (sshkey_type_from_name(key_type_name) != ca->type) {
1791			fatal("CA key type %s doesn't match specified %s",
1792			    sshkey_ssh_name(ca), key_type_name);
1793		}
1794	} else if (ca->type == KEY_RSA) {
1795		/* Default to a good signature algorithm */
1796		key_type_name = "rsa-sha2-512";
1797	}
1798	ca_fp = sshkey_fingerprint(ca, fingerprint_hash, SSH_FP_DEFAULT);
1799
1800	finalise_cert_exts();
1801	for (i = 0; i < argc; i++) {
1802		/* Split list of principals */
1803		n = 0;
1804		if (cert_principals != NULL) {
1805			otmp = tmp = xstrdup(cert_principals);
1806			plist = NULL;
1807			for (; (cp = strsep(&tmp, ",")) != NULL; n++) {
1808				plist = xreallocarray(plist, n + 1, sizeof(*plist));
1809				if (*(plist[n] = xstrdup(cp)) == '\0')
1810					fatal("Empty principal name");
1811			}
1812			free(otmp);
1813		}
1814		if (n > SSHKEY_CERT_MAX_PRINCIPALS)
1815			fatal("Too many certificate principals specified");
1816
1817		tmp = tilde_expand_filename(argv[i], pw->pw_uid);
1818		if ((r = sshkey_load_public(tmp, &public, &comment)) != 0)
1819			fatal_r(r, "load pubkey \"%s\"", tmp);
1820		if (sshkey_is_cert(public))
1821			fatal_f("key \"%s\" type %s cannot be certified",
1822			    tmp, sshkey_type(public));
1823
1824		/* Prepare certificate to sign */
1825		if ((r = sshkey_to_certified(public)) != 0)
1826			fatal_r(r, "Could not upgrade key %s to certificate", tmp);
1827		public->cert->type = cert_key_type;
1828		public->cert->serial = (u_int64_t)cert_serial;
1829		public->cert->key_id = xstrdup(cert_key_id);
1830		public->cert->nprincipals = n;
1831		public->cert->principals = plist;
1832		public->cert->valid_after = cert_valid_from;
1833		public->cert->valid_before = cert_valid_to;
1834		prepare_options_buf(public->cert->critical, OPTIONS_CRITICAL);
1835		prepare_options_buf(public->cert->extensions,
1836		    OPTIONS_EXTENSIONS);
1837		if ((r = sshkey_from_private(ca,
1838		    &public->cert->signature_key)) != 0)
1839			fatal_r(r, "sshkey_from_private (ca key)");
1840
1841		if (agent_fd != -1 && (ca->flags & SSHKEY_FLAG_EXT) != 0) {
1842			if ((r = sshkey_certify_custom(public, ca,
1843			    key_type_name, sk_provider, NULL, agent_signer,
1844			    &agent_fd)) != 0)
1845				fatal_r(r, "Couldn't certify %s via agent", tmp);
1846		} else {
1847			if (sshkey_is_sk(ca) &&
1848			    (ca->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {
1849				notifier = notify_start(0,
1850				    "Confirm user presence for key %s %s",
1851				    sshkey_type(ca), ca_fp);
1852			}
1853			r = sshkey_certify(public, ca, key_type_name,
1854			    sk_provider, pin);
1855			notify_complete(notifier, "User presence confirmed");
1856			if (r != 0)
1857				fatal_r(r, "Couldn't certify key %s", tmp);
1858		}
1859
1860		if ((cp = strrchr(tmp, '.')) != NULL && strcmp(cp, ".pub") == 0)
1861			*cp = '\0';
1862		xasprintf(&out, "%s-cert.pub", tmp);
1863		free(tmp);
1864
1865		if ((r = sshkey_save_public(public, out, comment)) != 0) {
1866			fatal_r(r, "Unable to save public key to %s",
1867			    identity_file);
1868		}
1869
1870		if (!quiet) {
1871			sshkey_format_cert_validity(public->cert,
1872			    valid, sizeof(valid));
1873			logit("Signed %s key %s: id \"%s\" serial %llu%s%s "
1874			    "valid %s", sshkey_cert_type(public),
1875			    out, public->cert->key_id,
1876			    (unsigned long long)public->cert->serial,
1877			    cert_principals != NULL ? " for " : "",
1878			    cert_principals != NULL ? cert_principals : "",
1879			    valid);
1880		}
1881
1882		sshkey_free(public);
1883		free(out);
1884		if (cert_serial_autoinc)
1885			cert_serial++;
1886	}
1887	if (pin != NULL)
1888		freezero(pin, strlen(pin));
1889	free(ca_fp);
1890#ifdef ENABLE_PKCS11
1891	pkcs11_terminate();
1892#endif
1893	exit(0);
1894}
1895
1896static u_int64_t
1897parse_relative_time(const char *s, time_t now)
1898{
1899	int64_t mul, secs;
1900
1901	mul = *s == '-' ? -1 : 1;
1902
1903	if ((secs = convtime(s + 1)) == -1)
1904		fatal("Invalid relative certificate time %s", s);
1905	if (mul == -1 && secs > now)
1906		fatal("Certificate time %s cannot be represented", s);
1907	return now + (u_int64_t)(secs * mul);
1908}
1909
1910static void
1911parse_hex_u64(const char *s, uint64_t *up)
1912{
1913	char *ep;
1914	unsigned long long ull;
1915
1916	errno = 0;
1917	ull = strtoull(s, &ep, 16);
1918	if (*s == '\0' || *ep != '\0')
1919		fatal("Invalid certificate time: not a number");
1920	if (errno == ERANGE && ull == ULONG_MAX)
1921		fatal_fr(SSH_ERR_SYSTEM_ERROR, "Invalid certificate time");
1922	*up = (uint64_t)ull;
1923}
1924
1925static void
1926parse_cert_times(char *timespec)
1927{
1928	char *from, *to;
1929	time_t now = time(NULL);
1930	int64_t secs;
1931
1932	/* +timespec relative to now */
1933	if (*timespec == '+' && strchr(timespec, ':') == NULL) {
1934		if ((secs = convtime(timespec + 1)) == -1)
1935			fatal("Invalid relative certificate life %s", timespec);
1936		cert_valid_to = now + secs;
1937		/*
1938		 * Backdate certificate one minute to avoid problems on hosts
1939		 * with poorly-synchronised clocks.
1940		 */
1941		cert_valid_from = ((now - 59)/ 60) * 60;
1942		return;
1943	}
1944
1945	/*
1946	 * from:to, where
1947	 * from := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS | 0x... | "always"
1948	 *   to := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS | 0x... | "forever"
1949	 */
1950	from = xstrdup(timespec);
1951	to = strchr(from, ':');
1952	if (to == NULL || from == to || *(to + 1) == '\0')
1953		fatal("Invalid certificate life specification %s", timespec);
1954	*to++ = '\0';
1955
1956	if (*from == '-' || *from == '+')
1957		cert_valid_from = parse_relative_time(from, now);
1958	else if (strcmp(from, "always") == 0)
1959		cert_valid_from = 0;
1960	else if (strncmp(from, "0x", 2) == 0)
1961		parse_hex_u64(from, &cert_valid_from);
1962	else if (parse_absolute_time(from, &cert_valid_from) != 0)
1963		fatal("Invalid from time \"%s\"", from);
1964
1965	if (*to == '-' || *to == '+')
1966		cert_valid_to = parse_relative_time(to, now);
1967	else if (strcmp(to, "forever") == 0)
1968		cert_valid_to = ~(u_int64_t)0;
1969	else if (strncmp(to, "0x", 2) == 0)
1970		parse_hex_u64(to, &cert_valid_to);
1971	else if (parse_absolute_time(to, &cert_valid_to) != 0)
1972		fatal("Invalid to time \"%s\"", to);
1973
1974	if (cert_valid_to <= cert_valid_from)
1975		fatal("Empty certificate validity interval");
1976	free(from);
1977}
1978
1979static void
1980add_cert_option(char *opt)
1981{
1982	char *val, *cp;
1983	int iscrit = 0;
1984
1985	if (strcasecmp(opt, "clear") == 0)
1986		certflags_flags = 0;
1987	else if (strcasecmp(opt, "no-x11-forwarding") == 0)
1988		certflags_flags &= ~CERTOPT_X_FWD;
1989	else if (strcasecmp(opt, "permit-x11-forwarding") == 0)
1990		certflags_flags |= CERTOPT_X_FWD;
1991	else if (strcasecmp(opt, "no-agent-forwarding") == 0)
1992		certflags_flags &= ~CERTOPT_AGENT_FWD;
1993	else if (strcasecmp(opt, "permit-agent-forwarding") == 0)
1994		certflags_flags |= CERTOPT_AGENT_FWD;
1995	else if (strcasecmp(opt, "no-port-forwarding") == 0)
1996		certflags_flags &= ~CERTOPT_PORT_FWD;
1997	else if (strcasecmp(opt, "permit-port-forwarding") == 0)
1998		certflags_flags |= CERTOPT_PORT_FWD;
1999	else if (strcasecmp(opt, "no-pty") == 0)
2000		certflags_flags &= ~CERTOPT_PTY;
2001	else if (strcasecmp(opt, "permit-pty") == 0)
2002		certflags_flags |= CERTOPT_PTY;
2003	else if (strcasecmp(opt, "no-user-rc") == 0)
2004		certflags_flags &= ~CERTOPT_USER_RC;
2005	else if (strcasecmp(opt, "permit-user-rc") == 0)
2006		certflags_flags |= CERTOPT_USER_RC;
2007	else if (strcasecmp(opt, "touch-required") == 0)
2008		certflags_flags &= ~CERTOPT_NO_REQUIRE_USER_PRESENCE;
2009	else if (strcasecmp(opt, "no-touch-required") == 0)
2010		certflags_flags |= CERTOPT_NO_REQUIRE_USER_PRESENCE;
2011	else if (strcasecmp(opt, "no-verify-required") == 0)
2012		certflags_flags &= ~CERTOPT_REQUIRE_VERIFY;
2013	else if (strcasecmp(opt, "verify-required") == 0)
2014		certflags_flags |= CERTOPT_REQUIRE_VERIFY;
2015	else if (strncasecmp(opt, "force-command=", 14) == 0) {
2016		val = opt + 14;
2017		if (*val == '\0')
2018			fatal("Empty force-command option");
2019		if (certflags_command != NULL)
2020			fatal("force-command already specified");
2021		certflags_command = xstrdup(val);
2022	} else if (strncasecmp(opt, "source-address=", 15) == 0) {
2023		val = opt + 15;
2024		if (*val == '\0')
2025			fatal("Empty source-address option");
2026		if (certflags_src_addr != NULL)
2027			fatal("source-address already specified");
2028		if (addr_match_cidr_list(NULL, val) != 0)
2029			fatal("Invalid source-address list");
2030		certflags_src_addr = xstrdup(val);
2031	} else if (strncasecmp(opt, "extension:", 10) == 0 ||
2032		    (iscrit = (strncasecmp(opt, "critical:", 9) == 0))) {
2033		val = xstrdup(strchr(opt, ':') + 1);
2034		if ((cp = strchr(val, '=')) != NULL)
2035			*cp++ = '\0';
2036		cert_ext_add(val, cp, iscrit);
2037		free(val);
2038	} else
2039		fatal("Unsupported certificate option \"%s\"", opt);
2040}
2041
2042static void
2043show_options(struct sshbuf *optbuf, int in_critical)
2044{
2045	char *name, *arg, *hex;
2046	struct sshbuf *options, *option = NULL;
2047	int r;
2048
2049	if ((options = sshbuf_fromb(optbuf)) == NULL)
2050		fatal_f("sshbuf_fromb failed");
2051	while (sshbuf_len(options) != 0) {
2052		sshbuf_free(option);
2053		option = NULL;
2054		if ((r = sshbuf_get_cstring(options, &name, NULL)) != 0 ||
2055		    (r = sshbuf_froms(options, &option)) != 0)
2056			fatal_fr(r, "parse option");
2057		printf("                %s", name);
2058		if (!in_critical &&
2059		    (strcmp(name, "permit-X11-forwarding") == 0 ||
2060		    strcmp(name, "permit-agent-forwarding") == 0 ||
2061		    strcmp(name, "permit-port-forwarding") == 0 ||
2062		    strcmp(name, "permit-pty") == 0 ||
2063		    strcmp(name, "permit-user-rc") == 0 ||
2064		    strcmp(name, "no-touch-required") == 0)) {
2065			printf("\n");
2066		} else if (in_critical &&
2067		    (strcmp(name, "force-command") == 0 ||
2068		    strcmp(name, "source-address") == 0)) {
2069			if ((r = sshbuf_get_cstring(option, &arg, NULL)) != 0)
2070				fatal_fr(r, "parse critical");
2071			printf(" %s\n", arg);
2072			free(arg);
2073		} else if (in_critical &&
2074		    strcmp(name, "verify-required") == 0) {
2075			printf("\n");
2076		} else if (sshbuf_len(option) > 0) {
2077			hex = sshbuf_dtob16(option);
2078			printf(" UNKNOWN OPTION: %s (len %zu)\n",
2079			    hex, sshbuf_len(option));
2080			sshbuf_reset(option);
2081			free(hex);
2082		} else
2083			printf(" UNKNOWN FLAG OPTION\n");
2084		free(name);
2085		if (sshbuf_len(option) != 0)
2086			fatal("Option corrupt: extra data at end");
2087	}
2088	sshbuf_free(option);
2089	sshbuf_free(options);
2090}
2091
2092static void
2093print_cert(struct sshkey *key)
2094{
2095	char valid[64], *key_fp, *ca_fp;
2096	u_int i;
2097
2098	key_fp = sshkey_fingerprint(key, fingerprint_hash, SSH_FP_DEFAULT);
2099	ca_fp = sshkey_fingerprint(key->cert->signature_key,
2100	    fingerprint_hash, SSH_FP_DEFAULT);
2101	if (key_fp == NULL || ca_fp == NULL)
2102		fatal_f("sshkey_fingerprint fail");
2103	sshkey_format_cert_validity(key->cert, valid, sizeof(valid));
2104
2105	printf("        Type: %s %s certificate\n", sshkey_ssh_name(key),
2106	    sshkey_cert_type(key));
2107	printf("        Public key: %s %s\n", sshkey_type(key), key_fp);
2108	printf("        Signing CA: %s %s (using %s)\n",
2109	    sshkey_type(key->cert->signature_key), ca_fp,
2110	    key->cert->signature_type);
2111	printf("        Key ID: \"%s\"\n", key->cert->key_id);
2112	printf("        Serial: %llu\n", (unsigned long long)key->cert->serial);
2113	printf("        Valid: %s\n", valid);
2114	printf("        Principals: ");
2115	if (key->cert->nprincipals == 0)
2116		printf("(none)\n");
2117	else {
2118		for (i = 0; i < key->cert->nprincipals; i++)
2119			printf("\n                %s",
2120			    key->cert->principals[i]);
2121		printf("\n");
2122	}
2123	printf("        Critical Options: ");
2124	if (sshbuf_len(key->cert->critical) == 0)
2125		printf("(none)\n");
2126	else {
2127		printf("\n");
2128		show_options(key->cert->critical, 1);
2129	}
2130	printf("        Extensions: ");
2131	if (sshbuf_len(key->cert->extensions) == 0)
2132		printf("(none)\n");
2133	else {
2134		printf("\n");
2135		show_options(key->cert->extensions, 0);
2136	}
2137}
2138
2139__dead static void
2140do_show_cert(struct passwd *pw)
2141{
2142	struct sshkey *key = NULL;
2143	struct stat st;
2144	int r, is_stdin = 0, ok = 0;
2145	FILE *f;
2146	char *cp, *line = NULL;
2147	const char *path;
2148	size_t linesize = 0;
2149	u_long lnum = 0;
2150
2151	if (!have_identity)
2152		ask_filename(pw, "Enter file in which the key is");
2153	if (strcmp(identity_file, "-") != 0 && stat(identity_file, &st) == -1)
2154		fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
2155
2156	path = identity_file;
2157	if (strcmp(path, "-") == 0) {
2158		f = stdin;
2159		path = "(stdin)";
2160		is_stdin = 1;
2161	} else if ((f = fopen(identity_file, "r")) == NULL)
2162		fatal("fopen %s: %s", identity_file, strerror(errno));
2163
2164	while (getline(&line, &linesize, f) != -1) {
2165		lnum++;
2166		sshkey_free(key);
2167		key = NULL;
2168		/* Trim leading space and comments */
2169		cp = line + strspn(line, " \t");
2170		if (*cp == '#' || *cp == '\0')
2171			continue;
2172		if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
2173			fatal("sshkey_new");
2174		if ((r = sshkey_read(key, &cp)) != 0) {
2175			error_r(r, "%s:%lu: invalid key", path, lnum);
2176			continue;
2177		}
2178		if (!sshkey_is_cert(key)) {
2179			error("%s:%lu is not a certificate", path, lnum);
2180			continue;
2181		}
2182		ok = 1;
2183		if (!is_stdin && lnum == 1)
2184			printf("%s:\n", path);
2185		else
2186			printf("%s:%lu:\n", path, lnum);
2187		print_cert(key);
2188	}
2189	free(line);
2190	sshkey_free(key);
2191	fclose(f);
2192	exit(ok ? 0 : 1);
2193}
2194
2195static void
2196load_krl(const char *path, struct ssh_krl **krlp)
2197{
2198	struct sshbuf *krlbuf;
2199	int r;
2200
2201	if ((r = sshbuf_load_file(path, &krlbuf)) != 0)
2202		fatal_r(r, "Unable to load KRL %s", path);
2203	/* XXX check sigs */
2204	if ((r = ssh_krl_from_blob(krlbuf, krlp)) != 0 ||
2205	    *krlp == NULL)
2206		fatal_r(r, "Invalid KRL file %s", path);
2207	sshbuf_free(krlbuf);
2208}
2209
2210static void
2211hash_to_blob(const char *cp, u_char **blobp, size_t *lenp,
2212    const char *file, u_long lnum)
2213{
2214	char *tmp;
2215	size_t tlen;
2216	struct sshbuf *b;
2217	int r;
2218
2219	if (strncmp(cp, "SHA256:", 7) != 0)
2220		fatal("%s:%lu: unsupported hash algorithm", file, lnum);
2221	cp += 7;
2222
2223	/*
2224	 * OpenSSH base64 hashes omit trailing '='
2225	 * characters; put them back for decode.
2226	 */
2227	if ((tlen = strlen(cp)) >= SIZE_MAX - 5)
2228		fatal_f("hash too long: %zu bytes", tlen);
2229	tmp = xmalloc(tlen + 4 + 1);
2230	strlcpy(tmp, cp, tlen + 1);
2231	while ((tlen % 4) != 0) {
2232		tmp[tlen++] = '=';
2233		tmp[tlen] = '\0';
2234	}
2235	if ((b = sshbuf_new()) == NULL)
2236		fatal_f("sshbuf_new failed");
2237	if ((r = sshbuf_b64tod(b, tmp)) != 0)
2238		fatal_r(r, "%s:%lu: decode hash failed", file, lnum);
2239	free(tmp);
2240	*lenp = sshbuf_len(b);
2241	*blobp = xmalloc(*lenp);
2242	memcpy(*blobp, sshbuf_ptr(b), *lenp);
2243	sshbuf_free(b);
2244}
2245
2246static void
2247update_krl_from_file(struct passwd *pw, const char *file, int wild_ca,
2248    const struct sshkey *ca, struct ssh_krl *krl)
2249{
2250	struct sshkey *key = NULL;
2251	u_long lnum = 0;
2252	char *path, *cp, *ep, *line = NULL;
2253	u_char *blob = NULL;
2254	size_t blen = 0, linesize = 0;
2255	unsigned long long serial, serial2;
2256	int i, was_explicit_key, was_sha1, was_sha256, was_hash, r;
2257	FILE *krl_spec;
2258
2259	path = tilde_expand_filename(file, pw->pw_uid);
2260	if (strcmp(path, "-") == 0) {
2261		krl_spec = stdin;
2262		free(path);
2263		path = xstrdup("(standard input)");
2264	} else if ((krl_spec = fopen(path, "r")) == NULL)
2265		fatal("fopen %s: %s", path, strerror(errno));
2266
2267	if (!quiet)
2268		printf("Revoking from %s\n", path);
2269	while (getline(&line, &linesize, krl_spec) != -1) {
2270		if (linesize >= INT_MAX) {
2271			fatal_f("%s contains unparsable line, len=%zu",
2272			    path, linesize);
2273		}
2274		lnum++;
2275		was_explicit_key = was_sha1 = was_sha256 = was_hash = 0;
2276		cp = line + strspn(line, " \t");
2277		/* Trim trailing space, comments and strip \n */
2278		for (i = 0, r = -1; cp[i] != '\0'; i++) {
2279			if (cp[i] == '#' || cp[i] == '\n') {
2280				cp[i] = '\0';
2281				break;
2282			}
2283			if (cp[i] == ' ' || cp[i] == '\t') {
2284				/* Remember the start of a span of whitespace */
2285				if (r == -1)
2286					r = i;
2287			} else
2288				r = -1;
2289		}
2290		if (r != -1)
2291			cp[r] = '\0';
2292		if (*cp == '\0')
2293			continue;
2294		if (strncasecmp(cp, "serial:", 7) == 0) {
2295			if (ca == NULL && !wild_ca) {
2296				fatal("revoking certificates by serial number "
2297				    "requires specification of a CA key");
2298			}
2299			cp += 7;
2300			cp = cp + strspn(cp, " \t");
2301			errno = 0;
2302			serial = strtoull(cp, &ep, 0);
2303			if (*cp == '\0' || (*ep != '\0' && *ep != '-'))
2304				fatal("%s:%lu: invalid serial \"%s\"",
2305				    path, lnum, cp);
2306			if (errno == ERANGE && serial == ULLONG_MAX)
2307				fatal("%s:%lu: serial out of range",
2308				    path, lnum);
2309			serial2 = serial;
2310			if (*ep == '-') {
2311				cp = ep + 1;
2312				errno = 0;
2313				serial2 = strtoull(cp, &ep, 0);
2314				if (*cp == '\0' || *ep != '\0')
2315					fatal("%s:%lu: invalid serial \"%s\"",
2316					    path, lnum, cp);
2317				if (errno == ERANGE && serial2 == ULLONG_MAX)
2318					fatal("%s:%lu: serial out of range",
2319					    path, lnum);
2320				if (serial2 <= serial)
2321					fatal("%s:%lu: invalid serial range "
2322					    "%llu:%llu", path, lnum,
2323					    (unsigned long long)serial,
2324					    (unsigned long long)serial2);
2325			}
2326			if (ssh_krl_revoke_cert_by_serial_range(krl,
2327			    ca, serial, serial2) != 0) {
2328				fatal_f("revoke serial failed");
2329			}
2330		} else if (strncasecmp(cp, "id:", 3) == 0) {
2331			if (ca == NULL && !wild_ca) {
2332				fatal("revoking certificates by key ID "
2333				    "requires specification of a CA key");
2334			}
2335			cp += 3;
2336			cp = cp + strspn(cp, " \t");
2337			if (ssh_krl_revoke_cert_by_key_id(krl, ca, cp) != 0)
2338				fatal_f("revoke key ID failed");
2339		} else if (strncasecmp(cp, "hash:", 5) == 0) {
2340			cp += 5;
2341			cp = cp + strspn(cp, " \t");
2342			hash_to_blob(cp, &blob, &blen, file, lnum);
2343			r = ssh_krl_revoke_key_sha256(krl, blob, blen);
2344			if (r != 0)
2345				fatal_fr(r, "revoke key failed");
2346		} else {
2347			if (strncasecmp(cp, "key:", 4) == 0) {
2348				cp += 4;
2349				cp = cp + strspn(cp, " \t");
2350				was_explicit_key = 1;
2351			} else if (strncasecmp(cp, "sha1:", 5) == 0) {
2352				cp += 5;
2353				cp = cp + strspn(cp, " \t");
2354				was_sha1 = 1;
2355			} else if (strncasecmp(cp, "sha256:", 7) == 0) {
2356				cp += 7;
2357				cp = cp + strspn(cp, " \t");
2358				was_sha256 = 1;
2359				/*
2360				 * Just try to process the line as a key.
2361				 * Parsing will fail if it isn't.
2362				 */
2363			}
2364			if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
2365				fatal("sshkey_new");
2366			if ((r = sshkey_read(key, &cp)) != 0)
2367				fatal_r(r, "%s:%lu: invalid key", path, lnum);
2368			if (was_explicit_key)
2369				r = ssh_krl_revoke_key_explicit(krl, key);
2370			else if (was_sha1) {
2371				if (sshkey_fingerprint_raw(key,
2372				    SSH_DIGEST_SHA1, &blob, &blen) != 0) {
2373					fatal("%s:%lu: fingerprint failed",
2374					    file, lnum);
2375				}
2376				r = ssh_krl_revoke_key_sha1(krl, blob, blen);
2377			} else if (was_sha256) {
2378				if (sshkey_fingerprint_raw(key,
2379				    SSH_DIGEST_SHA256, &blob, &blen) != 0) {
2380					fatal("%s:%lu: fingerprint failed",
2381					    file, lnum);
2382				}
2383				r = ssh_krl_revoke_key_sha256(krl, blob, blen);
2384			} else
2385				r = ssh_krl_revoke_key(krl, key);
2386			if (r != 0)
2387				fatal_fr(r, "revoke key failed");
2388			freezero(blob, blen);
2389			blob = NULL;
2390			blen = 0;
2391			sshkey_free(key);
2392		}
2393	}
2394	if (strcmp(path, "-") != 0)
2395		fclose(krl_spec);
2396	free(line);
2397	free(path);
2398}
2399
2400static void
2401do_gen_krl(struct passwd *pw, int updating, const char *ca_key_path,
2402    unsigned long long krl_version, const char *krl_comment,
2403    int argc, char **argv)
2404{
2405	struct ssh_krl *krl;
2406	struct stat sb;
2407	struct sshkey *ca = NULL;
2408	int i, r, wild_ca = 0;
2409	char *tmp;
2410	struct sshbuf *kbuf;
2411
2412	if (*identity_file == '\0')
2413		fatal("KRL generation requires an output file");
2414	if (stat(identity_file, &sb) == -1) {
2415		if (errno != ENOENT)
2416			fatal("Cannot access KRL \"%s\": %s",
2417			    identity_file, strerror(errno));
2418		if (updating)
2419			fatal("KRL \"%s\" does not exist", identity_file);
2420	}
2421	if (ca_key_path != NULL) {
2422		if (strcasecmp(ca_key_path, "none") == 0)
2423			wild_ca = 1;
2424		else {
2425			tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
2426			if ((r = sshkey_load_public(tmp, &ca, NULL)) != 0)
2427				fatal_r(r, "Cannot load CA public key %s", tmp);
2428			free(tmp);
2429		}
2430	}
2431
2432	if (updating)
2433		load_krl(identity_file, &krl);
2434	else if ((krl = ssh_krl_init()) == NULL)
2435		fatal("couldn't create KRL");
2436
2437	if (krl_version != 0)
2438		ssh_krl_set_version(krl, krl_version);
2439	if (krl_comment != NULL)
2440		ssh_krl_set_comment(krl, krl_comment);
2441
2442	for (i = 0; i < argc; i++)
2443		update_krl_from_file(pw, argv[i], wild_ca, ca, krl);
2444
2445	if ((kbuf = sshbuf_new()) == NULL)
2446		fatal("sshbuf_new failed");
2447	if (ssh_krl_to_blob(krl, kbuf) != 0)
2448		fatal("Couldn't generate KRL");
2449	if ((r = sshbuf_write_file(identity_file, kbuf)) != 0)
2450		fatal("write %s: %s", identity_file, strerror(errno));
2451	sshbuf_free(kbuf);
2452	ssh_krl_free(krl);
2453	sshkey_free(ca);
2454}
2455
2456__dead static void
2457do_check_krl(struct passwd *pw, int print_krl, int argc, char **argv)
2458{
2459	int i, r, ret = 0;
2460	char *comment;
2461	struct ssh_krl *krl;
2462	struct sshkey *k;
2463
2464	if (*identity_file == '\0')
2465		fatal("KRL checking requires an input file");
2466	load_krl(identity_file, &krl);
2467	if (print_krl)
2468		krl_dump(krl, stdout);
2469	for (i = 0; i < argc; i++) {
2470		if ((r = sshkey_load_public(argv[i], &k, &comment)) != 0)
2471			fatal_r(r, "Cannot load public key %s", argv[i]);
2472		r = ssh_krl_check_key(krl, k);
2473		printf("%s%s%s%s: %s\n", argv[i],
2474		    *comment ? " (" : "", comment, *comment ? ")" : "",
2475		    r == 0 ? "ok" : "REVOKED");
2476		if (r != 0)
2477			ret = 1;
2478		sshkey_free(k);
2479		free(comment);
2480	}
2481	ssh_krl_free(krl);
2482	exit(ret);
2483}
2484
2485static struct sshkey *
2486load_sign_key(const char *keypath, const struct sshkey *pubkey)
2487{
2488	size_t i, slen, plen = strlen(keypath);
2489	char *privpath = xstrdup(keypath);
2490	static const char * const suffixes[] = { "-cert.pub", ".pub", NULL };
2491	struct sshkey *ret = NULL, *privkey = NULL;
2492	int r, waspub = 0;
2493	struct stat st;
2494
2495	/*
2496	 * If passed a public key filename, then try to locate the corresponding
2497	 * private key. This lets us specify certificates on the command-line
2498	 * and have ssh-keygen find the appropriate private key.
2499	 */
2500	for (i = 0; suffixes[i]; i++) {
2501		slen = strlen(suffixes[i]);
2502		if (plen <= slen ||
2503		    strcmp(privpath + plen - slen, suffixes[i]) != 0)
2504			continue;
2505		privpath[plen - slen] = '\0';
2506		debug_f("%s looks like a public key, using private key "
2507		    "path %s instead", keypath, privpath);
2508		waspub = 1;
2509	}
2510	if (waspub && stat(privpath, &st) != 0 && errno == ENOENT)
2511		fatal("No private key found for public key \"%s\"", keypath);
2512	if ((r = sshkey_load_private(privpath, "", &privkey, NULL)) != 0 &&
2513	    (r != SSH_ERR_KEY_WRONG_PASSPHRASE)) {
2514		debug_fr(r, "load private key \"%s\"", privpath);
2515		fatal("No private key found for \"%s\"", privpath);
2516	} else if (privkey == NULL)
2517		privkey = load_identity(privpath, NULL);
2518
2519	if (!sshkey_equal_public(pubkey, privkey)) {
2520		error("Public key %s doesn't match private %s",
2521		    keypath, privpath);
2522		goto done;
2523	}
2524	if (sshkey_is_cert(pubkey) && !sshkey_is_cert(privkey)) {
2525		/*
2526		 * Graft the certificate onto the private key to make
2527		 * it capable of signing.
2528		 */
2529		if ((r = sshkey_to_certified(privkey)) != 0) {
2530			error_fr(r, "sshkey_to_certified");
2531			goto done;
2532		}
2533		if ((r = sshkey_cert_copy(pubkey, privkey)) != 0) {
2534			error_fr(r, "sshkey_cert_copy");
2535			goto done;
2536		}
2537	}
2538	/* success */
2539	ret = privkey;
2540	privkey = NULL;
2541 done:
2542	sshkey_free(privkey);
2543	free(privpath);
2544	return ret;
2545}
2546
2547static int
2548sign_one(struct sshkey *signkey, const char *filename, int fd,
2549    const char *sig_namespace, const char *hashalg, sshsig_signer *signer,
2550    void *signer_ctx)
2551{
2552	struct sshbuf *sigbuf = NULL, *abuf = NULL;
2553	int r = SSH_ERR_INTERNAL_ERROR, wfd = -1, oerrno;
2554	char *wfile = NULL, *asig = NULL, *fp = NULL;
2555	char *pin = NULL, *prompt = NULL;
2556
2557	if (!quiet) {
2558		if (fd == STDIN_FILENO)
2559			fprintf(stderr, "Signing data on standard input\n");
2560		else
2561			fprintf(stderr, "Signing file %s\n", filename);
2562	}
2563	if (signer == NULL && sshkey_is_sk(signkey)) {
2564		if ((signkey->sk_flags & SSH_SK_USER_VERIFICATION_REQD)) {
2565			xasprintf(&prompt, "Enter PIN for %s key: ",
2566			    sshkey_type(signkey));
2567			if ((pin = read_passphrase(prompt,
2568			    RP_ALLOW_STDIN)) == NULL)
2569				fatal_f("couldn't read PIN");
2570		}
2571		if ((signkey->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {
2572			if ((fp = sshkey_fingerprint(signkey, fingerprint_hash,
2573			    SSH_FP_DEFAULT)) == NULL)
2574				fatal_f("fingerprint failed");
2575			fprintf(stderr, "Confirm user presence for key %s %s\n",
2576			    sshkey_type(signkey), fp);
2577			free(fp);
2578		}
2579	}
2580	if ((r = sshsig_sign_fd(signkey, hashalg, sk_provider, pin,
2581	    fd, sig_namespace, &sigbuf, signer, signer_ctx)) != 0) {
2582		error_r(r, "Signing %s failed", filename);
2583		goto out;
2584	}
2585	if ((r = sshsig_armor(sigbuf, &abuf)) != 0) {
2586		error_fr(r, "sshsig_armor");
2587		goto out;
2588	}
2589	if ((asig = sshbuf_dup_string(abuf)) == NULL) {
2590		error_f("buffer error");
2591		r = SSH_ERR_ALLOC_FAIL;
2592		goto out;
2593	}
2594
2595	if (fd == STDIN_FILENO) {
2596		fputs(asig, stdout);
2597		fflush(stdout);
2598	} else {
2599		xasprintf(&wfile, "%s.sig", filename);
2600		if (confirm_overwrite(wfile)) {
2601			if ((wfd = open(wfile, O_WRONLY|O_CREAT|O_TRUNC,
2602			    0666)) == -1) {
2603				oerrno = errno;
2604				error("Cannot open %s: %s",
2605				    wfile, strerror(errno));
2606				errno = oerrno;
2607				r = SSH_ERR_SYSTEM_ERROR;
2608				goto out;
2609			}
2610			if (atomicio(vwrite, wfd, asig,
2611			    strlen(asig)) != strlen(asig)) {
2612				oerrno = errno;
2613				error("Cannot write to %s: %s",
2614				    wfile, strerror(errno));
2615				errno = oerrno;
2616				r = SSH_ERR_SYSTEM_ERROR;
2617				goto out;
2618			}
2619			if (!quiet) {
2620				fprintf(stderr, "Write signature to %s\n",
2621				    wfile);
2622			}
2623		}
2624	}
2625	/* success */
2626	r = 0;
2627 out:
2628	free(wfile);
2629	free(prompt);
2630	free(asig);
2631	if (pin != NULL)
2632		freezero(pin, strlen(pin));
2633	sshbuf_free(abuf);
2634	sshbuf_free(sigbuf);
2635	if (wfd != -1)
2636		close(wfd);
2637	return r;
2638}
2639
2640static int
2641sig_process_opts(char * const *opts, size_t nopts, char **hashalgp,
2642    uint64_t *verify_timep, int *print_pubkey)
2643{
2644	size_t i;
2645	time_t now;
2646
2647	if (verify_timep != NULL)
2648		*verify_timep = 0;
2649	if (print_pubkey != NULL)
2650		*print_pubkey = 0;
2651	if (hashalgp != NULL)
2652		*hashalgp = NULL;
2653	for (i = 0; i < nopts; i++) {
2654		if (hashalgp != NULL &&
2655		    strncasecmp(opts[i], "hashalg=", 8) == 0) {
2656			*hashalgp = xstrdup(opts[i] + 8);
2657		} else if (verify_timep &&
2658		    strncasecmp(opts[i], "verify-time=", 12) == 0) {
2659			if (parse_absolute_time(opts[i] + 12,
2660			    verify_timep) != 0 || *verify_timep == 0) {
2661				error("Invalid \"verify-time\" option");
2662				return SSH_ERR_INVALID_ARGUMENT;
2663			}
2664		} else if (print_pubkey &&
2665		    strcasecmp(opts[i], "print-pubkey") == 0) {
2666			*print_pubkey = 1;
2667		} else {
2668			error("Invalid option \"%s\"", opts[i]);
2669			return SSH_ERR_INVALID_ARGUMENT;
2670		}
2671	}
2672	if (verify_timep && *verify_timep == 0) {
2673		if ((now = time(NULL)) < 0) {
2674			error("Time is before epoch");
2675			return SSH_ERR_INVALID_ARGUMENT;
2676		}
2677		*verify_timep = (uint64_t)now;
2678	}
2679	return 0;
2680}
2681
2682
2683static int
2684sig_sign(const char *keypath, const char *sig_namespace, int require_agent,
2685    int argc, char **argv, char * const *opts, size_t nopts)
2686{
2687	int i, fd = -1, r, ret = -1;
2688	int agent_fd = -1;
2689	struct sshkey *pubkey = NULL, *privkey = NULL, *signkey = NULL;
2690	sshsig_signer *signer = NULL;
2691	char *hashalg = NULL;
2692
2693	/* Check file arguments. */
2694	for (i = 0; i < argc; i++) {
2695		if (strcmp(argv[i], "-") != 0)
2696			continue;
2697		if (i > 0 || argc > 1)
2698			fatal("Cannot sign mix of paths and standard input");
2699	}
2700
2701	if (sig_process_opts(opts, nopts, &hashalg, NULL, NULL) != 0)
2702		goto done; /* error already logged */
2703
2704	if ((r = sshkey_load_public(keypath, &pubkey, NULL)) != 0) {
2705		error_r(r, "Couldn't load public key %s", keypath);
2706		goto done;
2707	}
2708
2709	if ((r = ssh_get_authentication_socket(&agent_fd)) != 0) {
2710		if (require_agent)
2711			fatal("Couldn't get agent socket");
2712		debug_r(r, "Couldn't get agent socket");
2713	} else {
2714		if ((r = ssh_agent_has_key(agent_fd, pubkey)) == 0)
2715			signer = agent_signer;
2716		else {
2717			if (require_agent)
2718				fatal("Couldn't find key in agent");
2719			debug_r(r, "Couldn't find key in agent");
2720		}
2721	}
2722
2723	if (signer == NULL) {
2724		/* Not using agent - try to load private key */
2725		if ((privkey = load_sign_key(keypath, pubkey)) == NULL)
2726			goto done;
2727		signkey = privkey;
2728	} else {
2729		/* Will use key in agent */
2730		signkey = pubkey;
2731	}
2732
2733	if (argc == 0) {
2734		if ((r = sign_one(signkey, "(stdin)", STDIN_FILENO,
2735		    sig_namespace, hashalg, signer, &agent_fd)) != 0)
2736			goto done;
2737	} else {
2738		for (i = 0; i < argc; i++) {
2739			if (strcmp(argv[i], "-") == 0)
2740				fd = STDIN_FILENO;
2741			else if ((fd = open(argv[i], O_RDONLY)) == -1) {
2742				error("Cannot open %s for signing: %s",
2743				    argv[i], strerror(errno));
2744				goto done;
2745			}
2746			if ((r = sign_one(signkey, argv[i], fd, sig_namespace,
2747			    hashalg, signer, &agent_fd)) != 0)
2748				goto done;
2749			if (fd != STDIN_FILENO)
2750				close(fd);
2751			fd = -1;
2752		}
2753	}
2754
2755	ret = 0;
2756done:
2757	if (fd != -1 && fd != STDIN_FILENO)
2758		close(fd);
2759	sshkey_free(pubkey);
2760	sshkey_free(privkey);
2761	free(hashalg);
2762	return ret;
2763}
2764
2765static int
2766sig_verify(const char *signature, const char *sig_namespace,
2767    const char *principal, const char *allowed_keys, const char *revoked_keys,
2768    char * const *opts, size_t nopts)
2769{
2770	int r, ret = -1;
2771	int print_pubkey = 0;
2772	struct sshbuf *sigbuf = NULL, *abuf = NULL;
2773	struct sshkey *sign_key = NULL;
2774	char *fp = NULL;
2775	struct sshkey_sig_details *sig_details = NULL;
2776	uint64_t verify_time = 0;
2777
2778	if (sig_process_opts(opts, nopts, NULL, &verify_time,
2779	    &print_pubkey) != 0)
2780		goto done; /* error already logged */
2781
2782	memset(&sig_details, 0, sizeof(sig_details));
2783	if ((r = sshbuf_load_file(signature, &abuf)) != 0) {
2784		error_r(r, "Couldn't read signature file");
2785		goto done;
2786	}
2787
2788	if ((r = sshsig_dearmor(abuf, &sigbuf)) != 0) {
2789		error_fr(r, "sshsig_armor");
2790		goto done;
2791	}
2792	if ((r = sshsig_verify_fd(sigbuf, STDIN_FILENO, sig_namespace,
2793	    &sign_key, &sig_details)) != 0)
2794		goto done; /* sshsig_verify() prints error */
2795
2796	if ((fp = sshkey_fingerprint(sign_key, fingerprint_hash,
2797	    SSH_FP_DEFAULT)) == NULL)
2798		fatal_f("sshkey_fingerprint failed");
2799	debug("Valid (unverified) signature from key %s", fp);
2800	if (sig_details != NULL) {
2801		debug2_f("signature details: counter = %u, flags = 0x%02x",
2802		    sig_details->sk_counter, sig_details->sk_flags);
2803	}
2804	free(fp);
2805	fp = NULL;
2806
2807	if (revoked_keys != NULL) {
2808		if ((r = sshkey_check_revoked(sign_key, revoked_keys)) != 0) {
2809			debug3_fr(r, "sshkey_check_revoked");
2810			goto done;
2811		}
2812	}
2813
2814	if (allowed_keys != NULL && (r = sshsig_check_allowed_keys(allowed_keys,
2815	    sign_key, principal, sig_namespace, verify_time)) != 0) {
2816		debug3_fr(r, "sshsig_check_allowed_keys");
2817		goto done;
2818	}
2819	/* success */
2820	ret = 0;
2821done:
2822	if (!quiet) {
2823		if (ret == 0) {
2824			if ((fp = sshkey_fingerprint(sign_key, fingerprint_hash,
2825			    SSH_FP_DEFAULT)) == NULL)
2826				fatal_f("sshkey_fingerprint failed");
2827			if (principal == NULL) {
2828				printf("Good \"%s\" signature with %s key %s\n",
2829				    sig_namespace, sshkey_type(sign_key), fp);
2830
2831			} else {
2832				printf("Good \"%s\" signature for %s with %s key %s\n",
2833				    sig_namespace, principal,
2834				    sshkey_type(sign_key), fp);
2835			}
2836		} else {
2837			printf("Could not verify signature.\n");
2838		}
2839	}
2840	/* Print the signature key if requested */
2841	if (ret == 0 && print_pubkey && sign_key != NULL) {
2842		if ((r = sshkey_write(sign_key, stdout)) == 0)
2843			fputc('\n', stdout);
2844		else {
2845			error_r(r, "Could not print public key.\n");
2846			ret = -1;
2847		}
2848	}
2849	sshbuf_free(sigbuf);
2850	sshbuf_free(abuf);
2851	sshkey_free(sign_key);
2852	sshkey_sig_details_free(sig_details);
2853	free(fp);
2854	return ret;
2855}
2856
2857static int
2858sig_find_principals(const char *signature, const char *allowed_keys,
2859    char * const *opts, size_t nopts)
2860{
2861	int r, ret = -1;
2862	struct sshbuf *sigbuf = NULL, *abuf = NULL;
2863	struct sshkey *sign_key = NULL;
2864	char *principals = NULL, *cp, *tmp;
2865	uint64_t verify_time = 0;
2866
2867	if (sig_process_opts(opts, nopts, NULL, &verify_time, NULL) != 0)
2868		goto done; /* error already logged */
2869
2870	if ((r = sshbuf_load_file(signature, &abuf)) != 0) {
2871		error_r(r, "Couldn't read signature file");
2872		goto done;
2873	}
2874	if ((r = sshsig_dearmor(abuf, &sigbuf)) != 0) {
2875		error_fr(r, "sshsig_armor");
2876		goto done;
2877	}
2878	if ((r = sshsig_get_pubkey(sigbuf, &sign_key)) != 0) {
2879		error_fr(r, "sshsig_get_pubkey");
2880		goto done;
2881	}
2882	if ((r = sshsig_find_principals(allowed_keys, sign_key,
2883	    verify_time, &principals)) != 0) {
2884		if (r != SSH_ERR_KEY_NOT_FOUND)
2885			error_fr(r, "sshsig_find_principal");
2886		goto done;
2887	}
2888	ret = 0;
2889done:
2890	if (ret == 0 ) {
2891		/* Emit matching principals one per line */
2892		tmp = principals;
2893		while ((cp = strsep(&tmp, ",")) != NULL && *cp != '\0')
2894			puts(cp);
2895	} else {
2896		fprintf(stderr, "No principal matched.\n");
2897	}
2898	sshbuf_free(sigbuf);
2899	sshbuf_free(abuf);
2900	sshkey_free(sign_key);
2901	free(principals);
2902	return ret;
2903}
2904
2905static int
2906sig_match_principals(const char *allowed_keys, char *principal,
2907	char * const *opts, size_t nopts)
2908{
2909	int r;
2910	char **principals = NULL;
2911	size_t i, nprincipals = 0;
2912
2913	if ((r = sig_process_opts(opts, nopts, NULL, NULL, NULL)) != 0)
2914		return r; /* error already logged */
2915
2916	if ((r = sshsig_match_principals(allowed_keys, principal,
2917	    &principals, &nprincipals)) != 0) {
2918		debug_f("match: %s", ssh_err(r));
2919		fprintf(stderr, "No principal matched.\n");
2920		return r;
2921	}
2922	for (i = 0; i < nprincipals; i++) {
2923		printf("%s\n", principals[i]);
2924		free(principals[i]);
2925	}
2926	free(principals);
2927
2928	return 0;
2929}
2930
2931static void
2932do_moduli_gen(const char *out_file, char **opts, size_t nopts)
2933{
2934#ifdef WITH_OPENSSL
2935	/* Moduli generation/screening */
2936	u_int32_t memory = 0;
2937	BIGNUM *start = NULL;
2938	int moduli_bits = 0;
2939	FILE *out;
2940	size_t i;
2941	const char *errstr;
2942
2943	/* Parse options */
2944	for (i = 0; i < nopts; i++) {
2945		if (strncmp(opts[i], "memory=", 7) == 0) {
2946			memory = (u_int32_t)strtonum(opts[i]+7, 1,
2947			    UINT_MAX, &errstr);
2948			if (errstr) {
2949				fatal("Memory limit is %s: %s",
2950				    errstr, opts[i]+7);
2951			}
2952		} else if (strncmp(opts[i], "start=", 6) == 0) {
2953			/* XXX - also compare length against bits */
2954			if (BN_hex2bn(&start, opts[i]+6) == 0)
2955				fatal("Invalid start point.");
2956		} else if (strncmp(opts[i], "bits=", 5) == 0) {
2957			moduli_bits = (int)strtonum(opts[i]+5, 1,
2958			    INT_MAX, &errstr);
2959			if (errstr) {
2960				fatal("Invalid number: %s (%s)",
2961					opts[i]+12, errstr);
2962			}
2963		} else {
2964			fatal("Option \"%s\" is unsupported for moduli "
2965			    "generation", opts[i]);
2966		}
2967	}
2968
2969	if ((out = fopen(out_file, "w")) == NULL) {
2970		fatal("Couldn't open modulus candidate file \"%s\": %s",
2971		    out_file, strerror(errno));
2972	}
2973	setvbuf(out, NULL, _IOLBF, 0);
2974
2975	if (moduli_bits == 0)
2976		moduli_bits = DEFAULT_BITS;
2977	if (gen_candidates(out, memory, moduli_bits, start) != 0)
2978		fatal("modulus candidate generation failed");
2979#else /* WITH_OPENSSL */
2980	fatal("Moduli generation is not supported");
2981#endif /* WITH_OPENSSL */
2982}
2983
2984static void
2985do_moduli_screen(const char *out_file, char **opts, size_t nopts)
2986{
2987#ifdef WITH_OPENSSL
2988	/* Moduli generation/screening */
2989	char *checkpoint = NULL;
2990	u_int32_t generator_wanted = 0;
2991	unsigned long start_lineno = 0, lines_to_process = 0;
2992	int prime_tests = 0;
2993	FILE *out, *in = stdin;
2994	size_t i;
2995	const char *errstr;
2996
2997	/* Parse options */
2998	for (i = 0; i < nopts; i++) {
2999		if (strncmp(opts[i], "lines=", 6) == 0) {
3000			lines_to_process = strtoul(opts[i]+6, NULL, 10);
3001		} else if (strncmp(opts[i], "start-line=", 11) == 0) {
3002			start_lineno = strtoul(opts[i]+11, NULL, 10);
3003		} else if (strncmp(opts[i], "checkpoint=", 11) == 0) {
3004			free(checkpoint);
3005			checkpoint = xstrdup(opts[i]+11);
3006		} else if (strncmp(opts[i], "generator=", 10) == 0) {
3007			generator_wanted = (u_int32_t)strtonum(
3008			    opts[i]+10, 1, UINT_MAX, &errstr);
3009			if (errstr != NULL) {
3010				fatal("Generator invalid: %s (%s)",
3011				    opts[i]+10, errstr);
3012			}
3013		} else if (strncmp(opts[i], "prime-tests=", 12) == 0) {
3014			prime_tests = (int)strtonum(opts[i]+12, 1,
3015			    INT_MAX, &errstr);
3016			if (errstr) {
3017				fatal("Invalid number: %s (%s)",
3018					opts[i]+12, errstr);
3019			}
3020		} else {
3021			fatal("Option \"%s\" is unsupported for moduli "
3022			    "screening", opts[i]);
3023		}
3024	}
3025
3026	if (have_identity && strcmp(identity_file, "-") != 0) {
3027		if ((in = fopen(identity_file, "r")) == NULL) {
3028			fatal("Couldn't open modulus candidate "
3029			    "file \"%s\": %s", identity_file,
3030			    strerror(errno));
3031		}
3032	}
3033
3034	if ((out = fopen(out_file, "a")) == NULL) {
3035		fatal("Couldn't open moduli file \"%s\": %s",
3036		    out_file, strerror(errno));
3037	}
3038	setvbuf(out, NULL, _IOLBF, 0);
3039	if (prime_test(in, out, prime_tests == 0 ? 100 : prime_tests,
3040	    generator_wanted, checkpoint,
3041	    start_lineno, lines_to_process) != 0)
3042		fatal("modulus screening failed");
3043	if (in != stdin)
3044		(void)fclose(in);
3045	free(checkpoint);
3046#else /* WITH_OPENSSL */
3047	fatal("Moduli screening is not supported");
3048#endif /* WITH_OPENSSL */
3049}
3050
3051/* Read and confirm a passphrase */
3052static char *
3053read_check_passphrase(const char *prompt1, const char *prompt2,
3054    const char *retry_prompt)
3055{
3056	char *passphrase1, *passphrase2;
3057
3058	for (;;) {
3059		passphrase1 = read_passphrase(prompt1, RP_ALLOW_STDIN);
3060		passphrase2 = read_passphrase(prompt2, RP_ALLOW_STDIN);
3061		if (strcmp(passphrase1, passphrase2) == 0) {
3062			freezero(passphrase2, strlen(passphrase2));
3063			return passphrase1;
3064		}
3065		/* The passphrases do not match. Clear them and retry. */
3066		freezero(passphrase1, strlen(passphrase1));
3067		freezero(passphrase2, strlen(passphrase2));
3068		fputs(retry_prompt, stdout);
3069		fputc('\n', stdout);
3070		fflush(stdout);
3071	}
3072	/* NOTREACHED */
3073	return NULL;
3074}
3075
3076static char *
3077private_key_passphrase(void)
3078{
3079	if (identity_passphrase)
3080		return xstrdup(identity_passphrase);
3081	if (identity_new_passphrase)
3082		return xstrdup(identity_new_passphrase);
3083
3084	return read_check_passphrase(
3085	    "Enter passphrase (empty for no passphrase): ",
3086	    "Enter same passphrase again: ",
3087	    "Passphrases do not match.  Try again.");
3088}
3089
3090static char *
3091sk_suffix(const char *application, const uint8_t *user, size_t userlen)
3092{
3093	char *ret, *cp;
3094	size_t slen, i;
3095
3096	/* Trim off URL-like preamble */
3097	if (strncmp(application, "ssh://", 6) == 0)
3098		ret =  xstrdup(application + 6);
3099	else if (strncmp(application, "ssh:", 4) == 0)
3100		ret =  xstrdup(application + 4);
3101	else
3102		ret = xstrdup(application);
3103
3104	/* Count trailing zeros in user */
3105	for (i = 0; i < userlen; i++) {
3106		if (user[userlen - i - 1] != 0)
3107			break;
3108	}
3109	if (i >= userlen)
3110		return ret; /* user-id was default all-zeros */
3111
3112	/* Append user-id, escaping non-UTF-8 characters */
3113	slen = userlen - i;
3114	if (asmprintf(&cp, INT_MAX, NULL, "%.*s", (int)slen, user) == -1)
3115		fatal_f("asmprintf failed");
3116	/* Don't emit a user-id that contains path or control characters */
3117	if (strchr(cp, '/') != NULL || strstr(cp, "..") != NULL ||
3118	    strchr(cp, '\\') != NULL) {
3119		free(cp);
3120		cp = tohex(user, slen);
3121	}
3122	xextendf(&ret, "_", "%s", cp);
3123	free(cp);
3124	return ret;
3125}
3126
3127static int
3128do_download_sk(const char *skprovider, const char *device)
3129{
3130	struct sshsk_resident_key **srks;
3131	size_t nsrks, i;
3132	int r, ret = -1;
3133	char *fp, *pin = NULL, *pass = NULL, *path, *pubpath;
3134	const char *ext;
3135	struct sshkey *key;
3136
3137	if (skprovider == NULL)
3138		fatal("Cannot download keys without provider");
3139
3140	pin = read_passphrase("Enter PIN for authenticator: ", RP_ALLOW_STDIN);
3141	if (!quiet) {
3142		printf("You may need to touch your authenticator "
3143		    "to authorize key download.\n");
3144	}
3145	if ((r = sshsk_load_resident(skprovider, device, pin, 0,
3146	    &srks, &nsrks)) != 0) {
3147		if (pin != NULL)
3148			freezero(pin, strlen(pin));
3149		error_r(r, "Unable to load resident keys");
3150		return -1;
3151	}
3152	if (nsrks == 0)
3153		logit("No keys to download");
3154	if (pin != NULL)
3155		freezero(pin, strlen(pin));
3156
3157	for (i = 0; i < nsrks; i++) {
3158		key = srks[i]->key;
3159		if (key->type != KEY_ECDSA_SK && key->type != KEY_ED25519_SK) {
3160			error("Unsupported key type %s (%d)",
3161			    sshkey_type(key), key->type);
3162			continue;
3163		}
3164		if ((fp = sshkey_fingerprint(key, fingerprint_hash,
3165		    SSH_FP_DEFAULT)) == NULL)
3166			fatal_f("sshkey_fingerprint failed");
3167		debug_f("key %zu: %s %s %s (flags 0x%02x)", i,
3168		    sshkey_type(key), fp, key->sk_application, key->sk_flags);
3169		ext = sk_suffix(key->sk_application,
3170		    srks[i]->user_id, srks[i]->user_id_len);
3171		xasprintf(&path, "id_%s_rk%s%s",
3172		    key->type == KEY_ECDSA_SK ? "ecdsa_sk" : "ed25519_sk",
3173		    *ext == '\0' ? "" : "_", ext);
3174
3175		/* If the file already exists, ask the user to confirm. */
3176		if (!confirm_overwrite(path)) {
3177			free(path);
3178			break;
3179		}
3180
3181		/* Save the key with the application string as the comment */
3182		if (pass == NULL)
3183			pass = private_key_passphrase();
3184		if ((r = sshkey_save_private(key, path, pass,
3185		    key->sk_application, private_key_format,
3186		    openssh_format_cipher, rounds)) != 0) {
3187			error_r(r, "Saving key \"%s\" failed", path);
3188			free(path);
3189			break;
3190		}
3191		if (!quiet) {
3192			printf("Saved %s key%s%s to %s\n", sshkey_type(key),
3193			    *ext != '\0' ? " " : "",
3194			    *ext != '\0' ? key->sk_application : "",
3195			    path);
3196		}
3197
3198		/* Save public key too */
3199		xasprintf(&pubpath, "%s.pub", path);
3200		free(path);
3201		if ((r = sshkey_save_public(key, pubpath,
3202		    key->sk_application)) != 0) {
3203			error_r(r, "Saving public key \"%s\" failed", pubpath);
3204			free(pubpath);
3205			break;
3206		}
3207		free(pubpath);
3208	}
3209
3210	if (i >= nsrks)
3211		ret = 0; /* success */
3212	if (pass != NULL)
3213		freezero(pass, strlen(pass));
3214	sshsk_free_resident_keys(srks, nsrks);
3215	return ret;
3216}
3217
3218static void
3219save_attestation(struct sshbuf *attest, const char *path)
3220{
3221	mode_t omask;
3222	int r;
3223
3224	if (path == NULL)
3225		return; /* nothing to do */
3226	if (attest == NULL || sshbuf_len(attest) == 0)
3227		fatal("Enrollment did not return attestation data");
3228	omask = umask(077);
3229	r = sshbuf_write_file(path, attest);
3230	umask(omask);
3231	if (r != 0)
3232		fatal_r(r, "Unable to write attestation data \"%s\"", path);
3233	if (!quiet)
3234		printf("Your FIDO attestation certificate has been saved in "
3235		    "%s\n", path);
3236}
3237
3238static int
3239confirm_sk_overwrite(const char *application, const char *user)
3240{
3241	char yesno[3];
3242
3243	printf("A resident key scoped to '%s' with user id '%s' already "
3244	    "exists.\n", application == NULL ? "ssh:" : application,
3245	    user == NULL ? "null" : user);
3246	printf("Overwrite key in token (y/n)? ");
3247	fflush(stdout);
3248	if (fgets(yesno, sizeof(yesno), stdin) == NULL)
3249		return 0;
3250	if (yesno[0] != 'y' && yesno[0] != 'Y')
3251		return 0;
3252	return 1;
3253}
3254
3255__dead static void
3256usage(void)
3257{
3258	fprintf(stderr,
3259	    "usage: ssh-keygen [-q] [-a rounds] [-b bits] [-C comment] [-f output_keyfile]\n"
3260	    "                  [-m format] [-N new_passphrase] [-O option]\n"
3261	    "                  [-t dsa | ecdsa | ecdsa-sk | ed25519 | ed25519-sk | rsa]\n"
3262	    "                  [-w provider] [-Z cipher]\n"
3263	    "       ssh-keygen -p [-a rounds] [-f keyfile] [-m format] [-N new_passphrase]\n"
3264	    "                   [-P old_passphrase] [-Z cipher]\n"
3265#ifdef WITH_OPENSSL
3266	    "       ssh-keygen -i [-f input_keyfile] [-m key_format]\n"
3267	    "       ssh-keygen -e [-f input_keyfile] [-m key_format]\n"
3268#endif
3269	    "       ssh-keygen -y [-f input_keyfile]\n"
3270	    "       ssh-keygen -c [-a rounds] [-C comment] [-f keyfile] [-P passphrase]\n"
3271	    "       ssh-keygen -l [-v] [-E fingerprint_hash] [-f input_keyfile]\n"
3272	    "       ssh-keygen -B [-f input_keyfile]\n");
3273#ifdef ENABLE_PKCS11
3274	fprintf(stderr,
3275	    "       ssh-keygen -D pkcs11\n");
3276#endif
3277	fprintf(stderr,
3278	    "       ssh-keygen -F hostname [-lv] [-f known_hosts_file]\n"
3279	    "       ssh-keygen -H [-f known_hosts_file]\n"
3280	    "       ssh-keygen -K [-a rounds] [-w provider]\n"
3281	    "       ssh-keygen -R hostname [-f known_hosts_file]\n"
3282	    "       ssh-keygen -r hostname [-g] [-f input_keyfile]\n"
3283#ifdef WITH_OPENSSL
3284	    "       ssh-keygen -M generate [-O option] output_file\n"
3285	    "       ssh-keygen -M screen [-f input_file] [-O option] output_file\n"
3286#endif
3287	    "       ssh-keygen -I certificate_identity -s ca_key [-hU] [-D pkcs11_provider]\n"
3288	    "                  [-n principals] [-O option] [-V validity_interval]\n"
3289	    "                  [-z serial_number] file ...\n"
3290	    "       ssh-keygen -L [-f input_keyfile]\n"
3291	    "       ssh-keygen -A [-a rounds] [-f prefix_path]\n"
3292	    "       ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number]\n"
3293	    "                  file ...\n"
3294	    "       ssh-keygen -Q [-l] -f krl_file [file ...]\n"
3295	    "       ssh-keygen -Y find-principals -s signature_file -f allowed_signers_file\n"
3296	    "       ssh-keygen -Y match-principals -I signer_identity -f allowed_signers_file\n"
3297	    "       ssh-keygen -Y check-novalidate -n namespace -s signature_file\n"
3298	    "       ssh-keygen -Y sign -f key_file -n namespace file [-O option] ...\n"
3299	    "       ssh-keygen -Y verify -f allowed_signers_file -I signer_identity\n"
3300	    "                  -n namespace -s signature_file [-r krl_file] [-O option]\n");
3301	exit(1);
3302}
3303
3304/*
3305 * Main program for key management.
3306 */
3307int
3308main(int argc, char **argv)
3309{
3310	char comment[1024], *passphrase = NULL;
3311	char *rr_hostname = NULL, *ep, *fp, *ra;
3312	struct sshkey *private, *public;
3313	struct passwd *pw;
3314	int r, opt, type;
3315	int change_passphrase = 0, change_comment = 0, show_cert = 0;
3316	int find_host = 0, delete_host = 0, hash_hosts = 0;
3317	int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0;
3318	int prefer_agent = 0, convert_to = 0, convert_from = 0;
3319	int print_public = 0, print_generic = 0, cert_serial_autoinc = 0;
3320	int do_gen_candidates = 0, do_screen_candidates = 0, download_sk = 0;
3321	unsigned long long cert_serial = 0;
3322	char *identity_comment = NULL, *ca_key_path = NULL, **opts = NULL;
3323	char *sk_application = NULL, *sk_device = NULL, *sk_user = NULL;
3324	char *sk_attestation_path = NULL;
3325	struct sshbuf *challenge = NULL, *attest = NULL;
3326	size_t i, nopts = 0;
3327	u_int32_t bits = 0;
3328	uint8_t sk_flags = SSH_SK_USER_PRESENCE_REQD;
3329	const char *errstr;
3330	int log_level = SYSLOG_LEVEL_INFO;
3331	char *sign_op = NULL;
3332
3333	extern int optind;
3334	extern char *optarg;
3335
3336	/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
3337	sanitise_stdfd();
3338
3339#ifdef WITH_OPENSSL
3340	OpenSSL_add_all_algorithms();
3341#endif
3342	log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);
3343
3344	setlocale(LC_CTYPE, "");
3345
3346	/* we need this for the home * directory.  */
3347	pw = getpwuid(getuid());
3348	if (!pw)
3349		fatal("No user exists for uid %lu", (u_long)getuid());
3350	pw = pwcopy(pw);
3351	if (gethostname(hostname, sizeof(hostname)) == -1)
3352		fatal("gethostname: %s", strerror(errno));
3353
3354	sk_provider = getenv("SSH_SK_PROVIDER");
3355
3356	/* Remaining characters: dGjJSTWx */
3357	while ((opt = getopt(argc, argv, "ABHKLQUXceghiklopquvy"
3358	    "C:D:E:F:I:M:N:O:P:R:V:Y:Z:"
3359	    "a:b:f:g:m:n:r:s:t:w:z:")) != -1) {
3360		switch (opt) {
3361		case 'A':
3362			gen_all_hostkeys = 1;
3363			break;
3364		case 'b':
3365			bits = (u_int32_t)strtonum(optarg, 1, UINT32_MAX,
3366			    &errstr);
3367			if (errstr)
3368				fatal("Bits has bad value %s (%s)",
3369					optarg, errstr);
3370			break;
3371		case 'E':
3372			fingerprint_hash = ssh_digest_alg_by_name(optarg);
3373			if (fingerprint_hash == -1)
3374				fatal("Invalid hash algorithm \"%s\"", optarg);
3375			break;
3376		case 'F':
3377			find_host = 1;
3378			rr_hostname = optarg;
3379			break;
3380		case 'H':
3381			hash_hosts = 1;
3382			break;
3383		case 'I':
3384			cert_key_id = optarg;
3385			break;
3386		case 'R':
3387			delete_host = 1;
3388			rr_hostname = optarg;
3389			break;
3390		case 'L':
3391			show_cert = 1;
3392			break;
3393		case 'l':
3394			print_fingerprint = 1;
3395			break;
3396		case 'B':
3397			print_bubblebabble = 1;
3398			break;
3399		case 'm':
3400			if (strcasecmp(optarg, "RFC4716") == 0 ||
3401			    strcasecmp(optarg, "ssh2") == 0) {
3402				convert_format = FMT_RFC4716;
3403				break;
3404			}
3405			if (strcasecmp(optarg, "PKCS8") == 0) {
3406				convert_format = FMT_PKCS8;
3407				private_key_format = SSHKEY_PRIVATE_PKCS8;
3408				break;
3409			}
3410			if (strcasecmp(optarg, "PEM") == 0) {
3411				convert_format = FMT_PEM;
3412				private_key_format = SSHKEY_PRIVATE_PEM;
3413				break;
3414			}
3415			fatal("Unsupported conversion format \"%s\"", optarg);
3416		case 'n':
3417			cert_principals = optarg;
3418			break;
3419		case 'o':
3420			/* no-op; new format is already the default */
3421			break;
3422		case 'p':
3423			change_passphrase = 1;
3424			break;
3425		case 'c':
3426			change_comment = 1;
3427			break;
3428		case 'f':
3429			if (strlcpy(identity_file, optarg,
3430			    sizeof(identity_file)) >= sizeof(identity_file))
3431				fatal("Identity filename too long");
3432			have_identity = 1;
3433			break;
3434		case 'g':
3435			print_generic = 1;
3436			break;
3437		case 'K':
3438			download_sk = 1;
3439			break;
3440		case 'P':
3441			identity_passphrase = optarg;
3442			break;
3443		case 'N':
3444			identity_new_passphrase = optarg;
3445			break;
3446		case 'Q':
3447			check_krl = 1;
3448			break;
3449		case 'O':
3450			opts = xrecallocarray(opts, nopts, nopts + 1,
3451			    sizeof(*opts));
3452			opts[nopts++] = xstrdup(optarg);
3453			break;
3454		case 'Z':
3455			openssh_format_cipher = optarg;
3456			if (cipher_by_name(openssh_format_cipher) == NULL)
3457				fatal("Invalid OpenSSH-format cipher '%s'",
3458				    openssh_format_cipher);
3459			break;
3460		case 'C':
3461			identity_comment = optarg;
3462			break;
3463		case 'q':
3464			quiet = 1;
3465			break;
3466		case 'e':
3467			/* export key */
3468			convert_to = 1;
3469			break;
3470		case 'h':
3471			cert_key_type = SSH2_CERT_TYPE_HOST;
3472			certflags_flags = 0;
3473			break;
3474		case 'k':
3475			gen_krl = 1;
3476			break;
3477		case 'i':
3478		case 'X':
3479			/* import key */
3480			convert_from = 1;
3481			break;
3482		case 'y':
3483			print_public = 1;
3484			break;
3485		case 's':
3486			ca_key_path = optarg;
3487			break;
3488		case 't':
3489			key_type_name = optarg;
3490			break;
3491		case 'D':
3492			pkcs11provider = optarg;
3493			break;
3494		case 'U':
3495			prefer_agent = 1;
3496			break;
3497		case 'u':
3498			update_krl = 1;
3499			break;
3500		case 'v':
3501			if (log_level == SYSLOG_LEVEL_INFO)
3502				log_level = SYSLOG_LEVEL_DEBUG1;
3503			else {
3504				if (log_level >= SYSLOG_LEVEL_DEBUG1 &&
3505				    log_level < SYSLOG_LEVEL_DEBUG3)
3506					log_level++;
3507			}
3508			break;
3509		case 'r':
3510			rr_hostname = optarg;
3511			break;
3512		case 'a':
3513			rounds = (int)strtonum(optarg, 1, INT_MAX, &errstr);
3514			if (errstr)
3515				fatal("Invalid number: %s (%s)",
3516					optarg, errstr);
3517			break;
3518		case 'V':
3519			parse_cert_times(optarg);
3520			break;
3521		case 'Y':
3522			sign_op = optarg;
3523			break;
3524		case 'w':
3525			sk_provider = optarg;
3526			break;
3527		case 'z':
3528			errno = 0;
3529			if (*optarg == '+') {
3530				cert_serial_autoinc = 1;
3531				optarg++;
3532			}
3533			cert_serial = strtoull(optarg, &ep, 10);
3534			if (*optarg < '0' || *optarg > '9' || *ep != '\0' ||
3535			    (errno == ERANGE && cert_serial == ULLONG_MAX))
3536				fatal("Invalid serial number \"%s\"", optarg);
3537			break;
3538		case 'M':
3539			if (strcmp(optarg, "generate") == 0)
3540				do_gen_candidates = 1;
3541			else if (strcmp(optarg, "screen") == 0)
3542				do_screen_candidates = 1;
3543			else
3544				fatal("Unsupported moduli option %s", optarg);
3545			break;
3546		default:
3547			usage();
3548		}
3549	}
3550
3551	if (sk_provider == NULL)
3552		sk_provider = "internal";
3553
3554	/* reinit */
3555	log_init(argv[0], log_level, SYSLOG_FACILITY_USER, 1);
3556
3557	argv += optind;
3558	argc -= optind;
3559
3560	if (sign_op != NULL) {
3561		if (strncmp(sign_op, "find-principals", 15) == 0) {
3562			if (ca_key_path == NULL) {
3563				error("Too few arguments for find-principals:"
3564				    "missing signature file");
3565				exit(1);
3566			}
3567			if (!have_identity) {
3568				error("Too few arguments for find-principals:"
3569				    "missing allowed keys file");
3570				exit(1);
3571			}
3572			return sig_find_principals(ca_key_path, identity_file,
3573			    opts, nopts);
3574		} else if (strncmp(sign_op, "match-principals", 16) == 0) {
3575			if (!have_identity) {
3576				error("Too few arguments for match-principals:"
3577				    "missing allowed keys file");
3578				exit(1);
3579			}
3580			if (cert_key_id == NULL) {
3581				error("Too few arguments for match-principals: "
3582				    "missing principal ID");
3583				exit(1);
3584			}
3585			return sig_match_principals(identity_file, cert_key_id,
3586			    opts, nopts);
3587		} else if (strncmp(sign_op, "sign", 4) == 0) {
3588			/* NB. cert_principals is actually namespace, via -n */
3589			if (cert_principals == NULL ||
3590			    *cert_principals == '\0') {
3591				error("Too few arguments for sign: "
3592				    "missing namespace");
3593				exit(1);
3594			}
3595			if (!have_identity) {
3596				error("Too few arguments for sign: "
3597				    "missing key");
3598				exit(1);
3599			}
3600			return sig_sign(identity_file, cert_principals,
3601			    prefer_agent, argc, argv, opts, nopts);
3602		} else if (strncmp(sign_op, "check-novalidate", 16) == 0) {
3603			/* NB. cert_principals is actually namespace, via -n */
3604			if (cert_principals == NULL ||
3605			    *cert_principals == '\0') {
3606				error("Too few arguments for check-novalidate: "
3607				    "missing namespace");
3608				exit(1);
3609			}
3610			if (ca_key_path == NULL) {
3611				error("Too few arguments for check-novalidate: "
3612				    "missing signature file");
3613				exit(1);
3614			}
3615			return sig_verify(ca_key_path, cert_principals,
3616			    NULL, NULL, NULL, opts, nopts);
3617		} else if (strncmp(sign_op, "verify", 6) == 0) {
3618			/* NB. cert_principals is actually namespace, via -n */
3619			if (cert_principals == NULL ||
3620			    *cert_principals == '\0') {
3621				error("Too few arguments for verify: "
3622				    "missing namespace");
3623				exit(1);
3624			}
3625			if (ca_key_path == NULL) {
3626				error("Too few arguments for verify: "
3627				    "missing signature file");
3628				exit(1);
3629			}
3630			if (!have_identity) {
3631				error("Too few arguments for sign: "
3632				    "missing allowed keys file");
3633				exit(1);
3634			}
3635			if (cert_key_id == NULL) {
3636				error("Too few arguments for verify: "
3637				    "missing principal identity");
3638				exit(1);
3639			}
3640			return sig_verify(ca_key_path, cert_principals,
3641			    cert_key_id, identity_file, rr_hostname,
3642			    opts, nopts);
3643		}
3644		error("Unsupported operation for -Y: \"%s\"", sign_op);
3645		usage();
3646		/* NOTREACHED */
3647	}
3648
3649	if (ca_key_path != NULL) {
3650		if (argc < 1 && !gen_krl) {
3651			error("Too few arguments.");
3652			usage();
3653		}
3654	} else if (argc > 0 && !gen_krl && !check_krl &&
3655	    !do_gen_candidates && !do_screen_candidates) {
3656		error("Too many arguments.");
3657		usage();
3658	}
3659	if (change_passphrase && change_comment) {
3660		error("Can only have one of -p and -c.");
3661		usage();
3662	}
3663	if (print_fingerprint && (delete_host || hash_hosts)) {
3664		error("Cannot use -l with -H or -R.");
3665		usage();
3666	}
3667	if (gen_krl) {
3668		do_gen_krl(pw, update_krl, ca_key_path,
3669		    cert_serial, identity_comment, argc, argv);
3670		return (0);
3671	}
3672	if (check_krl) {
3673		do_check_krl(pw, print_fingerprint, argc, argv);
3674		return (0);
3675	}
3676	if (ca_key_path != NULL) {
3677		if (cert_key_id == NULL)
3678			fatal("Must specify key id (-I) when certifying");
3679		for (i = 0; i < nopts; i++)
3680			add_cert_option(opts[i]);
3681		do_ca_sign(pw, ca_key_path, prefer_agent,
3682		    cert_serial, cert_serial_autoinc, argc, argv);
3683	}
3684	if (show_cert)
3685		do_show_cert(pw);
3686	if (delete_host || hash_hosts || find_host) {
3687		do_known_hosts(pw, rr_hostname, find_host,
3688		    delete_host, hash_hosts);
3689	}
3690	if (pkcs11provider != NULL)
3691		do_download(pw);
3692	if (download_sk) {
3693		for (i = 0; i < nopts; i++) {
3694			if (strncasecmp(opts[i], "device=", 7) == 0) {
3695				sk_device = xstrdup(opts[i] + 7);
3696			} else {
3697				fatal("Option \"%s\" is unsupported for "
3698				    "FIDO authenticator download", opts[i]);
3699			}
3700		}
3701		return do_download_sk(sk_provider, sk_device);
3702	}
3703	if (print_fingerprint || print_bubblebabble)
3704		do_fingerprint(pw);
3705	if (change_passphrase)
3706		do_change_passphrase(pw);
3707	if (change_comment)
3708		do_change_comment(pw, identity_comment);
3709#ifdef WITH_OPENSSL
3710	if (convert_to)
3711		do_convert_to(pw);
3712	if (convert_from)
3713		do_convert_from(pw);
3714#else /* WITH_OPENSSL */
3715	if (convert_to || convert_from)
3716		fatal("key conversion disabled at compile time");
3717#endif /* WITH_OPENSSL */
3718	if (print_public)
3719		do_print_public(pw);
3720	if (rr_hostname != NULL) {
3721		unsigned int n = 0;
3722
3723		if (have_identity) {
3724			n = do_print_resource_record(pw, identity_file,
3725			    rr_hostname, print_generic, opts, nopts);
3726			if (n == 0)
3727				fatal("%s: %s", identity_file, strerror(errno));
3728			exit(0);
3729		} else {
3730
3731			n += do_print_resource_record(pw,
3732			    _PATH_HOST_RSA_KEY_FILE, rr_hostname,
3733			    print_generic, opts, nopts);
3734			n += do_print_resource_record(pw,
3735			    _PATH_HOST_DSA_KEY_FILE, rr_hostname,
3736			    print_generic, opts, nopts);
3737			n += do_print_resource_record(pw,
3738			    _PATH_HOST_ECDSA_KEY_FILE, rr_hostname,
3739			    print_generic, opts, nopts);
3740			n += do_print_resource_record(pw,
3741			    _PATH_HOST_ED25519_KEY_FILE, rr_hostname,
3742			    print_generic, opts, nopts);
3743			n += do_print_resource_record(pw,
3744			    _PATH_HOST_XMSS_KEY_FILE, rr_hostname,
3745			    print_generic, opts, nopts);
3746			if (n == 0)
3747				fatal("no keys found.");
3748			exit(0);
3749		}
3750	}
3751
3752	if (do_gen_candidates || do_screen_candidates) {
3753		if (argc <= 0)
3754			fatal("No output file specified");
3755		else if (argc > 1)
3756			fatal("Too many output files specified");
3757	}
3758	if (do_gen_candidates) {
3759		do_moduli_gen(argv[0], opts, nopts);
3760		return 0;
3761	}
3762	if (do_screen_candidates) {
3763		do_moduli_screen(argv[0], opts, nopts);
3764		return 0;
3765	}
3766
3767	if (gen_all_hostkeys) {
3768		do_gen_all_hostkeys(pw);
3769		return (0);
3770	}
3771
3772	if (key_type_name == NULL)
3773		key_type_name = DEFAULT_KEY_TYPE_NAME;
3774
3775	type = sshkey_type_from_name(key_type_name);
3776	type_bits_valid(type, key_type_name, &bits);
3777
3778	if (!quiet)
3779		printf("Generating public/private %s key pair.\n",
3780		    key_type_name);
3781	switch (type) {
3782	case KEY_ECDSA_SK:
3783	case KEY_ED25519_SK:
3784		for (i = 0; i < nopts; i++) {
3785			if (strcasecmp(opts[i], "no-touch-required") == 0) {
3786				sk_flags &= ~SSH_SK_USER_PRESENCE_REQD;
3787			} else if (strcasecmp(opts[i], "verify-required") == 0) {
3788				sk_flags |= SSH_SK_USER_VERIFICATION_REQD;
3789			} else if (strcasecmp(opts[i], "resident") == 0) {
3790				sk_flags |= SSH_SK_RESIDENT_KEY;
3791			} else if (strncasecmp(opts[i], "device=", 7) == 0) {
3792				sk_device = xstrdup(opts[i] + 7);
3793			} else if (strncasecmp(opts[i], "user=", 5) == 0) {
3794				sk_user = xstrdup(opts[i] + 5);
3795			} else if (strncasecmp(opts[i], "challenge=", 10) == 0) {
3796				if ((r = sshbuf_load_file(opts[i] + 10,
3797				    &challenge)) != 0) {
3798					fatal_r(r, "Unable to load FIDO "
3799					    "enrollment challenge \"%s\"",
3800					    opts[i] + 10);
3801				}
3802			} else if (strncasecmp(opts[i],
3803			    "write-attestation=", 18) == 0) {
3804				sk_attestation_path = opts[i] + 18;
3805			} else if (strncasecmp(opts[i],
3806			    "application=", 12) == 0) {
3807				sk_application = xstrdup(opts[i] + 12);
3808				if (strncmp(sk_application, "ssh:", 4) != 0) {
3809					fatal("FIDO application string must "
3810					    "begin with \"ssh:\"");
3811				}
3812			} else {
3813				fatal("Option \"%s\" is unsupported for "
3814				    "FIDO authenticator enrollment", opts[i]);
3815			}
3816		}
3817		if ((attest = sshbuf_new()) == NULL)
3818			fatal("sshbuf_new failed");
3819		r = 0;
3820		for (i = 0 ;;) {
3821			if (!quiet) {
3822				printf("You may need to touch your "
3823				    "authenticator%s to authorize key "
3824				    "generation.\n",
3825				    r == 0 ? "" : " again");
3826			}
3827			fflush(stdout);
3828			r = sshsk_enroll(type, sk_provider, sk_device,
3829			    sk_application == NULL ? "ssh:" : sk_application,
3830			    sk_user, sk_flags, passphrase, challenge,
3831			    &private, attest);
3832			if (r == 0)
3833				break;
3834			if (r == SSH_ERR_KEY_BAD_PERMISSIONS &&
3835			    (sk_flags & SSH_SK_RESIDENT_KEY) != 0 &&
3836			    (sk_flags & SSH_SK_FORCE_OPERATION) == 0 &&
3837			    confirm_sk_overwrite(sk_application, sk_user)) {
3838				sk_flags |= SSH_SK_FORCE_OPERATION;
3839				continue;
3840			}
3841			if (r != SSH_ERR_KEY_WRONG_PASSPHRASE)
3842				fatal_r(r, "Key enrollment failed");
3843			else if (passphrase != NULL) {
3844				error("PIN incorrect");
3845				freezero(passphrase, strlen(passphrase));
3846				passphrase = NULL;
3847			}
3848			if (++i >= 3)
3849				fatal("Too many incorrect PINs");
3850			passphrase = read_passphrase("Enter PIN for "
3851			    "authenticator: ", RP_ALLOW_STDIN);
3852		}
3853		if (passphrase != NULL) {
3854			freezero(passphrase, strlen(passphrase));
3855			passphrase = NULL;
3856		}
3857		break;
3858	default:
3859		if ((r = sshkey_generate(type, bits, &private)) != 0)
3860			fatal("sshkey_generate failed");
3861		break;
3862	}
3863	if ((r = sshkey_from_private(private, &public)) != 0)
3864		fatal_r(r, "sshkey_from_private");
3865
3866	if (!have_identity)
3867		ask_filename(pw, "Enter file in which to save the key");
3868
3869	/* Create ~/.ssh directory if it doesn't already exist. */
3870	hostfile_create_user_ssh_dir(identity_file, !quiet);
3871
3872	/* If the file already exists, ask the user to confirm. */
3873	if (!confirm_overwrite(identity_file))
3874		exit(1);
3875
3876	/* Determine the passphrase for the private key */
3877	passphrase = private_key_passphrase();
3878	if (identity_comment) {
3879		strlcpy(comment, identity_comment, sizeof(comment));
3880	} else {
3881		/* Create default comment field for the passphrase. */
3882		snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname);
3883	}
3884
3885	/* Save the key with the given passphrase and comment. */
3886	if ((r = sshkey_save_private(private, identity_file, passphrase,
3887	    comment, private_key_format, openssh_format_cipher, rounds)) != 0) {
3888		error_r(r, "Saving key \"%s\" failed", identity_file);
3889		freezero(passphrase, strlen(passphrase));
3890		exit(1);
3891	}
3892	freezero(passphrase, strlen(passphrase));
3893	sshkey_free(private);
3894
3895	if (!quiet) {
3896		printf("Your identification has been saved in %s\n",
3897		    identity_file);
3898	}
3899
3900	strlcat(identity_file, ".pub", sizeof(identity_file));
3901	if ((r = sshkey_save_public(public, identity_file, comment)) != 0)
3902		fatal_r(r, "Unable to save public key to %s", identity_file);
3903
3904	if (!quiet) {
3905		fp = sshkey_fingerprint(public, fingerprint_hash,
3906		    SSH_FP_DEFAULT);
3907		ra = sshkey_fingerprint(public, fingerprint_hash,
3908		    SSH_FP_RANDOMART);
3909		if (fp == NULL || ra == NULL)
3910			fatal("sshkey_fingerprint failed");
3911		printf("Your public key has been saved in %s\n",
3912		    identity_file);
3913		printf("The key fingerprint is:\n");
3914		printf("%s %s\n", fp, comment);
3915		printf("The key's randomart image is:\n");
3916		printf("%s\n", ra);
3917		free(ra);
3918		free(fp);
3919	}
3920
3921	if (sk_attestation_path != NULL)
3922		save_attestation(attest, sk_attestation_path);
3923
3924	sshbuf_free(attest);
3925	sshkey_free(public);
3926
3927	exit(0);
3928}
3929