cc.h: Fix FHF_MASK.
[u/mdw/catacomb] / key-misc.c
index 2d9c855..5ff7078 100644 (file)
@@ -1,13 +1,13 @@
 /* -*-c-*-
  *
- * $Id: key-misc.c,v 1.1 1999/12/22 15:47:48 mdw Exp $
+ * $Id$
  *
  * Simple key management
  *
  * (c) 1999 Straylight/Edgeware
  */
 
-/*----- Licensing notice --------------------------------------------------* 
+/*----- Licensing notice --------------------------------------------------*
  *
  * This file is part of Catacomb.
  *
  * it under the terms of the GNU Library General Public License as
  * published by the Free Software Foundation; either version 2 of the
  * License, or (at your option) any later version.
- * 
+ *
  * Catacomb is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU Library General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Library General Public
  * License along with Catacomb; if not, write to the Free
  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  * 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)
@@ -219,7 +177,7 @@ key *key_bytag(key_file *f, const char *tag)
  *             @const char *tag@ = pointer to tag string
  *             @dstr *d@ = pointer to string for full tag name
  *             @key **k@ = where to store the key pointer
- *             @key_data **kd@ = where to store the key data pointer
+ *             @key_data ***kd@ = where to store the key data pointer
  *
  * Returns:    Zero if OK, nonzero if it failed.
  *
@@ -227,15 +185,15 @@ key *key_bytag(key_file *f, const char *tag)
  *             qualified by the names of subkeys, separated by dots.  Hence,
  *             a qualified tag is ID|TAG[.TAG...].  The various result
  *             pointers can be null to indicate that the result isn't
- *             interesting. 
+ *             interesting.
  */
 
-int key_qtag(key_file *f, const char *tag, dstr *d, key **k, key_data **kd)
+int key_qtag(key_file *f, const char *tag, dstr *d, key **k, key_data ***kd)
 {
   dstr dd = DSTR_INIT;
   const char *q;
   key *kk;
-  key_data *kkd;
+  key_data **kkd;
 
   /* --- Find the end of the base tag --- */
 
@@ -264,36 +222,42 @@ int key_qtag(key_file *f, const char *tag, dstr *d, key **k, key_data **kd)
 
   /* --- Now dig through the rest of the tag --- */
 
-  while (q && *q) {
-
-    /* --- Stick on the next bit of the fullqtag --- */
-
-    DRESET(&dd);
-    while (*q && *q != '.') {
-      DPUTC(&dd, *q);
-      q++;
-    }
-    DPUTZ(&dd);
-    if (d) {
-      DPUTC(d, '.');
-      DPUTD(d, &dd);
-    }
-
-    /* --- Look up the subkey --- */
-
-    if (kkd->e != KENC_STRUCT) {
-      kkd = 0;
-      break;
+  if (q) {
+    while (*q) {
+      key_struct *ks;
+
+      /* --- Stick on the next bit of the fullqtag --- */
+
+      DRESET(&dd);
+      while (*q && *q != '.') {
+       DPUTC(&dd, *q);
+       q++;
+      }
+      DPUTZ(&dd);
+      if (d) {
+       DPUTC(d, '.');
+       DPUTD(d, &dd);
+      }
+
+      /* --- Look up the subkey --- */
+
+      if ((*kkd)->e != KENC_STRUCT) {
+       kkd = 0;
+       break;
+      }
+      if ((ks = sym_find(&(*kkd)->u.s, dd.buf, -1, 0, 0)) == 0) {
+       kkd = 0;
+       break;
+      }
+      kkd = &ks->k;
     }
-    if ((kkd = key_structfind(kkd, dd.buf)) == 0)
-      break;
   }
 
   /* --- Return the results --- */
 
+  dstr_destroy(&dd);
   if (!kkd)
     return (-1);
-  dstr_destroy(&dd);
   if (kd)
     *kd = kkd;
   return (0);
@@ -325,6 +289,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 +356,52 @@ 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;
+  sym_iter ai;
+
+  if (!key_encode(k->k, &d, kf))
+    goto done;
+  rc = 1;
+  GH_HASHSTR(h, "catacomb-key-fingerprint:");
+  GH_HASHU32(h, k->id);
+  GH_HASHSTR8(h, k->type);
+  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);
+    for (i = 0; i < n; i++) {
+      GH_HASHSTR8(h, SYM_NAME(v[i]));
+      GH_HASHSTR16(h, v[i]->p);
+    }
+    xfree(v);
+  }
+done:
+  dstr_destroy(&d);
+  return (rc);
+}
+
 /*----- That's all, folks -------------------------------------------------*/