From 981bf1273304e1bc6604ea22b6ab4bd9ae07974b Mon Sep 17 00:00:00 2001 From: mdw Date: Thu, 8 Apr 2004 01:02:49 +0000 Subject: [PATCH] key-binary.c --- key-attr.c | 9 +++++++-- key-error.c | 11 ++++++++--- key-misc.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- key.h | 24 +++++++++++++++++++++++- keyutil.c | 50 +++++++++++++++++++++++++++++--------------------- 5 files changed, 122 insertions(+), 28 deletions(-) diff --git a/key-attr.c b/key-attr.c index d4f2e05..75b2f1e 100644 --- a/key-attr.c +++ b/key-attr.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: key-attr.c,v 1.3 2001/06/22 19:39:43 mdw Exp $ + * $Id: key-attr.c,v 1.4 2004/04/08 01:02:49 mdw Exp $ * * Key attribute manipulation * @@ -30,6 +30,9 @@ /*----- Revision history --------------------------------------------------* * * $Log: key-attr.c,v $ + * Revision 1.4 2004/04/08 01:02:49 mdw + * key-binary.c + * * Revision 1.3 2001/06/22 19:39:43 mdw * Allow tagging if the tag is owned by a deleted key. * @@ -67,7 +70,7 @@ int key_chkident(const char *p) { - if (!p || !*p) + if (!p || !*p || strlen(p) > 255) return (-1); while (*p) { if (*p == ':' || *p == '.' || isspace((unsigned char)*p)) @@ -176,6 +179,8 @@ int key_putattr(key_file *f, key *k, const char *n, const char *v) if (!(f->f & KF_WRITE)) return (KERR_READONLY); + if (strlen(n) > 255) + return (KERR_BADATTR); if (v) { a = sym_find(&k->a, n, -1, sizeof(*a), &found); diff --git a/key-error.c b/key-error.c index 7b72d44..400e6bf 100644 --- a/key-error.c +++ b/key-error.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: key-error.c,v 1.2 2000/02/12 18:55:40 mdw Exp $ + * $Id: key-error.c,v 1.3 2004/04/08 01:02:49 mdw Exp $ * * Translating key error codes into strings * @@ -30,6 +30,9 @@ /*----- Revision history --------------------------------------------------* * * $Log: key-error.c,v $ + * Revision 1.3 2004/04/08 01:02:49 mdw + * key-binary.c + * * Revision 1.2 2000/02/12 18:55:40 mdw * Make it all compile properly. * @@ -40,6 +43,7 @@ /*----- Header files ------------------------------------------------------*/ +#include #include "key.h" /*----- Error reporting ---------------------------------------------------*/ @@ -70,12 +74,13 @@ const char *key_strerror(int err) "Failed to unlock encrypted key", "Unexpected key encoding type", "Key not found", + "Bad attribute name", "Unknown error code" }; unsigned e = -err; - if (e >= KERR_MAX) - e = KERR_MAX; + if (e >= N(tab)) + e = N(tab); return (tab[e]); } diff --git a/key-misc.c b/key-misc.c index afd0a4b..a502293 100644 --- a/key-misc.c +++ b/key-misc.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: key-misc.c,v 1.3 2001/06/22 19:39:12 mdw Exp $ + * $Id: key-misc.c,v 1.4 2004/04/08 01:02:49 mdw Exp $ * * Simple key management * @@ -30,6 +30,9 @@ /*----- Revision history --------------------------------------------------* * * $Log: key-misc.c,v $ + * Revision 1.4 2004/04/08 01:02:49 mdw + * key-binary.c + * * Revision 1.3 2001/06/22 19:39:12 mdw * New interface to find out whether a key has expired. Also, a bug fix * to @key_bytag@ so that it finds expired keys correctly. @@ -365,4 +368,55 @@ int key_used(key_file *f, key *k, time_t t) return (0); } +/* --- @key_fingerprint@ --- * + * + * Arguments: @key *k@ = the key to fingerprint + * @ghash *h@ = the hash to use + * @const key_filter *kf@ = filter to apply + * + * Returns: Nonzero if the key slightly matched the filter. + * + * Use: Updates the hash context with the key contents. + */ + +static int abyname(const void *a, const void *b) { + key_attr *const *x = a, *const *y = b; + return (strcmp(SYM_NAME(*x), SYM_NAME(*y))); +} + +int key_fingerprint(key *k, ghash *h, const key_filter *kf) +{ + dstr d = DSTR_INIT; + int rc = 0; + key_attr *a, **v; + size_t n, i, len; + octet b[2]; + sym_iter ai; + + if (!key_encode(&k->k, &d, kf)) + goto done; + rc = 1; + GH_HASH(h, d.buf, d.len); + for (n = 0, sym_mkiter(&ai, &k->a); (a = sym_next(&ai)) != 0; n++); + if (n) { + v = xmalloc(n * sizeof(*v)); + for (i = 0, sym_mkiter(&ai, &k->a); (a = sym_next(&ai)) != 0; i++) + v[i] = a; + qsort(v, n, sizeof(*v), abyname); + len = strlen(k->type); STORE8(b, len); + GH_HASH(h, b, 1); GH_HASH(h, k->type, len); + for (i = 0; i < n; i++) { + a = v[i]; + len = strlen(SYM_NAME(a)); STORE8(b, len); + GH_HASH(h, b, 1); GH_HASH(h, SYM_NAME(a), len); + len = strlen(a->p); STORE16(b, len); + GH_HASH(h, b, 2); GH_HASH(h, a->p, len); + } + xfree(v); + } +done: + dstr_destroy(&d); + return (rc); +} + /*----- That's all, folks -------------------------------------------------*/ diff --git a/key.h b/key.h index 8629a57..05ba9a3 100644 --- a/key.h +++ b/key.h @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: key.h,v 1.9 2001/06/22 19:37:59 mdw Exp $ + * $Id: key.h,v 1.10 2004/04/08 01:02:49 mdw Exp $ * * Simple key management * @@ -30,6 +30,9 @@ /*----- Revision history --------------------------------------------------* * * $Log: key.h,v $ + * Revision 1.10 2004/04/08 01:02:49 mdw + * key-binary.c + * * Revision 1.9 2001/06/22 19:37:59 mdw * New interface to enquire whether a key has expired. * @@ -81,6 +84,10 @@ # include "key-data.h" #endif +#ifndef CATACOMB_GHASH_H +# include "ghash.h" +#endif + #ifndef CATACOMB_MP_H # include "mp.h" #endif @@ -200,6 +207,7 @@ enum { KERR_BADPASS = -10, /* Error decrypting locked key */ KERR_WRONGTYPE = -11, /* Key has incorrect type */ KERR_NOTFOUND = -12, /* Key couldn't be found */ + KERR_BADATTR = -13, /* Malformed attribute name */ KERR_MAX /* Largest possible error */ }; @@ -420,6 +428,20 @@ extern int key_expire(key_file */*f*/, key */*k*/); extern int key_used(key_file */*f*/, key */*k*/, time_t /*t*/); +/* --- @key_fingerprint@ --- * + * + * Arguments: @key *k@ = the key to fingerprint + * @ghash *h@ = the hash to use + * @const key_filter *kf@ = filter to apply + * + * Returns: Nonzero if the key slightly matched the filter. + * + * Use: Updates the hash context with the key contents. + */ + +extern int key_fingerprint(key */*k*/, ghash */*h*/, + const key_filter */*kf*/); + /*----- Setting and reading attributes ------------------------------------*/ /* --- @key_chkident@ --- * diff --git a/keyutil.c b/keyutil.c index 025c8f2..2df4368 100644 --- a/keyutil.c +++ b/keyutil.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: keyutil.c,v 1.22 2004/04/03 15:45:06 mdw Exp $ + * $Id: keyutil.c,v 1.23 2004/04/08 01:02:49 mdw Exp $ * * Simple key manager program * @@ -30,6 +30,9 @@ /*----- Revision history --------------------------------------------------* * * $Log: keyutil.c,v $ + * Revision 1.23 2004/04/08 01:02:49 mdw + * key-binary.c + * * Revision 1.22 2004/04/03 15:45:06 mdw * Oops. Fix formatting. :-S * @@ -1575,42 +1578,42 @@ static int cmd_setattr(int argc, char *argv[]) /* --- @cmd_finger@ --- */ -static void fingerprint(key *k, const key_filter *kf) +static void fingerprint(key *k, const gchash *ch, const key_filter *kf) { - rmd160_ctx r; - octet hash[RMD160_HASHSZ]; + ghash *h; dstr d = DSTR_INIT; - int i; + const octet *p; + size_t i; - if (!key_encode(&k->k, &d, kf)) - return; - rmd160_init(&r); - rmd160_hash(&r, d.buf, d.len); - rmd160_done(&r, hash); - - DRESET(&d); - key_fulltag(k, &d); - for (i = 0; i < sizeof(hash); i++) { - if (i && i % 4 == 0) - putchar('-'); - printf("%02x", hash[i]); + h = GH_INIT(ch); + if (key_fingerprint(k, h, kf)) { + p = GH_DONE(h, 0); + key_fulltag(k, &d); + for (i = 0; i < ch->hashsz; i++) { + if (i && i % 4 == 0) + putchar('-'); + printf("%02x", p[i]); + } + printf(" %s\n", d.buf); } - printf(" %s\n", d.buf); dstr_destroy(&d); + GH_DESTROY(h); } static int cmd_finger(int argc, char *argv[]) { key_file f; int rc = 0; + const gchash *ch = &rmd160; key_filter kf = { KF_NONSECRET, KF_NONSECRET }; for (;;) { static struct option opt[] = { { "filter", OPTF_ARGREQ, 0, 'f' }, + { "algorithm", OPTF_ARGREQ, 0, 'a' }, { 0, 0, 0, 0 } }; - int i = mdwopt(argc, argv, "+f:", opt, 0, 0, 0); + int i = mdwopt(argc, argv, "+f:a:", opt, 0, 0, 0); if (i < 0) break; switch (i) { @@ -1620,6 +1623,10 @@ static int cmd_finger(int argc, char *argv[]) if (err || *p) die(EXIT_FAILURE, "bad filter string `%s'", optarg); } break; + case 'a': + if ((ch = ghash_byname(optarg)) == 0) + die(EXIT_FAILURE, "unknown hash algorithm `%s'", optarg); + break; default: rc = 1; break; @@ -1637,7 +1644,7 @@ static int cmd_finger(int argc, char *argv[]) for (i = 0; i < argc; i++) { key *k = key_bytag(&f, argv[i]); if (k) - fingerprint(k, &kf); + fingerprint(k, ch, &kf); else { rc = 1; moan("key `%s' not found", argv[i]); @@ -1647,7 +1654,7 @@ static int cmd_finger(int argc, char *argv[]) key_iter i; key *k; for (key_mkiter(&i, &f); (k = key_next(&i)) != 0; ) - fingerprint(k, &kf); + fingerprint(k, ch, &kf); } return (rc); } @@ -1911,6 +1918,7 @@ Options:\n\ Options:\n\ \n\ -f, --filter=FILT Only hash key components matching FILT.\n\ +-a, --algorithm=HASH Use the named HASH algorithm.\n\ " }, { "tidy", cmd_tidy, "tidy" }, { "extract", cmd_extract, "extract [-f filter] file [tag...]", "\ -- 2.11.0