aboutsummaryrefslogtreecommitdiff
path: root/ssh-keygen.c
diff options
context:
space:
mode:
authorEd Maste <emaste@FreeBSD.org>2021-02-14 21:07:21 +0000
committerEd Maste <emaste@FreeBSD.org>2021-02-14 21:07:21 +0000
commitdb903103f46785ea0bba0f228691e1f8fb3a643d (patch)
tree74026f96189cd1c487ea2c8e038b921e3861e1b1 /ssh-keygen.c
parent82e5fdc50050d6dccf1f547818312aebd3b6626e (diff)
downloadsrc-db903103f46785ea0bba0f228691e1f8fb3a643d.tar.gz
src-db903103f46785ea0bba0f228691e1f8fb3a643d.zip
Diffstat (limited to 'ssh-keygen.c')
-rw-r--r--ssh-keygen.c157
1 files changed, 68 insertions, 89 deletions
diff --git a/ssh-keygen.c b/ssh-keygen.c
index 0d6ed1fff2c5..2c5c75db7f08 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keygen.c,v 1.398 2020/02/07 03:27:54 djm Exp $ */
+/* $OpenBSD: ssh-keygen.c,v 1.409.2.1 2020/05/18 19:02:13 benno Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -327,8 +327,7 @@ load_identity(const char *filename, char **commentp)
else
pass = read_passphrase("Enter passphrase: ", RP_ALLOW_STDIN);
r = sshkey_load_private(filename, pass, &prv, commentp);
- explicit_bzero(pass, strlen(pass));
- free(pass);
+ freezero(pass, strlen(pass));
if (r != 0)
fatal("Load key \"%s\": %s", filename, ssh_err(r));
return prv;
@@ -670,9 +669,10 @@ do_convert_from_ssh2(struct passwd *pw, struct sshkey **k, int *private)
encoded[len-3] = '\0';
if ((r = sshbuf_b64tod(buf, encoded)) != 0)
fatal("%s: base64 decoding failed: %s", __func__, ssh_err(r));
- if (*private)
- *k = do_convert_private_ssh2(buf);
- else if ((r = sshkey_fromb(buf, k)) != 0)
+ if (*private) {
+ if ((*k = do_convert_private_ssh2(buf)) == NULL)
+ fatal("%s: private key conversion failed", __func__);
+ } else if ((r = sshkey_fromb(buf, k)) != 0)
fatal("decode blob failed: %s", ssh_err(r));
sshbuf_free(buf);
fclose(fp);
@@ -911,22 +911,25 @@ fingerprint_private(const char *path)
{
struct stat st;
char *comment = NULL;
- struct sshkey *public = NULL;
+ struct sshkey *privkey = NULL, *pubkey = NULL;
int r;
if (stat(identity_file, &st) == -1)
fatal("%s: %s", path, strerror(errno));
- if ((r = sshkey_load_public(path, &public, &comment)) != 0) {
+ if ((r = sshkey_load_public(path, &pubkey, &comment)) != 0)
debug("load public \"%s\": %s", path, ssh_err(r));
+ if (pubkey == NULL || comment == NULL || *comment == '\0') {
+ free(comment);
if ((r = sshkey_load_private(path, NULL,
- &public, &comment)) != 0) {
+ &privkey, &comment)) != 0)
debug("load private \"%s\": %s", path, ssh_err(r));
- fatal("%s is not a key file.", path);
- }
}
+ if (pubkey == NULL && privkey == NULL)
+ fatal("%s is not a key file.", path);
- fingerprint_one_key(public, comment);
- sshkey_free(public);
+ fingerprint_one_key(pubkey == NULL ? privkey : pubkey, comment);
+ sshkey_free(pubkey);
+ sshkey_free(privkey);
free(comment);
}
@@ -1054,7 +1057,6 @@ do_gen_all_hostkeys(struct passwd *pw)
struct sshkey *private, *public;
char comment[1024], *prv_tmp, *pub_tmp, *prv_file, *pub_file;
int i, type, fd, r;
- FILE *f;
for (i = 0; key_types[i].key_type; i++) {
public = private = NULL;
@@ -1092,11 +1094,11 @@ do_gen_all_hostkeys(struct passwd *pw)
fflush(stdout);
type = sshkey_type_from_name(key_types[i].key_type);
if ((fd = mkstemp(prv_tmp)) == -1) {
- error("Could not save your public key in %s: %s",
+ error("Could not save your private key in %s: %s",
prv_tmp, strerror(errno));
goto failnext;
}
- close(fd); /* just using mkstemp() to generate/reserve a name */
+ (void)close(fd); /* just using mkstemp() to reserve a name */
bits = 0;
type_bits_valid(type, NULL, &bits);
if ((r = sshkey_generate(type, bits, &private)) != 0) {
@@ -1120,25 +1122,10 @@ do_gen_all_hostkeys(struct passwd *pw)
goto failnext;
}
(void)fchmod(fd, 0644);
- f = fdopen(fd, "w");
- if (f == NULL) {
- error("fdopen %s failed: %s", pub_tmp, strerror(errno));
- close(fd);
- goto failnext;
- }
- if ((r = sshkey_write(public, f)) != 0) {
- error("write key failed: %s", ssh_err(r));
- fclose(f);
- goto failnext;
- }
- fprintf(f, " %s\n", comment);
- if (ferror(f) != 0) {
- error("write key failed: %s", strerror(errno));
- fclose(f);
- goto failnext;
- }
- if (fclose(f) != 0) {
- error("key close failed: %s", strerror(errno));
+ (void)close(fd);
+ if ((r = sshkey_save_public(public, pub_tmp, comment)) != 0) {
+ fatal("Unable to save public key to %s: %s",
+ identity_file, ssh_err(r));
goto failnext;
}
@@ -1424,8 +1411,7 @@ do_change_passphrase(struct passwd *pw)
RP_ALLOW_STDIN);
r = sshkey_load_private(identity_file, old_passphrase,
&private, &comment);
- explicit_bzero(old_passphrase, strlen(old_passphrase));
- free(old_passphrase);
+ freezero(old_passphrase, strlen(old_passphrase));
if (r != 0)
goto badkey;
} else if (r != 0) {
@@ -1456,8 +1442,7 @@ do_change_passphrase(struct passwd *pw)
exit(1);
}
/* Destroy the other copy. */
- explicit_bzero(passphrase2, strlen(passphrase2));
- free(passphrase2);
+ freezero(passphrase2, strlen(passphrase2));
}
/* Save the file using the new passphrase. */
@@ -1465,15 +1450,13 @@ do_change_passphrase(struct passwd *pw)
comment, private_key_format, openssh_format_cipher, rounds)) != 0) {
error("Saving key \"%s\" failed: %s.",
identity_file, ssh_err(r));
- explicit_bzero(passphrase1, strlen(passphrase1));
- free(passphrase1);
+ freezero(passphrase1, strlen(passphrase1));
sshkey_free(private);
free(comment);
exit(1);
}
/* Destroy the passphrase and the copy of the key in memory. */
- explicit_bzero(passphrase1, strlen(passphrase1));
- free(passphrase1);
+ freezero(passphrase1, strlen(passphrase1));
sshkey_free(private); /* Destroys contents */
free(comment);
@@ -1519,8 +1502,7 @@ do_change_comment(struct passwd *pw, const char *identity_comment)
struct sshkey *private;
struct sshkey *public;
struct stat st;
- FILE *f;
- int r, fd;
+ int r;
if (!have_identity)
ask_filename(pw, "Enter file in which the key is");
@@ -1543,8 +1525,7 @@ do_change_comment(struct passwd *pw, const char *identity_comment)
/* Try to load using the passphrase. */
if ((r = sshkey_load_private(identity_file, passphrase,
&private, &comment)) != 0) {
- explicit_bzero(passphrase, strlen(passphrase));
- free(passphrase);
+ freezero(passphrase, strlen(passphrase));
fatal("Cannot load private key \"%s\": %s.",
identity_file, ssh_err(r));
}
@@ -1589,31 +1570,22 @@ do_change_comment(struct passwd *pw, const char *identity_comment)
rounds)) != 0) {
error("Saving key \"%s\" failed: %s",
identity_file, ssh_err(r));
- explicit_bzero(passphrase, strlen(passphrase));
- free(passphrase);
+ freezero(passphrase, strlen(passphrase));
sshkey_free(private);
free(comment);
exit(1);
}
- explicit_bzero(passphrase, strlen(passphrase));
- free(passphrase);
+ freezero(passphrase, strlen(passphrase));
if ((r = sshkey_from_private(private, &public)) != 0)
fatal("sshkey_from_private failed: %s", ssh_err(r));
sshkey_free(private);
strlcat(identity_file, ".pub", sizeof(identity_file));
- fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
- if (fd == -1)
- fatal("Could not save your public key in %s", identity_file);
- f = fdopen(fd, "w");
- if (f == NULL)
- fatal("fdopen %s failed: %s", identity_file, strerror(errno));
- if ((r = sshkey_write(public, f)) != 0)
- fatal("write key failed: %s", ssh_err(r));
+ if ((r = sshkey_save_public(public, identity_file, new_comment)) != 0) {
+ fatal("Unable to save public key to %s: %s",
+ identity_file, ssh_err(r));
+ }
sshkey_free(public);
- fprintf(f, " %s\n", new_comment);
- fclose(f);
-
free(comment);
if (strlen(new_comment) > 0)
@@ -1678,7 +1650,7 @@ prepare_options_buf(struct sshbuf *c, int which)
if ((which & OPTIONS_EXTENSIONS) != 0 &&
(certflags_flags & CERTOPT_USER_RC) != 0)
add_flag_option(c, "permit-user-rc");
- if ((which & OPTIONS_CRITICAL) != 0 &&
+ if ((which & OPTIONS_EXTENSIONS) != 0 &&
(certflags_flags & CERTOPT_NO_REQUIRE_USER_PRESENCE) != 0)
add_flag_option(c, "no-touch-required");
if ((which & OPTIONS_CRITICAL) != 0 &&
@@ -1745,12 +1717,11 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent,
unsigned long long cert_serial, int cert_serial_autoinc,
int argc, char **argv)
{
- int r, i, fd, found, agent_fd = -1;
+ int r, i, found, agent_fd = -1;
u_int n;
struct sshkey *ca, *public;
char valid[64], *otmp, *tmp, *cp, *out, *comment;
char *ca_fp = NULL, **plist = NULL;
- FILE *f;
struct ssh_identitylist *agent_ids;
size_t j;
struct notifier_ctx *notifier = NULL;
@@ -1873,16 +1844,10 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent,
xasprintf(&out, "%s-cert.pub", tmp);
free(tmp);
- if ((fd = open(out, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1)
- fatal("Could not open \"%s\" for writing: %s", out,
- strerror(errno));
- if ((f = fdopen(fd, "w")) == NULL)
- fatal("%s: fdopen: %s", __func__, strerror(errno));
- if ((r = sshkey_write(public, f)) != 0)
- fatal("Could not write certified key to %s: %s",
- out, ssh_err(r));
- fprintf(f, " %s\n", comment);
- fclose(f);
+ if ((r = sshkey_save_public(public, out, comment)) != 0) {
+ fatal("Unable to save public key to %s: %s",
+ identity_file, ssh_err(r));
+ }
if (!quiet) {
sshkey_format_cert_validity(public->cert,
@@ -2330,6 +2295,9 @@ update_krl_from_file(struct passwd *pw, const char *file, int wild_ca,
cp = cp + strspn(cp, " \t");
hash_to_blob(cp, &blob, &blen, file, lnum);
r = ssh_krl_revoke_key_sha256(krl, blob, blen);
+ if (r != 0)
+ fatal("%s: revoke key failed: %s",
+ __func__, ssh_err(r));
} else {
if (strncasecmp(cp, "key:", 4) == 0) {
cp += 4;
@@ -2444,7 +2412,7 @@ do_gen_krl(struct passwd *pw, int updating, const char *ca_key_path,
}
static void
-do_check_krl(struct passwd *pw, int argc, char **argv)
+do_check_krl(struct passwd *pw, int print_krl, int argc, char **argv)
{
int i, r, ret = 0;
char *comment;
@@ -2454,6 +2422,8 @@ do_check_krl(struct passwd *pw, int argc, char **argv)
if (*identity_file == '\0')
fatal("KRL checking requires an input file");
load_krl(identity_file, &krl);
+ if (print_krl)
+ krl_dump(krl, stdout);
for (i = 0; i < argc; i++) {
if ((r = sshkey_load_public(argv[i], &k, &comment)) != 0)
fatal("Cannot load public key %s: %s",
@@ -2481,7 +2451,7 @@ load_sign_key(const char *keypath, const struct sshkey *pubkey)
int r;
/*
- * If passed a public key filename, then try to locate the correponding
+ * If passed a public key filename, then try to locate the corresponding
* private key. This lets us specify certificates on the command-line
* and have ssh-keygen find the appropriate private key.
*/
@@ -2965,22 +2935,31 @@ do_download_sk(const char *skprovider, const char *device)
struct sshkey **keys;
size_t nkeys, i;
int r, ok = -1;
- char *fp, *pin, *pass = NULL, *path, *pubpath;
+ char *fp, *pin = NULL, *pass = NULL, *path, *pubpath;
const char *ext;
if (skprovider == NULL)
fatal("Cannot download keys without provider");
- pin = read_passphrase("Enter PIN for authenticator: ", RP_ALLOW_STDIN);
- if ((r = sshsk_load_resident(skprovider, device, pin,
- &keys, &nkeys)) != 0) {
- freezero(pin, strlen(pin));
- error("Unable to load resident keys: %s", ssh_err(r));
- return -1;
+ for (i = 0; i < 2; i++) {
+ if (i == 1) {
+ pin = read_passphrase("Enter PIN for authenticator: ",
+ RP_ALLOW_STDIN);
+ }
+ if ((r = sshsk_load_resident(skprovider, device, pin,
+ &keys, &nkeys)) != 0) {
+ if (i == 0 && r == SSH_ERR_KEY_WRONG_PASSPHRASE)
+ continue;
+ if (pin != NULL)
+ freezero(pin, strlen(pin));
+ error("Unable to load resident keys: %s", ssh_err(r));
+ return -1;
+ }
}
if (nkeys == 0)
logit("No keys to download");
- freezero(pin, strlen(pin));
+ if (pin != NULL)
+ freezero(pin, strlen(pin));
for (i = 0; i < nkeys; i++) {
if (keys[i]->type != KEY_ECDSA_SK &&
@@ -3030,9 +3009,9 @@ do_download_sk(const char *skprovider, const char *device)
free(path);
if ((r = sshkey_save_public(keys[i], pubpath,
keys[i]->sk_application)) != 0) {
- free(pubpath);
error("Saving public key \"%s\" failed: %s",
pubpath, ssh_err(r));
+ free(pubpath);
break;
}
free(pubpath);
@@ -3084,7 +3063,7 @@ usage(void)
" ssh-keygen -A [-f prefix_path]\n"
" ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number]\n"
" file ...\n"
- " ssh-keygen -Q -f krl_file file ...\n"
+ " ssh-keygen -Q [-l] -f krl_file [file ...]\n"
" ssh-keygen -Y find-principals -s signature_file -f allowed_signers_file\n"
" ssh-keygen -Y check-novalidate -n namespace -s signature_file\n"
" ssh-keygen -Y sign -f key_file -n namespace file ...\n"
@@ -3439,7 +3418,7 @@ main(int argc, char **argv)
return (0);
}
if (check_krl) {
- do_check_krl(pw, argc, argv);
+ do_check_krl(pw, print_fingerprint, argc, argv);
return (0);
}
if (ca_key_path != NULL) {
@@ -3672,7 +3651,7 @@ main(int argc, char **argv)
strlcat(identity_file, ".pub", sizeof(identity_file));
if ((r = sshkey_save_public(public, identity_file, comment)) != 0) {
fatal("Unable to save public key to %s: %s",
- identity_file, strerror(errno));
+ identity_file, ssh_err(r));
}
if (!quiet) {