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