#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
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 {
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@ --- *
*
* @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.
*/
* @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.
*/
--- /dev/null
+/* -*-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
* 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 --- */
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 --- */
/* --- 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 --- */
/* --- 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 --- */
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 -------------------------------------------------*/
#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
#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 {
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