General utilities cleanup. Add signature support to catcrypt. Throw in
[u/mdw/catacomb] / key-misc.c
index 2d9c855..37027c0 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: key-misc.c,v 1.1 1999/12/22 15:47:48 mdw Exp $
+ * $Id: key-misc.c,v 1.5 2004/04/08 01:36:15 mdw Exp $
  *
  * Simple key management
  *
  * MA 02111-1307, USA.
  */
 
-/*----- Revision history --------------------------------------------------* 
- *
- * $Log: key-misc.c,v $
- * Revision 1.1  1999/12/22 15:47:48  mdw
- * Major key-management revision.
- *
- */
-
 /*----- Header files ------------------------------------------------------*/
 
 #include <stdio.h>
@@ -42,7 +34,6 @@
 #include <string.h>
 #include <time.h>
 
-#include <mLib/alloc.h>
 #include <mLib/bits.h>
 #include <mLib/hash.h>
 #include <mLib/sub.h>
 
 #define KEY_LOAD(n) ((n) * 2)
 
-/*----- Error reporting ---------------------------------------------------*/
-
-/* --- @key_strerror@ --- *
- *
- * Arguments:  @int err@ = error code from @key_new@
- *
- * Returns:    Pointer to error string.
- *
- * Use:                Translates a @KERR@ error code into a human-readable
- *             string.
- */
-
-const char *key_strerror(int err)
-{
-  char *tab[] = {
-    "No error",
-    "Bad tag string",
-    "Bad type string",
-    "Bad comment string",
-    "Keyid already exists",
-    "Key tag already exists",
-    "Key file is read-only",
-    "Key will eventually expire",
-    "Bad key flags string",
-    "Unknown error code"
-  };
-  
-  unsigned e = -err;
-  if (e >= KERR_MAX)
-    e = KERR_MAX;
- return (tab[e]);
-}
-
 /*----- Iteration and iterators -------------------------------------------*/
 
 /* --- @key_mkiter@ --- *
@@ -205,7 +163,7 @@ key *key_bytag(key_file *f, const char *tag)
   uint32 id;
   key_ref *kr = sym_find(&f->bytag, tag, -1, 0, 0);
 
-  if (kr && !(KEY_EXPIRED(t, kr->k->exp) && KEY_EXPIRED(t, kr->k->exp)))
+  if (kr && !(KEY_EXPIRED(t, kr->k->exp) && KEY_EXPIRED(t, kr->k->del)))
     return (kr->k);
   id = strtoul(tag, &p, 16);
   if (!*p)
@@ -325,6 +283,19 @@ int key_delete(key_file *f, key *k)
   return (0);
 }
 
+/* --- @key_expired@ --- *
+ *
+ * Arguments:  @key *k@ = pointer to key block
+ *
+ * Returns:    Zero if the key is OK, nonzero if it's expired.
+ */
+
+int key_expired(key *k)
+{
+  time_t now = time(0);
+  return (KEY_EXPIRED(now, k->exp) || KEY_EXPIRED(now, k->del));
+}
+
 /* --- @key_expire@ --- *
  *
  * Arguments:  @key_file *f@ = pointer to file block
@@ -379,4 +350,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 -------------------------------------------------*/