Provide better interface to key locking.
authormdw <mdw>
Thu, 11 Nov 2004 19:40:25 +0000 (19:40 +0000)
committermdw <mdw>
Thu, 11 Nov 2004 19:40:25 +0000 (19:40 +0000)
Makefile.m4
key-data.h
key-error.c
key-error.h [new file with mode: 0644]
key-pass.c
key.h

index b269aee..d27ca10 100644 (file)
@@ -154,7 +154,7 @@ pkginclude_HEADERS = \
        arena.h paranoia.h buf.h qdparse.h \
        blkc.h hash.h gcipher.h ghash.h gmac.h grand.h ghash-def.h \
        lcrand.h fibrand.h rc4.h seal.h rand.h noise.h fipstest.h maurer.h \
-       key.h key-data.h passphrase.h pixie.h lmem.h \
+       key.h key-error.h key-data.h passphrase.h pixie.h lmem.h \
        mpx.h bitops.h mpw.h mpscan.h mparena.h mp.h mptext.h mpint.h \
        exp.h mpbarrett.h mpmont.h mpreduce.h mp-exp.h \
        mpcrt.h mprand.h mpmul.h \
index b9c9dc4..5644834 100644 (file)
 #include <mLib/dstr.h>
 #include <mLib/sym.h>
 
+#ifndef CATACOMB_KEY_ERROR_H
+#  include "key-error.h"
+#endif
+
 #ifndef CATACOMB_MP_H
 #  include "mp.h"
 #endif
@@ -141,6 +145,13 @@ enum {
   KENC_MAX                             /* Dummy limit constant */
 };
 
+/* --- Key locking return codes --- */
+
+#define KL_OK 0                                /* All good */
+#define KL_IOERR -1                    /* I/O problem (e.g., getting pp) */
+#define KL_KEYERR -2                   /* Wrong key supplied */
+#define KL_DATAERR -3                  /* Data format error */
+
 /* --- Key flag filtering --- */
 
 typedef struct key_filter {
@@ -438,7 +449,37 @@ extern int key_unpack(key_packdef */*kp*/, key_data */*kd*/, dstr */*d*/);
 
 extern void key_unpackdone(key_packdef */*kp*/);
 
-/*----- Passphrase encryption ---------------------------------------------*/
+/*----- Key encryption ----------------------------------------------------*/
+
+/* --- @key_lock@ --- *
+ *
+ * Arguments:  @key_data *kt@ = destination block
+ *             @key_data *k@ = source key data block
+ *             @const void *e@ = secret to encrypt key with
+ *             @size_t esz@ = size of the secret
+ *
+ * Returns:    ---
+ *
+ * Use:                Encrypts a key data block using a secret.
+ */
+
+extern void key_lock(key_data */*kt*/, key_data */*k*/,
+                    const void */*e*/, size_t /*esz*/);
+
+/* --- @key_unlock@ --- *
+ *
+ * Arguments:  @key_data *kt@ = target block
+ *             @key_data *k@ = source key data block
+ *             @const void *e@ = secret to decrypt the block with
+ *             @size_t esz@ = size of the secret
+ *
+ * Returns:    Zero for success, or a @KERR_@ error code.
+ *
+ * Use:                Unlocks a key using a secret.
+ */
+
+extern int key_unlock(key_data */*kt*/, key_data */*k*/,
+                     const void */*e*/, size_t /*esz*/);
 
 /* --- @key_plock@ --- *
  *
@@ -446,7 +487,7 @@ extern void key_unpackdone(key_packdef */*kp*/);
  *             @key_data *k@ = source key data block
  *             @key_data *kt@ = target key data block
  *
- * Returns:    Zero if successful, nonzero if there was a problem.
+ * Returns:    Zero if successful, a @KERR@ error code on failure.
  *
  * Use:                Locks a key by encrypting it with a passphrase.
  */
@@ -459,7 +500,7 @@ extern int key_plock(const char */*tag*/, key_data */*k*/, key_data */*kt*/);
  *             @key_data *k@ = source key data block
  *             @key_data *kt@ = target key data block
  *
