xref: /openbsd-src/usr.bin/ssh/ssh-keygen.c (revision daf88648c0e349d5c02e1504293082072c981640)
1 /* $OpenBSD: ssh-keygen.c,v 1.160 2007/01/21 01:41:54 stevesk 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 <sys/types.h>
16 #include <sys/stat.h>
17 #include <sys/socket.h>
18 #include <sys/param.h>
19 
20 #include <openssl/evp.h>
21 #include <openssl/pem.h>
22 
23 #include <errno.h>
24 #include <fcntl.h>
25 #include <pwd.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <unistd.h>
30 
31 #include "xmalloc.h"
32 #include "key.h"
33 #include "rsa.h"
34 #include "authfile.h"
35 #include "uuencode.h"
36 #include "buffer.h"
37 #include "pathnames.h"
38 #include "log.h"
39 #include "misc.h"
40 #include "match.h"
41 #include "hostfile.h"
42 #include "dns.h"
43 
44 #ifdef SMARTCARD
45 #include "scard.h"
46 #endif
47 
48 /* Number of bits in the RSA/DSA key.  This value can be set on the command line. */
49 #define DEFAULT_BITS		2048
50 #define DEFAULT_BITS_DSA	1024
51 u_int32_t bits = 0;
52 
53 /*
54  * Flag indicating that we just want to change the passphrase.  This can be
55  * set on the command line.
56  */
57 int change_passphrase = 0;
58 
59 /*
60  * Flag indicating that we just want to change the comment.  This can be set
61  * on the command line.
62  */
63 int change_comment = 0;
64 
65 int quiet = 0;
66 
67 /* Flag indicating that we want to hash a known_hosts file */
68 int hash_hosts = 0;
69 /* Flag indicating that we want lookup a host in known_hosts file */
70 int find_host = 0;
71 /* Flag indicating that we want to delete a host from a known_hosts file */
72 int delete_host = 0;
73 
74 /* Flag indicating that we just want to see the key fingerprint */
75 int print_fingerprint = 0;
76 int print_bubblebabble = 0;
77 
78 /* The identity file name, given on the command line or entered by the user. */
79 char identity_file[1024];
80 int have_identity = 0;
81 
82 /* This is set to the passphrase if given on the command line. */
83 char *identity_passphrase = NULL;
84 
85 /* This is set to the new passphrase if given on the command line. */
86 char *identity_new_passphrase = NULL;
87 
88 /* This is set to the new comment if given on the command line. */
89 char *identity_comment = NULL;
90 
91 /* Dump public key file in format used by real and the original SSH 2 */
92 int convert_to_ssh2 = 0;
93 int convert_from_ssh2 = 0;
94 int print_public = 0;
95 int print_generic = 0;
96 
97 char *key_type_name = NULL;
98 
99 /* argv0 */
100 extern char *__progname;
101 
102 char hostname[MAXHOSTNAMELEN];
103 
104 /* moduli.c */
105 int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *);
106 int prime_test(FILE *, FILE *, u_int32_t, u_int32_t);
107 
108 static void
109 ask_filename(struct passwd *pw, const char *prompt)
110 {
111 	char buf[1024];
112 	char *name = NULL;
113 
114 	if (key_type_name == NULL)
115 		name = _PATH_SSH_CLIENT_ID_RSA;
116 	else {
117 		switch (key_type_from_name(key_type_name)) {
118 		case KEY_RSA1:
119 			name = _PATH_SSH_CLIENT_IDENTITY;
120 			break;
121 		case KEY_DSA:
122 			name = _PATH_SSH_CLIENT_ID_DSA;
123 			break;
124 		case KEY_RSA:
125 			name = _PATH_SSH_CLIENT_ID_RSA;
126 			break;
127 		default:
128 			fprintf(stderr, "bad key type");
129 			exit(1);
130 			break;
131 		}
132 	}
133 	snprintf(identity_file, sizeof(identity_file), "%s/%s", pw->pw_dir, name);
134 	fprintf(stderr, "%s (%s): ", prompt, identity_file);
135 	if (fgets(buf, sizeof(buf), stdin) == NULL)
136 		exit(1);
137 	if (strchr(buf, '\n'))
138 		*strchr(buf, '\n') = 0;
139 	if (strcmp(buf, "") != 0)
140 		strlcpy(identity_file, buf, sizeof(identity_file));
141 	have_identity = 1;
142 }
143 
144 static Key *
145 load_identity(char *filename)
146 {
147 	char *pass;
148 	Key *prv;
149 
150 	prv = key_load_private(filename, "", NULL);
151 	if (prv == NULL) {
152 		if (identity_passphrase)
153 			pass = xstrdup(identity_passphrase);
154 		else
155 			pass = read_passphrase("Enter passphrase: ",
156 			    RP_ALLOW_STDIN);
157 		prv = key_load_private(filename, pass, NULL);
158 		memset(pass, 0, strlen(pass));
159 		xfree(pass);
160 	}
161 	return prv;
162 }
163 
164 #define SSH_COM_PUBLIC_BEGIN		"---- BEGIN SSH2 PUBLIC KEY ----"
165 #define SSH_COM_PUBLIC_END		"---- END SSH2 PUBLIC KEY ----"
166 #define SSH_COM_PRIVATE_BEGIN		"---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----"
167 #define	SSH_COM_PRIVATE_KEY_MAGIC	0x3f6ff9eb
168 
169 static void
170 do_convert_to_ssh2(struct passwd *pw)
171 {
172 	Key *k;
173 	u_int len;
174 	u_char *blob;
175 	struct stat st;
176 
177 	if (!have_identity)
178 		ask_filename(pw, "Enter file in which the key is");
179 	if (stat(identity_file, &st) < 0) {
180 		perror(identity_file);
181 		exit(1);
182 	}
183 	if ((k = key_load_public(identity_file, NULL)) == NULL) {
184 		if ((k = load_identity(identity_file)) == NULL) {
185 			fprintf(stderr, "load failed\n");
186 			exit(1);
187 		}
188 	}
189 	if (k->type == KEY_RSA1) {
190 		fprintf(stderr, "version 1 keys are not supported\n");
191 		exit(1);
192 	}
193 	if (key_to_blob(k, &blob, &len) <= 0) {
194 		fprintf(stderr, "key_to_blob failed\n");
195 		exit(1);
196 	}
197 	fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN);
198 	fprintf(stdout,
199 	    "Comment: \"%u-bit %s, converted from OpenSSH by %s@%s\"\n",
200 	    key_size(k), key_type(k),
201 	    pw->pw_name, hostname);
202 	dump_base64(stdout, blob, len);
203 	fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END);
204 	key_free(k);
205 	xfree(blob);
206 	exit(0);
207 }
208 
209 static void
210 buffer_get_bignum_bits(Buffer *b, BIGNUM *value)
211 {
212 	u_int bignum_bits = buffer_get_int(b);
213 	u_int bytes = (bignum_bits + 7) / 8;
214 
215 	if (buffer_len(b) < bytes)
216 		fatal("buffer_get_bignum_bits: input buffer too small: "
217 		    "need %d have %d", bytes, buffer_len(b));
218 	if (BN_bin2bn(buffer_ptr(b), bytes, value) == NULL)
219 		fatal("buffer_get_bignum_bits: BN_bin2bn failed");
220 	buffer_consume(b, bytes);
221 }
222 
223 static Key *
224 do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
225 {
226 	Buffer b;
227 	Key *key = NULL;
228 	char *type, *cipher;
229 	u_char *sig, data[] = "abcde12345";
230 	int magic, rlen, ktype, i1, i2, i3, i4;
231 	u_int slen;
232 	u_long e;
233 
234 	buffer_init(&b);
235 	buffer_append(&b, blob, blen);
236 
237 	magic = buffer_get_int(&b);
238 	if (magic != SSH_COM_PRIVATE_KEY_MAGIC) {
239 		error("bad magic 0x%x != 0x%x", magic, SSH_COM_PRIVATE_KEY_MAGIC);
240 		buffer_free(&b);
241 		return NULL;
242 	}
243 	i1 = buffer_get_int(&b);
244 	type   = buffer_get_string(&b, NULL);
245 	cipher = buffer_get_string(&b, NULL);
246 	i2 = buffer_get_int(&b);
247 	i3 = buffer_get_int(&b);
248 	i4 = buffer_get_int(&b);
249 	debug("ignore (%d %d %d %d)", i1, i2, i3, i4);
250 	if (strcmp(cipher, "none") != 0) {
251 		error("unsupported cipher %s", cipher);
252 		xfree(cipher);
253 		buffer_free(&b);
254 		xfree(type);
255 		return NULL;
256 	}
257 	xfree(cipher);
258 
259 	if (strstr(type, "dsa")) {
260 		ktype = KEY_DSA;
261 	} else if (strstr(type, "rsa")) {
262 		ktype = KEY_RSA;
263 	} else {
264 		buffer_free(&b);
265 		xfree(type);
266 		return NULL;
267 	}
268 	key = key_new_private(ktype);
269 	xfree(type);
270 
271 	switch (key->type) {
272 	case KEY_DSA:
273 		buffer_get_bignum_bits(&b, key->dsa->p);
274 		buffer_get_bignum_bits(&b, key->dsa->g);
275 		buffer_get_bignum_bits(&b, key->dsa->q);
276 		buffer_get_bignum_bits(&b, key->dsa->pub_key);
277 		buffer_get_bignum_bits(&b, key->dsa->priv_key);
278 		break;
279 	case KEY_RSA:
280 		e = buffer_get_char(&b);
281 		debug("e %lx", e);
282 		if (e < 30) {
283 			e <<= 8;
284 			e += buffer_get_char(&b);
285 			debug("e %lx", e);
286 			e <<= 8;
287 			e += buffer_get_char(&b);
288 			debug("e %lx", e);
289 		}
290 		if (!BN_set_word(key->rsa->e, e)) {
291 			buffer_free(&b);
292 			key_free(key);
293 			return NULL;
294 		}
295 		buffer_get_bignum_bits(&b, key->rsa->d);
296 		buffer_get_bignum_bits(&b, key->rsa->n);
297 		buffer_get_bignum_bits(&b, key->rsa->iqmp);
298 		buffer_get_bignum_bits(&b, key->rsa->q);
299 		buffer_get_bignum_bits(&b, key->rsa->p);
300 		rsa_generate_additional_parameters(key->rsa);
301 		break;
302 	}
303 	rlen = buffer_len(&b);
304 	if (rlen != 0)
305 		error("do_convert_private_ssh2_from_blob: "
306 		    "remaining bytes in key blob %d", rlen);
307 	buffer_free(&b);
308 
309 	/* try the key */
310 	key_sign(key, &sig, &slen, data, sizeof(data));
311 	key_verify(key, sig, slen, data, sizeof(data));
312 	xfree(sig);
313 	return key;
314 }
315 
316 static int
317 get_line(FILE *fp, char *line, size_t len)
318 {
319 	int c;
320 	size_t pos = 0;
321 
322 	line[0] = '\0';
323 	while ((c = fgetc(fp)) != EOF) {
324 		if (pos >= len - 1) {
325 			fprintf(stderr, "input line too long.\n");
326 			exit(1);
327 		}
328 		switch (c) {
329 		case '\r':
330 			c = fgetc(fp);
331 			if (c != EOF && c != '\n' && ungetc(c, fp) == EOF) {
332 				fprintf(stderr, "unget: %s\n", strerror(errno));
333 				exit(1);
334 			}
335 			return pos;
336 		case '\n':
337 			return pos;
338 		}
339 		line[pos++] = c;
340 		line[pos] = '\0';
341 	}
342 	/* We reached EOF */
343 	return -1;
344 }
345 
346 static void
347 do_convert_from_ssh2(struct passwd *pw)
348 {
349 	Key *k;
350 	int blen;
351 	u_int len;
352 	char line[1024];
353 	u_char blob[8096];
354 	char encoded[8096];
355 	struct stat st;
356 	int escaped = 0, private = 0, ok;
357 	FILE *fp;
358 
359 	if (!have_identity)
360 		ask_filename(pw, "Enter file in which the key is");
361 	if (stat(identity_file, &st) < 0) {
362 		perror(identity_file);
363 		exit(1);
364 	}
365 	fp = fopen(identity_file, "r");
366 	if (fp == NULL) {
367 		perror(identity_file);
368 		exit(1);
369 	}
370 	encoded[0] = '\0';
371 	while ((blen = get_line(fp, line, sizeof(line))) != -1) {
372 		if (line[blen - 1] == '\\')
373 			escaped++;
374 		if (strncmp(line, "----", 4) == 0 ||
375 		    strstr(line, ": ") != NULL) {
376 			if (strstr(line, SSH_COM_PRIVATE_BEGIN) != NULL)
377 				private = 1;
378 			if (strstr(line, " END ") != NULL) {
379 				break;
380 			}
381 			/* fprintf(stderr, "ignore: %s", line); */
382 			continue;
383 		}
384 		if (escaped) {
385 			escaped--;
386 			/* fprintf(stderr, "escaped: %s", line); */
387 			continue;
388 		}
389 		strlcat(encoded, line, sizeof(encoded));
390 	}
391 	len = strlen(encoded);
392 	if (((len % 4) == 3) &&
393 	    (encoded[len-1] == '=') &&
394 	    (encoded[len-2] == '=') &&
395 	    (encoded[len-3] == '='))
396 		encoded[len-3] = '\0';
397 	blen = uudecode(encoded, blob, sizeof(blob));
398 	if (blen < 0) {
399 		fprintf(stderr, "uudecode failed.\n");
400 		exit(1);
401 	}
402 	k = private ?
403 	    do_convert_private_ssh2_from_blob(blob, blen) :
404 	    key_from_blob(blob, blen);
405 	if (k == NULL) {
406 		fprintf(stderr, "decode blob failed.\n");
407 		exit(1);
408 	}
409 	ok = private ?
410 	    (k->type == KEY_DSA ?
411 		 PEM_write_DSAPrivateKey(stdout, k->dsa, NULL, NULL, 0, NULL, NULL) :
412 		 PEM_write_RSAPrivateKey(stdout, k->rsa, NULL, NULL, 0, NULL, NULL)) :
413 	    key_write(k, stdout);
414 	if (!ok) {
415 		fprintf(stderr, "key write failed");
416 		exit(1);
417 	}
418 	key_free(k);
419 	if (!private)
420 		fprintf(stdout, "\n");
421 	fclose(fp);
422 	exit(0);
423 }
424 
425 static void
426 do_print_public(struct passwd *pw)
427 {
428 	Key *prv;
429 	struct stat st;
430 
431 	if (!have_identity)
432 		ask_filename(pw, "Enter file in which the key is");
433 	if (stat(identity_file, &st) < 0) {
434 		perror(identity_file);
435 		exit(1);
436 	}
437 	prv = load_identity(identity_file);
438 	if (prv == NULL) {
439 		fprintf(stderr, "load failed\n");
440 		exit(1);
441 	}
442 	if (!key_write(prv, stdout))
443 		fprintf(stderr, "key_write failed");
444 	key_free(prv);
445 	fprintf(stdout, "\n");
446 	exit(0);
447 }
448 
449 #ifdef SMARTCARD
450 static void
451 do_upload(struct passwd *pw, const char *sc_reader_id)
452 {
453 	Key *prv = NULL;
454 	struct stat st;
455 	int ret;
456 
457 	if (!have_identity)
458 		ask_filename(pw, "Enter file in which the key is");
459 	if (stat(identity_file, &st) < 0) {
460 		perror(identity_file);
461 		exit(1);
462 	}
463 	prv = load_identity(identity_file);
464 	if (prv == NULL) {
465 		error("load failed");
466 		exit(1);
467 	}
468 	ret = sc_put_key(prv, sc_reader_id);
469 	key_free(prv);
470 	if (ret < 0)
471 		exit(1);
472 	logit("loading key done");
473 	exit(0);
474 }
475 
476 static void
477 do_download(struct passwd *pw, const char *sc_reader_id)
478 {
479 	Key **keys = NULL;
480 	int i;
481 
482 	keys = sc_get_keys(sc_reader_id, NULL);
483 	if (keys == NULL)
484 		fatal("cannot read public key from smartcard");
485 	for (i = 0; keys[i]; i++) {
486 		key_write(keys[i], stdout);
487 		key_free(keys[i]);
488 		fprintf(stdout, "\n");
489 	}
490 	xfree(keys);
491 	exit(0);
492 }
493 #endif /* SMARTCARD */
494 
495 static void
496 do_fingerprint(struct passwd *pw)
497 {
498 	FILE *f;
499 	Key *public;
500 	char *comment = NULL, *cp, *ep, line[16*1024], *fp;
501 	int i, skip = 0, num = 1, invalid = 1;
502 	enum fp_rep rep;
503 	enum fp_type fptype;
504 	struct stat st;
505 
506 	fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;
507 	rep =    print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX;
508 
509 	if (!have_identity)
510 		ask_filename(pw, "Enter file in which the key is");
511 	if (stat(identity_file, &st) < 0) {
512 		perror(identity_file);
513 		exit(1);
514 	}
515 	public = key_load_public(identity_file, &comment);
516 	if (public != NULL) {
517 		fp = key_fingerprint(public, fptype, rep);
518 		printf("%u %s %s\n", key_size(public), fp, comment);
519 		key_free(public);
520 		xfree(comment);
521 		xfree(fp);
522 		exit(0);
523 	}
524 	if (comment) {
525 		xfree(comment);
526 		comment = NULL;
527 	}
528 
529 	f = fopen(identity_file, "r");
530 	if (f != NULL) {
531 		while (fgets(line, sizeof(line), f)) {
532 			i = strlen(line) - 1;
533 			if (line[i] != '\n') {
534 				error("line %d too long: %.40s...", num, line);
535 				skip = 1;
536 				continue;
537 			}
538 			num++;
539 			if (skip) {
540 				skip = 0;
541 				continue;
542 			}
543 			line[i] = '\0';
544 
545 			/* Skip leading whitespace, empty and comment lines. */
546 			for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
547 				;
548 			if (!*cp || *cp == '\n' || *cp == '#')
549 				continue;
550 			i = strtol(cp, &ep, 10);
551 			if (i == 0 || ep == NULL || (*ep != ' ' && *ep != '\t')) {
552 				int quoted = 0;
553 				comment = cp;
554 				for (; *cp && (quoted || (*cp != ' ' &&
555 				    *cp != '\t')); cp++) {
556 					if (*cp == '\\' && cp[1] == '"')
557 						cp++;	/* Skip both */
558 					else if (*cp == '"')
559 						quoted = !quoted;
560 				}
561 				if (!*cp)
562 					continue;
563 				*cp++ = '\0';
564 			}
565 			ep = cp;
566 			public = key_new(KEY_RSA1);
567 			if (key_read(public, &cp) != 1) {
568 				cp = ep;
569 				key_free(public);
570 				public = key_new(KEY_UNSPEC);
571 				if (key_read(public, &cp) != 1) {
572 					key_free(public);
573 					continue;
574 				}
575 			}
576 			comment = *cp ? cp : comment;
577 			fp = key_fingerprint(public, fptype, rep);
578 			printf("%u %s %s\n", key_size(public), fp,
579 			    comment ? comment : "no comment");
580 			xfree(fp);
581 			key_free(public);
582 			invalid = 0;
583 		}
584 		fclose(f);
585 	}
586 	if (invalid) {
587 		printf("%s is not a public key file.\n", identity_file);
588 		exit(1);
589 	}
590 	exit(0);
591 }
592 
593 static void
594 print_host(FILE *f, char *name, Key *public, int hash)
595 {
596 	if (hash && (name = host_hash(name, NULL, 0)) == NULL)
597 		fatal("hash_host failed");
598 	fprintf(f, "%s ", name);
599 	if (!key_write(public, f))
600 		fatal("key_write failed");
601 	fprintf(f, "\n");
602 }
603 
604 static void
605 do_known_hosts(struct passwd *pw, const char *name)
606 {
607 	FILE *in, *out = stdout;
608 	Key *public;
609 	char *cp, *cp2, *kp, *kp2;
610 	char line[16*1024], tmp[MAXPATHLEN], old[MAXPATHLEN];
611 	int c, i, skip = 0, inplace = 0, num = 0, invalid = 0, has_unhashed = 0;
612 
613 	if (!have_identity) {
614 		cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid);
615 		if (strlcpy(identity_file, cp, sizeof(identity_file)) >=
616 		    sizeof(identity_file))
617 			fatal("Specified known hosts path too long");
618 		xfree(cp);
619 		have_identity = 1;
620 	}
621 	if ((in = fopen(identity_file, "r")) == NULL)
622 		fatal("fopen: %s", strerror(errno));
623 
624 	/*
625 	 * Find hosts goes to stdout, hash and deletions happen in-place
626 	 * A corner case is ssh-keygen -HF foo, which should go to stdout
627 	 */
628 	if (!find_host && (hash_hosts || delete_host)) {
629 		if (strlcpy(tmp, identity_file, sizeof(tmp)) >= sizeof(tmp) ||
630 		    strlcat(tmp, ".XXXXXXXXXX", sizeof(tmp)) >= sizeof(tmp) ||
631 		    strlcpy(old, identity_file, sizeof(old)) >= sizeof(old) ||
632 		    strlcat(old, ".old", sizeof(old)) >= sizeof(old))
633 			fatal("known_hosts path too long");
634 		umask(077);
635 		if ((c = mkstemp(tmp)) == -1)
636 			fatal("mkstemp: %s", strerror(errno));
637 		if ((out = fdopen(c, "w")) == NULL) {
638 			c = errno;
639 			unlink(tmp);
640 			fatal("fdopen: %s", strerror(c));
641 		}
642 		inplace = 1;
643 	}
644 
645 	while (fgets(line, sizeof(line), in)) {
646 		num++;
647 		i = strlen(line) - 1;
648 		if (line[i] != '\n') {
649 			error("line %d too long: %.40s...", num, line);
650 			skip = 1;
651 			invalid = 1;
652 			continue;
653 		}
654 		if (skip) {
655 			skip = 0;
656 			continue;
657 		}
658 		line[i] = '\0';
659 
660 		/* Skip leading whitespace, empty and comment lines. */
661 		for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
662 			;
663 		if (!*cp || *cp == '\n' || *cp == '#') {
664 			if (inplace)
665 				fprintf(out, "%s\n", cp);
666 			continue;
667 		}
668 		/* Find the end of the host name portion. */
669 		for (kp = cp; *kp && *kp != ' ' && *kp != '\t'; kp++)
670 			;
671 		if (*kp == '\0' || *(kp + 1) == '\0') {
672 			error("line %d missing key: %.40s...",
673 			    num, line);
674 			invalid = 1;
675 			continue;
676 		}
677 		*kp++ = '\0';
678 		kp2 = kp;
679 
680 		public = key_new(KEY_RSA1);
681 		if (key_read(public, &kp) != 1) {
682 			kp = kp2;
683 			key_free(public);
684 			public = key_new(KEY_UNSPEC);
685 			if (key_read(public, &kp) != 1) {
686 				error("line %d invalid key: %.40s...",
687 				    num, line);
688 				key_free(public);
689 				invalid = 1;
690 				continue;
691 			}
692 		}
693 
694 		if (*cp == HASH_DELIM) {
695 			if (find_host || delete_host) {
696 				cp2 = host_hash(name, cp, strlen(cp));
697 				if (cp2 == NULL) {
698 					error("line %d: invalid hashed "
699 					    "name: %.64s...", num, line);
700 					invalid = 1;
701 					continue;
702 				}
703 				c = (strcmp(cp2, cp) == 0);
704 				if (find_host && c) {
705 					printf("# Host %s found: "
706 					    "line %d type %s\n", name,
707 					    num, key_type(public));
708 					print_host(out, cp, public, 0);
709 				}
710 				if (delete_host && !c)
711 					print_host(out, cp, public, 0);
712 			} else if (hash_hosts)
713 				print_host(out, cp, public, 0);
714 		} else {
715 			if (find_host || delete_host) {
716 				c = (match_hostname(name, cp,
717 				    strlen(cp)) == 1);
718 				if (find_host && c) {
719 					printf("# Host %s found: "
720 					    "line %d type %s\n", name,
721 					    num, key_type(public));
722 					print_host(out, cp, public, hash_hosts);
723 				}
724 				if (delete_host && !c)
725 					print_host(out, cp, public, 0);
726 			} else if (hash_hosts) {
727 				for (cp2 = strsep(&cp, ",");
728 				    cp2 != NULL && *cp2 != '\0';
729 				    cp2 = strsep(&cp, ",")) {
730 					if (strcspn(cp2, "*?!") != strlen(cp2))
731 						fprintf(stderr, "Warning: "
732 						    "ignoring host name with "
733 						    "metacharacters: %.64s\n",
734 						    cp2);
735 					else
736 						print_host(out, cp2, public, 1);
737 				}
738 				has_unhashed = 1;
739 			}
740 		}
741 		key_free(public);
742 	}
743 	fclose(in);
744 
745 	if (invalid) {
746 		fprintf(stderr, "%s is not a valid known_host file.\n",
747 		    identity_file);
748 		if (inplace) {
749 			fprintf(stderr, "Not replacing existing known_hosts "
750 			    "file because of errors\n");
751 			fclose(out);
752 			unlink(tmp);
753 		}
754 		exit(1);
755 	}
756 
757 	if (inplace) {
758 		fclose(out);
759 
760 		/* Backup existing file */
761 		if (unlink(old) == -1 && errno != ENOENT)
762 			fatal("unlink %.100s: %s", old, strerror(errno));
763 		if (link(identity_file, old) == -1)
764 			fatal("link %.100s to %.100s: %s", identity_file, old,
765 			    strerror(errno));
766 		/* Move new one into place */
767 		if (rename(tmp, identity_file) == -1) {
768 			error("rename\"%s\" to \"%s\": %s", tmp, identity_file,
769 			    strerror(errno));
770 			unlink(tmp);
771 			unlink(old);
772 			exit(1);
773 		}
774 
775 		fprintf(stderr, "%s updated.\n", identity_file);
776 		fprintf(stderr, "Original contents retained as %s\n", old);
777 		if (has_unhashed) {
778 			fprintf(stderr, "WARNING: %s contains unhashed "
779 			    "entries\n", old);
780 			fprintf(stderr, "Delete this file to ensure privacy "
781 			    "of hostnames\n");
782 		}
783 	}
784 
785 	exit(0);
786 }
787 
788 /*
789  * Perform changing a passphrase.  The argument is the passwd structure
790  * for the current user.
791  */
792 static void
793 do_change_passphrase(struct passwd *pw)
794 {
795 	char *comment;
796 	char *old_passphrase, *passphrase1, *passphrase2;
797 	struct stat st;
798 	Key *private;
799 
800 	if (!have_identity)
801 		ask_filename(pw, "Enter file in which the key is");
802 	if (stat(identity_file, &st) < 0) {
803 		perror(identity_file);
804 		exit(1);
805 	}
806 	/* Try to load the file with empty passphrase. */
807 	private = key_load_private(identity_file, "", &comment);
808 	if (private == NULL) {
809 		if (identity_passphrase)
810 			old_passphrase = xstrdup(identity_passphrase);
811 		else
812 			old_passphrase =
813 			    read_passphrase("Enter old passphrase: ",
814 			    RP_ALLOW_STDIN);
815 		private = key_load_private(identity_file, old_passphrase,
816 		    &comment);
817 		memset(old_passphrase, 0, strlen(old_passphrase));
818 		xfree(old_passphrase);
819 		if (private == NULL) {
820 			printf("Bad passphrase.\n");
821 			exit(1);
822 		}
823 	}
824 	printf("Key has comment '%s'\n", comment);
825 
826 	/* Ask the new passphrase (twice). */
827 	if (identity_new_passphrase) {
828 		passphrase1 = xstrdup(identity_new_passphrase);
829 		passphrase2 = NULL;
830 	} else {
831 		passphrase1 =
832 			read_passphrase("Enter new passphrase (empty for no "
833 			    "passphrase): ", RP_ALLOW_STDIN);
834 		passphrase2 = read_passphrase("Enter same passphrase again: ",
835 		    RP_ALLOW_STDIN);
836 
837 		/* Verify that they are the same. */
838 		if (strcmp(passphrase1, passphrase2) != 0) {
839 			memset(passphrase1, 0, strlen(passphrase1));
840 			memset(passphrase2, 0, strlen(passphrase2));
841 			xfree(passphrase1);
842 			xfree(passphrase2);
843 			printf("Pass phrases do not match.  Try again.\n");
844 			exit(1);
845 		}
846 		/* Destroy the other copy. */
847 		memset(passphrase2, 0, strlen(passphrase2));
848 		xfree(passphrase2);
849 	}
850 
851 	/* Save the file using the new passphrase. */
852 	if (!key_save_private(private, identity_file, passphrase1, comment)) {
853 		printf("Saving the key failed: %s.\n", identity_file);
854 		memset(passphrase1, 0, strlen(passphrase1));
855 		xfree(passphrase1);
856 		key_free(private);
857 		xfree(comment);
858 		exit(1);
859 	}
860 	/* Destroy the passphrase and the copy of the key in memory. */
861 	memset(passphrase1, 0, strlen(passphrase1));
862 	xfree(passphrase1);
863 	key_free(private);		 /* Destroys contents */
864 	xfree(comment);
865 
866 	printf("Your identification has been saved with the new passphrase.\n");
867 	exit(0);
868 }
869 
870 /*
871  * Print the SSHFP RR.
872  */
873 static int
874 do_print_resource_record(struct passwd *pw, char *fname, char *hname)
875 {
876 	Key *public;
877 	char *comment = NULL;
878 	struct stat st;
879 
880 	if (fname == NULL)
881 		ask_filename(pw, "Enter file in which the key is");
882 	if (stat(fname, &st) < 0) {
883 		if (errno == ENOENT)
884 			return 0;
885 		perror(fname);
886 		exit(1);
887 	}
888 	public = key_load_public(fname, &comment);
889 	if (public != NULL) {
890 		export_dns_rr(hname, public, stdout, print_generic);
891 		key_free(public);
892 		xfree(comment);
893 		return 1;
894 	}
895 	if (comment)
896 		xfree(comment);
897 
898 	printf("failed to read v2 public key from %s.\n", fname);
899 	exit(1);
900 }
901 
902 /*
903  * Change the comment of a private key file.
904  */
905 static void
906 do_change_comment(struct passwd *pw)
907 {
908 	char new_comment[1024], *comment, *passphrase;
909 	Key *private;
910 	Key *public;
911 	struct stat st;
912 	FILE *f;
913 	int fd;
914 
915 	if (!have_identity)
916 		ask_filename(pw, "Enter file in which the key is");
917 	if (stat(identity_file, &st) < 0) {
918 		perror(identity_file);
919 		exit(1);
920 	}
921 	private = key_load_private(identity_file, "", &comment);
922 	if (private == NULL) {
923 		if (identity_passphrase)
924 			passphrase = xstrdup(identity_passphrase);
925 		else if (identity_new_passphrase)
926 			passphrase = xstrdup(identity_new_passphrase);
927 		else
928 			passphrase = read_passphrase("Enter passphrase: ",
929 			    RP_ALLOW_STDIN);
930 		/* Try to load using the passphrase. */
931 		private = key_load_private(identity_file, passphrase, &comment);
932 		if (private == NULL) {
933 			memset(passphrase, 0, strlen(passphrase));
934 			xfree(passphrase);
935 			printf("Bad passphrase.\n");
936 			exit(1);
937 		}
938 	} else {
939 		passphrase = xstrdup("");
940 	}
941 	if (private->type != KEY_RSA1) {
942 		fprintf(stderr, "Comments are only supported for RSA1 keys.\n");
943 		key_free(private);
944 		exit(1);
945 	}
946 	printf("Key now has comment '%s'\n", comment);
947 
948 	if (identity_comment) {
949 		strlcpy(new_comment, identity_comment, sizeof(new_comment));
950 	} else {
951 		printf("Enter new comment: ");
952 		fflush(stdout);
953 		if (!fgets(new_comment, sizeof(new_comment), stdin)) {
954 			memset(passphrase, 0, strlen(passphrase));
955 			key_free(private);
956 			exit(1);
957 		}
958 		if (strchr(new_comment, '\n'))
959 			*strchr(new_comment, '\n') = 0;
960 	}
961 
962 	/* Save the file using the new passphrase. */
963 	if (!key_save_private(private, identity_file, passphrase, new_comment)) {
964 		printf("Saving the key failed: %s.\n", identity_file);
965 		memset(passphrase, 0, strlen(passphrase));
966 		xfree(passphrase);
967 		key_free(private);
968 		xfree(comment);
969 		exit(1);
970 	}
971 	memset(passphrase, 0, strlen(passphrase));
972 	xfree(passphrase);
973 	public = key_from_private(private);
974 	key_free(private);
975 
976 	strlcat(identity_file, ".pub", sizeof(identity_file));
977 	fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
978 	if (fd == -1) {
979 		printf("Could not save your public key in %s\n", identity_file);
980 		exit(1);
981 	}
982 	f = fdopen(fd, "w");
983 	if (f == NULL) {
984 		printf("fdopen %s failed", identity_file);
985 		exit(1);
986 	}
987 	if (!key_write(public, f))
988 		fprintf(stderr, "write key failed");
989 	key_free(public);
990 	fprintf(f, " %s\n", new_comment);
991 	fclose(f);
992 
993 	xfree(comment);
994 
995 	printf("The comment in your key file has been changed.\n");
996 	exit(0);
997 }
998 
999 static void
1000 usage(void)
1001 {
1002 	fprintf(stderr, "Usage: %s [options]\n", __progname);
1003 	fprintf(stderr, "Options:\n");
1004 	fprintf(stderr, "  -a trials   Number of trials for screening DH-GEX moduli.\n");
1005 	fprintf(stderr, "  -B          Show bubblebabble digest of key file.\n");
1006 	fprintf(stderr, "  -b bits     Number of bits in the key to create.\n");
1007 	fprintf(stderr, "  -C comment  Provide new comment.\n");
1008 	fprintf(stderr, "  -c          Change comment in private and public key files.\n");
1009 #ifdef SMARTCARD
1010 	fprintf(stderr, "  -D reader   Download public key from smartcard.\n");
1011 #endif /* SMARTCARD */
1012 	fprintf(stderr, "  -e          Convert OpenSSH to RFC 4716 key file.\n");
1013 	fprintf(stderr, "  -F hostname Find hostname in known hosts file.\n");
1014 	fprintf(stderr, "  -f filename Filename of the key file.\n");
1015 	fprintf(stderr, "  -G file     Generate candidates for DH-GEX moduli.\n");
1016 	fprintf(stderr, "  -g          Use generic DNS resource record format.\n");
1017 	fprintf(stderr, "  -H          Hash names in known_hosts file.\n");
1018 	fprintf(stderr, "  -i          Convert RFC 4716 to OpenSSH key file.\n");
1019 	fprintf(stderr, "  -l          Show fingerprint of key file.\n");
1020 	fprintf(stderr, "  -M memory   Amount of memory (MB) to use for generating DH-GEX moduli.\n");
1021 	fprintf(stderr, "  -N phrase   Provide new passphrase.\n");
1022 	fprintf(stderr, "  -P phrase   Provide old passphrase.\n");
1023 	fprintf(stderr, "  -p          Change passphrase of private key file.\n");
1024 	fprintf(stderr, "  -q          Quiet.\n");
1025 	fprintf(stderr, "  -R hostname Remove host from known_hosts file.\n");
1026 	fprintf(stderr, "  -r hostname Print DNS resource record.\n");
1027 	fprintf(stderr, "  -S start    Start point (hex) for generating DH-GEX moduli.\n");
1028 	fprintf(stderr, "  -T file     Screen candidates for DH-GEX moduli.\n");
1029 	fprintf(stderr, "  -t type     Specify type of key to create.\n");
1030 #ifdef SMARTCARD
1031 	fprintf(stderr, "  -U reader   Upload private key to smartcard.\n");
1032 #endif /* SMARTCARD */
1033 	fprintf(stderr, "  -v          Verbose.\n");
1034 	fprintf(stderr, "  -W gen      Generator to use for generating DH-GEX moduli.\n");
1035 	fprintf(stderr, "  -y          Read private key file and print public key.\n");
1036 
1037 	exit(1);
1038 }
1039 
1040 /*
1041  * Main program for key management.
1042  */
1043 int
1044 main(int argc, char **argv)
1045 {
1046 	char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2;
1047 	char out_file[MAXPATHLEN], *reader_id = NULL;
1048 	char *rr_hostname = NULL;
1049 	Key *private, *public;
1050 	struct passwd *pw;
1051 	struct stat st;
1052 	int opt, type, fd, download = 0;
1053 	u_int32_t memory = 0, generator_wanted = 0, trials = 100;
1054 	int do_gen_candidates = 0, do_screen_candidates = 0;
1055 	int log_level = SYSLOG_LEVEL_INFO;
1056 	BIGNUM *start = NULL;
1057 	FILE *f;
1058 	const char *errstr;
1059 
1060 	extern int optind;
1061 	extern char *optarg;
1062 
1063 	/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
1064 	sanitise_stdfd();
1065 
1066 	SSLeay_add_all_algorithms();
1067 	log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);
1068 
1069 	/* we need this for the home * directory.  */
1070 	pw = getpwuid(getuid());
1071 	if (!pw) {
1072 		printf("You don't exist, go away!\n");
1073 		exit(1);
1074 	}
1075 	if (gethostname(hostname, sizeof(hostname)) < 0) {
1076 		perror("gethostname");
1077 		exit(1);
1078 	}
1079 
1080 	while ((opt = getopt(argc, argv,
1081 	    "degiqpclBHvxXyF:b:f:t:U:D:P:N:C:r:g:R:T:G:M:S:a:W:")) != -1) {
1082 		switch (opt) {
1083 		case 'b':
1084 			bits = (u_int32_t)strtonum(optarg, 768, 32768, &errstr);
1085 			if (errstr)
1086 				fatal("Bits has bad value %s (%s)",
1087 					optarg, errstr);
1088 			break;
1089 		case 'F':
1090 			find_host = 1;
1091 			rr_hostname = optarg;
1092 			break;
1093 		case 'H':
1094 			hash_hosts = 1;
1095 			break;
1096 		case 'R':
1097 			delete_host = 1;
1098 			rr_hostname = optarg;
1099 			break;
1100 		case 'l':
1101 			print_fingerprint = 1;
1102 			break;
1103 		case 'B':
1104 			print_bubblebabble = 1;
1105 			break;
1106 		case 'p':
1107 			change_passphrase = 1;
1108 			break;
1109 		case 'c':
1110 			change_comment = 1;
1111 			break;
1112 		case 'f':
1113 			if (strlcpy(identity_file, optarg, sizeof(identity_file)) >=
1114 			    sizeof(identity_file))
1115 				fatal("Identity filename too long");
1116 			have_identity = 1;
1117 			break;
1118 		case 'g':
1119 			print_generic = 1;
1120 			break;
1121 		case 'P':
1122 			identity_passphrase = optarg;
1123 			break;
1124 		case 'N':
1125 			identity_new_passphrase = optarg;
1126 			break;
1127 		case 'C':
1128 			identity_comment = optarg;
1129 			break;
1130 		case 'q':
1131 			quiet = 1;
1132 			break;
1133 		case 'e':
1134 		case 'x':
1135 			/* export key */
1136 			convert_to_ssh2 = 1;
1137 			break;
1138 		case 'i':
1139 		case 'X':
1140 			/* import key */
1141 			convert_from_ssh2 = 1;
1142 			break;
1143 		case 'y':
1144 			print_public = 1;
1145 			break;
1146 		case 'd':
1147 			key_type_name = "dsa";
1148 			break;
1149 		case 't':
1150 			key_type_name = optarg;
1151 			break;
1152 		case 'D':
1153 			download = 1;
1154 			/*FALLTHROUGH*/
1155 		case 'U':
1156 			reader_id = optarg;
1157 			break;
1158 		case 'v':
1159 			if (log_level == SYSLOG_LEVEL_INFO)
1160 				log_level = SYSLOG_LEVEL_DEBUG1;
1161 			else {
1162 				if (log_level >= SYSLOG_LEVEL_DEBUG1 &&
1163 				    log_level < SYSLOG_LEVEL_DEBUG3)
1164 					log_level++;
1165 			}
1166 			break;
1167 		case 'r':
1168 			rr_hostname = optarg;
1169 			break;
1170 		case 'W':
1171 			generator_wanted = (u_int32_t)strtonum(optarg, 1,
1172 			    UINT_MAX, &errstr);
1173 			if (errstr)
1174 				fatal("Desired generator has bad value: %s (%s)",
1175 					optarg, errstr);
1176 			break;
1177 		case 'a':
1178 			trials = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr);
1179 			if (errstr)
1180 				fatal("Invalid number of trials: %s (%s)",
1181 					optarg, errstr);
1182 			break;
1183 		case 'M':
1184 			memory = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr);
1185 			if (errstr) {
1186 				fatal("Memory limit is %s: %s", errstr, optarg);
1187 			}
1188 			break;
1189 		case 'G':
1190 			do_gen_candidates = 1;
1191 			if (strlcpy(out_file, optarg, sizeof(out_file)) >=
1192 			    sizeof(out_file))
1193 				fatal("Output filename too long");
1194 			break;
1195 		case 'T':
1196 			do_screen_candidates = 1;
1197 			if (strlcpy(out_file, optarg, sizeof(out_file)) >=
1198 			    sizeof(out_file))
1199 				fatal("Output filename too long");
1200 			break;
1201 		case 'S':
1202 			/* XXX - also compare length against bits */
1203 			if (BN_hex2bn(&start, optarg) == 0)
1204 				fatal("Invalid start point.");
1205 			break;
1206 		case '?':
1207 		default:
1208 			usage();
1209 		}
1210 	}
1211 
1212 	/* reinit */
1213 	log_init(argv[0], log_level, SYSLOG_FACILITY_USER, 1);
1214 
1215 	if (optind < argc) {
1216 		printf("Too many arguments.\n");
1217 		usage();
1218 	}
1219 	if (change_passphrase && change_comment) {
1220 		printf("Can only have one of -p and -c.\n");
1221 		usage();
1222 	}
1223 	if (delete_host || hash_hosts || find_host)
1224 		do_known_hosts(pw, rr_hostname);
1225 	if (print_fingerprint || print_bubblebabble)
1226 		do_fingerprint(pw);
1227 	if (change_passphrase)
1228 		do_change_passphrase(pw);
1229 	if (change_comment)
1230 		do_change_comment(pw);
1231 	if (convert_to_ssh2)
1232 		do_convert_to_ssh2(pw);
1233 	if (convert_from_ssh2)
1234 		do_convert_from_ssh2(pw);
1235 	if (print_public)
1236 		do_print_public(pw);
1237 	if (rr_hostname != NULL) {
1238 		unsigned int n = 0;
1239 
1240 		if (have_identity) {
1241 			n = do_print_resource_record(pw,
1242 			    identity_file, rr_hostname);
1243 			if (n == 0) {
1244 				perror(identity_file);
1245 				exit(1);
1246 			}
1247 			exit(0);
1248 		} else {
1249 
1250 			n += do_print_resource_record(pw,
1251 			    _PATH_HOST_RSA_KEY_FILE, rr_hostname);
1252 			n += do_print_resource_record(pw,
1253 			    _PATH_HOST_DSA_KEY_FILE, rr_hostname);
1254 
1255 			if (n == 0)
1256 				fatal("no keys found.");
1257 			exit(0);
1258 		}
1259 	}
1260 	if (reader_id != NULL) {
1261 #ifdef SMARTCARD
1262 		if (download)
1263 			do_download(pw, reader_id);
1264 		else
1265 			do_upload(pw, reader_id);
1266 #else /* SMARTCARD */
1267 		fatal("no support for smartcards.");
1268 #endif /* SMARTCARD */
1269 	}
1270 
1271 	if (do_gen_candidates) {
1272 		FILE *out = fopen(out_file, "w");
1273 
1274 		if (out == NULL) {
1275 			error("Couldn't open modulus candidate file \"%s\": %s",
1276 			    out_file, strerror(errno));
1277 			return (1);
1278 		}
1279 		if (bits == 0)
1280 			bits = DEFAULT_BITS;
1281 		if (gen_candidates(out, memory, bits, start) != 0)
1282 			fatal("modulus candidate generation failed");
1283 
1284 		return (0);
1285 	}
1286 
1287 	if (do_screen_candidates) {
1288 		FILE *in;
1289 		FILE *out = fopen(out_file, "w");
1290 
1291 		if (have_identity && strcmp(identity_file, "-") != 0) {
1292 			if ((in = fopen(identity_file, "r")) == NULL) {
1293 				fatal("Couldn't open modulus candidate "
1294 				    "file \"%s\": %s", identity_file,
1295 				    strerror(errno));
1296 			}
1297 		} else
1298 			in = stdin;
1299 
1300 		if (out == NULL) {
1301 			fatal("Couldn't open moduli file \"%s\": %s",
1302 			    out_file, strerror(errno));
1303 		}
1304 		if (prime_test(in, out, trials, generator_wanted) != 0)
1305 			fatal("modulus screening failed");
1306 		return (0);
1307 	}
1308 
1309 	arc4random_stir();
1310 
1311 	if (key_type_name == NULL)
1312 		key_type_name = "rsa";
1313 
1314 	type = key_type_from_name(key_type_name);
1315 	if (type == KEY_UNSPEC) {
1316 		fprintf(stderr, "unknown key type %s\n", key_type_name);
1317 		exit(1);
1318 	}
1319 	if (bits == 0)
1320 		bits = (type == KEY_DSA) ? DEFAULT_BITS_DSA : DEFAULT_BITS;
1321 	if (type == KEY_DSA && bits != 1024)
1322 		fatal("DSA keys must be 1024 bits");
1323 	if (!quiet)
1324 		printf("Generating public/private %s key pair.\n", key_type_name);
1325 	private = key_generate(type, bits);
1326 	if (private == NULL) {
1327 		fprintf(stderr, "key_generate failed");
1328 		exit(1);
1329 	}
1330 	public  = key_from_private(private);
1331 
1332 	if (!have_identity)
1333 		ask_filename(pw, "Enter file in which to save the key");
1334 
1335 	/* Create ~/.ssh directory if it doesn't already exist. */
1336 	snprintf(dotsshdir, sizeof dotsshdir, "%s/%s", pw->pw_dir, _PATH_SSH_USER_DIR);
1337 	if (strstr(identity_file, dotsshdir) != NULL &&
1338 	    stat(dotsshdir, &st) < 0) {
1339 		if (mkdir(dotsshdir, 0700) < 0)
1340 			error("Could not create directory '%s'.", dotsshdir);
1341 		else if (!quiet)
1342 			printf("Created directory '%s'.\n", dotsshdir);
1343 	}
1344 	/* If the file already exists, ask the user to confirm. */
1345 	if (stat(identity_file, &st) >= 0) {
1346 		char yesno[3];
1347 		printf("%s already exists.\n", identity_file);
1348 		printf("Overwrite (y/n)? ");
1349 		fflush(stdout);
1350 		if (fgets(yesno, sizeof(yesno), stdin) == NULL)
1351 			exit(1);
1352 		if (yesno[0] != 'y' && yesno[0] != 'Y')
1353 			exit(1);
1354 	}
1355 	/* Ask for a passphrase (twice). */
1356 	if (identity_passphrase)
1357 		passphrase1 = xstrdup(identity_passphrase);
1358 	else if (identity_new_passphrase)
1359 		passphrase1 = xstrdup(identity_new_passphrase);
1360 	else {
1361 passphrase_again:
1362 		passphrase1 =
1363 			read_passphrase("Enter passphrase (empty for no "
1364 			    "passphrase): ", RP_ALLOW_STDIN);
1365 		passphrase2 = read_passphrase("Enter same passphrase again: ",
1366 		    RP_ALLOW_STDIN);
1367 		if (strcmp(passphrase1, passphrase2) != 0) {
1368 			/*
1369 			 * The passphrases do not match.  Clear them and
1370 			 * retry.
1371 			 */
1372 			memset(passphrase1, 0, strlen(passphrase1));
1373 			memset(passphrase2, 0, strlen(passphrase2));
1374 			xfree(passphrase1);
1375 			xfree(passphrase2);
1376 			printf("Passphrases do not match.  Try again.\n");
1377 			goto passphrase_again;
1378 		}
1379 		/* Clear the other copy of the passphrase. */
1380 		memset(passphrase2, 0, strlen(passphrase2));
1381 		xfree(passphrase2);
1382 	}
1383 
1384 	if (identity_comment) {
1385 		strlcpy(comment, identity_comment, sizeof(comment));
1386 	} else {
1387 		/* Create default commend field for the passphrase. */
1388 		snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname);
1389 	}
1390 
1391 	/* Save the key with the given passphrase and comment. */
1392 	if (!key_save_private(private, identity_file, passphrase1, comment)) {
1393 		printf("Saving the key failed: %s.\n", identity_file);
1394 		memset(passphrase1, 0, strlen(passphrase1));
1395 		xfree(passphrase1);
1396 		exit(1);
1397 	}
1398 	/* Clear the passphrase. */
1399 	memset(passphrase1, 0, strlen(passphrase1));
1400 	xfree(passphrase1);
1401 
1402 	/* Clear the private key and the random number generator. */
1403 	key_free(private);
1404 	arc4random_stir();
1405 
1406 	if (!quiet)
1407 		printf("Your identification has been saved in %s.\n", identity_file);
1408 
1409 	strlcat(identity_file, ".pub", sizeof(identity_file));
1410 	fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
1411 	if (fd == -1) {
1412 		printf("Could not save your public key in %s\n", identity_file);
1413 		exit(1);
1414 	}
1415 	f = fdopen(fd, "w");
1416 	if (f == NULL) {
1417 		printf("fdopen %s failed", identity_file);
1418 		exit(1);
1419 	}
1420 	if (!key_write(public, f))
1421 		fprintf(stderr, "write key failed");
1422 	fprintf(f, " %s\n", comment);
1423 	fclose(f);
1424 
1425 	if (!quiet) {
1426 		char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX);
1427 		printf("Your public key has been saved in %s.\n",
1428 		    identity_file);
1429 		printf("The key fingerprint is:\n");
1430 		printf("%s %s\n", fp, comment);
1431 		xfree(fp);
1432 	}
1433 
1434 	key_free(public);
1435 	exit(0);
1436 }
1437