upstream: give ssh-keygen the ability to dump the contents of a

binary key revocation list: ssh-keygen -lQf /path bz#3132; ok dtucker

OpenBSD-Commit-ID: b76afc4e3b74ab735dbde4e5f0cfa1f02356033b
This commit is contained in:
djm@openbsd.org 2020-04-03 02:26:56 +00:00 committed by Damien Miller
parent af628b8a6c
commit 6ec7457171
4 changed files with 107 additions and 8 deletions

94
krl.c
View File

@ -14,7 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $OpenBSD: krl.c,v 1.47 2020/01/25 23:02:13 djm Exp $ */ /* $OpenBSD: krl.c,v 1.48 2020/04/03 02:26:56 djm Exp $ */
#include "includes.h" #include "includes.h"
@ -38,6 +38,7 @@
#include "log.h" #include "log.h"
#include "digest.h" #include "digest.h"
#include "bitmap.h" #include "bitmap.h"
#include "utf8.h"
#include "krl.h" #include "krl.h"
@ -1355,3 +1356,94 @@ ssh_krl_file_contains_key(const char *path, const struct sshkey *key)
errno = oerrno; errno = oerrno;
return r; return r;
} }
int
krl_dump(struct ssh_krl *krl, FILE *f)
{
struct sshkey *key = NULL;
struct revoked_blob *rb;
struct revoked_certs *rc;
struct revoked_serial *rs;
struct revoked_key_id *rki;
int r, ret = 0;
char *fp, timestamp[64];
/* Try to print in a KRL spec-compatible format */
format_timestamp(krl->generated_date, timestamp, sizeof(timestamp));
fprintf(f, "# KRL version %lld\n", krl->krl_version);
fprintf(f, "# Generated at %s\n", timestamp);
if (krl->comment != NULL && *krl->comment != '\0') {
r = INT_MAX;
asmprintf(&fp, INT_MAX, &r, "%s", krl->comment);
fprintf(f, "# Comment: %s\n", fp);
free(fp);
}
fputc('\n', f);
RB_FOREACH(rb, revoked_blob_tree, &krl->revoked_keys) {
if ((r = sshkey_from_blob(rb->blob, rb->len, &key)) != 0) {
ret = SSH_ERR_INVALID_FORMAT;
error("Parse key in KRL: %s", ssh_err(r));
continue;
}
if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT,
SSH_FP_DEFAULT)) == NULL) {
ret = SSH_ERR_INVALID_FORMAT;
error("sshkey_fingerprint failed");
continue;
}
fprintf(f, "hash: SHA256:%s # %s\n", fp, sshkey_ssh_name(key));
free(fp);
free(key);
}
RB_FOREACH(rb, revoked_blob_tree, &krl->revoked_sha256s) {
fp = tohex(rb->blob, rb->len);
fprintf(f, "hash: SHA256:%s\n", fp);
free(fp);
}
RB_FOREACH(rb, revoked_blob_tree, &krl->revoked_sha1s) {
/*
* There is not KRL spec keyword for raw SHA1 hashes, so
* print them as comments.
*/
fp = tohex(rb->blob, rb->len);
fprintf(f, "# hash SHA1:%s\n", fp);
free(fp);
}
TAILQ_FOREACH(rc, &krl->revoked_certs, entry) {
fputc('\n', f);
if (rc->ca_key == NULL)
fprintf(f, "# Wildcard CA\n");
else {
if ((fp = sshkey_fingerprint(rc->ca_key,
SSH_FP_HASH_DEFAULT, SSH_FP_DEFAULT)) == NULL) {
ret = SSH_ERR_INVALID_FORMAT;
error("sshkey_fingerprint failed");
continue;
}
fprintf(f, "# CA key %s %s\n",
sshkey_ssh_name(rc->ca_key), fp);
free(fp);
}
RB_FOREACH(rs, revoked_serial_tree, &rc->revoked_serials) {
if (rs->lo == rs->hi)
fprintf(f, "serial: %lld\n", rs->lo);
else {
fprintf(f, "serial: %lld-%lld\n",
rs->lo, rs->hi);
}
}
RB_FOREACH(rki, revoked_key_id_tree, &rc->revoked_key_ids) {
/*
* We don't want key IDs with embedded newlines to
* mess up the display.
*/
r = INT_MAX;
asmprintf(&fp, INT_MAX, &r, "%s", rki->key_id);
fprintf(f, "id: %s\n", fp);
free(fp);
}
}
return ret;
}