- * Returns:    Zero if it worked, nonzero if it didn't.
+ * Returns:    Zero if successful, a @KERR@ error code on failure.
  *
  * Use:                Unlocks a passphrase-locked key.
  */
index 75e4246..b114798 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: key-error.c,v 1.4 2004/04/08 01:36:15 mdw Exp $
+ * $Id$
  *
  * Translating key error codes into strings
  *
@@ -30,7 +30,7 @@
 /*----- Header files ------------------------------------------------------*/
 
 #include <mLib/macros.h>
-#include "key.h"
+#include "key-error.h"
 
 /*----- Error reporting ---------------------------------------------------*/
 
@@ -61,6 +61,8 @@ const char *key_strerror(int err)
     "Unexpected key encoding type",
     "Key not found",
     "Bad attribute name",
+    "Malformed key data",
+    "I/O errror",
     "Unknown error code"
   };
   
diff --git a/key-error.h b/key-error.h
new file mode 100644 (file)
index 0000000..94b53c2
--- /dev/null
@@ -0,0 +1,78 @@
+/* -*-c-*-
+ *
+ * $Id$
+ *
+ * Key management error codes
+ *
+ * (c) 2004 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------* 
+ *
+ * This file is part of Catacomb.
+ *
+ * Catacomb is free software; you can redistribute it and/or modify
+ * 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.
+ */
+
+#ifndef CATACOMB_KEY_ERROR_H
+#define CATACOMB_KEY_ERROR_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/*----- Error codes -------------------------------------------------------*/
+
+enum {
+  KERR_OK = 0,                         /* No error */
+  KERR_BADTAG = -1,                    /* Malformed tag string */
+  KERR_BADTYPE = -2,                   /* Malformed type string */
+  KERR_BADCOMMENT = -3,                        /* Malformed comment string */
+  KERR_DUPID = -4,                     /* Duplicate keyid */
+  KERR_DUPTAG = -5,                    /* Duplicate key tag string */
+  KERR_READONLY = -6,                  /* Key file is read-only */
+  KERR_WILLEXPIRE = -7,                        /* Key will eventually expire */
+  KERR_EXPIRED = -8,                   /* Key has already expired */
+  KERR_BADFLAGS = -9,                  /* Error in flags string */
+  KERR_BADPASS = -10,                  /* Error decrypting locked key */
+  KERR_WRONGTYPE = -11,                        /* Key has incorrect type */
+  KERR_NOTFOUND = -12,                 /* Key couldn't be found */
+  KERR_BADATTR = -13,                  /* Malformed attribute name */
+  KERR_MALFORMED = -14,                        /* Key data is malformed */
+  KERR_IO = -15,                       /* I/O error of some kind */
+  KERR_MAX = -16                       /* Not useful */
+};
+
+/*----- Functions provided ------------------------------------------------*/
+
+/* --- @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.
+ */
+
+extern const char *key_strerror(int /*err*/);
+
+/*----- That's all, folks -------------------------------------------------*/
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif
index bdc992a..1b0997a 100644 (file)
  * has been replaced incompatibly.
  */
 
-/* --- @key_plock@ --- *
+/* --- @key_lock@ --- *
  *
- * Arguments:  @const char *tag@ = tag to use for passphrase
+ * Arguments:  @key_data *kt@ = destination block
  *             @key_data *k@ = source key data block
- *             @key_data *kt@ = target key data block
+ *             @const void *e@ = secret to encrypt key with
+ *             @size_t esz@ = size of the secret
  *
- * Returns:    Zero if successful, nonzero if there was a problem.
+ * Returns:    ---
  *
- * Use:                Locks a key by encrypting it with a passphrase.
+ * Use:                Encrypts a key data block using a secret.
  */
 
