1 /* $OpenBSD: ssh-keygen.c,v 1.307 2017/07/07 03:53:12 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"
47 #include "pathnames.h"
56 #include "ssh-pkcs11.h"
64 # define DEFAULT_KEY_TYPE_NAME "rsa"
66 # define DEFAULT_KEY_TYPE_NAME "ed25519"
69 /* Number of bits in the RSA/DSA key. This value can be set on the command line. */
70 #define DEFAULT_BITS 2048
71 #define DEFAULT_BITS_DSA 1024
72 #define DEFAULT_BITS_ECDSA 256
76 * Flag indicating that we just want to change the passphrase. This can be
77 * set on the command line.
79 int change_passphrase
= 0;
82 * Flag indicating that we just want to change the comment. This can be set
83 * on the command line.
85 int change_comment
= 0;
89 int log_level
= SYSLOG_LEVEL_INFO
;
91 /* Flag indicating that we want to hash a known_hosts file */
93 /* Flag indicating that we want lookup a host in known_hosts file */
95 /* Flag indicating that we want to delete a host from a known_hosts file */
98 /* Flag indicating that we want to show the contents of a certificate */
101 /* Flag indicating that we just want to see the key fingerprint */
102 int print_fingerprint
= 0;
103 int print_bubblebabble
= 0;
105 /* Hash algorithm to use for fingerprints. */
106 int fingerprint_hash
= SSH_FP_HASH_DEFAULT
;
108 /* The identity file name, given on the command line or entered by the user. */
109 char identity_file
[1024];
110 int have_identity
= 0;
112 /* This is set to the passphrase if given on the command line. */
113 char *identity_passphrase
= NULL
;
115 /* This is set to the new passphrase if given on the command line. */
116 char *identity_new_passphrase
= NULL
;
118 /* This is set to the new comment if given on the command line. */
119 char *identity_comment
= NULL
;
121 /* Path to CA key when certifying keys. */
122 char *ca_key_path
= NULL
;
124 /* Prefer to use agent keys for CA signing */
125 int prefer_agent
= 0;
127 /* Certificate serial number */
128 unsigned long long cert_serial
= 0;
130 /* Key type when certifying */
131 u_int cert_key_type
= SSH2_CERT_TYPE_USER
;
133 /* "key ID" of signed key */
134 char *cert_key_id
= NULL
;
136 /* Comma-separated list of principal names for certifying keys */
137 char *cert_principals
= NULL
;
139 /* Validity period for certificates */
140 u_int64_t cert_valid_from
= 0;
141 u_int64_t cert_valid_to
= ~0ULL;
143 /* Certificate options */
144 #define CERTOPT_X_FWD (1)
145 #define CERTOPT_AGENT_FWD (1<<1)
146 #define CERTOPT_PORT_FWD (1<<2)
147 #define CERTOPT_PTY (1<<3)
148 #define CERTOPT_USER_RC (1<<4)
149 #define CERTOPT_DEFAULT (CERTOPT_X_FWD|CERTOPT_AGENT_FWD| \
150 CERTOPT_PORT_FWD|CERTOPT_PTY|CERTOPT_USER_RC)
151 u_int32_t certflags_flags
= CERTOPT_DEFAULT
;
152 char *certflags_command
= NULL
;
153 char *certflags_src_addr
= NULL
;
155 /* Arbitrary extensions specified by user */
156 struct cert_userext
{
161 struct cert_userext
*cert_userext
;
162 size_t ncert_userext
;
164 /* Conversion to/from various formats */
166 int convert_from
= 0;
171 } convert_format
= FMT_RFC4716
;
172 int print_public
= 0;
173 int print_generic
= 0;
175 char *key_type_name
= NULL
;
177 /* Load key from this PKCS#11 provider */
178 char *pkcs11provider
= NULL
;
180 /* Use new OpenSSH private key format when writing SSH2 keys instead of PEM */
181 int use_new_format
= 0;
183 /* Cipher for new-format private keys */
184 char *new_format_cipher
= NULL
;
187 * Number of KDF rounds to derive new format keys /
188 * number of primality trials when screening moduli.
193 extern char *__progname
;
195 char hostname
[NI_MAXHOST
];
199 int gen_candidates(FILE *, u_int32_t
, u_int32_t
, BIGNUM
*);
200 int prime_test(FILE *, FILE *, u_int32_t
, u_int32_t
, char *, unsigned long,
205 type_bits_valid(int type
, const char *name
, u_int32_t
*bitsp
)
211 if (type
== KEY_UNSPEC
)
212 fatal("unknown key type %s", key_type_name
);
216 *bitsp
= DEFAULT_BITS_DSA
;
217 else if (type
== KEY_ECDSA
) {
219 (nid
= sshkey_ecdsa_nid_from_name(name
)) > 0)
220 *bitsp
= sshkey_curve_nid_to_bits(nid
);
222 *bitsp
= DEFAULT_BITS_ECDSA
;
225 *bitsp
= DEFAULT_BITS
;
228 maxbits
= (type
== KEY_DSA
) ?
229 OPENSSL_DSA_MAX_MODULUS_BITS
: OPENSSL_RSA_MAX_MODULUS_BITS
;
230 if (*bitsp
> maxbits
)
231 fatal("key bits exceeds maximum %d", maxbits
);
235 fatal("Invalid DSA key length: must be 1024 bits");
238 if (*bitsp
< SSH_RSA_MINIMUM_MODULUS_SIZE
)
239 fatal("Invalid RSA key length: minimum is %d bits",
240 SSH_RSA_MINIMUM_MODULUS_SIZE
);
243 if (sshkey_ecdsa_bits_to_nid(*bitsp
) == -1)
244 fatal("Invalid ECDSA key length: valid lengths are "
245 "256, 384 or 521 bits");
251 ask_filename(struct passwd
*pw
, const char *prompt
)
256 if (key_type_name
== NULL
)
257 name
= _PATH_SSH_CLIENT_ID_RSA
;
259 switch (sshkey_type_from_name(key_type_name
)) {
262 name
= _PATH_SSH_CLIENT_ID_DSA
;
264 #ifdef OPENSSL_HAS_ECC
267 name
= _PATH_SSH_CLIENT_ID_ECDSA
;
272 name
= _PATH_SSH_CLIENT_ID_RSA
;
275 case KEY_ED25519_CERT
:
276 name
= _PATH_SSH_CLIENT_ID_ED25519
;
279 fatal("bad key type");
282 snprintf(identity_file
, sizeof(identity_file
),
283 "%s/%s", pw
->pw_dir
, name
);
284 printf("%s (%s): ", prompt
, identity_file
);
286 if (fgets(buf
, sizeof(buf
), stdin
) == NULL
)
288 buf
[strcspn(buf
, "\n")] = '\0';
289 if (strcmp(buf
, "") != 0)
290 strlcpy(identity_file
, buf
, sizeof(identity_file
));
294 static struct sshkey
*
295 load_identity(char *filename
)
301 if ((r
= sshkey_load_private(filename
, "", &prv
, NULL
)) == 0)
303 if (r
!= SSH_ERR_KEY_WRONG_PASSPHRASE
)
304 fatal("Load key \"%s\": %s", filename
, ssh_err(r
));
305 if (identity_passphrase
)
306 pass
= xstrdup(identity_passphrase
);
308 pass
= read_passphrase("Enter passphrase: ", RP_ALLOW_STDIN
);
309 r
= sshkey_load_private(filename
, pass
, &prv
, NULL
);
310 explicit_bzero(pass
, strlen(pass
));
313 fatal("Load key \"%s\": %s", filename
, ssh_err(r
));
317 #define SSH_COM_PUBLIC_BEGIN "---- BEGIN SSH2 PUBLIC KEY ----"
318 #define SSH_COM_PUBLIC_END "---- END SSH2 PUBLIC KEY ----"
319 #define SSH_COM_PRIVATE_BEGIN "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----"
320 #define SSH_COM_PRIVATE_KEY_MAGIC 0x3f6ff9eb
324 do_convert_to_ssh2(struct passwd
*pw
, struct sshkey
*k
)
331 if ((r
= sshkey_to_blob(k
, &blob
, &len
)) != 0)
332 fatal("key_to_blob failed: %s", ssh_err(r
));
333 /* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */
334 snprintf(comment
, sizeof(comment
),
335 "%u-bit %s, converted by %s@%s from OpenSSH",
336 sshkey_size(k
), sshkey_type(k
),
337 pw
->pw_name
, hostname
);
339 fprintf(stdout
, "%s\n", SSH_COM_PUBLIC_BEGIN
);
340 fprintf(stdout
, "Comment: \"%s\"\n", comment
);
341 dump_base64(stdout
, blob
, len
);
342 fprintf(stdout
, "%s\n", SSH_COM_PUBLIC_END
);
349 do_convert_to_pkcs8(struct sshkey
*k
)
351 switch (sshkey_type_plain(k
->type
)) {
353 if (!PEM_write_RSA_PUBKEY(stdout
, k
->rsa
))
354 fatal("PEM_write_RSA_PUBKEY failed");
357 if (!PEM_write_DSA_PUBKEY(stdout
, k
->dsa
))
358 fatal("PEM_write_DSA_PUBKEY failed");
360 #ifdef OPENSSL_HAS_ECC
362 if (!PEM_write_EC_PUBKEY(stdout
, k
->ecdsa
))
363 fatal("PEM_write_EC_PUBKEY failed");
367 fatal("%s: unsupported key type %s", __func__
, sshkey_type(k
));
373 do_convert_to_pem(struct sshkey
*k
)
375 switch (sshkey_type_plain(k
->type
)) {
377 if (!PEM_write_RSAPublicKey(stdout
, k
->rsa
))
378 fatal("PEM_write_RSAPublicKey failed");
380 #if notyet /* OpenSSH 0.9.8 lacks this function */
382 if (!PEM_write_DSAPublicKey(stdout
, k
->dsa
))
383 fatal("PEM_write_DSAPublicKey failed");
388 fatal("%s: unsupported key type %s", __func__
, sshkey_type(k
));
394 do_convert_to(struct passwd
*pw
)
401 ask_filename(pw
, "Enter file in which the key is");
402 if (stat(identity_file
, &st
) < 0)
403 fatal("%s: %s: %s", __progname
, identity_file
, strerror(errno
));
404 if ((r
= sshkey_load_public(identity_file
, &k
, NULL
)) != 0)
405 k
= load_identity(identity_file
);
406 switch (convert_format
) {
408 do_convert_to_ssh2(pw
, k
);
411 do_convert_to_pkcs8(k
);
414 do_convert_to_pem(k
);
417 fatal("%s: unknown key format %d", __func__
, convert_format
);
423 * This is almost exactly the bignum1 encoding, but with 32 bit for length
427 buffer_get_bignum_bits(struct sshbuf
*b
, BIGNUM
*value
)
429 u_int bytes
, bignum_bits
;
432 if ((r
= sshbuf_get_u32(b
, &bignum_bits
)) != 0)
433 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
434 bytes
= (bignum_bits
+ 7) / 8;
435 if (sshbuf_len(b
) < bytes
)
436 fatal("%s: input buffer too small: need %d have %zu",
437 __func__
, bytes
, sshbuf_len(b
));
438 if (BN_bin2bn(sshbuf_ptr(b
), bytes
, value
) == NULL
)
439 fatal("%s: BN_bin2bn failed", __func__
);
440 if ((r
= sshbuf_consume(b
, bytes
)) != 0)
441 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
444 static struct sshkey
*
445 do_convert_private_ssh2_from_blob(u_char
*blob
, u_int blen
)
448 struct sshkey
*key
= NULL
;
450 u_char e1
, e2
, e3
, *sig
= NULL
, data
[] = "abcde12345";
452 u_int magic
, i1
, i2
, i3
, i4
;
456 if ((b
= sshbuf_from(blob
, blen
)) == NULL
)
457 fatal("%s: sshbuf_from failed", __func__
);
458 if ((r
= sshbuf_get_u32(b
, &magic
)) != 0)
459 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
461 if (magic
!= SSH_COM_PRIVATE_KEY_MAGIC
) {
462 error("bad magic 0x%x != 0x%x", magic
,
463 SSH_COM_PRIVATE_KEY_MAGIC
);
467 if ((r
= sshbuf_get_u32(b
, &i1
)) != 0 ||
468 (r
= sshbuf_get_cstring(b
, &type
, NULL
)) != 0 ||
469 (r
= sshbuf_get_cstring(b
, &cipher
, NULL
)) != 0 ||
470 (r
= sshbuf_get_u32(b
, &i2
)) != 0 ||
471 (r
= sshbuf_get_u32(b
, &i3
)) != 0 ||
472 (r
= sshbuf_get_u32(b
, &i4
)) != 0)
473 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
474 debug("ignore (%d %d %d %d)", i1
, i2
, i3
, i4
);
475 if (strcmp(cipher
, "none") != 0) {
476 error("unsupported cipher %s", cipher
);
484 if (strstr(type
, "dsa")) {
486 } else if (strstr(type
, "rsa")) {
493 if ((key
= sshkey_new_private(ktype
)) == NULL
)
494 fatal("sshkey_new_private failed");
499 buffer_get_bignum_bits(b
, key
->dsa
->p
);
500 buffer_get_bignum_bits(b
, key
->dsa
->g
);
501 buffer_get_bignum_bits(b
, key
->dsa
->q
);
502 buffer_get_bignum_bits(b
, key
->dsa
->pub_key
);
503 buffer_get_bignum_bits(b
, key
->dsa
->priv_key
);
506 if ((r
= sshbuf_get_u8(b
, &e1
)) != 0 ||
507 (e1
< 30 && (r
= sshbuf_get_u8(b
, &e2
)) != 0) ||
508 (e1
< 30 && (r
= sshbuf_get_u8(b
, &e3
)) != 0))
509 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
520 if (!BN_set_word(key
->rsa
->e
, e
)) {
525 buffer_get_bignum_bits(b
, key
->rsa
->d
);
526 buffer_get_bignum_bits(b
, key
->rsa
->n
);
527 buffer_get_bignum_bits(b
, key
->rsa
->iqmp
);
528 buffer_get_bignum_bits(b
, key
->rsa
->q
);
529 buffer_get_bignum_bits(b
, key
->rsa
->p
);
530 if ((r
= ssh_rsa_generate_additional_parameters(key
)) != 0)
531 fatal("generate RSA parameters failed: %s", ssh_err(r
));
534 rlen
= sshbuf_len(b
);
536 error("do_convert_private_ssh2_from_blob: "
537 "remaining bytes in key blob %d", rlen
);
541 if (sshkey_sign(key
, &sig
, &slen
, data
, sizeof(data
), NULL
, 0) != 0 ||
542 sshkey_verify(key
, sig
, slen
, data
, sizeof(data
), 0) != 0) {
552 get_line(FILE *fp
, char *line
, size_t len
)
558 while ((c
= fgetc(fp
)) != EOF
) {
560 fatal("input line too long.");
564 if (c
!= EOF
&& c
!= '\n' && ungetc(c
, fp
) == EOF
)
565 fatal("unget: %s", strerror(errno
));
578 do_convert_from_ssh2(struct passwd
*pw
, struct sshkey
**k
, int *private)
580 int r
, blen
, escaped
= 0;
587 if ((fp
= fopen(identity_file
, "r")) == NULL
)
588 fatal("%s: %s: %s", __progname
, identity_file
, strerror(errno
));
590 while ((blen
= get_line(fp
, line
, sizeof(line
))) != -1) {
591 if (blen
> 0 && line
[blen
- 1] == '\\')
593 if (strncmp(line
, "----", 4) == 0 ||
594 strstr(line
, ": ") != NULL
) {
595 if (strstr(line
, SSH_COM_PRIVATE_BEGIN
) != NULL
)
597 if (strstr(line
, " END ") != NULL
) {
600 /* fprintf(stderr, "ignore: %s", line); */
605 /* fprintf(stderr, "escaped: %s", line); */
608 strlcat(encoded
, line
, sizeof(encoded
));
610 len
= strlen(encoded
);
611 if (((len
% 4) == 3) &&
612 (encoded
[len
-1] == '=') &&
613 (encoded
[len
-2] == '=') &&
614 (encoded
[len
-3] == '='))
615 encoded
[len
-3] = '\0';
616 blen
= uudecode(encoded
, blob
, sizeof(blob
));
618 fatal("uudecode failed.");
620 *k
= do_convert_private_ssh2_from_blob(blob
, blen
);
621 else if ((r
= sshkey_from_blob(blob
, blen
, k
)) != 0)
622 fatal("decode blob failed: %s", ssh_err(r
));
627 do_convert_from_pkcs8(struct sshkey
**k
, int *private)
632 if ((fp
= fopen(identity_file
, "r")) == NULL
)
633 fatal("%s: %s: %s", __progname
, identity_file
, strerror(errno
));
634 if ((pubkey
= PEM_read_PUBKEY(fp
, NULL
, NULL
, NULL
)) == NULL
) {
635 fatal("%s: %s is not a recognised public key format", __func__
,
639 switch (EVP_PKEY_type(pubkey
->type
)) {
641 if ((*k
= sshkey_new(KEY_UNSPEC
)) == NULL
)
642 fatal("sshkey_new failed");
643 (*k
)->type
= KEY_RSA
;
644 (*k
)->rsa
= EVP_PKEY_get1_RSA(pubkey
);
647 if ((*k
= sshkey_new(KEY_UNSPEC
)) == NULL
)
648 fatal("sshkey_new failed");
649 (*k
)->type
= KEY_DSA
;
650 (*k
)->dsa
= EVP_PKEY_get1_DSA(pubkey
);
652 #ifdef OPENSSL_HAS_ECC
654 if ((*k
= sshkey_new(KEY_UNSPEC
)) == NULL
)
655 fatal("sshkey_new failed");
656 (*k
)->type
= KEY_ECDSA
;
657 (*k
)->ecdsa
= EVP_PKEY_get1_EC_KEY(pubkey
);
658 (*k
)->ecdsa_nid
= sshkey_ecdsa_key_to_nid((*k
)->ecdsa
);
662 fatal("%s: unsupported pubkey type %d", __func__
,
663 EVP_PKEY_type(pubkey
->type
));
665 EVP_PKEY_free(pubkey
);
670 do_convert_from_pem(struct sshkey
**k
, int *private)
678 if ((fp
= fopen(identity_file
, "r")) == NULL
)
679 fatal("%s: %s: %s", __progname
, identity_file
, strerror(errno
));
680 if ((rsa
= PEM_read_RSAPublicKey(fp
, NULL
, NULL
, NULL
)) != NULL
) {
681 if ((*k
= sshkey_new(KEY_UNSPEC
)) == NULL
)
682 fatal("sshkey_new failed");
683 (*k
)->type
= KEY_RSA
;
688 #if notyet /* OpenSSH 0.9.8 lacks this function */
690 if ((dsa
= PEM_read_DSAPublicKey(fp
, NULL
, NULL
, NULL
)) != NULL
) {
691 if ((*k
= sshkey_new(KEY_UNSPEC
)) == NULL
)
692 fatal("sshkey_new failed");
693 (*k
)->type
= KEY_DSA
;
700 fatal("%s: unrecognised raw private key format", __func__
);
704 do_convert_from(struct passwd
*pw
)
706 struct sshkey
*k
= NULL
;
707 int r
, private = 0, ok
= 0;
711 ask_filename(pw
, "Enter file in which the key is");
712 if (stat(identity_file
, &st
) < 0)
713 fatal("%s: %s: %s", __progname
, identity_file
, strerror(errno
));
715 switch (convert_format
) {
717 do_convert_from_ssh2(pw
, &k
, &private);
720 do_convert_from_pkcs8(&k
, &private);
723 do_convert_from_pem(&k
, &private);
726 fatal("%s: unknown key format %d", __func__
, convert_format
);
730 if ((r
= sshkey_write(k
, stdout
)) == 0)
733 fprintf(stdout
, "\n");
737 ok
= PEM_write_DSAPrivateKey(stdout
, k
->dsa
, NULL
,
738 NULL
, 0, NULL
, NULL
);
740 #ifdef OPENSSL_HAS_ECC
742 ok
= PEM_write_ECPrivateKey(stdout
, k
->ecdsa
, NULL
,
743 NULL
, 0, NULL
, NULL
);
747 ok
= PEM_write_RSAPrivateKey(stdout
, k
->rsa
, NULL
,
748 NULL
, 0, NULL
, NULL
);
751 fatal("%s: unsupported key type %s", __func__
,
757 fatal("key write failed");
764 do_print_public(struct passwd
*pw
)
771 ask_filename(pw
, "Enter file in which the key is");
772 if (stat(identity_file
, &st
) < 0)
773 fatal("%s: %s", identity_file
, strerror(errno
));
774 prv
= load_identity(identity_file
);
775 if ((r
= sshkey_write(prv
, stdout
)) != 0)
776 error("sshkey_write failed: %s", ssh_err(r
));
778 fprintf(stdout
, "\n");
783 do_download(struct passwd
*pw
)
786 struct sshkey
**keys
= NULL
;
788 enum sshkey_fp_rep rep
;
792 fptype
= print_bubblebabble
? SSH_DIGEST_SHA1
: fingerprint_hash
;
793 rep
= print_bubblebabble
? SSH_FP_BUBBLEBABBLE
: SSH_FP_DEFAULT
;
796 nkeys
= pkcs11_add_provider(pkcs11provider
, NULL
, &keys
);
798 fatal("cannot read public key from pkcs11");
799 for (i
= 0; i
< nkeys
; i
++) {
800 if (print_fingerprint
) {
801 fp
= sshkey_fingerprint(keys
[i
], fptype
, rep
);
802 ra
= sshkey_fingerprint(keys
[i
], fingerprint_hash
,
804 if (fp
== NULL
|| ra
== NULL
)
805 fatal("%s: sshkey_fingerprint fail", __func__
);
806 printf("%u %s %s (PKCS11 key)\n", sshkey_size(keys
[i
]),
807 fp
, sshkey_type(keys
[i
]));
808 if (log_level
>= SYSLOG_LEVEL_VERBOSE
)
813 (void) sshkey_write(keys
[i
], stdout
); /* XXX check */
814 fprintf(stdout
, "\n");
816 sshkey_free(keys
[i
]);
822 fatal("no pkcs11 support");
823 #endif /* ENABLE_PKCS11 */
826 static struct sshkey
*
827 try_read_key(char **cpp
)
832 if ((ret
= sshkey_new(KEY_UNSPEC
)) == NULL
)
833 fatal("sshkey_new failed");
834 if ((r
= sshkey_read(ret
, cpp
)) == 0)
842 fingerprint_one_key(const struct sshkey
*public, const char *comment
)
844 char *fp
= NULL
, *ra
= NULL
;
845 enum sshkey_fp_rep rep
;
848 fptype
= print_bubblebabble
? SSH_DIGEST_SHA1
: fingerprint_hash
;
849 rep
= print_bubblebabble
? SSH_FP_BUBBLEBABBLE
: SSH_FP_DEFAULT
;
850 fp
= sshkey_fingerprint(public, fptype
, rep
);
851 ra
= sshkey_fingerprint(public, fingerprint_hash
, SSH_FP_RANDOMART
);
852 if (fp
== NULL
|| ra
== NULL
)
853 fatal("%s: sshkey_fingerprint failed", __func__
);
854 mprintf("%u %s %s (%s)\n", sshkey_size(public), fp
,
855 comment
? comment
: "no comment", sshkey_type(public));
856 if (log_level
>= SYSLOG_LEVEL_VERBOSE
)
863 fingerprint_private(const char *path
)
866 char *comment
= NULL
;
867 struct sshkey
*public = NULL
;
870 if (stat(identity_file
, &st
) < 0)
871 fatal("%s: %s", path
, strerror(errno
));
872 if ((r
= sshkey_load_public(path
, &public, &comment
)) != 0) {
873 debug("load public \"%s\": %s", path
, ssh_err(r
));
874 if ((r
= sshkey_load_private(path
, NULL
,
875 &public, &comment
)) != 0) {
876 debug("load private \"%s\": %s", path
, ssh_err(r
));
877 fatal("%s is not a key file.", path
);
881 fingerprint_one_key(public, comment
);
887 do_fingerprint(struct passwd
*pw
)
890 struct sshkey
*public = NULL
;
891 char *comment
= NULL
, *cp
, *ep
, line
[SSH_MAX_PUBKEY_BYTES
];
897 ask_filename(pw
, "Enter file in which the key is");
898 path
= identity_file
;
900 if (strcmp(identity_file
, "-") == 0) {
903 } else if ((f
= fopen(path
, "r")) == NULL
)
904 fatal("%s: %s: %s", __progname
, path
, strerror(errno
));
906 while (read_keyfile_line(f
, path
, line
, sizeof(line
), &lnum
) == 0) {
908 cp
[strcspn(cp
, "\n")] = '\0';
909 /* Trim leading space and comments */
910 cp
= line
+ strspn(line
, " \t");
911 if (*cp
== '#' || *cp
== '\0')
915 * Input may be plain keys, private keys, authorized_keys
920 * Try private keys first. Assume a key is private if
921 * "SSH PRIVATE KEY" appears on the first line and we're
922 * not reading from stdin (XXX support private keys on stdin).
924 if (lnum
== 1 && strcmp(identity_file
, "-") != 0 &&
925 strstr(cp
, "PRIVATE KEY") != NULL
) {
927 fingerprint_private(path
);
932 * If it's not a private key, then this must be prepared to
933 * accept a public key prefixed with a hostname or options.
934 * Try a bare key first, otherwise skip the leading stuff.
936 if ((public = try_read_key(&cp
)) == NULL
) {
937 i
= strtol(cp
, &ep
, 10);
938 if (i
== 0 || ep
== NULL
||
939 (*ep
!= ' ' && *ep
!= '\t')) {
943 for (; *cp
&& (quoted
|| (*cp
!= ' ' &&
944 *cp
!= '\t')); cp
++) {
945 if (*cp
== '\\' && cp
[1] == '"')
946 cp
++; /* Skip both */
955 /* Retry after parsing leading hostname/key options */
956 if (public == NULL
&& (public = try_read_key(&cp
)) == NULL
) {
957 debug("%s:%lu: not a public key", path
, lnum
);
961 /* Find trailing comment, if any */
962 for (; *cp
== ' ' || *cp
== '\t'; cp
++)
964 if (*cp
!= '\0' && *cp
!= '#')
967 fingerprint_one_key(public, comment
);
969 invalid
= 0; /* One good key in the file is sufficient */
974 fatal("%s is not a public key file.", path
);
979 do_gen_all_hostkeys(struct passwd
*pw
)
983 char *key_type_display
;
987 { "rsa", "RSA" ,_PATH_HOST_RSA_KEY_FILE
},
988 { "dsa", "DSA", _PATH_HOST_DSA_KEY_FILE
},
989 #ifdef OPENSSL_HAS_ECC
990 { "ecdsa", "ECDSA",_PATH_HOST_ECDSA_KEY_FILE
},
991 #endif /* OPENSSL_HAS_ECC */
992 #endif /* WITH_OPENSSL */
993 { "ed25519", "ED25519",_PATH_HOST_ED25519_KEY_FILE
},
999 struct sshkey
*private, *public;
1000 char comment
[1024], *prv_tmp
, *pub_tmp
, *prv_file
, *pub_file
;
1004 for (i
= 0; key_types
[i
].key_type
; i
++) {
1005 public = private = NULL
;
1006 prv_tmp
= pub_tmp
= prv_file
= pub_file
= NULL
;
1008 xasprintf(&prv_file
, "%s%s",
1009 identity_file
, key_types
[i
].path
);
1011 /* Check whether private key exists and is not zero-length */
1012 if (stat(prv_file
, &st
) == 0) {
1013 if (st
.st_size
!= 0)
1015 } else if (errno
!= ENOENT
) {
1016 error("Could not stat %s: %s", key_types
[i
].path
,
1022 * Private key doesn't exist or is invalid; proceed with
1025 xasprintf(&prv_tmp
, "%s%s.XXXXXXXXXX",
1026 identity_file
, key_types
[i
].path
);
1027 xasprintf(&pub_tmp
, "%s%s.pub.XXXXXXXXXX",
1028 identity_file
, key_types
[i
].path
);
1029 xasprintf(&pub_file
, "%s%s.pub",
1030 identity_file
, key_types
[i
].path
);
1034 printf("%s: generating new host keys: ", __progname
);
1036 printf("%s ", key_types
[i
].key_type_display
);
1038 type
= sshkey_type_from_name(key_types
[i
].key_type
);
1039 if ((fd
= mkstemp(prv_tmp
)) == -1) {
1040 error("Could not save your public key in %s: %s",
1041 prv_tmp
, strerror(errno
));
1044 close(fd
); /* just using mkstemp() to generate/reserve a name */
1046 type_bits_valid(type
, NULL
, &bits
);
1047 if ((r
= sshkey_generate(type
, bits
, &private)) != 0) {
1048 error("sshkey_generate failed: %s", ssh_err(r
));
1051 if ((r
= sshkey_from_private(private, &public)) != 0)
1052 fatal("sshkey_from_private failed: %s", ssh_err(r
));
1053 snprintf(comment
, sizeof comment
, "%s@%s", pw
->pw_name
,
1055 if ((r
= sshkey_save_private(private, prv_tmp
, "",
1056 comment
, use_new_format
, new_format_cipher
, rounds
)) != 0) {
1057 error("Saving key \"%s\" failed: %s",
1058 prv_tmp
, ssh_err(r
));
1061 if ((fd
= mkstemp(pub_tmp
)) == -1) {
1062 error("Could not save your public key in %s: %s",
1063 pub_tmp
, strerror(errno
));
1066 (void)fchmod(fd
, 0644);
1067 f
= fdopen(fd
, "w");
1069 error("fdopen %s failed: %s", pub_tmp
, strerror(errno
));
1073 if ((r
= sshkey_write(public, f
)) != 0) {
1074 error("write key failed: %s", ssh_err(r
));
1078 fprintf(f
, " %s\n", comment
);
1079 if (ferror(f
) != 0) {
1080 error("write key failed: %s", strerror(errno
));
1084 if (fclose(f
) != 0) {
1085 error("key close failed: %s", strerror(errno
));
1089 /* Rename temporary files to their permanent locations. */
1090 if (rename(pub_tmp
, pub_file
) != 0) {
1091 error("Unable to move %s into position: %s",
1092 pub_file
, strerror(errno
));
1095 if (rename(prv_tmp
, prv_file
) != 0) {
1096 error("Unable to move %s into position: %s",
1097 key_types
[i
].path
, strerror(errno
));
1103 sshkey_free(private);
1104 sshkey_free(public);
1114 struct known_hosts_ctx
{
1115 const char *host
; /* Hostname searched for in find/delete case */
1116 FILE *out
; /* Output file, stdout for find_hosts case */
1117 int has_unhashed
; /* When hashing, original had unhashed hosts */
1118 int found_key
; /* For find/delete, host was found */
1119 int invalid
; /* File contained invalid items; don't delete */
1123 known_hosts_hash(struct hostkey_foreach_line
*l
, void *_ctx
)
1125 struct known_hosts_ctx
*ctx
= (struct known_hosts_ctx
*)_ctx
;
1126 char *hashed
, *cp
, *hosts
, *ohosts
;
1127 int has_wild
= l
->hosts
&& strcspn(l
->hosts
, "*?!") != strlen(l
->hosts
);
1128 int was_hashed
= l
->hosts
&& l
->hosts
[0] == HASH_DELIM
;
1130 switch (l
->status
) {
1132 case HKF_STATUS_MATCHED
:
1134 * Don't hash hosts already already hashed, with wildcard
1135 * characters or a CA/revocation marker.
1137 if (was_hashed
|| has_wild
|| l
->marker
!= MRK_NONE
) {
1138 fprintf(ctx
->out
, "%s\n", l
->line
);
1139 if (has_wild
&& !find_host
) {
1140 logit("%s:%lu: ignoring host name "
1141 "with wildcard: %.64s", l
->path
,
1142 l
->linenum
, l
->hosts
);
1147 * Split any comma-separated hostnames from the host list,
1148 * hash and store separately.
1150 ohosts
= hosts
= xstrdup(l
->hosts
);
1151 while ((cp
= strsep(&hosts
, ",")) != NULL
&& *cp
!= '\0') {
1153 if ((hashed
= host_hash(cp
, NULL
, 0)) == NULL
)
1154 fatal("hash_host failed");
1155 fprintf(ctx
->out
, "%s %s\n", hashed
, l
->rawkey
);
1156 ctx
->has_unhashed
= 1;
1160 case HKF_STATUS_INVALID
:
1161 /* Retain invalid lines, but mark file as invalid. */
1163 logit("%s:%lu: invalid line", l
->path
, l
->linenum
);
1166 fprintf(ctx
->out
, "%s\n", l
->line
);
1174 known_hosts_find_delete(struct hostkey_foreach_line
*l
, void *_ctx
)
1176 struct known_hosts_ctx
*ctx
= (struct known_hosts_ctx
*)_ctx
;
1177 enum sshkey_fp_rep rep
;
1181 fptype
= print_bubblebabble
? SSH_DIGEST_SHA1
: fingerprint_hash
;
1182 rep
= print_bubblebabble
? SSH_FP_BUBBLEBABBLE
: SSH_FP_DEFAULT
;
1184 if (l
->status
== HKF_STATUS_MATCHED
) {
1186 if (l
->marker
!= MRK_NONE
) {
1187 /* Don't remove CA and revocation lines */
1188 fprintf(ctx
->out
, "%s\n", l
->line
);
1191 * Hostname matches and has no CA/revoke
1192 * marker, delete it by *not* writing the
1197 printf("# Host %s found: line %lu\n",
1198 ctx
->host
, l
->linenum
);
1201 } else if (find_host
) {
1204 printf("# Host %s found: line %lu %s\n",
1206 l
->linenum
, l
->marker
== MRK_CA
? "CA" :
1207 (l
->marker
== MRK_REVOKE
? "REVOKED" : ""));
1210 known_hosts_hash(l
, ctx
);
1211 else if (print_fingerprint
) {
1212 fp
= sshkey_fingerprint(l
->key
, fptype
, rep
);
1213 mprintf("%s %s %s %s\n", ctx
->host
,
1214 sshkey_type(l
->key
), fp
, l
->comment
);
1217 fprintf(ctx
->out
, "%s\n", l
->line
);
1220 } else if (delete_host
) {
1221 /* Retain non-matching hosts when deleting */
1222 if (l
->status
== HKF_STATUS_INVALID
) {
1224 logit("%s:%lu: invalid line", l
->path
, l
->linenum
);
1226 fprintf(ctx
->out
, "%s\n", l
->line
);
1232 do_known_hosts(struct passwd
*pw
, const char *name
)
1234 char *cp
, tmp
[PATH_MAX
], old
[PATH_MAX
];
1235 int r
, fd
, oerrno
, inplace
= 0;
1236 struct known_hosts_ctx ctx
;
1237 u_int foreach_options
;
1239 if (!have_identity
) {
1240 cp
= tilde_expand_filename(_PATH_SSH_USER_HOSTFILE
, pw
->pw_uid
);
1241 if (strlcpy(identity_file
, cp
, sizeof(identity_file
)) >=
1242 sizeof(identity_file
))
1243 fatal("Specified known hosts path too long");
1248 memset(&ctx
, 0, sizeof(ctx
));
1253 * Find hosts goes to stdout, hash and deletions happen in-place
1254 * A corner case is ssh-keygen -HF foo, which should go to stdout
1256 if (!find_host
&& (hash_hosts
|| delete_host
)) {
1257 if (strlcpy(tmp
, identity_file
, sizeof(tmp
)) >= sizeof(tmp
) ||
1258 strlcat(tmp
, ".XXXXXXXXXX", sizeof(tmp
)) >= sizeof(tmp
) ||
1259 strlcpy(old
, identity_file
, sizeof(old
)) >= sizeof(old
) ||
1260 strlcat(old
, ".old", sizeof(old
)) >= sizeof(old
))
1261 fatal("known_hosts path too long");
1263 if ((fd
= mkstemp(tmp
)) == -1)
1264 fatal("mkstemp: %s", strerror(errno
));
1265 if ((ctx
.out
= fdopen(fd
, "w")) == NULL
) {
1268 fatal("fdopen: %s", strerror(oerrno
));
1273 /* XXX support identity_file == "-" for stdin */
1274 foreach_options
= find_host
? HKF_WANT_MATCH
: 0;
1275 foreach_options
|= print_fingerprint
? HKF_WANT_PARSE_KEY
: 0;
1276 if ((r
= hostkeys_foreach(identity_file
,
1277 hash_hosts
? known_hosts_hash
: known_hosts_find_delete
, &ctx
,
1278 name
, NULL
, foreach_options
)) != 0) {
1281 fatal("%s: hostkeys_foreach failed: %s", __func__
, ssh_err(r
));
1288 error("%s is not a valid known_hosts file.", identity_file
);
1290 error("Not replacing existing known_hosts "
1291 "file because of errors");
1295 } else if (delete_host
&& !ctx
.found_key
) {
1296 logit("Host %s not found in %s", name
, identity_file
);
1299 } else if (inplace
) {
1300 /* Backup existing file */
1301 if (unlink(old
) == -1 && errno
!= ENOENT
)
1302 fatal("unlink %.100s: %s", old
, strerror(errno
));
1303 if (link(identity_file
, old
) == -1)
1304 fatal("link %.100s to %.100s: %s", identity_file
, old
,
1306 /* Move new one into place */
1307 if (rename(tmp
, identity_file
) == -1) {
1308 error("rename\"%s\" to \"%s\": %s", tmp
, identity_file
,
1315 printf("%s updated.\n", identity_file
);
1316 printf("Original contents retained as %s\n", old
);
1317 if (ctx
.has_unhashed
) {
1318 logit("WARNING: %s contains unhashed entries", old
);
1319 logit("Delete this file to ensure privacy "
1324 exit (find_host
&& !ctx
.found_key
);
1328 * Perform changing a passphrase. The argument is the passwd structure
1329 * for the current user.
1332 do_change_passphrase(struct passwd
*pw
)
1335 char *old_passphrase
, *passphrase1
, *passphrase2
;
1337 struct sshkey
*private;
1341 ask_filename(pw
, "Enter file in which the key is");
1342 if (stat(identity_file
, &st
) < 0)
1343 fatal("%s: %s", identity_file
, strerror(errno
));
1344 /* Try to load the file with empty passphrase. */
1345 r
= sshkey_load_private(identity_file
, "", &private, &comment
);
1346 if (r
== SSH_ERR_KEY_WRONG_PASSPHRASE
) {
1347 if (identity_passphrase
)
1348 old_passphrase
= xstrdup(identity_passphrase
);
1351 read_passphrase("Enter old passphrase: ",
1353 r
= sshkey_load_private(identity_file
, old_passphrase
,
1354 &private, &comment
);
1355 explicit_bzero(old_passphrase
, strlen(old_passphrase
));
1356 free(old_passphrase
);
1359 } else if (r
!= 0) {
1361 fatal("Failed to load key %s: %s", identity_file
, ssh_err(r
));
1364 mprintf("Key has comment '%s'\n", comment
);
1366 /* Ask the new passphrase (twice). */
1367 if (identity_new_passphrase
) {
1368 passphrase1
= xstrdup(identity_new_passphrase
);
1372 read_passphrase("Enter new passphrase (empty for no "
1373 "passphrase): ", RP_ALLOW_STDIN
);
1374 passphrase2
= read_passphrase("Enter same passphrase again: ",
1377 /* Verify that they are the same. */
1378 if (strcmp(passphrase1
, passphrase2
) != 0) {
1379 explicit_bzero(passphrase1
, strlen(passphrase1
));
1380 explicit_bzero(passphrase2
, strlen(passphrase2
));
1383 printf("Pass phrases do not match. Try again.\n");
1386 /* Destroy the other copy. */
1387 explicit_bzero(passphrase2
, strlen(passphrase2
));
1391 /* Save the file using the new passphrase. */
1392 if ((r
= sshkey_save_private(private, identity_file
, passphrase1
,
1393 comment
, use_new_format
, new_format_cipher
, rounds
)) != 0) {
1394 error("Saving key \"%s\" failed: %s.",
1395 identity_file
, ssh_err(r
));
1396 explicit_bzero(passphrase1
, strlen(passphrase1
));
1398 sshkey_free(private);
1402 /* Destroy the passphrase and the copy of the key in memory. */
1403 explicit_bzero(passphrase1
, strlen(passphrase1
));
1405 sshkey_free(private); /* Destroys contents */
1408 printf("Your identification has been saved with the new passphrase.\n");
1413 * Print the SSHFP RR.
1416 do_print_resource_record(struct passwd
*pw
, char *fname
, char *hname
)
1418 struct sshkey
*public;
1419 char *comment
= NULL
;
1424 fatal("%s: no filename", __func__
);
1425 if (stat(fname
, &st
) < 0) {
1426 if (errno
== ENOENT
)
1428 fatal("%s: %s", fname
, strerror(errno
));
1430 if ((r
= sshkey_load_public(fname
, &public, &comment
)) != 0)
1431 fatal("Failed to read v2 public key from \"%s\": %s.",
1433 export_dns_rr(hname
, public, stdout
, print_generic
);
1434 sshkey_free(public);
1440 * Change the comment of a private key file.
1443 do_change_comment(struct passwd
*pw
)
1445 char new_comment
[1024], *comment
, *passphrase
;
1446 struct sshkey
*private;
1447 struct sshkey
*public;
1453 ask_filename(pw
, "Enter file in which the key is");
1454 if (stat(identity_file
, &st
) < 0)
1455 fatal("%s: %s", identity_file
, strerror(errno
));
1456 if ((r
= sshkey_load_private(identity_file
, "",
1457 &private, &comment
)) == 0)
1458 passphrase
= xstrdup("");
1459 else if (r
!= SSH_ERR_KEY_WRONG_PASSPHRASE
)
1460 fatal("Cannot load private key \"%s\": %s.",
1461 identity_file
, ssh_err(r
));
1463 if (identity_passphrase
)
1464 passphrase
= xstrdup(identity_passphrase
);
1465 else if (identity_new_passphrase
)
1466 passphrase
= xstrdup(identity_new_passphrase
);
1468 passphrase
= read_passphrase("Enter passphrase: ",
1470 /* Try to load using the passphrase. */
1471 if ((r
= sshkey_load_private(identity_file
, passphrase
,
1472 &private, &comment
)) != 0) {
1473 explicit_bzero(passphrase
, strlen(passphrase
));
1475 fatal("Cannot load private key \"%s\": %s.",
1476 identity_file
, ssh_err(r
));
1480 if (private->type
!= KEY_ED25519
&& !use_new_format
) {
1481 error("Comments are only supported for keys stored in "
1482 "the new format (-o).");
1483 explicit_bzero(passphrase
, strlen(passphrase
));
1484 sshkey_free(private);
1488 printf("Key now has comment '%s'\n", comment
);
1490 printf("Key now has no comment\n");
1492 if (identity_comment
) {
1493 strlcpy(new_comment
, identity_comment
, sizeof(new_comment
));
1495 printf("Enter new comment: ");
1497 if (!fgets(new_comment
, sizeof(new_comment
), stdin
)) {
1498 explicit_bzero(passphrase
, strlen(passphrase
));
1499 sshkey_free(private);
1502 new_comment
[strcspn(new_comment
, "\n")] = '\0';
1505 /* Save the file using the new passphrase. */
1506 if ((r
= sshkey_save_private(private, identity_file
, passphrase
,
1507 new_comment
, use_new_format
, new_format_cipher
, rounds
)) != 0) {
1508 error("Saving key \"%s\" failed: %s",
1509 identity_file
, ssh_err(r
));
1510 explicit_bzero(passphrase
, strlen(passphrase
));
1512 sshkey_free(private);
1516 explicit_bzero(passphrase
, strlen(passphrase
));
1518 if ((r
= sshkey_from_private(private, &public)) != 0)
1519 fatal("sshkey_from_private failed: %s", ssh_err(r
));
1520 sshkey_free(private);
1522 strlcat(identity_file
, ".pub", sizeof(identity_file
));
1523 fd
= open(identity_file
, O_WRONLY
| O_CREAT
| O_TRUNC
, 0644);
1525 fatal("Could not save your public key in %s", identity_file
);
1526 f
= fdopen(fd
, "w");
1528 fatal("fdopen %s failed: %s", identity_file
, strerror(errno
));
1529 if ((r
= sshkey_write(public, f
)) != 0)
1530 fatal("write key failed: %s", ssh_err(r
));
1531 sshkey_free(public);
1532 fprintf(f
, " %s\n", new_comment
);
1537 printf("The comment in your key file has been changed.\n");
1542 add_flag_option(struct sshbuf
*c
, const char *name
)
1546 debug3("%s: %s", __func__
, name
);
1547 if ((r
= sshbuf_put_cstring(c
, name
)) != 0 ||
1548 (r
= sshbuf_put_string(c
, NULL
, 0)) != 0)
1549 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
1553 add_string_option(struct sshbuf
*c
, const char *name
, const char *value
)
1558 debug3("%s: %s=%s", __func__
, name
, value
);
1559 if ((b
= sshbuf_new()) == NULL
)
1560 fatal("%s: sshbuf_new failed", __func__
);
1561 if ((r
= sshbuf_put_cstring(b
, value
)) != 0 ||
1562 (r
= sshbuf_put_cstring(c
, name
)) != 0 ||
1563 (r
= sshbuf_put_stringb(c
, b
)) != 0)
1564 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
1569 #define OPTIONS_CRITICAL 1
1570 #define OPTIONS_EXTENSIONS 2
1572 prepare_options_buf(struct sshbuf
*c
, int which
)
1577 if ((which
& OPTIONS_CRITICAL
) != 0 &&
1578 certflags_command
!= NULL
)
1579 add_string_option(c
, "force-command", certflags_command
);
1580 if ((which
& OPTIONS_EXTENSIONS
) != 0 &&
1581 (certflags_flags
& CERTOPT_X_FWD
) != 0)
1582 add_flag_option(c
, "permit-X11-forwarding");
1583 if ((which
& OPTIONS_EXTENSIONS
) != 0 &&
1584 (certflags_flags
& CERTOPT_AGENT_FWD
) != 0)
1585 add_flag_option(c
, "permit-agent-forwarding");
1586 if ((which
& OPTIONS_EXTENSIONS
) != 0 &&
1587 (certflags_flags
& CERTOPT_PORT_FWD
) != 0)
1588 add_flag_option(c
, "permit-port-forwarding");
1589 if ((which
& OPTIONS_EXTENSIONS
) != 0 &&
1590 (certflags_flags
& CERTOPT_PTY
) != 0)
1591 add_flag_option(c
, "permit-pty");
1592 if ((which
& OPTIONS_EXTENSIONS
) != 0 &&
1593 (certflags_flags
& CERTOPT_USER_RC
) != 0)
1594 add_flag_option(c
, "permit-user-rc");
1595 if ((which
& OPTIONS_CRITICAL
) != 0 &&
1596 certflags_src_addr
!= NULL
)
1597 add_string_option(c
, "source-address", certflags_src_addr
);
1598 for (i
= 0; i
< ncert_userext
; i
++) {
1599 if ((cert_userext
[i
].crit
&& (which
& OPTIONS_EXTENSIONS
)) ||
1600 (!cert_userext
[i
].crit
&& (which
& OPTIONS_CRITICAL
)))
1602 if (cert_userext
[i
].val
== NULL
)
1603 add_flag_option(c
, cert_userext
[i
].key
);
1605 add_string_option(c
, cert_userext
[i
].key
,
1606 cert_userext
[i
].val
);
1611 static struct sshkey
*
1612 load_pkcs11_key(char *path
)
1614 #ifdef ENABLE_PKCS11
1615 struct sshkey
**keys
= NULL
, *public, *private = NULL
;
1618 if ((r
= sshkey_load_public(path
, &public, NULL
)) != 0)
1619 fatal("Couldn't load CA public key \"%s\": %s",
1622 nkeys
= pkcs11_add_provider(pkcs11provider
, identity_passphrase
, &keys
);
1623 debug3("%s: %d keys", __func__
, nkeys
);
1625 fatal("cannot read public key from pkcs11");
1626 for (i
= 0; i
< nkeys
; i
++) {
1627 if (sshkey_equal_public(public, keys
[i
])) {
1631 sshkey_free(keys
[i
]);
1634 sshkey_free(public);
1637 fatal("no pkcs11 support");
1638 #endif /* ENABLE_PKCS11 */
1641 /* Signer for sshkey_certify_custom that uses the agent */
1643 agent_signer(const struct sshkey
*key
, u_char
**sigp
, size_t *lenp
,
1644 const u_char
*data
, size_t datalen
,
1645 const char *alg
, u_int compat
, void *ctx
)
1647 int *agent_fdp
= (int *)ctx
;
1649 return ssh_agent_sign(*agent_fdp
, key
, sigp
, lenp
,
1650 data
, datalen
, alg
, compat
);
1654 do_ca_sign(struct passwd
*pw
, int argc
, char **argv
)
1656 int r
, i
, fd
, found
, agent_fd
= -1;
1658 struct sshkey
*ca
, *public;
1659 char valid
[64], *otmp
, *tmp
, *cp
, *out
, *comment
, **plist
= NULL
;
1661 struct ssh_identitylist
*agent_ids
;
1664 #ifdef ENABLE_PKCS11
1667 tmp
= tilde_expand_filename(ca_key_path
, pw
->pw_uid
);
1668 if (pkcs11provider
!= NULL
) {
1669 /* If a PKCS#11 token was specified then try to use it */
1670 if ((ca
= load_pkcs11_key(tmp
)) == NULL
)
1671 fatal("No PKCS#11 key matching %s found", ca_key_path
);
1672 } else if (prefer_agent
) {
1674 * Agent signature requested. Try to use agent after making
1675 * sure the public key specified is actually present in the
1678 if ((r
= sshkey_load_public(tmp
, &ca
, NULL
)) != 0)
1679 fatal("Cannot load CA public key %s: %s",
1681 if ((r
= ssh_get_authentication_socket(&agent_fd
)) != 0)
1682 fatal("Cannot use public key for CA signature: %s",
1684 if ((r
= ssh_fetch_identitylist(agent_fd
, &agent_ids
)) != 0)
1685 fatal("Retrieve agent key list: %s", ssh_err(r
));
1687 for (j
= 0; j
< agent_ids
->nkeys
; j
++) {
1688 if (sshkey_equal(ca
, agent_ids
->keys
[j
])) {
1694 fatal("CA key %s not found in agent", tmp
);
1695 ssh_free_identitylist(agent_ids
);
1696 ca
->flags
|= SSHKEY_FLAG_EXT
;
1698 /* CA key is assumed to be a private key on the filesystem */
1699 ca
= load_identity(tmp
);
1703 if (key_type_name
!= NULL
&&
1704 sshkey_type_from_name(key_type_name
) != ca
->type
) {
1705 fatal("CA key type %s doesn't match specified %s",
1706 sshkey_ssh_name(ca
), key_type_name
);
1709 for (i
= 0; i
< argc
; i
++) {
1710 /* Split list of principals */
1712 if (cert_principals
!= NULL
) {
1713 otmp
= tmp
= xstrdup(cert_principals
);
1715 for (; (cp
= strsep(&tmp
, ",")) != NULL
; n
++) {
1716 plist
= xreallocarray(plist
, n
+ 1, sizeof(*plist
));
1717 if (*(plist
[n
] = xstrdup(cp
)) == '\0')
1718 fatal("Empty principal name");
1723 tmp
= tilde_expand_filename(argv
[i
], pw
->pw_uid
);
1724 if ((r
= sshkey_load_public(tmp
, &public, &comment
)) != 0)
1725 fatal("%s: unable to open \"%s\": %s",
1726 __func__
, tmp
, ssh_err(r
));
1727 if (public->type
!= KEY_RSA
&& public->type
!= KEY_DSA
&&
1728 public->type
!= KEY_ECDSA
&& public->type
!= KEY_ED25519
)
1729 fatal("%s: key \"%s\" type %s cannot be certified",
1730 __func__
, tmp
, sshkey_type(public));
1732 /* Prepare certificate to sign */
1733 if ((r
= sshkey_to_certified(public)) != 0)
1734 fatal("Could not upgrade key %s to certificate: %s",
1736 public->cert
->type
= cert_key_type
;
1737 public->cert
->serial
= (u_int64_t
)cert_serial
;
1738 public->cert
->key_id
= xstrdup(cert_key_id
);
1739 public->cert
->nprincipals
= n
;
1740 public->cert
->principals
= plist
;
1741 public->cert
->valid_after
= cert_valid_from
;
1742 public->cert
->valid_before
= cert_valid_to
;
1743 prepare_options_buf(public->cert
->critical
, OPTIONS_CRITICAL
);
1744 prepare_options_buf(public->cert
->extensions
,
1745 OPTIONS_EXTENSIONS
);
1746 if ((r
= sshkey_from_private(ca
,
1747 &public->cert
->signature_key
)) != 0)
1748 fatal("sshkey_from_private (ca key): %s", ssh_err(r
));
1750 if (agent_fd
!= -1 && (ca
->flags
& SSHKEY_FLAG_EXT
) != 0) {
1751 if ((r
= sshkey_certify_custom(public, ca
,
1752 key_type_name
, agent_signer
, &agent_fd
)) != 0)
1753 fatal("Couldn't certify key %s via agent: %s",
1756 if ((sshkey_certify(public, ca
, key_type_name
)) != 0)
1757 fatal("Couldn't certify key %s: %s",
1761 if ((cp
= strrchr(tmp
, '.')) != NULL
&& strcmp(cp
, ".pub") == 0)
1763 xasprintf(&out
, "%s-cert.pub", tmp
);
1766 if ((fd
= open(out
, O_WRONLY
|O_CREAT
|O_TRUNC
, 0644)) == -1)
1767 fatal("Could not open \"%s\" for writing: %s", out
,
1769 if ((f
= fdopen(fd
, "w")) == NULL
)
1770 fatal("%s: fdopen: %s", __func__
, strerror(errno
));
1771 if ((r
= sshkey_write(public, f
)) != 0)
1772 fatal("Could not write certified key to %s: %s",
1774 fprintf(f
, " %s\n", comment
);
1778 sshkey_format_cert_validity(public->cert
,
1779 valid
, sizeof(valid
));
1780 logit("Signed %s key %s: id \"%s\" serial %llu%s%s "
1781 "valid %s", sshkey_cert_type(public),
1782 out
, public->cert
->key_id
,
1783 (unsigned long long)public->cert
->serial
,
1784 cert_principals
!= NULL
? " for " : "",
1785 cert_principals
!= NULL
? cert_principals
: "",
1789 sshkey_free(public);
1792 #ifdef ENABLE_PKCS11
1799 parse_relative_time(const char *s
, time_t now
)
1803 mul
= *s
== '-' ? -1 : 1;
1805 if ((secs
= convtime(s
+ 1)) == -1)
1806 fatal("Invalid relative certificate time %s", s
);
1807 if (mul
== -1 && secs
> now
)
1808 fatal("Certificate time %s cannot be represented", s
);
1809 return now
+ (u_int64_t
)(secs
* mul
);
1813 parse_absolute_time(const char *s
)
1820 * POSIX strptime says "The application shall ensure that there
1821 * is white-space or other non-alphanumeric characters between
1822 * any two conversion specifications" so arrange things this way.
1824 switch (strlen(s
)) {
1827 snprintf(buf
, sizeof(buf
), "%.4s-%.2s-%.2s", s
, s
+ 4, s
+ 6);
1830 fmt
= "%Y-%m-%dT%H:%M:%S";
1831 snprintf(buf
, sizeof(buf
), "%.4s-%.2s-%.2sT%.2s:%.2s:%.2s",
1832 s
, s
+ 4, s
+ 6, s
+ 8, s
+ 10, s
+ 12);
1835 fatal("Invalid certificate time format %s", s
);
1838 memset(&tm
, 0, sizeof(tm
));
1839 if (strptime(buf
, fmt
, &tm
) == NULL
)
1840 fatal("Invalid certificate time %s", s
);
1841 if ((tt
= mktime(&tm
)) < 0)
1842 fatal("Certificate time %s cannot be represented", s
);
1843 return (u_int64_t
)tt
;
1847 parse_cert_times(char *timespec
)
1850 time_t now
= time(NULL
);
1853 /* +timespec relative to now */
1854 if (*timespec
== '+' && strchr(timespec
, ':') == NULL
) {
1855 if ((secs
= convtime(timespec
+ 1)) == -1)
1856 fatal("Invalid relative certificate life %s", timespec
);
1857 cert_valid_to
= now
+ secs
;
1859 * Backdate certificate one minute to avoid problems on hosts
1860 * with poorly-synchronised clocks.
1862 cert_valid_from
= ((now
- 59)/ 60) * 60;
1868 * from := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS
1869 * to := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS
1871 from
= xstrdup(timespec
);
1872 to
= strchr(from
, ':');
1873 if (to
== NULL
|| from
== to
|| *(to
+ 1) == '\0')
1874 fatal("Invalid certificate life specification %s", timespec
);
1877 if (*from
== '-' || *from
== '+')
1878 cert_valid_from
= parse_relative_time(from
, now
);
1880 cert_valid_from
= parse_absolute_time(from
);
1882 if (*to
== '-' || *to
== '+')
1883 cert_valid_to
= parse_relative_time(to
, now
);
1885 cert_valid_to
= parse_absolute_time(to
);
1887 if (cert_valid_to
<= cert_valid_from
)
1888 fatal("Empty certificate validity interval");
1893 add_cert_option(char *opt
)
1898 if (strcasecmp(opt
, "clear") == 0)
1899 certflags_flags
= 0;
1900 else if (strcasecmp(opt
, "no-x11-forwarding") == 0)
1901 certflags_flags
&= ~CERTOPT_X_FWD
;
1902 else if (strcasecmp(opt
, "permit-x11-forwarding") == 0)
1903 certflags_flags
|= CERTOPT_X_FWD
;
1904 else if (strcasecmp(opt
, "no-agent-forwarding") == 0)
1905 certflags_flags
&= ~CERTOPT_AGENT_FWD
;
1906 else if (strcasecmp(opt
, "permit-agent-forwarding") == 0)
1907 certflags_flags
|= CERTOPT_AGENT_FWD
;
1908 else if (strcasecmp(opt
, "no-port-forwarding") == 0)
1909 certflags_flags
&= ~CERTOPT_PORT_FWD
;
1910 else if (strcasecmp(opt
, "permit-port-forwarding") == 0)
1911 certflags_flags
|= CERTOPT_PORT_FWD
;
1912 else if (strcasecmp(opt
, "no-pty") == 0)
1913 certflags_flags
&= ~CERTOPT_PTY
;
1914 else if (strcasecmp(opt
, "permit-pty") == 0)
1915 certflags_flags
|= CERTOPT_PTY
;
1916 else if (strcasecmp(opt
, "no-user-rc") == 0)
1917 certflags_flags
&= ~CERTOPT_USER_RC
;
1918 else if (strcasecmp(opt
, "permit-user-rc") == 0)
1919 certflags_flags
|= CERTOPT_USER_RC
;
1920 else if (strncasecmp(opt
, "force-command=", 14) == 0) {
1923 fatal("Empty force-command option");
1924 if (certflags_command
!= NULL
)
1925 fatal("force-command already specified");
1926 certflags_command
= xstrdup(val
);
1927 } else if (strncasecmp(opt
, "source-address=", 15) == 0) {
1930 fatal("Empty source-address option");
1931 if (certflags_src_addr
!= NULL
)
1932 fatal("source-address already specified");
1933 if (addr_match_cidr_list(NULL
, val
) != 0)
1934 fatal("Invalid source-address list");
1935 certflags_src_addr
= xstrdup(val
);
1936 } else if (strncasecmp(opt
, "extension:", 10) == 0 ||
1937 (iscrit
= (strncasecmp(opt
, "critical:", 9) == 0))) {
1938 val
= xstrdup(strchr(opt
, ':') + 1);
1939 if ((cp
= strchr(val
, '=')) != NULL
)
1941 cert_userext
= xreallocarray(cert_userext
, ncert_userext
+ 1,
1942 sizeof(*cert_userext
));
1943 cert_userext
[ncert_userext
].key
= val
;
1944 cert_userext
[ncert_userext
].val
= cp
== NULL
?
1946 cert_userext
[ncert_userext
].crit
= iscrit
;
1949 fatal("Unsupported certificate option \"%s\"", opt
);
1953 show_options(struct sshbuf
*optbuf
, int in_critical
)
1956 struct sshbuf
*options
, *option
= NULL
;
1959 if ((options
= sshbuf_fromb(optbuf
)) == NULL
)
1960 fatal("%s: sshbuf_fromb failed", __func__
);
1961 while (sshbuf_len(options
) != 0) {
1962 sshbuf_free(option
);
1964 if ((r
= sshbuf_get_cstring(options
, &name
, NULL
)) != 0 ||
1965 (r
= sshbuf_froms(options
, &option
)) != 0)
1966 fatal("%s: buffer error: %s", __func__
, ssh_err(r
));
1967 printf(" %s", name
);
1969 (strcmp(name
, "permit-X11-forwarding") == 0 ||
1970 strcmp(name
, "permit-agent-forwarding") == 0 ||
1971 strcmp(name
, "permit-port-forwarding") == 0 ||
1972 strcmp(name
, "permit-pty") == 0 ||
1973 strcmp(name
, "permit-user-rc") == 0))
1975 else if (in_critical
&&
1976 (strcmp(name
, "force-command") == 0 ||
1977 strcmp(name
, "source-address") == 0)) {
1978 if ((r
= sshbuf_get_cstring(option
, &arg
, NULL
)) != 0)
1979 fatal("%s: buffer error: %s",
1980 __func__
, ssh_err(r
));
1981 printf(" %s\n", arg
);
1984 printf(" UNKNOWN OPTION (len %zu)\n",
1985 sshbuf_len(option
));
1986 sshbuf_reset(option
);
1989 if (sshbuf_len(option
) != 0)
1990 fatal("Option corrupt: extra data at end");
1992 sshbuf_free(option
);
1993 sshbuf_free(options
);
1997 print_cert(struct sshkey
*key
)
1999 char valid
[64], *key_fp
, *ca_fp
;
2002 key_fp
= sshkey_fingerprint(key
, fingerprint_hash
, SSH_FP_DEFAULT
);
2003 ca_fp
= sshkey_fingerprint(key
->cert
->signature_key
,
2004 fingerprint_hash
, SSH_FP_DEFAULT
);
2005 if (key_fp
== NULL
|| ca_fp
== NULL
)
2006 fatal("%s: sshkey_fingerprint fail", __func__
);
2007 sshkey_format_cert_validity(key
->cert
, valid
, sizeof(valid
));
2009 printf(" Type: %s %s certificate\n", sshkey_ssh_name(key
),
2010 sshkey_cert_type(key
));
2011 printf(" Public key: %s %s\n", sshkey_type(key
), key_fp
);
2012 printf(" Signing CA: %s %s\n",
2013 sshkey_type(key
->cert
->signature_key
), ca_fp
);
2014 printf(" Key ID: \"%s\"\n", key
->cert
->key_id
);
2015 printf(" Serial: %llu\n", (unsigned long long)key
->cert
->serial
);
2016 printf(" Valid: %s\n", valid
);
2017 printf(" Principals: ");
2018 if (key
->cert
->nprincipals
== 0)
2021 for (i
= 0; i
< key
->cert
->nprincipals
; i
++)
2023 key
->cert
->principals
[i
]);
2026 printf(" Critical Options: ");
2027 if (sshbuf_len(key
->cert
->critical
) == 0)
2031 show_options(key
->cert
->critical
, 1);
2033 printf(" Extensions: ");
2034 if (sshbuf_len(key
->cert
->extensions
) == 0)
2038 show_options(key
->cert
->extensions
, 0);
2043 do_show_cert(struct passwd
*pw
)
2045 struct sshkey
*key
= NULL
;
2047 int r
, is_stdin
= 0, ok
= 0;
2049 char *cp
, line
[SSH_MAX_PUBKEY_BYTES
];
2054 ask_filename(pw
, "Enter file in which the key is");
2055 if (strcmp(identity_file
, "-") != 0 && stat(identity_file
, &st
) < 0)
2056 fatal("%s: %s: %s", __progname
, identity_file
, strerror(errno
));
2058 path
= identity_file
;
2059 if (strcmp(path
, "-") == 0) {
2063 } else if ((f
= fopen(identity_file
, "r")) == NULL
)
2064 fatal("fopen %s: %s", identity_file
, strerror(errno
));
2066 while (read_keyfile_line(f
, path
, line
, sizeof(line
), &lnum
) == 0) {
2069 /* Trim leading space and comments */
2070 cp
= line
+ strspn(line
, " \t");
2071 if (*cp
== '#' || *cp
== '\0')
2073 if ((key
= sshkey_new(KEY_UNSPEC
)) == NULL
)
2074 fatal("sshkey_new");
2075 if ((r
= sshkey_read(key
, &cp
)) != 0) {
2076 error("%s:%lu: invalid key: %s", path
,
2080 if (!sshkey_is_cert(key
)) {
2081 error("%s:%lu is not a certificate", path
, lnum
);
2085 if (!is_stdin
&& lnum
== 1)
2086 printf("%s:\n", path
);
2088 printf("%s:%lu:\n", path
, lnum
);
2097 load_krl(const char *path
, struct ssh_krl
**krlp
)
2099 struct sshbuf
*krlbuf
;
2102 if ((krlbuf
= sshbuf_new()) == NULL
)
2103 fatal("sshbuf_new failed");
2104 if ((fd
= open(path
, O_RDONLY
)) == -1)
2105 fatal("open %s: %s", path
, strerror(errno
));
2106 if ((r
= sshkey_load_file(fd
, krlbuf
)) != 0)
2107 fatal("Unable to load KRL: %s", ssh_err(r
));
2109 /* XXX check sigs */
2110 if ((r
= ssh_krl_from_blob(krlbuf
, krlp
, NULL
, 0)) != 0 ||
2112 fatal("Invalid KRL file: %s", ssh_err(r
));
2113 sshbuf_free(krlbuf
);
2117 update_krl_from_file(struct passwd
*pw
, const char *file
, int wild_ca
,
2118 const struct sshkey
*ca
, struct ssh_krl
*krl
)
2120 struct sshkey
*key
= NULL
;
2122 char *path
, *cp
, *ep
, line
[SSH_MAX_PUBKEY_BYTES
];
2123 unsigned long long serial
, serial2
;
2124 int i
, was_explicit_key
, was_sha1
, r
;
2127 path
= tilde_expand_filename(file
, pw
->pw_uid
);
2128 if (strcmp(path
, "-") == 0) {
2131 path
= xstrdup("(standard input)");
2132 } else if ((krl_spec
= fopen(path
, "r")) == NULL
)
2133 fatal("fopen %s: %s", path
, strerror(errno
));
2136 printf("Revoking from %s\n", path
);
2137 while (read_keyfile_line(krl_spec
, path
, line
, sizeof(line
),
2139 was_explicit_key
= was_sha1
= 0;
2140 cp
= line
+ strspn(line
, " \t");
2141 /* Trim trailing space, comments and strip \n */
2142 for (i
= 0, r
= -1; cp
[i
] != '\0'; i
++) {
2143 if (cp
[i
] == '#' || cp
[i
] == '\n') {
2147 if (cp
[i
] == ' ' || cp
[i
] == '\t') {
2148 /* Remember the start of a span of whitespace */
2158 if (strncasecmp(cp
, "serial:", 7) == 0) {
2159 if (ca
== NULL
&& !wild_ca
) {
2160 fatal("revoking certificates by serial number "
2161 "requires specification of a CA key");
2164 cp
= cp
+ strspn(cp
, " \t");
2166 serial
= strtoull(cp
, &ep
, 0);
2167 if (*cp
== '\0' || (*ep
!= '\0' && *ep
!= '-'))
2168 fatal("%s:%lu: invalid serial \"%s\"",
2170 if (errno
== ERANGE
&& serial
== ULLONG_MAX
)
2171 fatal("%s:%lu: serial out of range",
2177 serial2
= strtoull(cp
, &ep
, 0);
2178 if (*cp
== '\0' || *ep
!= '\0')
2179 fatal("%s:%lu: invalid serial \"%s\"",
2181 if (errno
== ERANGE
&& serial2
== ULLONG_MAX
)
2182 fatal("%s:%lu: serial out of range",
2184 if (serial2
<= serial
)
2185 fatal("%s:%lu: invalid serial range "
2186 "%llu:%llu", path
, lnum
,
2187 (unsigned long long)serial
,
2188 (unsigned long long)serial2
);
2190 if (ssh_krl_revoke_cert_by_serial_range(krl
,
2191 ca
, serial
, serial2
) != 0) {
2192 fatal("%s: revoke serial failed",
2195 } else if (strncasecmp(cp
, "id:", 3) == 0) {
2196 if (ca
== NULL
&& !wild_ca
) {
2197 fatal("revoking certificates by key ID "
2198 "requires specification of a CA key");
2201 cp
= cp
+ strspn(cp
, " \t");
2202 if (ssh_krl_revoke_cert_by_key_id(krl
, ca
, cp
) != 0)
2203 fatal("%s: revoke key ID failed", __func__
);
2205 if (strncasecmp(cp
, "key:", 4) == 0) {
2207 cp
= cp
+ strspn(cp
, " \t");
2208 was_explicit_key
= 1;
2209 } else if (strncasecmp(cp
, "sha1:", 5) == 0) {
2211 cp
= cp
+ strspn(cp
, " \t");
2215 * Just try to process the line as a key.
2216 * Parsing will fail if it isn't.
2219 if ((key
= sshkey_new(KEY_UNSPEC
)) == NULL
)
2220 fatal("sshkey_new");
2221 if ((r
= sshkey_read(key
, &cp
)) != 0)
2222 fatal("%s:%lu: invalid key: %s",
2223 path
, lnum
, ssh_err(r
));
2224 if (was_explicit_key
)
2225 r
= ssh_krl_revoke_key_explicit(krl
, key
);
2227 r
= ssh_krl_revoke_key_sha1(krl
, key
);
2229 r
= ssh_krl_revoke_key(krl
, key
);
2231 fatal("%s: revoke key failed: %s",
2232 __func__
, ssh_err(r
));
2236 if (strcmp(path
, "-") != 0)
2242 do_gen_krl(struct passwd
*pw
, int updating
, int argc
, char **argv
)
2244 struct ssh_krl
*krl
;
2246 struct sshkey
*ca
= NULL
;
2247 int fd
, i
, r
, wild_ca
= 0;
2249 struct sshbuf
*kbuf
;
2251 if (*identity_file
== '\0')
2252 fatal("KRL generation requires an output file");
2253 if (stat(identity_file
, &sb
) == -1) {
2254 if (errno
!= ENOENT
)
2255 fatal("Cannot access KRL \"%s\": %s",
2256 identity_file
, strerror(errno
));
2258 fatal("KRL \"%s\" does not exist", identity_file
);
2260 if (ca_key_path
!= NULL
) {
2261 if (strcasecmp(ca_key_path
, "none") == 0)
2264 tmp
= tilde_expand_filename(ca_key_path
, pw
->pw_uid
);
2265 if ((r
= sshkey_load_public(tmp
, &ca
, NULL
)) != 0)
2266 fatal("Cannot load CA public key %s: %s",
2273 load_krl(identity_file
, &krl
);
2274 else if ((krl
= ssh_krl_init()) == NULL
)
2275 fatal("couldn't create KRL");
2277 if (cert_serial
!= 0)
2278 ssh_krl_set_version(krl
, cert_serial
);
2279 if (identity_comment
!= NULL
)
2280 ssh_krl_set_comment(krl
, identity_comment
);
2282 for (i
= 0; i
< argc
; i
++)
2283 update_krl_from_file(pw
, argv
[i
], wild_ca
, ca
, krl
);
2285 if ((kbuf
= sshbuf_new()) == NULL
)
2286 fatal("sshbuf_new failed");
2287 if (ssh_krl_to_blob(krl
, kbuf
, NULL
, 0) != 0)
2288 fatal("Couldn't generate KRL");
2289 if ((fd
= open(identity_file
, O_WRONLY
|O_CREAT
|O_TRUNC
, 0644)) == -1)
2290 fatal("open %s: %s", identity_file
, strerror(errno
));
2291 if (atomicio(vwrite
, fd
, (void *)sshbuf_ptr(kbuf
), sshbuf_len(kbuf
)) !=
2293 fatal("write %s: %s", identity_file
, strerror(errno
));
2301 do_check_krl(struct passwd
*pw
, int argc
, char **argv
)
2305 struct ssh_krl
*krl
;
2308 if (*identity_file
== '\0')
2309 fatal("KRL checking requires an input file");
2310 load_krl(identity_file
, &krl
);
2311 for (i
= 0; i
< argc
; i
++) {
2312 if ((r
= sshkey_load_public(argv
[i
], &k
, &comment
)) != 0)
2313 fatal("Cannot load public key %s: %s",
2314 argv
[i
], ssh_err(r
));
2315 r
= ssh_krl_check_key(krl
, k
);
2316 printf("%s%s%s%s: %s\n", argv
[i
],
2317 *comment
? " (" : "", comment
, *comment
? ")" : "",
2318 r
== 0 ? "ok" : "REVOKED");
2332 "usage: ssh-keygen [-q] [-b bits] [-t dsa | ecdsa | ed25519 | rsa]\n"
2333 " [-N new_passphrase] [-C comment] [-f output_keyfile]\n"
2334 " ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile]\n"
2335 " ssh-keygen -i [-m key_format] [-f input_keyfile]\n"
2336 " ssh-keygen -e [-m key_format] [-f input_keyfile]\n"
2337 " ssh-keygen -y [-f input_keyfile]\n"
2338 " ssh-keygen -c [-P passphrase] [-C comment] [-f keyfile]\n"
2339 " ssh-keygen -l [-v] [-E fingerprint_hash] [-f input_keyfile]\n"
2340 " ssh-keygen -B [-f input_keyfile]\n");
2341 #ifdef ENABLE_PKCS11
2343 " ssh-keygen -D pkcs11\n");
2346 " ssh-keygen -F hostname [-f known_hosts_file] [-l]\n"
2347 " ssh-keygen -H [-f known_hosts_file]\n"
2348 " ssh-keygen -R hostname [-f known_hosts_file]\n"
2349 " ssh-keygen -r hostname [-f input_keyfile] [-g]\n"
2351 " ssh-keygen -G output_file [-v] [-b bits] [-M memory] [-S start_point]\n"
2352 " ssh-keygen -T output_file -f input_file [-v] [-a rounds] [-J num_lines]\n"
2353 " [-j start_line] [-K checkpt] [-W generator]\n"
2355 " ssh-keygen -s ca_key -I certificate_identity [-h] [-U]\n"
2356 " [-D pkcs11_provider] [-n principals] [-O option]\n"
2357 " [-V validity_interval] [-z serial_number] file ...\n"
2358 " ssh-keygen -L [-f input_keyfile]\n"
2360 " ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number]\n"
2362 " ssh-keygen -Q -f krl_file file ...\n");
2367 * Main program for key management.
2370 main(int argc
, char **argv
)
2372 char dotsshdir
[PATH_MAX
], comment
[1024], *passphrase1
, *passphrase2
;
2373 char *rr_hostname
= NULL
, *ep
, *fp
, *ra
;
2374 struct sshkey
*private, *public;
2377 int r
, opt
, type
, fd
;
2378 int gen_all_hostkeys
= 0, gen_krl
= 0, update_krl
= 0, check_krl
= 0;
2382 /* Moduli generation/screening */
2383 char out_file
[PATH_MAX
], *checkpoint
= NULL
;
2384 u_int32_t memory
= 0, generator_wanted
= 0;
2385 int do_gen_candidates
= 0, do_screen_candidates
= 0;
2386 unsigned long start_lineno
= 0, lines_to_process
= 0;
2387 BIGNUM
*start
= NULL
;
2391 extern char *optarg
;
2393 ssh_malloc_init(); /* must be called before any mallocs */
2394 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
2397 __progname
= ssh_get_progname(argv
[0]);
2400 OpenSSL_add_all_algorithms();
2402 log_init(argv
[0], SYSLOG_LEVEL_INFO
, SYSLOG_FACILITY_USER
, 1);
2408 /* we need this for the home * directory. */
2409 pw
= getpwuid(getuid());
2411 fatal("No user exists for uid %lu", (u_long
)getuid());
2412 if (gethostname(hostname
, sizeof(hostname
)) < 0)
2413 fatal("gethostname: %s", strerror(errno
));
2415 /* Remaining characters: Ydw */
2416 while ((opt
= getopt(argc
, argv
, "ABHLQUXceghiklopquvxy"
2417 "C:D:E:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Z:"
2418 "a:b:f:g:j:m:n:r:s:t:z:")) != -1) {
2421 gen_all_hostkeys
= 1;
2424 bits
= (u_int32_t
)strtonum(optarg
, 256, 32768, &errstr
);
2426 fatal("Bits has bad value %s (%s)",
2430 fingerprint_hash
= ssh_digest_alg_by_name(optarg
);
2431 if (fingerprint_hash
== -1)
2432 fatal("Invalid hash algorithm \"%s\"", optarg
);
2436 rr_hostname
= optarg
;
2442 cert_key_id
= optarg
;
2446 rr_hostname
= optarg
;
2452 print_fingerprint
= 1;
2455 print_bubblebabble
= 1;
2458 if (strcasecmp(optarg
, "RFC4716") == 0 ||
2459 strcasecmp(optarg
, "ssh2") == 0) {
2460 convert_format
= FMT_RFC4716
;
2463 if (strcasecmp(optarg
, "PKCS8") == 0) {
2464 convert_format
= FMT_PKCS8
;
2467 if (strcasecmp(optarg
, "PEM") == 0) {
2468 convert_format
= FMT_PEM
;
2471 fatal("Unsupported conversion format \"%s\"", optarg
);
2473 cert_principals
= optarg
;
2479 change_passphrase
= 1;
2485 if (strlcpy(identity_file
, optarg
,
2486 sizeof(identity_file
)) >= sizeof(identity_file
))
2487 fatal("Identity filename too long");
2494 identity_passphrase
= optarg
;
2497 identity_new_passphrase
= optarg
;
2503 add_cert_option(optarg
);
2506 new_format_cipher
= optarg
;
2509 identity_comment
= optarg
;
2520 cert_key_type
= SSH2_CERT_TYPE_HOST
;
2521 certflags_flags
= 0;
2535 ca_key_path
= optarg
;
2538 key_type_name
= optarg
;
2541 pkcs11provider
= optarg
;
2550 if (log_level
== SYSLOG_LEVEL_INFO
)
2551 log_level
= SYSLOG_LEVEL_DEBUG1
;
2553 if (log_level
>= SYSLOG_LEVEL_DEBUG1
&&
2554 log_level
< SYSLOG_LEVEL_DEBUG3
)
2559 rr_hostname
= optarg
;
2562 rounds
= (int)strtonum(optarg
, 1, INT_MAX
, &errstr
);
2564 fatal("Invalid number: %s (%s)",
2568 parse_cert_times(optarg
);
2572 cert_serial
= strtoull(optarg
, &ep
, 10);
2573 if (*optarg
< '0' || *optarg
> '9' || *ep
!= '\0' ||
2574 (errno
== ERANGE
&& cert_serial
== ULLONG_MAX
))
2575 fatal("Invalid serial number \"%s\"", optarg
);
2578 /* Moduli generation/screening */
2580 do_gen_candidates
= 1;
2581 if (strlcpy(out_file
, optarg
, sizeof(out_file
)) >=
2583 fatal("Output filename too long");
2586 lines_to_process
= strtoul(optarg
, NULL
, 10);
2589 start_lineno
= strtoul(optarg
, NULL
, 10);
2592 if (strlen(optarg
) >= PATH_MAX
)
2593 fatal("Checkpoint filename too long");
2594 checkpoint
= xstrdup(optarg
);
2597 memory
= (u_int32_t
)strtonum(optarg
, 1, UINT_MAX
,
2600 fatal("Memory limit is %s: %s", errstr
, optarg
);
2603 /* XXX - also compare length against bits */
2604 if (BN_hex2bn(&start
, optarg
) == 0)
2605 fatal("Invalid start point.");
2608 do_screen_candidates
= 1;
2609 if (strlcpy(out_file
, optarg
, sizeof(out_file
)) >=
2611 fatal("Output filename too long");
2614 generator_wanted
= (u_int32_t
)strtonum(optarg
, 1,
2617 fatal("Desired generator invalid: %s (%s)",
2620 #endif /* WITH_OPENSSL */
2628 log_init(argv
[0], log_level
, SYSLOG_FACILITY_USER
, 1);
2633 if (ca_key_path
!= NULL
) {
2634 if (argc
< 1 && !gen_krl
) {
2635 error("Too few arguments.");
2638 } else if (argc
> 0 && !gen_krl
&& !check_krl
) {
2639 error("Too many arguments.");
2642 if (change_passphrase
&& change_comment
) {
2643 error("Can only have one of -p and -c.");
2646 if (print_fingerprint
&& (delete_host
|| hash_hosts
)) {
2647 error("Cannot use -l with -H or -R.");
2651 do_gen_krl(pw
, update_krl
, argc
, argv
);
2655 do_check_krl(pw
, argc
, argv
);
2658 if (ca_key_path
!= NULL
) {
2659 if (cert_key_id
== NULL
)
2660 fatal("Must specify key id (-I) when certifying");
2661 do_ca_sign(pw
, argc
, argv
);
2665 if (delete_host
|| hash_hosts
|| find_host
)
2666 do_known_hosts(pw
, rr_hostname
);
2667 if (pkcs11provider
!= NULL
)
2669 if (print_fingerprint
|| print_bubblebabble
)
2671 if (change_passphrase
)
2672 do_change_passphrase(pw
);
2674 do_change_comment(pw
);
2679 do_convert_from(pw
);
2682 do_print_public(pw
);
2683 if (rr_hostname
!= NULL
) {
2686 if (have_identity
) {
2687 n
= do_print_resource_record(pw
,
2688 identity_file
, rr_hostname
);
2690 fatal("%s: %s", identity_file
, strerror(errno
));
2694 n
+= do_print_resource_record(pw
,
2695 _PATH_HOST_RSA_KEY_FILE
, rr_hostname
);
2696 n
+= do_print_resource_record(pw
,
2697 _PATH_HOST_DSA_KEY_FILE
, rr_hostname
);
2698 n
+= do_print_resource_record(pw
,
2699 _PATH_HOST_ECDSA_KEY_FILE
, rr_hostname
);
2700 n
+= do_print_resource_record(pw
,
2701 _PATH_HOST_ED25519_KEY_FILE
, rr_hostname
);
2703 fatal("no keys found.");
2709 if (do_gen_candidates
) {
2710 FILE *out
= fopen(out_file
, "w");
2713 error("Couldn't open modulus candidate file \"%s\": %s",
2714 out_file
, strerror(errno
));
2718 bits
= DEFAULT_BITS
;
2719 if (gen_candidates(out
, memory
, bits
, start
) != 0)
2720 fatal("modulus candidate generation failed");
2725 if (do_screen_candidates
) {
2727 FILE *out
= fopen(out_file
, "a");
2729 if (have_identity
&& strcmp(identity_file
, "-") != 0) {
2730 if ((in
= fopen(identity_file
, "r")) == NULL
) {
2731 fatal("Couldn't open modulus candidate "
2732 "file \"%s\": %s", identity_file
,
2739 fatal("Couldn't open moduli file \"%s\": %s",
2740 out_file
, strerror(errno
));
2742 if (prime_test(in
, out
, rounds
== 0 ? 100 : rounds
,
2743 generator_wanted
, checkpoint
,
2744 start_lineno
, lines_to_process
) != 0)
2745 fatal("modulus screening failed");
2750 if (gen_all_hostkeys
) {
2751 do_gen_all_hostkeys(pw
);
2755 if (key_type_name
== NULL
)
2756 key_type_name
= DEFAULT_KEY_TYPE_NAME
;
2758 type
= sshkey_type_from_name(key_type_name
);
2759 type_bits_valid(type
, key_type_name
, &bits
);
2762 printf("Generating public/private %s key pair.\n",
2764 if ((r
= sshkey_generate(type
, bits
, &private)) != 0)
2765 fatal("sshkey_generate failed");
2766 if ((r
= sshkey_from_private(private, &public)) != 0)
2767 fatal("sshkey_from_private failed: %s\n", ssh_err(r
));
2770 ask_filename(pw
, "Enter file in which to save the key");
2772 /* Create ~/.ssh directory if it doesn't already exist. */
2773 snprintf(dotsshdir
, sizeof dotsshdir
, "%s/%s",
2774 pw
->pw_dir
, _PATH_SSH_USER_DIR
);
2775 if (strstr(identity_file
, dotsshdir
) != NULL
) {
2776 if (stat(dotsshdir
, &st
) < 0) {
2777 if (errno
!= ENOENT
) {
2778 error("Could not stat %s: %s", dotsshdir
,
2780 } else if (mkdir(dotsshdir
, 0700) < 0) {
2781 error("Could not create directory '%s': %s",
2782 dotsshdir
, strerror(errno
));
2784 printf("Created directory '%s'.\n", dotsshdir
);
2787 /* If the file already exists, ask the user to confirm. */
2788 if (stat(identity_file
, &st
) >= 0) {
2790 printf("%s already exists.\n", identity_file
);
2791 printf("Overwrite (y/n)? ");
2793 if (fgets(yesno
, sizeof(yesno
), stdin
) == NULL
)
2795 if (yesno
[0] != 'y' && yesno
[0] != 'Y')
2798 /* Ask for a passphrase (twice). */
2799 if (identity_passphrase
)
2800 passphrase1
= xstrdup(identity_passphrase
);
2801 else if (identity_new_passphrase
)
2802 passphrase1
= xstrdup(identity_new_passphrase
);
2806 read_passphrase("Enter passphrase (empty for no "
2807 "passphrase): ", RP_ALLOW_STDIN
);
2808 passphrase2
= read_passphrase("Enter same passphrase again: ",
2810 if (strcmp(passphrase1
, passphrase2
) != 0) {
2812 * The passphrases do not match. Clear them and
2815 explicit_bzero(passphrase1
, strlen(passphrase1
));
2816 explicit_bzero(passphrase2
, strlen(passphrase2
));
2819 printf("Passphrases do not match. Try again.\n");
2820 goto passphrase_again
;
2822 /* Clear the other copy of the passphrase. */
2823 explicit_bzero(passphrase2
, strlen(passphrase2
));
2827 if (identity_comment
) {
2828 strlcpy(comment
, identity_comment
, sizeof(comment
));
2830 /* Create default comment field for the passphrase. */
2831 snprintf(comment
, sizeof comment
, "%s@%s", pw
->pw_name
, hostname
);
2834 /* Save the key with the given passphrase and comment. */
2835 if ((r
= sshkey_save_private(private, identity_file
, passphrase1
,
2836 comment
, use_new_format
, new_format_cipher
, rounds
)) != 0) {
2837 error("Saving key \"%s\" failed: %s",
2838 identity_file
, ssh_err(r
));
2839 explicit_bzero(passphrase1
, strlen(passphrase1
));
2843 /* Clear the passphrase. */
2844 explicit_bzero(passphrase1
, strlen(passphrase1
));
2847 /* Clear the private key and the random number generator. */
2848 sshkey_free(private);
2851 printf("Your identification has been saved in %s.\n", identity_file
);
2853 strlcat(identity_file
, ".pub", sizeof(identity_file
));
2854 if ((fd
= open(identity_file
, O_WRONLY
|O_CREAT
|O_TRUNC
, 0644)) == -1)
2855 fatal("Unable to save public key to %s: %s",
2856 identity_file
, strerror(errno
));
2857 if ((f
= fdopen(fd
, "w")) == NULL
)
2858 fatal("fdopen %s failed: %s", identity_file
, strerror(errno
));
2859 if ((r
= sshkey_write(public, f
)) != 0)
2860 error("write key failed: %s", ssh_err(r
));
2861 fprintf(f
, " %s\n", comment
);
2865 fp
= sshkey_fingerprint(public, fingerprint_hash
,
2867 ra
= sshkey_fingerprint(public, fingerprint_hash
,
2869 if (fp
== NULL
|| ra
== NULL
)
2870 fatal("sshkey_fingerprint failed");
2871 printf("Your public key has been saved in %s.\n",
2873 printf("The key fingerprint is:\n");
2874 printf("%s %s\n", fp
, comment
);
2875 printf("The key's randomart image is:\n");
2881 sshkey_free(public);