/* -*-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
*
/*----- 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.
*
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))
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);
/* -*-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
*
/*----- 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.
*
/*----- Header files ------------------------------------------------------*/
+#include <mLib/macros.h>
#include "key.h"
/*----- Error reporting ---------------------------------------------------*/
"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]);
}
/* -*-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
*
/*----- 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.
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 -------------------------------------------------*/
/* -*-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
*
/*----- 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.
*
# include "key-data.h"
#endif
+#ifndef CATACOMB_GHASH_H
+# include "ghash.h"
+#endif
+
#ifndef CATACOMB_MP_H
# include "mp.h"
#endif
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 */
};
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@ --- *
/* -*-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
*
/*----- 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
*
/* --- @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) {
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;
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]);
key_iter i;
key *k;
for (key_mkiter(&i, &f); (k = key_next(&i)) != 0; )
- fingerprint(k, &kf);
+ fingerprint(k, ch, &kf);
}
return (rc);
}
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...]", "\