-int key_plock(const char *tag, key_data *k, key_data *kt)
+void key_lock(key_data *kt, key_data *k, const void *e, size_t esz)
 {
   dstr d = DSTR_INIT;
   octet b[RMD160_HASHSZ * 2];
   octet *m;
   size_t msz;
-  char buf[256];
+  rmd160_mgfctx r;
+  blowfish_cbcctx c;
+  rmd160_mackey mk;
+  rmd160_macctx mc;
 
   /* --- Sanity check --- */
 
@@ -89,71 +93,57 @@ int key_plock(const char *tag, key_data *k, key_data *kt)
   m = (octet *)d.buf + RMD160_HASHSZ * 2;
   msz = d.len - RMD160_HASHSZ * 2;
 
-  /* --- Read the passphrase --- */
-
-  if (passphrase_read(tag, PMODE_VERIFY, buf, sizeof(buf))) {
-    dstr_destroy(&d);
-    return (-1);
-  }
-
   /* --- Hash the passphrase to make a key --- */
 
-  {
-    rmd160_mgfctx r;
-    rmd160_mgfkeybegin(&r);
-    rmd160_mgfkeyadd(&r, d.buf, RMD160_HASHSZ);
-    rmd160_mgfkeyadd(&r, buf, strlen(buf));
-    rmd160_mgfencrypt(&r, 0, b, sizeof(b));
-    BURN(r);
-    BURN(buf);
-  }
+  rmd160_mgfkeybegin(&r);
+  rmd160_mgfkeyadd(&r, d.buf, RMD160_HASHSZ);
+  rmd160_mgfkeyadd(&r, e, esz);
+  rmd160_mgfencrypt(&r, 0, b, sizeof(b));
+  BURN(r);
 
   /* --- Encrypt the plaintext --- */
 
-  {
-    blowfish_cbcctx c;
-    blowfish_cbcinit(&c, b, RMD160_HASHSZ, 0);
-    blowfish_cbcencrypt(&c, m, m, msz);
-    BURN(c);
-  }
+  blowfish_cbcinit(&c, b, RMD160_HASHSZ, 0);
+  blowfish_cbcencrypt(&c, m, m, msz);
+  BURN(c);
 
   /* --- MAC the ciphertext --- */
 
-  {
-    rmd160_mackey mk;
-    rmd160_macctx mc;
-    rmd160_hmacinit(&mk, b + RMD160_HASHSZ, RMD160_HASHSZ);
-    rmd160_macinit(&mc, &mk);
-    rmd160_machash(&mc, m, msz);
-    rmd160_macdone(&mc, d.buf + RMD160_HASHSZ);
-    BURN(mk);
-    BURN(mc);
-  }
+  rmd160_hmacinit(&mk, b + RMD160_HASHSZ, RMD160_HASHSZ);
+  rmd160_macinit(&mc, &mk);
+  rmd160_machash(&mc, m, msz);
+  rmd160_macdone(&mc, d.buf + RMD160_HASHSZ);
+  BURN(mk);
+  BURN(mc);
 
   /* --- Done --- */
 
   BURN(b);
   key_encrypted(kt, d.buf, d.len);
   dstr_destroy(&d);
-  return (0);
 }
 
-/* --- @key_punlock@ --- *
+/* --- @key_unlock@ --- *
  *
- * Arguments:  @const char *tag@ = tag to use for passphrase
+ * Arguments:  @key_data *kt@ = target block
  *             @key_data *k@ = source key data block
- *             @key_data *kt@ = target key data block
+ *             @const void *e@ = secret to decrypt the block with
+ *             @size_t esz@ = size of the secret
  *
- * Returns:    Zero if it worked, nonzero if it didn't.
+ * Returns:    Zero for success, or a @KERR_@ error code.
  *
- * Use:                Unlocks a passphrase-locked key.
+ * Use:                Unlocks a key using a secret.
  */
 
