chiark / gitweb /
Version bump.
[catacomb] / key.h
1 /* -*-c-*-
2  *
3  * $Id: key.h,v 1.6 2000/06/17 11:27:43 mdw Exp $
4  *
5  * Simple key management
6  *
7  * (c) 1999 Straylight/Edgeware
8  */
9
10 /*----- Licensing notice --------------------------------------------------* 
11  *
12  * This file is part of Catacomb.
13  *
14  * Catacomb is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU Library General Public License as
16  * published by the Free Software Foundation; either version 2 of the
17  * License, or (at your option) any later version.
18  * 
19  * Catacomb is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU Library General Public License for more details.
23  * 
24  * You should have received a copy of the GNU Library General Public
25  * License along with Catacomb; if not, write to the Free
26  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27  * MA 02111-1307, USA.
28  */
29
30 /*----- Revision history --------------------------------------------------* 
31  *
32  * $Log: key.h,v $
33  * Revision 1.6  2000/06/17 11:27:43  mdw
34  * Add key fetching interface.
35  *
36  * Revision 1.5  2000/02/12 18:55:40  mdw
37  * Make it all compile properly.
38  *
39  * Revision 1.4  2000/02/12 18:21:02  mdw
40  * Overhaul of key management (again).
41  *
42  * Revision 1.3  1999/12/22 15:47:48  mdw
43  * Major key-management revision.
44  *
45  * Revision 1.2  1999/12/10 23:29:48  mdw
46  * Change header file guard names.
47  *
48  * Revision 1.1  1999/09/03 08:41:12  mdw
49  * Initial import.
50  *
51  */
52
53 #ifndef CATACOMB_KEY_H
54 #define CATACOMB_KEY_H
55
56 #ifdef __cplusplus
57   extern "C" {
58 #endif
59
60 /*----- Header files ------------------------------------------------------*/
61
62 #include <stdio.h>
63 #include <time.h>
64
65 #include <mLib/bits.h>
66 #include <mLib/dstr.h>
67 #include <mLib/hash.h>
68 #include <mLib/sym.h>
69
70 #ifndef CATACOMB_KEY_DATA_H
71 #  include "key-data.h"
72 #endif
73
74 #ifndef CATACOMB_MP_H
75 #  include "mp.h"
76 #endif
77
78 /*----- Data structures ---------------------------------------------------*/
79
80 /* --- Key attributes --- *
81  *
82  * Each attribute is stored as a symbol in a symbol table.  The value is
83  * the plain (not url-encoded) text to be written to the the file.  If the
84  * value is binary data, then by this point it's base-64 encoded.
85  */
86
87 typedef struct key_attr {
88   sym_base _b;                          /* Symbol table data */
89   char *p;                              /* Pointer to attribute value */
90 } key_attr;
91
92 /* --- Main key structure --- *
93  *
94  * Each key is stored in two symbol tables, one indexed by keyid, and the
95  * other indexed by type.  Because many keys can have the same type, the type
96  * table contains a list of keys, sorted in descending order of expiry.
97  */
98
99 typedef struct key {
100
101   /* --- Hashtable management --- */
102   
103   hash_base _b;                         /* Symbol table data */
104   struct key *next;                     /* Next key of the same type */
105
106   /* --- Basic key attributes --- */
107
108   uint32 id;                            /* Key id used to name it */
109   char *tag;                            /* Textual tag name */
110   char *type;                           /* Textual key type */
111   time_t exp, del;                      /* Expiry times for keys */
112
113   /* --- The key data itself --- */
114
115   key_data k;                           /* The actual key data */
116
117   /* --- Other attributes and commentary --- */
118
119   sym_table a;                          /* Hashtable of key attributes */
120   char *c;                              /* Any additional comments */
121 } key;
122
123 /* --- The keys-by-type entries --- */
124
125 typedef struct key_ref {
126   sym_base _b;                          /* Symbol table data */
127   key *k;                               /* Pointer to first key in list */
128 } key_ref;
129
130 /* --- A key file --- */
131
132 typedef struct key_file {
133   FILE *fp;                             /* File pointer open on file */
134   char *name;                           /* Filename used to create it */
135   unsigned f;                           /* Various useful flags */
136   hash_table byid;                      /* Table of keys by keyid */
137   sym_table bytype;                     /* Table of keys by type */
138   sym_table bytag;                      /* Table of keys by tag */
139   size_t idload;                        /* Loading on id table */
140 } key_file;
141
142 /* --- Key file flags --- */
143
144 enum {
145   KF_WRITE = 1,                         /* File opened for writing */
146   KF_MODIFIED = 2                       /* File has been modified */
147 };
148
149 /* --- Iterating over keys --- *
150  *
151  * Both of these are simple symbol table iterators, but they're made distinct
152  * types for the dubious benefits that type safety brings.
153  */
154
155 typedef struct { hash_iter i; time_t t; } key_iter;
156 typedef struct { sym_iter i; } key_attriter;
157
158 /* --- Key fetching --- */
159
160 typedef struct key_fetchdef {
161   char *name;                           /* Name of item */
162   size_t off;                           /* Offset into target structure */
163   unsigned e;                           /* Flags for the item */
164   const struct key_fetchdef *kf;        /* Substructure pointer */
165 } key_fetchdef;
166
167 /* --- File opening options --- */
168
169 enum {
170   KOPEN_READ,
171   KOPEN_WRITE
172 };
173
174 /* --- Various other magic numbers --- */
175
176 #define KEXP_FOREVER ((time_t)-1)       /* Never expire this key */
177 #define KEXP_EXPIRE ((time_t)-2)        /* Expire this key when unused */
178
179 /* --- Key error codes --- */
180
181 enum {
182   KERR_OK = 0,                          /* No error */
183   KERR_BADTAG = -1,                     /* Malformed tag string */
184   KERR_BADTYPE = -2,                    /* Malformed type string */
185   KERR_BADCOMMENT = -3,                 /* Malformed comment string */
186   KERR_DUPID = -4,                      /* Duplicate keyid */
187   KERR_DUPTAG = -5,                     /* Duplicate key tag string */
188   KERR_READONLY = -6,                   /* Key file is read-only */
189   KERR_WILLEXPIRE = -7,                 /* Key will eventually expire */
190   KERR_EXPIRED = -8,                    /* Key has already expired */
191   KERR_BADFLAGS = -9,                   /* Error in flags string */
192   KERR_BADPASS = -10,                   /* Error decrypting locked key */
193   KERR_WRONGTYPE = -11,                 /* Key has incorrect type */
194   KERR_NOTFOUND = -12,                  /* Key couldn't be found */
195   KERR_MAX                              /* Largest possible error */
196 };
197
198 /* --- Write error codes --- */
199
200 enum {
201   KWRITE_OK,                            /* Everything went fine */
202   KWRITE_FAIL = -1,                     /* Close attempt failed */
203   KWRITE_BROKEN = -2                    /* Key ring needs manual fixing */
204 };
205
206 /* --- Error reporting functions for @key_merge@ and @key_open@ --- */
207
208 typedef void key_reporter(const char */*file*/, int /*line*/,
209                           const char */*err*/, void */*p*/);
210
211 /* --- Macros for testing expiry --- */
212
213 #define KEY_EXPIRED(now, exp)                                           \
214   ((exp) == KEXP_EXPIRE || ((exp) != KEXP_FOREVER && (exp) < (now)))
215
216 /*----- Reading and writing keys and files --------------------------------*/
217
218 /* --- @key_merge@ --- *
219  *
220  * Arguments:   @key_file *f@ = pointer to file structure
221  *              @const char *file@ = name of file (for error messages)
222  *              @FILE *fp@ = file handle to read from
223  *              @key_reporter *rep@ = error reporting function
224  *              @void *arg@ = argument for function
225  *
226  * Returns:     Error code (one of the @KERR@ constants).
227  *
228  * Use:         Reads keys from a file, and inserts them into the file.
229  */
230
231 extern int key_merge(key_file */*f*/, const char */*file*/, FILE */*fp*/,
232                      key_reporter */*rep*/, void */*arg*/);
233
234 /* --- @key_extract@ --- *
235  *
236  * Arguments:   @key_file *f@ = pointer to file structure
237  *              @key *k@ = key to extract
238  *              @FILE *fp@ = file to write on
239  *              @const key_filter *kf@ = pointer to key selection block
240  *
241  * Returns:     Zero if OK, EOF on error.
242  *
243  * Use:         Extracts a key to an ouptut file.
244  */
245
246 extern int key_extract(key_file */*f*/, key */*k*/, FILE */*fp*/,
247                        const key_filter */*kf*/);
248
249 /* --- @key_open@ --- *
250  *
251  * Arguments:   @key_file *f@ = pointer to file structure to initialize
252  *              @const char *file@ = pointer to the file name
253  *              @int how@ = opening options (@KOPEN_*@).
254  *              @key_reporter *rep@ = error reporting function
255  *              @void *arg@ = argument for function
256  *
257  * Returns:     Zero if it worked, nonzero otherwise.
258  *
259  * Use:         Opens a key file, reads its contents, and stores them in a
260  *              structure.  The file is locked appropriately until closed
261  *              using @key_close@.  On an error, everything is cleared away
262  *              tidily.  If the file is opened with @KOPEN_WRITE@, it's
263  *              created if necessary, with read and write permissions for its
264  *              owner only.
265  */
266
267 extern int key_open(key_file */*f*/, const char */*file*/, int /*how*/,
268                     key_reporter */*rep*/, void */*arg*/);
269
270 /* --- @key_close@ --- *
271  *
272  * Arguments:   @key_file *f@ = pointer to key file block
273  *
274  * Returns:     A @KWRITE_@ code indicating how it went.
275  *
276  * Use:         Frees all the key data, writes any changes.  Make sure that
277  *              all hell breaks loose if this returns @KWRITE_BROKEN@.
278  */
279
280 extern int key_close(key_file */*f*/);
281
282 /* --- @key_save@ --- *
283  *
284  * Arguments:   @key_file *f@ = pointer to key file block
285  *
286  * Returns:     A @KWRITE_@ code indicating how well it worked.
287  *
288  * Use:         Writes a key file's data back to the actual file.  This code
289  *              is extremely careful about error handling.  It should usually
290  *              be able to back out somewhere sensible, but it can tell when
291  *              it's got itself into a real pickle and starts leaving well
292  *              alone.
293  *
294  *              Callers, please make sure that you ring alarm bells when this
295  *              function returns @KWRITE_BROKEN@.
296  */
297
298 extern int key_save(key_file */*f*/);
299
300 /* --- @key_lockfile@ --- *
301  *
302  * Arguments:   @key_file *f@ = pointer to file structure to initialize
303  *              @const char *file@ = pointer to the file name
304  *              @int how@ = opening options (@KOPEN_*@).
305  *
306  * Returns:     Zero if it worked, nonzero otherwise.
307  *
308  * Use:         Opens a keyfile and stores the information needed for
309  *              continued access in the structure.
310  *
311  *              If the file is opened with @KOPEN_WRITE@, it's created if
312  *              necessary with read and write permissions for owner only, and
313  *              locked for update while it's open.
314  *
315  *              This is a system-dependent routine, and only really intended
316  *              for the private use of @key_open@.
317  */
318
319 extern int key_lockfile(key_file */*f*/, const char */*file*/, int /*how*/);
320
321 /*----- Creating and manipulating keys ------------------------------------*/
322
323 /* --- @key_new@ ---
324  *
325  * Arguments:   @key_file *f@ = pointer to key file
326  *              @uint32 id@ = keyid to set
327  *              @const char *type@ = the type of this key
328  *              @time_t exp@ = when the key expires
329  *              @int *err@ = where to store the error condition
330  *
331  * Returns:     Key block containing new data, or null if it couldn't be
332  *              done.
333  *
334  * Use:         Attaches a new key to a key file.  You must have a writable
335  *              key file for this to work.
336  *
337  *              The type is a key type string.  This interface doesn't care
338  *              about how type strings are formatted: it just treats them as
339  *              opaque gobs of text.  Clients are advised to choose some
340  *              standard for representing key types, though.
341  *
342  *              The expiry time should either be a time in the future, or the
343  *              magic value @KEXP_FOREVER@ which means `never expire this
344  *              key'.  Be careful with `forever' keys.  If I were you, I'd
345  *              use a more sophisticated key management system than this for
346  *              them.
347  *
348  *              You have to set the actual key yourself.
349  */
350
351 extern key *key_new(key_file */*f*/, uint32 /*id*/, const char */*type*/,
352                     time_t /*exp*/, int */*err*/);
353
354 /* --- @key_delete@ --- *
355  *
356  * Arguments:   @key_file *f@ = pointer to file block
357  *              @key *k@ = key to delete
358  *
359  * Returns:     Error code (one of the @KERR@ constants).
360  *
361  * Use:         Removes the given key from the list.  The key file must be
362  *              writable.  (Due to the horridness of the data structures,
363  *              deleted keys aren't actually removed, just marked so that
364  *              they can't be looked up or iterated over.  One upshot of
365  *              this is that they don't get written back to the file when
366  *              it's closed.)
367  */
368
369 extern int key_delete(key_file */*f*/, key */*k*/);
370
371 /* --- @key_expire@ --- *
372  *
373  * Arguments:   @key_file *f@ = pointer to file block
374  *              @key *k@ = pointer to key block
375  *
376  * Returns:     Error code (one of the @KERR@ constants).
377  *
378  * Use:         Immediately marks the key as expired.  It may be removed
379  *              immediately, if it is no longer required, and will be removed
380  *              by a tidy operation when it is no longer required.  The key
381  *              file must be writable.
382  */
383
384 extern int key_expire(key_file */*f*/, key */*k*/);
385
386 /* --- @key_used@ --- *
387  *
388  * Arguments:   @key_file *f@ = pointer to key file
389  *              @key *k@ = pointer to key block
390  *              @time_t t@ = when key can be removed
391  *
392  * Returns:     Zero if OK, nonzero on failure.
393  *
394  * Use:         Marks a key as being required until a given time.  Even
395  *              though the key may expire before then (and won't be returned
396  *              by type after that time), it will still be available when
397  *              requested explicitly by id.  The key file must be writable.
398  *
399  *              The only (current) reason for failure is attempting to use
400  *              a key which can expire for something which can't.
401  */
402
403 extern int key_used(key_file */*f*/, key */*k*/, time_t /*t*/);
404
405 /*----- Setting and reading attributes ------------------------------------*/
406
407 /* --- @key_chkident@ --- *
408  *
409  * Arguments:   @const char *p@ = pointer to a type string
410  *
411  * Returns:     Zero if OK, -1 on error.
412  *
413  * Use:         Checks whether an identification component string is OK.
414  */
415
416 extern int key_chkident(const char */*p*/);
417
418 /* --- @key_chkcomment@ --- *
419  *
420  * Arguments:   @const char *p@ = pointer to a comment string
421  *
422  * Returns:     Zero if OK, -1 on error.
423  *
424  * Use:         Checks whether a comment string is OK.
425  */
426
427 extern int key_chkcomment(const char */*p*/);
428
429 /* --- @key_setcomment@ --- *
430  *
431  * Arguments:   @key_file *f@ = pointer to key file block
432  *              @key *k@ = pointer to key block
433  *              @const char *c@ = pointer to comment to set, or zero
434  *
435  * Returns:     Error code (one of the @KERR@ constants).
436  *
437  * Use:         Replaces the key's current comment with a new one.
438  */
439
440 extern int key_setcomment(key_file */*f*/, key */*k*/, const char */*c*/);
441
442 /* --- @key_settag@ --- *
443  *
444  * Arguments:   @key_file *f@ = pointer to key file block
445  *              @key *k@ = pointer to key block
446  *              @const char *tag@ = pointer to comment to set, or zero
447  *
448  * Returns:     Error code (one of the @KERR@ constants).
449  *
450  * Use:         Replaces the key's current tag with a new one.
451  */
452
453 extern int key_settag(key_file */*f*/, key */*k*/, const char */*tag*/);
454
455 /* --- @key_fulltag@ --- *
456  *
457  * Arguments:   @key *k@ = pointer to key
458  *              @dstr *d@ = pointer to destination string
459  *
460  * Returns:     ---
461  *
462  * Use:         Emits the key's full tag, which has the form
463  *              `ID:TYPE[:TAG]'.  This is used in the textual file format,
464  *              and to identify passphrases for locked keys.
465  */
466
467 extern void key_fulltag(key */*k*/, dstr */*d*/);
468
469 /* --- @key_qtag@ --- *
470  *
471  * Arguments:   @key_file *f@ = key file to find a key from
472  *              @const char *tag@ = pointer to tag string
473  *              @dstr *d@ = pointer to string for full tag name
474  *              @key **k@ = where to store the key pointer
475  *              @key_data **kd@ = where to store the key data pointer
476  *
477  * Returns:     Zero if OK, nonzero if it failed.
478  *
479  * Use:         Performs a full lookup on a qualified tag name.  The tag is
480  *              qualified by the names of subkeys, separated by dots.  Hence,
481  *              a qualified tag is ID|TAG[.TAG...].  The various result
482  *              pointers can be null to indicate that the result isn't
483  *              interesting. 
484  */
485
486 extern int key_qtag(key_file */*f*/, const char */*tag*/,
487                     dstr */*d*/, key **/*k*/, key_data **/*kd*/);
488
489 /* --- @key_getattr@ --- *
490  *
491  * Arguments:   @key_file *f@ = pointer to file
492  *              @key *k@ = pointer to key
493  *              @const char *n@ = pointer to attribute name
494  *
495  * Returns:     Pointer to attribute value, or null if not found.
496  *
497  * Use:         Returns the value of a key attribute.
498  */
499
500 extern const char *key_getattr(key_file */*f*/, key */*k*/,
501                                const char */*n*/);
502
503 /* --- @key_putattr@ --- *
504  *
505  * Arguments:   @key_file *f@ = pointer to file
506  *              @key *k@ = pointer to key
507  *              @const char *n@ = pointer to attribute name
508  *              @const char *v@ = pointer to attribute value or null
509  *
510  * Returns:     Error code (one of the @KERR@ constants).
511  *
512  * Use:         Inserts an attribute on a key.  If an attribute with the same
513  *              name already exists, it is deleted.  Setting a null value
514  *              removes the attribute.
515  */
516
517 extern int key_putattr(key_file */*f*/, key */*k*/,
518                        const char */*n*/, const char */*v*/);
519
520 /* --- @key_mkattriter@ --- *
521  *
522  * Arguments:   @key_attriter *i@ = pointer to attribute iterator
523  *              @key *k@ = pointer to key
524  *
525  * Returns:     ---
526  *
527  * Use:         Initializes an attribute iterator.  The attributes are
528  *              returned by @key_nextattr@.
529  */
530
531 extern void key_mkattriter(key_attriter */*i*/, key */*k*/);
532
533 /* --- @key_nextattr@ --- *
534  *
535  * Arguments:   @key_attriter *i@ = pointer to attribute iterator
536  *              @const char **n, **v@ = pointers to name and value
537  *
538  * Returns:     Zero if no attribute available, or nonzero if returned OK.
539  *
540  * Use:         Returns the next attribute.
541  */
542
543 extern int key_nextattr(key_attriter */*i*/,
544                         const char **/*n*/, const char **/*v*/);
545
546 /*----- Searching and iterating -------------------------------------------*/
547
548 /* --- @key_bytype@ --- *
549  *
550  * Arguments:   @key_file *f@ = key file we want a key from
551  *              @const char *type@ = type string for desired key
552  *
553  * Returns:     Pointer to the best key to use, or null.
554  *
555  * Use:         Looks up a key by its type.  Returns the key with the latest
556  *              expiry time.  This function will not return an expired key.
557  */
558
559 extern key *key_bytype(key_file */*f*/, const char */*type*/);
560
561 /* --- @key_byid@ --- *
562  *
563  * Arguments:   @key_file *f@ = key file to find a key from
564  *              @uint32 id@ = id to look for
565  *
566  * Returns:     Key with matching id.
567  *
568  * Use:         Returns a key given its id.  This function will return an
569  *              expired key, but not a deleted one.
570  */
571
572 extern key *key_byid(key_file */*f*/, uint32 /*id*/);
573
574 /* --- @key_bytag@ --- *
575  *
576  * Arguments:   @key_file *f@ = key file to find a key from
577  *              @const char *tag@ = pointer to tag string
578  *
579  * Returns:     Key with matching id or tag.
580  *
581  * Use:         Returns a key given its tag or id.  This function will return
582  *              an expired key, but not a deleted one.
583  */
584
585 extern key *key_bytag(key_file */*f*/, const char */*tag*/);
586
587 /* --- @key_mkiter@ --- *
588  *
589  * Arguments:   @key_iter *i@ = pointer to iterator object
590  *              @key_file *f@ = pointer to file structure
591  *
592  * Returns:     ---
593  *
594  * Use:         Initializes a key iterator.  The keys are returned by
595  *              @key_next@.
596  */
597
598 extern void key_mkiter(key_iter */*i*/, key_file */*f*/);
599
600 /* --- @key_next@ --- *
601  *
602  * Arguments:   @key_iter *i@ = pointer to iterator object
603  *
604  * Returns:     Pointer to next key, or null.
605  *
606  * Use:         Returns the next key in some arbitrary sequence.
607  */
608
609 extern key *key_next(key_iter */*i*/);
610
611 /*----- Fetching key data conveniently ------------------------------------*/
612
613 /* --- @key_fetchinit@ --- *
614  *
615  * Arguments:   @const key_fetchdef *kf@ = pointer to base definition
616  *              @key_packstruct *kps@ = pointer to destination packing def
617  *              @void *p@ = pointer to destination block
618  *
619  * Returns:     Pointer to packing definition.
620  *
621  * Use:         Initializes a packing definition (@key_packdef@ structure).
622  *              If @kps@ is null on entry, an appropriately sized block is
623  *              allocated automatically.  Otherwise it must be large enough.
624  */
625
626 extern key_packdef *key_fetchinit(const key_fetchdef */*kf*/,
627                                   key_packstruct */*kp*/, void */*p*/);
628
629 /* --- @key_fetch@ --- *
630  *
631  * Arguments:   @key_packdef *kp@ = pointer to packing structure
632  *              @key *k@ = key file containing desired key
633  *
634  * Returns:     Error code, or zero.
635  *
636  * Use:         Fetches an unpacked key from a packed one.
637  */
638
639 extern int key_fetch(key_packdef */*kp*/, key */*k*/);
640
641 /* --- @key_fetchbyname@ --- *
642  *
643  * Arguments:   @key_packdef *kp@ = pointer to packing structure
644  *              @key_file *kf@ = key file containing desired key
645  *              @const char *tag@ = user's tag describing the key
646  *
647  * Returns:     Error code, or zero.
648  *
649  * Use:         Fetches a named key from a key file and unpacks it
650  *              conveniently.
651  */
652
653 extern int key_fetchbyname(key_packdef */*kp*/,
654                            key_file */*kf*/, const char */*tag*/);
655
656 /* --- @key_fetchdone@ --- *
657  *
658  * Arguments:   @key_packdef *kp@ = pointer to packing structure
659  *
660  * Returns:     ---
661  *
662  * Use:         Frees a packing structure.  If the structure was allocated by
663  *              @key_fetchinit@ then it is freed.
664  */
665
666 extern void key_fetchdone(key_packdef */*kp*/);
667
668 /*----- Other functions ---------------------------------------------------*/
669
670 /* --- @key_moan@ --- *
671  *
672  * Arguments:   @const char *file@ = name of the file
673  *              @int line@ = line number in file
674  *              @const char *msg@ = error message
675  *              @void *p@ = argument pointer
676  *
677  * Returns:     ---
678  *
679  * Use:         Reports an error message about loading a key file.
680  */
681
682 extern void key_moan(const char */*file*/, int /*line*/,
683                      const char */*msg*/, void */*p*/);
684
685 /* --- @key_strerror@ --- *
686  *
687  * Arguments:   @int err@ = error code from @key_new@
688  *
689  * Returns:     Pointer to error string.
690  *
691  * Use:         Translates a @KERR@ error code into a human-readable string.
692  */
693
694 extern const char *key_strerror(int /*err*/);
695
696 /*----- That's all, folks -------------------------------------------------*/
697
698 #ifdef __cplusplus
699   }
700 #endif
701
702 #endif