chiark / gitweb /
New peer option `-mobile': follow rapid IP address and port changes.
[tripe] / server / keymgmt.c
index edd31b2a443b7bc52e59637190390550e479a2de..ae456c37ed7d72d5f0dac43d7c1a02de90ce3ccd 100644 (file)
@@ -1,13 +1,11 @@
 /* -*-c-*-
- *
- * $Id$
  *
  * Key loading and storing
  *
  * (c) 2001 Straylight/Edgeware
  */
 
-/*----- Licensing notice --------------------------------------------------* 
+/*----- Licensing notice --------------------------------------------------*
  *
  * This file is part of Trivial IP Encryption (TrIPE).
  *
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * TrIPE 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 General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with TrIPE; if not, write to the Free Software Foundation,
  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
@@ -100,7 +98,7 @@ done:
   return (e);
 }
 
-static const kgops kgdh_ops = { "tripe-dh", kgdh_priv, kgdh_pub };
+static const kgops kgdh_ops = { "dh", kgdh_priv, kgdh_pub };
 
 /* --- Elliptic curve --- */
 
@@ -156,7 +154,7 @@ done:
   return (e);
 }
 
-static const kgops kgec_ops = { "tripe-ec", kgec_priv, kgec_pub };
+static const kgops kgec_ops = { "ec", kgec_priv, kgec_pub };
 
 /* --- Table of supported key types --- */
 
@@ -249,7 +247,8 @@ static const char *algs_check(algswitch *a, const group *g)
   /* --- Derive the key sizes --- *
    *
    * Must ensure that we have non-empty keys.  This isn't ideal, but it
-   * provides a handy sanity check.
+   * provides a handy sanity check.  Also must be based on a 64- or 128-bit
+   * block cipher or we can't do the data expiry properly.
    */
 
   a->hashsz = a->h->hashsz;
@@ -258,6 +257,11 @@ static const char *algs_check(algswitch *a, const group *g)
   if ((a->mksz = keysz(a->hashsz, a->m->keysz)) == 0)
     return ("no key size found for MAC");
 
+  /* --- Derive the data limit --- */
+
+  if (a->c->blksz < 16) a->expsz = MEG(64);
+  else a->expsz = MEG(2048);
+
   /* --- Ensure that the tag size is sane --- */
 
   if (a->tagsz > a->m->hashsz) return ("tag length too large");
@@ -293,13 +297,13 @@ static int algs_samep(const algswitch *a, const algswitch *aa)
 /* --- @keymoan@ --- *
  *
  * Arguments:  @const char *file@ = name of the file
- *              @int line@ = line number in file
- *              @const char *msg@ = error message
- *              @void *p@ = argument pointer
+ *             @int line@ = line number in file
+ *             @const char *msg@ = error message
+ *             @void *p@ = argument pointer
  *
- * Returns:     ---
+ * Returns:    ---
  *
- * Use:         Reports an error message about loading a key file.
+ * Use:                Reports an error message about loading a key file.
  */
 
 static void keymoan(const char *file, int line, const char *msg, void *p)
@@ -311,6 +315,41 @@ static void keymoan(const char *file, int line, const char *msg, void *p)
         A_END);
 }
 
+/* --- @keykg@ --- *
+ *
+ * Arguments:  @key_file *kf@ = pointer to key file
+ *             @key *k@ = pointer to key
+ *             @const char **tyr@ = where to put the type string
+ *
+ * Returns:    Pointer to indicated key-group options, or null.
+ *
+ * Use:                Looks up a key's group indicator and tries to find a matching
+ *             table entry.
+ */
+
+static const kgops *keykg(key_file *kf, key *k, const char **tyr)
+{
+  const char *ty;
+  const kgops **ko;
+
+  /* --- Look up the key type in the table --- *
+   *
+   * There are several places to look for this.  The most obvious is the
+   * `kx-group' key attribute.  But there's also the key type itself.
+   */
+
+  ty = key_getattr(kf, k, "kx-group");
+  if (!ty && strncmp(k->type, "tripe-", 6) == 0) ty = k->type + 6;
+  if (!ty) ty = "dh";
+  if (tyr) *tyr = ty;
+
+  for (ko = kgtab; *ko; ko++) {
+    if (strcmp((*ko)->ty, ty) == 0)
+      return (*ko);
+  }
+  return (0);
+}
+
 /* --- @loadpriv@ --- *
  *
  * Arguments:  @dstr *d@ = string to write errors in
@@ -329,8 +368,8 @@ static int loadpriv(dstr *d)
   group *g = 0;
   mp *x = 0;
   int rc = -1;
-  const kgops **ko;
-  const char *e;
+  const kgops *ko;
+  const char *e, *tag, *ty;
   algswitch a;
 
   /* --- Open the private key file --- */
