chiark / gitweb /
server/: Prepare an interface for multiple bulk-crypto transforms.
[tripe] / server / keymgmt.c
index 6835968db0bffd0a59cdc33ea048250877b2496b..d28421fe977e555e3bff1d62b2f1752ad807c050 100644 (file)
@@ -178,18 +178,11 @@ static const kgops *kgtab[] = {
 static int algs_get(algswitch *a, dstr *e, key_file *kf, key *k)
 {
   const char *p;
+  const bulkcrypto *bulk;
   char *q, *qq;
   dstr d = DSTR_INIT;
   int rc = -1;
 
-  /* --- Symmetric encryption for bulk data --- */
-
-  if ((p = key_getattr(kf, k, "cipher")) == 0) p = "blowfish-cbc";
-  if ((a->c = gcipher_byname(p)) == 0) {
-    a_format(e, "unknown-cipher", "%s", p, A_END);
-    goto done;
-  }
-
   /* --- Hash function --- */
 
   if ((p = key_getattr(kf, k, "hash")) == 0) p = "rmd160";
@@ -210,41 +203,70 @@ static int algs_get(algswitch *a, dstr *e, key_file *kf, key *k)
     goto done;
   }
 
-  /* --- Message authentication for bulk data --- */
+  /* --- Bulk crypto transform --- */
 
-  if ((p = key_getattr(kf, k, "mac")) != 0) {
-    dstr_reset(&d);
-    dstr_puts(&d, p);
-    if ((q = strchr(d.buf, '/')) != 0)
-      *q++ = 0;
-    if ((a->m = gmac_byname(d.buf)) == 0) {
-      a_format(e, "unknown-mac", "%s", d.buf, A_END);
+  if ((p = key_getattr(kf, k, "bulk")) == 0) p = "v0";
+  for (bulk = bulktab; bulk->name && strcmp(p, bulk->name) != 0; bulk++);
+  if (!bulk->name) {
+    a_format(e, "unknown-bulk-transform", "%s", p, A_END);
+    goto done;
+  }
+  a->bulk = bulk;
+
+  /* --- Symmetric encryption for bulk data --- */
+
+  if (!(a->bulk->prim & BCP_CIPHER))
+    a->c = 0;
+  else {
+    if ((p = key_getattr(kf, k, "cipher")) == 0) p = "blowfish-cbc";
+    if ((a->c = gcipher_byname(p)) == 0) {
+      a_format(e, "unknown-cipher", "%s", p, A_END);
       goto done;
     }
-    if (!q)
-      a->tagsz = a->m->hashsz;
-    else {
-      unsigned long n = strtoul(q, &qq, 0);
-      if (*qq)  {
-       a_format(e, "bad-tag-length-string", "%s", q, A_END);
+  }
+
+  /* --- Message authentication for bulk data --- */
+
+  if (!(a->bulk->prim & BCP_MAC)) {
+    a->m = 0;
+    a->tagsz = 0;
+  } else {
+    if ((p = key_getattr(kf, k, "mac")) != 0) {
+      dstr_reset(&d);
+      dstr_puts(&d, p);
+      if ((q = strchr(d.buf, '/')) != 0)
+       *q++ = 0;
+      if ((a->m = gmac_byname(d.buf)) == 0) {
+       a_format(e, "unknown-mac", "%s", d.buf, A_END);
        goto done;
       }
-      if (n%8 || n/8 > a->m->hashsz) {
-       a_format(e, "bad-tag-length", "%lu", n, A_END);
+      if (!q)
+       a->tagsz = a->m->hashsz;
+      else {
+       unsigned long n = strtoul(q, &qq, 0);
+       if (*qq)  {
+         a_format(e, "bad-tag-length-string", "%s", q, A_END);
+         goto done;
+       }
+       if (n%8 || n/8 > a->m->hashsz) {
+         a_format(e, "bad-tag-length", "%lu", n, A_END);
+         goto done;
+       }
+       a->tagsz = n/8;
+      }
+    } else {
+      dstr_reset(&d);
+      dstr_putf(&d, "%s-hmac", a->h->name);
+      if ((a->m = gmac_byname(d.buf)) == 0) {
+       a_format(e, "no-hmac-for-hash", "%s", a->h->name, A_END);
        goto done;
       }
-      a->tagsz = n/8;
+      a->tagsz = a->h->hashsz/2;
     }
-  } else {
-    dstr_reset(&d);
-    dstr_putf(&d, "%s-hmac", a->h->name);
-    if ((a->m = gmac_byname(d.buf)) == 0) {
-      a_format(e, "no-hmac-for-hash", "%s", a->h->name, A_END);
-      goto done;
-    }
-    a->tagsz = a->h->hashsz/2;
   }
 
+  /* --- All done --- */
+
   rc = 0;
 done:
   dstr_destroy(&d);
@@ -267,6 +289,10 @@ done:
 
 static int algs_check(algswitch *a, dstr *e, const group *g)
 {
+  /* --- Check the bulk crypto transform --- */
+
+  if (a->bulk->check(a, e)) return (-1);
+
   /* --- Derive the key sizes --- *
    *
    * Must ensure that we have non-empty keys.  This isn't ideal, but it
@@ -275,13 +301,13 @@ static int algs_check(algswitch *a, dstr *e, const group *g)
    */
 
   a->hashsz = a->h->hashsz;
-  if ((a->cksz = keysz(a->hashsz, a->c->keysz)) == 0) {
+  if (a->c && (a->cksz = keysz(a->hashsz, a->c->keysz)) == 0) {
     a_format(e, "cipher", "%s", a->c->name,
             "no-key-size", "%lu", (unsigned long)a->hashsz,
             A_END);
     return (-1);
   }
-  if ((a->mksz = keysz(a->hashsz, a->m->keysz)) == 0) {
+  if (a->m && (a->mksz = keysz(a->hashsz, a->m->keysz)) == 0) {
     a_format(e, "mac", "%s", a->m->name,
             "no-key-size", "%lu", (unsigned long)a->hashsz,
             A_END);
@@ -290,7 +316,7 @@ static int algs_check(algswitch *a, dstr *e, const group *g)
 
   /* --- Derive the data limit --- */
 
-  if (a->c->blksz < 16) a->expsz = MEG(64);
+  if (a->c && a->c->blksz < 16) a->expsz = MEG(64);
   else a->expsz = MEG(2048);
 
   /* --- Ensure the MGF accepts hashes as keys --- */