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