ssh-keygen.c revision 262566
1/* $OpenBSD: ssh-keygen.c,v 1.238 2013/12/06 13:39:49 markus Exp $ */
2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 *                    All rights reserved
6 * Identity and host key generation and maintenance.
7 *
8 * As far as I am concerned, the code I have written for this software
9 * can be used freely for any purpose.  Any derived versions of this
10 * software must be clearly marked as such, and if the derived work is
11 * incompatible with the protocol description in the RFC file, it must be
12 * called by a name other than "ssh" or "Secure Shell".
13 */
14
15#include "includes.h"
16
17#include <sys/types.h>
18#include <sys/socket.h>
19#include <sys/stat.h>
20#include <sys/param.h>
21
22#include <openssl/evp.h>
23#include <openssl/pem.h>
24#include "openbsd-compat/openssl-compat.h"
25
26#include <errno.h>
27#include <fcntl.h>
28#include <netdb.h>
29#ifdef HAVE_PATHS_H
30# include <paths.h>
31#endif
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
39#include "xmalloc.h"
40#include "key.h"
41#include "rsa.h"
42#include "authfile.h"
43#include "uuencode.h"
44#include "buffer.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 "ssh-pkcs11.h"
54#include "atomicio.h"
55#include "krl.h"
56
57/* Number of bits in the RSA/DSA key.  This value can be set on the command line. */
58#define DEFAULT_BITS		2048
59#define DEFAULT_BITS_DSA	1024
60#define DEFAULT_BITS_ECDSA	256
61u_int32_t bits = 0;
62
63/*
64 * Flag indicating that we just want to change the passphrase.  This can be
65 * set on the command line.
66 */
67int change_passphrase = 0;
68
69/*
70 * Flag indicating that we just want to change the comment.  This can be set
71 * on the command line.
72 */
73int change_comment = 0;
74
75int quiet = 0;
76
77int log_level = SYSLOG_LEVEL_INFO;
78
79/* Flag indicating that we want to hash a known_hosts file */
80int hash_hosts = 0;
81/* Flag indicating that we want lookup a host in known_hosts file */
82int find_host = 0;
83/* Flag indicating that we want to delete a host from a known_hosts file */
84int delete_host = 0;
85
86/* Flag indicating that we want to show the contents of a certificate */
87int show_cert = 0;
88
89/* Flag indicating that we just want to see the key fingerprint */
90int print_fingerprint = 0;
91int print_bubblebabble = 0;
92
93/* The identity file name, given on the command line or entered by the user. */
94char identity_file[1024];
95int have_identity = 0;
96
97/* This is set to the passphrase if given on the command line. */
98char *identity_passphrase = NULL;
99
100/* This is set to the new passphrase if given on the command line. */
101char *identity_new_passphrase = NULL;
102
103/* This is set to the new comment if given on the command line. */
104char *identity_comment = NULL;
105
106/* Path to CA key when certifying keys. */
107char *ca_key_path = NULL;
108
109/* Certificate serial number */
110unsigned long long cert_serial = 0;
111
112/* Key type when certifying */
113u_int cert_key_type = SSH2_CERT_TYPE_USER;
114
115/* "key ID" of signed key */
116char *cert_key_id = NULL;
117
118/* Comma-separated list of principal names for certifying keys */
119char *cert_principals = NULL;
120
121/* Validity period for certificates */
122u_int64_t cert_valid_from = 0;
123u_int64_t cert_valid_to = ~0ULL;
124
125/* Certificate options */
126#define CERTOPT_X_FWD	(1)
127#define CERTOPT_AGENT_FWD	(1<<1)
128#define CERTOPT_PORT_FWD	(1<<2)
129#define CERTOPT_PTY		(1<<3)
130#define CERTOPT_USER_RC	(1<<4)
131#define CERTOPT_DEFAULT	(CERTOPT_X_FWD|CERTOPT_AGENT_FWD| \
132			 CERTOPT_PORT_FWD|CERTOPT_PTY|CERTOPT_USER_RC)
133u_int32_t certflags_flags = CERTOPT_DEFAULT;
134char *certflags_command = NULL;
135char *certflags_src_addr = NULL;
136
137/* Conversion to/from various formats */
138int convert_to = 0;
139int convert_from = 0;
140enum {
141	FMT_RFC4716,
142	FMT_PKCS8,
143	FMT_PEM
144} convert_format = FMT_RFC4716;
145int print_public = 0;
146int print_generic = 0;
147
148char *key_type_name = NULL;
149
150/* Load key from this PKCS#11 provider */
151char *pkcs11provider = NULL;
152
153/* Use new OpenSSH private key format when writing SSH2 keys instead of PEM */
154int use_new_format = 0;
155
156/* Cipher for new-format private keys */
157char *new_format_cipher = NULL;
158
159/*
160 * Number of KDF rounds to derive new format keys /
161 * number of primality trials when screening moduli.
162 */
163int rounds = 0;
164
165/* argv0 */
166extern char *__progname;
167
168char hostname[MAXHOSTNAMELEN];
169
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
175static void
176type_bits_valid(int type, u_int32_t *bitsp)
177{
178	u_int maxbits;
179
180	if (type == KEY_UNSPEC) {
181		fprintf(stderr, "unknown key type %s\n", key_type_name);
182		exit(1);
183	}
184	if (*bitsp == 0) {
185		if (type == KEY_DSA)
186			*bitsp = DEFAULT_BITS_DSA;
187		else if (type == KEY_ECDSA)
188			*bitsp = DEFAULT_BITS_ECDSA;
189		else
190			*bitsp = DEFAULT_BITS;
191	}
192	maxbits = (type == KEY_DSA) ?
193	    OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS;
194	if (*bitsp > maxbits) {
195		fprintf(stderr, "key bits exceeds maximum %d\n", maxbits);
196		exit(1);
197	}
198	if (type == KEY_DSA && *bitsp != 1024)
199		fatal("DSA keys must be 1024 bits");
200	else if (type != KEY_ECDSA && type != KEY_ED25519 && *bitsp < 768)
201		fatal("Key must at least be 768 bits");
202	else if (type == KEY_ECDSA && key_ecdsa_bits_to_nid(*bitsp) == -1)
203		fatal("Invalid ECDSA key length - valid lengths are "
204		    "256, 384 or 521 bits");
205}
206
207static void
208ask_filename(struct passwd *pw, const char *prompt)
209{
210	char buf[1024];
211	char *name = NULL;
212
213	if (key_type_name == NULL)
214		name = _PATH_SSH_CLIENT_ID_RSA;
215	else {
216		switch (key_type_from_name(key_type_name)) {
217		case KEY_RSA1:
218			name = _PATH_SSH_CLIENT_IDENTITY;
219			break;
220		case KEY_DSA_CERT:
221		case KEY_DSA_CERT_V00:
222		case KEY_DSA:
223			name = _PATH_SSH_CLIENT_ID_DSA;
224			break;
225#ifdef OPENSSL_HAS_ECC
226		case KEY_ECDSA_CERT:
227		case KEY_ECDSA:
228			name = _PATH_SSH_CLIENT_ID_ECDSA;
229			break;
230#endif
231		case KEY_RSA_CERT:
232		case KEY_RSA_CERT_V00:
233		case KEY_RSA:
234			name = _PATH_SSH_CLIENT_ID_RSA;
235			break;
236		case KEY_ED25519:
237		case KEY_ED25519_CERT:
238			name = _PATH_SSH_CLIENT_ID_ED25519;
239			break;
240		default:
241			fprintf(stderr, "bad key type\n");
242			exit(1);
243			break;
244		}
245	}
246	snprintf(identity_file, sizeof(identity_file), "%s/%s", pw->pw_dir, name);
247	fprintf(stderr, "%s (%s): ", prompt, identity_file);
248	if (fgets(buf, sizeof(buf), stdin) == NULL)
249		exit(1);
250	buf[strcspn(buf, "\n")] = '\0';
251	if (strcmp(buf, "") != 0)
252		strlcpy(identity_file, buf, sizeof(identity_file));
253	have_identity = 1;
254}
255
256static Key *
257load_identity(char *filename)
258{
259	char *pass;
260	Key *prv;
261
262	prv = key_load_private(filename, "", NULL);
263	if (prv == NULL) {
264		if (identity_passphrase)
265			pass = xstrdup(identity_passphrase);
266		else
267			pass = read_passphrase("Enter passphrase: ",
268			    RP_ALLOW_STDIN);
269		prv = key_load_private(filename, pass, NULL);
270		memset(pass, 0, strlen(pass));
271		free(pass);
272	}
273	return prv;
274}
275
276#define SSH_COM_PUBLIC_BEGIN		"---- BEGIN SSH2 PUBLIC KEY ----"
277#define SSH_COM_PUBLIC_END		"---- END SSH2 PUBLIC KEY ----"
278#define SSH_COM_PRIVATE_BEGIN		"---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----"
279#define	SSH_COM_PRIVATE_KEY_MAGIC	0x3f6ff9eb
280
281static void
282do_convert_to_ssh2(struct passwd *pw, Key *k)
283{
284	u_int len;
285	u_char *blob;
286	char comment[61];
287
288	if (k->type == KEY_RSA1) {
289		fprintf(stderr, "version 1 keys are not supported\n");
290		exit(1);
291	}
292	if (key_to_blob(k, &blob, &len) <= 0) {
293		fprintf(stderr, "key_to_blob failed\n");
294		exit(1);
295	}
296	/* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */
297	snprintf(comment, sizeof(comment),
298	    "%u-bit %s, converted by %s@%s from OpenSSH",
299	    key_size(k), key_type(k),
300	    pw->pw_name, hostname);
301
302	fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN);
303	fprintf(stdout, "Comment: \"%s\"\n", comment);
304	dump_base64(stdout, blob, len);
305	fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END);
306	key_free(k);
307	free(blob);
308	exit(0);
309}
310
311static void
312do_convert_to_pkcs8(Key *k)
313{
314	switch (key_type_plain(k->type)) {
315	case KEY_RSA1:
316	case KEY_RSA:
317		if (!PEM_write_RSA_PUBKEY(stdout, k->rsa))
318			fatal("PEM_write_RSA_PUBKEY failed");
319		break;
320	case KEY_DSA:
321		if (!PEM_write_DSA_PUBKEY(stdout, k->dsa))
322			fatal("PEM_write_DSA_PUBKEY failed");
323		break;
324#ifdef OPENSSL_HAS_ECC
325	case KEY_ECDSA:
326		if (!PEM_write_EC_PUBKEY(stdout, k->ecdsa))
327			fatal("PEM_write_EC_PUBKEY failed");
328		break;
329#endif
330	default:
331		fatal("%s: unsupported key type %s", __func__, key_type(k));
332	}
333	exit(0);
334}
335
336static void
337do_convert_to_pem(Key *k)
338{
339	switch (key_type_plain(k->type)) {
340	case KEY_RSA1:
341	case KEY_RSA:
342		if (!PEM_write_RSAPublicKey(stdout, k->rsa))
343			fatal("PEM_write_RSAPublicKey failed");
344		break;
345#if notyet /* OpenSSH 0.9.8 lacks this function */
346	case KEY_DSA:
347		if (!PEM_write_DSAPublicKey(stdout, k->dsa))
348			fatal("PEM_write_DSAPublicKey failed");
349		break;
350#endif
351	/* XXX ECDSA? */
352	default:
353		fatal("%s: unsupported key type %s", __func__, key_type(k));
354	}
355	exit(0);
356}
357
358static void
359do_convert_to(struct passwd *pw)
360{
361	Key *k;
362	struct stat st;
363
364	if (!have_identity)
365		ask_filename(pw, "Enter file in which the key is");
366	if (stat(identity_file, &st) < 0)
367		fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
368	if ((k = key_load_public(identity_file, NULL)) == NULL) {
369		if ((k = load_identity(identity_file)) == NULL) {
370			fprintf(stderr, "load failed\n");
371			exit(1);
372		}
373	}
374
375	switch (convert_format) {
376	case FMT_RFC4716:
377		do_convert_to_ssh2(pw, k);
378		break;
379	case FMT_PKCS8:
380		do_convert_to_pkcs8(k);
381		break;
382	case FMT_PEM:
383		do_convert_to_pem(k);
384		break;
385	default:
386		fatal("%s: unknown key format %d", __func__, convert_format);
387	}
388	exit(0);
389}
390
391static void
392buffer_get_bignum_bits(Buffer *b, BIGNUM *value)
393{
394	u_int bignum_bits = buffer_get_int(b);
395	u_int bytes = (bignum_bits + 7) / 8;
396
397	if (buffer_len(b) < bytes)
398		fatal("buffer_get_bignum_bits: input buffer too small: "
399		    "need %d have %d", bytes, buffer_len(b));
400	if (BN_bin2bn(buffer_ptr(b), bytes, value) == NULL)
401		fatal("buffer_get_bignum_bits: BN_bin2bn failed");
402	buffer_consume(b, bytes);
403}
404
405static Key *
406do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
407{
408	Buffer b;
409	Key *key = NULL;
410	char *type, *cipher;
411	u_char *sig, data[] = "abcde12345";
412	int magic, rlen, ktype, i1, i2, i3, i4;
413	u_int slen;
414	u_long e;
415
416	buffer_init(&b);
417	buffer_append(&b, blob, blen);
418
419	magic = buffer_get_int(&b);
420	if (magic != SSH_COM_PRIVATE_KEY_MAGIC) {
421		error("bad magic 0x%x != 0x%x", magic, SSH_COM_PRIVATE_KEY_MAGIC);
422		buffer_free(&b);
423		return NULL;
424	}
425	i1 = buffer_get_int(&b);
426	type   = buffer_get_string(&b, NULL);
427	cipher = buffer_get_string(&b, NULL);
428	i2 = buffer_get_int(&b);
429	i3 = buffer_get_int(&b);
430	i4 = buffer_get_int(&b);
431	debug("ignore (%d %d %d %d)", i1, i2, i3, i4);
432	if (strcmp(cipher, "none") != 0) {
433		error("unsupported cipher %s", cipher);
434		free(cipher);
435		buffer_free(&b);
436		free(type);
437		return NULL;
438	}
439	free(cipher);
440
441	if (strstr(type, "dsa")) {
442		ktype = KEY_DSA;
443	} else if (strstr(type, "rsa")) {
444		ktype = KEY_RSA;
445	} else {
446		buffer_free(&b);
447		free(type);
448		return NULL;
449	}
450	key = key_new_private(ktype);
451	free(type);
452
453	switch (key->type) {
454	case KEY_DSA:
455		buffer_get_bignum_bits(&b, key->dsa->p);
456		buffer_get_bignum_bits(&b, key->dsa->g);
457		buffer_get_bignum_bits(&b, key->dsa->q);
458		buffer_get_bignum_bits(&b, key->dsa->pub_key);
459		buffer_get_bignum_bits(&b, key->dsa->priv_key);
460		break;
461	case KEY_RSA:
462		e = buffer_get_char(&b);
463		debug("e %lx", e);
464		if (e < 30) {
465			e <<= 8;
466			e += buffer_get_char(&b);
467			debug("e %lx", e);
468			e <<= 8;
469			e += buffer_get_char(&b);
470			debug("e %lx", e);
471		}
472		if (!BN_set_word(key->rsa->e, e)) {
473			buffer_free(&b);
474			key_free(key);
475			return NULL;
476		}
477		buffer_get_bignum_bits(&b, key->rsa->d);
478		buffer_get_bignum_bits(&b, key->rsa->n);
479		buffer_get_bignum_bits(&b, key->rsa->iqmp);
480		buffer_get_bignum_bits(&b, key->rsa->q);
481		buffer_get_bignum_bits(&b, key->rsa->p);
482		rsa_generate_additional_parameters(key->rsa);
483		break;
484	}
485	rlen = buffer_len(&b);
486	if (rlen != 0)
487		error("do_convert_private_ssh2_from_blob: "
488		    "remaining bytes in key blob %d", rlen);
489	buffer_free(&b);
490
491	/* try the key */
492	key_sign(key, &sig, &slen, data, sizeof(data));
493	key_verify(key, sig, slen, data, sizeof(data));
494	free(sig);
495	return key;
496}
497
498static int
499get_line(FILE *fp, char *line, size_t len)
500{
501	int c;
502	size_t pos = 0;
503
504	line[0] = '\0';
505	while ((c = fgetc(fp)) != EOF) {
506		if (pos >= len - 1) {
507			fprintf(stderr, "input line too long.\n");
508			exit(1);
509		}
510		switch (c) {
511		case '\r':
512			c = fgetc(fp);
513			if (c != EOF && c != '\n' && ungetc(c, fp) == EOF) {
514				fprintf(stderr, "unget: %s\n", strerror(errno));
515				exit(1);
516			}
517			return pos;
518		case '\n':
519			return pos;
520		}
521		line[pos++] = c;
522		line[pos] = '\0';
523	}
524	/* We reached EOF */
525	return -1;
526}
527
528static void
529do_convert_from_ssh2(struct passwd *pw, Key **k, int *private)
530{
531	int blen;
532	u_int len;
533	char line[1024];
534	u_char blob[8096];
535	char encoded[8096];
536	int escaped = 0;
537	FILE *fp;
538
539	if ((fp = fopen(identity_file, "r")) == NULL)
540		fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
541	encoded[0] = '\0';
542	while ((blen = get_line(fp, line, sizeof(line))) != -1) {
543		if (blen > 0 && line[blen - 1] == '\\')
544			escaped++;
545		if (strncmp(line, "----", 4) == 0 ||
546		    strstr(line, ": ") != NULL) {
547			if (strstr(line, SSH_COM_PRIVATE_BEGIN) != NULL)
548				*private = 1;
549			if (strstr(line, " END ") != NULL) {
550				break;
551			}
552			/* fprintf(stderr, "ignore: %s", line); */
553			continue;
554		}
555		if (escaped) {
556			escaped--;
557			/* fprintf(stderr, "escaped: %s", line); */
558			continue;
559		}
560		strlcat(encoded, line, sizeof(encoded));
561	}
562	len = strlen(encoded);
563	if (((len % 4) == 3) &&
564	    (encoded[len-1] == '=') &&
565	    (encoded[len-2] == '=') &&
566	    (encoded[len-3] == '='))
567		encoded[len-3] = '\0';
568	blen = uudecode(encoded, blob, sizeof(blob));
569	if (blen < 0) {
570		fprintf(stderr, "uudecode failed.\n");
571		exit(1);
572	}
573	*k = *private ?
574	    do_convert_private_ssh2_from_blob(blob, blen) :
575	    key_from_blob(blob, blen);
576	if (*k == NULL) {
577		fprintf(stderr, "decode blob failed.\n");
578		exit(1);
579	}
580	fclose(fp);
581}
582
583static void
584do_convert_from_pkcs8(Key **k, int *private)
585{
586	EVP_PKEY *pubkey;
587	FILE *fp;
588
589	if ((fp = fopen(identity_file, "r")) == NULL)
590		fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
591	if ((pubkey = PEM_read_PUBKEY(fp, NULL, NULL, NULL)) == NULL) {
592		fatal("%s: %s is not a recognised public key format", __func__,
593		    identity_file);
594	}
595	fclose(fp);
596	switch (EVP_PKEY_type(pubkey->type)) {
597	case EVP_PKEY_RSA:
598		*k = key_new(KEY_UNSPEC);
599		(*k)->type = KEY_RSA;
600		(*k)->rsa = EVP_PKEY_get1_RSA(pubkey);
601		break;
602	case EVP_PKEY_DSA:
603		*k = key_new(KEY_UNSPEC);
604		(*k)->type = KEY_DSA;
605		(*k)->dsa = EVP_PKEY_get1_DSA(pubkey);
606		break;
607#ifdef OPENSSL_HAS_ECC
608	case EVP_PKEY_EC:
609		*k = key_new(KEY_UNSPEC);
610		(*k)->type = KEY_ECDSA;
611		(*k)->ecdsa = EVP_PKEY_get1_EC_KEY(pubkey);
612		(*k)->ecdsa_nid = key_ecdsa_key_to_nid((*k)->ecdsa);
613		break;
614#endif
615	default:
616		fatal("%s: unsupported pubkey type %d", __func__,
617		    EVP_PKEY_type(pubkey->type));
618	}
619	EVP_PKEY_free(pubkey);
620	return;
621}
622
623static void
624do_convert_from_pem(Key **k, int *private)
625{
626	FILE *fp;
627	RSA *rsa;
628#ifdef notyet
629	DSA *dsa;
630#endif
631
632	if ((fp = fopen(identity_file, "r")) == NULL)
633		fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
634	if ((rsa = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL)) != NULL) {
635		*k = key_new(KEY_UNSPEC);
636		(*k)->type = KEY_RSA;
637		(*k)->rsa = rsa;
638		fclose(fp);
639		return;
640	}
641#if notyet /* OpenSSH 0.9.8 lacks this function */
642	rewind(fp);
643	if ((dsa = PEM_read_DSAPublicKey(fp, NULL, NULL, NULL)) != NULL) {
644		*k = key_new(KEY_UNSPEC);
645		(*k)->type = KEY_DSA;
646		(*k)->dsa = dsa;
647		fclose(fp);
648		return;
649	}
650	/* XXX ECDSA */
651#endif
652	fatal("%s: unrecognised raw private key format", __func__);
653}
654
655static void
656do_convert_from(struct passwd *pw)
657{
658	Key *k = NULL;
659	int private = 0, ok = 0;
660	struct stat st;
661
662	if (!have_identity)
663		ask_filename(pw, "Enter file in which the key is");
664	if (stat(identity_file, &st) < 0)
665		fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
666
667	switch (convert_format) {
668	case FMT_RFC4716:
669		do_convert_from_ssh2(pw, &k, &private);
670		break;
671	case FMT_PKCS8:
672		do_convert_from_pkcs8(&k, &private);
673		break;
674	case FMT_PEM:
675		do_convert_from_pem(&k, &private);
676		break;
677	default:
678		fatal("%s: unknown key format %d", __func__, convert_format);
679	}
680
681	if (!private)
682		ok = key_write(k, stdout);
683		if (ok)
684			fprintf(stdout, "\n");
685	else {
686		switch (k->type) {
687		case KEY_DSA:
688			ok = PEM_write_DSAPrivateKey(stdout, k->dsa, NULL,
689			    NULL, 0, NULL, NULL);
690			break;
691#ifdef OPENSSL_HAS_ECC
692		case KEY_ECDSA:
693			ok = PEM_write_ECPrivateKey(stdout, k->ecdsa, NULL,
694			    NULL, 0, NULL, NULL);
695			break;
696#endif
697		case KEY_RSA:
698			ok = PEM_write_RSAPrivateKey(stdout, k->rsa, NULL,
699			    NULL, 0, NULL, NULL);
700			break;
701		default:
702			fatal("%s: unsupported key type %s", __func__,
703			    key_type(k));
704		}
705	}
706
707	if (!ok) {
708		fprintf(stderr, "key write failed\n");
709		exit(1);
710	}
711	key_free(k);
712	exit(0);
713}
714
715static void
716do_print_public(struct passwd *pw)
717{
718	Key *prv;
719	struct stat st;
720
721	if (!have_identity)
722		ask_filename(pw, "Enter file in which the key is");
723	if (stat(identity_file, &st) < 0) {
724		perror(identity_file);
725		exit(1);
726	}
727	prv = load_identity(identity_file);
728	if (prv == NULL) {
729		fprintf(stderr, "load failed\n");
730		exit(1);
731	}
732	if (!key_write(prv, stdout))
733		fprintf(stderr, "key_write failed");
734	key_free(prv);
735	fprintf(stdout, "\n");
736	exit(0);
737}
738
739static void
740do_download(struct passwd *pw)
741{
742#ifdef ENABLE_PKCS11
743	Key **keys = NULL;
744	int i, nkeys;
745	enum fp_rep rep;
746	enum fp_type fptype;
747	char *fp, *ra;
748
749	fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;
750	rep =    print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX;
751
752	pkcs11_init(0);
753	nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys);
754	if (nkeys <= 0)
755		fatal("cannot read public key from pkcs11");
756	for (i = 0; i < nkeys; i++) {
757		if (print_fingerprint) {
758			fp = key_fingerprint(keys[i], fptype, rep);
759			ra = key_fingerprint(keys[i], SSH_FP_MD5,
760			    SSH_FP_RANDOMART);
761			printf("%u %s %s (PKCS11 key)\n", key_size(keys[i]),
762			    fp, key_type(keys[i]));
763			if (log_level >= SYSLOG_LEVEL_VERBOSE)
764				printf("%s\n", ra);
765			free(ra);
766			free(fp);
767		} else {
768			key_write(keys[i], stdout);
769			fprintf(stdout, "\n");
770		}
771		key_free(keys[i]);
772	}
773	free(keys);
774	pkcs11_terminate();
775	exit(0);
776#else
777	fatal("no pkcs11 support");
778#endif /* ENABLE_PKCS11 */
779}
780
781static void
782do_fingerprint(struct passwd *pw)
783{
784	FILE *f;
785	Key *public;
786	char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra;
787	int i, skip = 0, num = 0, invalid = 1;
788	enum fp_rep rep;
789	enum fp_type fptype;
790	struct stat st;
791
792	fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;
793	rep =    print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX;
794
795	if (!have_identity)
796		ask_filename(pw, "Enter file in which the key is");
797	if (stat(identity_file, &st) < 0) {
798		perror(identity_file);
799		exit(1);
800	}
801	public = key_load_public(identity_file, &comment);
802	if (public != NULL) {
803		fp = key_fingerprint(public, fptype, rep);
804		ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
805		printf("%u %s %s (%s)\n", key_size(public), fp, comment,
806		    key_type(public));
807		if (log_level >= SYSLOG_LEVEL_VERBOSE)
808			printf("%s\n", ra);
809		key_free(public);
810		free(comment);
811		free(ra);
812		free(fp);
813		exit(0);
814	}
815	if (comment) {
816		free(comment);
817		comment = NULL;
818	}
819
820	if ((f = fopen(identity_file, "r")) == NULL)
821		fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
822
823	while (fgets(line, sizeof(line), f)) {
824		if ((cp = strchr(line, '\n')) == NULL) {
825			error("line %d too long: %.40s...",
826			    num + 1, line);
827			skip = 1;
828			continue;
829		}
830		num++;
831		if (skip) {
832			skip = 0;
833			continue;
834		}
835		*cp = '\0';
836
837		/* Skip leading whitespace, empty and comment lines. */
838		for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
839			;
840		if (!*cp || *cp == '\n' || *cp == '#')
841			continue;
842		i = strtol(cp, &ep, 10);
843		if (i == 0 || ep == NULL || (*ep != ' ' && *ep != '\t')) {
844			int quoted = 0;
845			comment = cp;
846			for (; *cp && (quoted || (*cp != ' ' &&
847			    *cp != '\t')); cp++) {
848				if (*cp == '\\' && cp[1] == '"')
849					cp++;	/* Skip both */
850				else if (*cp == '"')
851					quoted = !quoted;
852			}
853			if (!*cp)
854				continue;
855			*cp++ = '\0';
856		}
857		ep = cp;
858		public = key_new(KEY_RSA1);
859		if (key_read(public, &cp) != 1) {
860			cp = ep;
861			key_free(public);
862			public = key_new(KEY_UNSPEC);
863			if (key_read(public, &cp) != 1) {
864				key_free(public);
865				continue;
866			}
867		}
868		comment = *cp ? cp : comment;
869		fp = key_fingerprint(public, fptype, rep);
870		ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
871		printf("%u %s %s (%s)\n", key_size(public), fp,
872		    comment ? comment : "no comment", key_type(public));
873		if (log_level >= SYSLOG_LEVEL_VERBOSE)
874			printf("%s\n", ra);
875		free(ra);
876		free(fp);
877		key_free(public);
878		invalid = 0;
879	}
880	fclose(f);
881
882	if (invalid) {
883		printf("%s is not a public key file.\n", identity_file);
884		exit(1);
885	}
886	exit(0);
887}
888
889static void
890do_gen_all_hostkeys(struct passwd *pw)
891{
892	struct {
893		char *key_type;
894		char *key_type_display;
895		char *path;
896	} key_types[] = {
897		{ "rsa1", "RSA1", _PATH_HOST_KEY_FILE },
898		{ "rsa", "RSA" ,_PATH_HOST_RSA_KEY_FILE },
899		{ "dsa", "DSA", _PATH_HOST_DSA_KEY_FILE },
900#ifdef OPENSSL_HAS_ECC
901		{ "ecdsa", "ECDSA",_PATH_HOST_ECDSA_KEY_FILE },
902#endif
903		{ "ed25519", "ED25519",_PATH_HOST_ED25519_KEY_FILE },
904		{ NULL, NULL, NULL }
905	};
906
907	int first = 0;
908	struct stat st;
909	Key *private, *public;
910	char comment[1024];
911	int i, type, fd;
912	FILE *f;
913
914	for (i = 0; key_types[i].key_type; i++) {
915		if (stat(key_types[i].path, &st) == 0)
916			continue;
917		if (errno != ENOENT) {
918			printf("Could not stat %s: %s", key_types[i].path,
919			    strerror(errno));
920			first = 0;
921			continue;
922		}
923
924		if (first == 0) {
925			first = 1;
926			printf("%s: generating new host keys: ", __progname);
927		}
928		printf("%s ", key_types[i].key_type_display);
929		fflush(stdout);
930		type = key_type_from_name(key_types[i].key_type);
931		strlcpy(identity_file, key_types[i].path, sizeof(identity_file));
932		bits = 0;
933		type_bits_valid(type, &bits);
934		private = key_generate(type, bits);
935		if (private == NULL) {
936			fprintf(stderr, "key_generate failed\n");
937			first = 0;
938			continue;
939		}
940		public  = key_from_private(private);
941		snprintf(comment, sizeof comment, "%s@%s", pw->pw_name,
942		    hostname);
943		if (!key_save_private(private, identity_file, "", comment,
944		    use_new_format, new_format_cipher, rounds)) {
945			printf("Saving the key failed: %s.\n", identity_file);
946			key_free(private);
947			key_free(public);
948			first = 0;
949			continue;
950		}
951		key_free(private);
952		strlcat(identity_file, ".pub", sizeof(identity_file));
953		fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
954		if (fd == -1) {
955			printf("Could not save your public key in %s\n",
956			    identity_file);
957			key_free(public);
958			first = 0;
959			continue;
960		}
961		f = fdopen(fd, "w");
962		if (f == NULL) {
963			printf("fdopen %s failed\n", identity_file);
964			key_free(public);
965			first = 0;
966			continue;
967		}
968		if (!key_write(public, f)) {
969			fprintf(stderr, "write key failed\n");
970			key_free(public);
971			first = 0;
972			continue;
973		}
974		fprintf(f, " %s\n", comment);
975		fclose(f);
976		key_free(public);
977
978	}
979	if (first != 0)
980		printf("\n");
981}
982
983static void
984printhost(FILE *f, const char *name, Key *public, int ca, int hash)
985{
986	if (print_fingerprint) {
987		enum fp_rep rep;
988		enum fp_type fptype;
989		char *fp, *ra;
990
991		fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;
992		rep =    print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX;
993		fp = key_fingerprint(public, fptype, rep);
994		ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
995		printf("%u %s %s (%s)\n", key_size(public), fp, name,
996		    key_type(public));
997		if (log_level >= SYSLOG_LEVEL_VERBOSE)
998			printf("%s\n", ra);
999		free(ra);
1000		free(fp);
1001	} else {
1002		if (hash && (name = host_hash(name, NULL, 0)) == NULL)
1003			fatal("hash_host failed");
1004		fprintf(f, "%s%s%s ", ca ? CA_MARKER : "", ca ? " " : "", name);
1005		if (!key_write(public, f))
1006			fatal("key_write failed");
1007		fprintf(f, "\n");
1008	}
1009}
1010
1011static void
1012do_known_hosts(struct passwd *pw, const char *name)
1013{
1014	FILE *in, *out = stdout;
1015	Key *pub;
1016	char *cp, *cp2, *kp, *kp2;
1017	char line[16*1024], tmp[MAXPATHLEN], old[MAXPATHLEN];
1018	int c, skip = 0, inplace = 0, num = 0, invalid = 0, has_unhashed = 0;
1019	int ca;
1020	int found_key = 0;
1021
1022	if (!have_identity) {
1023		cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid);
1024		if (strlcpy(identity_file, cp, sizeof(identity_file)) >=
1025		    sizeof(identity_file))
1026			fatal("Specified known hosts path too long");
1027		free(cp);
1028		have_identity = 1;
1029	}
1030	if ((in = fopen(identity_file, "r")) == NULL)
1031		fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
1032
1033	/*
1034	 * Find hosts goes to stdout, hash and deletions happen in-place
1035	 * A corner case is ssh-keygen -HF foo, which should go to stdout
1036	 */
1037	if (!find_host && (hash_hosts || delete_host)) {
1038		if (strlcpy(tmp, identity_file, sizeof(tmp)) >= sizeof(tmp) ||
1039		    strlcat(tmp, ".XXXXXXXXXX", sizeof(tmp)) >= sizeof(tmp) ||
1040		    strlcpy(old, identity_file, sizeof(old)) >= sizeof(old) ||
1041		    strlcat(old, ".old", sizeof(old)) >= sizeof(old))
1042			fatal("known_hosts path too long");
1043		umask(077);
1044		if ((c = mkstemp(tmp)) == -1)
1045			fatal("mkstemp: %s", strerror(errno));
1046		if ((out = fdopen(c, "w")) == NULL) {
1047			c = errno;
1048			unlink(tmp);
1049			fatal("fdopen: %s", strerror(c));
1050		}
1051		inplace = 1;
1052	}
1053
1054	while (fgets(line, sizeof(line), in)) {
1055		if ((cp = strchr(line, '\n')) == NULL) {
1056			error("line %d too long: %.40s...", num + 1, line);
1057			skip = 1;
1058			invalid = 1;
1059			continue;
1060		}
1061		num++;
1062		if (skip) {
1063			skip = 0;
1064			continue;
1065		}
1066		*cp = '\0';
1067
1068		/* Skip leading whitespace, empty and comment lines. */
1069		for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
1070			;
1071		if (!*cp || *cp == '\n' || *cp == '#') {
1072			if (inplace)
1073				fprintf(out, "%s\n", cp);
1074			continue;
1075		}
1076		/* Check whether this is a CA key */
1077		if (strncasecmp(cp, CA_MARKER, sizeof(CA_MARKER) - 1) == 0 &&
1078		    (cp[sizeof(CA_MARKER) - 1] == ' ' ||
1079		    cp[sizeof(CA_MARKER) - 1] == '\t')) {
1080			ca = 1;
1081			cp += sizeof(CA_MARKER);
1082		} else
1083			ca = 0;
1084
1085		/* Find the end of the host name portion. */
1086		for (kp = cp; *kp && *kp != ' ' && *kp != '\t'; kp++)
1087			;
1088
1089		if (*kp == '\0' || *(kp + 1) == '\0') {
1090			error("line %d missing key: %.40s...",
1091			    num, line);
1092			invalid = 1;
1093			continue;
1094		}
1095		*kp++ = '\0';
1096		kp2 = kp;
1097
1098		pub = key_new(KEY_RSA1);
1099		if (key_read(pub, &kp) != 1) {
1100			kp = kp2;
1101			key_free(pub);
1102			pub = key_new(KEY_UNSPEC);
1103			if (key_read(pub, &kp) != 1) {
1104				error("line %d invalid key: %.40s...",
1105				    num, line);
1106				key_free(pub);
1107				invalid = 1;
1108				continue;
1109			}
1110		}
1111
1112		if (*cp == HASH_DELIM) {
1113			if (find_host || delete_host) {
1114				cp2 = host_hash(name, cp, strlen(cp));
1115				if (cp2 == NULL) {
1116					error("line %d: invalid hashed "
1117					    "name: %.64s...", num, line);
1118					invalid = 1;
1119					continue;
1120				}
1121				c = (strcmp(cp2, cp) == 0);
1122				if (find_host && c) {
1123					if (!quiet)
1124						printf("# Host %s found: "
1125						    "line %d type %s%s\n", name,
1126						    num, key_type(pub),
1127						    ca ? " (CA key)" : "");
1128					printhost(out, cp, pub, ca, 0);
1129					found_key = 1;
1130				}
1131				if (delete_host) {
1132					if (!c && !ca)
1133						printhost(out, cp, pub, ca, 0);
1134					else
1135						printf("# Host %s found: "
1136						    "line %d type %s\n", name,
1137						    num, key_type(pub));
1138				}
1139			} else if (hash_hosts)
1140				printhost(out, cp, pub, ca, 0);
1141		} else {
1142			if (find_host || delete_host) {
1143				c = (match_hostname(name, cp,
1144				    strlen(cp)) == 1);
1145				if (find_host && c) {
1146					if (!quiet)
1147						printf("# Host %s found: "
1148						    "line %d type %s%s\n", name,
1149						    num, key_type(pub),
1150						    ca ? " (CA key)" : "");
1151					printhost(out, name, pub,
1152					    ca, hash_hosts && !ca);
1153					found_key = 1;
1154				}
1155				if (delete_host) {
1156					if (!c && !ca)
1157						printhost(out, cp, pub, ca, 0);
1158					else
1159						printf("# Host %s found: "
1160						    "line %d type %s\n", name,
1161						    num, key_type(pub));
1162				}
1163			} else if (hash_hosts) {
1164				for (cp2 = strsep(&cp, ",");
1165				    cp2 != NULL && *cp2 != '\0';
1166				    cp2 = strsep(&cp, ",")) {
1167					if (ca) {
1168						fprintf(stderr, "Warning: "
1169						    "ignoring CA key for host: "
1170						    "%.64s\n", cp2);
1171						printhost(out, cp2, pub, ca, 0);
1172					} else if (strcspn(cp2, "*?!") !=
1173					    strlen(cp2)) {
1174						fprintf(stderr, "Warning: "
1175						    "ignoring host name with "
1176						    "metacharacters: %.64s\n",
1177						    cp2);
1178						printhost(out, cp2, pub, ca, 0);
1179					} else
1180						printhost(out, cp2, pub, ca, 1);
1181				}
1182				has_unhashed = 1;
1183			}
1184		}
1185		key_free(pub);
1186	}
1187	fclose(in);
1188
1189	if (invalid) {
1190		fprintf(stderr, "%s is not a valid known_hosts file.\n",
1191		    identity_file);
1192		if (inplace) {
1193			fprintf(stderr, "Not replacing existing known_hosts "
1194			    "file because of errors\n");
1195			fclose(out);
1196			unlink(tmp);
1197		}
1198		exit(1);
1199	}
1200
1201	if (inplace) {
1202		fclose(out);
1203
1204		/* Backup existing file */
1205		if (unlink(old) == -1 && errno != ENOENT)
1206			fatal("unlink %.100s: %s", old, strerror(errno));
1207		if (link(identity_file, old) == -1)
1208			fatal("link %.100s to %.100s: %s", identity_file, old,
1209			    strerror(errno));
1210		/* Move new one into place */
1211		if (rename(tmp, identity_file) == -1) {
1212			error("rename\"%s\" to \"%s\": %s", tmp, identity_file,
1213			    strerror(errno));
1214			unlink(tmp);
1215			unlink(old);
1216			exit(1);
1217		}
1218
1219		fprintf(stderr, "%s updated.\n", identity_file);
1220		fprintf(stderr, "Original contents retained as %s\n", old);
1221		if (has_unhashed) {
1222			fprintf(stderr, "WARNING: %s contains unhashed "
1223			    "entries\n", old);
1224			fprintf(stderr, "Delete this file to ensure privacy "
1225			    "of hostnames\n");
1226		}
1227	}
1228
1229	exit (find_host && !found_key);
1230}
1231
1232/*
1233 * Perform changing a passphrase.  The argument is the passwd structure
1234 * for the current user.
1235 */
1236static void
1237do_change_passphrase(struct passwd *pw)
1238{
1239	char *comment;
1240	char *old_passphrase, *passphrase1, *passphrase2;
1241	struct stat st;
1242	Key *private;
1243
1244	if (!have_identity)
1245		ask_filename(pw, "Enter file in which the key is");
1246	if (stat(identity_file, &st) < 0) {
1247		perror(identity_file);
1248		exit(1);
1249	}
1250	/* Try to load the file with empty passphrase. */
1251	private = key_load_private(identity_file, "", &comment);
1252	if (private == NULL) {
1253		if (identity_passphrase)
1254			old_passphrase = xstrdup(identity_passphrase);
1255		else
1256			old_passphrase =
1257			    read_passphrase("Enter old passphrase: ",
1258			    RP_ALLOW_STDIN);
1259		private = key_load_private(identity_file, old_passphrase,
1260		    &comment);
1261		memset(old_passphrase, 0, strlen(old_passphrase));
1262		free(old_passphrase);
1263		if (private == NULL) {
1264			printf("Bad passphrase.\n");
1265			exit(1);
1266		}
1267	}
1268	printf("Key has comment '%s'\n", comment);
1269
1270	/* Ask the new passphrase (twice). */
1271	if (identity_new_passphrase) {
1272		passphrase1 = xstrdup(identity_new_passphrase);
1273		passphrase2 = NULL;
1274	} else {
1275		passphrase1 =
1276			read_passphrase("Enter new passphrase (empty for no "
1277			    "passphrase): ", RP_ALLOW_STDIN);
1278		passphrase2 = read_passphrase("Enter same passphrase again: ",
1279		    RP_ALLOW_STDIN);
1280
1281		/* Verify that they are the same. */
1282		if (strcmp(passphrase1, passphrase2) != 0) {
1283			memset(passphrase1, 0, strlen(passphrase1));
1284			memset(passphrase2, 0, strlen(passphrase2));
1285			free(passphrase1);
1286			free(passphrase2);
1287			printf("Pass phrases do not match.  Try again.\n");
1288			exit(1);
1289		}
1290		/* Destroy the other copy. */
1291		memset(passphrase2, 0, strlen(passphrase2));
1292		free(passphrase2);
1293	}
1294
1295	/* Save the file using the new passphrase. */
1296	if (!key_save_private(private, identity_file, passphrase1, comment,
1297	    use_new_format, new_format_cipher, rounds)) {
1298		printf("Saving the key failed: %s.\n", identity_file);
1299		memset(passphrase1, 0, strlen(passphrase1));
1300		free(passphrase1);
1301		key_free(private);
1302		free(comment);
1303		exit(1);
1304	}
1305	/* Destroy the passphrase and the copy of the key in memory. */
1306	memset(passphrase1, 0, strlen(passphrase1));
1307	free(passphrase1);
1308	key_free(private);		 /* Destroys contents */
1309	free(comment);
1310
1311	printf("Your identification has been saved with the new passphrase.\n");
1312	exit(0);
1313}
1314
1315/*
1316 * Print the SSHFP RR.
1317 */
1318static int
1319do_print_resource_record(struct passwd *pw, char *fname, char *hname)
1320{
1321	Key *public;
1322	char *comment = NULL;
1323	struct stat st;
1324
1325	if (fname == NULL)
1326		fatal("%s: no filename", __func__);
1327	if (stat(fname, &st) < 0) {
1328		if (errno == ENOENT)
1329			return 0;
1330		perror(fname);
1331		exit(1);
1332	}
1333	public = key_load_public(fname, &comment);
1334	if (public != NULL) {
1335		export_dns_rr(hname, public, stdout, print_generic);
1336		key_free(public);
1337		free(comment);
1338		return 1;
1339	}
1340	if (comment)
1341		free(comment);
1342
1343	printf("failed to read v2 public key from %s.\n", fname);
1344	exit(1);
1345}
1346
1347/*
1348 * Change the comment of a private key file.
1349 */
1350static void
1351do_change_comment(struct passwd *pw)
1352{
1353	char new_comment[1024], *comment, *passphrase;
1354	Key *private;
1355	Key *public;
1356	struct stat st;
1357	FILE *f;
1358	int fd;
1359
1360	if (!have_identity)
1361		ask_filename(pw, "Enter file in which the key is");
1362	if (stat(identity_file, &st) < 0) {
1363		perror(identity_file);
1364		exit(1);
1365	}
1366	private = key_load_private(identity_file, "", &comment);
1367	if (private == NULL) {
1368		if (identity_passphrase)
1369			passphrase = xstrdup(identity_passphrase);
1370		else if (identity_new_passphrase)
1371			passphrase = xstrdup(identity_new_passphrase);
1372		else
1373			passphrase = read_passphrase("Enter passphrase: ",
1374			    RP_ALLOW_STDIN);
1375		/* Try to load using the passphrase. */
1376		private = key_load_private(identity_file, passphrase, &comment);
1377		if (private == NULL) {
1378			memset(passphrase, 0, strlen(passphrase));
1379			free(passphrase);
1380			printf("Bad passphrase.\n");
1381			exit(1);
1382		}
1383	} else {
1384		passphrase = xstrdup("");
1385	}
1386	if (private->type != KEY_RSA1) {
1387		fprintf(stderr, "Comments are only supported for RSA1 keys.\n");
1388		key_free(private);
1389		exit(1);
1390	}
1391	printf("Key now has comment '%s'\n", comment);
1392
1393	if (identity_comment) {
1394		strlcpy(new_comment, identity_comment, sizeof(new_comment));
1395	} else {
1396		printf("Enter new comment: ");
1397		fflush(stdout);
1398		if (!fgets(new_comment, sizeof(new_comment), stdin)) {
1399			memset(passphrase, 0, strlen(passphrase));
1400			key_free(private);
1401			exit(1);
1402		}
1403		new_comment[strcspn(new_comment, "\n")] = '\0';
1404	}
1405
1406	/* Save the file using the new passphrase. */
1407	if (!key_save_private(private, identity_file, passphrase, new_comment,
1408	    use_new_format, new_format_cipher, rounds)) {
1409		printf("Saving the key failed: %s.\n", identity_file);
1410		memset(passphrase, 0, strlen(passphrase));
1411		free(passphrase);
1412		key_free(private);
1413		free(comment);
1414		exit(1);
1415	}
1416	memset(passphrase, 0, strlen(passphrase));
1417	free(passphrase);
1418	public = key_from_private(private);
1419	key_free(private);
1420
1421	strlcat(identity_file, ".pub", sizeof(identity_file));
1422	fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
1423	if (fd == -1) {
1424		printf("Could not save your public key in %s\n", identity_file);
1425		exit(1);
1426	}
1427	f = fdopen(fd, "w");
1428	if (f == NULL) {
1429		printf("fdopen %s failed\n", identity_file);
1430		exit(1);
1431	}
1432	if (!key_write(public, f))
1433		fprintf(stderr, "write key failed\n");
1434	key_free(public);
1435	fprintf(f, " %s\n", new_comment);
1436	fclose(f);
1437
1438	free(comment);
1439
1440	printf("The comment in your key file has been changed.\n");
1441	exit(0);
1442}
1443
1444static const char *
1445fmt_validity(u_int64_t valid_from, u_int64_t valid_to)
1446{
1447	char from[32], to[32];
1448	static char ret[64];
1449	time_t tt;
1450	struct tm *tm;
1451
1452	*from = *to = '\0';
1453	if (valid_from == 0 && valid_to == 0xffffffffffffffffULL)
1454		return "forever";
1455
1456	if (valid_from != 0) {
1457		/* XXX revisit INT_MAX in 2038 :) */
1458		tt = valid_from > INT_MAX ? INT_MAX : valid_from;
1459		tm = localtime(&tt);
1460		strftime(from, sizeof(from), "%Y-%m-%dT%H:%M:%S", tm);
1461	}
1462	if (valid_to != 0xffffffffffffffffULL) {
1463		/* XXX revisit INT_MAX in 2038 :) */
1464		tt = valid_to > INT_MAX ? INT_MAX : valid_to;
1465		tm = localtime(&tt);
1466		strftime(to, sizeof(to), "%Y-%m-%dT%H:%M:%S", tm);
1467	}
1468
1469	if (valid_from == 0) {
1470		snprintf(ret, sizeof(ret), "before %s", to);
1471		return ret;
1472	}
1473	if (valid_to == 0xffffffffffffffffULL) {
1474		snprintf(ret, sizeof(ret), "after %s", from);
1475		return ret;
1476	}
1477
1478	snprintf(ret, sizeof(ret), "from %s to %s", from, to);
1479	return ret;
1480}
1481
1482static void
1483add_flag_option(Buffer *c, const char *name)
1484{
1485	debug3("%s: %s", __func__, name);
1486	buffer_put_cstring(c, name);
1487	buffer_put_string(c, NULL, 0);
1488}
1489
1490static void
1491add_string_option(Buffer *c, const char *name, const char *value)
1492{
1493	Buffer b;
1494
1495	debug3("%s: %s=%s", __func__, name, value);
1496	buffer_init(&b);
1497	buffer_put_cstring(&b, value);
1498
1499	buffer_put_cstring(c, name);
1500	buffer_put_string(c, buffer_ptr(&b), buffer_len(&b));
1501
1502	buffer_free(&b);
1503}
1504
1505#define OPTIONS_CRITICAL	1
1506#define OPTIONS_EXTENSIONS	2
1507static void
1508prepare_options_buf(Buffer *c, int which)
1509{
1510	buffer_clear(c);
1511	if ((which & OPTIONS_CRITICAL) != 0 &&
1512	    certflags_command != NULL)
1513		add_string_option(c, "force-command", certflags_command);
1514	if ((which & OPTIONS_EXTENSIONS) != 0 &&
1515	    (certflags_flags & CERTOPT_X_FWD) != 0)
1516		add_flag_option(c, "permit-X11-forwarding");
1517	if ((which & OPTIONS_EXTENSIONS) != 0 &&
1518	    (certflags_flags & CERTOPT_AGENT_FWD) != 0)
1519		add_flag_option(c, "permit-agent-forwarding");
1520	if ((which & OPTIONS_EXTENSIONS) != 0 &&
1521	    (certflags_flags & CERTOPT_PORT_FWD) != 0)
1522		add_flag_option(c, "permit-port-forwarding");
1523	if ((which & OPTIONS_EXTENSIONS) != 0 &&
1524	    (certflags_flags & CERTOPT_PTY) != 0)
1525		add_flag_option(c, "permit-pty");
1526	if ((which & OPTIONS_EXTENSIONS) != 0 &&
1527	    (certflags_flags & CERTOPT_USER_RC) != 0)
1528		add_flag_option(c, "permit-user-rc");
1529	if ((which & OPTIONS_CRITICAL) != 0 &&
1530	    certflags_src_addr != NULL)
1531		add_string_option(c, "source-address", certflags_src_addr);
1532}
1533
1534static Key *
1535load_pkcs11_key(char *path)
1536{
1537#ifdef ENABLE_PKCS11
1538	Key **keys = NULL, *public, *private = NULL;
1539	int i, nkeys;
1540
1541	if ((public = key_load_public(path, NULL)) == NULL)
1542		fatal("Couldn't load CA public key \"%s\"", path);
1543
1544	nkeys = pkcs11_add_provider(pkcs11provider, identity_passphrase, &keys);
1545	debug3("%s: %d keys", __func__, nkeys);
1546	if (nkeys <= 0)
1547		fatal("cannot read public key from pkcs11");
1548	for (i = 0; i < nkeys; i++) {
1549		if (key_equal_public(public, keys[i])) {
1550			private = keys[i];
1551			continue;
1552		}
1553		key_free(keys[i]);
1554	}
1555	free(keys);
1556	key_free(public);
1557	return private;
1558#else
1559	fatal("no pkcs11 support");
1560#endif /* ENABLE_PKCS11 */
1561}
1562
1563static void
1564do_ca_sign(struct passwd *pw, int argc, char **argv)
1565{
1566	int i, fd;
1567	u_int n;
1568	Key *ca, *public;
1569	char *otmp, *tmp, *cp, *out, *comment, **plist = NULL;
1570	FILE *f;
1571	int v00 = 0; /* legacy keys */
1572
1573	if (key_type_name != NULL) {
1574		switch (key_type_from_name(key_type_name)) {
1575		case KEY_RSA_CERT_V00:
1576		case KEY_DSA_CERT_V00:
1577			v00 = 1;
1578			break;
1579		case KEY_UNSPEC:
1580			if (strcasecmp(key_type_name, "v00") == 0) {
1581				v00 = 1;
1582				break;
1583			} else if (strcasecmp(key_type_name, "v01") == 0)
1584				break;
1585			/* FALLTHROUGH */
1586		default:
1587			fprintf(stderr, "unknown key type %s\n", key_type_name);
1588			exit(1);
1589		}
1590	}
1591
1592	pkcs11_init(1);
1593	tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
1594	if (pkcs11provider != NULL) {
1595		if ((ca = load_pkcs11_key(tmp)) == NULL)
1596			fatal("No PKCS#11 key matching %s found", ca_key_path);
1597	} else if ((ca = load_identity(tmp)) == NULL)
1598		fatal("Couldn't load CA key \"%s\"", tmp);
1599	free(tmp);
1600
1601	for (i = 0; i < argc; i++) {
1602		/* Split list of principals */
1603		n = 0;
1604		if (cert_principals != NULL) {
1605			otmp = tmp = xstrdup(cert_principals);
1606			plist = NULL;
1607			for (; (cp = strsep(&tmp, ",")) != NULL; n++) {
1608				plist = xrealloc(plist, n + 1, sizeof(*plist));
1609				if (*(plist[n] = xstrdup(cp)) == '\0')
1610					fatal("Empty principal name");
1611			}
1612			free(otmp);
1613		}
1614
1615		tmp = tilde_expand_filename(argv[i], pw->pw_uid);
1616		if ((public = key_load_public(tmp, &comment)) == NULL)
1617			fatal("%s: unable to open \"%s\"", __func__, tmp);
1618		if (public->type != KEY_RSA && public->type != KEY_DSA &&
1619		    public->type != KEY_ECDSA && public->type != KEY_ED25519)
1620			fatal("%s: key \"%s\" type %s cannot be certified",
1621			    __func__, tmp, key_type(public));
1622
1623		/* Prepare certificate to sign */
1624		if (key_to_certified(public, v00) != 0)
1625			fatal("Could not upgrade key %s to certificate", tmp);
1626		public->cert->type = cert_key_type;
1627		public->cert->serial = (u_int64_t)cert_serial;
1628		public->cert->key_id = xstrdup(cert_key_id);
1629		public->cert->nprincipals = n;
1630		public->cert->principals = plist;
1631		public->cert->valid_after = cert_valid_from;
1632		public->cert->valid_before = cert_valid_to;
1633		if (v00) {
1634			prepare_options_buf(&public->cert->critical,
1635			    OPTIONS_CRITICAL|OPTIONS_EXTENSIONS);
1636		} else {
1637			prepare_options_buf(&public->cert->critical,
1638			    OPTIONS_CRITICAL);
1639			prepare_options_buf(&public->cert->extensions,
1640			    OPTIONS_EXTENSIONS);
1641		}
1642		public->cert->signature_key = key_from_private(ca);
1643
1644		if (key_certify(public, ca) != 0)
1645			fatal("Couldn't not certify key %s", tmp);
1646
1647		if ((cp = strrchr(tmp, '.')) != NULL && strcmp(cp, ".pub") == 0)
1648			*cp = '\0';
1649		xasprintf(&out, "%s-cert.pub", tmp);
1650		free(tmp);
1651
1652		if ((fd = open(out, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1)
1653			fatal("Could not open \"%s\" for writing: %s", out,
1654			    strerror(errno));
1655		if ((f = fdopen(fd, "w")) == NULL)
1656			fatal("%s: fdopen: %s", __func__, strerror(errno));
1657		if (!key_write(public, f))
1658			fatal("Could not write certified key to %s", out);
1659		fprintf(f, " %s\n", comment);
1660		fclose(f);
1661
1662		if (!quiet) {
1663			logit("Signed %s key %s: id \"%s\" serial %llu%s%s "
1664			    "valid %s", key_cert_type(public),
1665			    out, public->cert->key_id,
1666			    (unsigned long long)public->cert->serial,
1667			    cert_principals != NULL ? " for " : "",
1668			    cert_principals != NULL ? cert_principals : "",
1669			    fmt_validity(cert_valid_from, cert_valid_to));
1670		}
1671
1672		key_free(public);
1673		free(out);
1674	}
1675	pkcs11_terminate();
1676	exit(0);
1677}
1678
1679static u_int64_t
1680parse_relative_time(const char *s, time_t now)
1681{
1682	int64_t mul, secs;
1683
1684	mul = *s == '-' ? -1 : 1;
1685
1686	if ((secs = convtime(s + 1)) == -1)
1687		fatal("Invalid relative certificate time %s", s);
1688	if (mul == -1 && secs > now)
1689		fatal("Certificate time %s cannot be represented", s);
1690	return now + (u_int64_t)(secs * mul);
1691}
1692
1693static u_int64_t
1694parse_absolute_time(const char *s)
1695{
1696	struct tm tm;
1697	time_t tt;
1698	char buf[32], *fmt;
1699
1700	/*
1701	 * POSIX strptime says "The application shall ensure that there
1702	 * is white-space or other non-alphanumeric characters between
1703	 * any two conversion specifications" so arrange things this way.
1704	 */
1705	switch (strlen(s)) {
1706	case 8:
1707		fmt = "%Y-%m-%d";
1708		snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2s", s, s + 4, s + 6);
1709		break;
1710	case 14:
1711		fmt = "%Y-%m-%dT%H:%M:%S";
1712		snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2sT%.2s:%.2s:%.2s",
1713		    s, s + 4, s + 6, s + 8, s + 10, s + 12);
1714		break;
1715	default:
1716		fatal("Invalid certificate time format %s", s);
1717	}
1718
1719	bzero(&tm, sizeof(tm));
1720	if (strptime(buf, fmt, &tm) == NULL)
1721		fatal("Invalid certificate time %s", s);
1722	if ((tt = mktime(&tm)) < 0)
1723		fatal("Certificate time %s cannot be represented", s);
1724	return (u_int64_t)tt;
1725}
1726
1727static void
1728parse_cert_times(char *timespec)
1729{
1730	char *from, *to;
1731	time_t now = time(NULL);
1732	int64_t secs;
1733
1734	/* +timespec relative to now */
1735	if (*timespec == '+' && strchr(timespec, ':') == NULL) {
1736		if ((secs = convtime(timespec + 1)) == -1)
1737			fatal("Invalid relative certificate life %s", timespec);
1738		cert_valid_to = now + secs;
1739		/*
1740		 * Backdate certificate one minute to avoid problems on hosts
1741		 * with poorly-synchronised clocks.
1742		 */
1743		cert_valid_from = ((now - 59)/ 60) * 60;
1744		return;
1745	}
1746
1747	/*
1748	 * from:to, where
1749	 * from := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS
1750	 *   to := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS
1751	 */
1752	from = xstrdup(timespec);
1753	to = strchr(from, ':');
1754	if (to == NULL || from == to || *(to + 1) == '\0')
1755		fatal("Invalid certificate life specification %s", timespec);
1756	*to++ = '\0';
1757
1758	if (*from == '-' || *from == '+')
1759		cert_valid_from = parse_relative_time(from, now);
1760	else
1761		cert_valid_from = parse_absolute_time(from);
1762
1763	if (*to == '-' || *to == '+')
1764		cert_valid_to = parse_relative_time(to, now);
1765	else
1766		cert_valid_to = parse_absolute_time(to);
1767
1768	if (cert_valid_to <= cert_valid_from)
1769		fatal("Empty certificate validity interval");
1770	free(from);
1771}
1772
1773static void
1774add_cert_option(char *opt)
1775{
1776	char *val;
1777
1778	if (strcasecmp(opt, "clear") == 0)
1779		certflags_flags = 0;
1780	else if (strcasecmp(opt, "no-x11-forwarding") == 0)
1781		certflags_flags &= ~CERTOPT_X_FWD;
1782	else if (strcasecmp(opt, "permit-x11-forwarding") == 0)
1783		certflags_flags |= CERTOPT_X_FWD;
1784	else if (strcasecmp(opt, "no-agent-forwarding") == 0)
1785		certflags_flags &= ~CERTOPT_AGENT_FWD;
1786	else if (strcasecmp(opt, "permit-agent-forwarding") == 0)
1787		certflags_flags |= CERTOPT_AGENT_FWD;
1788	else if (strcasecmp(opt, "no-port-forwarding") == 0)
1789		certflags_flags &= ~CERTOPT_PORT_FWD;
1790	else if (strcasecmp(opt, "permit-port-forwarding") == 0)
1791		certflags_flags |= CERTOPT_PORT_FWD;
1792	else if (strcasecmp(opt, "no-pty") == 0)
1793		certflags_flags &= ~CERTOPT_PTY;
1794	else if (strcasecmp(opt, "permit-pty") == 0)
1795		certflags_flags |= CERTOPT_PTY;
1796	else if (strcasecmp(opt, "no-user-rc") == 0)
1797		certflags_flags &= ~CERTOPT_USER_RC;
1798	else if (strcasecmp(opt, "permit-user-rc") == 0)
1799		certflags_flags |= CERTOPT_USER_RC;
1800	else if (strncasecmp(opt, "force-command=", 14) == 0) {
1801		val = opt + 14;
1802		if (*val == '\0')
1803			fatal("Empty force-command option");
1804		if (certflags_command != NULL)
1805			fatal("force-command already specified");
1806		certflags_command = xstrdup(val);
1807	} else if (strncasecmp(opt, "source-address=", 15) == 0) {
1808		val = opt + 15;
1809		if (*val == '\0')
1810			fatal("Empty source-address option");
1811		if (certflags_src_addr != NULL)
1812			fatal("source-address already specified");
1813		if (addr_match_cidr_list(NULL, val) != 0)
1814			fatal("Invalid source-address list");
1815		certflags_src_addr = xstrdup(val);
1816	} else
1817		fatal("Unsupported certificate option \"%s\"", opt);
1818}
1819
1820static void
1821show_options(const Buffer *optbuf, int v00, int in_critical)
1822{
1823	char *name;
1824	u_char *data;
1825	u_int dlen;
1826	Buffer options, option;
1827
1828	buffer_init(&options);
1829	buffer_append(&options, buffer_ptr(optbuf), buffer_len(optbuf));
1830
1831	buffer_init(&option);
1832	while (buffer_len(&options) != 0) {
1833		name = buffer_get_string(&options, NULL);
1834		data = buffer_get_string_ptr(&options, &dlen);
1835		buffer_append(&option, data, dlen);
1836		printf("                %s", name);
1837		if ((v00 || !in_critical) &&
1838		    (strcmp(name, "permit-X11-forwarding") == 0 ||
1839		    strcmp(name, "permit-agent-forwarding") == 0 ||
1840		    strcmp(name, "permit-port-forwarding") == 0 ||
1841		    strcmp(name, "permit-pty") == 0 ||
1842		    strcmp(name, "permit-user-rc") == 0))
1843			printf("\n");
1844		else if ((v00 || in_critical) &&
1845		    (strcmp(name, "force-command") == 0 ||
1846		    strcmp(name, "source-address") == 0)) {
1847			data = buffer_get_string(&option, NULL);
1848			printf(" %s\n", data);
1849			free(data);
1850		} else {
1851			printf(" UNKNOWN OPTION (len %u)\n",
1852			    buffer_len(&option));
1853			buffer_clear(&option);
1854		}
1855		free(name);
1856		if (buffer_len(&option) != 0)
1857			fatal("Option corrupt: extra data at end");
1858	}
1859	buffer_free(&option);
1860	buffer_free(&options);
1861}
1862
1863static void
1864do_show_cert(struct passwd *pw)
1865{
1866	Key *key;
1867	struct stat st;
1868	char *key_fp, *ca_fp;
1869	u_int i, v00;
1870
1871	if (!have_identity)
1872		ask_filename(pw, "Enter file in which the key is");
1873	if (stat(identity_file, &st) < 0)
1874		fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
1875	if ((key = key_load_public(identity_file, NULL)) == NULL)
1876		fatal("%s is not a public key", identity_file);
1877	if (!key_is_cert(key))
1878		fatal("%s is not a certificate", identity_file);
1879	v00 = key->type == KEY_RSA_CERT_V00 || key->type == KEY_DSA_CERT_V00;
1880
1881	key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
1882	ca_fp = key_fingerprint(key->cert->signature_key,
1883	    SSH_FP_MD5, SSH_FP_HEX);
1884
1885	printf("%s:\n", identity_file);
1886	printf("        Type: %s %s certificate\n", key_ssh_name(key),
1887	    key_cert_type(key));
1888	printf("        Public key: %s %s\n", key_type(key), key_fp);
1889	printf("        Signing CA: %s %s\n",
1890	    key_type(key->cert->signature_key), ca_fp);
1891	printf("        Key ID: \"%s\"\n", key->cert->key_id);
1892	if (!v00) {
1893		printf("        Serial: %llu\n",
1894		    (unsigned long long)key->cert->serial);
1895	}
1896	printf("        Valid: %s\n",
1897	    fmt_validity(key->cert->valid_after, key->cert->valid_before));
1898	printf("        Principals: ");
1899	if (key->cert->nprincipals == 0)
1900		printf("(none)\n");
1901	else {
1902		for (i = 0; i < key->cert->nprincipals; i++)
1903			printf("\n                %s",
1904			    key->cert->principals[i]);
1905		printf("\n");
1906	}
1907	printf("        Critical Options: ");
1908	if (buffer_len(&key->cert->critical) == 0)
1909		printf("(none)\n");
1910	else {
1911		printf("\n");
1912		show_options(&key->cert->critical, v00, 1);
1913	}
1914	if (!v00) {
1915		printf("        Extensions: ");
1916		if (buffer_len(&key->cert->extensions) == 0)
1917			printf("(none)\n");
1918		else {
1919			printf("\n");
1920			show_options(&key->cert->extensions, v00, 0);
1921		}
1922	}
1923	exit(0);
1924}
1925
1926static void
1927load_krl(const char *path, struct ssh_krl **krlp)
1928{
1929	Buffer krlbuf;
1930	int fd;
1931
1932	buffer_init(&krlbuf);
1933	if ((fd = open(path, O_RDONLY)) == -1)
1934		fatal("open %s: %s", path, strerror(errno));
1935	if (!key_load_file(fd, path, &krlbuf))
1936		fatal("Unable to load KRL");
1937	close(fd);
1938	/* XXX check sigs */
1939	if (ssh_krl_from_blob(&krlbuf, krlp, NULL, 0) != 0 ||
1940	    *krlp == NULL)
1941		fatal("Invalid KRL file");
1942	buffer_free(&krlbuf);
1943}
1944
1945static void
1946update_krl_from_file(struct passwd *pw, const char *file, const Key *ca,
1947    struct ssh_krl *krl)
1948{
1949	Key *key = NULL;
1950	u_long lnum = 0;
1951	char *path, *cp, *ep, line[SSH_MAX_PUBKEY_BYTES];
1952	unsigned long long serial, serial2;
1953	int i, was_explicit_key, was_sha1, r;
1954	FILE *krl_spec;
1955
1956	path = tilde_expand_filename(file, pw->pw_uid);
1957	if (strcmp(path, "-") == 0) {
1958		krl_spec = stdin;
1959		free(path);
1960		path = xstrdup("(standard input)");
1961	} else if ((krl_spec = fopen(path, "r")) == NULL)
1962		fatal("fopen %s: %s", path, strerror(errno));
1963
1964	if (!quiet)
1965		printf("Revoking from %s\n", path);
1966	while (read_keyfile_line(krl_spec, path, line, sizeof(line),
1967	    &lnum) == 0) {
1968		was_explicit_key = was_sha1 = 0;
1969		cp = line + strspn(line, " \t");
1970		/* Trim trailing space, comments and strip \n */
1971		for (i = 0, r = -1; cp[i] != '\0'; i++) {
1972			if (cp[i] == '#' || cp[i] == '\n') {
1973				cp[i] = '\0';
1974				break;
1975			}
1976			if (cp[i] == ' ' || cp[i] == '\t') {
1977				/* Remember the start of a span of whitespace */
1978				if (r == -1)
1979					r = i;
1980			} else
1981				r = -1;
1982		}
1983		if (r != -1)
1984			cp[r] = '\0';
1985		if (*cp == '\0')
1986			continue;
1987		if (strncasecmp(cp, "serial:", 7) == 0) {
1988			if (ca == NULL) {
1989				fatal("revoking certificates by serial number "
1990				    "requires specification of a CA key");
1991			}
1992			cp += 7;
1993			cp = cp + strspn(cp, " \t");
1994			errno = 0;
1995			serial = strtoull(cp, &ep, 0);
1996			if (*cp == '\0' || (*ep != '\0' && *ep != '-'))
1997				fatal("%s:%lu: invalid serial \"%s\"",
1998				    path, lnum, cp);
1999			if (errno == ERANGE && serial == ULLONG_MAX)
2000				fatal("%s:%lu: serial out of range",
2001				    path, lnum);
2002			serial2 = serial;
2003			if (*ep == '-') {
2004				cp = ep + 1;
2005				errno = 0;
2006				serial2 = strtoull(cp, &ep, 0);
2007				if (*cp == '\0' || *ep != '\0')
2008					fatal("%s:%lu: invalid serial \"%s\"",
2009					    path, lnum, cp);
2010				if (errno == ERANGE && serial2 == ULLONG_MAX)
2011					fatal("%s:%lu: serial out of range",
2012					    path, lnum);
2013				if (serial2 <= serial)
2014					fatal("%s:%lu: invalid serial range "
2015					    "%llu:%llu", path, lnum,
2016					    (unsigned long long)serial,
2017					    (unsigned long long)serial2);
2018			}
2019			if (ssh_krl_revoke_cert_by_serial_range(krl,
2020			    ca, serial, serial2) != 0) {
2021				fatal("%s: revoke serial failed",
2022				    __func__);
2023			}
2024		} else if (strncasecmp(cp, "id:", 3) == 0) {
2025			if (ca == NULL) {
2026				fatal("revoking certificates by key ID "
2027				    "requires specification of a CA key");
2028			}
2029			cp += 3;
2030			cp = cp + strspn(cp, " \t");
2031			if (ssh_krl_revoke_cert_by_key_id(krl, ca, cp) != 0)
2032				fatal("%s: revoke key ID failed", __func__);
2033		} else {
2034			if (strncasecmp(cp, "key:", 4) == 0) {
2035				cp += 4;
2036				cp = cp + strspn(cp, " \t");
2037				was_explicit_key = 1;
2038			} else if (strncasecmp(cp, "sha1:", 5) == 0) {
2039				cp += 5;
2040				cp = cp + strspn(cp, " \t");
2041				was_sha1 = 1;
2042			} else {
2043				/*
2044				 * Just try to process the line as a key.
2045				 * Parsing will fail if it isn't.
2046				 */
2047			}
2048			if ((key = key_new(KEY_UNSPEC)) == NULL)
2049				fatal("key_new");
2050			if (key_read(key, &cp) != 1)
2051				fatal("%s:%lu: invalid key", path, lnum);
2052			if (was_explicit_key)
2053				r = ssh_krl_revoke_key_explicit(krl, key);
2054			else if (was_sha1)
2055				r = ssh_krl_revoke_key_sha1(krl, key);
2056			else
2057				r = ssh_krl_revoke_key(krl, key);
2058			if (r != 0)
2059				fatal("%s: revoke key failed", __func__);
2060			key_free(key);
2061		}
2062	}
2063	if (strcmp(path, "-") != 0)
2064		fclose(krl_spec);
2065	free(path);
2066}
2067
2068static void
2069do_gen_krl(struct passwd *pw, int updating, int argc, char **argv)
2070{
2071	struct ssh_krl *krl;
2072	struct stat sb;
2073	Key *ca = NULL;
2074	int fd, i;
2075	char *tmp;
2076	Buffer kbuf;
2077
2078	if (*identity_file == '\0')
2079		fatal("KRL generation requires an output file");
2080	if (stat(identity_file, &sb) == -1) {
2081		if (errno != ENOENT)
2082			fatal("Cannot access KRL \"%s\": %s",
2083			    identity_file, strerror(errno));
2084		if (updating)
2085			fatal("KRL \"%s\" does not exist", identity_file);
2086	}
2087	if (ca_key_path != NULL) {
2088		tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
2089		if ((ca = key_load_public(tmp, NULL)) == NULL)
2090			fatal("Cannot load CA public key %s", tmp);
2091		free(tmp);
2092	}
2093
2094	if (updating)
2095		load_krl(identity_file, &krl);
2096	else if ((krl = ssh_krl_init()) == NULL)
2097		fatal("couldn't create KRL");
2098
2099	if (cert_serial != 0)
2100		ssh_krl_set_version(krl, cert_serial);
2101	if (identity_comment != NULL)
2102		ssh_krl_set_comment(krl, identity_comment);
2103
2104	for (i = 0; i < argc; i++)
2105		update_krl_from_file(pw, argv[i], ca, krl);
2106
2107	buffer_init(&kbuf);
2108	if (ssh_krl_to_blob(krl, &kbuf, NULL, 0) != 0)
2109		fatal("Couldn't generate KRL");
2110	if ((fd = open(identity_file, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1)
2111		fatal("open %s: %s", identity_file, strerror(errno));
2112	if (atomicio(vwrite, fd, buffer_ptr(&kbuf), buffer_len(&kbuf)) !=
2113	    buffer_len(&kbuf))
2114		fatal("write %s: %s", identity_file, strerror(errno));
2115	close(fd);
2116	buffer_free(&kbuf);
2117	ssh_krl_free(krl);
2118	if (ca != NULL)
2119		key_free(ca);
2120}
2121
2122static void
2123do_check_krl(struct passwd *pw, int argc, char **argv)
2124{
2125	int i, r, ret = 0;
2126	char *comment;
2127	struct ssh_krl *krl;
2128	Key *k;
2129
2130	if (*identity_file == '\0')
2131		fatal("KRL checking requires an input file");
2132	load_krl(identity_file, &krl);
2133	for (i = 0; i < argc; i++) {
2134		if ((k = key_load_public(argv[i], &comment)) == NULL)
2135			fatal("Cannot load public key %s", argv[i]);
2136		r = ssh_krl_check_key(krl, k);
2137		printf("%s%s%s%s: %s\n", argv[i],
2138		    *comment ? " (" : "", comment, *comment ? ")" : "",
2139		    r == 0 ? "ok" : "REVOKED");
2140		if (r != 0)
2141			ret = 1;
2142		key_free(k);
2143		free(comment);
2144	}
2145	ssh_krl_free(krl);
2146	exit(ret);
2147}
2148
2149static void
2150usage(void)
2151{
2152	fprintf(stderr, "usage: %s [options]\n", __progname);
2153	fprintf(stderr, "Options:\n");
2154	fprintf(stderr, "  -A          Generate non-existent host keys for all key types.\n");
2155	fprintf(stderr, "  -a number   Number of KDF rounds for new key format or moduli primality tests.\n");
2156	fprintf(stderr, "  -B          Show bubblebabble digest of key file.\n");
2157	fprintf(stderr, "  -b bits     Number of bits in the key to create.\n");
2158	fprintf(stderr, "  -C comment  Provide new comment.\n");
2159	fprintf(stderr, "  -c          Change comment in private and public key files.\n");
2160#ifdef ENABLE_PKCS11
2161	fprintf(stderr, "  -D pkcs11   Download public key from pkcs11 token.\n");
2162#endif
2163	fprintf(stderr, "  -e          Export OpenSSH to foreign format key file.\n");
2164	fprintf(stderr, "  -F hostname Find hostname in known hosts file.\n");
2165	fprintf(stderr, "  -f filename Filename of the key file.\n");
2166	fprintf(stderr, "  -G file     Generate candidates for DH-GEX moduli.\n");
2167	fprintf(stderr, "  -g          Use generic DNS resource record format.\n");
2168	fprintf(stderr, "  -H          Hash names in known_hosts file.\n");
2169	fprintf(stderr, "  -h          Generate host certificate instead of a user certificate.\n");
2170	fprintf(stderr, "  -I key_id   Key identifier to include in certificate.\n");
2171	fprintf(stderr, "  -i          Import foreign format to OpenSSH key file.\n");
2172	fprintf(stderr, "  -J number   Screen this number of moduli lines.\n");
2173	fprintf(stderr, "  -j number   Start screening moduli at specified line.\n");
2174	fprintf(stderr, "  -K checkpt  Write checkpoints to this file.\n");
2175	fprintf(stderr, "  -k          Generate a KRL file.\n");
2176	fprintf(stderr, "  -L          Print the contents of a certificate.\n");
2177	fprintf(stderr, "  -l          Show fingerprint of key file.\n");
2178	fprintf(stderr, "  -M memory   Amount of memory (MB) to use for generating DH-GEX moduli.\n");
2179	fprintf(stderr, "  -m key_fmt  Conversion format for -e/-i (PEM|PKCS8|RFC4716).\n");
2180	fprintf(stderr, "  -N phrase   Provide new passphrase.\n");
2181	fprintf(stderr, "  -n name,... User/host principal names to include in certificate\n");
2182	fprintf(stderr, "  -O option   Specify a certificate option.\n");
2183	fprintf(stderr, "  -o          Enforce new private key format.\n");
2184	fprintf(stderr, "  -P phrase   Provide old passphrase.\n");
2185	fprintf(stderr, "  -p          Change passphrase of private key file.\n");
2186	fprintf(stderr, "  -Q          Test whether key(s) are revoked in KRL.\n");
2187	fprintf(stderr, "  -q          Quiet.\n");
2188	fprintf(stderr, "  -R hostname Remove host from known_hosts file.\n");
2189	fprintf(stderr, "  -r hostname Print DNS resource record.\n");
2190	fprintf(stderr, "  -S start    Start point (hex) for generating DH-GEX moduli.\n");
2191	fprintf(stderr, "  -s ca_key   Certify keys with CA key.\n");
2192	fprintf(stderr, "  -T file     Screen candidates for DH-GEX moduli.\n");
2193	fprintf(stderr, "  -t type     Specify type of key to create.\n");
2194	fprintf(stderr, "  -u          Update KRL rather than creating a new one.\n");
2195	fprintf(stderr, "  -V from:to  Specify certificate validity interval.\n");
2196	fprintf(stderr, "  -v          Verbose.\n");
2197	fprintf(stderr, "  -W gen      Generator to use for generating DH-GEX moduli.\n");
2198	fprintf(stderr, "  -y          Read private key file and print public key.\n");
2199	fprintf(stderr, "  -z serial   Specify a serial number.\n");
2200	fprintf(stderr, "  -Z cipher   Specify a cipher for new private key format.\n");
2201
2202	exit(1);
2203}
2204
2205/*
2206 * Main program for key management.
2207 */
2208int
2209main(int argc, char **argv)
2210{
2211	char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2;
2212	char *checkpoint = NULL;
2213	char out_file[MAXPATHLEN], *ep, *rr_hostname = NULL;
2214	Key *private, *public;
2215	struct passwd *pw;
2216	struct stat st;
2217	int opt, type, fd;
2218	u_int32_t memory = 0, generator_wanted = 0;
2219	int do_gen_candidates = 0, do_screen_candidates = 0;
2220	int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0;
2221	unsigned long start_lineno = 0, lines_to_process = 0;
2222	BIGNUM *start = NULL;
2223	FILE *f;
2224	const char *errstr;
2225
2226	extern int optind;
2227	extern char *optarg;
2228
2229	/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
2230	sanitise_stdfd();
2231
2232	__progname = ssh_get_progname(argv[0]);
2233
2234	OpenSSL_add_all_algorithms();
2235	log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);
2236
2237	seed_rng();
2238
2239	/* we need this for the home * directory.  */
2240	pw = getpwuid(getuid());
2241	if (!pw) {
2242		printf("No user exists for uid %lu\n", (u_long)getuid());
2243		exit(1);
2244	}
2245	if (gethostname(hostname, sizeof(hostname)) < 0) {
2246		perror("gethostname");
2247		exit(1);
2248	}
2249
2250	/* Remaining characters: EUYdw */
2251	while ((opt = getopt(argc, argv, "ABHLQXceghiklopquvxy"
2252	    "C:D:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Z:a:b:f:g:j:m:n:r:s:t:z:")) != -1) {
2253		switch (opt) {
2254		case 'A':
2255			gen_all_hostkeys = 1;
2256			break;
2257		case 'b':
2258			bits = (u_int32_t)strtonum(optarg, 256, 32768, &errstr);
2259			if (errstr)
2260				fatal("Bits has bad value %s (%s)",
2261					optarg, errstr);
2262			break;
2263		case 'F':
2264			find_host = 1;
2265			rr_hostname = optarg;
2266			break;
2267		case 'H':
2268			hash_hosts = 1;
2269			break;
2270		case 'I':
2271			cert_key_id = optarg;
2272			break;
2273		case 'J':
2274			lines_to_process = strtoul(optarg, NULL, 10);
2275                        break;
2276		case 'j':
2277			start_lineno = strtoul(optarg, NULL, 10);
2278                        break;
2279		case 'R':
2280			delete_host = 1;
2281			rr_hostname = optarg;
2282			break;
2283		case 'L':
2284			show_cert = 1;
2285			break;
2286		case 'l':
2287			print_fingerprint = 1;
2288			break;
2289		case 'B':
2290			print_bubblebabble = 1;
2291			break;
2292		case 'm':
2293			if (strcasecmp(optarg, "RFC4716") == 0 ||
2294			    strcasecmp(optarg, "ssh2") == 0) {
2295				convert_format = FMT_RFC4716;
2296				break;
2297			}
2298			if (strcasecmp(optarg, "PKCS8") == 0) {
2299				convert_format = FMT_PKCS8;
2300				break;
2301			}
2302			if (strcasecmp(optarg, "PEM") == 0) {
2303				convert_format = FMT_PEM;
2304				break;
2305			}
2306			fatal("Unsupported conversion format \"%s\"", optarg);
2307		case 'n':
2308			cert_principals = optarg;
2309			break;
2310		case 'o':
2311			use_new_format = 1;
2312			break;
2313		case 'p':
2314			change_passphrase = 1;
2315			break;
2316		case 'c':
2317			change_comment = 1;
2318			break;
2319		case 'f':
2320			if (strlcpy(identity_file, optarg, sizeof(identity_file)) >=
2321			    sizeof(identity_file))
2322				fatal("Identity filename too long");
2323			have_identity = 1;
2324			break;
2325		case 'g':
2326			print_generic = 1;
2327			break;
2328		case 'P':
2329			identity_passphrase = optarg;
2330			break;
2331		case 'N':
2332			identity_new_passphrase = optarg;
2333			break;
2334		case 'Q':
2335			check_krl = 1;
2336			break;
2337		case 'O':
2338			add_cert_option(optarg);
2339			break;
2340		case 'Z':
2341			new_format_cipher = optarg;
2342			break;
2343		case 'C':
2344			identity_comment = optarg;
2345			break;
2346		case 'q':
2347			quiet = 1;
2348			break;
2349		case 'e':
2350		case 'x':
2351			/* export key */
2352			convert_to = 1;
2353			break;
2354		case 'h':
2355			cert_key_type = SSH2_CERT_TYPE_HOST;
2356			certflags_flags = 0;
2357			break;
2358		case 'k':
2359			gen_krl = 1;
2360			break;
2361		case 'i':
2362		case 'X':
2363			/* import key */
2364			convert_from = 1;
2365			break;
2366		case 'y':
2367			print_public = 1;
2368			break;
2369		case 's':
2370			ca_key_path = optarg;
2371			break;
2372		case 't':
2373			key_type_name = optarg;
2374			break;
2375		case 'D':
2376			pkcs11provider = optarg;
2377			break;
2378		case 'u':
2379			update_krl = 1;
2380			break;
2381		case 'v':
2382			if (log_level == SYSLOG_LEVEL_INFO)
2383				log_level = SYSLOG_LEVEL_DEBUG1;
2384			else {
2385				if (log_level >= SYSLOG_LEVEL_DEBUG1 &&
2386				    log_level < SYSLOG_LEVEL_DEBUG3)
2387					log_level++;
2388			}
2389			break;
2390		case 'r':
2391			rr_hostname = optarg;
2392			break;
2393		case 'W':
2394			generator_wanted = (u_int32_t)strtonum(optarg, 1,
2395			    UINT_MAX, &errstr);
2396			if (errstr)
2397				fatal("Desired generator has bad value: %s (%s)",
2398					optarg, errstr);
2399			break;
2400		case 'a':
2401			rounds = (int)strtonum(optarg, 1, INT_MAX, &errstr);
2402			if (errstr)
2403				fatal("Invalid number: %s (%s)",
2404					optarg, errstr);
2405			break;
2406		case 'M':
2407			memory = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr);
2408			if (errstr)
2409				fatal("Memory limit is %s: %s", errstr, optarg);
2410			break;
2411		case 'G':
2412			do_gen_candidates = 1;
2413			if (strlcpy(out_file, optarg, sizeof(out_file)) >=
2414			    sizeof(out_file))
2415				fatal("Output filename too long");
2416			break;
2417		case 'T':
2418			do_screen_candidates = 1;
2419			if (strlcpy(out_file, optarg, sizeof(out_file)) >=
2420			    sizeof(out_file))
2421				fatal("Output filename too long");
2422			break;
2423		case 'K':
2424			if (strlen(optarg) >= MAXPATHLEN)
2425				fatal("Checkpoint filename too long");
2426			checkpoint = xstrdup(optarg);
2427			break;
2428		case 'S':
2429			/* XXX - also compare length against bits */
2430			if (BN_hex2bn(&start, optarg) == 0)
2431				fatal("Invalid start point.");
2432			break;
2433		case 'V':
2434			parse_cert_times(optarg);
2435			break;
2436		case 'z':
2437			errno = 0;
2438			cert_serial = strtoull(optarg, &ep, 10);
2439			if (*optarg < '0' || *optarg > '9' || *ep != '\0' ||
2440			    (errno == ERANGE && cert_serial == ULLONG_MAX))
2441				fatal("Invalid serial number \"%s\"", optarg);
2442			break;
2443		case '?':
2444		default:
2445			usage();
2446		}
2447	}
2448
2449	/* reinit */
2450	log_init(argv[0], log_level, SYSLOG_FACILITY_USER, 1);
2451
2452	argv += optind;
2453	argc -= optind;
2454
2455	if (ca_key_path != NULL) {
2456		if (argc < 1 && !gen_krl) {
2457			printf("Too few arguments.\n");
2458			usage();
2459		}
2460	} else if (argc > 0 && !gen_krl && !check_krl) {
2461		printf("Too many arguments.\n");
2462		usage();
2463	}
2464	if (change_passphrase && change_comment) {
2465		printf("Can only have one of -p and -c.\n");
2466		usage();
2467	}
2468	if (print_fingerprint && (delete_host || hash_hosts)) {
2469		printf("Cannot use -l with -H or -R.\n");
2470		usage();
2471	}
2472	if (gen_krl) {
2473		do_gen_krl(pw, update_krl, argc, argv);
2474		return (0);
2475	}
2476	if (check_krl) {
2477		do_check_krl(pw, argc, argv);
2478		return (0);
2479	}
2480	if (ca_key_path != NULL) {
2481		if (cert_key_id == NULL)
2482			fatal("Must specify key id (-I) when certifying");
2483		do_ca_sign(pw, argc, argv);
2484	}
2485	if (show_cert)
2486		do_show_cert(pw);
2487	if (delete_host || hash_hosts || find_host)
2488		do_known_hosts(pw, rr_hostname);
2489	if (pkcs11provider != NULL)
2490		do_download(pw);
2491	if (print_fingerprint || print_bubblebabble)
2492		do_fingerprint(pw);
2493	if (change_passphrase)
2494		do_change_passphrase(pw);
2495	if (change_comment)
2496		do_change_comment(pw);
2497	if (convert_to)
2498		do_convert_to(pw);
2499	if (convert_from)
2500		do_convert_from(pw);
2501	if (print_public)
2502		do_print_public(pw);
2503	if (rr_hostname != NULL) {
2504		unsigned int n = 0;
2505
2506		if (have_identity) {
2507			n = do_print_resource_record(pw,
2508			    identity_file, rr_hostname);
2509			if (n == 0) {
2510				perror(identity_file);
2511				exit(1);
2512			}
2513			exit(0);
2514		} else {
2515
2516			n += do_print_resource_record(pw,
2517			    _PATH_HOST_RSA_KEY_FILE, rr_hostname);
2518			n += do_print_resource_record(pw,
2519			    _PATH_HOST_DSA_KEY_FILE, rr_hostname);
2520			n += do_print_resource_record(pw,
2521			    _PATH_HOST_ECDSA_KEY_FILE, rr_hostname);
2522
2523			if (n == 0)
2524				fatal("no keys found.");
2525			exit(0);
2526		}
2527	}
2528
2529	if (do_gen_candidates) {
2530		FILE *out = fopen(out_file, "w");
2531
2532		if (out == NULL) {
2533			error("Couldn't open modulus candidate file \"%s\": %s",
2534			    out_file, strerror(errno));
2535			return (1);
2536		}
2537		if (bits == 0)
2538			bits = DEFAULT_BITS;
2539		if (gen_candidates(out, memory, bits, start) != 0)
2540			fatal("modulus candidate generation failed");
2541
2542		return (0);
2543	}
2544
2545	if (do_screen_candidates) {
2546		FILE *in;
2547		FILE *out = fopen(out_file, "a");
2548
2549		if (have_identity && strcmp(identity_file, "-") != 0) {
2550			if ((in = fopen(identity_file, "r")) == NULL) {
2551				fatal("Couldn't open modulus candidate "
2552				    "file \"%s\": %s", identity_file,
2553				    strerror(errno));
2554			}
2555		} else
2556			in = stdin;
2557
2558		if (out == NULL) {
2559			fatal("Couldn't open moduli file \"%s\": %s",
2560			    out_file, strerror(errno));
2561		}
2562		if (prime_test(in, out, rounds == 0 ? 100 : rounds,
2563		    generator_wanted, checkpoint,
2564		    start_lineno, lines_to_process) != 0)
2565			fatal("modulus screening failed");
2566		return (0);
2567	}
2568
2569	if (gen_all_hostkeys) {
2570		do_gen_all_hostkeys(pw);
2571		return (0);
2572	}
2573
2574	if (key_type_name == NULL)
2575		key_type_name = "rsa";
2576
2577	type = key_type_from_name(key_type_name);
2578	type_bits_valid(type, &bits);
2579
2580	if (!quiet)
2581		printf("Generating public/private %s key pair.\n", key_type_name);
2582	private = key_generate(type, bits);
2583	if (private == NULL) {
2584		fprintf(stderr, "key_generate failed\n");
2585		exit(1);
2586	}
2587	public  = key_from_private(private);
2588
2589	if (!have_identity)
2590		ask_filename(pw, "Enter file in which to save the key");
2591
2592	/* Create ~/.ssh directory if it doesn't already exist. */
2593	snprintf(dotsshdir, sizeof dotsshdir, "%s/%s",
2594	    pw->pw_dir, _PATH_SSH_USER_DIR);
2595	if (strstr(identity_file, dotsshdir) != NULL) {
2596		if (stat(dotsshdir, &st) < 0) {
2597			if (errno != ENOENT) {
2598				error("Could not stat %s: %s", dotsshdir,
2599				    strerror(errno));
2600			} else if (mkdir(dotsshdir, 0700) < 0) {
2601				error("Could not create directory '%s': %s",
2602				    dotsshdir, strerror(errno));
2603			} else if (!quiet)
2604				printf("Created directory '%s'.\n", dotsshdir);
2605		}
2606	}
2607	/* If the file already exists, ask the user to confirm. */
2608	if (stat(identity_file, &st) >= 0) {
2609		char yesno[3];
2610		printf("%s already exists.\n", identity_file);
2611		printf("Overwrite (y/n)? ");
2612		fflush(stdout);
2613		if (fgets(yesno, sizeof(yesno), stdin) == NULL)
2614			exit(1);
2615		if (yesno[0] != 'y' && yesno[0] != 'Y')
2616			exit(1);
2617	}
2618	/* Ask for a passphrase (twice). */
2619	if (identity_passphrase)
2620		passphrase1 = xstrdup(identity_passphrase);
2621	else if (identity_new_passphrase)
2622		passphrase1 = xstrdup(identity_new_passphrase);
2623	else {
2624passphrase_again:
2625		passphrase1 =
2626			read_passphrase("Enter passphrase (empty for no "
2627			    "passphrase): ", RP_ALLOW_STDIN);
2628		passphrase2 = read_passphrase("Enter same passphrase again: ",
2629		    RP_ALLOW_STDIN);
2630		if (strcmp(passphrase1, passphrase2) != 0) {
2631			/*
2632			 * The passphrases do not match.  Clear them and
2633			 * retry.
2634			 */
2635			memset(passphrase1, 0, strlen(passphrase1));
2636			memset(passphrase2, 0, strlen(passphrase2));
2637			free(passphrase1);
2638			free(passphrase2);
2639			printf("Passphrases do not match.  Try again.\n");
2640			goto passphrase_again;
2641		}
2642		/* Clear the other copy of the passphrase. */
2643		memset(passphrase2, 0, strlen(passphrase2));
2644		free(passphrase2);
2645	}
2646
2647	if (identity_comment) {
2648		strlcpy(comment, identity_comment, sizeof(comment));
2649	} else {
2650		/* Create default comment field for the passphrase. */
2651		snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname);
2652	}
2653
2654	/* Save the key with the given passphrase and comment. */
2655	if (!key_save_private(private, identity_file, passphrase1, comment,
2656	    use_new_format, new_format_cipher, rounds)) {
2657		printf("Saving the key failed: %s.\n", identity_file);
2658		memset(passphrase1, 0, strlen(passphrase1));
2659		free(passphrase1);
2660		exit(1);
2661	}
2662	/* Clear the passphrase. */
2663	memset(passphrase1, 0, strlen(passphrase1));
2664	free(passphrase1);
2665
2666	/* Clear the private key and the random number generator. */
2667	key_free(private);
2668
2669	if (!quiet)
2670		printf("Your identification has been saved in %s.\n", identity_file);
2671
2672	strlcat(identity_file, ".pub", sizeof(identity_file));
2673	fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
2674	if (fd == -1) {
2675		printf("Could not save your public key in %s\n", identity_file);
2676		exit(1);
2677	}
2678	f = fdopen(fd, "w");
2679	if (f == NULL) {
2680		printf("fdopen %s failed\n", identity_file);
2681		exit(1);
2682	}
2683	if (!key_write(public, f))
2684		fprintf(stderr, "write key failed\n");
2685	fprintf(f, " %s\n", comment);
2686	fclose(f);
2687
2688	if (!quiet) {
2689		char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX);
2690		char *ra = key_fingerprint(public, SSH_FP_MD5,
2691		    SSH_FP_RANDOMART);
2692		printf("Your public key has been saved in %s.\n",
2693		    identity_file);
2694		printf("The key fingerprint is:\n");
2695		printf("%s %s\n", fp, comment);
2696		printf("The key's randomart image is:\n");
2697		printf("%s\n", ra);
2698		free(ra);
2699		free(fp);
2700	}
2701
2702	key_free(public);
2703	exit(0);
2704}
2705