Hi,
This is another OpenSSH key revocation list (KRL) change: to support KRL
signing and verification in ssh-keygen(1).
The KRL format has supported signing of KRLs and verification of KRL
signatures for a long time, but there is currently no way to generate a
signed KRL or check the signature on one. The final patch hooks this up
for ssh-keygen(1) at least.
ok?
---
ssh-keygen.c | 62 ++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 51 insertions(+), 11 deletions(-)
diff --git a/ssh-keygen.c b/ssh-keygen.c
index 869b675..29b8aec 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -2179,7 +2179,8 @@ do_show_cert(struct passwd *pw)
}
static void
-load_krl(const char *path, struct ssh_krl **krlp)
+load_krl(const char *path, struct ssh_krl **krlp,
+ struct sshkey **trusted_keys, size_t ntrusted_keys)
{
struct sshbuf *krlbuf;
int r;
@@ -2187,7 +2188,8 @@ load_krl(const char *path, struct ssh_krl **krlp)
if ((r = sshbuf_load_file(path, &krlbuf)) != 0)
fatal_r(r, "Unable to load KRL %s", path);
/* XXX check sigs */
- if ((r = ssh_krl_from_blob(krlbuf, krlp, NULL, 0)) != 0 ||
+ if ((r = ssh_krl_from_blob(krlbuf, krlp,
+ trusted_keys, ntrusted_keys)) != 0 ||
*krlp == NULL)
fatal_r(r, "Invalid KRL file %s", path);
sshbuf_free(krlbuf);
@@ -2378,20 +2380,54 @@ update_krl_from_file(struct passwd *pw, const char
*file, int wild_ca,
free(path);
}
+static void
+krl_process_opts(struct passwd *pw, char * const *opts, size_t nopts,
+ struct sshkey ***sig_keys, size_t *nsig_keys)
+{
+ struct sshkey *key;
+ char *path;
+ size_t i;
+
+ for (i = 0; i < nopts; i++) {
+ if (strncasecmp(opts[i], "signing-key=", 12) == 0) {
+ path = tilde_expand_filename(opts[i] + 12, pw->pw_uid);
+ key = load_identity(path, NULL);
+ free(path);
+ *sig_keys = xrecallocarray(*sig_keys, *nsig_keys,
+ *nsig_keys + 1, sizeof(*sig_keys));
+ (*sig_keys)[(*nsig_keys)++] = key;
+ } else
+ fatal("Invalid option \"%s\"", opts[i]);
+ }
+}
+
+static void
+free_sig_keys(struct sshkey **sig_keys, size_t nsig_keys)
+{
+ size_t i;
+
+ for (i = 0; i < nsig_keys; i++)
+ sshkey_free(sig_keys[i]);
+ free(sig_keys);
+}
+
static void
do_gen_krl(struct passwd *pw, int updating, const char *ca_key_path,
unsigned long long krl_version, const char *krl_comment,
+ char * const *opts, size_t nopts,
int argc, char **argv)
{
struct ssh_krl *krl;
struct stat sb;
- struct sshkey *ca = NULL;
+ struct sshkey *ca = NULL, **sig_keys = NULL;
int i, r, wild_ca = 0;
+ size_t nsig_keys = 0;
char *tmp;
struct sshbuf *kbuf;
if (*identity_file == '\0')
fatal("KRL generation requires an output file");
+ krl_process_opts(pw, opts, nopts, &sig_keys, &nsig_keys);
if (stat(identity_file, &sb) == -1) {
if (errno != ENOENT)
fatal("Cannot access KRL \"%s\": %s",
@@ -2411,7 +2447,7 @@ do_gen_krl(struct passwd *pw, int updating, const char
*ca_key_path,
}
if (updating)
- load_krl(identity_file, &krl);
+ load_krl(identity_file, &krl, NULL, 0);
else if ((krl = ssh_krl_init()) == NULL)
fatal("couldn't create KRL");
@@ -2425,26 +2461,30 @@ do_gen_krl(struct passwd *pw, int updating, const char
*ca_key_path,
if ((kbuf = sshbuf_new()) == NULL)
fatal("sshbuf_new failed");
- if (ssh_krl_to_blob(krl, kbuf, NULL, 0) != 0)
+ if (ssh_krl_to_blob(krl, kbuf, sig_keys, nsig_keys) != 0)
fatal("Couldn't generate KRL");
if ((r = sshbuf_write_file(identity_file, kbuf)) != 0)
fatal("write %s: %s", identity_file, strerror(errno));
sshbuf_free(kbuf);
ssh_krl_free(krl);
sshkey_free(ca);
+ free_sig_keys(sig_keys, nsig_keys);
}
static void
-do_check_krl(struct passwd *pw, int print_krl, int argc, char **argv)
+do_check_krl(struct passwd *pw, int print_krl,
+ char * const *opts, size_t nopts, int argc, char **argv)
{
int i, r, ret = 0;
char *comment;
struct ssh_krl *krl;
- struct sshkey *k;
+ struct sshkey *k = NULL, **sig_keys = NULL;
+ size_t nsig_keys = 0;
if (*identity_file == '\0')
fatal("KRL checking requires an input file");
- load_krl(identity_file, &krl);
+ krl_process_opts(pw, opts, nopts, &sig_keys, &nsig_keys);
+ load_krl(identity_file, &krl, sig_keys, nsig_keys);
if (print_krl)
krl_dump(krl, stdout);
for (i = 0; i < argc; i++) {
@@ -2460,6 +2500,7 @@ do_check_krl(struct passwd *pw, int print_krl, int argc,
char **argv)
free(comment);
}
ssh_krl_free(krl);
+ free_sig_keys(sig_keys, nsig_keys);
exit(ret);
}
@@ -2660,7 +2701,6 @@ sig_process_opts(char * const *opts, size_t nopts, char
**hashalgp,
return 0;
}
-
static int
sig_sign(const char *keypath, const char *sig_namespace, int require_agent,
int argc, char **argv, char * const *opts, size_t nopts)
@@ -3643,11 +3683,11 @@ main(int argc, char **argv)
}
if (gen_krl) {
do_gen_krl(pw, update_krl, ca_key_path,
- cert_serial, identity_comment, argc, argv);
+ cert_serial, identity_comment, opts, nopts, argc, argv);
return (0);
}
if (check_krl) {
- do_check_krl(pw, print_fingerprint, argc, argv);
+ do_check_krl(pw, print_fingerprint, opts, nopts, argc, argv);
return (0);
}
if (ca_key_path != NULL) {
--
2.39.0