X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/3f6ded6afc4be82774b2613b64b5cf38b16a3d27..e564e3f84ad0ea42b78559c0bfe304893fd5e76b:/key-data.h diff --git a/key-data.h b/key-data.h index 4ee99aa..d6a5636 100644 --- a/key-data.h +++ b/key-data.h @@ -1,13 +1,13 @@ /* -*-c-*- * - * $Id: key-data.h,v 1.2 2000/06/17 11:26:18 mdw Exp $ + * $Id$ * * Manipulating key data * * (c) 1999 Straylight/Edgeware */ -/*----- Licensing notice --------------------------------------------------* +/*----- Licensing notice --------------------------------------------------* * * This file is part of Catacomb. * @@ -15,29 +15,18 @@ * 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-data.h,v $ - * Revision 1.2 2000/06/17 11:26:18 mdw - * Add the key packing interface. - * - * Revision 1.1 2000/02/12 18:21:23 mdw - * Overhaul of key management (again). - * - */ - #ifndef CATACOMB_KEY_DATA_H #define CATACOMB_KEY_DATA_H @@ -53,10 +42,18 @@ #include #include +#ifndef CATACOMB_KEY_ERROR_H +# include "key-error.h" +#endif + #ifndef CATACOMB_MP_H # include "mp.h" #endif +#ifndef CATACOMB_EC_H +# include "ec.h" +#endif + /*----- Data structures ---------------------------------------------------*/ /* --- Key binary data --- */ @@ -70,23 +67,29 @@ typedef struct key_bin { typedef struct key_data { unsigned e; /* Encoding type for key data */ + unsigned ref; /* Reference counter */ union { key_bin k; /* Binary key data */ mp *m; /* Multiprecision integer */ sym_table s; /* Structured key data */ + char *p; /* String pointer */ + ec e; /* Elliptic curve point */ } u; } key_data; typedef struct key_struct { sym_base _b; - key_data k; + key_data *k; } key_struct; +typedef struct key_subkeyiter { sym_iter i; } key_subkeyiter; + /* --- Packing and unpacking --- */ typedef struct key_packdef { + unsigned e; /* Key data encoding type */ void *p; /* Pointer to the destination */ - key_data kd; /* Key data block */ + key_data *kd; /* Key data block */ } key_packdef; typedef struct key_packstruct { @@ -118,11 +121,13 @@ enum { /* --- Bottom two bits are the encoding type --- */ - KF_ENCMASK = 0x03, /* Encoding mask */ + KF_ENCMASK = 0x83, /* Encoding mask */ KENC_BINARY = 0x00, /* Plain binary key (@k@) */ KENC_MP = 0x01, /* Multiprecision integer (@i@) */ KENC_STRUCT = 0x02, /* Structured key data (@s@) */ KENC_ENCRYPT = 0x03, /* Encrypted key type (@k@) */ + KENC_STRING = 0x80, /* ASCII string (@p@) */ + KENC_EC = 0x81, /* Elliptic curve point (@e@) */ /* --- Key category bits --- */ @@ -136,14 +141,20 @@ enum { /* --- Other flags --- */ KF_BURN = 0x10, /* Burn key after use */ - KF_TEMP = 0x20, /* Temporary copy flag */ - KF_OPT = 0x40, /* Optional key (for @key_unpack@) */ + KF_OPT = 0x20, /* Optional key (for @key_unpack@) */ /* --- Tag end --- */ 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 { @@ -201,54 +212,77 @@ extern int key_match(key_data */*k*/, const key_filter */*kf*/); /*----- Setting new key data ----------------------------------------------*/ -/* --- @key_binary@ --- * +/* --- @key_newraw@ --- * * - * Arguments: @key_data *k@ = pointer to key data block + * Arguments: @unsigned e@ = encoding type to set + * + * Returns: New key block, not filled in. + */ + +extern key_data *key_newraw(unsigned /*e*/); + +/* --- @key_newbinary@ --- * + * + * Arguments: @unsigned e@ = other encoding flags * @const void *p@ = pointer to key data * @size_t sz@ = size of the key data * - * Returns: --- - * - * Use: Sets a binary key in a key data block. + * Returns: New key data object. */ -extern void key_binary(key_data */*k*/, const void */*p*/, size_t /*sz*/); +extern key_data *key_newbinary(unsigned /*e*/, + const void */*p*/, size_t /*sz*/); -/* --- @key_encrypted@ --- * +/* --- @key_newencrypted@ --- * * - * Arguments: @key_data *k@ = pointer to key data block + * Arguments: @unsigned e@ = other encoding flags * @const void *p@ = pointer to key data * @size_t sz@ = size of the key data * - * Returns: --- - * - * Use: Sets an encrypted key in a key data block. + * Returns: New key data object. */ -extern void key_encrypted(key_data */*k*/, const void */*p*/, size_t /*sz*/); +extern key_data *key_newencrypted(unsigned /*e*/, + const void */*p*/, size_t /*sz*/); -/* --- @key_mp@ --- * +/* --- @key_newmp@ --- * * - * Arguments: @key_data *k@ = pointer to key data block + * Arguments: @unsigned e@ = other encoding flags * @mp *m@ = pointer to the value to set * - * Returns: --- + * Returns: New key data object. + */ + +extern key_data *key_newmp(unsigned /*e*/, mp */*m*/); + +/* --- @key_newstring@ --- * + * + * Arguments: @unsigned e@ = other encoding flags + * @const char *p@ = pointer to the value to set * - * Use: Sets a multiprecision integer key in a key block. + * Returns: New key data object. */ -extern void key_mp(key_data */*k*/, mp */*m*/); +extern key_data *key_newstring(unsigned /*e*/, const char */*p*/); -/* --- @key_structure@ --- * +/* --- @key_newec@ --- * * - * Arguments: @key_data *k@ = pointer to key data block + * Arguments: @unsigned e@ = other encoding flags + * @const ec *pt@ = pointer to the value to set * - * Returns: --- + * Returns: New key data object. + */ + +extern key_data *key_newec(unsigned /*e*/, const ec */*pt*/); + +/* --- @key_newstruct@ --- * + * + * Arguments: --- * - * Use: Initializes a structured key type. + * Returns: New key data object. */ -extern void key_structure(key_data */*k*/); +extern key_data *key_newstruct(void); /* --- @key_structfind@ --- * * @@ -262,31 +296,106 @@ extern void key_structure(key_data */*k*/); extern key_data *key_structfind(key_data */*k*/, const char */*tag*/); -/* --- @key_structcreate@ --- * +/* --- @key_mksubkeyiter@ --- * + * + * Arguments: @key_subkeyiter *i@ = pointer to iterator block + * @key_data *k@ = pointer to key data block + * + * Returns: --- + * + * Use: Initializes a subkey iterator. + */ + +extern void key_mksubkeyiter(key_subkeyiter */*i*/, key_data */*k*/); + +/* --- @key_nextsubkey@ --- * + * + * Arguments: @key_structiter *i@ = pointer to iterator block + * @const char **tag@ = where to put the tag pointer, or null + * @key_data **kd@ = where to put the key data pointer, or null + * + * Returns: Nonzero if there was another item, zero if we hit the + * end-stop. + * + * Use: Collects the next subkey of a structured key. + */ + +extern int key_nextsubkey(key_subkeyiter */*i*/, + const char **/*tag*/, key_data **/*kd*/); + +/* --- @key_structset@, @key_structsteal@ --- * * * Arguments: @key_data *k@ = pointer to key data block * @const char *tag@ = pointer to tag string + * @key_data *kd@ = new key data to store + * + * Returns: --- + * + * Use: Creates a new subkey. Stealing doesn't affect @kd@'s + * refcount. If @kd@ is null, the subkey is deleted. + */ + +extern void key_structset(key_data */*k*/, + const char */*tag*/, key_data */*kd*/); +extern void key_structsteal(key_data */*k*/, + const char */*tag*/, key_data */*kd*/); + +/* --- @key_split@ --- * * - * Returns: Pointer to newly created key data. + * Arguments: @key_data **kk@ = address of pointer to key data block * - * Use: Creates a new uninitialized subkey. + * Returns: --- + * + * Use: Replaces @*kk@ with a pointer to the same key data, but with + * just one reference. */ -extern key_data *key_structcreate(key_data */*k*/, const char */*tag*/); +extern void key_split(key_data **/*kk*/); /*----- Miscellaneous operations ------------------------------------------*/ +/* --- @key_incref@ --- * + * + * Arguments: @key_data *k@ = pointer to key data + * + * Returns: --- + * + * Use: Increments the refcount on a key data block. + */ + +#define KEY_INCREF(k) ((k)->ref++) +extern void key_incref(key_data */*k*/); + /* --- @key_destroy@ --- * * * Arguments: @key_data *k@ = pointer to key data to destroy * * Returns: --- * - * Use: Destroys a lump of key data. + * Use: Destroys a block of key data, regardless of reference count. + * Don't use this unless you know what you're doing. */ extern void key_destroy(key_data */*k*/); +/* --- @key_drop@ --- * + * + * Arguments: @key_data *k@ = pointer to key data to destroy + * + * Returns: --- + * + * Use: Drops a reference to key data, destroying it if necessary. + */ + +#define KEY_DROP(k) do { \ + key_data *_k = k; \ + _k->ref--; \ + if (_k->ref == 0) \ + key_destroy(_k); \ +} while (0) + +extern void key_drop(key_data */*k*/); + /* --- @key_do@ --- * * * Arguments: @key_data *k@ = pointer to key data block @@ -297,7 +406,7 @@ extern void key_destroy(key_data */*k*/); * * Returns: Nonzero return code from function, or zero. * - * Use: Runs a function over all the leaves of a key. + * Use: Runs a function over all the leaves of a key. */ extern int key_do(key_data */*k*/, const key_filter */*kf*/, dstr */*d*/, @@ -305,34 +414,35 @@ extern int key_do(key_data */*k*/, const key_filter */*kf*/, dstr */*d*/, dstr */*d*/, void */*p*/), void */*p*/); -/* --- @key_copy@ --- * +/* --- @key_copydata@ --- * * - * Arguments: @key_data *kd@ = pointer to destination data block - * @key_data *k@ = pointer to source data block + * Arguments: @key_data *k@ = key data to copy * @const key_filter *kf@ = pointer to filter block * - * Returns: Nonzero if an item was actually copied. + * Returns: Pointer to a copy of the data, or null if the root subkey + * didn't match the filter. * - * Use: Copies a chunk of key data from one place to another. + * Use: Copies a chunk of key data. Subkeys, whether they're + * structured or leaves, which don't match the filter aren't + * copied. The copy may or may not have structure in common + * with the original. */ -extern int key_copy(key_data */*kd*/, key_data */*k*/, - const key_filter */*kf*/); +extern key_data *key_copydata(key_data */*k*/, const key_filter */*kf*/); /*----- Textual encoding --------------------------------------------------*/ /* --- @key_read@ --- * * * Arguments: @const char *p@ = pointer to textual key representation - * @key_data *k@ = pointer to output block for key data * @char **pp@ = where to store the end pointer * - * Returns: Zero if all went well, nonzero if there was a problem. + * Returns: The newly-read key data, or null if it failed. * * Use: Parses a textual key description. */ -extern int key_read(const char */*p*/, key_data */*k*/, char **/*pp*/); +extern key_data *key_read(const char */*p*/, char **/*pp*/); /* --- @key_write@ --- * * @@ -345,8 +455,7 @@ extern int key_read(const char */*p*/, key_data */*k*/, char **/*pp*/); * Use: Writes a key in a textual encoding. */ -extern int key_write(key_data */*k*/, dstr */*d*/, - const key_filter */*kf*/); +extern int key_write(key_data */*k*/, dstr */*d*/, const key_filter */*kf*/); /*----- Key binary encoding -----------------------------------------------*/ @@ -354,14 +463,13 @@ extern int key_write(key_data */*k*/, dstr */*d*/, * * Arguments: @const void *p@ = pointer to buffer to read * @size_t sz@ = size of the buffer - * @key_data *k@ = pointer to key data block to write to * - * Returns: Zero if everything worked, nonzero otherwise. + * Returns: The newly-read key data, or null if it failed. * * Use: Decodes a binary representation of a key. */ -extern int key_decode(const void */*p*/, size_t /*sz*/, key_data */*k*/); +extern key_data *key_decode(const void */*p*/, size_t /*sz*/); /* --- @key_encode@ --- * * @@ -382,7 +490,7 @@ extern int key_encode(key_data */*k*/, dstr */*d*/, /* --- @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. @@ -390,7 +498,7 @@ extern int key_encode(key_data */*k*/, dstr */*d*/, * Use: Packs a key from a data structure. */ -extern int key_pack(key_packdef */*kp*/, key_data */*kd*/, dstr */*d*/); +extern int key_pack(key_packdef */*kp*/, key_data **/*kd*/, dstr */*d*/); /* --- @key_unpack@ --- * * @@ -417,34 +525,65 @@ 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@ = where to store the destination pointer + * @key_data *k@ = source key data block or null to use @*kt@ + * @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@ = where to store the destination pointer + * @key_data *k@ = source key data block or null to use @*kt@ + * @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@ --- * * - * Arguments: @const char *tag@ = tag to use for passphrase - * @key_data *k@ = source key data block - * @key_data *kt@ = target key data block + * Arguments: @key_data **kt@ = where to store the destination pointer + * @key_data *k@ = source key data block or null to use @*kt@ + * @const char *tag@ = tag to use for passphrase * - * 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. */ -extern int key_plock(const char */*tag*/, key_data */*k*/, key_data */*kt*/); +extern int key_plock(key_data **/*kt*/, key_data */*k*/, + const char */*tag*/); /* --- @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 + * Arguments: @key_data **kt@ = where to store the destination pointer + * @key_data *k@ = source key data block or null to use @*kt@ + * @const char *tag@ = tag to use for passphrase * - * 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. */ -extern int key_punlock(const char */*tag*/, - key_data */*k*/, key_data */*kt*/); +extern int key_punlock(key_data **/*kt*/, key_data */*k*/, + const char */*tag*/); /*----- That's all, folks -------------------------------------------------*/