xref: /freebsd/crypto/openssh/ssh-keygen.c (revision 1a2cdef4962b47be5057809ce730a733b7f3c27c)
1 /*
2  * Author: Tatu Ylonen <ylo@cs.hut.fi>
3  * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4  *                    All rights reserved
5  * Identity and host key generation and maintenance.
6  *
7  * As far as I am concerned, the code I have written for this software
8  * can be used freely for any purpose.  Any derived versions of this
9  * software must be clearly marked as such, and if the derived work is
10  * incompatible with the protocol description in the RFC file, it must be
11  * called by a name other than "ssh" or "Secure Shell".
12  */
13 
14 #include "includes.h"
15 RCSID("$OpenBSD: ssh-keygen.c,v 1.32 2000/10/09 21:30:44 markus Exp $");
16 
17 #include <openssl/evp.h>
18 #include <openssl/pem.h>
19 #include <openssl/rsa.h>
20 #include <openssl/dsa.h>
21 
22 #include "ssh.h"
23 #include "xmalloc.h"
24 #include "key.h"
25 #include "rsa.h"
26 #include "dsa.h"
27 #include "authfile.h"
28 #include "uuencode.h"
29 
30 #include "buffer.h"
31 #include "bufaux.h"
32 
33 /* Number of bits in the RSA/DSA key.  This value can be changed on the command line. */
34 int bits = 1024;
35 
36 /*
37  * Flag indicating that we just want to change the passphrase.  This can be
38  * set on the command line.
39  */
40 int change_passphrase = 0;
41 
42 /*
43  * Flag indicating that we just want to change the comment.  This can be set
44  * on the command line.
45  */
46 int change_comment = 0;
47 
48 int quiet = 0;
49 
50 /* Flag indicating that we just want to see the key fingerprint */
51 int print_fingerprint = 0;
52 
53 /* The identity file name, given on the command line or entered by the user. */
54 char identity_file[1024];
55 int have_identity = 0;
56 
57 /* This is set to the passphrase if given on the command line. */
58 char *identity_passphrase = NULL;
59 
60 /* This is set to the new passphrase if given on the command line. */
61 char *identity_new_passphrase = NULL;
62 
63 /* This is set to the new comment if given on the command line. */
64 char *identity_comment = NULL;
65 
66 /* Dump public key file in format used by real and the original SSH 2 */
67 int convert_to_ssh2 = 0;
68 int convert_from_ssh2 = 0;
69 int print_public = 0;
70 int dsa_mode = 0;
71 
72 /* argv0 */
73 extern char *__progname;
74 
75 char hostname[MAXHOSTNAMELEN];
76 
77 void
78 ask_filename(struct passwd *pw, const char *prompt)
79 {
80 	char buf[1024];
81 	snprintf(identity_file, sizeof(identity_file), "%s/%s",
82 	    pw->pw_dir,
83 	    dsa_mode ? SSH_CLIENT_ID_DSA: SSH_CLIENT_IDENTITY);
84 	printf("%s (%s): ", prompt, identity_file);
85 	fflush(stdout);
86 	if (fgets(buf, sizeof(buf), stdin) == NULL)
87 		exit(1);
88 	if (strchr(buf, '\n'))
89 		*strchr(buf, '\n') = 0;
90 	if (strcmp(buf, "") != 0)
91 		strlcpy(identity_file, buf, sizeof(identity_file));
92 	have_identity = 1;
93 }
94 
95 int
96 try_load_key(char *filename, Key *k)
97 {
98 	int success = 1;
99 	if (!load_private_key(filename, "", k, NULL)) {
100 		char *pass = read_passphrase("Enter passphrase: ", 1);
101 		if (!load_private_key(filename, pass, k, NULL)) {
102 			success = 0;
103 		}
104 		memset(pass, 0, strlen(pass));
105 		xfree(pass);
106 	}
107 	return success;
108 }
109 
110 #define SSH_COM_PUBLIC_BEGIN		"---- BEGIN SSH2 PUBLIC KEY ----"
111 #define SSH_COM_PUBLIC_END  		"---- END SSH2 PUBLIC KEY ----"
112 #define SSH_COM_PRIVATE_BEGIN		"---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----"
113 #define	SSH_COM_PRIVATE_KEY_MAGIC	0x3f6ff9eb
114 
115 void
116 do_convert_to_ssh2(struct passwd *pw)
117 {
118 	Key *k;
119 	int len;
120 	unsigned char *blob;
121 	struct stat st;
122 
123 	if (!have_identity)
124 		ask_filename(pw, "Enter file in which the key is");
125 	if (stat(identity_file, &st) < 0) {
126 		perror(identity_file);
127 		exit(1);
128 	}
129 	k = key_new(KEY_DSA);
130 	if (!try_load_key(identity_file, k)) {
131 		fprintf(stderr, "load failed\n");
132 		exit(1);
133 	}
134 	dsa_make_key_blob(k, &blob, &len);
135 	fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN);
136 	fprintf(stdout,
137 	    "Comment: \"%d-bit %s, converted from OpenSSH by %s@%s\"\n",
138 	    key_size(k), key_type(k),
139 	    pw->pw_name, hostname);
140 	dump_base64(stdout, blob, len);
141 	fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END);
142 	key_free(k);
143 	xfree(blob);
144 	exit(0);
145 }
146 
147 void
148 buffer_get_bignum_bits(Buffer *b, BIGNUM *value)
149 {
150 	int bits = buffer_get_int(b);
151 	int bytes = (bits + 7) / 8;
152 	if (buffer_len(b) < bytes)
153 		fatal("buffer_get_bignum_bits: input buffer too small");
154 	BN_bin2bn((unsigned char *)buffer_ptr(b), bytes, value);
155 	buffer_consume(b, bytes);
156 }
157 
158 Key *
159 do_convert_private_ssh2_from_blob(char *blob, int blen)
160 {
161 	Buffer b;
162 	DSA *dsa;
163 	Key *key = NULL;
164 	int ignore, magic, rlen;
165 	char *type, *cipher;
166 
167 	buffer_init(&b);
168 	buffer_append(&b, blob, blen);
169 
170 	magic  = buffer_get_int(&b);
171 	if (magic != SSH_COM_PRIVATE_KEY_MAGIC) {
172 		error("bad magic 0x%x != 0x%x", magic, SSH_COM_PRIVATE_KEY_MAGIC);
173 		buffer_free(&b);
174 		return NULL;
175 	}
176 	ignore = buffer_get_int(&b);
177 	type   = buffer_get_string(&b, NULL);
178 	cipher = buffer_get_string(&b, NULL);
179 	ignore = buffer_get_int(&b);
180 	ignore = buffer_get_int(&b);
181 	ignore = buffer_get_int(&b);
182 	xfree(type);
183 
184 	if (strcmp(cipher, "none") != 0) {
185 		error("unsupported cipher %s", cipher);
186 		xfree(cipher);
187 		buffer_free(&b);
188 		return NULL;
189 	}
190 	xfree(cipher);
191 
192 	key = key_new(KEY_DSA);
193 	dsa = key->dsa;
194 	dsa->priv_key = BN_new();
195 	if (dsa->priv_key == NULL) {
196 		error("alloc priv_key failed");
197 		key_free(key);
198 		return NULL;
199 	}
200 	buffer_get_bignum_bits(&b, dsa->p);
201 	buffer_get_bignum_bits(&b, dsa->g);
202 	buffer_get_bignum_bits(&b, dsa->q);
203 	buffer_get_bignum_bits(&b, dsa->pub_key);
204 	buffer_get_bignum_bits(&b, dsa->priv_key);
205 	rlen = buffer_len(&b);
206 	if(rlen != 0)
207 		error("do_convert_private_ssh2_from_blob: remaining bytes in key blob %d", rlen);
208 	buffer_free(&b);
209 	return key;
210 }
211 
212 void
213 do_convert_from_ssh2(struct passwd *pw)
214 {
215 	Key *k;
216 	int blen;
217 	char line[1024], *p;
218 	char blob[8096];
219 	char encoded[8096];
220 	struct stat st;
221 	int escaped = 0, private = 0, ok;
222 	FILE *fp;
223 
224 	if (!have_identity)
225 		ask_filename(pw, "Enter file in which the key is");
226 	if (stat(identity_file, &st) < 0) {
227 		perror(identity_file);
228 		exit(1);
229 	}
230 	fp = fopen(identity_file, "r");
231 	if (fp == NULL) {
232 		perror(identity_file);
233 		exit(1);
234 	}
235 	encoded[0] = '\0';
236 	while (fgets(line, sizeof(line), fp)) {
237 		if (!(p = strchr(line, '\n'))) {
238 			fprintf(stderr, "input line too long.\n");
239 			exit(1);
240 		}
241 		if (p > line && p[-1] == '\\')
242 			escaped++;
243 		if (strncmp(line, "----", 4) == 0 ||
244 		    strstr(line, ": ") != NULL) {
245 			if (strstr(line, SSH_COM_PRIVATE_BEGIN) != NULL)
246 				private = 1;
247 			fprintf(stderr, "ignore: %s", line);
248 			continue;
249 		}
250 		if (escaped) {
251 			escaped--;
252 			fprintf(stderr, "escaped: %s", line);
253 			continue;
254 		}
255 		*p = '\0';
256 		strlcat(encoded, line, sizeof(encoded));
257 	}
258 	blen = uudecode(encoded, (unsigned char *)blob, sizeof(blob));
259 	if (blen < 0) {
260 		fprintf(stderr, "uudecode failed.\n");
261 		exit(1);
262 	}
263 	k = private ?
264 	    do_convert_private_ssh2_from_blob(blob, blen) :
265 	    dsa_key_from_blob(blob, blen);
266 	if (k == NULL) {
267 		fprintf(stderr, "decode blob failed.\n");
268 		exit(1);
269 	}
270 	ok = private ?
271 	    PEM_write_DSAPrivateKey(stdout, k->dsa, NULL, NULL, 0, NULL, NULL) :
272 	    key_write(k, stdout);
273 	if (!ok) {
274 		fprintf(stderr, "key write failed");
275 		exit(1);
276 	}
277 	key_free(k);
278 	fprintf(stdout, "\n");
279 	fclose(fp);
280 	exit(0);
281 }
282 
283 void
284 do_print_public(struct passwd *pw)
285 {
286 	Key *k;
287 	int len;
288 	unsigned char *blob;
289 	struct stat st;
290 
291 	if (!have_identity)
292 		ask_filename(pw, "Enter file in which the key is");
293 	if (stat(identity_file, &st) < 0) {
294 		perror(identity_file);
295 		exit(1);
296 	}
297 	k = key_new(KEY_DSA);
298 	if (!try_load_key(identity_file, k)) {
299 		fprintf(stderr, "load failed\n");
300 		exit(1);
301 	}
302 	dsa_make_key_blob(k, &blob, &len);
303 	if (!key_write(k, stdout))
304 		fprintf(stderr, "key_write failed");
305 	key_free(k);
306 	xfree(blob);
307 	fprintf(stdout, "\n");
308 	exit(0);
309 }
310 
311 void
312 do_fingerprint(struct passwd *pw)
313 {
314 	/* XXX RSA1 only */
315 
316 	FILE *f;
317 	Key *public;
318 	char *comment = NULL, *cp, *ep, line[16*1024];
319 	int i, skip = 0, num = 1, invalid = 1;
320 	unsigned int ignore;
321 	struct stat st;
322 
323 	if (!have_identity)
324 		ask_filename(pw, "Enter file in which the key is");
325 	if (stat(identity_file, &st) < 0) {
326 		perror(identity_file);
327 		exit(1);
328 	}
329 	public = key_new(KEY_RSA);
330 	if (load_public_key(identity_file, public, &comment)) {
331 		printf("%d %s %s\n", BN_num_bits(public->rsa->n),
332 		    key_fingerprint(public), comment);
333 		key_free(public);
334 		exit(0);
335 	}
336 
337 	f = fopen(identity_file, "r");
338 	if (f != NULL) {
339 		while (fgets(line, sizeof(line), f)) {
340 			i = strlen(line) - 1;
341 			if (line[i] != '\n') {
342 				error("line %d too long: %.40s...", num, line);
343 				skip = 1;
344 				continue;
345 			}
346 			num++;
347 			if (skip) {
348 				skip = 0;
349 				continue;
350 			}
351 			line[i] = '\0';
352 
353 			/* Skip leading whitespace, empty and comment lines. */
354 			for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
355 				;
356 			if (!*cp || *cp == '\n' || *cp == '#')
357 				continue ;
358 			i = strtol(cp, &ep, 10);
359 			if (i == 0 || ep == NULL || (*ep != ' ' && *ep != '\t')) {
360 				int quoted = 0;
361 				comment = cp;
362 				for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
363 					if (*cp == '\\' && cp[1] == '"')
364 						cp++;	/* Skip both */
365 					else if (*cp == '"')
366 						quoted = !quoted;
367 				}
368 				if (!*cp)
369 					continue;
370 				*cp++ = '\0';
371 			}
372 			ep = cp;
373 			if (auth_rsa_read_key(&cp, &ignore, public->rsa->e, public->rsa->n)) {
374 				invalid = 0;
375 				comment = *cp ? cp : comment;
376 				printf("%d %s %s\n", key_size(public),
377 				    key_fingerprint(public),
378 				    comment ? comment : "no comment");
379 			}
380 		}
381 		fclose(f);
382 	}
383 	key_free(public);
384 	if (invalid) {
385 		printf("%s is not a valid key file.\n", identity_file);
386 		exit(1);
387 	}
388 	exit(0);
389 }
390 
391 /*
392  * Perform changing a passphrase.  The argument is the passwd structure
393  * for the current user.
394  */
395 void
396 do_change_passphrase(struct passwd *pw)
397 {
398 	char *comment;
399 	char *old_passphrase, *passphrase1, *passphrase2;
400 	struct stat st;
401 	Key *private;
402 	Key *public;
403 	int type = dsa_mode ? KEY_DSA : KEY_RSA;
404 
405 	if (!have_identity)
406 		ask_filename(pw, "Enter file in which the key is");
407 	if (stat(identity_file, &st) < 0) {
408 		perror(identity_file);
409 		exit(1);
410 	}
411 
412 	if (type == KEY_RSA) {
413 		/* XXX this works currently only for RSA */
414 		public = key_new(type);
415 		if (!load_public_key(identity_file, public, NULL)) {
416 			printf("%s is not a valid key file.\n", identity_file);
417 			exit(1);
418 		}
419 		/* Clear the public key since we are just about to load the whole file. */
420 		key_free(public);
421 	}
422 
423 	/* Try to load the file with empty passphrase. */
424 	private = key_new(type);
425 	if (!load_private_key(identity_file, "", private, &comment)) {
426 		if (identity_passphrase)
427 			old_passphrase = xstrdup(identity_passphrase);
428 		else
429 			old_passphrase = read_passphrase("Enter old passphrase: ", 1);
430 		if (!load_private_key(identity_file, old_passphrase, private, &comment)) {
431 			memset(old_passphrase, 0, strlen(old_passphrase));
432 			xfree(old_passphrase);
433 			printf("Bad passphrase.\n");
434 			exit(1);
435 		}
436 		memset(old_passphrase, 0, strlen(old_passphrase));
437 		xfree(old_passphrase);
438 	}
439 	printf("Key has comment '%s'\n", comment);
440 
441 	/* Ask the new passphrase (twice). */
442 	if (identity_new_passphrase) {
443 		passphrase1 = xstrdup(identity_new_passphrase);
444 		passphrase2 = NULL;
445 	} else {
446 		passphrase1 =
447 			read_passphrase("Enter new passphrase (empty for no passphrase): ", 1);
448 		passphrase2 = read_passphrase("Enter same passphrase again: ", 1);
449 
450 		/* Verify that they are the same. */
451 		if (strcmp(passphrase1, passphrase2) != 0) {
452 			memset(passphrase1, 0, strlen(passphrase1));
453 			memset(passphrase2, 0, strlen(passphrase2));
454 			xfree(passphrase1);
455 			xfree(passphrase2);
456 			printf("Pass phrases do not match.  Try again.\n");
457 			exit(1);
458 		}
459 		/* Destroy the other copy. */
460 		memset(passphrase2, 0, strlen(passphrase2));
461 		xfree(passphrase2);
462 	}
463 
464 	/* Save the file using the new passphrase. */
465 	if (!save_private_key(identity_file, passphrase1, private, comment)) {
466 		printf("Saving the key failed: %s: %s.\n",
467 		       identity_file, strerror(errno));
468 		memset(passphrase1, 0, strlen(passphrase1));
469 		xfree(passphrase1);
470 		key_free(private);
471 		xfree(comment);
472 		exit(1);
473 	}
474 	/* Destroy the passphrase and the copy of the key in memory. */
475 	memset(passphrase1, 0, strlen(passphrase1));
476 	xfree(passphrase1);
477 	key_free(private);		 /* Destroys contents */
478 	xfree(comment);
479 
480 	printf("Your identification has been saved with the new passphrase.\n");
481 	exit(0);
482 }
483 
484 /*
485  * Change the comment of a private key file.
486  */
487 void
488 do_change_comment(struct passwd *pw)
489 {
490 	char new_comment[1024], *comment;
491 	Key *private;
492 	Key *public;
493 	char *passphrase;
494 	struct stat st;
495 	FILE *f;
496 
497 	if (!have_identity)
498 		ask_filename(pw, "Enter file in which the key is");
499 	if (stat(identity_file, &st) < 0) {
500 		perror(identity_file);
501 		exit(1);
502 	}
503 	/*
504 	 * Try to load the public key from the file the verify that it is
505 	 * readable and of the proper format.
506 	 */
507 	public = key_new(KEY_RSA);
508 	if (!load_public_key(identity_file, public, NULL)) {
509 		printf("%s is not a valid key file.\n", identity_file);
510 		exit(1);
511 	}
512 
513 	private = key_new(KEY_RSA);
514 	if (load_private_key(identity_file, "", private, &comment))
515 		passphrase = xstrdup("");
516 	else {
517 		if (identity_passphrase)
518 			passphrase = xstrdup(identity_passphrase);
519 		else if (identity_new_passphrase)
520 			passphrase = xstrdup(identity_new_passphrase);
521 		else
522 			passphrase = read_passphrase("Enter passphrase: ", 1);
523 		/* Try to load using the passphrase. */
524 		if (!load_private_key(identity_file, passphrase, private, &comment)) {
525 			memset(passphrase, 0, strlen(passphrase));
526 			xfree(passphrase);
527 			printf("Bad passphrase.\n");
528 			exit(1);
529 		}
530 	}
531 	printf("Key now has comment '%s'\n", comment);
532 
533 	if (identity_comment) {
534 		strlcpy(new_comment, identity_comment, sizeof(new_comment));
535 	} else {
536 		printf("Enter new comment: ");
537 		fflush(stdout);
538 		if (!fgets(new_comment, sizeof(new_comment), stdin)) {
539 			memset(passphrase, 0, strlen(passphrase));
540 			key_free(private);
541 			exit(1);
542 		}
543 		if (strchr(new_comment, '\n'))
544 			*strchr(new_comment, '\n') = 0;
545 	}
546 
547 	/* Save the file using the new passphrase. */
548 	if (!save_private_key(identity_file, passphrase, private, new_comment)) {
549 		printf("Saving the key failed: %s: %s.\n",
550 		       identity_file, strerror(errno));
551 		memset(passphrase, 0, strlen(passphrase));
552 		xfree(passphrase);
553 		key_free(private);
554 		xfree(comment);
555 		exit(1);
556 	}
557 	memset(passphrase, 0, strlen(passphrase));
558 	xfree(passphrase);
559 	key_free(private);
560 
561 	strlcat(identity_file, ".pub", sizeof(identity_file));
562 	f = fopen(identity_file, "w");
563 	if (!f) {
564 		printf("Could not save your public key in %s\n", identity_file);
565 		exit(1);
566 	}
567 	if (!key_write(public, f))
568 		fprintf(stderr, "write key failed");
569 	key_free(public);
570 	fprintf(f, " %s\n", new_comment);
571 	fclose(f);
572 
573 	xfree(comment);
574 
575 	printf("The comment in your key file has been changed.\n");
576 	exit(0);
577 }
578 
579 void
580 usage(void)
581 {
582 	printf("Usage: %s [-lpqxXydc] [-b bits] [-f file] [-C comment] [-N new-pass] [-P pass]\n", __progname);
583 	exit(1);
584 }
585 
586 /*
587  * Main program for key management.
588  */
589 int
590 main(int ac, char **av)
591 {
592 	char dotsshdir[16 * 1024], comment[1024], *passphrase1, *passphrase2;
593 	struct passwd *pw;
594 	int opt;
595 	struct stat st;
596 	FILE *f;
597 	Key *private;
598 	Key *public;
599 	extern int optind;
600 	extern char *optarg;
601 
602 	SSLeay_add_all_algorithms();
603 
604 	/* we need this for the home * directory.  */
605 	pw = getpwuid(getuid());
606 	if (!pw) {
607 		printf("You don't exist, go away!\n");
608 		exit(1);
609 	}
610 	if (gethostname(hostname, sizeof(hostname)) < 0) {
611 		perror("gethostname");
612 		exit(1);
613 	}
614 
615 	while ((opt = getopt(ac, av, "dqpclRxXyb:f:P:N:C:")) != EOF) {
616 		switch (opt) {
617 		case 'b':
618 			bits = atoi(optarg);
619 			if (bits < 512 || bits > 32768) {
620 				printf("Bits has bad value.\n");
621 				exit(1);
622 			}
623 			break;
624 
625 		case 'l':
626 			print_fingerprint = 1;
627 			break;
628 
629 		case 'p':
630 			change_passphrase = 1;
631 			break;
632 
633 		case 'c':
634 			change_comment = 1;
635 			break;
636 
637 		case 'f':
638 			strlcpy(identity_file, optarg, sizeof(identity_file));
639 			have_identity = 1;
640 			break;
641 
642 		case 'P':
643 			identity_passphrase = optarg;
644 			break;
645 
646 		case 'N':
647 			identity_new_passphrase = optarg;
648 			break;
649 
650 		case 'C':
651 			identity_comment = optarg;
652 			break;
653 
654 		case 'q':
655 			quiet = 1;
656 			break;
657 
658 		case 'R':
659 			if (rsa_alive() == 0)
660 				exit(1);
661 			else
662 				exit(0);
663 			break;
664 
665 		case 'x':
666 			convert_to_ssh2 = 1;
667 			break;
668 
669 		case 'X':
670 			convert_from_ssh2 = 1;
671 			break;
672 
673 		case 'y':
674 			print_public = 1;
675 			break;
676 
677 		case 'd':
678 			dsa_mode = 1;
679 			break;
680 
681 		case '?':
682 		default:
683 			usage();
684 		}
685 	}
686 	if (optind < ac) {
687 		printf("Too many arguments.\n");
688 		usage();
689 	}
690 	if (change_passphrase && change_comment) {
691 		printf("Can only have one of -p and -c.\n");
692 		usage();
693 	}
694 	/* check if RSA support is needed and exists */
695 	if (dsa_mode == 0 && rsa_alive() == 0) {
696 		fprintf(stderr,
697 			"%s: no RSA support in libssl and libcrypto.  See ssl(8).\n",
698 			__progname);
699 		exit(1);
700 	}
701 	if (print_fingerprint)
702 		do_fingerprint(pw);
703 	if (change_passphrase)
704 		do_change_passphrase(pw);
705 	if (change_comment)
706 		do_change_comment(pw);
707 	if (convert_to_ssh2)
708 		do_convert_to_ssh2(pw);
709 	if (convert_from_ssh2)
710 		do_convert_from_ssh2(pw);
711 	if (print_public)
712 		do_print_public(pw);
713 
714 	arc4random_stir();
715 
716 	if (dsa_mode != 0) {
717 		if (!quiet)
718 			printf("Generating DSA parameter and key.\n");
719 		public = private = dsa_generate_key(bits);
720 		if (private == NULL) {
721 			fprintf(stderr, "dsa_generate_keys failed");
722 			exit(1);
723 		}
724 	} else {
725 		if (quiet)
726 			rsa_set_verbose(0);
727 		/* Generate the rsa key pair. */
728 		public = key_new(KEY_RSA);
729 		private = key_new(KEY_RSA);
730 		rsa_generate_key(private->rsa, public->rsa, bits);
731 	}
732 
733 	if (!have_identity)
734 		ask_filename(pw, "Enter file in which to save the key");
735 
736 	/* Create ~/.ssh directory if it doesn\'t already exist. */
737 	snprintf(dotsshdir, sizeof dotsshdir, "%s/%s", pw->pw_dir, SSH_USER_DIR);
738 	if (strstr(identity_file, dotsshdir) != NULL &&
739 	    stat(dotsshdir, &st) < 0) {
740 		if (mkdir(dotsshdir, 0700) < 0)
741 			error("Could not create directory '%s'.", dotsshdir);
742 		else if (!quiet)
743 			printf("Created directory '%s'.\n", dotsshdir);
744 	}
745 	/* If the file already exists, ask the user to confirm. */
746 	if (stat(identity_file, &st) >= 0) {
747 		char yesno[3];
748 		printf("%s already exists.\n", identity_file);
749 		printf("Overwrite (y/n)? ");
750 		fflush(stdout);
751 		if (fgets(yesno, sizeof(yesno), stdin) == NULL)
752 			exit(1);
753 		if (yesno[0] != 'y' && yesno[0] != 'Y')
754 			exit(1);
755 	}
756 	/* Ask for a passphrase (twice). */
757 	if (identity_passphrase)
758 		passphrase1 = xstrdup(identity_passphrase);
759 	else if (identity_new_passphrase)
760 		passphrase1 = xstrdup(identity_new_passphrase);
761 	else {
762 passphrase_again:
763 		passphrase1 =
764 			read_passphrase("Enter passphrase (empty for no passphrase): ", 1);
765 		passphrase2 = read_passphrase("Enter same passphrase again: ", 1);
766 		if (strcmp(passphrase1, passphrase2) != 0) {
767 			/* The passphrases do not match.  Clear them and retry. */
768 			memset(passphrase1, 0, strlen(passphrase1));
769 			memset(passphrase2, 0, strlen(passphrase2));
770 			xfree(passphrase1);
771 			xfree(passphrase2);
772 			printf("Passphrases do not match.  Try again.\n");
773 			goto passphrase_again;
774 		}
775 		/* Clear the other copy of the passphrase. */
776 		memset(passphrase2, 0, strlen(passphrase2));
777 		xfree(passphrase2);
778 	}
779 
780 	if (identity_comment) {
781 		strlcpy(comment, identity_comment, sizeof(comment));
782 	} else {
783 		/* Create default commend field for the passphrase. */
784 		snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname);
785 	}
786 
787 	/* Save the key with the given passphrase and comment. */
788 	if (!save_private_key(identity_file, passphrase1, private, comment)) {
789 		printf("Saving the key failed: %s: %s.\n",
790 		    identity_file, strerror(errno));
791 		memset(passphrase1, 0, strlen(passphrase1));
792 		xfree(passphrase1);
793 		exit(1);
794 	}
795 	/* Clear the passphrase. */
796 	memset(passphrase1, 0, strlen(passphrase1));
797 	xfree(passphrase1);
798 
799 	/* Clear the private key and the random number generator. */
800 	if (private != public) {
801 		key_free(private);
802 	}
803 	arc4random_stir();
804 
805 	if (!quiet)
806 		printf("Your identification has been saved in %s.\n", identity_file);
807 
808 	strlcat(identity_file, ".pub", sizeof(identity_file));
809 	f = fopen(identity_file, "w");
810 	if (!f) {
811 		printf("Could not save your public key in %s\n", identity_file);
812 		exit(1);
813 	}
814 	if (!key_write(public, f))
815 		fprintf(stderr, "write key failed");
816 	fprintf(f, " %s\n", comment);
817 	fclose(f);
818 
819 	if (!quiet) {
820 		printf("Your public key has been saved in %s.\n",
821 		    identity_file);
822 		printf("The key fingerprint is:\n");
823 		printf("%s %s\n", key_fingerprint(public), comment);
824 	}
825 
826 	key_free(public);
827 	exit(0);
828 }
829