@@ -343,25 +382,24 @@ static int loadpriv(dstr *d)
 
   /* --- Find the private key --- */
 
-  if (key_qtag(&kf, tag_priv, &t, &k, &kd)) {
-    dstr_putf(d, "private key `%s' not found in keyring `%s'",
-             tag_priv, kr_priv);
+  if (tag_priv ?
+      key_qtag(&kf, tag = tag_priv, &t, &k, &kd) :
+      key_qtag(&kf, tag = "tripe", &t, &k, &kd) &&
+       key_qtag(&kf, tag = "tripe-dh", &t, &k, &kd)) {
+    dstr_putf(d, "private key `%s' not found in keyring `%s'", tag, kr_priv);
     goto done_1;
   }
 
   /* --- Look up the key type in the table --- */
 
-  for (ko = kgtab; *ko; ko++) {
-    if (strcmp((*ko)->ty, k->type) == 0)
-      goto tymatch;
+  if ((ko = keykg(&kf, k, &ty)) == 0) {
+    dstr_putf(d, "private key `%s' has unknown type `%s'", t.buf, ty);
+    goto done_1;
   }
-  dstr_putf(d, "private key `%s' has unknown type `%s'", t.buf, k->type);
-  goto done_1;
-tymatch:;
 
   /* --- Load the key --- */
 
-  if ((e = (*ko)->loadpriv(*kd, &g, &x, &t)) != 0) {
+  if ((e = ko->loadpriv(*kd, &g, &x, &t)) != 0) {
     dstr_putf(d, "error reading private key `%s': %s", t.buf, e);
     goto done_1;
   }
@@ -384,7 +422,7 @@ tymatch:;
 
   /* --- Good, we're happy --- *
    *
-   * Dodginess!  We change the group over here, but don't free any old group
+   * Dodginess!         We change the group over here, but don't free any old group
    * elements.  This assumes that the new group is basically the same as the
    * old one, and will happily adopt the existing elements.  If it isn't,
    * then we lose badly.  Check this, then.
@@ -562,8 +600,8 @@ int km_getpubkey(const char *tag, ge *kpub, time_t *t_exp)
   key *k;
   key_data **kd;
   dstr t = DSTR_INIT;
-  const kgops **ko;
-  const char *e;
+  const kgops *ko;
+  const char *e, *ty;
   group *g = 0;
   ge *p = 0;
   algswitch a;
@@ -578,27 +616,24 @@ int km_getpubkey(const char *tag, ge *kpub, time_t *t_exp)
 
   /* --- Look up the key type in the table --- */
 
-  for (ko = kgtab; *ko; ko++) {
-    if (strcmp((*ko)->ty, k->type) == 0)
-      goto tymatch;
+  if ((ko = keykg(kf_pub, k, &ty)) == 0) {
+    a_warn("KEYMGMT",
+          "public-key", "%s", t.buf,
+          "unknown-type", "%s", ty,
+          A_END);
+    goto done;
   }
-  a_warn("KEYMGMT",
-        "public-key", "%s", t.buf,
-        "unknown-type", "%s", k->type,
-        A_END);
-  goto done;
-tymatch:;
 
   /* --- Load the key --- */
 
-  if ((e = (*ko)->loadpub(*kd, &g, &p, &t)) != 0) {
+  if ((e = ko->loadpub(*kd, &g, &p, &t)) != 0) {
     a_warn("KEYMGMT", "public-key", "%s", t.buf, "bad", "%s", e, A_END);
     goto done;
   }
 
   /* --- Ensure that the group is correct --- *
    *
-   * Dodginess!  We assume that if this works, our global group is willing to
+   * Dodginess!         We assume that if this works, our global group is willing to
    * adopt this public element.  Probably reasonable.
    */