From: mdw Date: Thu, 11 Nov 2004 19:40:25 +0000 (+0000) Subject: Provide better interface to key locking. X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/commitdiff_plain/1dda051bbae15d2f45db44e1828056b3f2e97285 Provide better interface to key locking. --- diff --git a/Makefile.m4 b/Makefile.m4 index b269aee..d27ca10 100644 --- a/Makefile.m4 +++ b/Makefile.m4 @@ -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 \ diff --git a/key-data.h b/key-data.h index b9c9dc4..5644834 100644 --- a/key-data.h +++ b/key-data.h @@ -42,6 +42,10 @@ #include #include +#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. */ diff --git a/key-error.c b/key-error.c index 75e4246..b114798 100644 --- a/key-error.c +++ b/key-error.c @@ -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 -#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 index 0000000..94b53c2 --- /dev/null +++ b/key-error.h @@ -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 diff --git a/key-pass.c b/key-pass.c index bdc992a..1b0997a 100644 --- a/key-pass.c +++ b/key-pass.c @@ -54,24 +54,28 @@ * 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 --- a/key.h +++ b/key.h @@ -44,6 +44,10 @@ #include #include +#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