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