Release 2.1.2.
[u/mdw/catacomb] / key-pack.c
index e6f2825..8b25dac 100644 (file)
@@ -1,13 +1,13 @@
 /* -*-c-*-
  *
- * $Id: key-pack.c,v 1.1 2000/06/17 10:42:41 mdw Exp $
+ * $Id$
  *
  * Packing and unpacking key data
  *
  * (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-pack.c,v $
- * Revision 1.1  2000/06/17 10:42:41  mdw
- * Packing and unpacking structured keys.
- *
- */
-
 /*----- Header files ------------------------------------------------------*/
 
 #include <mLib/dstr.h>
@@ -47,7 +39,7 @@
 /* --- @key_pack@ --- *
  *
  * Arguments:  @key_packdef *kp@ = pointer to packing structure
- *             @key_data *kd@ = pointer to destination key data
+ *             @key_data **kd@ = where to put the key data pointer
  *             @dstr *d@ = pointer to tag string for the key data
  *
  * Returns:    Error code, or zero.
  * Use:                Packs a key from a data structure.
  */
 
-int key_pack(key_packdef *kp, key_data *kd, dstr *d)
+int key_pack(key_packdef *kp, key_data **kd, dstr *d)
 {
-  switch (kp->kd.e & KF_ENCMASK) {
+  switch (kp->e & KF_ENCMASK) {
 
     /* --- Binary and integer keys are easy --- */
 
-    case KENC_BINARY:
-      kd->u.k = *(key_bin *)kp->p;
+    case KENC_BINARY: {
+      key_bin *b = kp->p;
+      *kd = key_newbinary(kp->e, b->k, b->sz);
       return (0);
+    }
     case KENC_MP:
-      kd->u.m = *(mp **)kp->p;
+      *kd = key_newmp(kp->e, *(mp **)kp->p);
+      return (0);
+    case KENC_STRING:
+      *kd = key_newstring(kp->e, *(char **)kp->p);
+      return (0);
+    case KENC_EC:
+      *kd = key_newec(kp->e, (ec *)kp->p);
       return (0);
 
     /* --- Encrypted keys are a little tricky --- *
@@ -74,12 +74,11 @@ int key_pack(key_packdef *kp, key_data *kd, dstr *d)
      */
 
     case KENC_ENCRYPT: {
-      key_data kkd;
+      key_data *kkd;
       int err = key_pack(kp->p, &kkd, d);
       if (!err) {
-       if (key_plock(d->buf, &kkd, kd))
-         err = KERR_BADPASS;
-       key_destroy(&kkd);
+       err = key_plock(kd, kkd, d->buf);
+       key_drop(kkd);
       }
       return (err);
     }
@@ -91,25 +90,25 @@ int key_pack(key_packdef *kp, key_data *kd, dstr *d)
       key_packstruct *p;
       size_t l = d->len;
 
-      key_structure(kd);
+      *kd = key_newstruct();
       DPUTC(d, '.');
       for (p = kp->p; p->name; p++) {
        key_data *kkd;
        d->len = l + 1;
        DPUTS(d, p->name);
-       kkd = key_structcreate(kd, p->name);
-       if ((err = key_pack(&p->kp, kkd, d)) != 0) {
-         key_destroy(kd);
+       if ((err = key_pack(&p->kp, &kkd, d)) != 0) {
+         key_drop(*kd);
          return (err);
        }
+       key_structsteal(*kd, p->name, kkd);
       }
       d->len = l;
       d->buf[l] = 0;
       return (0);
     }
+    default:
+      abort();
   }
-
-  return (KERR_BADTYPE);
 }
 
 /* --- @key_unpack@ --- *
@@ -125,24 +124,21 @@ int key_pack(key_packdef *kp, key_data *kd, dstr *d)
 
 int key_unpack(key_packdef *kp, key_data *kd, dstr *d)
 {
-  unsigned e = kp->kd.e & KF_ENCMASK;
+  unsigned e = kp->e & KF_ENCMASK;
   int err;
 
   /* --- Decrypt the encrypted key --- */
 
-  while ((kd->e & KF_ENCMASK) == KENC_ENCRYPT) {
-    if (key_punlock(d->buf, kd, &kp->kd)) {
-      err = KERR_BADPASS;
+  if ((kd->e & KF_ENCMASK) == KENC_ENCRYPT) {
+    if ((err = key_punlock(&kp->kd, kd, d->buf)) != 0)
       goto fail;
-    }
-    kd = &kp->kd;
-    kd->e |= KF_TEMP;
+    kd = kp->kd;
   }
 
   /* --- Ensure that the key has the right type --- */
 
   if ((kd->e & KF_ENCMASK) != e) {
-    err = KERR_BADTYPE;
+    err = KERR_WRONGTYPE;
     goto fail;
   }
 
@@ -161,6 +157,12 @@ int key_unpack(key_packdef *kp, key_data *kd, dstr *d)
     case KENC_MP:
       *(mp **)kp->p = kd->u.m;
       break;
+    case KENC_STRING:
+      *(char **)kp->p = kd->u.p;
+      break;
+    case KENC_EC:
+      *(ec *)kp->p = kd->u.e;
+      break;
 
     /* --- Structured keys take a little care --- */
 
@@ -182,7 +184,7 @@ int key_unpack(key_packdef *kp, key_data *kd, dstr *d)
        /* --- Find and unpack the subkey --- */
 
        if ((kkd = key_structfind(kd, p->name)) == 0) {
-         if (!(p->kp.kd.e & KF_OPT)) {
+         if (!(p->kp.e & KF_OPT)) {
            err = KERR_NOTFOUND;
            goto tidy;
          }
@@ -205,6 +207,9 @@ int key_unpack(key_packdef *kp, key_data *kd, dstr *d)
        key_unpackdone(&q->kp);
       goto fail;
     }
+
+    default:
+      abort();
   }
 
   return (0);
@@ -212,8 +217,10 @@ int key_unpack(key_packdef *kp, key_data *kd, dstr *d)
   /* --- Something went wrong --- */
 
 fail:
-  if (kd == &kp->kd)
-    key_destroy(kd);
+  if (kp->kd) {
+    key_drop(kp->kd);
+    kp->kd = 0;
+  }
   return (err);
 }
 
@@ -229,9 +236,11 @@ fail:
 
 void key_unpackdone(key_packdef *kp)
 {
-  if (kp->kd.e & KF_TEMP)
-    key_destroy(&kp->kd);
-  if ((kp->kd.e & KF_ENCMASK) == KENC_STRUCT) {
+  if (kp->kd) {
+    key_drop(kp->kd);
+    kp->kd = 0;
+  }
+  if ((kp->e & KF_ENCMASK) == KENC_STRUCT) {
     key_packstruct *p;
     for (p = kp->p; p->name; p++)
       key_unpackdone(&p->kp);