3
krl.h
View File

@ -14,7 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $OpenBSD: krl.h,v 1.7 2019/06/21 04:21:04 djm Exp $ */ /* $OpenBSD: krl.h,v 1.8 2020/04/03 02:26:56 djm Exp $ */
#ifndef _KRL_H #ifndef _KRL_H
#define _KRL_H #define _KRL_H
@ -61,6 +61,7 @@ int ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp,
const struct sshkey **sign_ca_keys, size_t nsign_ca_keys); 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_check_key(struct ssh_krl *krl, const struct sshkey *key);
int ssh_krl_file_contains_key(const char *path, const struct sshkey *key); int ssh_krl_file_contains_key(const char *path, const struct sshkey *key);
int krl_dump(struct ssh_krl *krl, FILE *f);
#endif /* _KRL_H */ #endif /* _KRL_H */

View File

@ -1,4 +1,4 @@
.\" $OpenBSD: ssh-keygen.1,v 1.202 2020/02/24 04:27:58 dtucker Exp $ .\" $OpenBSD: ssh-keygen.1,v 1.203 2020/04/03 02:26:56 djm Exp $
.\" .\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi> .\" Author: Tatu Ylonen <ylo@cs.hut.fi>
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland .\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -35,7 +35,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.Dd $Mdocdate: February 24 2020 $ .Dd $Mdocdate: April 3 2020 $
.Dt SSH-KEYGEN 1 .Dt SSH-KEYGEN 1
.Os .Os
.Sh NAME .Sh NAME
@ -135,6 +135,7 @@
.Ar .Ar
.Nm ssh-keygen .Nm ssh-keygen
.Fl Q .Fl Q
.Op Fl l
.Fl f Ar krl_file .Fl f Ar krl_file
.Ar .Ar
.Nm ssh-keygen .Nm ssh-keygen
@ -521,6 +522,9 @@ containing the private key, for the old passphrase, and twice for the
new passphrase. new passphrase.
.It Fl Q .It Fl Q
Test whether keys have been revoked in a KRL. Test whether keys have been revoked in a KRL.
If the
.Fl l
option is also specified then the contents of the KRL will be printed.
.It Fl q .It Fl q
Silence Silence
.Nm ssh-keygen . .Nm ssh-keygen .

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-keygen.c,v 1.404 2020/03/13 03:17:07 djm Exp $ */ /* $OpenBSD: ssh-keygen.c,v 1.405 2020/04/03 02:26:56 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -2439,7 +2439,7 @@ do_gen_krl(struct passwd *pw, int updating, const char *ca_key_path,
} }
static void 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; int i, r, ret = 0;
char *comment; char *comment;
@ -2449,6 +2449,8 @@ do_check_krl(struct passwd *pw, int argc, char **argv)
if (*identity_file == '\0') if (*identity_file == '\0')
fatal("KRL checking requires an input file"); fatal("KRL checking requires an input file");
load_krl(identity_file, &krl); load_krl(identity_file, &krl);
if (print_krl)
krl_dump(krl, stdout);
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
if ((r = sshkey_load_public(argv[i], &k, &comment)) != 0) if ((r = sshkey_load_public(argv[i], &k, &comment)) != 0)
fatal("Cannot load public key %s: %s", fatal("Cannot load public key %s: %s",
@ -3086,7 +3088,7 @@ usage(void)
" ssh-keygen -A [-f prefix_path]\n" " ssh-keygen -A [-f prefix_path]\n"
" ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number]\n" " ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number]\n"
" file ...\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 find-principals -s signature_file -f allowed_signers_file\n"
" ssh-keygen -Y check-novalidate -n namespace -s signature_file\n" " ssh-keygen -Y check-novalidate -n namespace -s signature_file\n"
" ssh-keygen -Y sign -f key_file -n namespace file ...\n" " ssh-keygen -Y sign -f key_file -n namespace file ...\n"
@ -3441,7 +3443,7 @@ main(int argc, char **argv)
return (0); return (0);
} }
if (check_krl) { if (check_krl) {
do_check_krl(pw, argc, argv); do_check_krl(pw, print_fingerprint, argc, argv);
return (0); return (0);
} }
if (ca_key_path != NULL) { if (ca_key_path != NULL) {