1 /* $OpenBSD: ssh-keygen.c,v 1.381 2020/01/02 22:40:09 djm Exp $ */
3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
6 * Identity and host key generation and maintenance.
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".
17 #include <sys/types.h>
18 #include <sys/socket.h>
22 #include <openssl/evp.h>
23 #include <openssl/pem.h>
24 #include "openbsd-compat/openssl-compat.h"
50 #include "pathnames.h"
59 #include "ssh-pkcs11.h"
67 #include "sk-api.h" /* XXX for SSH_SK_USER_PRESENCE_REQD; remove */
70 # define DEFAULT_KEY_TYPE_NAME "rsa"
72 # define DEFAULT_KEY_TYPE_NAME "ed25519"
76 * Default number of bits in the RSA, DSA and ECDSA keys. These value can be
77 * overridden on the command line.
79 * These values, with the exception of DSA, provide security equivalent to at
80 * least 128 bits of security according to NIST Special Publication 800-57:
81 * Recommendation for Key Management Part 1 rev 4 section 5.6.1.
82 * For DSA it (and FIPS-186-4 section 4.2) specifies that the only size for
83 * which a 160bit hash is acceptable is 1kbit, and since ssh-dss specifies only
84 * SHA1 we limit the DSA key size 1k bits.
86 #define DEFAULT_BITS 3072
87 #define DEFAULT_BITS_DSA 1024
88 #define DEFAULT_BITS_ECDSA 256
92 /* Flag indicating that we just want to see the key fingerprint */
93 static int print_fingerprint
= 0;
94 static int print_bubblebabble
= 0;
96 /* Hash algorithm to use for fingerprints. */
97 static int fingerprint_hash
= SSH_FP_HASH_DEFAULT
;
99 /* The identity file name, given on the command line or entered by the user. */
100 static char identity_file
[PATH_MAX
];
101 static int have_identity
= 0;
103 /* This is set to the passphrase if given on the command line. */
104 static char *identity_passphrase
= NULL
;
106 /* This is set to the new passphrase if given on the command line. */
107 static char *identity_new_passphrase
= NULL
;
109 /* Key type when certifying */
110 static u_int cert_key_type
= SSH2_CERT_TYPE_USER
;
112 /* "key ID" of signed key */
113 static char *cert_key_id
= NULL
;
115 /* Comma-separated list of principal names for certifying keys */
116 static char *cert_principals
= NULL
;
118 /* Validity period for certificates */
119 static u_int64_t cert_valid_from
= 0;
120 static u_int64_t cert_valid_to
= ~0ULL;
122 /* Certificate options */
123 #define CERTOPT_X_FWD (1)
124 #define CERTOPT_AGENT_FWD (1<<1)
125 #define CERTOPT_PORT_FWD (1<<2)
126 #define CERTOPT_PTY (1<<3)
127 #define CERTOPT_USER_RC (1<<4)
128 #define CERTOPT_NO_REQUIRE_USER_PRESENCE (1<<5)
129 #define CERTOPT_DEFAULT (CERTOPT_X_FWD|CERTOPT_AGENT_FWD| \
130 CERTOPT_PORT_FWD|CERTOPT_PTY|CERTOPT_USER_RC)
131 static u_int32_t certflags_flags
= CERTOPT_DEFAULT
;
132 static char *certflags_command
= NULL
;
133 static char *certflags_src_addr
= NULL
;
135 /* Arbitrary extensions specified by user */
136 struct cert_userext
{
141 static struct cert_userext
*cert_userext
;
142 static size_t ncert_userext
;
144 /* Conversion to/from various formats */
149 } convert_format
= FMT_RFC4716
;
151 static char *key_type_name
= NULL
;
153 /* Load key from this PKCS#11 provider */
154 static char *pkcs11provider
= NULL
;
156 /* FIDO/U2F provider to use */
157 static char *sk_provider
= NULL
;
159 /* Format for writing private keys */
160 static int private_key_format
= SSHKEY_PRIVATE_OPENSSH
;
162 /* Cipher for new-format private keys */
163 static char *openssh_format_cipher
= NULL
;
165 /* Number of KDF rounds to derive new format keys. */
166 static int rounds
= 0;
169 extern char *__progname
;
171 static char hostname
[NI_MAXHOST
];
175 int gen_candidates(FILE *, u_int32_t
, u_int32_t
, BIGNUM
*);
176 int prime_test(FILE *, FILE *, u_int32_t
, u_int32_t
, char *, unsigned long,
181 type_bits_valid(int type
, const char *name
, u_int32_t
*bitsp
)
183 if (type
== KEY_UNSPEC
)
184 fatal("unknown key type %s", key_type_name
);
191 *bitsp
= DEFAULT_BITS_DSA
;
195 (nid
= sshkey_ecdsa_nid_from_name(name
)) > 0)
196 *bitsp
= sshkey_curve_nid_to_bits(nid
);
198 *bitsp
= DEFAULT_BITS_ECDSA
;
201 *bitsp
= DEFAULT_BITS
;
210 fatal("Invalid DSA key length: must be 1024 bits");
213 if (*bitsp
< SSH_RSA_MINIMUM_MODULUS_SIZE
)
214 fatal("Invalid RSA key length: minimum is %d bits",
215 SSH_RSA_MINIMUM_MODULUS_SIZE
);
216 else if (*bitsp
> OPENSSL_RSA_MAX_MODULUS_BITS
)
217 fatal("Invalid RSA key length: maximum is %d bits",
218 OPENSSL_RSA_MAX_MODULUS_BITS
);
221 if (sshkey_ecdsa_bits_to_nid(*bitsp
) == -1)
222 fatal("Invalid ECDSA key length: valid lengths are "
223 #ifdef OPENSSL_HAS_NISTP521
224 "256, 384 or 521 bits");
233 * Checks whether a file exists and, if so, asks the user whether they wish
235 * Returns nonzero if the file does not already exist or if the user agrees to
236 * overwrite, or zero otherwise.
239 confirm_overwrite(const char *filename
)
244 if (stat(filename
, &st
) != 0)
246 printf("%s already exists.\n", filename
);
247 printf("Overwrite (y/n)? ");
249 if (fgets(yesno
, sizeof(yesno
), stdin
) == NULL
)
251 if (yesno
[0] != 'y' && yesno
[0] != 'Y')
257 ask_filename(struct passwd
*pw
, const char *prompt
)
262 if (key_type_name
== NULL
)
263 name
= _PATH_SSH_CLIENT_ID_RSA
;
265 switch (sshkey_type_from_name(key_type_name
)) {
268 name
= _PATH_SSH_CLIENT_ID_DSA
;
270 #ifdef OPENSSL_HAS_ECC
273 name
= _PATH_SSH_CLIENT_ID_ECDSA
;
275 case KEY_ECDSA_SK_CERT
:
277 name
= _PATH_SSH_CLIENT_ID_ECDSA_SK
;
282 name
= _PATH_SSH_CLIENT_ID_RSA
;
285 case KEY_ED25519_CERT
:
286 name
= _PATH_SSH_CLIENT_ID_ED25519
;
289 case KEY_ED25519_SK_CERT
:
290 name
= _PATH_SSH_CLIENT_ID_ED25519_SK
;
294 name
= _PATH_SSH_CLIENT_ID_XMSS
;
297 fatal("bad key type");
300 snprintf(identity_file
, sizeof(identity_file
),
301 "%s/%s", pw
->pw_dir
, name
);
302 printf("%s (%s): ", prompt
, identity_file
);
304 if (fgets(buf
, sizeof(buf
), stdin
) == NULL
)
306 buf
[strcspn(buf
, "\n")] = '\0';
307 if (strcmp(buf
, "") != 0)
308 strlcpy(identity_file
, buf
, sizeof(identity_file
));
312 static struct sshkey
*
313 load_identity(const char *filename
, char **commentp
)
319 if (commentp
!= NULL
)
321 if ((r
= sshkey_load_private(filename
, "", &prv
, commentp
)) == 0)
323 if (r
!= SSH_ERR_KEY_WRONG_PASSPHRASE
)
324 fatal("Load key \"%s\": %s", filename
, ssh_err(r
));
325 if (identity_passphrase
)
326 pass
= xstrdup(identity_passphrase
);
328 pass
= read_passphrase("Enter passphrase: ", RP_ALLOW_STDIN
);
329 r
= sshkey_load_private(filename
, pass
, &prv
, commentp
);
330 explicit_bzero(pass
, strlen(pass
));
333 fatal("Load key \"%s\": %s", filename
, ssh_err(r
));
337 #define SSH_COM_PUBLIC_BEGIN "---- BEGIN SSH2 PUBLIC KEY ----"
338 #define SSH_COM_PUBLIC_END "---- END SSH2 PUBLIC KEY ----"
339 #define SSH_COM_PRIVATE_BEGIN "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----"
340 #define SSH_COM_PRIVATE_KEY_MAGIC 0x3f6ff9eb
344 do_convert_to_ssh2(struct passwd
*pw
, struct sshkey
*k
)
347 char comment
[61], *b64
;
350 if ((b
= sshbuf_new()) == NULL
)
351 fatal("%s: sshbuf_new failed", __func__
);
352 if ((r
= sshkey_putb(k
, b
)) != 0)
353 fatal("key_to_blob failed: %s", ssh_err(r
));
354 if ((b64
= sshbuf_dtob64_string(b
, 1)) == NULL
)
355 fatal("%s: sshbuf_dtob64_string failed", __func__
);
357 /* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */
358 snprintf(comment
, sizeof(comment
),
359 "%u-bit %s, converted by %s@%s from OpenSSH",
360 sshkey_size(k
), sshkey_type(k
),
361 pw
->pw_name
, hostname
);
366 fprintf(stdout
, "%s\n", SSH_COM_PUBLIC_BEGIN
);
367 fprintf(stdout
, "Comment: \"%s\"\n%s", comment
, b64
);
368 fprintf(stdout
, "%s\n", SSH_COM_PUBLIC_END
);
374 do_convert_to_pkcs8(struct sshkey
*k
)
376 switch (sshkey_type_plain(k
->type
)) {
378 if (!PEM_write_RSA_PUBKEY(stdout
, k
->rsa
))
379 fatal("PEM_write_RSA_PUBKEY failed");
382 if (!PEM_write_DSA_PUBKEY(stdout
, k
->dsa
))
383 fatal("PEM_write_DSA_PUBKEY failed");
385 #ifdef OPENSSL_HAS_ECC
387 if (!PEM_write_EC_PUBKEY(stdout
, k
->ecdsa
))
388 fatal("PEM_write_EC_PUBKEY failed");
392 fatal("%s: unsupported key type %s", __func__
, sshkey_type(k
));
398 do_convert_to_pem(struct sshkey
*k
)
400 switch (sshkey_type_plain(k
->type
)) {
402 if (!PEM_write_RSAPublicKey(stdout
, k
->rsa
))
403 fatal("PEM_write_RSAPublicKey failed");
406 fatal("%s: unsupported key type %s", __func__
, sshkey_type(k
));
412 do_convert_to(struct passwd
*pw
)
419 ask_filename(pw
, "Enter file in which the key is");
420 if (stat(identity_file
, &st
) == -1)
421 fatal("%s: %s: %s", __progname
, identity_file
, strerror(errno
));
422 if ((r
= sshkey_load_public(identity_file
, &k
, NULL
)) != 0)
423 k
= load_identity(identity_file
, NULL
);
424 switch (convert_format
) {
426 do_convert_to_ssh2(pw
, k
);
429 do_convert_to_pkcs8(k
);
432 do_convert_to_pem(k
);
435 fatal("%s: unknown key format %d", __func__
, convert_format
);
441 * This is almost exactly the bignum1 encoding, but with 32 bit for length
445 buffer_get_bignum_bits(struct sshbuf
*b
, BIGNUM
*value
)
447 u_int bytes
, bignum_bits
;
450 if ((r
= sshbuf_get_u32(b
, &bignum_bits
)) != 0)
451 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
452 bytes
= (bignum_bits
+ 7) / 8;
453 if (sshbuf_len(b
) < bytes
)
454 fatal("%s: input buffer too small: need %d have %zu",
455 __func__
, bytes
, sshbuf_len(b
));
456 if (BN_bin2bn(sshbuf_ptr(b
), bytes
, value
) == NULL
)
457 fatal("%s: BN_bin2bn failed", __func__
);
458 if ((r
= sshbuf_consume(b
, bytes
)) != 0)
459 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
462 static struct sshkey
*
463 do_convert_private_ssh2(struct sshbuf
*b
)
465 struct sshkey
*key
= NULL
;
467 u_char e1
, e2
, e3
, *sig
= NULL
, data
[] = "abcde12345";
469 u_int magic
, i1
, i2
, i3
, i4
;
472 BIGNUM
*dsa_p
= NULL
, *dsa_q
= NULL
, *dsa_g
= NULL
;
473 BIGNUM
*dsa_pub_key
= NULL
, *dsa_priv_key
= NULL
;
474 BIGNUM
*rsa_n
= NULL
, *rsa_e
= NULL
, *rsa_d
= NULL
;
475 BIGNUM
*rsa_p
= NULL
, *rsa_q
= NULL
, *rsa_iqmp
= NULL
;
477 if ((r
= sshbuf_get_u32(b
, &magic
)) != 0)
478 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
480 if (magic
!= SSH_COM_PRIVATE_KEY_MAGIC
) {
481 error("bad magic 0x%x != 0x%x", magic
,
482 SSH_COM_PRIVATE_KEY_MAGIC
);
485 if ((r
= sshbuf_get_u32(b
, &i1
)) != 0 ||
486 (r
= sshbuf_get_cstring(b
, &type
, NULL
)) != 0 ||
487 (r
= sshbuf_get_cstring(b
, &cipher
, NULL
)) != 0 ||
488 (r
= sshbuf_get_u32(b
, &i2
)) != 0 ||
489 (r
= sshbuf_get_u32(b
, &i3
)) != 0 ||
490 (r
= sshbuf_get_u32(b
, &i4
)) != 0)
491 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
492 debug("ignore (%d %d %d %d)", i1
, i2
, i3
, i4
);
493 if (strcmp(cipher
, "none") != 0) {
494 error("unsupported cipher %s", cipher
);
501 if (strstr(type
, "dsa")) {
503 } else if (strstr(type
, "rsa")) {
509 if ((key
= sshkey_new(ktype
)) == NULL
)
510 fatal("sshkey_new failed");
515 if ((dsa_p
= BN_new()) == NULL
||
516 (dsa_q
= BN_new()) == NULL
||
517 (dsa_g
= BN_new()) == NULL
||
518 (dsa_pub_key
= BN_new()) == NULL
||
519 (dsa_priv_key
= BN_new()) == NULL
)
520 fatal("%s: BN_new", __func__
);
521 buffer_get_bignum_bits(b
, dsa_p
);
522 buffer_get_bignum_bits(b
, dsa_g
);
523 buffer_get_bignum_bits(b
, dsa_q
);
524 buffer_get_bignum_bits(b
, dsa_pub_key
);
525 buffer_get_bignum_bits(b
, dsa_priv_key
);
526 if (!DSA_set0_pqg(key
->dsa
, dsa_p
, dsa_q
, dsa_g
))
527 fatal("%s: DSA_set0_pqg failed", __func__
);
528 dsa_p
= dsa_q
= dsa_g
= NULL
; /* transferred */
529 if (!DSA_set0_key(key
->dsa
, dsa_pub_key
, dsa_priv_key
))
530 fatal("%s: DSA_set0_key failed", __func__
);
531 dsa_pub_key
= dsa_priv_key
= NULL
; /* transferred */
534 if ((r
= sshbuf_get_u8(b
, &e1
)) != 0 ||
535 (e1
< 30 && (r
= sshbuf_get_u8(b
, &e2
)) != 0) ||
536 (e1
< 30 && (r
= sshbuf_get_u8(b
, &e3
)) != 0))
537 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
548 if ((rsa_e
= BN_new()) == NULL
)
549 fatal("%s: BN_new", __func__
);
550 if (!BN_set_word(rsa_e
, e
)) {
551 BN_clear_free(rsa_e
);
555 if ((rsa_n
= BN_new()) == NULL
||
556 (rsa_d
= BN_new()) == NULL
||
557 (rsa_p
= BN_new()) == NULL
||
558 (rsa_q
= BN_new()) == NULL
||
559 (rsa_iqmp
= BN_new()) == NULL
)
560 fatal("%s: BN_new", __func__
);
561 buffer_get_bignum_bits(b
, rsa_d
);
562 buffer_get_bignum_bits(b
, rsa_n
);
563 buffer_get_bignum_bits(b
, rsa_iqmp
);
564 buffer_get_bignum_bits(b
, rsa_q
);
565 buffer_get_bignum_bits(b
, rsa_p
);
566 if (!RSA_set0_key(key
->rsa
, rsa_n
, rsa_e
, rsa_d
))
567 fatal("%s: RSA_set0_key failed", __func__
);
568 rsa_n
= rsa_e
= rsa_d
= NULL
; /* transferred */
569 if (!RSA_set0_factors(key
->rsa
, rsa_p
, rsa_q
))
570 fatal("%s: RSA_set0_factors failed", __func__
);
571 rsa_p
= rsa_q
= NULL
; /* transferred */
572 if ((r
= ssh_rsa_complete_crt_parameters(key
, rsa_iqmp
)) != 0)
573 fatal("generate RSA parameters failed: %s", ssh_err(r
));
574 BN_clear_free(rsa_iqmp
);
577 rlen
= sshbuf_len(b
);
579 error("%s: remaining bytes in key blob %d", __func__
, rlen
);
582 if (sshkey_sign(key
, &sig
, &slen
, data
, sizeof(data
),
583 NULL
, NULL
, 0) != 0 ||
584 sshkey_verify(key
, sig
, slen
, data
, sizeof(data
),
585 NULL
, 0, NULL
) != 0) {
595 get_line(FILE *fp
, char *line
, size_t len
)
601 while ((c
= fgetc(fp
)) != EOF
) {
603 fatal("input line too long.");
607 if (c
!= EOF
&& c
!= '\n' && ungetc(c
, fp
) == EOF
)
608 fatal("unget: %s", strerror(errno
));
621 do_convert_from_ssh2(struct passwd
*pw
, struct sshkey
**k
, int *private)
623 int r
, blen
, escaped
= 0;
630 if ((buf
= sshbuf_new()) == NULL
)
631 fatal("sshbuf_new failed");
632 if ((fp
= fopen(identity_file
, "r")) == NULL
)
633 fatal("%s: %s: %s", __progname
, identity_file
, strerror(errno
));
635 while ((blen
= get_line(fp
, line
, sizeof(line
))) != -1) {
636 if (blen
> 0 && line
[blen
- 1] == '\\')
638 if (strncmp(line
, "----", 4) == 0 ||
639 strstr(line
, ": ") != NULL
) {
640 if (strstr(line
, SSH_COM_PRIVATE_BEGIN
) != NULL
)
642 if (strstr(line
, " END ") != NULL
) {
645 /* fprintf(stderr, "ignore: %s", line); */
650 /* fprintf(stderr, "escaped: %s", line); */
653 strlcat(encoded
, line
, sizeof(encoded
));
655 len
= strlen(encoded
);
656 if (((len
% 4) == 3) &&
657 (encoded
[len
-1] == '=') &&
658 (encoded
[len
-2] == '=') &&
659 (encoded
[len
-3] == '='))
660 encoded
[len
-3] = '\0';
661 if ((r
= sshbuf_b64tod(buf
, encoded
)) != 0)
662 fatal("%s: base64 decoding failed: %s", __func__
, ssh_err(r
));
664 *k
= do_convert_private_ssh2(buf
);
665 else if ((r
= sshkey_fromb(buf
, k
)) != 0)
666 fatal("decode blob failed: %s", ssh_err(r
));
672 do_convert_from_pkcs8(struct sshkey
**k
, int *private)
677 if ((fp
= fopen(identity_file
, "r")) == NULL
)
678 fatal("%s: %s: %s", __progname
, identity_file
, strerror(errno
));
679 if ((pubkey
= PEM_read_PUBKEY(fp
, NULL
, NULL
, NULL
)) == NULL
) {
680 fatal("%s: %s is not a recognised public key format", __func__
,
684 switch (EVP_PKEY_base_id(pubkey
)) {
686 if ((*k
= sshkey_new(KEY_UNSPEC
)) == NULL
)
687 fatal("sshkey_new failed");
688 (*k
)->type
= KEY_RSA
;
689 (*k
)->rsa
= EVP_PKEY_get1_RSA(pubkey
);
692 if ((*k
= sshkey_new(KEY_UNSPEC
)) == NULL
)
693 fatal("sshkey_new failed");
694 (*k
)->type
= KEY_DSA
;
695 (*k
)->dsa
= EVP_PKEY_get1_DSA(pubkey
);
697 #ifdef OPENSSL_HAS_ECC
699 if ((*k
= sshkey_new(KEY_UNSPEC
)) == NULL
)
700 fatal("sshkey_new failed");
701 (*k
)->type
= KEY_ECDSA
;
702 (*k
)->ecdsa
= EVP_PKEY_get1_EC_KEY(pubkey
);
703 (*k
)->ecdsa_nid
= sshkey_ecdsa_key_to_nid((*k
)->ecdsa
);
707 fatal("%s: unsupported pubkey type %d", __func__
,
708 EVP_PKEY_base_id(pubkey
));
710 EVP_PKEY_free(pubkey
);
715 do_convert_from_pem(struct sshkey
**k
, int *private)
720 if ((fp
= fopen(identity_file
, "r")) == NULL
)
721 fatal("%s: %s: %s", __progname
, identity_file
, strerror(errno
));
722 if ((rsa
= PEM_read_RSAPublicKey(fp
, NULL
, NULL
, NULL
)) != NULL
) {
723 if ((*k
= sshkey_new(KEY_UNSPEC
)) == NULL
)
724 fatal("sshkey_new failed");
725 (*k
)->type
= KEY_RSA
;
730 fatal("%s: unrecognised raw private key format", __func__
);
734 do_convert_from(struct passwd
*pw
)
736 struct sshkey
*k
= NULL
;
737 int r
, private = 0, ok
= 0;
741 ask_filename(pw
, "Enter file in which the key is");
742 if (stat(identity_file
, &st
) == -1)
743 fatal("%s: %s: %s", __progname
, identity_file
, strerror(errno
));
745 switch (convert_format
) {
747 do_convert_from_ssh2(pw
, &k
, &private);
750 do_convert_from_pkcs8(&k
, &private);
753 do_convert_from_pem(&k
, &private);
756 fatal("%s: unknown key format %d", __func__
, convert_format
);
760 if ((r
= sshkey_write(k
, stdout
)) == 0)
763 fprintf(stdout
, "\n");
767 ok
= PEM_write_DSAPrivateKey(stdout
, k
->dsa
, NULL
,
768 NULL
, 0, NULL
, NULL
);
770 #ifdef OPENSSL_HAS_ECC
772 ok
= PEM_write_ECPrivateKey(stdout
, k
->ecdsa
, NULL
,
773 NULL
, 0, NULL
, NULL
);
777 ok
= PEM_write_RSAPrivateKey(stdout
, k
->rsa
, NULL
,
778 NULL
, 0, NULL
, NULL
);
781 fatal("%s: unsupported key type %s", __func__
,
787 fatal("key write failed");
794 do_print_public(struct passwd
*pw
)
799 char *comment
= NULL
;
802 ask_filename(pw
, "Enter file in which the key is");
803 if (stat(identity_file
, &st
) == -1)
804 fatal("%s: %s", identity_file
, strerror(errno
));
805 prv
= load_identity(identity_file
, &comment
);
806 if ((r
= sshkey_write(prv
, stdout
)) != 0)
807 error("sshkey_write failed: %s", ssh_err(r
));
809 if (comment
!= NULL
&& *comment
!= '\0')
810 fprintf(stdout
, " %s", comment
);
811 fprintf(stdout
, "\n");
817 do_download(struct passwd
*pw
)
820 struct sshkey
**keys
= NULL
;
822 enum sshkey_fp_rep rep
;
826 fptype
= print_bubblebabble
? SSH_DIGEST_SHA1
: fingerprint_hash
;
827 rep
= print_bubblebabble
? SSH_FP_BUBBLEBABBLE
: SSH_FP_DEFAULT
;
830 nkeys
= pkcs11_add_provider(pkcs11provider
, NULL
, &keys
);
832 fatal("cannot read public key from pkcs11");
833 for (i
= 0; i
< nkeys
; i
++) {
834 if (print_fingerprint
) {
835 fp
= sshkey_fingerprint(keys
[i
], fptype
, rep
);
836 ra
= sshkey_fingerprint(keys
[i
], fingerprint_hash
,
838 if (fp
== NULL
|| ra
== NULL
)
839 fatal("%s: sshkey_fingerprint fail", __func__
);
840 printf("%u %s %s (PKCS11 key)\n", sshkey_size(keys
[i
]),
841 fp
, sshkey_type(keys
[i
]));
842 if (log_level_get() >= SYSLOG_LEVEL_VERBOSE
)
847 (void) sshkey_write(keys
[i
], stdout
); /* XXX check */
848 fprintf(stdout
, "\n");
850 sshkey_free(keys
[i
]);
856 fatal("no pkcs11 support");
857 #endif /* ENABLE_PKCS11 */
860 static struct sshkey
*
861 try_read_key(char **cpp
)
866 if ((ret
= sshkey_new(KEY_UNSPEC
)) == NULL
)
867 fatal("sshkey_new failed");
868 if ((r
= sshkey_read(ret
, cpp
)) == 0)
876 fingerprint_one_key(const struct sshkey
*public, const char *comment
)
878 char *fp
= NULL
, *ra
= NULL
;
879 enum sshkey_fp_rep rep
;
882 fptype
= print_bubblebabble
? SSH_DIGEST_SHA1
: fingerprint_hash
;
883 rep
= print_bubblebabble
? SSH_FP_BUBBLEBABBLE
: SSH_FP_DEFAULT
;
884 fp
= sshkey_fingerprint(public, fptype
, rep
);
885 ra
= sshkey_fingerprint(public, fingerprint_hash
, SSH_FP_RANDOMART
);
886 if (fp
== NULL
|| ra
== NULL
)
887 fatal("%s: sshkey_fingerprint failed", __func__
);
888 mprintf("%u %s %s (%s)\n", sshkey_size(public), fp
,
889 comment
? comment
: "no comment", sshkey_type(public));
890 if (log_level_get() >= SYSLOG_LEVEL_VERBOSE
)
897 fingerprint_private(const char *path
)
900 char *comment
= NULL
;
901 struct sshkey
*public = NULL
;
904 if (stat(identity_file
, &st
) == -1)
905 fatal("%s: %s", path
, strerror(errno
));
906 if ((r
= sshkey_load_public(path
, &public, &comment
)) != 0) {
907 debug("load public \"%s\": %s", path
, ssh_err(r
));
908 if ((r
= sshkey_load_private(path
, NULL
,
909 &public, &comment
)) != 0) {
910 debug("load private \"%s\": %s", path
, ssh_err(r
));
911 fatal("%s is not a key file.", path
);
915 fingerprint_one_key(public, comment
);
921 do_fingerprint(struct passwd
*pw
)
924 struct sshkey
*public = NULL
;
925 char *comment
= NULL
, *cp
, *ep
, *line
= NULL
;
932 ask_filename(pw
, "Enter file in which the key is");
933 path
= identity_file
;
935 if (strcmp(identity_file
, "-") == 0) {
938 } else if ((f
= fopen(path
, "r")) == NULL
)
939 fatal("%s: %s: %s", __progname
, path
, strerror(errno
));
941 while (getline(&line
, &linesize
, f
) != -1) {
944 cp
[strcspn(cp
, "\n")] = '\0';
945 /* Trim leading space and comments */
946 cp
= line
+ strspn(line
, " \t");
947 if (*cp
== '#' || *cp
== '\0')
951 * Input may be plain keys, private keys, authorized_keys
956 * Try private keys first. Assume a key is private if
957 * "SSH PRIVATE KEY" appears on the first line and we're
958 * not reading from stdin (XXX support private keys on stdin).
960 if (lnum
== 1 && strcmp(identity_file
, "-") != 0 &&
961 strstr(cp
, "PRIVATE KEY") != NULL
) {
964 fingerprint_private(path
);
969 * If it's not a private key, then this must be prepared to
970 * accept a public key prefixed with a hostname or options.
971 * Try a bare key first, otherwise skip the leading stuff.
973 if ((public = try_read_key(&cp
)) == NULL
) {
974 i
= strtol(cp
, &ep
, 10);
975 if (i
== 0 || ep
== NULL
||
976 (*ep
!= ' ' && *ep
!= '\t')) {
980 for (; *cp
&& (quoted
|| (*cp
!= ' ' &&
981 *cp
!= '\t')); cp
++) {
982 if (*cp
== '\\' && cp
[1] == '"')
983 cp
++; /* Skip both */
992 /* Retry after parsing leading hostname/key options */
993 if (public == NULL
&& (public = try_read_key(&cp
)) == NULL
) {
994 debug("%s:%lu: not a public key", path
, lnum
);
998 /* Find trailing comment, if any */
999 for (; *cp
== ' ' || *cp
== '\t'; cp
++)
1001 if (*cp
!= '\0' && *cp
!= '#')
1004 fingerprint_one_key(public, comment
);
1005 sshkey_free(public);
1006 invalid
= 0; /* One good key in the file is sufficient */
1012 fatal("%s is not a public key file.", path
);
1017 do_gen_all_hostkeys(struct passwd
*pw
)
1021 char *key_type_display
;
1025 { "rsa", "RSA" ,_PATH_HOST_RSA_KEY_FILE
},
1026 { "dsa", "DSA", _PATH_HOST_DSA_KEY_FILE
},
1027 #ifdef OPENSSL_HAS_ECC
1028 { "ecdsa", "ECDSA",_PATH_HOST_ECDSA_KEY_FILE
},
1029 #endif /* OPENSSL_HAS_ECC */
1030 #endif /* WITH_OPENSSL */
1031 { "ed25519", "ED25519",_PATH_HOST_ED25519_KEY_FILE
},
1033 { "xmss", "XMSS",_PATH_HOST_XMSS_KEY_FILE
},
1034 #endif /* WITH_XMSS */
1035 { NULL
, NULL
, NULL
}
1041 struct sshkey
*private, *public;
1042 char comment
[1024], *prv_tmp
, *pub_tmp
, *prv_file
, *pub_file
;
1046 for (i
= 0; key_types
[i
].key_type
; i
++) {
1047 public = private = NULL
;
1048 prv_tmp
= pub_tmp
= prv_file
= pub_file
= NULL
;
1050 xasprintf(&prv_file
, "%s%s",
1051 identity_file
, key_types
[i
].path
);
1053 /* Check whether private key exists and is not zero-length */
1054 if (stat(prv_file
, &st
) == 0) {
1055 if (st
.st_size
!= 0)
1057 } else if (errno
!= ENOENT
) {
1058 error("Could not stat %s: %s", key_types
[i
].path
,
1064 * Private key doesn't exist or is invalid; proceed with
1067 xasprintf(&prv_tmp
, "%s%s.XXXXXXXXXX",
1068 identity_file
, key_types
[i
].path
);
1069 xasprintf(&pub_tmp
, "%s%s.pub.XXXXXXXXXX",
1070 identity_file
, key_types
[i
].path
);
1071 xasprintf(&pub_file
, "%s%s.pub",
1072 identity_file
, key_types
[i
].path
);
1076 printf("%s: generating new host keys: ", __progname
);
1078 printf("%s ", key_types
[i
].key_type_display
);
1080 type
= sshkey_type_from_name(key_types
[i
].key_type
);
1081 if ((fd
= mkstemp(prv_tmp
)) == -1) {
1082 error("Could not save your public key in %s: %s",
1083 prv_tmp
, strerror(errno
));
1086 close(fd
); /* just using mkstemp() to generate/reserve a name */
1088 type_bits_valid(type
, NULL
, &bits
);
1089 if ((r
= sshkey_generate(type
, bits
, &private)) != 0) {
1090 error("sshkey_generate failed: %s", ssh_err(r
));
1093 if ((r
= sshkey_from_private(private, &public)) != 0)
1094 fatal("sshkey_from_private failed: %s", ssh_err(r
));
1095 snprintf(comment
, sizeof comment
, "%s@%s", pw
->pw_name
,
1097 if ((r
= sshkey_save_private(private, prv_tmp
, "",
1098 comment
, private_key_format
, openssh_format_cipher
,
1100 error("Saving key \"%s\" failed: %s",
1101 prv_tmp
, ssh_err(r
));
1104 if ((fd
= mkstemp(pub_tmp
)) == -1) {
1105 error("Could not save your public key in %s: %s",
1106 pub_tmp
, strerror(errno
));
1109 (void)fchmod(fd
, 0644);
1110 f
= fdopen(fd
, "w");
1112 error("fdopen %s failed: %s", pub_tmp
, strerror(errno
));
1116 if ((r
= sshkey_write(public, f
)) != 0) {
1117 error("write key failed: %s", ssh_err(r
));
1121 fprintf(f
, " %s\n", comment
);
1122 if (ferror(f
) != 0) {
1123 error("write key failed: %s", strerror(errno
));
1127 if (fclose(f
) != 0) {
1128 error("key close failed: %s", strerror(errno
));
1132 /* Rename temporary files to their permanent locations. */
1133 if (rename(pub_tmp
, pub_file
) != 0) {
1134 error("Unable to move %s into position: %s",
1135 pub_file
, strerror(errno
));
1138 if (rename(prv_tmp
, prv_file
) != 0) {
1139 error("Unable to move %s into position: %s",
1140 key_types
[i
].path
, strerror(errno
));
1146 sshkey_free(private);
1147 sshkey_free(public);
1157 struct known_hosts_ctx
{
1158 const char *host
; /* Hostname searched for in find/delete case */
1159 FILE *out
; /* Output file, stdout for find_hosts case */
1160 int has_unhashed
; /* When hashing, original had unhashed hosts */
1161 int found_key
; /* For find/delete, host was found */
1162 int invalid
; /* File contained invalid items; don't delete */
1163 int hash_hosts
; /* Hash hostnames as we go */
1164 int find_host
; /* Search for specific hostname */
1165 int delete_host
; /* Delete host from known_hosts */
1169 known_hosts_hash(struct hostkey_foreach_line
*l
, void *_ctx
)
1171 struct known_hosts_ctx
*ctx
= (struct known_hosts_ctx
*)_ctx
;
1172 char *hashed
, *cp
, *hosts
, *ohosts
;
1173 int has_wild
= l
->hosts
&& strcspn(l
->hosts
, "*?!") != strlen(l
->hosts
);
1174 int was_hashed
= l
->hosts
&& l
->hosts
[0] == HASH_DELIM
;
1176 switch (l
->status
) {
1178 case HKF_STATUS_MATCHED
:
1180 * Don't hash hosts already already hashed, with wildcard
1181 * characters or a CA/revocation marker.
1183 if (was_hashed
|| has_wild
|| l
->marker
!= MRK_NONE
) {
1184 fprintf(ctx
->out
, "%s\n", l
->line
);
1185 if (has_wild
&& !ctx
->find_host
) {
1186 logit("%s:%lu: ignoring host name "
1187 "with wildcard: %.64s", l
->path
,
1188 l
->linenum
, l
->hosts
);
1193 * Split any comma-separated hostnames from the host list,
1194 * hash and store separately.
1196 ohosts
= hosts
= xstrdup(l
->hosts
);
1197 while ((cp
= strsep(&hosts
, ",")) != NULL
&& *cp
!= '\0') {
1199 if ((hashed
= host_hash(cp
, NULL
, 0)) == NULL
)
1200 fatal("hash_host failed");
1201 fprintf(ctx
->out
, "%s %s\n", hashed
, l
->rawkey
);
1202 ctx
->has_unhashed
= 1;
1206 case HKF_STATUS_INVALID
:
1207 /* Retain invalid lines, but mark file as invalid. */
1209 logit("%s:%lu: invalid line", l
->path
, l
->linenum
);
1212 fprintf(ctx
->out
, "%s\n", l
->line
);
1220 known_hosts_find_delete(struct hostkey_foreach_line
*l
, void *_ctx
)
1222 struct known_hosts_ctx
*ctx
= (struct known_hosts_ctx
*)_ctx
;
1223 enum sshkey_fp_rep rep
;
1225 char *fp
= NULL
, *ra
= NULL
;
1227 fptype
= print_bubblebabble
? SSH_DIGEST_SHA1
: fingerprint_hash
;
1228 rep
= print_bubblebabble
? SSH_FP_BUBBLEBABBLE
: SSH_FP_DEFAULT
;
1230 if (l
->status
== HKF_STATUS_MATCHED
) {
1231 if (ctx
->delete_host
) {
1232 if (l
->marker
!= MRK_NONE
) {
1233 /* Don't remove CA and revocation lines */
1234 fprintf(ctx
->out
, "%s\n", l
->line
);
1237 * Hostname matches and has no CA/revoke
1238 * marker, delete it by *not* writing the
1243 printf("# Host %s found: line %lu\n",
1244 ctx
->host
, l
->linenum
);
1247 } else if (ctx
->find_host
) {
1250 printf("# Host %s found: line %lu %s\n",
1252 l
->linenum
, l
->marker
== MRK_CA
? "CA" :
1253 (l
->marker
== MRK_REVOKE
? "REVOKED" : ""));
1255 if (ctx
->hash_hosts
)
1256 known_hosts_hash(l
, ctx
);
1257 else if (print_fingerprint
) {
1258 fp
= sshkey_fingerprint(l
->key
, fptype
, rep
);
1259 ra
= sshkey_fingerprint(l
->key
,
1260 fingerprint_hash
, SSH_FP_RANDOMART
);
1261 if (fp
== NULL
|| ra
== NULL
)
1262 fatal("%s: sshkey_fingerprint failed",
1264 mprintf("%s %s %s %s\n", ctx
->host
,
1265 sshkey_type(l
->key
), fp
, l
->comment
);
1266 if (log_level_get() >= SYSLOG_LEVEL_VERBOSE
)
1271 fprintf(ctx
->out
, "%s\n", l
->line
);
1274 } else if (ctx
->delete_host
) {
1275 /* Retain non-matching hosts when deleting */
1276 if (l
->status
== HKF_STATUS_INVALID
) {
1278 logit("%s:%lu: invalid line", l
->path
, l
->linenum
);
1280 fprintf(ctx
->out
, "%s\n", l
->line
);
1286 do_known_hosts(struct passwd
*pw
, const char *name
, int find_host
,
1287 int delete_host
, int hash_hosts
)
1289 char *cp
, tmp
[PATH_MAX
], old
[PATH_MAX
];
1290 int r
, fd
, oerrno
, inplace
= 0;
1291 struct known_hosts_ctx ctx
;
1292 u_int foreach_options
;
1294 if (!have_identity
) {
1295 cp
= tilde_expand_filename(_PATH_SSH_USER_HOSTFILE
, pw
->pw_uid
);
1296 if (strlcpy(identity_file
, cp
, sizeof(identity_file
)) >=
1297 sizeof(identity_file
))
1298 fatal("Specified known hosts path too long");
1303 memset(&ctx
, 0, sizeof(ctx
));
1306 ctx
.hash_hosts
= hash_hosts
;
1307 ctx
.find_host
= find_host
;
1308 ctx
.delete_host
= delete_host
;
1311 * Find hosts goes to stdout, hash and deletions happen in-place
1312 * A corner case is ssh-keygen -HF foo, which should go to stdout
1314 if (!find_host
&& (hash_hosts
|| delete_host
)) {
1315 if (strlcpy(tmp
, identity_file
, sizeof(tmp
)) >= sizeof(tmp
) ||
1316 strlcat(tmp
, ".XXXXXXXXXX", sizeof(tmp
)) >= sizeof(tmp
) ||
1317 strlcpy(old
, identity_file
, sizeof(old
)) >= sizeof(old
) ||
1318 strlcat(old
, ".old", sizeof(old
)) >= sizeof(old
))
1319 fatal("known_hosts path too long");
1321 if ((fd
= mkstemp(tmp
)) == -1)
1322 fatal("mkstemp: %s", strerror(errno
));
1323 if ((ctx
.out
= fdopen(fd
, "w")) == NULL
) {
1326 fatal("fdopen: %s", strerror(oerrno
));
1330 /* XXX support identity_file == "-" for stdin */
1331 foreach_options
= find_host
? HKF_WANT_MATCH
: 0;
1332 foreach_options
|= print_fingerprint
? HKF_WANT_PARSE_KEY
: 0;
1333 if ((r
= hostkeys_foreach(identity_file
, (find_host
|| !hash_hosts
) ?
1334 known_hosts_find_delete
: known_hosts_hash
, &ctx
, name
, NULL
,
1335 foreach_options
)) != 0) {
1338 fatal("%s: hostkeys_foreach failed: %s", __func__
, ssh_err(r
));
1345 error("%s is not a valid known_hosts file.", identity_file
);
1347 error("Not replacing existing known_hosts "
1348 "file because of errors");
1352 } else if (delete_host
&& !ctx
.found_key
) {
1353 logit("Host %s not found in %s", name
, identity_file
);
1356 } else if (inplace
) {
1357 /* Backup existing file */
1358 if (unlink(old
) == -1 && errno
!= ENOENT
)
1359 fatal("unlink %.100s: %s", old
, strerror(errno
));
1360 if (link(identity_file
, old
) == -1)
1361 fatal("link %.100s to %.100s: %s", identity_file
, old
,
1363 /* Move new one into place */
1364 if (rename(tmp
, identity_file
) == -1) {
1365 error("rename\"%s\" to \"%s\": %s", tmp
, identity_file
,
1372 printf("%s updated.\n", identity_file
);
1373 printf("Original contents retained as %s\n", old
);
1374 if (ctx
.has_unhashed
) {
1375 logit("WARNING: %s contains unhashed entries", old
);
1376 logit("Delete this file to ensure privacy "
1381 exit (find_host
&& !ctx
.found_key
);
1385 * Perform changing a passphrase. The argument is the passwd structure
1386 * for the current user.
1389 do_change_passphrase(struct passwd
*pw
)
1392 char *old_passphrase
, *passphrase1
, *passphrase2
;
1394 struct sshkey
*private;
1398 ask_filename(pw
, "Enter file in which the key is");
1399 if (stat(identity_file
, &st
) == -1)
1400 fatal("%s: %s", identity_file
, strerror(errno
));
1401 /* Try to load the file with empty passphrase. */
1402 r
= sshkey_load_private(identity_file
, "", &private, &comment
);
1403 if (r
== SSH_ERR_KEY_WRONG_PASSPHRASE
) {
1404 if (identity_passphrase
)
1405 old_passphrase
= xstrdup(identity_passphrase
);
1408 read_passphrase("Enter old passphrase: ",
1410 r
= sshkey_load_private(identity_file
, old_passphrase
,
1411 &private, &comment
);
1412 explicit_bzero(old_passphrase
, strlen(old_passphrase
));
1413 free(old_passphrase
);
1416 } else if (r
!= 0) {
1418 fatal("Failed to load key %s: %s", identity_file
, ssh_err(r
));
1421 mprintf("Key has comment '%s'\n", comment
);
1423 /* Ask the new passphrase (twice). */
1424 if (identity_new_passphrase
) {
1425 passphrase1
= xstrdup(identity_new_passphrase
);
1429 read_passphrase("Enter new passphrase (empty for no "
1430 "passphrase): ", RP_ALLOW_STDIN
);
1431 passphrase2
= read_passphrase("Enter same passphrase again: ",
1434 /* Verify that they are the same. */
1435 if (strcmp(passphrase1
, passphrase2
) != 0) {
1436 explicit_bzero(passphrase1
, strlen(passphrase1
));
1437 explicit_bzero(passphrase2
, strlen(passphrase2
));
1440 printf("Pass phrases do not match. Try again.\n");
1443 /* Destroy the other copy. */
1444 explicit_bzero(passphrase2
, strlen(passphrase2
));
1448 /* Save the file using the new passphrase. */
1449 if ((r
= sshkey_save_private(private, identity_file
, passphrase1
,
1450 comment
, private_key_format
, openssh_format_cipher
, rounds
)) != 0) {
1451 error("Saving key \"%s\" failed: %s.",
1452 identity_file
, ssh_err(r
));
1453 explicit_bzero(passphrase1
, strlen(passphrase1
));
1455 sshkey_free(private);
1459 /* Destroy the passphrase and the copy of the key in memory. */
1460 explicit_bzero(passphrase1
, strlen(passphrase1
));
1462 sshkey_free(private); /* Destroys contents */
1465 printf("Your identification has been saved with the new passphrase.\n");
1470 * Print the SSHFP RR.
1473 do_print_resource_record(struct passwd
*pw
, char *fname
, char *hname
,
1476 struct sshkey
*public;
1477 char *comment
= NULL
;
1482 fatal("%s: no filename", __func__
);
1483 if (stat(fname
, &st
) == -1) {
1484 if (errno
== ENOENT
)
1486 fatal("%s: %s", fname
, strerror(errno
));
1488 if ((r
= sshkey_load_public(fname
, &public, &comment
)) != 0)
1489 fatal("Failed to read v2 public key from \"%s\": %s.",
1491 export_dns_rr(hname
, public, stdout
, print_generic
);
1492 sshkey_free(public);
1498 * Change the comment of a private key file.
1501 do_change_comment(struct passwd
*pw
, const char *identity_comment
)
1503 char new_comment
[1024], *comment
, *passphrase
;
1504 struct sshkey
*private;
1505 struct sshkey
*public;
1511 ask_filename(pw
, "Enter file in which the key is");
1512 if (stat(identity_file
, &st
) == -1)
1513 fatal("%s: %s", identity_file
, strerror(errno
));
1514 if ((r
= sshkey_load_private(identity_file
, "",
1515 &private, &comment
)) == 0)
1516 passphrase
= xstrdup("");
1517 else if (r
!= SSH_ERR_KEY_WRONG_PASSPHRASE
)
1518 fatal("Cannot load private key \"%s\": %s.",
1519 identity_file
, ssh_err(r
));
1521 if (identity_passphrase
)
1522 passphrase
= xstrdup(identity_passphrase
);
1523 else if (identity_new_passphrase
)
1524 passphrase
= xstrdup(identity_new_passphrase
);
1526 passphrase
= read_passphrase("Enter passphrase: ",
1528 /* Try to load using the passphrase. */
1529 if ((r
= sshkey_load_private(identity_file
, passphrase
,
1530 &private, &comment
)) != 0) {
1531 explicit_bzero(passphrase
, strlen(passphrase
));
1533 fatal("Cannot load private key \"%s\": %s.",
1534 identity_file
, ssh_err(r
));
1538 if (private->type
!= KEY_ED25519
&& private->type
!= KEY_XMSS
&&
1539 private_key_format
!= SSHKEY_PRIVATE_OPENSSH
) {
1540 error("Comments are only supported for keys stored in "
1541 "the new format (-o).");
1542 explicit_bzero(passphrase
, strlen(passphrase
));
1543 sshkey_free(private);
1547 printf("Old comment: %s\n", comment
);
1549 printf("No existing comment\n");
1551 if (identity_comment
) {
1552 strlcpy(new_comment
, identity_comment
, sizeof(new_comment
));
1554 printf("New comment: ");
1556 if (!fgets(new_comment
, sizeof(new_comment
), stdin
)) {
1557 explicit_bzero(passphrase
, strlen(passphrase
));
1558 sshkey_free(private);
1561 new_comment
[strcspn(new_comment
, "\n")] = '\0';
1563 if (comment
!= NULL
&& strcmp(comment
, new_comment
) == 0) {
1564 printf("No change to comment\n");
1566 sshkey_free(private);
1571 /* Save the file using the new passphrase. */
1572 if ((r
= sshkey_save_private(private, identity_file
, passphrase
,
1573 new_comment
, private_key_format
, openssh_format_cipher
,
1575 error("Saving key \"%s\" failed: %s",
1576 identity_file
, ssh_err(r
));
1577 explicit_bzero(passphrase
, strlen(passphrase
));
1579 sshkey_free(private);
1583 explicit_bzero(passphrase
, strlen(passphrase
));
1585 if ((r
= sshkey_from_private(private, &public)) != 0)
1586 fatal("sshkey_from_private failed: %s", ssh_err(r
));
1587 sshkey_free(private);
1589 strlcat(identity_file
, ".pub", sizeof(identity_file
));
1590 fd
= open(identity_file
, O_WRONLY
| O_CREAT
| O_TRUNC
, 0644);
1592 fatal("Could not save your public key in %s", identity_file
);
1593 f
= fdopen(fd
, "w");
1595 fatal("fdopen %s failed: %s", identity_file
, strerror(errno
));
1596 if ((r
= sshkey_write(public, f
)) != 0)
1597 fatal("write key failed: %s", ssh_err(r
));
1598 sshkey_free(public);
1599 fprintf(f
, " %s\n", new_comment
);
1604 if (strlen(new_comment
) > 0)
1605 printf("Comment '%s' applied\n", new_comment
);
1607 printf("Comment removed\n");
1613 add_flag_option(struct sshbuf
*c
, const char *name
)
1617 debug3("%s: %s", __func__
, name
);
1618 if ((r
= sshbuf_put_cstring(c
, name
)) != 0 ||
1619 (r
= sshbuf_put_string(c
, NULL
, 0)) != 0)
1620 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
1624 add_string_option(struct sshbuf
*c
, const char *name
, const char *value
)
1629 debug3("%s: %s=%s", __func__
, name
, value
);
1630 if ((b
= sshbuf_new()) == NULL
)
1631 fatal("%s: sshbuf_new failed", __func__
);
1632 if ((r
= sshbuf_put_cstring(b
, value
)) != 0 ||
1633 (r
= sshbuf_put_cstring(c
, name
)) != 0 ||
1634 (r
= sshbuf_put_stringb(c
, b
)) != 0)
1635 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
1640 #define OPTIONS_CRITICAL 1
1641 #define OPTIONS_EXTENSIONS 2
1643 prepare_options_buf(struct sshbuf
*c
, int which
)
1648 if ((which
& OPTIONS_CRITICAL
) != 0 &&
1649 certflags_command
!= NULL
)
1650 add_string_option(c
, "force-command", certflags_command
);
1651 if ((which
& OPTIONS_EXTENSIONS
) != 0 &&
1652 (certflags_flags
& CERTOPT_X_FWD
) != 0)
1653 add_flag_option(c
, "permit-X11-forwarding");
1654 if ((which
& OPTIONS_EXTENSIONS
) != 0 &&
1655 (certflags_flags
& CERTOPT_AGENT_FWD
) != 0)
1656 add_flag_option(c
, "permit-agent-forwarding");
1657 if ((which
& OPTIONS_EXTENSIONS
) != 0 &&
1658 (certflags_flags
& CERTOPT_PORT_FWD
) != 0)
1659 add_flag_option(c
, "permit-port-forwarding");
1660 if ((which
& OPTIONS_EXTENSIONS
) != 0 &&
1661 (certflags_flags
& CERTOPT_PTY
) != 0)
1662 add_flag_option(c
, "permit-pty");
1663 if ((which
& OPTIONS_EXTENSIONS
) != 0 &&
1664 (certflags_flags
& CERTOPT_USER_RC
) != 0)
1665 add_flag_option(c
, "permit-user-rc");
1666 if ((which
& OPTIONS_CRITICAL
) != 0 &&
1667 (certflags_flags
& CERTOPT_NO_REQUIRE_USER_PRESENCE
) != 0)
1668 add_flag_option(c
, "no-touch-required");
1669 if ((which
& OPTIONS_CRITICAL
) != 0 &&
1670 certflags_src_addr
!= NULL
)
1671 add_string_option(c
, "source-address", certflags_src_addr
);
1672 for (i
= 0; i
< ncert_userext
; i
++) {
1673 if ((cert_userext
[i
].crit
&& (which
& OPTIONS_EXTENSIONS
)) ||
1674 (!cert_userext
[i
].crit
&& (which
& OPTIONS_CRITICAL
)))
1676 if (cert_userext
[i
].val
== NULL
)
1677 add_flag_option(c
, cert_userext
[i
].key
);
1679 add_string_option(c
, cert_userext
[i
].key
,
1680 cert_userext
[i
].val
);
1685 static struct sshkey
*
1686 load_pkcs11_key(char *path
)
1688 #ifdef ENABLE_PKCS11
1689 struct sshkey
**keys
= NULL
, *public, *private = NULL
;
1692 if ((r
= sshkey_load_public(path
, &public, NULL
)) != 0)
1693 fatal("Couldn't load CA public key \"%s\": %s",
1696 nkeys
= pkcs11_add_provider(pkcs11provider
, identity_passphrase
, &keys
);
1697 debug3("%s: %d keys", __func__
, nkeys
);
1699 fatal("cannot read public key from pkcs11");
1700 for (i
= 0; i
< nkeys
; i
++) {
1701 if (sshkey_equal_public(public, keys
[i
])) {
1705 sshkey_free(keys
[i
]);
1708 sshkey_free(public);
1711 fatal("no pkcs11 support");
1712 #endif /* ENABLE_PKCS11 */
1715 /* Signer for sshkey_certify_custom that uses the agent */
1717 agent_signer(struct sshkey
*key
, u_char
**sigp
, size_t *lenp
,
1718 const u_char
*data
, size_t datalen
,
1719 const char *alg
, const char *provider
, u_int compat
, void *ctx
)
1721 int *agent_fdp
= (int *)ctx
;
1723 return ssh_agent_sign(*agent_fdp
, key
, sigp
, lenp
,
1724 data
, datalen
, alg
, compat
);
1728 do_ca_sign(struct passwd
*pw
, const char *ca_key_path
, int prefer_agent
,
1729 unsigned long long cert_serial
, int cert_serial_autoinc
,
1730 int argc
, char **argv
)
1732 int r
, i
, fd
, found
, agent_fd
= -1;
1734 struct sshkey
*ca
, *public;
1735 char valid
[64], *otmp
, *tmp
, *cp
, *out
, *comment
;
1736 char *ca_fp
= NULL
, **plist
= NULL
;
1738 struct ssh_identitylist
*agent_ids
;
1740 struct notifier_ctx
*notifier
= NULL
;
1742 #ifdef ENABLE_PKCS11
1745 tmp
= tilde_expand_filename(ca_key_path
, pw
->pw_uid
);
1746 if (pkcs11provider
!= NULL
) {
1747 /* If a PKCS#11 token was specified then try to use it */
1748 if ((ca
= load_pkcs11_key(tmp
)) == NULL
)
1749 fatal("No PKCS#11 key matching %s found", ca_key_path
);
1750 } else if (prefer_agent
) {
1752 * Agent signature requested. Try to use agent after making
1753 * sure the public key specified is actually present in the
1756 if ((r
= sshkey_load_public(tmp
, &ca
, NULL
)) != 0)
1757 fatal("Cannot load CA public key %s: %s",
1759 if ((r
= ssh_get_authentication_socket(&agent_fd
)) != 0)
1760 fatal("Cannot use public key for CA signature: %s",
1762 if ((r
= ssh_fetch_identitylist(agent_fd
, &agent_ids
)) != 0)
1763 fatal("Retrieve agent key list: %s", ssh_err(r
));
1765 for (j
= 0; j
< agent_ids
->nkeys
; j
++) {
1766 if (sshkey_equal(ca
, agent_ids
->keys
[j
])) {
1772 fatal("CA key %s not found in agent", tmp
);
1773 ssh_free_identitylist(agent_ids
);
1774 ca
->flags
|= SSHKEY_FLAG_EXT
;
1776 /* CA key is assumed to be a private key on the filesystem */
1777 ca
= load_identity(tmp
, NULL
);
1781 if (key_type_name
!= NULL
&&
1782 sshkey_type_from_name(key_type_name
) != ca
->type
) {
1783 fatal("CA key type %s doesn't match specified %s",
1784 sshkey_ssh_name(ca
), key_type_name
);
1786 ca_fp
= sshkey_fingerprint(ca
, fingerprint_hash
, SSH_FP_DEFAULT
);
1788 for (i
= 0; i
< argc
; i
++) {
1789 /* Split list of principals */
1791 if (cert_principals
!= NULL
) {
1792 otmp
= tmp
= xstrdup(cert_principals
);
1794 for (; (cp
= strsep(&tmp
, ",")) != NULL
; n
++) {
1795 plist
= xreallocarray(plist
, n
+ 1, sizeof(*plist
));
1796 if (*(plist
[n
] = xstrdup(cp
)) == '\0')
1797 fatal("Empty principal name");
1801 if (n
> SSHKEY_CERT_MAX_PRINCIPALS
)
1802 fatal("Too many certificate principals specified");
1804 tmp
= tilde_expand_filename(argv
[i
], pw
->pw_uid
);
1805 if ((r
= sshkey_load_public(tmp
, &public, &comment
)) != 0)
1806 fatal("%s: unable to open \"%s\": %s",
1807 __func__
, tmp
, ssh_err(r
));
1808 if (sshkey_is_cert(public))
1809 fatal("%s: key \"%s\" type %s cannot be certified",
1810 __func__
, tmp
, sshkey_type(public));
1812 /* Prepare certificate to sign */
1813 if ((r
= sshkey_to_certified(public)) != 0)
1814 fatal("Could not upgrade key %s to certificate: %s",
1816 public->cert
->type
= cert_key_type
;
1817 public->cert
->serial
= (u_int64_t
)cert_serial
;
1818 public->cert
->key_id
= xstrdup(cert_key_id
);
1819 public->cert
->nprincipals
= n
;
1820 public->cert
->principals
= plist
;
1821 public->cert
->valid_after
= cert_valid_from
;
1822 public->cert
->valid_before
= cert_valid_to
;
1823 prepare_options_buf(public->cert
->critical
, OPTIONS_CRITICAL
);
1824 prepare_options_buf(public->cert
->extensions
,
1825 OPTIONS_EXTENSIONS
);
1826 if ((r
= sshkey_from_private(ca
,
1827 &public->cert
->signature_key
)) != 0)
1828 fatal("sshkey_from_private (ca key): %s", ssh_err(r
));
1830 if (agent_fd
!= -1 && (ca
->flags
& SSHKEY_FLAG_EXT
) != 0) {
1831 if ((r
= sshkey_certify_custom(public, ca
,
1832 key_type_name
, sk_provider
, agent_signer
,
1834 fatal("Couldn't certify key %s via agent: %s",
1837 if (sshkey_is_sk(ca
) &&
1838 (ca
->sk_flags
& SSH_SK_USER_PRESENCE_REQD
)) {
1839 notifier
= notify_start(0,
1840 "Confirm user presence for key %s %s",
1841 sshkey_type(ca
), ca_fp
);
1843 r
= sshkey_certify(public, ca
, key_type_name
,
1845 notify_complete(notifier
);
1847 fatal("Couldn't certify key %s: %s",
1851 if ((cp
= strrchr(tmp
, '.')) != NULL
&& strcmp(cp
, ".pub") == 0)
1853 xasprintf(&out
, "%s-cert.pub", tmp
);
1856 if ((fd
= open(out
, O_WRONLY
|O_CREAT
|O_TRUNC
, 0644)) == -1)
1857 fatal("Could not open \"%s\" for writing: %s", out
,
1859 if ((f
= fdopen(fd
, "w")) == NULL
)
1860 fatal("%s: fdopen: %s", __func__
, strerror(errno
));
1861 if ((r
= sshkey_write(public, f
)) != 0)
1862 fatal("Could not write certified key to %s: %s",
1864 fprintf(f
, " %s\n", comment
);
1868 sshkey_format_cert_validity(public->cert
,
1869 valid
, sizeof(valid
));
1870 logit("Signed %s key %s: id \"%s\" serial %llu%s%s "
1871 "valid %s", sshkey_cert_type(public),
1872 out
, public->cert
->key_id
,
1873 (unsigned long long)public->cert
->serial
,
1874 cert_principals
!= NULL
? " for " : "",
1875 cert_principals
!= NULL
? cert_principals
: "",
1879 sshkey_free(public);
1881 if (cert_serial_autoinc
)
1885 #ifdef ENABLE_PKCS11
1892 parse_relative_time(const char *s
, time_t now
)
1896 mul
= *s
== '-' ? -1 : 1;
1898 if ((secs
= convtime(s
+ 1)) == -1)
1899 fatal("Invalid relative certificate time %s", s
);
1900 if (mul
== -1 && secs
> now
)
1901 fatal("Certificate time %s cannot be represented", s
);
1902 return now
+ (u_int64_t
)(secs
* mul
);
1906 parse_cert_times(char *timespec
)
1909 time_t now
= time(NULL
);
1912 /* +timespec relative to now */
1913 if (*timespec
== '+' && strchr(timespec
, ':') == NULL
) {
1914 if ((secs
= convtime(timespec
+ 1)) == -1)
1915 fatal("Invalid relative certificate life %s", timespec
);
1916 cert_valid_to
= now
+ secs
;
1918 * Backdate certificate one minute to avoid problems on hosts
1919 * with poorly-synchronised clocks.
1921 cert_valid_from
= ((now
- 59)/ 60) * 60;
1927 * from := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS | "always"
1928 * to := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS | "forever"
1930 from
= xstrdup(timespec
);
1931 to
= strchr(from
, ':');
1932 if (to
== NULL
|| from
== to
|| *(to
+ 1) == '\0')
1933 fatal("Invalid certificate life specification %s", timespec
);
1936 if (*from
== '-' || *from
== '+')
1937 cert_valid_from
= parse_relative_time(from
, now
);
1938 else if (strcmp(from
, "always") == 0)
1939 cert_valid_from
= 0;
1940 else if (parse_absolute_time(from
, &cert_valid_from
) != 0)
1941 fatal("Invalid from time \"%s\"", from
);
1943 if (*to
== '-' || *to
== '+')
1944 cert_valid_to
= parse_relative_time(to
, now
);
1945 else if (strcmp(to
, "forever") == 0)
1946 cert_valid_to
= ~(u_int64_t
)0;
1947 else if (parse_absolute_time(to
, &cert_valid_to
) != 0)
1948 fatal("Invalid to time \"%s\"", to
);
1950 if (cert_valid_to
<= cert_valid_from
)
1951 fatal("Empty certificate validity interval");
1956 add_cert_option(char *opt
)
1961 if (strcasecmp(opt
, "clear") == 0)
1962 certflags_flags
= 0;
1963 else if (strcasecmp(opt
, "no-x11-forwarding") == 0)
1964 certflags_flags
&= ~CERTOPT_X_FWD
;
1965 else if (strcasecmp(opt
, "permit-x11-forwarding") == 0)
1966 certflags_flags
|= CERTOPT_X_FWD
;
1967 else if (strcasecmp(opt
, "no-agent-forwarding") == 0)
1968 certflags_flags
&= ~CERTOPT_AGENT_FWD
;
1969 else if (strcasecmp(opt
, "permit-agent-forwarding") == 0)
1970 certflags_flags
|= CERTOPT_AGENT_FWD
;
1971 else if (strcasecmp(opt
, "no-port-forwarding") == 0)
1972 certflags_flags
&= ~CERTOPT_PORT_FWD
;
1973 else if (strcasecmp(opt
, "permit-port-forwarding") == 0)
1974 certflags_flags
|= CERTOPT_PORT_FWD
;
1975 else if (strcasecmp(opt
, "no-pty") == 0)
1976 certflags_flags
&= ~CERTOPT_PTY
;
1977 else if (strcasecmp(opt
, "permit-pty") == 0)
1978 certflags_flags
|= CERTOPT_PTY
;
1979 else if (strcasecmp(opt
, "no-user-rc") == 0)
1980 certflags_flags
&= ~CERTOPT_USER_RC
;
1981 else if (strcasecmp(opt
, "permit-user-rc") == 0)
1982 certflags_flags
|= CERTOPT_USER_RC
;
1983 else if (strcasecmp(opt
, "touch-required") == 0)
1984 certflags_flags
&= ~CERTOPT_NO_REQUIRE_USER_PRESENCE
;
1985 else if (strcasecmp(opt
, "no-touch-required") == 0)
1986 certflags_flags
|= CERTOPT_NO_REQUIRE_USER_PRESENCE
;
1987 else if (strncasecmp(opt
, "force-command=", 14) == 0) {
1990 fatal("Empty force-command option");
1991 if (certflags_command
!= NULL
)
1992 fatal("force-command already specified");
1993 certflags_command
= xstrdup(val
);
1994 } else if (strncasecmp(opt
, "source-address=", 15) == 0) {
1997 fatal("Empty source-address option");
1998 if (certflags_src_addr
!= NULL
)
1999 fatal("source-address already specified");
2000 if (addr_match_cidr_list(NULL
, val
) != 0)
2001 fatal("Invalid source-address list");
2002 certflags_src_addr
= xstrdup(val
);
2003 } else if (strncasecmp(opt
, "extension:", 10) == 0 ||
2004 (iscrit
= (strncasecmp(opt
, "critical:", 9) == 0))) {
2005 val
= xstrdup(strchr(opt
, ':') + 1);
2006 if ((cp
= strchr(val
, '=')) != NULL
)
2008 cert_userext
= xreallocarray(cert_userext
, ncert_userext
+ 1,
2009 sizeof(*cert_userext
));
2010 cert_userext
[ncert_userext
].key
= val
;
2011 cert_userext
[ncert_userext
].val
= cp
== NULL
?
2013 cert_userext
[ncert_userext
].crit
= iscrit
;
2016 fatal("Unsupported certificate option \"%s\"", opt
);
2020 show_options(struct sshbuf
*optbuf
, int in_critical
)
2023 struct sshbuf
*options
, *option
= NULL
;
2026 if ((options
= sshbuf_fromb(optbuf
)) == NULL
)
2027 fatal("%s: sshbuf_fromb failed", __func__
);
2028 while (sshbuf_len(options
) != 0) {
2029 sshbuf_free(option
);
2031 if ((r
= sshbuf_get_cstring(options
, &name
, NULL
)) != 0 ||
2032 (r
= sshbuf_froms(options
, &option
)) != 0)
2033 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
2034 printf(" %s", name
);
2036 (strcmp(name
, "permit-X11-forwarding") == 0 ||
2037 strcmp(name
, "permit-agent-forwarding") == 0 ||
2038 strcmp(name
, "permit-port-forwarding") == 0 ||
2039 strcmp(name
, "permit-pty") == 0 ||
2040 strcmp(name
, "permit-user-rc") == 0 ||
2041 strcmp(name
, "no-touch-required") == 0)) {
2043 } else if (in_critical
&&
2044 (strcmp(name
, "force-command") == 0 ||
2045 strcmp(name
, "source-address") == 0)) {
2046 if ((r
= sshbuf_get_cstring(option
, &arg
, NULL
)) != 0)
2047 fatal("%s: buffer error: %s",
2048 __func__
, ssh_err(r
));
2049 printf(" %s\n", arg
);
2052 printf(" UNKNOWN OPTION (len %zu)\n",
2053 sshbuf_len(option
));
2054 sshbuf_reset(option
);
2057 if (sshbuf_len(option
) != 0)
2058 fatal("Option corrupt: extra data at end");
2060 sshbuf_free(option
);
2061 sshbuf_free(options
);
2065 print_cert(struct sshkey
*key
)
2067 char valid
[64], *key_fp
, *ca_fp
;
2070 key_fp
= sshkey_fingerprint(key
, fingerprint_hash
, SSH_FP_DEFAULT
);
2071 ca_fp
= sshkey_fingerprint(key
->cert
->signature_key
,
2072 fingerprint_hash
, SSH_FP_DEFAULT
);
2073 if (key_fp
== NULL
|| ca_fp
== NULL
)
2074 fatal("%s: sshkey_fingerprint fail", __func__
);
2075 sshkey_format_cert_validity(key
->cert
, valid
, sizeof(valid
));
2077 printf(" Type: %s %s certificate\n", sshkey_ssh_name(key
),
2078 sshkey_cert_type(key
));
2079 printf(" Public key: %s %s\n", sshkey_type(key
), key_fp
);
2080 printf(" Signing CA: %s %s (using %s)\n",
2081 sshkey_type(key
->cert
->signature_key
), ca_fp
,
2082 key
->cert
->signature_type
);
2083 printf(" Key ID: \"%s\"\n", key
->cert
->key_id
);
2084 printf(" Serial: %llu\n", (unsigned long long)key
->cert
->serial
);
2085 printf(" Valid: %s\n", valid
);
2086 printf(" Principals: ");
2087 if (key
->cert
->nprincipals
== 0)
2090 for (i
= 0; i
< key
->cert
->nprincipals
; i
++)
2092 key
->cert
->principals
[i
]);
2095 printf(" Critical Options: ");
2096 if (sshbuf_len(key
->cert
->critical
) == 0)
2100 show_options(key
->cert
->critical
, 1);
2102 printf(" Extensions: ");
2103 if (sshbuf_len(key
->cert
->extensions
) == 0)
2107 show_options(key
->cert
->extensions
, 0);
2112 do_show_cert(struct passwd
*pw
)
2114 struct sshkey
*key
= NULL
;
2116 int r
, is_stdin
= 0, ok
= 0;
2118 char *cp
, *line
= NULL
;
2120 size_t linesize
= 0;
2124 ask_filename(pw
, "Enter file in which the key is");
2125 if (strcmp(identity_file
, "-") != 0 && stat(identity_file
, &st
) == -1)
2126 fatal("%s: %s: %s", __progname
, identity_file
, strerror(errno
));
2128 path
= identity_file
;
2129 if (strcmp(path
, "-") == 0) {
2133 } else if ((f
= fopen(identity_file
, "r")) == NULL
)
2134 fatal("fopen %s: %s", identity_file
, strerror(errno
));
2136 while (getline(&line
, &linesize
, f
) != -1) {
2140 /* Trim leading space and comments */
2141 cp
= line
+ strspn(line
, " \t");
2142 if (*cp
== '#' || *cp
== '\0')
2144 if ((key
= sshkey_new(KEY_UNSPEC
)) == NULL
)
2145 fatal("sshkey_new");
2146 if ((r
= sshkey_read(key
, &cp
)) != 0) {
2147 error("%s:%lu: invalid key: %s", path
,
2151 if (!sshkey_is_cert(key
)) {
2152 error("%s:%lu is not a certificate", path
, lnum
);
2156 if (!is_stdin
&& lnum
== 1)
2157 printf("%s:\n", path
);
2159 printf("%s:%lu:\n", path
, lnum
);
2169 load_krl(const char *path
, struct ssh_krl
**krlp
)
2171 struct sshbuf
*krlbuf
;
2174 if ((krlbuf
= sshbuf_new()) == NULL
)
2175 fatal("sshbuf_new failed");
2176 if ((fd
= open(path
, O_RDONLY
)) == -1)
2177 fatal("open %s: %s", path
, strerror(errno
));
2178 if ((r
= sshkey_load_file(fd
, krlbuf
)) != 0)
2179 fatal("Unable to load KRL: %s", ssh_err(r
));
2181 /* XXX check sigs */
2182 if ((r
= ssh_krl_from_blob(krlbuf
, krlp
, NULL
, 0)) != 0 ||
2184 fatal("Invalid KRL file: %s", ssh_err(r
));
2185 sshbuf_free(krlbuf
);
2189 hash_to_blob(const char *cp
, u_char
**blobp
, size_t *lenp
,
2190 const char *file
, u_long lnum
)
2197 if (strncmp(cp
, "SHA256:", 7) != 0)
2198 fatal("%s:%lu: unsupported hash algorithm", file
, lnum
);
2202 * OpenSSH base64 hashes omit trailing '='
2203 * characters; put them back for decode.
2206 tmp
= xmalloc(tlen
+ 4 + 1);
2207 strlcpy(tmp
, cp
, tlen
+ 1);
2208 while ((tlen
% 4) != 0) {
2212 if ((b
= sshbuf_new()) == NULL
)
2213 fatal("%s: sshbuf_new failed", __func__
);
2214 if ((r
= sshbuf_b64tod(b
, tmp
)) != 0)
2215 fatal("%s:%lu: decode hash failed: %s", file
, lnum
, ssh_err(r
));
2217 *lenp
= sshbuf_len(b
);
2218 *blobp
= xmalloc(*lenp
);
2219 memcpy(*blobp
, sshbuf_ptr(b
), *lenp
);
2224 update_krl_from_file(struct passwd
*pw
, const char *file
, int wild_ca
,
2225 const struct sshkey
*ca
, struct ssh_krl
*krl
)
2227 struct sshkey
*key
= NULL
;
2229 char *path
, *cp
, *ep
, *line
= NULL
;
2230 u_char
*blob
= NULL
;
2231 size_t blen
= 0, linesize
= 0;
2232 unsigned long long serial
, serial2
;
2233 int i
, was_explicit_key
, was_sha1
, was_sha256
, was_hash
, r
;
2236 path
= tilde_expand_filename(file
, pw
->pw_uid
);
2237 if (strcmp(path
, "-") == 0) {
2240 path
= xstrdup("(standard input)");
2241 } else if ((krl_spec
= fopen(path
, "r")) == NULL
)
2242 fatal("fopen %s: %s", path
, strerror(errno
));
2245 printf("Revoking from %s\n", path
);
2246 while (getline(&line
, &linesize
, krl_spec
) != -1) {
2248 was_explicit_key
= was_sha1
= was_sha256
= was_hash
= 0;
2249 cp
= line
+ strspn(line
, " \t");
2250 /* Trim trailing space, comments and strip \n */
2251 for (i
= 0, r
= -1; cp
[i
] != '\0'; i
++) {
2252 if (cp
[i
] == '#' || cp
[i
] == '\n') {
2256 if (cp
[i
] == ' ' || cp
[i
] == '\t') {
2257 /* Remember the start of a span of whitespace */
2267 if (strncasecmp(cp
, "serial:", 7) == 0) {
2268 if (ca
== NULL
&& !wild_ca
) {
2269 fatal("revoking certificates by serial number "
2270 "requires specification of a CA key");
2273 cp
= cp
+ strspn(cp
, " \t");
2275 serial
= strtoull(cp
, &ep
, 0);
2276 if (*cp
== '\0' || (*ep
!= '\0' && *ep
!= '-'))
2277 fatal("%s:%lu: invalid serial \"%s\"",
2279 if (errno
== ERANGE
&& serial
== ULLONG_MAX
)
2280 fatal("%s:%lu: serial out of range",
2286 serial2
= strtoull(cp
, &ep
, 0);
2287 if (*cp
== '\0' || *ep
!= '\0')
2288 fatal("%s:%lu: invalid serial \"%s\"",
2290 if (errno
== ERANGE
&& serial2
== ULLONG_MAX
)
2291 fatal("%s:%lu: serial out of range",
2293 if (serial2
<= serial
)
2294 fatal("%s:%lu: invalid serial range "
2295 "%llu:%llu", path
, lnum
,
2296 (unsigned long long)serial
,
2297 (unsigned long long)serial2
);
2299 if (ssh_krl_revoke_cert_by_serial_range(krl
,
2300 ca
, serial
, serial2
) != 0) {
2301 fatal("%s: revoke serial failed",
2304 } else if (strncasecmp(cp
, "id:", 3) == 0) {
2305 if (ca
== NULL
&& !wild_ca
) {
2306 fatal("revoking certificates by key ID "
2307 "requires specification of a CA key");
2310 cp
= cp
+ strspn(cp
, " \t");
2311 if (ssh_krl_revoke_cert_by_key_id(krl
, ca
, cp
) != 0)
2312 fatal("%s: revoke key ID failed", __func__
);
2313 } else if (strncasecmp(cp
, "hash:", 5) == 0) {
2315 cp
= cp
+ strspn(cp
, " \t");
2316 hash_to_blob(cp
, &blob
, &blen
, file
, lnum
);
2317 r
= ssh_krl_revoke_key_sha256(krl
, blob
, blen
);
2319 if (strncasecmp(cp
, "key:", 4) == 0) {
2321 cp
= cp
+ strspn(cp
, " \t");
2322 was_explicit_key
= 1;
2323 } else if (strncasecmp(cp
, "sha1:", 5) == 0) {
2325 cp
= cp
+ strspn(cp
, " \t");
2327 } else if (strncasecmp(cp
, "sha256:", 7) == 0) {
2329 cp
= cp
+ strspn(cp
, " \t");
2332 * Just try to process the line as a key.
2333 * Parsing will fail if it isn't.
2336 if ((key
= sshkey_new(KEY_UNSPEC
)) == NULL
)
2337 fatal("sshkey_new");
2338 if ((r
= sshkey_read(key
, &cp
)) != 0)
2339 fatal("%s:%lu: invalid key: %s",
2340 path
, lnum
, ssh_err(r
));
2341 if (was_explicit_key
)
2342 r
= ssh_krl_revoke_key_explicit(krl
, key
);
2343 else if (was_sha1
) {
2344 if (sshkey_fingerprint_raw(key
,
2345 SSH_DIGEST_SHA1
, &blob
, &blen
) != 0) {
2346 fatal("%s:%lu: fingerprint failed",
2349 r
= ssh_krl_revoke_key_sha1(krl
, blob
, blen
);
2350 } else if (was_sha256
) {
2351 if (sshkey_fingerprint_raw(key
,
2352 SSH_DIGEST_SHA256
, &blob
, &blen
) != 0) {
2353 fatal("%s:%lu: fingerprint failed",
2356 r
= ssh_krl_revoke_key_sha256(krl
, blob
, blen
);
2358 r
= ssh_krl_revoke_key(krl
, key
);
2360 fatal("%s: revoke key failed: %s",
2361 __func__
, ssh_err(r
));
2362 freezero(blob
, blen
);
2368 if (strcmp(path
, "-") != 0)
2375 do_gen_krl(struct passwd
*pw
, int updating
, const char *ca_key_path
,
2376 unsigned long long krl_version
, const char *krl_comment
,
2377 int argc
, char **argv
)
2379 struct ssh_krl
*krl
;
2381 struct sshkey
*ca
= NULL
;
2382 int fd
, i
, r
, wild_ca
= 0;
2384 struct sshbuf
*kbuf
;
2386 if (*identity_file
== '\0')
2387 fatal("KRL generation requires an output file");
2388 if (stat(identity_file
, &sb
) == -1) {
2389 if (errno
!= ENOENT
)
2390 fatal("Cannot access KRL \"%s\": %s",
2391 identity_file
, strerror(errno
));
2393 fatal("KRL \"%s\" does not exist", identity_file
);
2395 if (ca_key_path
!= NULL
) {
2396 if (strcasecmp(ca_key_path
, "none") == 0)
2399 tmp
= tilde_expand_filename(ca_key_path
, pw
->pw_uid
);
2400 if ((r
= sshkey_load_public(tmp
, &ca
, NULL
)) != 0)
2401 fatal("Cannot load CA public key %s: %s",
2408 load_krl(identity_file
, &krl
);
2409 else if ((krl
= ssh_krl_init()) == NULL
)
2410 fatal("couldn't create KRL");
2412 if (krl_version
!= 0)
2413 ssh_krl_set_version(krl
, krl_version
);
2414 if (krl_comment
!= NULL
)
2415 ssh_krl_set_comment(krl
, krl_comment
);
2417 for (i
= 0; i
< argc
; i
++)
2418 update_krl_from_file(pw
, argv
[i
], wild_ca
, ca
, krl
);
2420 if ((kbuf
= sshbuf_new()) == NULL
)
2421 fatal("sshbuf_new failed");
2422 if (ssh_krl_to_blob(krl
, kbuf
, NULL
, 0) != 0)
2423 fatal("Couldn't generate KRL");
2424 if ((fd
= open(identity_file
, O_WRONLY
|O_CREAT
|O_TRUNC
, 0644)) == -1)
2425 fatal("open %s: %s", identity_file
, strerror(errno
));
2426 if (atomicio(vwrite
, fd
, sshbuf_mutable_ptr(kbuf
), sshbuf_len(kbuf
)) !=
2428 fatal("write %s: %s", identity_file
, strerror(errno
));
2436 do_check_krl(struct passwd
*pw
, int argc
, char **argv
)
2440 struct ssh_krl
*krl
;
2443 if (*identity_file
== '\0')
2444 fatal("KRL checking requires an input file");
2445 load_krl(identity_file
, &krl
);
2446 for (i
= 0; i
< argc
; i
++) {
2447 if ((r
= sshkey_load_public(argv
[i
], &k
, &comment
)) != 0)
2448 fatal("Cannot load public key %s: %s",
2449 argv
[i
], ssh_err(r
));
2450 r
= ssh_krl_check_key(krl
, k
);
2451 printf("%s%s%s%s: %s\n", argv
[i
],
2452 *comment
? " (" : "", comment
, *comment
? ")" : "",
2453 r
== 0 ? "ok" : "REVOKED");
2463 static struct sshkey
*
2464 load_sign_key(const char *keypath
, const struct sshkey
*pubkey
)
2466 size_t i
, slen
, plen
= strlen(keypath
);
2467 char *privpath
= xstrdup(keypath
);
2468 const char *suffixes
[] = { "-cert.pub", ".pub", NULL
};
2469 struct sshkey
*ret
= NULL
, *privkey
= NULL
;
2473 * If passed a public key filename, then try to locate the correponding
2474 * private key. This lets us specify certificates on the command-line
2475 * and have ssh-keygen find the appropriate private key.
2477 for (i
= 0; suffixes
[i
]; i
++) {
2478 slen
= strlen(suffixes
[i
]);
2480 strcmp(privpath
+ plen
- slen
, suffixes
[i
]) != 0)
2482 privpath
[plen
- slen
] = '\0';
2483 debug("%s: %s looks like a public key, using private key "
2484 "path %s instead", __func__
, keypath
, privpath
);
2486 if ((privkey
= load_identity(privpath
, NULL
)) == NULL
) {
2487 error("Couldn't load identity %s", keypath
);
2490 if (!sshkey_equal_public(pubkey
, privkey
)) {
2491 error("Public key %s doesn't match private %s",
2495 if (sshkey_is_cert(pubkey
) && !sshkey_is_cert(privkey
)) {
2497 * Graft the certificate onto the private key to make
2498 * it capable of signing.
2500 if ((r
= sshkey_to_certified(privkey
)) != 0) {
2501 error("%s: sshkey_to_certified: %s", __func__
,
2505 if ((r
= sshkey_cert_copy(pubkey
, privkey
)) != 0) {
2506 error("%s: sshkey_cert_copy: %s", __func__
, ssh_err(r
));
2514 sshkey_free(privkey
);
2520 sign_one(struct sshkey
*signkey
, const char *filename
, int fd
,
2521 const char *sig_namespace
, sshsig_signer
*signer
, void *signer_ctx
)
2523 struct sshbuf
*sigbuf
= NULL
, *abuf
= NULL
;
2524 int r
= SSH_ERR_INTERNAL_ERROR
, wfd
= -1, oerrno
;
2525 char *wfile
= NULL
, *asig
= NULL
, *fp
= NULL
;
2528 if (fd
== STDIN_FILENO
)
2529 fprintf(stderr
, "Signing data on standard input\n");
2531 fprintf(stderr
, "Signing file %s\n", filename
);
2533 if (signer
== NULL
&& sshkey_is_sk(signkey
) &&
2534 (signkey
->sk_flags
& SSH_SK_USER_PRESENCE_REQD
)) {
2535 if ((fp
= sshkey_fingerprint(signkey
, fingerprint_hash
,
2536 SSH_FP_DEFAULT
)) == NULL
)
2537 fatal("%s: sshkey_fingerprint failed", __func__
);
2538 fprintf(stderr
, "Confirm user presence for key %s %s\n",
2539 sshkey_type(signkey
), fp
);
2542 if ((r
= sshsig_sign_fd(signkey
, NULL
, sk_provider
, fd
, sig_namespace
,
2543 &sigbuf
, signer
, signer_ctx
)) != 0) {
2544 error("Signing %s failed: %s", filename
, ssh_err(r
));
2547 if ((r
= sshsig_armor(sigbuf
, &abuf
)) != 0) {
2548 error("%s: sshsig_armor: %s", __func__
, ssh_err(r
));
2551 if ((asig
= sshbuf_dup_string(abuf
)) == NULL
) {
2552 error("%s: buffer error", __func__
);
2553 r
= SSH_ERR_ALLOC_FAIL
;
2557 if (fd
== STDIN_FILENO
) {
2558 fputs(asig
, stdout
);
2561 xasprintf(&wfile
, "%s.sig", filename
);
2562 if (confirm_overwrite(wfile
)) {
2563 if ((wfd
= open(wfile
, O_WRONLY
|O_CREAT
|O_TRUNC
,
2566 error("Cannot open %s: %s",
2567 wfile
, strerror(errno
));
2569 r
= SSH_ERR_SYSTEM_ERROR
;
2572 if (atomicio(vwrite
, wfd
, asig
,
2573 strlen(asig
)) != strlen(asig
)) {
2575 error("Cannot write to %s: %s",
2576 wfile
, strerror(errno
));
2578 r
= SSH_ERR_SYSTEM_ERROR
;
2582 fprintf(stderr
, "Write signature to %s\n",
2593 sshbuf_free(sigbuf
);
2600 sign(const char *keypath
, const char *sig_namespace
, int argc
, char **argv
)
2602 int i
, fd
= -1, r
, ret
= -1;
2604 struct sshkey
*pubkey
= NULL
, *privkey
= NULL
, *signkey
= NULL
;
2605 sshsig_signer
*signer
= NULL
;
2607 /* Check file arguments. */
2608 for (i
= 0; i
< argc
; i
++) {
2609 if (strcmp(argv
[i
], "-") != 0)
2611 if (i
> 0 || argc
> 1)
2612 fatal("Cannot sign mix of paths and standard input");
2615 if ((r
= sshkey_load_public(keypath
, &pubkey
, NULL
)) != 0) {
2616 error("Couldn't load public key %s: %s", keypath
, ssh_err(r
));
2620 if ((r
= ssh_get_authentication_socket(&agent_fd
)) != 0)
2621 debug("Couldn't get agent socket: %s", ssh_err(r
));
2623 if ((r
= ssh_agent_has_key(agent_fd
, pubkey
)) == 0)
2624 signer
= agent_signer
;
2626 debug("Couldn't find key in agent: %s", ssh_err(r
));
2629 if (signer
== NULL
) {
2630 /* Not using agent - try to load private key */
2631 if ((privkey
= load_sign_key(keypath
, pubkey
)) == NULL
)
2635 /* Will use key in agent */
2640 if ((r
= sign_one(signkey
, "(stdin)", STDIN_FILENO
,
2641 sig_namespace
, signer
, &agent_fd
)) != 0)
2644 for (i
= 0; i
< argc
; i
++) {
2645 if (strcmp(argv
[i
], "-") == 0)
2647 else if ((fd
= open(argv
[i
], O_RDONLY
)) == -1) {
2648 error("Cannot open %s for signing: %s",
2649 argv
[i
], strerror(errno
));
2652 if ((r
= sign_one(signkey
, argv
[i
], fd
, sig_namespace
,
2653 signer
, &agent_fd
)) != 0)
2655 if (fd
!= STDIN_FILENO
)
2663 if (fd
!= -1 && fd
!= STDIN_FILENO
)
2665 sshkey_free(pubkey
);
2666 sshkey_free(privkey
);
2671 verify(const char *signature
, const char *sig_namespace
, const char *principal
,
2672 const char *allowed_keys
, const char *revoked_keys
)
2674 int r
, ret
= -1, sigfd
= -1;
2675 struct sshbuf
*sigbuf
= NULL
, *abuf
= NULL
;
2676 struct sshkey
*sign_key
= NULL
;
2678 struct sshkey_sig_details
*sig_details
= NULL
;
2680 memset(&sig_details
, 0, sizeof(sig_details
));
2681 if ((abuf
= sshbuf_new()) == NULL
)
2682 fatal("%s: sshbuf_new() failed", __func__
);
2684 if ((sigfd
= open(signature
, O_RDONLY
)) < 0) {
2685 error("Couldn't open signature file %s", signature
);
2689 if ((r
= sshkey_load_file(sigfd
, abuf
)) != 0) {
2690 error("Couldn't read signature file: %s", ssh_err(r
));
2693 if ((r
= sshsig_dearmor(abuf
, &sigbuf
)) != 0) {
2694 error("%s: sshsig_armor: %s", __func__
, ssh_err(r
));
2697 if ((r
= sshsig_verify_fd(sigbuf
, STDIN_FILENO
, sig_namespace
,
2698 &sign_key
, &sig_details
)) != 0)
2699 goto done
; /* sshsig_verify() prints error */
2701 if ((fp
= sshkey_fingerprint(sign_key
, fingerprint_hash
,
2702 SSH_FP_DEFAULT
)) == NULL
)
2703 fatal("%s: sshkey_fingerprint failed", __func__
);
2704 debug("Valid (unverified) signature from key %s", fp
);
2705 if (sig_details
!= NULL
) {
2706 debug2("%s: signature details: counter = %u, flags = 0x%02x",
2707 __func__
, sig_details
->sk_counter
, sig_details
->sk_flags
);
2712 if (revoked_keys
!= NULL
) {
2713 if ((r
= sshkey_check_revoked(sign_key
, revoked_keys
)) != 0) {
2714 debug3("sshkey_check_revoked failed: %s", ssh_err(r
));
2719 if (allowed_keys
!= NULL
&&
2720 (r
= sshsig_check_allowed_keys(allowed_keys
, sign_key
,
2721 principal
, sig_namespace
)) != 0) {
2722 debug3("sshsig_check_allowed_keys failed: %s", ssh_err(r
));
2730 if ((fp
= sshkey_fingerprint(sign_key
, fingerprint_hash
,
2731 SSH_FP_DEFAULT
)) == NULL
) {
2732 fatal("%s: sshkey_fingerprint failed",
2735 if (principal
== NULL
) {
2736 printf("Good \"%s\" signature with %s key %s\n",
2737 sig_namespace
, sshkey_type(sign_key
), fp
);
2740 printf("Good \"%s\" signature for %s with %s key %s\n",
2741 sig_namespace
, principal
,
2742 sshkey_type(sign_key
), fp
);
2745 printf("Could not verify signature.\n");
2750 sshbuf_free(sigbuf
);
2752 sshkey_free(sign_key
);
2753 sshkey_sig_details_free(sig_details
);
2759 do_moduli_gen(const char *out_file
, char **opts
, size_t nopts
)
2762 /* Moduli generation/screening */
2763 u_int32_t memory
= 0;
2764 BIGNUM
*start
= NULL
;
2765 int moduli_bits
= 0;
2771 for (i
= 0; i
< nopts
; i
++) {
2772 if (strncmp(opts
[i
], "memory=", 7) == 0) {
2773 memory
= (u_int32_t
)strtonum(opts
[i
]+7, 1,
2776 fatal("Memory limit is %s: %s",
2779 } else if (strncmp(opts
[i
], "start=", 6) == 0) {
2780 /* XXX - also compare length against bits */
2781 if (BN_hex2bn(&start
, opts
[i
]+6) == 0)
2782 fatal("Invalid start point.");
2783 } else if (strncmp(opts
[i
], "bits=", 5) == 0) {
2784 moduli_bits
= (int)strtonum(opts
[i
]+5, 1,
2787 fatal("Invalid number: %s (%s)",
2788 opts
[i
]+12, errstr
);
2791 fatal("Option \"%s\" is unsupported for moduli "
2792 "generation", opts
[i
]);
2796 if ((out
= fopen(out_file
, "w")) == NULL
) {
2797 fatal("Couldn't open modulus candidate file \"%s\": %s",
2798 out_file
, strerror(errno
));
2800 setvbuf(out
, NULL
, _IOLBF
, 0);
2802 if (moduli_bits
== 0)
2803 moduli_bits
= DEFAULT_BITS
;
2804 if (gen_candidates(out
, memory
, moduli_bits
, start
) != 0)
2805 fatal("modulus candidate generation failed");
2806 #else /* WITH_OPENSSL */
2807 fatal("Moduli generation is not supported");
2808 #endif /* WITH_OPENSSL */
2812 do_moduli_screen(const char *out_file
, char **opts
, size_t nopts
)
2815 /* Moduli generation/screening */
2816 char *checkpoint
= NULL
;
2817 u_int32_t generator_wanted
= 0;
2818 unsigned long start_lineno
= 0, lines_to_process
= 0;
2819 int prime_tests
= 0;
2820 FILE *out
, *in
= stdin
;
2825 for (i
= 0; i
< nopts
; i
++) {
2826 if (strncmp(opts
[i
], "lines=", 6) == 0) {
2827 lines_to_process
= strtoul(opts
[i
]+6, NULL
, 10);
2828 } else if (strncmp(opts
[i
], "start-line=", 11) == 0) {
2829 start_lineno
= strtoul(opts
[i
]+11, NULL
, 10);
2830 } else if (strncmp(opts
[i
], "checkpoint=", 11) == 0) {
2831 checkpoint
= xstrdup(opts
[i
]+11);
2832 } else if (strncmp(opts
[i
], "generator=", 10) == 0) {
2833 generator_wanted
= (u_int32_t
)strtonum(
2834 opts
[i
]+10, 1, UINT_MAX
, &errstr
);
2835 if (errstr
!= NULL
) {
2836 fatal("Generator invalid: %s (%s)",
2837 opts
[i
]+10, errstr
);
2839 } else if (strncmp(opts
[i
], "prime-tests=", 12) == 0) {
2840 prime_tests
= (int)strtonum(opts
[i
]+12, 1,
2843 fatal("Invalid number: %s (%s)",
2844 opts
[i
]+12, errstr
);
2847 fatal("Option \"%s\" is unsupported for moduli "
2848 "screening", opts
[i
]);
2852 if (have_identity
&& strcmp(identity_file
, "-") != 0) {
2853 if ((in
= fopen(identity_file
, "r")) == NULL
) {
2854 fatal("Couldn't open modulus candidate "
2855 "file \"%s\": %s", identity_file
,
2860 if ((out
= fopen(out_file
, "a")) == NULL
) {
2861 fatal("Couldn't open moduli file \"%s\": %s",
2862 out_file
, strerror(errno
));
2864 setvbuf(out
, NULL
, _IOLBF
, 0);
2865 if (prime_test(in
, out
, prime_tests
== 0 ? 100 : prime_tests
,
2866 generator_wanted
, checkpoint
,
2867 start_lineno
, lines_to_process
) != 0)
2868 fatal("modulus screening failed");
2869 #else /* WITH_OPENSSL */
2870 fatal("Moduli screening is not supported");
2871 #endif /* WITH_OPENSSL */
2875 private_key_passphrase(void)
2877 char *passphrase1
, *passphrase2
;
2879 /* Ask for a passphrase (twice). */
2880 if (identity_passphrase
)
2881 passphrase1
= xstrdup(identity_passphrase
);
2882 else if (identity_new_passphrase
)
2883 passphrase1
= xstrdup(identity_new_passphrase
);
2887 read_passphrase("Enter passphrase (empty for no "
2888 "passphrase): ", RP_ALLOW_STDIN
);
2889 passphrase2
= read_passphrase("Enter same passphrase again: ",
2891 if (strcmp(passphrase1
, passphrase2
) != 0) {
2893 * The passphrases do not match. Clear them and
2896 freezero(passphrase1
, strlen(passphrase1
));
2897 freezero(passphrase2
, strlen(passphrase2
));
2898 printf("Passphrases do not match. Try again.\n");
2899 goto passphrase_again
;
2901 /* Clear the other copy of the passphrase. */
2902 freezero(passphrase2
, strlen(passphrase2
));
2908 skip_ssh_url_preamble(const char *s
)
2910 if (strncmp(s
, "ssh://", 6) == 0)
2912 else if (strncmp(s
, "ssh:", 4) == 0)
2918 do_download_sk(const char *skprovider
)
2920 struct sshkey
**keys
;
2923 char *fp
, *pin
, *pass
= NULL
, *path
, *pubpath
;
2926 if (skprovider
== NULL
)
2927 fatal("Cannot download keys without provider");
2929 pin
= read_passphrase("Enter PIN for security key: ", RP_ALLOW_STDIN
);
2930 if ((r
= sshsk_load_resident(skprovider
, pin
, &keys
, &nkeys
)) != 0) {
2931 freezero(pin
, strlen(pin
));
2932 error("Unable to load resident keys: %s", ssh_err(r
));
2936 logit("No keys to download");
2937 freezero(pin
, strlen(pin
));
2939 for (i
= 0; i
< nkeys
; i
++) {
2940 if (keys
[i
]->type
!= KEY_ECDSA_SK
&&
2941 keys
[i
]->type
!= KEY_ED25519_SK
) {
2942 error("Unsupported key type %s (%d)",
2943 sshkey_type(keys
[i
]), keys
[i
]->type
);
2946 if ((fp
= sshkey_fingerprint(keys
[i
],
2947 fingerprint_hash
, SSH_FP_DEFAULT
)) == NULL
)
2948 fatal("%s: sshkey_fingerprint failed", __func__
);
2949 debug("%s: key %zu: %s %s %s (flags 0x%02x)", __func__
, i
,
2950 sshkey_type(keys
[i
]), fp
, keys
[i
]->sk_application
,
2952 ext
= skip_ssh_url_preamble(keys
[i
]->sk_application
);
2953 xasprintf(&path
, "id_%s_rk%s%s",
2954 keys
[i
]->type
== KEY_ECDSA_SK
? "ecdsa_sk" : "ed25519_sk",
2955 *ext
== '\0' ? "" : "_", ext
);
2957 /* If the file already exists, ask the user to confirm. */
2958 if (!confirm_overwrite(path
)) {
2963 /* Save the key with the application string as the comment */
2965 pass
= private_key_passphrase();
2966 if ((r
= sshkey_save_private(keys
[i
], path
, pass
,
2967 keys
[i
]->sk_application
, private_key_format
,
2968 openssh_format_cipher
, rounds
)) != 0) {
2969 error("Saving key \"%s\" failed: %s",
2975 printf("Saved %s key%s%s to %s\n",
2976 sshkey_type(keys
[i
]),
2977 *ext
!= '\0' ? " " : "",
2978 *ext
!= '\0' ? keys
[i
]->sk_application
: "",
2982 /* Save public key too */
2983 xasprintf(&pubpath
, "%s.pub", path
);
2985 if ((r
= sshkey_save_public(keys
[i
], pubpath
,
2986 keys
[i
]->sk_application
)) != 0) {
2988 error("Saving public key \"%s\" failed: %s",
2989 pubpath
, ssh_err(r
));
2996 ok
= 0; /* success */
2998 freezero(pass
, strlen(pass
));
2999 for (i
= 0; i
< nkeys
; i
++)
3000 sshkey_free(keys
[i
]);
3009 "usage: ssh-keygen [-q] [-b bits] [-C comment] [-f output_keyfile] [-m format]\n"
3010 " [-t dsa | ecdsa | ecdsa-sk | ed25519 | ed25519-sk | rsa]\n"
3011 " [-N new_passphrase] [-w provider] [-x flags]\n"
3012 " ssh-keygen -p [-f keyfile] [-m format] [-N new_passphrase]\n"
3013 " [-P old_passphrase]\n"
3014 " ssh-keygen -i [-f input_keyfile] [-m key_format]\n"
3015 " ssh-keygen -e [-f input_keyfile] [-m key_format]\n"
3016 " ssh-keygen -y [-f input_keyfile]\n"
3017 " ssh-keygen -c [-C comment] [-f keyfile] [-P passphrase]\n"
3018 " ssh-keygen -l [-v] [-E fingerprint_hash] [-f input_keyfile]\n"
3019 " ssh-keygen -B [-f input_keyfile]\n");
3020 #ifdef ENABLE_PKCS11
3022 " ssh-keygen -D pkcs11\n");
3025 " ssh-keygen -K path [-w sk_provider]\n");
3027 " ssh-keygen -F hostname [-lv] [-f known_hosts_file]\n"
3028 " ssh-keygen -H [-f known_hosts_file]\n"
3029 " ssh-keygen -R hostname [-f known_hosts_file]\n"
3030 " ssh-keygen -r hostname [-g] [-f input_keyfile]\n"
3032 " ssh-keygen -M generate [-O option] output\n"
3033 " ssh-keygen -M screen [-f input_file] [-O option] [-a rounds] output_file\n"
3035 " ssh-keygen -I certificate_identity -s ca_key [-hU] [-D pkcs11_provider]\n"
3036 " [-n principals] [-O option] [-V validity_interval]\n"
3037 " [-z serial_number] file ...\n"
3038 " ssh-keygen -L [-f input_keyfile]\n"
3039 " ssh-keygen -A [-f prefix_path]\n"
3040 " ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number]\n"
3042 " ssh-keygen -Q -f krl_file file ...\n"
3043 " ssh-keygen -Y check-novalidate -n namespace -s signature_file\n"
3044 " ssh-keygen -Y sign -f key_file -n namespace file ...\n"
3045 " ssh-keygen -Y verify -f allowed_signers_file -I signer_identity\n"
3046 " -n namespace -s signature_file [-r revocation_file]\n");
3051 * Main program for key management.
3054 main(int argc
, char **argv
)
3056 char dotsshdir
[PATH_MAX
], comment
[1024], *passphrase
;
3057 char *rr_hostname
= NULL
, *ep
, *fp
, *ra
;
3058 struct sshkey
*private, *public;
3062 int change_passphrase
= 0, change_comment
= 0, show_cert
= 0;
3063 int find_host
= 0, delete_host
= 0, hash_hosts
= 0;
3064 int gen_all_hostkeys
= 0, gen_krl
= 0, update_krl
= 0, check_krl
= 0;
3065 int prefer_agent
= 0, convert_to
= 0, convert_from
= 0;
3066 int print_public
= 0, print_generic
= 0, cert_serial_autoinc
= 0;
3067 int do_gen_candidates
= 0, do_screen_candidates
= 0, download_sk
= 0;
3068 unsigned long long cert_serial
= 0;
3069 char *identity_comment
= NULL
, *ca_key_path
= NULL
, **opts
= NULL
;
3070 size_t i
, nopts
= 0;
3072 uint8_t sk_flags
= SSH_SK_USER_PRESENCE_REQD
;
3074 int log_level
= SYSLOG_LEVEL_INFO
;
3075 char *sign_op
= NULL
;
3078 extern char *optarg
;
3080 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
3083 __progname
= ssh_get_progname(argv
[0]);
3087 log_init(argv
[0], SYSLOG_LEVEL_INFO
, SYSLOG_FACILITY_USER
, 1);
3091 /* we need this for the home * directory. */
3092 pw
= getpwuid(getuid());
3094 fatal("No user exists for uid %lu", (u_long
)getuid());
3095 if (gethostname(hostname
, sizeof(hostname
)) == -1)
3096 fatal("gethostname: %s", strerror(errno
));
3098 sk_provider
= getenv("SSH_SK_PROVIDER");
3100 /* Remaining characters: dGjJSTWx */
3101 while ((opt
= getopt(argc
, argv
, "ABHKLQUXceghiklopquvy"
3102 "C:D:E:F:I:M:N:O:P:R:V:Y:Z:"
3103 "a:b:f:g:m:n:r:s:t:w:z:")) != -1) {
3106 gen_all_hostkeys
= 1;
3109 bits
= (u_int32_t
)strtonum(optarg
, 1, UINT32_MAX
,
3112 fatal("Bits has bad value %s (%s)",
3116 fingerprint_hash
= ssh_digest_alg_by_name(optarg
);
3117 if (fingerprint_hash
== -1)
3118 fatal("Invalid hash algorithm \"%s\"", optarg
);
3122 rr_hostname
= optarg
;
3128 cert_key_id
= optarg
;
3132 rr_hostname
= optarg
;
3138 print_fingerprint
= 1;
3141 print_bubblebabble
= 1;
3144 if (strcasecmp(optarg
, "RFC4716") == 0 ||
3145 strcasecmp(optarg
, "ssh2") == 0) {
3146 convert_format
= FMT_RFC4716
;
3149 if (strcasecmp(optarg
, "PKCS8") == 0) {
3150 convert_format
= FMT_PKCS8
;
3151 private_key_format
= SSHKEY_PRIVATE_PKCS8
;
3154 if (strcasecmp(optarg
, "PEM") == 0) {
3155 convert_format
= FMT_PEM
;
3156 private_key_format
= SSHKEY_PRIVATE_PEM
;
3159 fatal("Unsupported conversion format \"%s\"", optarg
);
3161 cert_principals
= optarg
;
3164 /* no-op; new format is already the default */
3167 change_passphrase
= 1;
3173 if (strlcpy(identity_file
, optarg
,
3174 sizeof(identity_file
)) >= sizeof(identity_file
))
3175 fatal("Identity filename too long");
3185 identity_passphrase
= optarg
;
3188 identity_new_passphrase
= optarg
;
3194 opts
= xrecallocarray(opts
, nopts
, nopts
+ 1,
3196 opts
[nopts
++] = xstrdup(optarg
);
3199 openssh_format_cipher
= optarg
;
3202 identity_comment
= optarg
;
3212 cert_key_type
= SSH2_CERT_TYPE_HOST
;
3213 certflags_flags
= 0;
3227 ca_key_path
= optarg
;
3230 key_type_name
= optarg
;
3233 pkcs11provider
= optarg
;
3242 if (log_level
== SYSLOG_LEVEL_INFO
)
3243 log_level
= SYSLOG_LEVEL_DEBUG1
;
3245 if (log_level
>= SYSLOG_LEVEL_DEBUG1
&&
3246 log_level
< SYSLOG_LEVEL_DEBUG3
)
3251 rr_hostname
= optarg
;
3254 rounds
= (int)strtonum(optarg
, 1, INT_MAX
, &errstr
);
3256 fatal("Invalid number: %s (%s)",
3260 parse_cert_times(optarg
);
3266 sk_provider
= optarg
;
3270 if (*optarg
== '+') {
3271 cert_serial_autoinc
= 1;
3274 cert_serial
= strtoull(optarg
, &ep
, 10);
3275 if (*optarg
< '0' || *optarg
> '9' || *ep
!= '\0' ||
3276 (errno
== ERANGE
&& cert_serial
== ULLONG_MAX
))
3277 fatal("Invalid serial number \"%s\"", optarg
);
3280 if (strcmp(optarg
, "generate") == 0)
3281 do_gen_candidates
= 1;
3282 else if (strcmp(optarg
, "screen") == 0)
3283 do_screen_candidates
= 1;
3285 fatal("Unsupported moduli option %s", optarg
);
3293 #ifdef ENABLE_SK_INTERNAL
3294 if (sk_provider
== NULL
)
3295 sk_provider
= "internal";
3299 log_init(argv
[0], log_level
, SYSLOG_FACILITY_USER
, 1);
3304 if (sign_op
!= NULL
) {
3305 if (cert_principals
== NULL
|| *cert_principals
== '\0') {
3306 error("Too few arguments for sign/verify: "
3307 "missing namespace");
3310 if (strncmp(sign_op
, "sign", 4) == 0) {
3311 if (!have_identity
) {
3312 error("Too few arguments for sign: "
3316 return sign(identity_file
, cert_principals
, argc
, argv
);
3317 } else if (strncmp(sign_op
, "check-novalidate", 16) == 0) {
3318 if (ca_key_path
== NULL
) {
3319 error("Too few arguments for check-novalidate: "
3320 "missing signature file");
3323 return verify(ca_key_path
, cert_principals
,
3325 } else if (strncmp(sign_op
, "verify", 6) == 0) {
3326 if (ca_key_path
== NULL
) {
3327 error("Too few arguments for verify: "
3328 "missing signature file");
3331 if (!have_identity
) {
3332 error("Too few arguments for sign: "
3333 "missing allowed keys file");
3336 if (cert_key_id
== NULL
) {
3337 error("Too few arguments for verify: "
3338 "missing principal ID");
3341 return verify(ca_key_path
, cert_principals
,
3342 cert_key_id
, identity_file
, rr_hostname
);
3348 if (ca_key_path
!= NULL
) {
3349 if (argc
< 1 && !gen_krl
) {
3350 error("Too few arguments.");
3353 } else if (argc
> 0 && !gen_krl
&& !check_krl
&&
3354 !do_gen_candidates
&& !do_screen_candidates
) {
3355 error("Too many arguments.");
3358 if (change_passphrase
&& change_comment
) {
3359 error("Can only have one of -p and -c.");
3362 if (print_fingerprint
&& (delete_host
|| hash_hosts
)) {
3363 error("Cannot use -l with -H or -R.");
3368 do_gen_krl(pw
, update_krl
, ca_key_path
,
3369 cert_serial
, identity_comment
, argc
, argv
);
3372 fatal("KRL generation not supported");
3377 do_check_krl(pw
, argc
, argv
);
3380 fatal("KRL checking not supported");
3383 if (ca_key_path
!= NULL
) {
3384 if (cert_key_id
== NULL
)
3385 fatal("Must specify key id (-I) when certifying");
3386 for (i
= 0; i
< nopts
; i
++)
3387 add_cert_option(opts
[i
]);
3388 do_ca_sign(pw
, ca_key_path
, prefer_agent
,
3389 cert_serial
, cert_serial_autoinc
, argc
, argv
);
3393 if (delete_host
|| hash_hosts
|| find_host
) {
3394 do_known_hosts(pw
, rr_hostname
, find_host
,
3395 delete_host
, hash_hosts
);
3397 if (pkcs11provider
!= NULL
)
3400 return do_download_sk(sk_provider
);
3401 if (print_fingerprint
|| print_bubblebabble
)
3403 if (change_passphrase
)
3404 do_change_passphrase(pw
);
3406 do_change_comment(pw
, identity_comment
);
3411 do_convert_from(pw
);
3412 #else /* WITH_OPENSSL */
3413 if (convert_to
|| convert_from
)
3414 fatal("key conversion disabled at compile time");
3415 #endif /* WITH_OPENSSL */
3417 do_print_public(pw
);
3418 if (rr_hostname
!= NULL
) {
3421 if (have_identity
) {
3422 n
= do_print_resource_record(pw
, identity_file
,
3423 rr_hostname
, print_generic
);
3425 fatal("%s: %s", identity_file
, strerror(errno
));
3429 n
+= do_print_resource_record(pw
,
3430 _PATH_HOST_RSA_KEY_FILE
, rr_hostname
,
3432 n
+= do_print_resource_record(pw
,
3433 _PATH_HOST_DSA_KEY_FILE
, rr_hostname
,
3435 n
+= do_print_resource_record(pw
,
3436 _PATH_HOST_ECDSA_KEY_FILE
, rr_hostname
,
3438 n
+= do_print_resource_record(pw
,
3439 _PATH_HOST_ED25519_KEY_FILE
, rr_hostname
,
3441 n
+= do_print_resource_record(pw
,
3442 _PATH_HOST_XMSS_KEY_FILE
, rr_hostname
,
3445 fatal("no keys found.");
3450 if (do_gen_candidates
|| do_screen_candidates
) {
3452 fatal("No output file specified");
3454 fatal("Too many output files specified");
3456 if (do_gen_candidates
) {
3457 do_moduli_gen(argv
[0], opts
, nopts
);
3460 if (do_screen_candidates
) {
3461 do_moduli_screen(argv
[0], opts
, nopts
);
3465 if (gen_all_hostkeys
) {
3466 do_gen_all_hostkeys(pw
);
3470 if (key_type_name
== NULL
)
3471 key_type_name
= DEFAULT_KEY_TYPE_NAME
;
3473 type
= sshkey_type_from_name(key_type_name
);
3474 type_bits_valid(type
, key_type_name
, &bits
);
3477 printf("Generating public/private %s key pair.\n",
3481 case KEY_ED25519_SK
:
3482 for (i
= 0; i
< nopts
; i
++) {
3483 if (strcasecmp(opts
[i
], "no-touch-required") == 0) {
3484 sk_flags
&= ~SSH_SK_USER_PRESENCE_REQD
;
3485 } else if (strcasecmp(opts
[i
], "resident") == 0) {
3486 sk_flags
|= SSH_SK_RESIDENT_KEY
;
3488 fatal("Option \"%s\" is unsupported for "
3489 "FIDO authenticator enrollment", opts
[i
]);
3493 printf("You may need to touch your security key "
3494 "to authorize key generation.\n");
3497 for (i
= 0 ; i
< 3; i
++) {
3499 printf("You may need to touch your security "
3500 "key to authorize key generation.\n");
3503 r
= sshsk_enroll(type
, sk_provider
,
3504 cert_key_id
== NULL
? "ssh:" : cert_key_id
,
3505 sk_flags
, passphrase
, NULL
, &private, NULL
);
3508 if (r
!= SSH_ERR_KEY_WRONG_PASSPHRASE
)
3509 exit(1); /* error message already printed */
3510 if (passphrase
!= NULL
)
3511 freezero(passphrase
, strlen(passphrase
));
3512 passphrase
= read_passphrase("Enter PIN for security "
3513 "key: ", RP_ALLOW_STDIN
);
3515 if (passphrase
!= NULL
)
3516 freezero(passphrase
, strlen(passphrase
));
3518 fatal("Too many incorrect PINs");
3521 if ((r
= sshkey_generate(type
, bits
, &private)) != 0)
3522 fatal("sshkey_generate failed");
3525 if ((r
= sshkey_from_private(private, &public)) != 0)
3526 fatal("sshkey_from_private failed: %s\n", ssh_err(r
));
3529 ask_filename(pw
, "Enter file in which to save the key");
3531 /* Create ~/.ssh directory if it doesn't already exist. */
3532 snprintf(dotsshdir
, sizeof dotsshdir
, "%s/%s",
3533 pw
->pw_dir
, _PATH_SSH_USER_DIR
);
3534 if (strstr(identity_file
, dotsshdir
) != NULL
) {
3535 if (stat(dotsshdir
, &st
) == -1) {
3536 if (errno
!= ENOENT
) {
3537 error("Could not stat %s: %s", dotsshdir
,
3539 } else if (mkdir(dotsshdir
, 0700) == -1) {
3540 error("Could not create directory '%s': %s",
3541 dotsshdir
, strerror(errno
));
3543 printf("Created directory '%s'.\n", dotsshdir
);
3546 /* If the file already exists, ask the user to confirm. */
3547 if (!confirm_overwrite(identity_file
))
3550 /* Determine the passphrase for the private key */
3551 passphrase
= private_key_passphrase();
3552 if (identity_comment
) {
3553 strlcpy(comment
, identity_comment
, sizeof(comment
));
3555 /* Create default comment field for the passphrase. */
3556 snprintf(comment
, sizeof comment
, "%s@%s", pw
->pw_name
, hostname
);
3559 /* Save the key with the given passphrase and comment. */
3560 if ((r
= sshkey_save_private(private, identity_file
, passphrase
,
3561 comment
, private_key_format
, openssh_format_cipher
, rounds
)) != 0) {
3562 error("Saving key \"%s\" failed: %s",
3563 identity_file
, ssh_err(r
));
3564 freezero(passphrase
, strlen(passphrase
));
3567 freezero(passphrase
, strlen(passphrase
));
3568 sshkey_free(private);
3571 printf("Your identification has been saved in %s.\n",
3575 strlcat(identity_file
, ".pub", sizeof(identity_file
));
3576 if ((r
= sshkey_save_public(public, identity_file
, comment
)) != 0) {
3577 fatal("Unable to save public key to %s: %s",
3578 identity_file
, strerror(errno
));
3582 fp
= sshkey_fingerprint(public, fingerprint_hash
,
3584 ra
= sshkey_fingerprint(public, fingerprint_hash
,
3586 if (fp
== NULL
|| ra
== NULL
)
3587 fatal("sshkey_fingerprint failed");
3588 printf("Your public key has been saved in %s.\n",
3590 printf("The key fingerprint is:\n");
3591 printf("%s %s\n", fp
, comment
);
3592 printf("The key's randomart image is:\n");
3598 sshkey_free(public);