-int key_punlock(const char *tag, key_data *k, key_data *kt)
+int key_unlock(key_data *kt, key_data *k, const void *e, size_t esz)
 {
   octet b[RMD160_HASHSZ * 2];
-  char buf[256];
   octet *p = 0;
+  int rc;
+  rmd160_mgfctx r;
+  blowfish_cbcctx c;
+  rmd160_mackey mk;
+  rmd160_macctx mc;
   size_t sz;
 
   /* --- Sanity check --- */
@@ -164,43 +154,30 @@ int key_punlock(const char *tag, key_data *k, key_data *kt)
   /* --- Check the size --- */
 
   if (k->u.k.sz < RMD160_HASHSZ * 2)
-    return (-1);
+    return (KERR_MALFORMED);
   sz = k->u.k.sz - RMD160_HASHSZ * 2;
 
-  /* --- Fetch the passphrase --- */
-
-  if (passphrase_read(tag, PMODE_READ, buf, sizeof(buf)))
-    goto fail;
-
   /* --- Hash the passphrase to make a key --- */
 
-  {
-    rmd160_mgfctx r;
-    rmd160_mgfkeybegin(&r);
-    rmd160_mgfkeyadd(&r, k->u.k.k, RMD160_HASHSZ);
-    rmd160_mgfkeyadd(&r, buf, strlen(buf));
-    rmd160_mgfencrypt(&r, 0, b, sizeof(b));
-    BURN(r);
-    BURN(buf);
-  }
+  rmd160_mgfkeybegin(&r);
+  rmd160_mgfkeyadd(&r, k->u.k.k, RMD160_HASHSZ);
+  rmd160_mgfkeyadd(&r, e, esz);
+  rmd160_mgfencrypt(&r, 0, b, sizeof(b));
+  BURN(r);
 
   /* --- Verify the MAC --- */
 
-  {
-    rmd160_mackey mk;
-    rmd160_macctx mc;
-    rmd160_hmacinit(&mk, b + RMD160_HASHSZ, RMD160_HASHSZ);
-    rmd160_macinit(&mc, &mk);
-    rmd160_machash(&mc, k->u.k.k + RMD160_HASHSZ * 2, sz);
-    rmd160_macdone(&mc, b + RMD160_HASHSZ);
-    if (memcmp(b + RMD160_HASHSZ, k->u.k.k + RMD160_HASHSZ,
-              RMD160_HASHSZ) != 0) {
-      passphrase_cancel(tag);
-      goto fail;
-    }
-    BURN(mk);
-    BURN(mc);
+  rmd160_hmacinit(&mk, b + RMD160_HASHSZ, RMD160_HASHSZ);
+  rmd160_macinit(&mc, &mk);
+  rmd160_machash(&mc, k->u.k.k + RMD160_HASHSZ * 2, sz);
+  rmd160_macdone(&mc, b + RMD160_HASHSZ);
+  if (memcmp(b + RMD160_HASHSZ, k->u.k.k + RMD160_HASHSZ,
+            RMD160_HASHSZ) != 0) {
+    rc = KERR_BADPASS;
+    goto fail;
   }
+  BURN(mk);
+  BURN(mc);
 
   /* --- Allocate a destination buffer --- */
 
@@ -208,21 +185,18 @@ int key_punlock(const char *tag, key_data *k, key_data *kt)
 
   /* --- Decrypt the key data --- */
 
-  {
-    blowfish_cbcctx c;
-    blowfish_cbcinit(&c, b, RMD160_HASHSZ, 0);
-    blowfish_cbcdecrypt(&c, k->u.k.k + RMD160_HASHSZ * 2, p, sz);
-    BURN(c);
-  }
+  blowfish_cbcinit(&c, b, RMD160_HASHSZ, 0);
+  blowfish_cbcdecrypt(&c, k->u.k.k + RMD160_HASHSZ * 2, p, sz);
+  BURN(c);
 
   /* --- Decode the key data into the destination buffer --- */
 
-  if (k == kt) {
+  if (k == kt)
     key_destroy(k);
-    passphrase_cancel(tag);
-  }
-  if (key_decode(p, sz, kt))
+  if (key_decode(p, sz, kt)) {
+    rc = KERR_MALFORMED;
     goto fail;
+  }
 
   /* --- Done --- */
 
@@ -234,7 +208,54 @@ int key_punlock(const char *tag, key_data *k, key_data *kt)
 fail:
   BURN(b);
   xfree(p);
-  return (-1);
+  return (rc);
+}
+
+/* --- @key_plock@ --- *
+ *
+ * Arguments:  @const char *tag@ = tag to use for passphrase
+ *             @key_data *k@ = source key data block
+ *             @key_data *kt@ = target key data block
+ *
+ * Returns:    Zero if successful, a @KERR@ error code on failure.
+ *
+ * Use:                Locks a key by encrypting it with a passphrase.
+ */
+
+int key_plock(const char *tag, key_data *k, key_data *kt)
+{
+  char buf[256];
+
+  if (passphrase_read(tag, PMODE_VERIFY, buf, sizeof(buf)))
+    return (KERR_IO);
+  key_lock(kt, k, buf, strlen(buf));
+  BURN(buf);
+  return (0);
+}
+
+/* --- @key_punlock@ --- *
+ *
+ * Arguments:  @const char *tag@ = tag to use for passphrase
+ *             @key_data *k@ = source key data block
+ *             @key_data *kt@ = target key data block
+ *
+ * Returns:    Zero if it worked, a @KERR_@ error code on failure.
+ *
+ * Use:                Unlocks a passphrase-locked key.
+ */
+
+int key_punlock(const char *tag, key_data *k, key_data *kt)
+{
+  char buf[256];
+  int rc;
+
+  if (passphrase_read(tag, PMODE_READ, buf, sizeof(buf)))
+    return (KERR_IO);
+  rc = key_unlock(kt, k, buf, strlen(buf));
+  BURN(buf);
+  if (rc == KERR_BADPASS || k == kt)
+    passphrase_cancel(tag);
+  return (rc);
 }
 
 /*----- That's all, folks -------------------------------------------------*/
diff --git a/key.h b/key.h
index 6f5bedb..aad448b 100644 (file)
--- a/key.h
+++ b/key.h
 #include <mLib/hash.h>
 #include <mLib/sym.h>
 
+#ifndef CATACOMB_KEY_ERROR_H
+#  include "key-error.h"
+#endif
+
 #ifndef CATACOMB_KEY_DATA_H
 #  include "key-data.h"
 #endif
@@ -155,26 +159,6 @@ typedef struct key_fetchdef {
 #define KEXP_FOREVER ((time_t)-1)      /* Never expire this key */
 #define KEXP_EXPIRE ((time_t)-2)       /* Expire this key when unused */
 
-/* --- Key error codes --- */
-
-enum {
-  KERR_OK = 0,                         /* No error */
-  KERR_BADTAG = -1,                    /* Malformed tag string */
-  KERR_BADTYPE = -2,                   /* Malformed type string */
-  KERR_BADCOMMENT = -3,                        /* Malformed comment string */
-  KERR_DUPID = -4,                     /* Duplicate keyid */
-  KERR_DUPTAG = -5,                    /* Duplicate key tag string */
-  KERR_READONLY = -6,                  /* Key file is read-only */
-  KERR_WILLEXPIRE = -7,                        /* Key will eventually expire */
-  KERR_EXPIRED = -8,                   /* Key has already expired */
-  KERR_BADFLAGS = -9,                  /* Error in flags string */
-  KERR_BADPASS = -10,                  /* Error decrypting locked key */
-  KERR_WRONGTYPE = -11,                        /* Key has incorrect type */
-  KERR_NOTFOUND = -12,                 /* Key couldn't be found */
-  KERR_BADATTR = -13,                  /* Malformed attribute name */
-  KERR_MAX                             /* Largest possible error */
-};
-
 /* --- Write error codes --- */
 
 enum {
@@ -697,17 +681,6 @@ extern void key_fetchdone(key_packdef */*kp*/);
 extern void key_moan(const char */*file*/, int /*line*/,
                     const char */*msg*/, void */*p*/);
 
-/* --- @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.
- */
-
-extern const char *key_strerror(int /*err*/);
-
 /*----- That's all, folks -------------------------------------------------*/
 
 #ifdef __cplusplus