Hello, I am currently using the KRL functionality of OpenSSH, and have written a convenience function for getting the set of revoked keys (in whatever format they have been stored) in the KRL. The patch, with the openssh-portable commit ID b109ce92aae0ca0376dce9513d953be60e449ae1 as the reference, is inline because I'm not sure if the list server accepts x-patch MIME type (so apologies for the long email). I would be happy to modify this if there are standards that I have failed to follow. This is my first time contributing to a OpenBSD project, so things may not be completely up to scratch on my end. I would also be happy to answer any questions about this. Thanks, Doug diff --git a/krl.c b/krl.c index e271a193..9fa03e68 100644 --- a/krl.c +++ b/krl.c @@ -28,6 +28,7 @@ #include <string.h> #include <time.h> #include <unistd.h> +#include <inttypes.h> #include "sshbuf.h" #include "ssherr.h" @@ -37,6 +38,7 @@ #include "log.h" #include "digest.h" #include "bitmap.h" +#include "uuencode.h" #include "krl.h" @@ -185,6 +187,50 @@ ssh_krl_free(struct ssh_krl *krl) } void +ssh_krl_dump(struct ssh_krl *krl) +{ + struct revoked_certs *rc, *trc; + struct revoked_key_id *rki, *tki; + struct revoked_serial *rs, *trs; + struct revoked_blob *rb, *trb; + struct sshbuf *sect; + int retval; + + if (krl == NULL) + return; + + TAILQ_FOREACH_SAFE(rc, &krl->revoked_certs, entry, trc) { + RB_FOREACH_SAFE(rki, revoked_key_id_tree, &rc->revoked_key_ids, tki) { + KRL_DBG(("%s: Key ID %s", __func__, rki->key_id)); + printf("Key ID: %s\n", rki->key_id); + } + RB_FOREACH_SAFE(rs, revoked_serial_tree, &rc->revoked_serials, trs) { + KRL_DBG(("%s: serial range %zu-%zu\n", __func__, rs->lo, rs->hi)); + if(rs->lo == rs->hi) { + printf("Serial Number: %zu\n", rs->lo); + } + else { + printf("Serial Range: %zu-%zu\n", rs->lo, rs->hi); + } + } + } + if ((sect = sshbuf_new()) == NULL) + fatal("Error allocating buffer"); + RB_FOREACH_SAFE(rb, revoked_blob_tree, &krl->revoked_sha1s, trb) { + retval = 0; + /* binary -> base64 will always be less than twice the size of the binary repr */ + retval = uuencode(rb->blob, rb->len, sshbuf_mutable_ptr(sect), 2 * rb->len); + if (retval == -1) { + fatal("Error encoding SHA1 blob"); + } + KRL_DBG(("%s: SHA1 %s\n", __func__, rb->blob)); + printf("SHA1 Digest: %s\n", sshbuf_ptr(sect)); + sshbuf_reset(sect); + } + sshbuf_free(sect); +} + +void ssh_krl_set_version(struct ssh_krl *krl, u_int64_t version) { krl->krl_version = version; diff --git a/krl.h b/krl.h index 675496cc..bf5b7e3f 100644 --- a/krl.h +++ b/krl.h @@ -59,6 +59,7 @@ int ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp, const struct sshkey **sign_ca_keys, size_t nsign_ca_keys); int ssh_krl_check_key(struct ssh_krl *krl, const struct sshkey *key); int ssh_krl_file_contains_key(const char *path, const struct sshkey *key); +void ssh_krl_dump(struct ssh_krl *krl); #endif /* _KRL_H */ diff --git a/ssh-keygen.1 b/ssh-keygen.1 index ce2213c7..17c873d5 100644 --- a/ssh-keygen.1 +++ b/ssh-keygen.1 @@ -134,7 +134,7 @@ .Nm ssh-keygen .Fl Q .Fl f Ar krl_file -.Ar +.Op Ar .Ek .Sh DESCRIPTION .Nm @@ -494,7 +494,7 @@ The program will prompt for the file containing the private key, for the old passphrase, and twice for the new passphrase. .It Fl Q -Test whether keys have been revoked in a KRL. +Test whether keys have been revoked, or display all revoked keys stored, in a KRL. .It Fl q Silence .Nm ssh-keygen . @@ -793,6 +793,8 @@ then .Nm will exit with a non-zero exit status. A zero exit status will only be returned if no key was revoked. +If no keys are provided, then all revoked keys stored in the KRL are printed. +The format of the output depends on how each of the revoked keys were stored. .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.ssh/identity diff --git a/ssh-keygen.c b/ssh-keygen.c index 2a7939bf..233f7025 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -2199,6 +2199,9 @@ do_check_krl(struct passwd *pw, int argc, char **argv) sshkey_free(k); free(comment); } + if (argc == 0) { + ssh_krl_dump(krl); + } ssh_krl_free(krl); exit(ret); }