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