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