]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - crypto/openssh/ssh-keygen.c
Merge llvm-project release/17.x llvmorg-17.0.3-0-g888437e1b600
[FreeBSD/FreeBSD.git] / crypto / openssh / ssh-keygen.c
1 /* $OpenBSD: ssh-keygen.c,v 1.471 2023/09/04 10:29:58 job 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 #ifdef HAVE_STDINT_H
28 # include <stdint.h>
29 #endif
30 #include <errno.h>
31 #include <fcntl.h>
32 #include <netdb.h>
33 #ifdef HAVE_PATHS_H
34 # include <paths.h>
35 #endif
36 #include <pwd.h>
37 #include <stdarg.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <unistd.h>
42 #include <limits.h>
43 #include <locale.h>
44 #include <time.h>
45
46 #include "xmalloc.h"
47 #include "sshkey.h"
48 #include "authfile.h"
49 #include "sshbuf.h"
50 #include "pathnames.h"
51 #include "log.h"
52 #include "misc.h"
53 #include "match.h"
54 #include "hostfile.h"
55 #include "dns.h"
56 #include "ssh.h"
57 #include "ssh2.h"
58 #include "ssherr.h"
59 #include "ssh-pkcs11.h"
60 #include "atomicio.h"
61 #include "krl.h"
62 #include "digest.h"
63 #include "utf8.h"
64 #include "authfd.h"
65 #include "sshsig.h"
66 #include "ssh-sk.h"
67 #include "sk-api.h" /* XXX for SSH_SK_USER_PRESENCE_REQD; remove */
68 #include "cipher.h"
69
70 #define DEFAULT_KEY_TYPE_NAME "ed25519"
71
72 /*
73  * Default number of bits in the RSA, DSA and ECDSA keys.  These value can be
74  * overridden on the command line.
75  *
76  * These values, with the exception of DSA, provide security equivalent to at
77  * least 128 bits of security according to NIST Special Publication 800-57:
78  * Recommendation for Key Management Part 1 rev 4 section 5.6.1.
79  * For DSA it (and FIPS-186-4 section 4.2) specifies that the only size for
80  * which a 160bit hash is acceptable is 1kbit, and since ssh-dss specifies only
81  * SHA1 we limit the DSA key size 1k bits.
82  */
83 #define DEFAULT_BITS            3072
84 #define DEFAULT_BITS_DSA        1024
85 #define DEFAULT_BITS_ECDSA      256
86
87 static int quiet = 0;
88
89 /* Flag indicating that we just want to see the key fingerprint */
90 static int print_fingerprint = 0;
91 static int print_bubblebabble = 0;
92
93 /* Hash algorithm to use for fingerprints. */
94 static int fingerprint_hash = SSH_FP_HASH_DEFAULT;
95
96 /* The identity file name, given on the command line or entered by the user. */
97 static char identity_file[PATH_MAX];
98 static int have_identity = 0;
99
100 /* This is set to the passphrase if given on the command line. */
101 static char *identity_passphrase = NULL;
102
103 /* This is set to the new passphrase if given on the command line. */
104 static char *identity_new_passphrase = NULL;
105
106 /* Key type when certifying */
107 static u_int cert_key_type = SSH2_CERT_TYPE_USER;
108
109 /* "key ID" of signed key */
110 static char *cert_key_id = NULL;
111
112 /* Comma-separated list of principal names for certifying keys */
113 static char *cert_principals = NULL;
114
115 /* Validity period for certificates */
116 static u_int64_t cert_valid_from = 0;
117 static u_int64_t cert_valid_to = ~0ULL;
118
119 /* Certificate options */
120 #define CERTOPT_X_FWD                           (1)
121 #define CERTOPT_AGENT_FWD                       (1<<1)
122 #define CERTOPT_PORT_FWD                        (1<<2)
123 #define CERTOPT_PTY                             (1<<3)
124 #define CERTOPT_USER_RC                         (1<<4)
125 #define CERTOPT_NO_REQUIRE_USER_PRESENCE        (1<<5)
126 #define CERTOPT_REQUIRE_VERIFY                  (1<<6)
127 #define CERTOPT_DEFAULT (CERTOPT_X_FWD|CERTOPT_AGENT_FWD| \
128                          CERTOPT_PORT_FWD|CERTOPT_PTY|CERTOPT_USER_RC)
129 static u_int32_t certflags_flags = CERTOPT_DEFAULT;
130 static char *certflags_command = NULL;
131 static char *certflags_src_addr = NULL;
132
133 /* Arbitrary extensions specified by user */
134 struct cert_ext {
135         char *key;
136         char *val;
137         int crit;
138 };
139 static struct cert_ext *cert_ext;
140 static size_t ncert_ext;
141
142 /* Conversion to/from various formats */
143 enum {
144         FMT_RFC4716,
145         FMT_PKCS8,
146         FMT_PEM
147 } convert_format = FMT_RFC4716;
148
149 static char *key_type_name = NULL;
150
151 /* Load key from this PKCS#11 provider */
152 static char *pkcs11provider = NULL;
153
154 /* FIDO/U2F provider to use */
155 static char *sk_provider = NULL;
156
157 /* Format for writing private keys */
158 static int private_key_format = SSHKEY_PRIVATE_OPENSSH;
159
160 /* Cipher for new-format private keys */
161 static char *openssh_format_cipher = NULL;
162
163 /* Number of KDF rounds to derive new format keys. */
164 static int rounds = 0;
165
166 /* argv0 */
167 extern char *__progname;
168
169 static char hostname[NI_MAXHOST];
170
171 #ifdef WITH_OPENSSL
172 /* moduli.c */
173 int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *);
174 int prime_test(FILE *, FILE *, u_int32_t, u_int32_t, char *, unsigned long,
175     unsigned long);
176 #endif
177
178 static void
179 type_bits_valid(int type, const char *name, u_int32_t *bitsp)
180 {
181         if (type == KEY_UNSPEC)
182                 fatal("unknown key type %s", key_type_name);
183         if (*bitsp == 0) {
184 #ifdef WITH_OPENSSL
185                 int nid;
186
187                 switch(type) {
188                 case KEY_DSA:
189                         *bitsp = DEFAULT_BITS_DSA;
190                         break;
191                 case KEY_ECDSA:
192                         if (name != NULL &&
193                             (nid = sshkey_ecdsa_nid_from_name(name)) > 0)
194                                 *bitsp = sshkey_curve_nid_to_bits(nid);
195                         if (*bitsp == 0)
196                                 *bitsp = DEFAULT_BITS_ECDSA;
197                         break;
198                 case KEY_RSA:
199                         *bitsp = DEFAULT_BITS;
200                         break;
201                 }
202 #endif
203         }
204 #ifdef WITH_OPENSSL
205         switch (type) {
206         case KEY_DSA:
207                 if (*bitsp != 1024)
208                         fatal("Invalid DSA key length: must be 1024 bits");
209                 break;
210         case KEY_RSA:
211                 if (*bitsp < SSH_RSA_MINIMUM_MODULUS_SIZE)
212                         fatal("Invalid RSA key length: minimum is %d bits",
213                             SSH_RSA_MINIMUM_MODULUS_SIZE);
214                 else if (*bitsp > OPENSSL_RSA_MAX_MODULUS_BITS)
215                         fatal("Invalid RSA key length: maximum is %d bits",
216                             OPENSSL_RSA_MAX_MODULUS_BITS);
217                 break;
218         case KEY_ECDSA:
219                 if (sshkey_ecdsa_bits_to_nid(*bitsp) == -1)
220 #ifdef OPENSSL_HAS_NISTP521
221                         fatal("Invalid ECDSA key length: valid lengths are "
222                             "256, 384 or 521 bits");
223 #else
224                         fatal("Invalid ECDSA key length: valid lengths are "
225                             "256 or 384 bits");
226 #endif
227         }
228 #endif
229 }
230
231 /*
232  * Checks whether a file exists and, if so, asks the user whether they wish
233  * to overwrite it.
234  * Returns nonzero if the file does not already exist or if the user agrees to
235  * overwrite, or zero otherwise.
236  */
237 static int
238 confirm_overwrite(const char *filename)
239 {
240         char yesno[3];
241         struct stat st;
242
243         if (stat(filename, &st) != 0)
244                 return 1;
245         printf("%s already exists.\n", filename);
246         printf("Overwrite (y/n)? ");
247         fflush(stdout);
248         if (fgets(yesno, sizeof(yesno), stdin) == NULL)
249                 return 0;
250         if (yesno[0] != 'y' && yesno[0] != 'Y')
251                 return 0;
252         return 1;
253 }
254
255 static void
256 ask_filename(struct passwd *pw, const char *prompt)
257 {
258         char buf[1024];
259         char *name = NULL;
260
261         if (key_type_name == NULL)
262                 name = _PATH_SSH_CLIENT_ID_ED25519;
263         else {
264                 switch (sshkey_type_from_name(key_type_name)) {
265                 case KEY_DSA_CERT:
266                 case KEY_DSA:
267                         name = _PATH_SSH_CLIENT_ID_DSA;
268                         break;
269 #ifdef OPENSSL_HAS_ECC
270                 case KEY_ECDSA_CERT:
271                 case KEY_ECDSA:
272                         name = _PATH_SSH_CLIENT_ID_ECDSA;
273                         break;
274                 case KEY_ECDSA_SK_CERT:
275                 case KEY_ECDSA_SK:
276                         name = _PATH_SSH_CLIENT_ID_ECDSA_SK;
277                         break;
278 #endif
279                 case KEY_RSA_CERT:
280                 case KEY_RSA:
281                         name = _PATH_SSH_CLIENT_ID_RSA;
282                         break;
283                 case KEY_ED25519:
284                 case KEY_ED25519_CERT:
285                         name = _PATH_SSH_CLIENT_ID_ED25519;
286                         break;
287                 case KEY_ED25519_SK:
288                 case KEY_ED25519_SK_CERT:
289                         name = _PATH_SSH_CLIENT_ID_ED25519_SK;
290                         break;
291                 case KEY_XMSS:
292                 case KEY_XMSS_CERT:
293                         name = _PATH_SSH_CLIENT_ID_XMSS;
294                         break;
295                 default:
296                         fatal("bad key type");
297                 }
298         }
299         snprintf(identity_file, sizeof(identity_file),
300             "%s/%s", pw->pw_dir, name);
301         printf("%s (%s): ", prompt, identity_file);
302         fflush(stdout);
303         if (fgets(buf, sizeof(buf), stdin) == NULL)
304                 exit(1);
305         buf[strcspn(buf, "\n")] = '\0';
306         if (strcmp(buf, "") != 0)
307                 strlcpy(identity_file, buf, sizeof(identity_file));
308         have_identity = 1;
309 }
310
311 static struct sshkey *
312 load_identity(const char *filename, char **commentp)
313 {
314         char *pass;
315         struct sshkey *prv;
316         int r;
317
318         if (commentp != NULL)
319                 *commentp = NULL;
320         if ((r = sshkey_load_private(filename, "", &prv, commentp)) == 0)
321                 return prv;
322         if (r != SSH_ERR_KEY_WRONG_PASSPHRASE)
323                 fatal_r(r, "Load key \"%s\"", filename);
324         if (identity_passphrase)
325                 pass = xstrdup(identity_passphrase);
326         else
327                 pass = read_passphrase("Enter passphrase: ", RP_ALLOW_STDIN);
328         r = sshkey_load_private(filename, pass, &prv, commentp);
329         freezero(pass, strlen(pass));
330         if (r != 0)
331                 fatal_r(r, "Load key \"%s\"", filename);
332         return prv;
333 }
334
335 #define SSH_COM_PUBLIC_BEGIN            "---- BEGIN SSH2 PUBLIC KEY ----"
336 #define SSH_COM_PUBLIC_END              "---- END SSH2 PUBLIC KEY ----"
337 #define SSH_COM_PRIVATE_BEGIN           "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----"
338 #define SSH_COM_PRIVATE_KEY_MAGIC       0x3f6ff9eb
339
340 #ifdef WITH_OPENSSL
341 static void
342 do_convert_to_ssh2(struct passwd *pw, struct sshkey *k)
343 {
344         struct sshbuf *b;
345         char comment[61], *b64;
346         int r;
347
348         if ((b = sshbuf_new()) == NULL)
349                 fatal_f("sshbuf_new failed");
350         if ((r = sshkey_putb(k, b)) != 0)
351                 fatal_fr(r, "put key");
352         if ((b64 = sshbuf_dtob64_string(b, 1)) == NULL)
353                 fatal_f("sshbuf_dtob64_string failed");
354
355         /* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */
356         snprintf(comment, sizeof(comment),
357             "%u-bit %s, converted by %s@%s from OpenSSH",
358             sshkey_size(k), sshkey_type(k),
359             pw->pw_name, hostname);
360
361         sshkey_free(k);
362         sshbuf_free(b);
363
364         fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN);
365         fprintf(stdout, "Comment: \"%s\"\n%s", comment, b64);
366         fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END);
367         free(b64);
368         exit(0);
369 }
370
371 static void
372 do_convert_to_pkcs8(struct sshkey *k)
373 {
374         switch (sshkey_type_plain(k->type)) {
375         case KEY_RSA:
376                 if (!PEM_write_RSA_PUBKEY(stdout, k->rsa))
377                         fatal("PEM_write_RSA_PUBKEY failed");
378                 break;
379         case KEY_DSA:
380                 if (!PEM_write_DSA_PUBKEY(stdout, k->dsa))
381                         fatal("PEM_write_DSA_PUBKEY failed");
382                 break;
383 #ifdef OPENSSL_HAS_ECC
384         case KEY_ECDSA:
385                 if (!PEM_write_EC_PUBKEY(stdout, k->ecdsa))
386                         fatal("PEM_write_EC_PUBKEY failed");
387                 break;
388 #endif
389         default:
390                 fatal_f("unsupported key type %s", sshkey_type(k));
391         }
392         exit(0);
393 }
394
395 static void
396 do_convert_to_pem(struct sshkey *k)
397 {
398         switch (sshkey_type_plain(k->type)) {
399         case KEY_RSA:
400                 if (!PEM_write_RSAPublicKey(stdout, k->rsa))
401                         fatal("PEM_write_RSAPublicKey failed");
402                 break;
403         case KEY_DSA:
404                 if (!PEM_write_DSA_PUBKEY(stdout, k->dsa))
405                         fatal("PEM_write_DSA_PUBKEY failed");
406                 break;
407 #ifdef OPENSSL_HAS_ECC
408         case KEY_ECDSA:
409                 if (!PEM_write_EC_PUBKEY(stdout, k->ecdsa))
410                         fatal("PEM_write_EC_PUBKEY failed");
411                 break;
412 #endif
413         default:
414                 fatal_f("unsupported key type %s", sshkey_type(k));
415         }
416         exit(0);
417 }
418
419 static void
420 do_convert_to(struct passwd *pw)
421 {
422         struct sshkey *k;
423         struct stat st;
424         int r;
425
426         if (!have_identity)
427                 ask_filename(pw, "Enter file in which the key is");
428         if (stat(identity_file, &st) == -1)
429                 fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
430         if ((r = sshkey_load_public(identity_file, &k, NULL)) != 0)
431                 k = load_identity(identity_file, NULL);
432         switch (convert_format) {
433         case FMT_RFC4716:
434                 do_convert_to_ssh2(pw, k);
435                 break;
436         case FMT_PKCS8:
437                 do_convert_to_pkcs8(k);
438                 break;
439         case FMT_PEM:
440                 do_convert_to_pem(k);
441                 break;
442         default:
443                 fatal_f("unknown key format %d", convert_format);
444         }
445         exit(0);
446 }
447
448 /*
449  * This is almost exactly the bignum1 encoding, but with 32 bit for length
450  * instead of 16.
451  */
452 static void
453 buffer_get_bignum_bits(struct sshbuf *b, BIGNUM *value)
454 {
455         u_int bytes, bignum_bits;
456         int r;
457
458         if ((r = sshbuf_get_u32(b, &bignum_bits)) != 0)
459                 fatal_fr(r, "parse");
460         bytes = (bignum_bits + 7) / 8;
461         if (sshbuf_len(b) < bytes)
462                 fatal_f("input buffer too small: need %d have %zu",
463                     bytes, sshbuf_len(b));
464         if (BN_bin2bn(sshbuf_ptr(b), bytes, value) == NULL)
465                 fatal_f("BN_bin2bn failed");
466         if ((r = sshbuf_consume(b, bytes)) != 0)
467                 fatal_fr(r, "consume");
468 }
469
470 static struct sshkey *
471 do_convert_private_ssh2(struct sshbuf *b)
472 {
473         struct sshkey *key = NULL;
474         char *type, *cipher;
475         const char *alg = NULL;
476         u_char e1, e2, e3, *sig = NULL, data[] = "abcde12345";
477         int r, rlen, ktype;
478         u_int magic, i1, i2, i3, i4;
479         size_t slen;
480         u_long e;
481         BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL;
482         BIGNUM *dsa_pub_key = NULL, *dsa_priv_key = NULL;
483         BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL;
484         BIGNUM *rsa_p = NULL, *rsa_q = NULL, *rsa_iqmp = NULL;
485
486         if ((r = sshbuf_get_u32(b, &magic)) != 0)
487                 fatal_fr(r, "parse magic");
488
489         if (magic != SSH_COM_PRIVATE_KEY_MAGIC) {
490                 error("bad magic 0x%x != 0x%x", magic,
491                     SSH_COM_PRIVATE_KEY_MAGIC);
492                 return NULL;
493         }
494         if ((r = sshbuf_get_u32(b, &i1)) != 0 ||
495             (r = sshbuf_get_cstring(b, &type, NULL)) != 0 ||
496             (r = sshbuf_get_cstring(b, &cipher, NULL)) != 0 ||
497             (r = sshbuf_get_u32(b, &i2)) != 0 ||
498             (r = sshbuf_get_u32(b, &i3)) != 0 ||
499             (r = sshbuf_get_u32(b, &i4)) != 0)
500                 fatal_fr(r, "parse");
501         debug("ignore (%d %d %d %d)", i1, i2, i3, i4);
502         if (strcmp(cipher, "none") != 0) {
503                 error("unsupported cipher %s", cipher);
504                 free(cipher);
505                 free(type);
506                 return NULL;
507         }
508         free(cipher);
509
510         if (strstr(type, "dsa")) {
511                 ktype = KEY_DSA;
512         } else if (strstr(type, "rsa")) {
513                 ktype = KEY_RSA;
514         } else {
515                 free(type);
516                 return NULL;
517         }
518         if ((key = sshkey_new(ktype)) == NULL)
519                 fatal("sshkey_new failed");
520         free(type);
521
522         switch (key->type) {
523         case KEY_DSA:
524                 if ((dsa_p = BN_new()) == NULL ||
525                     (dsa_q = BN_new()) == NULL ||
526                     (dsa_g = BN_new()) == NULL ||
527                     (dsa_pub_key = BN_new()) == NULL ||
528                     (dsa_priv_key = BN_new()) == NULL)
529                         fatal_f("BN_new");
530                 buffer_get_bignum_bits(b, dsa_p);
531                 buffer_get_bignum_bits(b, dsa_g);
532                 buffer_get_bignum_bits(b, dsa_q);
533                 buffer_get_bignum_bits(b, dsa_pub_key);
534                 buffer_get_bignum_bits(b, dsa_priv_key);
535                 if (!DSA_set0_pqg(key->dsa, dsa_p, dsa_q, dsa_g))
536                         fatal_f("DSA_set0_pqg failed");
537                 dsa_p = dsa_q = dsa_g = NULL; /* transferred */
538                 if (!DSA_set0_key(key->dsa, dsa_pub_key, dsa_priv_key))
539                         fatal_f("DSA_set0_key failed");
540                 dsa_pub_key = dsa_priv_key = NULL; /* transferred */
541                 break;
542         case KEY_RSA:
543                 if ((r = sshbuf_get_u8(b, &e1)) != 0 ||
544                     (e1 < 30 && (r = sshbuf_get_u8(b, &e2)) != 0) ||
545                     (e1 < 30 && (r = sshbuf_get_u8(b, &e3)) != 0))
546                         fatal_fr(r, "parse RSA");
547                 e = e1;
548                 debug("e %lx", e);
549                 if (e < 30) {
550                         e <<= 8;
551                         e += e2;
552                         debug("e %lx", e);
553                         e <<= 8;
554                         e += e3;
555                         debug("e %lx", e);
556                 }
557                 if ((rsa_e = BN_new()) == NULL)
558                         fatal_f("BN_new");
559                 if (!BN_set_word(rsa_e, e)) {
560                         BN_clear_free(rsa_e);
561                         sshkey_free(key);
562                         return NULL;
563                 }
564                 if ((rsa_n = BN_new()) == NULL ||
565                     (rsa_d = BN_new()) == NULL ||
566                     (rsa_p = BN_new()) == NULL ||
567                     (rsa_q = BN_new()) == NULL ||
568                     (rsa_iqmp = BN_new()) == NULL)
569                         fatal_f("BN_new");
570                 buffer_get_bignum_bits(b, rsa_d);
571                 buffer_get_bignum_bits(b, rsa_n);
572                 buffer_get_bignum_bits(b, rsa_iqmp);
573                 buffer_get_bignum_bits(b, rsa_q);
574                 buffer_get_bignum_bits(b, rsa_p);
575                 if (!RSA_set0_key(key->rsa, rsa_n, rsa_e, rsa_d))
576                         fatal_f("RSA_set0_key failed");
577                 rsa_n = rsa_e = rsa_d = NULL; /* transferred */
578                 if (!RSA_set0_factors(key->rsa, rsa_p, rsa_q))
579                         fatal_f("RSA_set0_factors failed");
580                 rsa_p = rsa_q = NULL; /* transferred */
581                 if ((r = ssh_rsa_complete_crt_parameters(key, rsa_iqmp)) != 0)
582                         fatal_fr(r, "generate RSA parameters");
583                 BN_clear_free(rsa_iqmp);
584                 alg = "rsa-sha2-256";
585                 break;
586         }
587         rlen = sshbuf_len(b);
588         if (rlen != 0)
589                 error_f("remaining bytes in key blob %d", rlen);
590
591         /* try the key */
592         if ((r = sshkey_sign(key, &sig, &slen, data, sizeof(data),
593             alg, NULL, NULL, 0)) != 0)
594                 error_fr(r, "signing with converted key failed");
595         else if ((r = sshkey_verify(key, sig, slen, data, sizeof(data),
596             alg, 0, NULL)) != 0)
597                 error_fr(r, "verification with converted key failed");
598         if (r != 0) {
599                 sshkey_free(key);
600                 free(sig);
601                 return NULL;
602         }
603         free(sig);
604         return key;
605 }
606
607 static int
608 get_line(FILE *fp, char *line, size_t len)
609 {
610         int c;
611         size_t pos = 0;
612
613         line[0] = '\0';
614         while ((c = fgetc(fp)) != EOF) {
615                 if (pos >= len - 1)
616                         fatal("input line too long.");
617                 switch (c) {
618                 case '\r':
619                         c = fgetc(fp);
620                         if (c != EOF && c != '\n' && ungetc(c, fp) == EOF)
621                                 fatal("unget: %s", strerror(errno));
622                         return pos;
623                 case '\n':
624                         return pos;
625                 }
626                 line[pos++] = c;
627                 line[pos] = '\0';
628         }
629         /* We reached EOF */
630         return -1;
631 }
632
633 static void
634 do_convert_from_ssh2(struct passwd *pw, struct sshkey **k, int *private)
635 {
636         int r, blen, escaped = 0;
637         u_int len;
638         char line[1024];
639         struct sshbuf *buf;
640         char encoded[8096];
641         FILE *fp;
642
643         if ((buf = sshbuf_new()) == NULL)
644                 fatal("sshbuf_new failed");
645         if ((fp = fopen(identity_file, "r")) == NULL)
646                 fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
647         encoded[0] = '\0';
648         while ((blen = get_line(fp, line, sizeof(line))) != -1) {
649                 if (blen > 0 && line[blen - 1] == '\\')
650                         escaped++;
651                 if (strncmp(line, "----", 4) == 0 ||
652                     strstr(line, ": ") != NULL) {
653                         if (strstr(line, SSH_COM_PRIVATE_BEGIN) != NULL)
654                                 *private = 1;
655                         if (strstr(line, " END ") != NULL) {
656                                 break;
657                         }
658                         /* fprintf(stderr, "ignore: %s", line); */
659                         continue;
660                 }
661                 if (escaped) {
662                         escaped--;
663                         /* fprintf(stderr, "escaped: %s", line); */
664                         continue;
665                 }
666                 strlcat(encoded, line, sizeof(encoded));
667         }
668         len = strlen(encoded);
669         if (((len % 4) == 3) &&
670             (encoded[len-1] == '=') &&
671             (encoded[len-2] == '=') &&
672             (encoded[len-3] == '='))
673                 encoded[len-3] = '\0';
674         if ((r = sshbuf_b64tod(buf, encoded)) != 0)
675                 fatal_fr(r, "base64 decode");
676         if (*private) {
677                 if ((*k = do_convert_private_ssh2(buf)) == NULL)
678                         fatal_f("private key conversion failed");
679         } else if ((r = sshkey_fromb(buf, k)) != 0)
680                 fatal_fr(r, "parse key");
681         sshbuf_free(buf);
682         fclose(fp);
683 }
684
685 static void
686 do_convert_from_pkcs8(struct sshkey **k, int *private)
687 {
688         EVP_PKEY *pubkey;
689         FILE *fp;
690
691         if ((fp = fopen(identity_file, "r")) == NULL)
692                 fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
693         if ((pubkey = PEM_read_PUBKEY(fp, NULL, NULL, NULL)) == NULL) {
694                 fatal_f("%s is not a recognised public key format",
695                     identity_file);
696         }
697         fclose(fp);
698         switch (EVP_PKEY_base_id(pubkey)) {
699         case EVP_PKEY_RSA:
700                 if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)
701                         fatal("sshkey_new failed");
702                 (*k)->type = KEY_RSA;
703                 (*k)->rsa = EVP_PKEY_get1_RSA(pubkey);
704                 break;
705         case EVP_PKEY_DSA:
706                 if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)
707                         fatal("sshkey_new failed");
708                 (*k)->type = KEY_DSA;
709                 (*k)->dsa = EVP_PKEY_get1_DSA(pubkey);
710                 break;
711 #ifdef OPENSSL_HAS_ECC
712         case EVP_PKEY_EC:
713                 if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)
714                         fatal("sshkey_new failed");
715                 (*k)->type = KEY_ECDSA;
716                 (*k)->ecdsa = EVP_PKEY_get1_EC_KEY(pubkey);
717                 (*k)->ecdsa_nid = sshkey_ecdsa_key_to_nid((*k)->ecdsa);
718                 break;
719 #endif
720         default:
721                 fatal_f("unsupported pubkey type %d",
722                     EVP_PKEY_base_id(pubkey));
723         }
724         EVP_PKEY_free(pubkey);
725         return;
726 }
727
728 static void
729 do_convert_from_pem(struct sshkey **k, int *private)
730 {
731         FILE *fp;
732         RSA *rsa;
733
734         if ((fp = fopen(identity_file, "r")) == NULL)
735                 fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
736         if ((rsa = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL)) != NULL) {
737                 if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)
738                         fatal("sshkey_new failed");
739                 (*k)->type = KEY_RSA;
740                 (*k)->rsa = rsa;
741                 fclose(fp);
742                 return;
743         }
744         fatal_f("unrecognised raw private key format");
745 }
746
747 static void
748 do_convert_from(struct passwd *pw)
749 {
750         struct sshkey *k = NULL;
751         int r, private = 0, ok = 0;
752         struct stat st;
753
754         if (!have_identity)
755                 ask_filename(pw, "Enter file in which the key is");
756         if (stat(identity_file, &st) == -1)
757                 fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
758
759         switch (convert_format) {
760         case FMT_RFC4716:
761                 do_convert_from_ssh2(pw, &k, &private);
762                 break;
763         case FMT_PKCS8:
764                 do_convert_from_pkcs8(&k, &private);
765                 break;
766         case FMT_PEM:
767                 do_convert_from_pem(&k, &private);
768                 break;
769         default:
770                 fatal_f("unknown key format %d", convert_format);
771         }
772
773         if (!private) {
774                 if ((r = sshkey_write(k, stdout)) == 0)
775                         ok = 1;
776                 if (ok)
777                         fprintf(stdout, "\n");
778         } else {
779                 switch (k->type) {
780                 case KEY_DSA:
781                         ok = PEM_write_DSAPrivateKey(stdout, k->dsa, NULL,
782                             NULL, 0, NULL, NULL);
783                         break;
784 #ifdef OPENSSL_HAS_ECC
785                 case KEY_ECDSA:
786                         ok = PEM_write_ECPrivateKey(stdout, k->ecdsa, NULL,
787                             NULL, 0, NULL, NULL);
788                         break;
789 #endif
790                 case KEY_RSA:
791                         ok = PEM_write_RSAPrivateKey(stdout, k->rsa, NULL,
792                             NULL, 0, NULL, NULL);
793                         break;
794                 default:
795                         fatal_f("unsupported key type %s", sshkey_type(k));
796                 }
797         }
798
799         if (!ok)
800                 fatal("key write failed");
801         sshkey_free(k);
802         exit(0);
803 }
804 #endif
805
806 static void
807 do_print_public(struct passwd *pw)
808 {
809         struct sshkey *prv;
810         struct stat st;
811         int r;
812         char *comment = NULL;
813
814         if (!have_identity)
815                 ask_filename(pw, "Enter file in which the key is");
816         if (stat(identity_file, &st) == -1)
817                 fatal("%s: %s", identity_file, strerror(errno));
818         prv = load_identity(identity_file, &comment);
819         if ((r = sshkey_write(prv, stdout)) != 0)
820                 fatal_fr(r, "write key");
821         if (comment != NULL && *comment != '\0')
822                 fprintf(stdout, " %s", comment);
823         fprintf(stdout, "\n");
824         if (sshkey_is_sk(prv)) {
825                 debug("sk_application: \"%s\", sk_flags 0x%02x",
826                         prv->sk_application, prv->sk_flags);
827         }
828         sshkey_free(prv);
829         free(comment);
830         exit(0);
831 }
832
833 static void
834 do_download(struct passwd *pw)
835 {
836 #ifdef ENABLE_PKCS11
837         struct sshkey **keys = NULL;
838         int i, nkeys;
839         enum sshkey_fp_rep rep;
840         int fptype;
841         char *fp, *ra, **comments = NULL;
842
843         fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash;
844         rep =    print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT;
845
846         pkcs11_init(1);
847         nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys, &comments);
848         if (nkeys <= 0)
849                 fatal("cannot read public key from pkcs11");
850         for (i = 0; i < nkeys; i++) {
851                 if (print_fingerprint) {
852                         fp = sshkey_fingerprint(keys[i], fptype, rep);
853                         ra = sshkey_fingerprint(keys[i], fingerprint_hash,
854                             SSH_FP_RANDOMART);
855                         if (fp == NULL || ra == NULL)
856                                 fatal_f("sshkey_fingerprint fail");
857                         printf("%u %s %s (PKCS11 key)\n", sshkey_size(keys[i]),
858                             fp, sshkey_type(keys[i]));
859                         if (log_level_get() >= SYSLOG_LEVEL_VERBOSE)
860                                 printf("%s\n", ra);
861                         free(ra);
862                         free(fp);
863                 } else {
864                         (void) sshkey_write(keys[i], stdout); /* XXX check */
865                         fprintf(stdout, "%s%s\n",
866                             *(comments[i]) == '\0' ? "" : " ", comments[i]);
867                 }
868                 free(comments[i]);
869                 sshkey_free(keys[i]);
870         }
871         free(comments);
872         free(keys);
873         pkcs11_terminate();
874         exit(0);
875 #else
876         fatal("no pkcs11 support");
877 #endif /* ENABLE_PKCS11 */
878 }
879
880 static struct sshkey *
881 try_read_key(char **cpp)
882 {
883         struct sshkey *ret;
884         int r;
885
886         if ((ret = sshkey_new(KEY_UNSPEC)) == NULL)
887                 fatal("sshkey_new failed");
888         if ((r = sshkey_read(ret, cpp)) == 0)
889                 return ret;
890         /* Not a key */
891         sshkey_free(ret);
892         return NULL;
893 }
894
895 static void
896 fingerprint_one_key(const struct sshkey *public, const char *comment)
897 {
898         char *fp = NULL, *ra = NULL;
899         enum sshkey_fp_rep rep;
900         int fptype;
901
902         fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash;
903         rep =    print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT;
904         fp = sshkey_fingerprint(public, fptype, rep);
905         ra = sshkey_fingerprint(public, fingerprint_hash, SSH_FP_RANDOMART);
906         if (fp == NULL || ra == NULL)
907                 fatal_f("sshkey_fingerprint failed");
908         mprintf("%u %s %s (%s)\n", sshkey_size(public), fp,
909             comment ? comment : "no comment", sshkey_type(public));
910         if (log_level_get() >= SYSLOG_LEVEL_VERBOSE)
911                 printf("%s\n", ra);
912         free(ra);
913         free(fp);
914 }
915
916 static void
917 fingerprint_private(const char *path)
918 {
919         struct stat st;
920         char *comment = NULL;
921         struct sshkey *privkey = NULL, *pubkey = NULL;
922         int r;
923
924         if (stat(identity_file, &st) == -1)
925                 fatal("%s: %s", path, strerror(errno));
926         if ((r = sshkey_load_public(path, &pubkey, &comment)) != 0)
927                 debug_r(r, "load public \"%s\"", path);
928         if (pubkey == NULL || comment == NULL || *comment == '\0') {
929                 free(comment);
930                 if ((r = sshkey_load_private(path, NULL,
931                     &privkey, &comment)) != 0)
932                         debug_r(r, "load private \"%s\"", path);
933         }
934         if (pubkey == NULL && privkey == NULL)
935                 fatal("%s is not a key file.", path);
936
937         fingerprint_one_key(pubkey == NULL ? privkey : pubkey, comment);
938         sshkey_free(pubkey);
939         sshkey_free(privkey);
940         free(comment);
941 }
942
943 static void
944 do_fingerprint(struct passwd *pw)
945 {
946         FILE *f;
947         struct sshkey *public = NULL;
948         char *comment = NULL, *cp, *ep, *line = NULL;
949         size_t linesize = 0;
950         int i, invalid = 1;
951         const char *path;
952         u_long lnum = 0;
953
954         if (!have_identity)
955                 ask_filename(pw, "Enter file in which the key is");
956         path = identity_file;
957
958         if (strcmp(identity_file, "-") == 0) {
959                 f = stdin;
960                 path = "(stdin)";
961         } else if ((f = fopen(path, "r")) == NULL)
962                 fatal("%s: %s: %s", __progname, path, strerror(errno));
963
964         while (getline(&line, &linesize, f) != -1) {
965                 lnum++;
966                 cp = line;
967                 cp[strcspn(cp, "\n")] = '\0';
968                 /* Trim leading space and comments */
969                 cp = line + strspn(line, " \t");
970                 if (*cp == '#' || *cp == '\0')
971                         continue;
972
973                 /*
974                  * Input may be plain keys, private keys, authorized_keys
975                  * or known_hosts.
976                  */
977
978                 /*
979                  * Try private keys first. Assume a key is private if
980                  * "SSH PRIVATE KEY" appears on the first line and we're
981                  * not reading from stdin (XXX support private keys on stdin).
982                  */
983                 if (lnum == 1 && strcmp(identity_file, "-") != 0 &&
984                     strstr(cp, "PRIVATE KEY") != NULL) {
985                         free(line);
986                         fclose(f);
987                         fingerprint_private(path);
988                         exit(0);
989                 }
990
991                 /*
992                  * If it's not a private key, then this must be prepared to
993                  * accept a public key prefixed with a hostname or options.
994                  * Try a bare key first, otherwise skip the leading stuff.
995                  */
996                 comment = NULL;
997                 if ((public = try_read_key(&cp)) == NULL) {
998                         i = strtol(cp, &ep, 10);
999                         if (i == 0 || ep == NULL ||
1000                             (*ep != ' ' && *ep != '\t')) {
1001                                 int quoted = 0;
1002
1003                                 comment = cp;
1004                                 for (; *cp && (quoted || (*cp != ' ' &&
1005                                     *cp != '\t')); cp++) {
1006                                         if (*cp == '\\' && cp[1] == '"')
1007                                                 cp++;   /* Skip both */
1008                                         else if (*cp == '"')
1009                                                 quoted = !quoted;
1010                                 }
1011                                 if (!*cp)
1012                                         continue;
1013                                 *cp++ = '\0';
1014                         }
1015                 }
1016                 /* Retry after parsing leading hostname/key options */
1017                 if (public == NULL && (public = try_read_key(&cp)) == NULL) {
1018                         debug("%s:%lu: not a public key", path, lnum);
1019                         continue;
1020                 }
1021
1022                 /* Find trailing comment, if any */
1023                 for (; *cp == ' ' || *cp == '\t'; cp++)
1024                         ;
1025                 if (*cp != '\0' && *cp != '#')
1026                         comment = cp;
1027
1028                 fingerprint_one_key(public, comment);
1029                 sshkey_free(public);
1030                 invalid = 0; /* One good key in the file is sufficient */
1031         }
1032         fclose(f);
1033         free(line);
1034
1035         if (invalid)
1036                 fatal("%s is not a public key file.", path);
1037         exit(0);
1038 }
1039
1040 static void
1041 do_gen_all_hostkeys(struct passwd *pw)
1042 {
1043         struct {
1044                 char *key_type;
1045                 char *key_type_display;
1046                 char *path;
1047         } key_types[] = {
1048 #ifdef WITH_OPENSSL
1049                 { "rsa", "RSA" ,_PATH_HOST_RSA_KEY_FILE },
1050 #ifdef OPENSSL_HAS_ECC
1051                 { "ecdsa", "ECDSA",_PATH_HOST_ECDSA_KEY_FILE },
1052 #endif /* OPENSSL_HAS_ECC */
1053 #endif /* WITH_OPENSSL */
1054                 { "ed25519", "ED25519",_PATH_HOST_ED25519_KEY_FILE },
1055 #ifdef WITH_XMSS
1056                 { "xmss", "XMSS",_PATH_HOST_XMSS_KEY_FILE },
1057 #endif /* WITH_XMSS */
1058                 { NULL, NULL, NULL }
1059         };
1060
1061         u_int32_t bits = 0;
1062         int first = 0;
1063         struct stat st;
1064         struct sshkey *private, *public;
1065         char comment[1024], *prv_tmp, *pub_tmp, *prv_file, *pub_file;
1066         int i, type, fd, r;
1067
1068         for (i = 0; key_types[i].key_type; i++) {
1069                 public = private = NULL;
1070                 prv_tmp = pub_tmp = prv_file = pub_file = NULL;
1071
1072                 xasprintf(&prv_file, "%s%s",
1073                     identity_file, key_types[i].path);
1074
1075                 /* Check whether private key exists and is not zero-length */
1076                 if (stat(prv_file, &st) == 0) {
1077                         if (st.st_size != 0)
1078                                 goto next;
1079                 } else if (errno != ENOENT) {
1080                         error("Could not stat %s: %s", key_types[i].path,
1081                             strerror(errno));
1082                         goto failnext;
1083                 }
1084
1085                 /*
1086                  * Private key doesn't exist or is invalid; proceed with
1087                  * key generation.
1088                  */
1089                 xasprintf(&prv_tmp, "%s%s.XXXXXXXXXX",
1090                     identity_file, key_types[i].path);
1091                 xasprintf(&pub_tmp, "%s%s.pub.XXXXXXXXXX",
1092                     identity_file, key_types[i].path);
1093                 xasprintf(&pub_file, "%s%s.pub",
1094                     identity_file, key_types[i].path);
1095
1096                 if (first == 0) {
1097                         first = 1;
1098                         printf("%s: generating new host keys: ", __progname);
1099                 }
1100                 printf("%s ", key_types[i].key_type_display);
1101                 fflush(stdout);
1102                 type = sshkey_type_from_name(key_types[i].key_type);
1103                 if ((fd = mkstemp(prv_tmp)) == -1) {
1104                         error("Could not save your private key in %s: %s",
1105                             prv_tmp, strerror(errno));
1106                         goto failnext;
1107                 }
1108                 (void)close(fd); /* just using mkstemp() to reserve a name */
1109                 bits = 0;
1110                 type_bits_valid(type, NULL, &bits);
1111                 if ((r = sshkey_generate(type, bits, &private)) != 0) {
1112                         error_r(r, "sshkey_generate failed");
1113                         goto failnext;
1114                 }
1115                 if ((r = sshkey_from_private(private, &public)) != 0)
1116                         fatal_fr(r, "sshkey_from_private");
1117                 snprintf(comment, sizeof comment, "%s@%s", pw->pw_name,
1118                     hostname);
1119                 if ((r = sshkey_save_private(private, prv_tmp, "",
1120                     comment, private_key_format, openssh_format_cipher,
1121                     rounds)) != 0) {
1122                         error_r(r, "Saving key \"%s\" failed", prv_tmp);
1123                         goto failnext;
1124                 }
1125                 if ((fd = mkstemp(pub_tmp)) == -1) {
1126                         error("Could not save your public key in %s: %s",
1127                             pub_tmp, strerror(errno));
1128                         goto failnext;
1129                 }
1130                 (void)fchmod(fd, 0644);
1131                 (void)close(fd);
1132                 if ((r = sshkey_save_public(public, pub_tmp, comment)) != 0) {
1133                         error_r(r, "Unable to save public key to %s",
1134                             identity_file);
1135                         goto failnext;
1136                 }
1137
1138                 /* Rename temporary files to their permanent locations. */
1139                 if (rename(pub_tmp, pub_file) != 0) {
1140                         error("Unable to move %s into position: %s",
1141                             pub_file, strerror(errno));
1142                         goto failnext;
1143                 }
1144                 if (rename(prv_tmp, prv_file) != 0) {
1145                         error("Unable to move %s into position: %s",
1146                             key_types[i].path, strerror(errno));
1147  failnext:
1148                         first = 0;
1149                         goto next;
1150                 }
1151  next:
1152                 sshkey_free(private);
1153                 sshkey_free(public);
1154                 free(prv_tmp);
1155                 free(pub_tmp);
1156                 free(prv_file);
1157                 free(pub_file);
1158         }
1159         if (first != 0)
1160                 printf("\n");
1161 }
1162
1163 struct known_hosts_ctx {
1164         const char *host;       /* Hostname searched for in find/delete case */
1165         FILE *out;              /* Output file, stdout for find_hosts case */
1166         int has_unhashed;       /* When hashing, original had unhashed hosts */
1167         int found_key;          /* For find/delete, host was found */
1168         int invalid;            /* File contained invalid items; don't delete */
1169         int hash_hosts;         /* Hash hostnames as we go */
1170         int find_host;          /* Search for specific hostname */
1171         int delete_host;        /* Delete host from known_hosts */
1172 };
1173
1174 static int
1175 known_hosts_hash(struct hostkey_foreach_line *l, void *_ctx)
1176 {
1177         struct known_hosts_ctx *ctx = (struct known_hosts_ctx *)_ctx;
1178         char *hashed, *cp, *hosts, *ohosts;
1179         int has_wild = l->hosts && strcspn(l->hosts, "*?!") != strlen(l->hosts);
1180         int was_hashed = l->hosts && l->hosts[0] == HASH_DELIM;
1181
1182         switch (l->status) {
1183         case HKF_STATUS_OK:
1184         case HKF_STATUS_MATCHED:
1185                 /*
1186                  * Don't hash hosts already hashed, with wildcard
1187                  * characters or a CA/revocation marker.
1188                  */
1189                 if (was_hashed || has_wild || l->marker != MRK_NONE) {
1190                         fprintf(ctx->out, "%s\n", l->line);
1191                         if (has_wild && !ctx->find_host) {
1192                                 logit("%s:%lu: ignoring host name "
1193                                     "with wildcard: %.64s", l->path,
1194                                     l->linenum, l->hosts);
1195                         }
1196                         return 0;
1197                 }
1198                 /*
1199                  * Split any comma-separated hostnames from the host list,
1200                  * hash and store separately.
1201                  */
1202                 ohosts = hosts = xstrdup(l->hosts);
1203                 while ((cp = strsep(&hosts, ",")) != NULL && *cp != '\0') {
1204                         lowercase(cp);
1205                         if ((hashed = host_hash(cp, NULL, 0)) == NULL)
1206                                 fatal("hash_host failed");
1207                         fprintf(ctx->out, "%s %s\n", hashed, l->rawkey);
1208                         free(hashed);
1209                         ctx->has_unhashed = 1;
1210                 }
1211                 free(ohosts);
1212                 return 0;
1213         case HKF_STATUS_INVALID:
1214                 /* Retain invalid lines, but mark file as invalid. */
1215                 ctx->invalid = 1;
1216                 logit("%s:%lu: invalid line", l->path, l->linenum);
1217                 /* FALLTHROUGH */
1218         default:
1219                 fprintf(ctx->out, "%s\n", l->line);
1220                 return 0;
1221         }
1222         /* NOTREACHED */
1223         return -1;
1224 }
1225
1226 static int
1227 known_hosts_find_delete(struct hostkey_foreach_line *l, void *_ctx)
1228 {
1229         struct known_hosts_ctx *ctx = (struct known_hosts_ctx *)_ctx;
1230         enum sshkey_fp_rep rep;
1231         int fptype;
1232         char *fp = NULL, *ra = NULL;
1233
1234         fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash;
1235         rep =    print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT;
1236
1237         if (l->status == HKF_STATUS_MATCHED) {
1238                 if (ctx->delete_host) {
1239                         if (l->marker != MRK_NONE) {
1240                                 /* Don't remove CA and revocation lines */
1241                                 fprintf(ctx->out, "%s\n", l->line);
1242                         } else {
1243                                 /*
1244                                  * Hostname matches and has no CA/revoke
1245                                  * marker, delete it by *not* writing the
1246                                  * line to ctx->out.
1247                                  */
1248                                 ctx->found_key = 1;
1249                                 if (!quiet)
1250                                         printf("# Host %s found: line %lu\n",
1251                                             ctx->host, l->linenum);
1252                         }
1253                         return 0;
1254                 } else if (ctx->find_host) {
1255                         ctx->found_key = 1;
1256                         if (!quiet) {
1257                                 printf("# Host %s found: line %lu %s\n",
1258                                     ctx->host,
1259                                     l->linenum, l->marker == MRK_CA ? "CA" :
1260                                     (l->marker == MRK_REVOKE ? "REVOKED" : ""));
1261                         }
1262                         if (ctx->hash_hosts)
1263                                 known_hosts_hash(l, ctx);
1264                         else if (print_fingerprint) {
1265                                 fp = sshkey_fingerprint(l->key, fptype, rep);
1266                                 ra = sshkey_fingerprint(l->key,
1267                                     fingerprint_hash, SSH_FP_RANDOMART);
1268                                 if (fp == NULL || ra == NULL)
1269                                         fatal_f("sshkey_fingerprint failed");
1270                                 mprintf("%s %s %s%s%s\n", ctx->host,
1271                                     sshkey_type(l->key), fp,
1272                                     l->comment[0] ? " " : "",
1273                                     l->comment);
1274                                 if (log_level_get() >= SYSLOG_LEVEL_VERBOSE)
1275                                         printf("%s\n", ra);
1276                                 free(ra);
1277                                 free(fp);
1278                         } else
1279                                 fprintf(ctx->out, "%s\n", l->line);
1280                         return 0;
1281                 }
1282         } else if (ctx->delete_host) {
1283                 /* Retain non-matching hosts when deleting */
1284                 if (l->status == HKF_STATUS_INVALID) {
1285                         ctx->invalid = 1;
1286                         logit("%s:%lu: invalid line", l->path, l->linenum);
1287                 }
1288                 fprintf(ctx->out, "%s\n", l->line);
1289         }
1290         return 0;
1291 }
1292
1293 static void
1294 do_known_hosts(struct passwd *pw, const char *name, int find_host,
1295     int delete_host, int hash_hosts)
1296 {
1297         char *cp, tmp[PATH_MAX], old[PATH_MAX];
1298         int r, fd, oerrno, inplace = 0;
1299         struct known_hosts_ctx ctx;
1300         u_int foreach_options;
1301         struct stat sb;
1302
1303         if (!have_identity) {
1304                 cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid);
1305                 if (strlcpy(identity_file, cp, sizeof(identity_file)) >=
1306                     sizeof(identity_file))
1307                         fatal("Specified known hosts path too long");
1308                 free(cp);
1309                 have_identity = 1;
1310         }
1311         if (stat(identity_file, &sb) != 0)
1312                 fatal("Cannot stat %s: %s", identity_file, strerror(errno));
1313
1314         memset(&ctx, 0, sizeof(ctx));
1315         ctx.out = stdout;
1316         ctx.host = name;
1317         ctx.hash_hosts = hash_hosts;
1318         ctx.find_host = find_host;
1319         ctx.delete_host = delete_host;
1320
1321         /*
1322          * Find hosts goes to stdout, hash and deletions happen in-place
1323          * A corner case is ssh-keygen -HF foo, which should go to stdout
1324          */
1325         if (!find_host && (hash_hosts || delete_host)) {
1326                 if (strlcpy(tmp, identity_file, sizeof(tmp)) >= sizeof(tmp) ||
1327                     strlcat(tmp, ".XXXXXXXXXX", sizeof(tmp)) >= sizeof(tmp) ||
1328                     strlcpy(old, identity_file, sizeof(old)) >= sizeof(old) ||
1329                     strlcat(old, ".old", sizeof(old)) >= sizeof(old))
1330                         fatal("known_hosts path too long");
1331                 umask(077);
1332                 if ((fd = mkstemp(tmp)) == -1)
1333                         fatal("mkstemp: %s", strerror(errno));
1334                 if ((ctx.out = fdopen(fd, "w")) == NULL) {
1335                         oerrno = errno;
1336                         unlink(tmp);
1337                         fatal("fdopen: %s", strerror(oerrno));
1338                 }
1339                 (void)fchmod(fd, sb.st_mode & 0644);
1340                 inplace = 1;
1341         }
1342         /* XXX support identity_file == "-" for stdin */
1343         foreach_options = find_host ? HKF_WANT_MATCH : 0;
1344         foreach_options |= print_fingerprint ? HKF_WANT_PARSE_KEY : 0;
1345         if ((r = hostkeys_foreach(identity_file, (find_host || !hash_hosts) ?
1346             known_hosts_find_delete : known_hosts_hash, &ctx, name, NULL,
1347             foreach_options, 0)) != 0) {
1348                 if (inplace)
1349                         unlink(tmp);
1350                 fatal_fr(r, "hostkeys_foreach");
1351         }
1352
1353         if (inplace)
1354                 fclose(ctx.out);
1355
1356         if (ctx.invalid) {
1357                 error("%s is not a valid known_hosts file.", identity_file);
1358                 if (inplace) {
1359                         error("Not replacing existing known_hosts "
1360                             "file because of errors");
1361                         unlink(tmp);
1362                 }
1363                 exit(1);
1364         } else if (delete_host && !ctx.found_key) {
1365                 logit("Host %s not found in %s", name, identity_file);
1366                 if (inplace)
1367                         unlink(tmp);
1368         } else if (inplace) {
1369                 /* Backup existing file */
1370                 if (unlink(old) == -1 && errno != ENOENT)
1371                         fatal("unlink %.100s: %s", old, strerror(errno));
1372                 if (link(identity_file, old) == -1)
1373                         fatal("link %.100s to %.100s: %s", identity_file, old,
1374                             strerror(errno));
1375                 /* Move new one into place */
1376                 if (rename(tmp, identity_file) == -1) {
1377                         error("rename\"%s\" to \"%s\": %s", tmp, identity_file,
1378                             strerror(errno));
1379                         unlink(tmp);
1380                         unlink(old);
1381                         exit(1);
1382                 }
1383
1384                 printf("%s updated.\n", identity_file);
1385                 printf("Original contents retained as %s\n", old);
1386                 if (ctx.has_unhashed) {
1387                         logit("WARNING: %s contains unhashed entries", old);
1388                         logit("Delete this file to ensure privacy "
1389                             "of hostnames");
1390                 }
1391         }
1392
1393         exit (find_host && !ctx.found_key);
1394 }
1395
1396 /*
1397  * Perform changing a passphrase.  The argument is the passwd structure
1398  * for the current user.
1399  */
1400 static void
1401 do_change_passphrase(struct passwd *pw)
1402 {
1403         char *comment;
1404         char *old_passphrase, *passphrase1, *passphrase2;
1405         struct stat st;
1406         struct sshkey *private;
1407         int r;
1408
1409         if (!have_identity)
1410                 ask_filename(pw, "Enter file in which the key is");
1411         if (stat(identity_file, &st) == -1)
1412                 fatal("%s: %s", identity_file, strerror(errno));
1413         /* Try to load the file with empty passphrase. */
1414         r = sshkey_load_private(identity_file, "", &private, &comment);
1415         if (r == SSH_ERR_KEY_WRONG_PASSPHRASE) {
1416                 if (identity_passphrase)
1417                         old_passphrase = xstrdup(identity_passphrase);
1418                 else
1419                         old_passphrase =
1420                             read_passphrase("Enter old passphrase: ",
1421                             RP_ALLOW_STDIN);
1422                 r = sshkey_load_private(identity_file, old_passphrase,
1423                     &private, &comment);
1424                 freezero(old_passphrase, strlen(old_passphrase));
1425                 if (r != 0)
1426                         goto badkey;
1427         } else if (r != 0) {
1428  badkey:
1429                 fatal_r(r, "Failed to load key %s", identity_file);
1430         }
1431         if (comment)
1432                 mprintf("Key has comment '%s'\n", comment);
1433
1434         /* Ask the new passphrase (twice). */
1435         if (identity_new_passphrase) {
1436                 passphrase1 = xstrdup(identity_new_passphrase);
1437                 passphrase2 = NULL;
1438         } else {
1439                 passphrase1 =
1440                         read_passphrase("Enter new passphrase (empty for no "
1441                             "passphrase): ", RP_ALLOW_STDIN);
1442                 passphrase2 = read_passphrase("Enter same passphrase again: ",
1443                     RP_ALLOW_STDIN);
1444
1445                 /* Verify that they are the same. */
1446                 if (strcmp(passphrase1, passphrase2) != 0) {
1447                         explicit_bzero(passphrase1, strlen(passphrase1));
1448                         explicit_bzero(passphrase2, strlen(passphrase2));
1449                         free(passphrase1);
1450                         free(passphrase2);
1451                         printf("Pass phrases do not match.  Try again.\n");
1452                         exit(1);
1453                 }
1454                 /* Destroy the other copy. */
1455                 freezero(passphrase2, strlen(passphrase2));
1456         }
1457
1458         /* Save the file using the new passphrase. */
1459         if ((r = sshkey_save_private(private, identity_file, passphrase1,
1460             comment, private_key_format, openssh_format_cipher, rounds)) != 0) {
1461                 error_r(r, "Saving key \"%s\" failed", identity_file);
1462                 freezero(passphrase1, strlen(passphrase1));
1463                 sshkey_free(private);
1464                 free(comment);
1465                 exit(1);
1466         }
1467         /* Destroy the passphrase and the copy of the key in memory. */
1468         freezero(passphrase1, strlen(passphrase1));
1469         sshkey_free(private);            /* Destroys contents */
1470         free(comment);
1471
1472         printf("Your identification has been saved with the new passphrase.\n");
1473         exit(0);
1474 }
1475
1476 /*
1477  * Print the SSHFP RR.
1478  */
1479 static int
1480 do_print_resource_record(struct passwd *pw, char *fname, char *hname,
1481     int print_generic, char * const *opts, size_t nopts)
1482 {
1483         struct sshkey *public;
1484         char *comment = NULL;
1485         struct stat st;
1486         int r, hash = -1;
1487         size_t i;
1488
1489         for (i = 0; i < nopts; i++) {
1490                 if (strncasecmp(opts[i], "hashalg=", 8) == 0) {
1491                         if ((hash = ssh_digest_alg_by_name(opts[i] + 8)) == -1)
1492                                 fatal("Unsupported hash algorithm");
1493                 } else {
1494                         error("Invalid option \"%s\"", opts[i]);
1495                         return SSH_ERR_INVALID_ARGUMENT;
1496                 }
1497         }
1498         if (fname == NULL)
1499                 fatal_f("no filename");
1500         if (stat(fname, &st) == -1) {
1501                 if (errno == ENOENT)
1502                         return 0;
1503                 fatal("%s: %s", fname, strerror(errno));
1504         }
1505         if ((r = sshkey_load_public(fname, &public, &comment)) != 0)
1506                 fatal_r(r, "Failed to read v2 public key from \"%s\"", fname);
1507         export_dns_rr(hname, public, stdout, print_generic, hash);
1508         sshkey_free(public);
1509         free(comment);
1510         return 1;
1511 }
1512
1513 /*
1514  * Change the comment of a private key file.
1515  */
1516 static void
1517 do_change_comment(struct passwd *pw, const char *identity_comment)
1518 {
1519         char new_comment[1024], *comment, *passphrase;
1520         struct sshkey *private;
1521         struct sshkey *public;
1522         struct stat st;
1523         int r;
1524
1525         if (!have_identity)
1526                 ask_filename(pw, "Enter file in which the key is");
1527         if (stat(identity_file, &st) == -1)
1528                 fatal("%s: %s", identity_file, strerror(errno));
1529         if ((r = sshkey_load_private(identity_file, "",
1530             &private, &comment)) == 0)
1531                 passphrase = xstrdup("");
1532         else if (r != SSH_ERR_KEY_WRONG_PASSPHRASE)
1533                 fatal_r(r, "Cannot load private key \"%s\"", identity_file);
1534         else {
1535                 if (identity_passphrase)
1536                         passphrase = xstrdup(identity_passphrase);
1537                 else if (identity_new_passphrase)
1538                         passphrase = xstrdup(identity_new_passphrase);
1539                 else
1540                         passphrase = read_passphrase("Enter passphrase: ",
1541                             RP_ALLOW_STDIN);
1542                 /* Try to load using the passphrase. */
1543                 if ((r = sshkey_load_private(identity_file, passphrase,
1544                     &private, &comment)) != 0) {
1545                         freezero(passphrase, strlen(passphrase));
1546                         fatal_r(r, "Cannot load private key \"%s\"",
1547                             identity_file);
1548                 }
1549         }
1550
1551         if (private->type != KEY_ED25519 && private->type != KEY_XMSS &&
1552             private_key_format != SSHKEY_PRIVATE_OPENSSH) {
1553                 error("Comments are only supported for keys stored in "
1554                     "the new format (-o).");
1555                 explicit_bzero(passphrase, strlen(passphrase));
1556                 sshkey_free(private);
1557                 exit(1);
1558         }
1559         if (comment)
1560                 printf("Old comment: %s\n", comment);
1561         else
1562                 printf("No existing comment\n");
1563
1564         if (identity_comment) {
1565                 strlcpy(new_comment, identity_comment, sizeof(new_comment));
1566         } else {
1567                 printf("New comment: ");
1568                 fflush(stdout);
1569                 if (!fgets(new_comment, sizeof(new_comment), stdin)) {
1570                         explicit_bzero(passphrase, strlen(passphrase));
1571                         sshkey_free(private);
1572                         exit(1);
1573                 }
1574                 new_comment[strcspn(new_comment, "\n")] = '\0';
1575         }
1576         if (comment != NULL && strcmp(comment, new_comment) == 0) {
1577                 printf("No change to comment\n");
1578                 free(passphrase);
1579                 sshkey_free(private);
1580                 free(comment);
1581                 exit(0);
1582         }
1583
1584         /* Save the file using the new passphrase. */
1585         if ((r = sshkey_save_private(private, identity_file, passphrase,
1586             new_comment, private_key_format, openssh_format_cipher,
1587             rounds)) != 0) {
1588                 error_r(r, "Saving key \"%s\" failed", identity_file);
1589                 freezero(passphrase, strlen(passphrase));
1590                 sshkey_free(private);
1591                 free(comment);
1592                 exit(1);
1593         }
1594         freezero(passphrase, strlen(passphrase));
1595         if ((r = sshkey_from_private(private, &public)) != 0)
1596                 fatal_fr(r, "sshkey_from_private");
1597         sshkey_free(private);
1598
1599         strlcat(identity_file, ".pub", sizeof(identity_file));
1600         if ((r = sshkey_save_public(public, identity_file, new_comment)) != 0)
1601                 fatal_r(r, "Unable to save public key to %s", identity_file);
1602         sshkey_free(public);
1603         free(comment);
1604
1605         if (strlen(new_comment) > 0)
1606                 printf("Comment '%s' applied\n", new_comment);
1607         else
1608                 printf("Comment removed\n");
1609
1610         exit(0);
1611 }
1612
1613 static void
1614 cert_ext_add(const char *key, const char *value, int iscrit)
1615 {
1616         cert_ext = xreallocarray(cert_ext, ncert_ext + 1, sizeof(*cert_ext));
1617         cert_ext[ncert_ext].key = xstrdup(key);
1618         cert_ext[ncert_ext].val = value == NULL ? NULL : xstrdup(value);
1619         cert_ext[ncert_ext].crit = iscrit;
1620         ncert_ext++;
1621 }
1622
1623 /* qsort(3) comparison function for certificate extensions */
1624 static int
1625 cert_ext_cmp(const void *_a, const void *_b)
1626 {
1627         const struct cert_ext *a = (const struct cert_ext *)_a;
1628         const struct cert_ext *b = (const struct cert_ext *)_b;
1629         int r;
1630
1631         if (a->crit != b->crit)
1632                 return (a->crit < b->crit) ? -1 : 1;
1633         if ((r = strcmp(a->key, b->key)) != 0)
1634                 return r;
1635         if ((a->val == NULL) != (b->val == NULL))
1636                 return (a->val == NULL) ? -1 : 1;
1637         if (a->val != NULL && (r = strcmp(a->val, b->val)) != 0)
1638                 return r;
1639         return 0;
1640 }
1641
1642 #define OPTIONS_CRITICAL        1
1643 #define OPTIONS_EXTENSIONS      2
1644 static void
1645 prepare_options_buf(struct sshbuf *c, int which)
1646 {
1647         struct sshbuf *b;
1648         size_t i;
1649         int r;
1650         const struct cert_ext *ext;
1651
1652         if ((b = sshbuf_new()) == NULL)
1653                 fatal_f("sshbuf_new failed");
1654         sshbuf_reset(c);
1655         for (i = 0; i < ncert_ext; i++) {
1656                 ext = &cert_ext[i];
1657                 if ((ext->crit && (which & OPTIONS_EXTENSIONS)) ||
1658                     (!ext->crit && (which & OPTIONS_CRITICAL)))
1659                         continue;
1660                 if (ext->val == NULL) {
1661                         /* flag option */
1662                         debug3_f("%s", ext->key);
1663                         if ((r = sshbuf_put_cstring(c, ext->key)) != 0 ||
1664                             (r = sshbuf_put_string(c, NULL, 0)) != 0)
1665                                 fatal_fr(r, "prepare flag");
1666                 } else {
1667                         /* key/value option */
1668                         debug3_f("%s=%s", ext->key, ext->val);
1669                         sshbuf_reset(b);
1670                         if ((r = sshbuf_put_cstring(c, ext->key)) != 0 ||
1671                             (r = sshbuf_put_cstring(b, ext->val)) != 0 ||
1672                             (r = sshbuf_put_stringb(c, b)) != 0)
1673                                 fatal_fr(r, "prepare k/v");
1674                 }
1675         }
1676         sshbuf_free(b);
1677 }
1678
1679 static void
1680 finalise_cert_exts(void)
1681 {
1682         /* critical options */
1683         if (certflags_command != NULL)
1684                 cert_ext_add("force-command", certflags_command, 1);
1685         if (certflags_src_addr != NULL)
1686                 cert_ext_add("source-address", certflags_src_addr, 1);
1687         if ((certflags_flags & CERTOPT_REQUIRE_VERIFY) != 0)
1688                 cert_ext_add("verify-required", NULL, 1);
1689         /* extensions */
1690         if ((certflags_flags & CERTOPT_X_FWD) != 0)
1691                 cert_ext_add("permit-X11-forwarding", NULL, 0);
1692         if ((certflags_flags & CERTOPT_AGENT_FWD) != 0)
1693                 cert_ext_add("permit-agent-forwarding", NULL, 0);
1694         if ((certflags_flags & CERTOPT_PORT_FWD) != 0)
1695                 cert_ext_add("permit-port-forwarding", NULL, 0);
1696         if ((certflags_flags & CERTOPT_PTY) != 0)
1697                 cert_ext_add("permit-pty", NULL, 0);
1698         if ((certflags_flags & CERTOPT_USER_RC) != 0)
1699                 cert_ext_add("permit-user-rc", NULL, 0);
1700         if ((certflags_flags & CERTOPT_NO_REQUIRE_USER_PRESENCE) != 0)
1701                 cert_ext_add("no-touch-required", NULL, 0);
1702         /* order lexically by key */
1703         if (ncert_ext > 0)
1704                 qsort(cert_ext, ncert_ext, sizeof(*cert_ext), cert_ext_cmp);
1705 }
1706
1707 static struct sshkey *
1708 load_pkcs11_key(char *path)
1709 {
1710 #ifdef ENABLE_PKCS11
1711         struct sshkey **keys = NULL, *public, *private = NULL;
1712         int r, i, nkeys;
1713
1714         if ((r = sshkey_load_public(path, &public, NULL)) != 0)
1715                 fatal_r(r, "Couldn't load CA public key \"%s\"", path);
1716
1717         nkeys = pkcs11_add_provider(pkcs11provider, identity_passphrase,
1718             &keys, NULL);
1719         debug3_f("%d keys", nkeys);
1720         if (nkeys <= 0)
1721                 fatal("cannot read public key from pkcs11");
1722         for (i = 0; i < nkeys; i++) {
1723                 if (sshkey_equal_public(public, keys[i])) {
1724                         private = keys[i];
1725                         continue;
1726                 }
1727                 sshkey_free(keys[i]);
1728         }
1729         free(keys);
1730         sshkey_free(public);
1731         return private;
1732 #else
1733         fatal("no pkcs11 support");
1734 #endif /* ENABLE_PKCS11 */
1735 }
1736
1737 /* Signer for sshkey_certify_custom that uses the agent */
1738 static int
1739 agent_signer(struct sshkey *key, u_char **sigp, size_t *lenp,
1740     const u_char *data, size_t datalen,
1741     const char *alg, const char *provider, const char *pin,
1742     u_int compat, void *ctx)
1743 {
1744         int *agent_fdp = (int *)ctx;
1745
1746         return ssh_agent_sign(*agent_fdp, key, sigp, lenp,
1747             data, datalen, alg, compat);
1748 }
1749
1750 static void
1751 do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent,
1752     unsigned long long cert_serial, int cert_serial_autoinc,
1753     int argc, char **argv)
1754 {
1755         int r, i, found, agent_fd = -1;
1756         u_int n;
1757         struct sshkey *ca, *public;
1758         char valid[64], *otmp, *tmp, *cp, *out, *comment;
1759         char *ca_fp = NULL, **plist = NULL, *pin = NULL;
1760         struct ssh_identitylist *agent_ids;
1761         size_t j;
1762         struct notifier_ctx *notifier = NULL;
1763
1764 #ifdef ENABLE_PKCS11
1765         pkcs11_init(1);
1766 #endif
1767         tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
1768         if (pkcs11provider != NULL) {
1769                 /* If a PKCS#11 token was specified then try to use it */
1770                 if ((ca = load_pkcs11_key(tmp)) == NULL)
1771                         fatal("No PKCS#11 key matching %s found", ca_key_path);
1772         } else if (prefer_agent) {
1773                 /*
1774                  * Agent signature requested. Try to use agent after making
1775                  * sure the public key specified is actually present in the
1776                  * agent.
1777                  */
1778                 if ((r = sshkey_load_public(tmp, &ca, NULL)) != 0)
1779                         fatal_r(r, "Cannot load CA public key %s", tmp);
1780                 if ((r = ssh_get_authentication_socket(&agent_fd)) != 0)
1781                         fatal_r(r, "Cannot use public key for CA signature");
1782                 if ((r = ssh_fetch_identitylist(agent_fd, &agent_ids)) != 0)
1783                         fatal_r(r, "Retrieve agent key list");
1784                 found = 0;
1785                 for (j = 0; j < agent_ids->nkeys; j++) {
1786                         if (sshkey_equal(ca, agent_ids->keys[j])) {
1787                                 found = 1;
1788                                 break;
1789                         }
1790                 }
1791                 if (!found)
1792                         fatal("CA key %s not found in agent", tmp);
1793                 ssh_free_identitylist(agent_ids);
1794                 ca->flags |= SSHKEY_FLAG_EXT;
1795         } else {
1796                 /* CA key is assumed to be a private key on the filesystem */
1797                 ca = load_identity(tmp, NULL);
1798                 if (sshkey_is_sk(ca) &&
1799                     (ca->sk_flags & SSH_SK_USER_VERIFICATION_REQD)) {
1800                         if ((pin = read_passphrase("Enter PIN for CA key: ",
1801                             RP_ALLOW_STDIN)) == NULL)
1802                                 fatal_f("couldn't read PIN");
1803                 }
1804         }
1805         free(tmp);
1806
1807         if (key_type_name != NULL) {
1808                 if (sshkey_type_from_name(key_type_name) != ca->type) {
1809                         fatal("CA key type %s doesn't match specified %s",
1810                             sshkey_ssh_name(ca), key_type_name);
1811                 }
1812         } else if (ca->type == KEY_RSA) {
1813                 /* Default to a good signature algorithm */
1814                 key_type_name = "rsa-sha2-512";
1815         }
1816         ca_fp = sshkey_fingerprint(ca, fingerprint_hash, SSH_FP_DEFAULT);
1817
1818         finalise_cert_exts();
1819         for (i = 0; i < argc; i++) {
1820                 /* Split list of principals */
1821                 n = 0;
1822                 if (cert_principals != NULL) {
1823                         otmp = tmp = xstrdup(cert_principals);
1824                         plist = NULL;
1825                         for (; (cp = strsep(&tmp, ",")) != NULL; n++) {
1826                                 plist = xreallocarray(plist, n + 1, sizeof(*plist));
1827                                 if (*(plist[n] = xstrdup(cp)) == '\0')
1828                                         fatal("Empty principal name");
1829                         }
1830                         free(otmp);
1831                 }
1832                 if (n > SSHKEY_CERT_MAX_PRINCIPALS)
1833                         fatal("Too many certificate principals specified");
1834
1835                 tmp = tilde_expand_filename(argv[i], pw->pw_uid);
1836                 if ((r = sshkey_load_public(tmp, &public, &comment)) != 0)
1837                         fatal_r(r, "load pubkey \"%s\"", tmp);
1838                 if (sshkey_is_cert(public))
1839                         fatal_f("key \"%s\" type %s cannot be certified",
1840                             tmp, sshkey_type(public));
1841
1842                 /* Prepare certificate to sign */
1843                 if ((r = sshkey_to_certified(public)) != 0)
1844                         fatal_r(r, "Could not upgrade key %s to certificate", tmp);
1845                 public->cert->type = cert_key_type;
1846                 public->cert->serial = (u_int64_t)cert_serial;
1847                 public->cert->key_id = xstrdup(cert_key_id);
1848                 public->cert->nprincipals = n;
1849                 public->cert->principals = plist;
1850                 public->cert->valid_after = cert_valid_from;
1851                 public->cert->valid_before = cert_valid_to;
1852                 prepare_options_buf(public->cert->critical, OPTIONS_CRITICAL);
1853                 prepare_options_buf(public->cert->extensions,
1854                     OPTIONS_EXTENSIONS);
1855                 if ((r = sshkey_from_private(ca,
1856                     &public->cert->signature_key)) != 0)
1857                         fatal_r(r, "sshkey_from_private (ca key)");
1858
1859                 if (agent_fd != -1 && (ca->flags & SSHKEY_FLAG_EXT) != 0) {
1860                         if ((r = sshkey_certify_custom(public, ca,
1861                             key_type_name, sk_provider, NULL, agent_signer,
1862                             &agent_fd)) != 0)
1863                                 fatal_r(r, "Couldn't certify %s via agent", tmp);
1864                 } else {
1865                         if (sshkey_is_sk(ca) &&
1866                             (ca->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {
1867                                 notifier = notify_start(0,
1868                                     "Confirm user presence for key %s %s",
1869                                     sshkey_type(ca), ca_fp);
1870                         }
1871                         r = sshkey_certify(public, ca, key_type_name,
1872                             sk_provider, pin);
1873                         notify_complete(notifier, "User presence confirmed");
1874                         if (r != 0)
1875                                 fatal_r(r, "Couldn't certify key %s", tmp);
1876                 }
1877
1878                 if ((cp = strrchr(tmp, '.')) != NULL && strcmp(cp, ".pub") == 0)
1879                         *cp = '\0';
1880                 xasprintf(&out, "%s-cert.pub", tmp);
1881                 free(tmp);
1882
1883                 if ((r = sshkey_save_public(public, out, comment)) != 0) {
1884                         fatal_r(r, "Unable to save public key to %s",
1885                             identity_file);
1886                 }
1887
1888                 if (!quiet) {
1889                         sshkey_format_cert_validity(public->cert,
1890                             valid, sizeof(valid));
1891                         logit("Signed %s key %s: id \"%s\" serial %llu%s%s "
1892                             "valid %s", sshkey_cert_type(public),
1893                             out, public->cert->key_id,
1894                             (unsigned long long)public->cert->serial,
1895                             cert_principals != NULL ? " for " : "",
1896                             cert_principals != NULL ? cert_principals : "",
1897                             valid);
1898                 }
1899
1900                 sshkey_free(public);
1901                 free(out);
1902                 if (cert_serial_autoinc)
1903                         cert_serial++;
1904         }
1905         if (pin != NULL)
1906                 freezero(pin, strlen(pin));
1907         free(ca_fp);
1908 #ifdef ENABLE_PKCS11
1909         pkcs11_terminate();
1910 #endif
1911         exit(0);
1912 }
1913
1914 static u_int64_t
1915 parse_relative_time(const char *s, time_t now)
1916 {
1917         int64_t mul, secs;
1918
1919         mul = *s == '-' ? -1 : 1;
1920
1921         if ((secs = convtime(s + 1)) == -1)
1922                 fatal("Invalid relative certificate time %s", s);
1923         if (mul == -1 && secs > now)
1924                 fatal("Certificate time %s cannot be represented", s);
1925         return now + (u_int64_t)(secs * mul);
1926 }
1927
1928 static void
1929 parse_hex_u64(const char *s, uint64_t *up)
1930 {
1931         char *ep;
1932         unsigned long long ull;
1933
1934         errno = 0;
1935         ull = strtoull(s, &ep, 16);
1936         if (*s == '\0' || *ep != '\0')
1937                 fatal("Invalid certificate time: not a number");
1938         if (errno == ERANGE && ull == ULONG_MAX)
1939                 fatal_fr(SSH_ERR_SYSTEM_ERROR, "Invalid certificate time");
1940         *up = (uint64_t)ull;
1941 }
1942
1943 static void
1944 parse_cert_times(char *timespec)
1945 {
1946         char *from, *to;
1947         time_t now = time(NULL);
1948         int64_t secs;
1949
1950         /* +timespec relative to now */
1951         if (*timespec == '+' && strchr(timespec, ':') == NULL) {
1952                 if ((secs = convtime(timespec + 1)) == -1)
1953                         fatal("Invalid relative certificate life %s", timespec);
1954                 cert_valid_to = now + secs;
1955                 /*
1956                  * Backdate certificate one minute to avoid problems on hosts
1957                  * with poorly-synchronised clocks.
1958                  */
1959                 cert_valid_from = ((now - 59)/ 60) * 60;
1960                 return;
1961         }
1962
1963         /*
1964          * from:to, where
1965          * from := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS | 0x... | "always"
1966          *   to := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS | 0x... | "forever"
1967          */
1968         from = xstrdup(timespec);
1969         to = strchr(from, ':');
1970         if (to == NULL || from == to || *(to + 1) == '\0')
1971                 fatal("Invalid certificate life specification %s", timespec);
1972         *to++ = '\0';
1973
1974         if (*from == '-' || *from == '+')
1975                 cert_valid_from = parse_relative_time(from, now);
1976         else if (strcmp(from, "always") == 0)
1977                 cert_valid_from = 0;
1978         else if (strncmp(from, "0x", 2) == 0)
1979                 parse_hex_u64(from, &cert_valid_from);
1980         else if (parse_absolute_time(from, &cert_valid_from) != 0)
1981                 fatal("Invalid from time \"%s\"", from);
1982
1983         if (*to == '-' || *to == '+')
1984                 cert_valid_to = parse_relative_time(to, now);
1985         else if (strcmp(to, "forever") == 0)
1986                 cert_valid_to = ~(u_int64_t)0;
1987         else if (strncmp(to, "0x", 2) == 0)
1988                 parse_hex_u64(to, &cert_valid_to);
1989         else if (parse_absolute_time(to, &cert_valid_to) != 0)
1990                 fatal("Invalid to time \"%s\"", to);
1991
1992         if (cert_valid_to <= cert_valid_from)
1993                 fatal("Empty certificate validity interval");
1994         free(from);
1995 }
1996
1997 static void
1998 add_cert_option(char *opt)
1999 {
2000         char *val, *cp;
2001         int iscrit = 0;
2002
2003         if (strcasecmp(opt, "clear") == 0)
2004                 certflags_flags = 0;
2005         else if (strcasecmp(opt, "no-x11-forwarding") == 0)
2006                 certflags_flags &= ~CERTOPT_X_FWD;
2007         else if (strcasecmp(opt, "permit-x11-forwarding") == 0)
2008                 certflags_flags |= CERTOPT_X_FWD;
2009         else if (strcasecmp(opt, "no-agent-forwarding") == 0)
2010                 certflags_flags &= ~CERTOPT_AGENT_FWD;
2011         else if (strcasecmp(opt, "permit-agent-forwarding") == 0)
2012                 certflags_flags |= CERTOPT_AGENT_FWD;
2013         else if (strcasecmp(opt, "no-port-forwarding") == 0)
2014                 certflags_flags &= ~CERTOPT_PORT_FWD;
2015         else if (strcasecmp(opt, "permit-port-forwarding") == 0)
2016                 certflags_flags |= CERTOPT_PORT_FWD;
2017         else if (strcasecmp(opt, "no-pty") == 0)
2018                 certflags_flags &= ~CERTOPT_PTY;
2019         else if (strcasecmp(opt, "permit-pty") == 0)
2020                 certflags_flags |= CERTOPT_PTY;
2021         else if (strcasecmp(opt, "no-user-rc") == 0)
2022                 certflags_flags &= ~CERTOPT_USER_RC;
2023         else if (strcasecmp(opt, "permit-user-rc") == 0)
2024                 certflags_flags |= CERTOPT_USER_RC;
2025         else if (strcasecmp(opt, "touch-required") == 0)
2026                 certflags_flags &= ~CERTOPT_NO_REQUIRE_USER_PRESENCE;
2027         else if (strcasecmp(opt, "no-touch-required") == 0)
2028                 certflags_flags |= CERTOPT_NO_REQUIRE_USER_PRESENCE;
2029         else if (strcasecmp(opt, "no-verify-required") == 0)
2030                 certflags_flags &= ~CERTOPT_REQUIRE_VERIFY;
2031         else if (strcasecmp(opt, "verify-required") == 0)
2032                 certflags_flags |= CERTOPT_REQUIRE_VERIFY;
2033         else if (strncasecmp(opt, "force-command=", 14) == 0) {
2034                 val = opt + 14;
2035                 if (*val == '\0')
2036                         fatal("Empty force-command option");
2037                 if (certflags_command != NULL)
2038                         fatal("force-command already specified");
2039                 certflags_command = xstrdup(val);
2040         } else if (strncasecmp(opt, "source-address=", 15) == 0) {
2041                 val = opt + 15;
2042                 if (*val == '\0')
2043                         fatal("Empty source-address option");
2044                 if (certflags_src_addr != NULL)
2045                         fatal("source-address already specified");
2046                 if (addr_match_cidr_list(NULL, val) != 0)
2047                         fatal("Invalid source-address list");
2048                 certflags_src_addr = xstrdup(val);
2049         } else if (strncasecmp(opt, "extension:", 10) == 0 ||
2050                     (iscrit = (strncasecmp(opt, "critical:", 9) == 0))) {
2051                 val = xstrdup(strchr(opt, ':') + 1);
2052                 if ((cp = strchr(val, '=')) != NULL)
2053                         *cp++ = '\0';
2054                 cert_ext_add(val, cp, iscrit);
2055                 free(val);
2056         } else
2057                 fatal("Unsupported certificate option \"%s\"", opt);
2058 }
2059
2060 static void
2061 show_options(struct sshbuf *optbuf, int in_critical)
2062 {
2063         char *name, *arg, *hex;
2064         struct sshbuf *options, *option = NULL;
2065         int r;
2066
2067         if ((options = sshbuf_fromb(optbuf)) == NULL)
2068                 fatal_f("sshbuf_fromb failed");
2069         while (sshbuf_len(options) != 0) {
2070                 sshbuf_free(option);
2071                 option = NULL;
2072                 if ((r = sshbuf_get_cstring(options, &name, NULL)) != 0 ||
2073                     (r = sshbuf_froms(options, &option)) != 0)
2074                         fatal_fr(r, "parse option");
2075                 printf("                %s", name);
2076                 if (!in_critical &&
2077                     (strcmp(name, "permit-X11-forwarding") == 0 ||
2078                     strcmp(name, "permit-agent-forwarding") == 0 ||
2079                     strcmp(name, "permit-port-forwarding") == 0 ||
2080                     strcmp(name, "permit-pty") == 0 ||
2081                     strcmp(name, "permit-user-rc") == 0 ||
2082                     strcmp(name, "no-touch-required") == 0)) {
2083                         printf("\n");
2084                 } else if (in_critical &&
2085                     (strcmp(name, "force-command") == 0 ||
2086                     strcmp(name, "source-address") == 0)) {
2087                         if ((r = sshbuf_get_cstring(option, &arg, NULL)) != 0)
2088                                 fatal_fr(r, "parse critical");
2089                         printf(" %s\n", arg);
2090                         free(arg);
2091                 } else if (in_critical &&
2092                     strcmp(name, "verify-required") == 0) {
2093                         printf("\n");
2094                 } else if (sshbuf_len(option) > 0) {
2095                         hex = sshbuf_dtob16(option);
2096                         printf(" UNKNOWN OPTION: %s (len %zu)\n",
2097                             hex, sshbuf_len(option));
2098                         sshbuf_reset(option);
2099                         free(hex);
2100                 } else
2101                         printf(" UNKNOWN FLAG OPTION\n");
2102                 free(name);
2103                 if (sshbuf_len(option) != 0)
2104                         fatal("Option corrupt: extra data at end");
2105         }
2106         sshbuf_free(option);
2107         sshbuf_free(options);
2108 }
2109
2110 static void
2111 print_cert(struct sshkey *key)
2112 {
2113         char valid[64], *key_fp, *ca_fp;
2114         u_int i;
2115
2116         key_fp = sshkey_fingerprint(key, fingerprint_hash, SSH_FP_DEFAULT);
2117         ca_fp = sshkey_fingerprint(key->cert->signature_key,
2118             fingerprint_hash, SSH_FP_DEFAULT);
2119         if (key_fp == NULL || ca_fp == NULL)
2120                 fatal_f("sshkey_fingerprint fail");
2121         sshkey_format_cert_validity(key->cert, valid, sizeof(valid));
2122
2123         printf("        Type: %s %s certificate\n", sshkey_ssh_name(key),
2124             sshkey_cert_type(key));
2125         printf("        Public key: %s %s\n", sshkey_type(key), key_fp);
2126         printf("        Signing CA: %s %s (using %s)\n",
2127             sshkey_type(key->cert->signature_key), ca_fp,
2128             key->cert->signature_type);
2129         printf("        Key ID: \"%s\"\n", key->cert->key_id);
2130         printf("        Serial: %llu\n", (unsigned long long)key->cert->serial);
2131         printf("        Valid: %s\n", valid);
2132         printf("        Principals: ");
2133         if (key->cert->nprincipals == 0)
2134                 printf("(none)\n");
2135         else {
2136                 for (i = 0; i < key->cert->nprincipals; i++)
2137                         printf("\n                %s",
2138                             key->cert->principals[i]);
2139                 printf("\n");
2140         }
2141         printf("        Critical Options: ");
2142         if (sshbuf_len(key->cert->critical) == 0)
2143                 printf("(none)\n");
2144         else {
2145                 printf("\n");
2146                 show_options(key->cert->critical, 1);
2147         }
2148         printf("        Extensions: ");
2149         if (sshbuf_len(key->cert->extensions) == 0)
2150                 printf("(none)\n");
2151         else {
2152                 printf("\n");
2153                 show_options(key->cert->extensions, 0);
2154         }
2155 }
2156
2157 static void
2158 do_show_cert(struct passwd *pw)
2159 {
2160         struct sshkey *key = NULL;
2161         struct stat st;
2162         int r, is_stdin = 0, ok = 0;
2163         FILE *f;
2164         char *cp, *line = NULL;
2165         const char *path;
2166         size_t linesize = 0;
2167         u_long lnum = 0;
2168
2169         if (!have_identity)
2170                 ask_filename(pw, "Enter file in which the key is");
2171         if (strcmp(identity_file, "-") != 0 && stat(identity_file, &st) == -1)
2172                 fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
2173
2174         path = identity_file;
2175         if (strcmp(path, "-") == 0) {
2176                 f = stdin;
2177                 path = "(stdin)";
2178                 is_stdin = 1;
2179         } else if ((f = fopen(identity_file, "r")) == NULL)
2180                 fatal("fopen %s: %s", identity_file, strerror(errno));
2181
2182         while (getline(&line, &linesize, f) != -1) {
2183                 lnum++;
2184                 sshkey_free(key);
2185                 key = NULL;
2186                 /* Trim leading space and comments */
2187                 cp = line + strspn(line, " \t");
2188                 if (*cp == '#' || *cp == '\0')
2189                         continue;
2190                 if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
2191                         fatal("sshkey_new");
2192                 if ((r = sshkey_read(key, &cp)) != 0) {
2193                         error_r(r, "%s:%lu: invalid key", path, lnum);
2194                         continue;
2195                 }
2196                 if (!sshkey_is_cert(key)) {
2197                         error("%s:%lu is not a certificate", path, lnum);
2198                         continue;
2199                 }
2200                 ok = 1;
2201                 if (!is_stdin && lnum == 1)
2202                         printf("%s:\n", path);
2203                 else
2204                         printf("%s:%lu:\n", path, lnum);
2205                 print_cert(key);
2206         }
2207         free(line);
2208         sshkey_free(key);
2209         fclose(f);
2210         exit(ok ? 0 : 1);
2211 }
2212
2213 static void
2214 load_krl(const char *path, struct ssh_krl **krlp)
2215 {
2216         struct sshbuf *krlbuf;
2217         int r;
2218
2219         if ((r = sshbuf_load_file(path, &krlbuf)) != 0)
2220                 fatal_r(r, "Unable to load KRL %s", path);
2221         /* XXX check sigs */
2222         if ((r = ssh_krl_from_blob(krlbuf, krlp)) != 0 ||
2223             *krlp == NULL)
2224                 fatal_r(r, "Invalid KRL file %s", path);
2225         sshbuf_free(krlbuf);
2226 }
2227
2228 static void
2229 hash_to_blob(const char *cp, u_char **blobp, size_t *lenp,
2230     const char *file, u_long lnum)
2231 {
2232         char *tmp;
2233         size_t tlen;
2234         struct sshbuf *b;
2235         int r;
2236
2237         if (strncmp(cp, "SHA256:", 7) != 0)
2238                 fatal("%s:%lu: unsupported hash algorithm", file, lnum);
2239         cp += 7;
2240
2241         /*
2242          * OpenSSH base64 hashes omit trailing '='
2243          * characters; put them back for decode.
2244          */
2245         if ((tlen = strlen(cp)) >= SIZE_MAX - 5)
2246                 fatal_f("hash too long: %zu bytes", tlen);
2247         tmp = xmalloc(tlen + 4 + 1);
2248         strlcpy(tmp, cp, tlen + 1);
2249         while ((tlen % 4) != 0) {
2250                 tmp[tlen++] = '=';
2251                 tmp[tlen] = '\0';
2252         }
2253         if ((b = sshbuf_new()) == NULL)
2254                 fatal_f("sshbuf_new failed");
2255         if ((r = sshbuf_b64tod(b, tmp)) != 0)
2256                 fatal_r(r, "%s:%lu: decode hash failed", file, lnum);
2257         free(tmp);
2258         *lenp = sshbuf_len(b);
2259         *blobp = xmalloc(*lenp);
2260         memcpy(*blobp, sshbuf_ptr(b), *lenp);
2261         sshbuf_free(b);
2262 }
2263
2264 static void
2265 update_krl_from_file(struct passwd *pw, const char *file, int wild_ca,
2266     const struct sshkey *ca, struct ssh_krl *krl)
2267 {
2268         struct sshkey *key = NULL;
2269         u_long lnum = 0;
2270         char *path, *cp, *ep, *line = NULL;
2271         u_char *blob = NULL;
2272         size_t blen = 0, linesize = 0;
2273         unsigned long long serial, serial2;
2274         int i, was_explicit_key, was_sha1, was_sha256, was_hash, r;
2275         FILE *krl_spec;
2276
2277         path = tilde_expand_filename(file, pw->pw_uid);
2278         if (strcmp(path, "-") == 0) {
2279                 krl_spec = stdin;
2280                 free(path);
2281                 path = xstrdup("(standard input)");
2282         } else if ((krl_spec = fopen(path, "r")) == NULL)
2283                 fatal("fopen %s: %s", path, strerror(errno));
2284
2285         if (!quiet)
2286                 printf("Revoking from %s\n", path);
2287         while (getline(&line, &linesize, krl_spec) != -1) {
2288                 if (linesize >= INT_MAX) {
2289                         fatal_f("%s contains unparsable line, len=%zu",
2290                             path, linesize);
2291                 }
2292                 lnum++;
2293                 was_explicit_key = was_sha1 = was_sha256 = was_hash = 0;
2294                 cp = line + strspn(line, " \t");
2295                 /* Trim trailing space, comments and strip \n */
2296                 for (i = 0, r = -1; cp[i] != '\0'; i++) {
2297                         if (cp[i] == '#' || cp[i] == '\n') {
2298                                 cp[i] = '\0';
2299                                 break;
2300                         }
2301                         if (cp[i] == ' ' || cp[i] == '\t') {
2302                                 /* Remember the start of a span of whitespace */
2303                                 if (r == -1)
2304                                         r = i;
2305                         } else
2306                                 r = -1;
2307                 }
2308                 if (r != -1)
2309                         cp[r] = '\0';
2310                 if (*cp == '\0')
2311                         continue;
2312                 if (strncasecmp(cp, "serial:", 7) == 0) {
2313                         if (ca == NULL && !wild_ca) {
2314                                 fatal("revoking certificates by serial number "
2315                                     "requires specification of a CA key");
2316                         }
2317                         cp += 7;
2318                         cp = cp + strspn(cp, " \t");
2319                         errno = 0;
2320                         serial = strtoull(cp, &ep, 0);
2321                         if (*cp == '\0' || (*ep != '\0' && *ep != '-'))
2322                                 fatal("%s:%lu: invalid serial \"%s\"",
2323                                     path, lnum, cp);
2324                         if (errno == ERANGE && serial == ULLONG_MAX)
2325                                 fatal("%s:%lu: serial out of range",
2326                                     path, lnum);
2327                         serial2 = serial;
2328                         if (*ep == '-') {
2329                                 cp = ep + 1;
2330                                 errno = 0;
2331                                 serial2 = strtoull(cp, &ep, 0);
2332                                 if (*cp == '\0' || *ep != '\0')
2333                                         fatal("%s:%lu: invalid serial \"%s\"",
2334                                             path, lnum, cp);
2335                                 if (errno == ERANGE && serial2 == ULLONG_MAX)
2336                                         fatal("%s:%lu: serial out of range",
2337                                             path, lnum);
2338                                 if (serial2 <= serial)
2339                                         fatal("%s:%lu: invalid serial range "
2340                                             "%llu:%llu", path, lnum,
2341                                             (unsigned long long)serial,
2342                                             (unsigned long long)serial2);
2343                         }
2344                         if (ssh_krl_revoke_cert_by_serial_range(krl,
2345                             ca, serial, serial2) != 0) {
2346                                 fatal_f("revoke serial failed");
2347                         }
2348                 } else if (strncasecmp(cp, "id:", 3) == 0) {
2349                         if (ca == NULL && !wild_ca) {
2350                                 fatal("revoking certificates by key ID "
2351                                     "requires specification of a CA key");
2352                         }
2353                         cp += 3;
2354                         cp = cp + strspn(cp, " \t");
2355                         if (ssh_krl_revoke_cert_by_key_id(krl, ca, cp) != 0)
2356                                 fatal_f("revoke key ID failed");
2357                 } else if (strncasecmp(cp, "hash:", 5) == 0) {
2358                         cp += 5;
2359                         cp = cp + strspn(cp, " \t");
2360                         hash_to_blob(cp, &blob, &blen, file, lnum);
2361                         r = ssh_krl_revoke_key_sha256(krl, blob, blen);
2362                         if (r != 0)
2363                                 fatal_fr(r, "revoke key failed");
2364                 } else {
2365                         if (strncasecmp(cp, "key:", 4) == 0) {
2366                                 cp += 4;
2367                                 cp = cp + strspn(cp, " \t");
2368                                 was_explicit_key = 1;
2369                         } else if (strncasecmp(cp, "sha1:", 5) == 0) {
2370                                 cp += 5;
2371                                 cp = cp + strspn(cp, " \t");
2372                                 was_sha1 = 1;
2373                         } else if (strncasecmp(cp, "sha256:", 7) == 0) {
2374                                 cp += 7;
2375                                 cp = cp + strspn(cp, " \t");
2376                                 was_sha256 = 1;
2377                                 /*
2378                                  * Just try to process the line as a key.
2379                                  * Parsing will fail if it isn't.
2380                                  */
2381                         }
2382                         if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
2383                                 fatal("sshkey_new");
2384                         if ((r = sshkey_read(key, &cp)) != 0)
2385                                 fatal_r(r, "%s:%lu: invalid key", path, lnum);
2386                         if (was_explicit_key)
2387                                 r = ssh_krl_revoke_key_explicit(krl, key);
2388                         else if (was_sha1) {
2389                                 if (sshkey_fingerprint_raw(key,
2390                                     SSH_DIGEST_SHA1, &blob, &blen) != 0) {
2391                                         fatal("%s:%lu: fingerprint failed",
2392                                             file, lnum);
2393                                 }
2394                                 r = ssh_krl_revoke_key_sha1(krl, blob, blen);
2395                         } else if (was_sha256) {
2396                                 if (sshkey_fingerprint_raw(key,
2397                                     SSH_DIGEST_SHA256, &blob, &blen) != 0) {
2398                                         fatal("%s:%lu: fingerprint failed",
2399                                             file, lnum);
2400                                 }
2401                                 r = ssh_krl_revoke_key_sha256(krl, blob, blen);
2402                         } else
2403                                 r = ssh_krl_revoke_key(krl, key);
2404                         if (r != 0)
2405                                 fatal_fr(r, "revoke key failed");
2406                         freezero(blob, blen);
2407                         blob = NULL;
2408                         blen = 0;
2409                         sshkey_free(key);
2410                 }
2411         }
2412         if (strcmp(path, "-") != 0)
2413                 fclose(krl_spec);
2414         free(line);
2415         free(path);
2416 }
2417
2418 static void
2419 do_gen_krl(struct passwd *pw, int updating, const char *ca_key_path,
2420     unsigned long long krl_version, const char *krl_comment,
2421     int argc, char **argv)
2422 {
2423         struct ssh_krl *krl;
2424         struct stat sb;
2425         struct sshkey *ca = NULL;
2426         int i, r, wild_ca = 0;
2427         char *tmp;
2428         struct sshbuf *kbuf;
2429
2430         if (*identity_file == '\0')
2431                 fatal("KRL generation requires an output file");
2432         if (stat(identity_file, &sb) == -1) {
2433                 if (errno != ENOENT)
2434                         fatal("Cannot access KRL \"%s\": %s",
2435                             identity_file, strerror(errno));
2436                 if (updating)
2437                         fatal("KRL \"%s\" does not exist", identity_file);
2438         }
2439         if (ca_key_path != NULL) {
2440                 if (strcasecmp(ca_key_path, "none") == 0)
2441                         wild_ca = 1;
2442                 else {
2443                         tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
2444                         if ((r = sshkey_load_public(tmp, &ca, NULL)) != 0)
2445                                 fatal_r(r, "Cannot load CA public key %s", tmp);
2446                         free(tmp);
2447                 }
2448         }
2449
2450         if (updating)
2451                 load_krl(identity_file, &krl);
2452         else if ((krl = ssh_krl_init()) == NULL)
2453                 fatal("couldn't create KRL");
2454
2455         if (krl_version != 0)
2456                 ssh_krl_set_version(krl, krl_version);
2457         if (krl_comment != NULL)
2458                 ssh_krl_set_comment(krl, krl_comment);
2459
2460         for (i = 0; i < argc; i++)
2461                 update_krl_from_file(pw, argv[i], wild_ca, ca, krl);
2462
2463         if ((kbuf = sshbuf_new()) == NULL)
2464                 fatal("sshbuf_new failed");
2465         if (ssh_krl_to_blob(krl, kbuf) != 0)
2466                 fatal("Couldn't generate KRL");
2467         if ((r = sshbuf_write_file(identity_file, kbuf)) != 0)
2468                 fatal("write %s: %s", identity_file, strerror(errno));
2469         sshbuf_free(kbuf);
2470         ssh_krl_free(krl);
2471         sshkey_free(ca);
2472 }
2473
2474 static void
2475 do_check_krl(struct passwd *pw, int print_krl, int argc, char **argv)
2476 {
2477         int i, r, ret = 0;
2478         char *comment;
2479         struct ssh_krl *krl;
2480         struct sshkey *k;
2481
2482         if (*identity_file == '\0')
2483                 fatal("KRL checking requires an input file");
2484         load_krl(identity_file, &krl);
2485         if (print_krl)
2486                 krl_dump(krl, stdout);
2487         for (i = 0; i < argc; i++) {
2488                 if ((r = sshkey_load_public(argv[i], &k, &comment)) != 0)
2489                         fatal_r(r, "Cannot load public key %s", argv[i]);
2490                 r = ssh_krl_check_key(krl, k);
2491                 printf("%s%s%s%s: %s\n", argv[i],
2492                     *comment ? " (" : "", comment, *comment ? ")" : "",
2493                     r == 0 ? "ok" : "REVOKED");
2494                 if (r != 0)
2495                         ret = 1;
2496                 sshkey_free(k);
2497                 free(comment);
2498         }
2499         ssh_krl_free(krl);
2500         exit(ret);
2501 }
2502
2503 static struct sshkey *
2504 load_sign_key(const char *keypath, const struct sshkey *pubkey)
2505 {
2506         size_t i, slen, plen = strlen(keypath);
2507         char *privpath = xstrdup(keypath);
2508         static const char * const suffixes[] = { "-cert.pub", ".pub", NULL };
2509         struct sshkey *ret = NULL, *privkey = NULL;
2510         int r, waspub = 0;
2511         struct stat st;
2512
2513         /*
2514          * If passed a public key filename, then try to locate the corresponding
2515          * private key. This lets us specify certificates on the command-line
2516          * and have ssh-keygen find the appropriate private key.
2517          */
2518         for (i = 0; suffixes[i]; i++) {
2519                 slen = strlen(suffixes[i]);
2520                 if (plen <= slen ||
2521                     strcmp(privpath + plen - slen, suffixes[i]) != 0)
2522                         continue;
2523                 privpath[plen - slen] = '\0';
2524                 debug_f("%s looks like a public key, using private key "
2525                     "path %s instead", keypath, privpath);
2526                 waspub = 1;
2527         }
2528         if (waspub && stat(privpath, &st) != 0 && errno == ENOENT)
2529                 fatal("No private key found for public key \"%s\"", keypath);
2530         if ((r = sshkey_load_private(privpath, "", &privkey, NULL)) != 0 &&
2531             (r != SSH_ERR_KEY_WRONG_PASSPHRASE)) {
2532                 debug_fr(r, "load private key \"%s\"", privpath);
2533                 fatal("No private key found for \"%s\"", privpath);
2534         } else if (privkey == NULL)
2535                 privkey = load_identity(privpath, NULL);
2536
2537         if (!sshkey_equal_public(pubkey, privkey)) {
2538                 error("Public key %s doesn't match private %s",
2539                     keypath, privpath);
2540                 goto done;
2541         }
2542         if (sshkey_is_cert(pubkey) && !sshkey_is_cert(privkey)) {
2543                 /*
2544                  * Graft the certificate onto the private key to make
2545                  * it capable of signing.
2546                  */
2547                 if ((r = sshkey_to_certified(privkey)) != 0) {
2548                         error_fr(r, "sshkey_to_certified");
2549                         goto done;
2550                 }
2551                 if ((r = sshkey_cert_copy(pubkey, privkey)) != 0) {
2552                         error_fr(r, "sshkey_cert_copy");
2553                         goto done;
2554                 }
2555         }
2556         /* success */
2557         ret = privkey;
2558         privkey = NULL;
2559  done:
2560         sshkey_free(privkey);
2561         free(privpath);
2562         return ret;
2563 }
2564
2565 static int
2566 sign_one(struct sshkey *signkey, const char *filename, int fd,
2567     const char *sig_namespace, const char *hashalg, sshsig_signer *signer,
2568     void *signer_ctx)
2569 {
2570         struct sshbuf *sigbuf = NULL, *abuf = NULL;
2571         int r = SSH_ERR_INTERNAL_ERROR, wfd = -1, oerrno;
2572         char *wfile = NULL, *asig = NULL, *fp = NULL;
2573         char *pin = NULL, *prompt = NULL;
2574
2575         if (!quiet) {
2576                 if (fd == STDIN_FILENO)
2577                         fprintf(stderr, "Signing data on standard input\n");
2578                 else
2579                         fprintf(stderr, "Signing file %s\n", filename);
2580         }
2581         if (signer == NULL && sshkey_is_sk(signkey)) {
2582                 if ((signkey->sk_flags & SSH_SK_USER_VERIFICATION_REQD)) {
2583                         xasprintf(&prompt, "Enter PIN for %s key: ",
2584                             sshkey_type(signkey));
2585                         if ((pin = read_passphrase(prompt,
2586                             RP_ALLOW_STDIN)) == NULL)
2587                                 fatal_f("couldn't read PIN");
2588                 }
2589                 if ((signkey->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {
2590                         if ((fp = sshkey_fingerprint(signkey, fingerprint_hash,
2591                             SSH_FP_DEFAULT)) == NULL)
2592                                 fatal_f("fingerprint failed");
2593                         fprintf(stderr, "Confirm user presence for key %s %s\n",
2594                             sshkey_type(signkey), fp);
2595                         free(fp);
2596                 }
2597         }
2598         if ((r = sshsig_sign_fd(signkey, hashalg, sk_provider, pin,
2599             fd, sig_namespace, &sigbuf, signer, signer_ctx)) != 0) {
2600                 error_r(r, "Signing %s failed", filename);
2601                 goto out;
2602         }
2603         if ((r = sshsig_armor(sigbuf, &abuf)) != 0) {
2604                 error_fr(r, "sshsig_armor");
2605                 goto out;
2606         }
2607         if ((asig = sshbuf_dup_string(abuf)) == NULL) {
2608                 error_f("buffer error");
2609                 r = SSH_ERR_ALLOC_FAIL;
2610                 goto out;
2611         }
2612
2613         if (fd == STDIN_FILENO) {
2614                 fputs(asig, stdout);
2615                 fflush(stdout);
2616         } else {
2617                 xasprintf(&wfile, "%s.sig", filename);
2618                 if (confirm_overwrite(wfile)) {
2619                         if ((wfd = open(wfile, O_WRONLY|O_CREAT|O_TRUNC,
2620                             0666)) == -1) {
2621                                 oerrno = errno;
2622                                 error("Cannot open %s: %s",
2623                                     wfile, strerror(errno));
2624                                 errno = oerrno;
2625                                 r = SSH_ERR_SYSTEM_ERROR;
2626                                 goto out;
2627                         }
2628                         if (atomicio(vwrite, wfd, asig,
2629                             strlen(asig)) != strlen(asig)) {
2630                                 oerrno = errno;
2631                                 error("Cannot write to %s: %s",
2632                                     wfile, strerror(errno));
2633                                 errno = oerrno;
2634                                 r = SSH_ERR_SYSTEM_ERROR;
2635                                 goto out;
2636                         }
2637                         if (!quiet) {
2638                                 fprintf(stderr, "Write signature to %s\n",
2639                                     wfile);
2640                         }
2641                 }
2642         }
2643         /* success */
2644         r = 0;
2645  out:
2646         free(wfile);
2647         free(prompt);
2648         free(asig);
2649         if (pin != NULL)
2650                 freezero(pin, strlen(pin));
2651         sshbuf_free(abuf);
2652         sshbuf_free(sigbuf);
2653         if (wfd != -1)
2654                 close(wfd);
2655         return r;
2656 }
2657
2658 static int
2659 sig_process_opts(char * const *opts, size_t nopts, char **hashalgp,
2660     uint64_t *verify_timep, int *print_pubkey)
2661 {
2662         size_t i;
2663         time_t now;
2664
2665         if (verify_timep != NULL)
2666                 *verify_timep = 0;
2667         if (print_pubkey != NULL)
2668                 *print_pubkey = 0;
2669         if (hashalgp != NULL)
2670                 *hashalgp = NULL;
2671         for (i = 0; i < nopts; i++) {
2672                 if (hashalgp != NULL &&
2673                     strncasecmp(opts[i], "hashalg=", 8) == 0) {
2674                         *hashalgp = xstrdup(opts[i] + 8);
2675                 } else if (verify_timep &&
2676                     strncasecmp(opts[i], "verify-time=", 12) == 0) {
2677                         if (parse_absolute_time(opts[i] + 12,
2678                             verify_timep) != 0 || *verify_timep == 0) {
2679                                 error("Invalid \"verify-time\" option");
2680                                 return SSH_ERR_INVALID_ARGUMENT;
2681                         }
2682                 } else if (print_pubkey &&
2683                     strcasecmp(opts[i], "print-pubkey") == 0) {
2684                         *print_pubkey = 1;
2685                 } else {
2686                         error("Invalid option \"%s\"", opts[i]);
2687                         return SSH_ERR_INVALID_ARGUMENT;
2688                 }
2689         }
2690         if (verify_timep && *verify_timep == 0) {
2691                 if ((now = time(NULL)) < 0) {
2692                         error("Time is before epoch");
2693                         return SSH_ERR_INVALID_ARGUMENT;
2694                 }
2695                 *verify_timep = (uint64_t)now;
2696         }
2697         return 0;
2698 }
2699
2700
2701 static int
2702 sig_sign(const char *keypath, const char *sig_namespace, int require_agent,
2703     int argc, char **argv, char * const *opts, size_t nopts)
2704 {
2705         int i, fd = -1, r, ret = -1;
2706         int agent_fd = -1;
2707         struct sshkey *pubkey = NULL, *privkey = NULL, *signkey = NULL;
2708         sshsig_signer *signer = NULL;
2709         char *hashalg = NULL;
2710
2711         /* Check file arguments. */
2712         for (i = 0; i < argc; i++) {
2713                 if (strcmp(argv[i], "-") != 0)
2714                         continue;
2715                 if (i > 0 || argc > 1)
2716                         fatal("Cannot sign mix of paths and standard input");
2717         }
2718
2719         if (sig_process_opts(opts, nopts, &hashalg, NULL, NULL) != 0)
2720                 goto done; /* error already logged */
2721
2722         if ((r = sshkey_load_public(keypath, &pubkey, NULL)) != 0) {
2723                 error_r(r, "Couldn't load public key %s", keypath);
2724                 goto done;
2725         }
2726
2727         if ((r = ssh_get_authentication_socket(&agent_fd)) != 0) {
2728                 if (require_agent)
2729                         fatal("Couldn't get agent socket");
2730                 debug_r(r, "Couldn't get agent socket");
2731         } else {
2732                 if ((r = ssh_agent_has_key(agent_fd, pubkey)) == 0)
2733                         signer = agent_signer;
2734                 else {
2735                         if (require_agent)
2736                                 fatal("Couldn't find key in agent");
2737                         debug_r(r, "Couldn't find key in agent");
2738                 }
2739         }
2740
2741         if (signer == NULL) {
2742                 /* Not using agent - try to load private key */
2743                 if ((privkey = load_sign_key(keypath, pubkey)) == NULL)
2744                         goto done;
2745                 signkey = privkey;
2746         } else {
2747                 /* Will use key in agent */
2748                 signkey = pubkey;
2749         }
2750
2751         if (argc == 0) {
2752                 if ((r = sign_one(signkey, "(stdin)", STDIN_FILENO,
2753                     sig_namespace, hashalg, signer, &agent_fd)) != 0)
2754                         goto done;
2755         } else {
2756                 for (i = 0; i < argc; i++) {
2757                         if (strcmp(argv[i], "-") == 0)
2758                                 fd = STDIN_FILENO;
2759                         else if ((fd = open(argv[i], O_RDONLY)) == -1) {
2760                                 error("Cannot open %s for signing: %s",
2761                                     argv[i], strerror(errno));
2762                                 goto done;
2763                         }
2764                         if ((r = sign_one(signkey, argv[i], fd, sig_namespace,
2765                             hashalg, signer, &agent_fd)) != 0)
2766                                 goto done;
2767                         if (fd != STDIN_FILENO)
2768                                 close(fd);
2769                         fd = -1;
2770                 }
2771         }
2772
2773         ret = 0;
2774 done:
2775         if (fd != -1 && fd != STDIN_FILENO)
2776                 close(fd);
2777         sshkey_free(pubkey);
2778         sshkey_free(privkey);
2779         free(hashalg);
2780         return ret;
2781 }
2782
2783 static int
2784 sig_verify(const char *signature, const char *sig_namespace,
2785     const char *principal, const char *allowed_keys, const char *revoked_keys,
2786     char * const *opts, size_t nopts)
2787 {
2788         int r, ret = -1;
2789         int print_pubkey = 0;
2790         struct sshbuf *sigbuf = NULL, *abuf = NULL;
2791         struct sshkey *sign_key = NULL;
2792         char *fp = NULL;
2793         struct sshkey_sig_details *sig_details = NULL;
2794         uint64_t verify_time = 0;
2795
2796         if (sig_process_opts(opts, nopts, NULL, &verify_time,
2797             &print_pubkey) != 0)
2798                 goto done; /* error already logged */
2799
2800         memset(&sig_details, 0, sizeof(sig_details));
2801         if ((r = sshbuf_load_file(signature, &abuf)) != 0) {
2802                 error_r(r, "Couldn't read signature file");
2803                 goto done;
2804         }
2805
2806         if ((r = sshsig_dearmor(abuf, &sigbuf)) != 0) {
2807                 error_fr(r, "sshsig_armor");
2808                 goto done;
2809         }
2810         if ((r = sshsig_verify_fd(sigbuf, STDIN_FILENO, sig_namespace,
2811             &sign_key, &sig_details)) != 0)
2812                 goto done; /* sshsig_verify() prints error */
2813
2814         if ((fp = sshkey_fingerprint(sign_key, fingerprint_hash,
2815             SSH_FP_DEFAULT)) == NULL)
2816                 fatal_f("sshkey_fingerprint failed");
2817         debug("Valid (unverified) signature from key %s", fp);
2818         if (sig_details != NULL) {
2819                 debug2_f("signature details: counter = %u, flags = 0x%02x",
2820                     sig_details->sk_counter, sig_details->sk_flags);
2821         }
2822         free(fp);
2823         fp = NULL;
2824
2825         if (revoked_keys != NULL) {
2826                 if ((r = sshkey_check_revoked(sign_key, revoked_keys)) != 0) {
2827                         debug3_fr(r, "sshkey_check_revoked");
2828                         goto done;
2829                 }
2830         }
2831
2832         if (allowed_keys != NULL && (r = sshsig_check_allowed_keys(allowed_keys,
2833             sign_key, principal, sig_namespace, verify_time)) != 0) {
2834                 debug3_fr(r, "sshsig_check_allowed_keys");
2835                 goto done;
2836         }
2837         /* success */
2838         ret = 0;
2839 done:
2840         if (!quiet) {
2841                 if (ret == 0) {
2842                         if ((fp = sshkey_fingerprint(sign_key, fingerprint_hash,
2843                             SSH_FP_DEFAULT)) == NULL)
2844                                 fatal_f("sshkey_fingerprint failed");
2845                         if (principal == NULL) {
2846                                 printf("Good \"%s\" signature with %s key %s\n",
2847                                     sig_namespace, sshkey_type(sign_key), fp);
2848
2849                         } else {
2850                                 printf("Good \"%s\" signature for %s with %s key %s\n",
2851                                     sig_namespace, principal,
2852                                     sshkey_type(sign_key), fp);
2853                         }
2854                 } else {
2855                         printf("Could not verify signature.\n");
2856                 }
2857         }
2858         /* Print the signature key if requested */
2859         if (ret == 0 && print_pubkey && sign_key != NULL) {
2860                 if ((r = sshkey_write(sign_key, stdout)) == 0)
2861                         fputc('\n', stdout);
2862                 else {
2863                         error_r(r, "Could not print public key.\n");
2864                         ret = -1;
2865                 }
2866         }
2867         sshbuf_free(sigbuf);
2868         sshbuf_free(abuf);
2869         sshkey_free(sign_key);
2870         sshkey_sig_details_free(sig_details);
2871         free(fp);
2872         return ret;
2873 }
2874
2875 static int
2876 sig_find_principals(const char *signature, const char *allowed_keys,
2877     char * const *opts, size_t nopts)
2878 {
2879         int r, ret = -1;
2880         struct sshbuf *sigbuf = NULL, *abuf = NULL;
2881         struct sshkey *sign_key = NULL;
2882         char *principals = NULL, *cp, *tmp;
2883         uint64_t verify_time = 0;
2884
2885         if (sig_process_opts(opts, nopts, NULL, &verify_time, NULL) != 0)
2886                 goto done; /* error already logged */
2887
2888         if ((r = sshbuf_load_file(signature, &abuf)) != 0) {
2889                 error_r(r, "Couldn't read signature file");
2890                 goto done;
2891         }
2892         if ((r = sshsig_dearmor(abuf, &sigbuf)) != 0) {
2893                 error_fr(r, "sshsig_armor");
2894                 goto done;
2895         }
2896         if ((r = sshsig_get_pubkey(sigbuf, &sign_key)) != 0) {
2897                 error_fr(r, "sshsig_get_pubkey");
2898                 goto done;
2899         }
2900         if ((r = sshsig_find_principals(allowed_keys, sign_key,
2901             verify_time, &principals)) != 0) {
2902                 if (r != SSH_ERR_KEY_NOT_FOUND)
2903                         error_fr(r, "sshsig_find_principal");
2904                 goto done;
2905         }
2906         ret = 0;
2907 done:
2908         if (ret == 0 ) {
2909                 /* Emit matching principals one per line */
2910                 tmp = principals;
2911                 while ((cp = strsep(&tmp, ",")) != NULL && *cp != '\0')
2912                         puts(cp);
2913         } else {
2914                 fprintf(stderr, "No principal matched.\n");
2915         }
2916         sshbuf_free(sigbuf);
2917         sshbuf_free(abuf);
2918         sshkey_free(sign_key);
2919         free(principals);
2920         return ret;
2921 }
2922
2923 static int
2924 sig_match_principals(const char *allowed_keys, char *principal,
2925         char * const *opts, size_t nopts)
2926 {
2927         int r;
2928         char **principals = NULL;
2929         size_t i, nprincipals = 0;
2930
2931         if ((r = sig_process_opts(opts, nopts, NULL, NULL, NULL)) != 0)
2932                 return r; /* error already logged */
2933
2934         if ((r = sshsig_match_principals(allowed_keys, principal,
2935             &principals, &nprincipals)) != 0) {
2936                 debug_f("match: %s", ssh_err(r));
2937                 fprintf(stderr, "No principal matched.\n");
2938                 return r;
2939         }
2940         for (i = 0; i < nprincipals; i++) {
2941                 printf("%s\n", principals[i]);
2942                 free(principals[i]);
2943         }
2944         free(principals);
2945
2946         return 0;
2947 }
2948
2949 static void
2950 do_moduli_gen(const char *out_file, char **opts, size_t nopts)
2951 {
2952 #ifdef WITH_OPENSSL
2953         /* Moduli generation/screening */
2954         u_int32_t memory = 0;
2955         BIGNUM *start = NULL;
2956         int moduli_bits = 0;
2957         FILE *out;
2958         size_t i;
2959         const char *errstr;
2960
2961         /* Parse options */
2962         for (i = 0; i < nopts; i++) {
2963                 if (strncmp(opts[i], "memory=", 7) == 0) {
2964                         memory = (u_int32_t)strtonum(opts[i]+7, 1,
2965                             UINT_MAX, &errstr);
2966                         if (errstr) {
2967                                 fatal("Memory limit is %s: %s",
2968                                     errstr, opts[i]+7);
2969                         }
2970                 } else if (strncmp(opts[i], "start=", 6) == 0) {
2971                         /* XXX - also compare length against bits */
2972                         if (BN_hex2bn(&start, opts[i]+6) == 0)
2973                                 fatal("Invalid start point.");
2974                 } else if (strncmp(opts[i], "bits=", 5) == 0) {
2975                         moduli_bits = (int)strtonum(opts[i]+5, 1,
2976                             INT_MAX, &errstr);
2977                         if (errstr) {
2978                                 fatal("Invalid number: %s (%s)",
2979                                         opts[i]+12, errstr);
2980                         }
2981                 } else {
2982                         fatal("Option \"%s\" is unsupported for moduli "
2983                             "generation", opts[i]);
2984                 }
2985         }
2986
2987         if ((out = fopen(out_file, "w")) == NULL) {
2988                 fatal("Couldn't open modulus candidate file \"%s\": %s",
2989                     out_file, strerror(errno));
2990         }
2991         setvbuf(out, NULL, _IOLBF, 0);
2992
2993         if (moduli_bits == 0)
2994                 moduli_bits = DEFAULT_BITS;
2995         if (gen_candidates(out, memory, moduli_bits, start) != 0)
2996                 fatal("modulus candidate generation failed");
2997 #else /* WITH_OPENSSL */
2998         fatal("Moduli generation is not supported");
2999 #endif /* WITH_OPENSSL */
3000 }
3001
3002 static void
3003 do_moduli_screen(const char *out_file, char **opts, size_t nopts)
3004 {
3005 #ifdef WITH_OPENSSL
3006         /* Moduli generation/screening */
3007         char *checkpoint = NULL;
3008         u_int32_t generator_wanted = 0;
3009         unsigned long start_lineno = 0, lines_to_process = 0;
3010         int prime_tests = 0;
3011         FILE *out, *in = stdin;
3012         size_t i;
3013         const char *errstr;
3014
3015         /* Parse options */
3016         for (i = 0; i < nopts; i++) {
3017                 if (strncmp(opts[i], "lines=", 6) == 0) {
3018                         lines_to_process = strtoul(opts[i]+6, NULL, 10);
3019                 } else if (strncmp(opts[i], "start-line=", 11) == 0) {
3020                         start_lineno = strtoul(opts[i]+11, NULL, 10);
3021                 } else if (strncmp(opts[i], "checkpoint=", 11) == 0) {
3022                         free(checkpoint);
3023                         checkpoint = xstrdup(opts[i]+11);
3024                 } else if (strncmp(opts[i], "generator=", 10) == 0) {
3025                         generator_wanted = (u_int32_t)strtonum(
3026                             opts[i]+10, 1, UINT_MAX, &errstr);
3027                         if (errstr != NULL) {
3028                                 fatal("Generator invalid: %s (%s)",
3029                                     opts[i]+10, errstr);
3030                         }
3031                 } else if (strncmp(opts[i], "prime-tests=", 12) == 0) {
3032                         prime_tests = (int)strtonum(opts[i]+12, 1,
3033                             INT_MAX, &errstr);
3034                         if (errstr) {
3035                                 fatal("Invalid number: %s (%s)",
3036                                         opts[i]+12, errstr);
3037                         }
3038                 } else {
3039                         fatal("Option \"%s\" is unsupported for moduli "
3040                             "screening", opts[i]);
3041                 }
3042         }
3043
3044         if (have_identity && strcmp(identity_file, "-") != 0) {
3045                 if ((in = fopen(identity_file, "r")) == NULL) {
3046                         fatal("Couldn't open modulus candidate "
3047                             "file \"%s\": %s", identity_file,
3048                             strerror(errno));
3049                 }
3050         }
3051
3052         if ((out = fopen(out_file, "a")) == NULL) {
3053                 fatal("Couldn't open moduli file \"%s\": %s",
3054                     out_file, strerror(errno));
3055         }
3056         setvbuf(out, NULL, _IOLBF, 0);
3057         if (prime_test(in, out, prime_tests == 0 ? 100 : prime_tests,
3058             generator_wanted, checkpoint,
3059             start_lineno, lines_to_process) != 0)
3060                 fatal("modulus screening failed");
3061         if (in != stdin)
3062                 (void)fclose(in);
3063         free(checkpoint);
3064 #else /* WITH_OPENSSL */
3065         fatal("Moduli screening is not supported");
3066 #endif /* WITH_OPENSSL */
3067 }
3068
3069 /* Read and confirm a passphrase */
3070 static char *
3071 read_check_passphrase(const char *prompt1, const char *prompt2,
3072     const char *retry_prompt)
3073 {
3074         char *passphrase1, *passphrase2;
3075
3076         for (;;) {
3077                 passphrase1 = read_passphrase(prompt1, RP_ALLOW_STDIN);
3078                 passphrase2 = read_passphrase(prompt2, RP_ALLOW_STDIN);
3079                 if (strcmp(passphrase1, passphrase2) == 0) {
3080                         freezero(passphrase2, strlen(passphrase2));
3081                         return passphrase1;
3082                 }
3083                 /* The passphrases do not match. Clear them and retry. */
3084                 freezero(passphrase1, strlen(passphrase1));
3085                 freezero(passphrase2, strlen(passphrase2));
3086                 fputs(retry_prompt, stdout);
3087                 fputc('\n', stdout);
3088                 fflush(stdout);
3089         }
3090         /* NOTREACHED */
3091         return NULL;
3092 }
3093
3094 static char *
3095 private_key_passphrase(void)
3096 {
3097         if (identity_passphrase)
3098                 return xstrdup(identity_passphrase);
3099         if (identity_new_passphrase)
3100                 return xstrdup(identity_new_passphrase);
3101
3102         return read_check_passphrase(
3103             "Enter passphrase (empty for no passphrase): ",
3104             "Enter same passphrase again: ",
3105             "Passphrases do not match.  Try again.");
3106 }
3107
3108 static char *
3109 sk_suffix(const char *application, const uint8_t *user, size_t userlen)
3110 {
3111         char *ret, *cp;
3112         size_t slen, i;
3113
3114         /* Trim off URL-like preamble */
3115         if (strncmp(application, "ssh://", 6) == 0)
3116                 ret =  xstrdup(application + 6);
3117         else if (strncmp(application, "ssh:", 4) == 0)
3118                 ret =  xstrdup(application + 4);
3119         else
3120                 ret = xstrdup(application);
3121
3122         /* Count trailing zeros in user */
3123         for (i = 0; i < userlen; i++) {
3124                 if (user[userlen - i - 1] != 0)
3125                         break;
3126         }
3127         if (i >= userlen)
3128                 return ret; /* user-id was default all-zeros */
3129
3130         /* Append user-id, escaping non-UTF-8 characters */
3131         slen = userlen - i;
3132         if (asmprintf(&cp, INT_MAX, NULL, "%.*s", (int)slen, user) == -1)
3133                 fatal_f("asmprintf failed");
3134         /* Don't emit a user-id that contains path or control characters */
3135         if (strchr(cp, '/') != NULL || strstr(cp, "..") != NULL ||
3136             strchr(cp, '\\') != NULL) {
3137                 free(cp);
3138                 cp = tohex(user, slen);
3139         }
3140         xextendf(&ret, "_", "%s", cp);
3141         free(cp);
3142         return ret;
3143 }
3144
3145 static int
3146 do_download_sk(const char *skprovider, const char *device)
3147 {
3148         struct sshsk_resident_key **srks;
3149         size_t nsrks, i;
3150         int r, ret = -1;
3151         char *fp, *pin = NULL, *pass = NULL, *path, *pubpath;
3152         const char *ext;
3153         struct sshkey *key;
3154
3155         if (skprovider == NULL)
3156                 fatal("Cannot download keys without provider");
3157
3158         pin = read_passphrase("Enter PIN for authenticator: ", RP_ALLOW_STDIN);
3159         if (!quiet) {
3160                 printf("You may need to touch your authenticator "
3161                     "to authorize key download.\n");
3162         }
3163         if ((r = sshsk_load_resident(skprovider, device, pin, 0,
3164             &srks, &nsrks)) != 0) {
3165                 if (pin != NULL)
3166                         freezero(pin, strlen(pin));
3167                 error_r(r, "Unable to load resident keys");
3168                 return -1;
3169         }
3170         if (nsrks == 0)
3171                 logit("No keys to download");
3172         if (pin != NULL)
3173                 freezero(pin, strlen(pin));
3174
3175         for (i = 0; i < nsrks; i++) {
3176                 key = srks[i]->key;
3177                 if (key->type != KEY_ECDSA_SK && key->type != KEY_ED25519_SK) {
3178                         error("Unsupported key type %s (%d)",
3179                             sshkey_type(key), key->type);
3180                         continue;
3181                 }
3182                 if ((fp = sshkey_fingerprint(key, fingerprint_hash,
3183                     SSH_FP_DEFAULT)) == NULL)
3184                         fatal_f("sshkey_fingerprint failed");
3185                 debug_f("key %zu: %s %s %s (flags 0x%02x)", i,
3186                     sshkey_type(key), fp, key->sk_application, key->sk_flags);
3187                 ext = sk_suffix(key->sk_application,
3188                     srks[i]->user_id, srks[i]->user_id_len);
3189                 xasprintf(&path, "id_%s_rk%s%s",
3190                     key->type == KEY_ECDSA_SK ? "ecdsa_sk" : "ed25519_sk",
3191                     *ext == '\0' ? "" : "_", ext);
3192
3193                 /* If the file already exists, ask the user to confirm. */
3194                 if (!confirm_overwrite(path)) {
3195                         free(path);
3196                         break;
3197                 }
3198
3199                 /* Save the key with the application string as the comment */
3200                 if (pass == NULL)
3201                         pass = private_key_passphrase();
3202                 if ((r = sshkey_save_private(key, path, pass,
3203                     key->sk_application, private_key_format,
3204                     openssh_format_cipher, rounds)) != 0) {
3205                         error_r(r, "Saving key \"%s\" failed", path);
3206                         free(path);
3207                         break;
3208                 }
3209                 if (!quiet) {
3210                         printf("Saved %s key%s%s to %s\n", sshkey_type(key),
3211                             *ext != '\0' ? " " : "",
3212                             *ext != '\0' ? key->sk_application : "",
3213                             path);
3214                 }
3215
3216                 /* Save public key too */
3217                 xasprintf(&pubpath, "%s.pub", path);
3218                 free(path);
3219                 if ((r = sshkey_save_public(key, pubpath,
3220                     key->sk_application)) != 0) {
3221                         error_r(r, "Saving public key \"%s\" failed", pubpath);
3222                         free(pubpath);
3223                         break;
3224                 }
3225                 free(pubpath);
3226         }
3227
3228         if (i >= nsrks)
3229                 ret = 0; /* success */
3230         if (pass != NULL)
3231                 freezero(pass, strlen(pass));
3232         sshsk_free_resident_keys(srks, nsrks);
3233         return ret;
3234 }
3235
3236 static void
3237 save_attestation(struct sshbuf *attest, const char *path)
3238 {
3239         mode_t omask;
3240         int r;
3241
3242         if (path == NULL)
3243                 return; /* nothing to do */
3244         if (attest == NULL || sshbuf_len(attest) == 0)
3245                 fatal("Enrollment did not return attestation data");
3246         omask = umask(077);
3247         r = sshbuf_write_file(path, attest);
3248         umask(omask);
3249         if (r != 0)
3250                 fatal_r(r, "Unable to write attestation data \"%s\"", path);
3251         if (!quiet)
3252                 printf("Your FIDO attestation certificate has been saved in "
3253                     "%s\n", path);
3254 }
3255
3256 static int
3257 confirm_sk_overwrite(const char *application, const char *user)
3258 {
3259         char yesno[3];
3260
3261         printf("A resident key scoped to '%s' with user id '%s' already "
3262             "exists.\n", application == NULL ? "ssh:" : application,
3263             user == NULL ? "null" : user);
3264         printf("Overwrite key in token (y/n)? ");
3265         fflush(stdout);
3266         if (fgets(yesno, sizeof(yesno), stdin) == NULL)
3267                 return 0;
3268         if (yesno[0] != 'y' && yesno[0] != 'Y')
3269                 return 0;
3270         return 1;
3271 }
3272
3273 static void
3274 usage(void)
3275 {
3276         fprintf(stderr,
3277             "usage: ssh-keygen [-q] [-a rounds] [-b bits] [-C comment] [-f output_keyfile]\n"
3278             "                  [-m format] [-N new_passphrase] [-O option]\n"
3279             "                  [-t dsa | ecdsa | ecdsa-sk | ed25519 | ed25519-sk | rsa]\n"
3280             "                  [-w provider] [-Z cipher]\n"
3281             "       ssh-keygen -p [-a rounds] [-f keyfile] [-m format] [-N new_passphrase]\n"
3282             "                   [-P old_passphrase] [-Z cipher]\n"
3283 #ifdef WITH_OPENSSL
3284             "       ssh-keygen -i [-f input_keyfile] [-m key_format]\n"
3285             "       ssh-keygen -e [-f input_keyfile] [-m key_format]\n"
3286 #endif
3287             "       ssh-keygen -y [-f input_keyfile]\n"
3288             "       ssh-keygen -c [-a rounds] [-C comment] [-f keyfile] [-P passphrase]\n"
3289             "       ssh-keygen -l [-v] [-E fingerprint_hash] [-f input_keyfile]\n"
3290             "       ssh-keygen -B [-f input_keyfile]\n");
3291 #ifdef ENABLE_PKCS11
3292         fprintf(stderr,
3293             "       ssh-keygen -D pkcs11\n");
3294 #endif
3295         fprintf(stderr,
3296             "       ssh-keygen -F hostname [-lv] [-f known_hosts_file]\n"
3297             "       ssh-keygen -H [-f known_hosts_file]\n"
3298             "       ssh-keygen -K [-a rounds] [-w provider]\n"
3299             "       ssh-keygen -R hostname [-f known_hosts_file]\n"
3300             "       ssh-keygen -r hostname [-g] [-f input_keyfile]\n"
3301 #ifdef WITH_OPENSSL
3302             "       ssh-keygen -M generate [-O option] output_file\n"
3303             "       ssh-keygen -M screen [-f input_file] [-O option] output_file\n"
3304 #endif
3305             "       ssh-keygen -I certificate_identity -s ca_key [-hU] [-D pkcs11_provider]\n"
3306             "                  [-n principals] [-O option] [-V validity_interval]\n"
3307             "                  [-z serial_number] file ...\n"
3308             "       ssh-keygen -L [-f input_keyfile]\n"
3309             "       ssh-keygen -A [-a rounds] [-f prefix_path]\n"
3310             "       ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number]\n"
3311             "                  file ...\n"
3312             "       ssh-keygen -Q [-l] -f krl_file [file ...]\n"
3313             "       ssh-keygen -Y find-principals -s signature_file -f allowed_signers_file\n"
3314             "       ssh-keygen -Y match-principals -I signer_identity -f allowed_signers_file\n"
3315             "       ssh-keygen -Y check-novalidate -n namespace -s signature_file\n"
3316             "       ssh-keygen -Y sign -f key_file -n namespace file [-O option] ...\n"
3317             "       ssh-keygen -Y verify -f allowed_signers_file -I signer_identity\n"
3318             "                  -n namespace -s signature_file [-r krl_file] [-O option]\n");
3319         exit(1);
3320 }
3321
3322 /*
3323  * Main program for key management.
3324  */
3325 int
3326 main(int argc, char **argv)
3327 {
3328         char comment[1024], *passphrase = NULL;
3329         char *rr_hostname = NULL, *ep, *fp, *ra;
3330         struct sshkey *private, *public;
3331         struct passwd *pw;
3332         int r, opt, type;
3333         int change_passphrase = 0, change_comment = 0, show_cert = 0;
3334         int find_host = 0, delete_host = 0, hash_hosts = 0;
3335         int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0;
3336         int prefer_agent = 0, convert_to = 0, convert_from = 0;
3337         int print_public = 0, print_generic = 0, cert_serial_autoinc = 0;
3338         int do_gen_candidates = 0, do_screen_candidates = 0, download_sk = 0;
3339         unsigned long long cert_serial = 0;
3340         char *identity_comment = NULL, *ca_key_path = NULL, **opts = NULL;
3341         char *sk_application = NULL, *sk_device = NULL, *sk_user = NULL;
3342         char *sk_attestation_path = NULL;
3343         struct sshbuf *challenge = NULL, *attest = NULL;
3344         size_t i, nopts = 0;
3345         u_int32_t bits = 0;
3346         uint8_t sk_flags = SSH_SK_USER_PRESENCE_REQD;
3347         const char *errstr;
3348         int log_level = SYSLOG_LEVEL_INFO;
3349         char *sign_op = NULL;
3350
3351         extern int optind;
3352         extern char *optarg;
3353
3354         /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
3355         sanitise_stdfd();
3356
3357         __progname = ssh_get_progname(argv[0]);
3358
3359         seed_rng();
3360
3361         log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);
3362
3363         msetlocale();
3364
3365         /* we need this for the home * directory.  */
3366         pw = getpwuid(getuid());
3367         if (!pw)
3368                 fatal("No user exists for uid %lu", (u_long)getuid());
3369         pw = pwcopy(pw);
3370         if (gethostname(hostname, sizeof(hostname)) == -1)
3371                 fatal("gethostname: %s", strerror(errno));
3372
3373         sk_provider = getenv("SSH_SK_PROVIDER");
3374
3375         /* Remaining characters: dGjJSTWx */
3376         while ((opt = getopt(argc, argv, "ABHKLQUXceghiklopquvy"
3377             "C:D:E:F:I:M:N:O:P:R:V:Y:Z:"
3378             "a:b:f:g:m:n:r:s:t:w:z:")) != -1) {
3379                 switch (opt) {
3380                 case 'A':
3381                         gen_all_hostkeys = 1;
3382                         break;
3383                 case 'b':
3384                         bits = (u_int32_t)strtonum(optarg, 1, UINT32_MAX,
3385                             &errstr);
3386                         if (errstr)
3387                                 fatal("Bits has bad value %s (%s)",
3388                                         optarg, errstr);
3389                         break;
3390                 case 'E':
3391                         fingerprint_hash = ssh_digest_alg_by_name(optarg);
3392                         if (fingerprint_hash == -1)
3393                                 fatal("Invalid hash algorithm \"%s\"", optarg);
3394                         break;
3395                 case 'F':
3396                         find_host = 1;
3397                         rr_hostname = optarg;
3398                         break;
3399                 case 'H':
3400                         hash_hosts = 1;
3401                         break;
3402                 case 'I':
3403                         cert_key_id = optarg;
3404                         break;
3405                 case 'R':
3406                         delete_host = 1;
3407                         rr_hostname = optarg;
3408                         break;
3409                 case 'L':
3410                         show_cert = 1;
3411                         break;
3412                 case 'l':
3413                         print_fingerprint = 1;
3414                         break;
3415                 case 'B':
3416                         print_bubblebabble = 1;
3417                         break;
3418                 case 'm':
3419                         if (strcasecmp(optarg, "RFC4716") == 0 ||
3420                             strcasecmp(optarg, "ssh2") == 0) {
3421                                 convert_format = FMT_RFC4716;
3422                                 break;
3423                         }
3424                         if (strcasecmp(optarg, "PKCS8") == 0) {
3425                                 convert_format = FMT_PKCS8;
3426                                 private_key_format = SSHKEY_PRIVATE_PKCS8;
3427                                 break;
3428                         }
3429                         if (strcasecmp(optarg, "PEM") == 0) {
3430                                 convert_format = FMT_PEM;
3431                                 private_key_format = SSHKEY_PRIVATE_PEM;
3432                                 break;
3433                         }
3434                         fatal("Unsupported conversion format \"%s\"", optarg);
3435                 case 'n':
3436                         cert_principals = optarg;
3437                         break;
3438                 case 'o':
3439                         /* no-op; new format is already the default */
3440                         break;
3441                 case 'p':
3442                         change_passphrase = 1;
3443                         break;
3444                 case 'c':
3445                         change_comment = 1;
3446                         break;
3447                 case 'f':
3448                         if (strlcpy(identity_file, optarg,
3449                             sizeof(identity_file)) >= sizeof(identity_file))
3450                                 fatal("Identity filename too long");
3451                         have_identity = 1;
3452                         break;
3453                 case 'g':
3454                         print_generic = 1;
3455                         break;
3456                 case 'K':
3457                         download_sk = 1;
3458                         break;
3459                 case 'P':
3460                         identity_passphrase = optarg;
3461                         break;
3462                 case 'N':
3463                         identity_new_passphrase = optarg;
3464                         break;
3465                 case 'Q':
3466                         check_krl = 1;
3467                         break;
3468                 case 'O':
3469                         opts = xrecallocarray(opts, nopts, nopts + 1,
3470                             sizeof(*opts));
3471                         opts[nopts++] = xstrdup(optarg);
3472                         break;
3473                 case 'Z':
3474                         openssh_format_cipher = optarg;
3475                         if (cipher_by_name(openssh_format_cipher) == NULL)
3476                                 fatal("Invalid OpenSSH-format cipher '%s'",
3477                                     openssh_format_cipher);
3478                         break;
3479                 case 'C':
3480                         identity_comment = optarg;
3481                         break;
3482                 case 'q':
3483                         quiet = 1;
3484                         break;
3485                 case 'e':
3486                         /* export key */
3487                         convert_to = 1;
3488                         break;
3489                 case 'h':
3490                         cert_key_type = SSH2_CERT_TYPE_HOST;
3491                         certflags_flags = 0;
3492                         break;
3493                 case 'k':
3494                         gen_krl = 1;
3495                         break;
3496                 case 'i':
3497                 case 'X':
3498                         /* import key */
3499                         convert_from = 1;
3500                         break;
3501                 case 'y':
3502                         print_public = 1;
3503                         break;
3504                 case 's':
3505                         ca_key_path = optarg;
3506                         break;
3507                 case 't':
3508                         key_type_name = optarg;
3509                         break;
3510                 case 'D':
3511                         pkcs11provider = optarg;
3512                         break;
3513                 case 'U':
3514                         prefer_agent = 1;
3515                         break;
3516                 case 'u':
3517                         update_krl = 1;
3518                         break;
3519                 case 'v':
3520                         if (log_level == SYSLOG_LEVEL_INFO)
3521                                 log_level = SYSLOG_LEVEL_DEBUG1;
3522                         else {
3523                                 if (log_level >= SYSLOG_LEVEL_DEBUG1 &&
3524                                     log_level < SYSLOG_LEVEL_DEBUG3)
3525                                         log_level++;
3526                         }
3527                         break;
3528                 case 'r':
3529                         rr_hostname = optarg;
3530                         break;
3531                 case 'a':
3532                         rounds = (int)strtonum(optarg, 1, INT_MAX, &errstr);
3533                         if (errstr)
3534                                 fatal("Invalid number: %s (%s)",
3535                                         optarg, errstr);
3536                         break;
3537                 case 'V':
3538                         parse_cert_times(optarg);
3539                         break;
3540                 case 'Y':
3541                         sign_op = optarg;
3542                         break;
3543                 case 'w':
3544                         sk_provider = optarg;
3545                         break;
3546                 case 'z':
3547                         errno = 0;
3548                         if (*optarg == '+') {
3549                                 cert_serial_autoinc = 1;
3550                                 optarg++;
3551                         }
3552                         cert_serial = strtoull(optarg, &ep, 10);
3553                         if (*optarg < '0' || *optarg > '9' || *ep != '\0' ||
3554                             (errno == ERANGE && cert_serial == ULLONG_MAX))
3555                                 fatal("Invalid serial number \"%s\"", optarg);
3556                         break;
3557                 case 'M':
3558                         if (strcmp(optarg, "generate") == 0)
3559                                 do_gen_candidates = 1;
3560                         else if (strcmp(optarg, "screen") == 0)
3561                                 do_screen_candidates = 1;
3562                         else
3563                                 fatal("Unsupported moduli option %s", optarg);
3564                         break;
3565                 default:
3566                         usage();
3567                 }
3568         }
3569
3570 #ifdef ENABLE_SK_INTERNAL
3571         if (sk_provider == NULL)
3572                 sk_provider = "internal";
3573 #endif
3574
3575         /* reinit */
3576         log_init(argv[0], log_level, SYSLOG_FACILITY_USER, 1);
3577
3578         argv += optind;
3579         argc -= optind;
3580
3581         if (sign_op != NULL) {
3582                 if (strncmp(sign_op, "find-principals", 15) == 0) {
3583                         if (ca_key_path == NULL) {
3584                                 error("Too few arguments for find-principals:"
3585                                     "missing signature file");
3586                                 exit(1);
3587                         }
3588                         if (!have_identity) {
3589                                 error("Too few arguments for find-principals:"
3590                                     "missing allowed keys file");
3591                                 exit(1);
3592                         }
3593                         return sig_find_principals(ca_key_path, identity_file,
3594                             opts, nopts);
3595                 } else if (strncmp(sign_op, "match-principals", 16) == 0) {
3596                         if (!have_identity) {
3597                                 error("Too few arguments for match-principals:"
3598                                     "missing allowed keys file");
3599                                 exit(1);
3600                         }
3601                         if (cert_key_id == NULL) {
3602                                 error("Too few arguments for match-principals: "
3603                                     "missing principal ID");
3604                                 exit(1);
3605                         }
3606                         return sig_match_principals(identity_file, cert_key_id,
3607                             opts, nopts);
3608                 } else if (strncmp(sign_op, "sign", 4) == 0) {
3609                         /* NB. cert_principals is actually namespace, via -n */
3610                         if (cert_principals == NULL ||
3611                             *cert_principals == '\0') {
3612                                 error("Too few arguments for sign: "
3613                                     "missing namespace");
3614                                 exit(1);
3615                         }
3616                         if (!have_identity) {
3617                                 error("Too few arguments for sign: "
3618                                     "missing key");
3619                                 exit(1);
3620                         }
3621                         return sig_sign(identity_file, cert_principals,
3622                             prefer_agent, argc, argv, opts, nopts);
3623                 } else if (strncmp(sign_op, "check-novalidate", 16) == 0) {
3624                         /* NB. cert_principals is actually namespace, via -n */
3625                         if (cert_principals == NULL ||
3626                             *cert_principals == '\0') {
3627                                 error("Too few arguments for check-novalidate: "
3628                                     "missing namespace");
3629                                 exit(1);
3630                         }
3631                         if (ca_key_path == NULL) {
3632                                 error("Too few arguments for check-novalidate: "
3633                                     "missing signature file");
3634                                 exit(1);
3635                         }
3636                         return sig_verify(ca_key_path, cert_principals,
3637                             NULL, NULL, NULL, opts, nopts);
3638                 } else if (strncmp(sign_op, "verify", 6) == 0) {
3639                         /* NB. cert_principals is actually namespace, via -n */
3640                         if (cert_principals == NULL ||
3641                             *cert_principals == '\0') {
3642                                 error("Too few arguments for verify: "
3643                                     "missing namespace");
3644                                 exit(1);
3645                         }
3646                         if (ca_key_path == NULL) {
3647                                 error("Too few arguments for verify: "
3648                                     "missing signature file");
3649                                 exit(1);
3650                         }
3651                         if (!have_identity) {
3652                                 error("Too few arguments for sign: "
3653                                     "missing allowed keys file");
3654                                 exit(1);
3655                         }
3656                         if (cert_key_id == NULL) {
3657                                 error("Too few arguments for verify: "
3658                                     "missing principal identity");
3659                                 exit(1);
3660                         }
3661                         return sig_verify(ca_key_path, cert_principals,
3662                             cert_key_id, identity_file, rr_hostname,
3663                             opts, nopts);
3664                 }
3665                 error("Unsupported operation for -Y: \"%s\"", sign_op);
3666                 usage();
3667                 /* NOTREACHED */
3668         }
3669
3670         if (ca_key_path != NULL) {
3671                 if (argc < 1 && !gen_krl) {
3672                         error("Too few arguments.");
3673                         usage();
3674                 }
3675         } else if (argc > 0 && !gen_krl && !check_krl &&
3676             !do_gen_candidates && !do_screen_candidates) {
3677                 error("Too many arguments.");
3678                 usage();
3679         }
3680         if (change_passphrase && change_comment) {
3681                 error("Can only have one of -p and -c.");
3682                 usage();
3683         }
3684         if (print_fingerprint && (delete_host || hash_hosts)) {
3685                 error("Cannot use -l with -H or -R.");
3686                 usage();
3687         }
3688         if (gen_krl) {
3689                 do_gen_krl(pw, update_krl, ca_key_path,
3690                     cert_serial, identity_comment, argc, argv);
3691                 return (0);
3692         }
3693         if (check_krl) {
3694                 do_check_krl(pw, print_fingerprint, argc, argv);
3695                 return (0);
3696         }
3697         if (ca_key_path != NULL) {
3698                 if (cert_key_id == NULL)
3699                         fatal("Must specify key id (-I) when certifying");
3700                 for (i = 0; i < nopts; i++)
3701                         add_cert_option(opts[i]);
3702                 do_ca_sign(pw, ca_key_path, prefer_agent,
3703                     cert_serial, cert_serial_autoinc, argc, argv);
3704         }
3705         if (show_cert)
3706                 do_show_cert(pw);
3707         if (delete_host || hash_hosts || find_host) {
3708                 do_known_hosts(pw, rr_hostname, find_host,
3709                     delete_host, hash_hosts);
3710         }
3711         if (pkcs11provider != NULL)
3712                 do_download(pw);
3713         if (download_sk) {
3714                 for (i = 0; i < nopts; i++) {
3715                         if (strncasecmp(opts[i], "device=", 7) == 0) {
3716                                 sk_device = xstrdup(opts[i] + 7);
3717                         } else {
3718                                 fatal("Option \"%s\" is unsupported for "
3719                                     "FIDO authenticator download", opts[i]);
3720                         }
3721                 }
3722                 return do_download_sk(sk_provider, sk_device);
3723         }
3724         if (print_fingerprint || print_bubblebabble)
3725                 do_fingerprint(pw);
3726         if (change_passphrase)
3727                 do_change_passphrase(pw);
3728         if (change_comment)
3729                 do_change_comment(pw, identity_comment);
3730 #ifdef WITH_OPENSSL
3731         if (convert_to)
3732                 do_convert_to(pw);
3733         if (convert_from)
3734                 do_convert_from(pw);
3735 #else /* WITH_OPENSSL */
3736         if (convert_to || convert_from)
3737                 fatal("key conversion disabled at compile time");
3738 #endif /* WITH_OPENSSL */
3739         if (print_public)
3740                 do_print_public(pw);
3741         if (rr_hostname != NULL) {
3742                 unsigned int n = 0;
3743
3744                 if (have_identity) {
3745                         n = do_print_resource_record(pw, identity_file,
3746                             rr_hostname, print_generic, opts, nopts);
3747                         if (n == 0)
3748                                 fatal("%s: %s", identity_file, strerror(errno));
3749                         exit(0);
3750                 } else {
3751
3752                         n += do_print_resource_record(pw,
3753                             _PATH_HOST_RSA_KEY_FILE, rr_hostname,
3754                             print_generic, opts, nopts);
3755                         n += do_print_resource_record(pw,
3756                             _PATH_HOST_DSA_KEY_FILE, rr_hostname,
3757                             print_generic, opts, nopts);
3758                         n += do_print_resource_record(pw,
3759                             _PATH_HOST_ECDSA_KEY_FILE, rr_hostname,
3760                             print_generic, opts, nopts);
3761                         n += do_print_resource_record(pw,
3762                             _PATH_HOST_ED25519_KEY_FILE, rr_hostname,
3763                             print_generic, opts, nopts);
3764                         n += do_print_resource_record(pw,
3765                             _PATH_HOST_XMSS_KEY_FILE, rr_hostname,
3766                             print_generic, opts, nopts);
3767                         if (n == 0)
3768                                 fatal("no keys found.");
3769                         exit(0);
3770                 }
3771         }
3772
3773         if (do_gen_candidates || do_screen_candidates) {
3774                 if (argc <= 0)
3775                         fatal("No output file specified");
3776                 else if (argc > 1)
3777                         fatal("Too many output files specified");
3778         }
3779         if (do_gen_candidates) {
3780                 do_moduli_gen(argv[0], opts, nopts);
3781                 return 0;
3782         }
3783         if (do_screen_candidates) {
3784                 do_moduli_screen(argv[0], opts, nopts);
3785                 return 0;
3786         }
3787
3788         if (gen_all_hostkeys) {
3789                 do_gen_all_hostkeys(pw);
3790                 return (0);
3791         }
3792
3793         if (key_type_name == NULL)
3794                 key_type_name = DEFAULT_KEY_TYPE_NAME;
3795
3796         type = sshkey_type_from_name(key_type_name);
3797         type_bits_valid(type, key_type_name, &bits);
3798
3799         if (!quiet)
3800                 printf("Generating public/private %s key pair.\n",
3801                     key_type_name);
3802         switch (type) {
3803         case KEY_ECDSA_SK:
3804         case KEY_ED25519_SK:
3805                 for (i = 0; i < nopts; i++) {
3806                         if (strcasecmp(opts[i], "no-touch-required") == 0) {
3807                                 sk_flags &= ~SSH_SK_USER_PRESENCE_REQD;
3808                         } else if (strcasecmp(opts[i], "verify-required") == 0) {
3809                                 sk_flags |= SSH_SK_USER_VERIFICATION_REQD;
3810                         } else if (strcasecmp(opts[i], "resident") == 0) {
3811                                 sk_flags |= SSH_SK_RESIDENT_KEY;
3812                         } else if (strncasecmp(opts[i], "device=", 7) == 0) {
3813                                 sk_device = xstrdup(opts[i] + 7);
3814                         } else if (strncasecmp(opts[i], "user=", 5) == 0) {
3815                                 sk_user = xstrdup(opts[i] + 5);
3816                         } else if (strncasecmp(opts[i], "challenge=", 10) == 0) {
3817                                 if ((r = sshbuf_load_file(opts[i] + 10,
3818                                     &challenge)) != 0) {
3819                                         fatal_r(r, "Unable to load FIDO "
3820                                             "enrollment challenge \"%s\"",
3821                                             opts[i] + 10);
3822                                 }
3823                         } else if (strncasecmp(opts[i],
3824                             "write-attestation=", 18) == 0) {
3825                                 sk_attestation_path = opts[i] + 18;
3826                         } else if (strncasecmp(opts[i],
3827                             "application=", 12) == 0) {
3828                                 sk_application = xstrdup(opts[i] + 12);
3829                                 if (strncmp(sk_application, "ssh:", 4) != 0) {
3830                                         fatal("FIDO application string must "
3831                                             "begin with \"ssh:\"");
3832                                 }
3833                         } else {
3834                                 fatal("Option \"%s\" is unsupported for "
3835                                     "FIDO authenticator enrollment", opts[i]);
3836                         }
3837                 }
3838                 if ((attest = sshbuf_new()) == NULL)
3839                         fatal("sshbuf_new failed");
3840                 r = 0;
3841                 for (i = 0 ;;) {
3842                         if (!quiet) {
3843                                 printf("You may need to touch your "
3844                                     "authenticator%s to authorize key "
3845                                     "generation.\n",
3846                                     r == 0 ? "" : " again");
3847                         }
3848                         fflush(stdout);
3849                         r = sshsk_enroll(type, sk_provider, sk_device,
3850                             sk_application == NULL ? "ssh:" : sk_application,
3851                             sk_user, sk_flags, passphrase, challenge,
3852                             &private, attest);
3853                         if (r == 0)
3854                                 break;
3855                         if (r == SSH_ERR_KEY_BAD_PERMISSIONS &&
3856                             (sk_flags & SSH_SK_RESIDENT_KEY) != 0 &&
3857                             (sk_flags & SSH_SK_FORCE_OPERATION) == 0 &&
3858                             confirm_sk_overwrite(sk_application, sk_user)) {
3859                                 sk_flags |= SSH_SK_FORCE_OPERATION;
3860                                 continue;
3861                         }
3862                         if (r != SSH_ERR_KEY_WRONG_PASSPHRASE)
3863                                 fatal_r(r, "Key enrollment failed");
3864                         else if (passphrase != NULL) {
3865                                 error("PIN incorrect");
3866                                 freezero(passphrase, strlen(passphrase));
3867                                 passphrase = NULL;
3868                         }
3869                         if (++i >= 3)
3870                                 fatal("Too many incorrect PINs");
3871                         passphrase = read_passphrase("Enter PIN for "
3872                             "authenticator: ", RP_ALLOW_STDIN);
3873                 }
3874                 if (passphrase != NULL) {
3875                         freezero(passphrase, strlen(passphrase));
3876                         passphrase = NULL;
3877                 }
3878                 break;
3879         default:
3880                 if ((r = sshkey_generate(type, bits, &private)) != 0)
3881                         fatal("sshkey_generate failed");
3882                 break;
3883         }
3884         if ((r = sshkey_from_private(private, &public)) != 0)
3885                 fatal_r(r, "sshkey_from_private");
3886
3887         if (!have_identity)
3888                 ask_filename(pw, "Enter file in which to save the key");
3889
3890         /* Create ~/.ssh directory if it doesn't already exist. */
3891         hostfile_create_user_ssh_dir(identity_file, !quiet);
3892
3893         /* If the file already exists, ask the user to confirm. */
3894         if (!confirm_overwrite(identity_file))
3895                 exit(1);
3896
3897         /* Determine the passphrase for the private key */
3898         passphrase = private_key_passphrase();
3899         if (identity_comment) {
3900                 strlcpy(comment, identity_comment, sizeof(comment));
3901         } else {
3902                 /* Create default comment field for the passphrase. */
3903                 snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname);
3904         }
3905
3906         /* Save the key with the given passphrase and comment. */
3907         if ((r = sshkey_save_private(private, identity_file, passphrase,
3908             comment, private_key_format, openssh_format_cipher, rounds)) != 0) {
3909                 error_r(r, "Saving key \"%s\" failed", identity_file);
3910                 freezero(passphrase, strlen(passphrase));
3911                 exit(1);
3912         }
3913         freezero(passphrase, strlen(passphrase));
3914         sshkey_free(private);
3915
3916         if (!quiet) {
3917                 printf("Your identification has been saved in %s\n",
3918                     identity_file);
3919         }
3920
3921         strlcat(identity_file, ".pub", sizeof(identity_file));
3922         if ((r = sshkey_save_public(public, identity_file, comment)) != 0)
3923                 fatal_r(r, "Unable to save public key to %s", identity_file);
3924
3925         if (!quiet) {
3926                 fp = sshkey_fingerprint(public, fingerprint_hash,
3927                     SSH_FP_DEFAULT);
3928                 ra = sshkey_fingerprint(public, fingerprint_hash,
3929                     SSH_FP_RANDOMART);
3930                 if (fp == NULL || ra == NULL)
3931                         fatal("sshkey_fingerprint failed");
3932                 printf("Your public key has been saved in %s\n",
3933                     identity_file);
3934                 printf("The key fingerprint is:\n");
3935                 printf("%s %s\n", fp, comment);
3936                 printf("The key's randomart image is:\n");
3937                 printf("%s\n", ra);
3938                 free(ra);
3939                 free(fp);
3940         }
3941
3942         if (sk_attestation_path != NULL)
3943                 save_attestation(attest, sk_attestation_path);
3944
3945         sshbuf_free(attest);
3946         sshkey_free(public);
3947
3948         exit(0);
3949 }