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