chiark / gitweb /
configure.ac: Replace with a new version.
[catacomb] / cc.h
1 /* -*-c-*-
2  *
3  * $Id$
4  *
5  * Catcrypt common stuff
6  *
7  * (c) 2004 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_CC_H
31 #define CATACOMB_CC_H
32
33 #ifdef __cplusplus
34   extern "C" {
35 #endif
36
37 /*----- Header files ------------------------------------------------------*/
38
39 #if _FILE_OFFSET_BITS != 64
40 #  error "Must set _FILE_OFFSET_BITS to 64."
41 #endif
42
43 #include <stdio.h>
44 #include <string.h>
45 #include <time.h>
46
47 #include <sys/types.h>
48 #include <sys/stat.h>
49
50 #include <mLib/dstr.h>
51
52 #include "key.h"
53 #include "gcipher.h"
54 #include "ghash.h"
55 #include "gmac.h"
56
57 /*----- Cryptographic object tables ---------------------------------------*/
58
59 /* --- Key encapsulation --- */
60
61 typedef struct kem {
62   const struct kemops *ops;
63   key_packdef *kp;
64   void *kd;
65   const gchash *h;
66   const gccipher *c, *cx;
67   const gcmac *m;
68 } kem;
69
70 typedef struct kemops {
71   const key_fetchdef *kf;               /* Key fetching structure */
72   size_t kdsz;                          /* Size of the key-data structure */
73   kem *(*init)(key */*k*/, void */*kd*/);
74   int (*doit)(kem */*k*/, dstr */*d*/, ghash */*h*/);
75   const char *(*check)(kem */*k*/);
76   void (*destroy)(kem */*k*/);
77 } kemops;
78
79 struct kemtab {
80   const char *name;
81   const kemops *encops;
82   const kemops *decops;
83 };
84
85 extern const struct kemtab kemtab[];
86
87 /* --- @getkem@ --- *
88  *
89  * Arguments:   @key *k@ = the key to load
90  *              @const char *app@ = application name
91  *              @int wantpriv@ = nonzero if we want to decrypt
92  *
93  * Returns:     A key-encapsulating thing.
94  *
95  * Use:         Loads a key.
96  */
97
98 extern kem *getkem(key */*k*/, const char */*app*/, int /*wantpriv*/);
99
100 /* --- @setupkem@ --- *
101  *
102  * Arguments:   @kem *k@ = key-encapsulation thing
103  *              @dstr *d@ = key-encapsulation data
104  *              @gcipher **cx@ = key-expansion function (for IVs)
105  *              @gcipher **c@ = where to put initialized encryption scheme
106  *              @gmac **m@ = where to put initialized MAC
107  *
108  * Returns:     Zero for success, nonzero on faliure.
109  *
110  * Use:         Initializes all the various symmetric things from a KEM.
111  */
112
113 extern int setupkem(kem */*k*/, dstr */*d*/,
114                     gcipher **/*cx*/, gcipher **/*c*/, gmac **/*m*/);
115
116 /* --- @freekem@ --- *
117  *
118  * Arguments:   @kem *k@ = key-encapsulation thing
119  *
120  * Returns:     ---
121  *
122  * Use:         Frees up a key-encapsulation thing.
123  */
124
125 extern void freekem(kem */*k*/);
126
127 /* --- Signing --- */
128
129 typedef struct sig {
130   const struct sigops *ops;
131   key_packdef *kp;
132   void *kd;
133   const gchash *ch;
134   ghash *h;
135 } sig;
136
137 typedef struct sigops {
138   const key_fetchdef *kf;               /* Key fetching structure */
139   size_t kdsz;                          /* Size of the key-data structure */
140   sig *(*init)(key */*k*/, void */*kd*/, const gchash */*hc*/);
141   int (*doit)(sig */*s*/, dstr */*d*/);
142   const char *(*check)(sig */*s*/);
143   void (*destroy)(sig */*s*/);
144 } sigops;
145
146 struct sigtab {
147   const char *name;
148   const sigops *signops;
149   const sigops *verifyops;
150   const gchash *ch;
151 };
152
153 extern const struct sigtab sigtab[];
154
155 /* --- @getsig@ --- *
156  *
157  * Arguments:   @key *k@ = the key to load
158  *              @const char *app@ = application name
159  *              @int wantpriv@ = nonzero if we want to sign
160  *
161  * Returns:     A signature-making thing.
162  *
163  * Use:         Loads a key and starts hashing.
164  */
165
166 extern sig *getsig(key */*k*/, const char */*app*/, int /*wantpriv*/);
167
168 /* --- @freesig@ --- *
169  *
170  * Arguments:   @sig *s@ = signature-making thing
171  *
172  * Returns:     ---
173  *
174  * Use:         Frees up a signature-making thing
175  */
176
177 extern void freesig(sig */*s*/);
178
179 /*----- File encodings ----------------------------------------------------*/
180
181 /* --- Data encoding --- */
182
183 typedef struct enc {
184   const struct encops *ops;
185   FILE *fp;
186 } enc;
187
188 typedef struct encops {
189   const char *name;
190   const char *rmode, *wmode;
191   int nraw, ncook;
192   enc *(*initenc)(FILE */*fp*/, const char */*msg*/);
193   enc *(*initdec)(FILE */*fp*/,
194                   int (*/*func*/)(const char *, void *), void */*p*/);
195   int (*read)(enc */*e*/, void */*p*/, size_t /*sz*/);
196   int (*write)(enc */*e*/, const void */*p*/, size_t /*sz*/);
197   int (*encdone)(enc */*e*/);
198   int (*decdone)(enc */*e*/);
199   void (*destroy)(enc */*e*/);
200 } encops;
201
202 extern const encops enctab[];
203
204 /* --- @getenc@ --- *
205  *
206  * Arguments:   @const char *enc@ = name of wanted encoding
207  *
208  * Returns:     Pointer to encoder operations.
209  *
210  * Use:         Finds a named encoder or decoder.
211  */
212
213 extern const encops *getenc(const char */*enc*/);
214
215 /* --- @checkbdry@ --- *
216  *
217  * Arguments:   @const char *b@ = boundary string found
218  *              @void *p@ = boundary string wanted
219  *
220  * Returns:     Nonzero if the boundary string is the one we wanted.
221  *
222  * Use:         Pass as @func@ to @initdec@ if you just want a simple life.
223  */
224
225 extern int checkbdry(const char */*b*/, void */*p*/);
226
227 /* --- @initenc@ --- *
228  *
229  * Arguments:   @const encops *eo@ = operations (from @getenc@)
230  *              @FILE *fp@ = file handle to attach
231  *              @const char *msg@ = banner message
232  *
233  * Returns:     The encoder object.
234  *
235  * Use:         Initializes an encoder.
236  */
237
238 extern enc *initenc(const encops */*eo*/, FILE */*fp*/, const char */*msg*/);
239
240 /* --- @initdec@ --- *
241  *
242  * Arguments:   @const encops *eo@ = operations (from @getenc@)
243  *              @FILE *fp@ = file handle to attach
244  *              @int (*func)(const char *, void *)@ = banner check function
245  *              @void *p@ = argument for @func@
246  *
247  * Returns:     The encoder object.
248  *
249  * Use:         Initializes an encoder.
250  */
251
252 extern enc *initdec(const encops */*eo*/, FILE */*fp*/,
253                     int (*/*func*/)(const char *, void *), void */*p*/);
254
255 /* --- @freeenc@ --- *
256  *
257  * Arguments:   @enc *e@ = encoder object
258  *
259  * Returns:     ---
260  *
261  * Use:         Frees an encoder object.
262  */
263
264 extern void freeenc(enc */*e*/);
265
266 /* --- @cmd_encode@, @cmd_decode@ --- */
267
268 #define CMD_ENCODE {                                                    \
269   "encode", cmd_encode,                                                 \
270     "encode [-p] [-f FORMAT] [-b LABEL] [-o OUTPUT] [FILE]",            \
271     "\
272 Options:\n\
273 \n\
274 -f, --format=FORMAT     Encode to FORMAT.\n\
275 -b, --boundary=LABEL    PEM boundary is LABEL.\n\
276 -o, --output=FILE       Write output to FILE.\n\
277 -p, --progress          Show progress on large files.\n\
278 " }
279
280 #define CMD_DECODE {                                                    \
281   "decode", cmd_decode,                                                 \
282     "decode [-p] [-f FORMAT] [-b LABEL] [-o OUTPUT] [FILE]",            \
283     "\
284 Options:\n\
285 \n\
286 -f, --format=FORMAT     Decode from FORMAT.\n\
287 -b, --boundary=LABEL    PEM boundary is LABEL.\n\
288 -o, --output=FILE       Write output to FILE.\n\
289 -p, --progress          Show progress on large files.\n\
290 " }
291
292 extern int cmd_encode(int /*argc*/, char */*argv*/[]);
293 extern int cmd_decode(int /*argc*/, char */*argv*/[]);
294
295 /*----- Hash encoding functions -------------------------------------------*/
296
297 /* --- Table --- */
298
299 #define ENCODINGS(_)                                                    \
300   _(HEX, hex)                                                           \
301   _(BASE64, base64)                                                     \
302   _(BASE32, base32)
303
304 enum {
305 #define ENUM(tag, name) ENC_##tag,
306   ENCODINGS(ENUM)
307 #undef ENUM
308   ENC_LIMIT
309 };
310
311 typedef struct encodeops {
312   const char *name;
313   void (*put)(const octet *, size_t, FILE *);
314   size_t (*get)(const char *, octet *, size_t, char **);
315 } encodeops;
316
317 extern const encodeops encodingtab[];
318
319 /* --- @getencoding@ --- *
320  *
321  * Arguments:   @const char *ename@ = encoding name
322  *
323  * Returns:     Pointer to encoding table entry, or null.
324  *
325  * Use:         Finds an encoding entry given its name.
326  */
327
328 extern const encodeops *getencoding(const char */*ename*/);
329
330 /*----- File hashing ------------------------------------------------------*/
331
332 typedef struct fhashstate {
333   const gchash *gch;
334   unsigned f;
335   struct fhent *ents;
336 } fhashstate;
337
338 #define FHF_BINARY 0x100u
339 #define FHF_PROGRESS 0x200u
340 #define FHF_JUNK 0x400u
341
342 #define FHF_MASK 0xff00u
343
344 /* --- @gethash@ --- *
345  *
346  * Arguments:   @const char *name@ = pointer to name string
347  *
348  * Returns:     Pointer to appropriate hash class.
349  *
350  * Use:         Chooses a hash function by name.
351  */
352
353 extern const gchash *gethash(const char */*name*/);
354
355 /* --- @describefile@ --- *
356  *
357  * Arguments:   @const struct stat *st@ = pointer to file state
358  *
359  * Returns:     A snappy one-word description of the file.
360  */
361
362 extern const char *describefile(const struct stat */*st*/);
363
364 /* --- @fhash_init@ ---*
365  *
366  * Arguments:   @fhashstate *fh@ = pointer to fhash state to initialize
367  *              @const gchash *gch@ = hash class to set
368  *              @unsigned f@ initial flags to set
369  *
370  * Returns:     ---
371  *
372  * Use:         Initializes an @fhashstate@ structure.
373  */
374
375 extern void fhash_init(fhashstate */*fh*/,
376                        const gchash */*gch*/, unsigned /*f*/);
377
378 /* --- @fhash_free@ --- *
379  *
380  * Arguments:   @fhashstate *fh@ = pointer to fhash state to free
381  *
382  * Returns:     ---
383  *
384  * Use:         Frees an fhash state.
385  */
386
387 extern void fhash_free(fhashstate */*fh*/);
388
389 /* --- @fhash@ --- *
390  *
391  * Arguments:   @fhashstate *fh@ = pointer to fhash state
392  *              @const char *file@ = file name to be hashed (null for stdin)
393  *              @void *buf@ = pointer to hash output buffer
394  *
395  * Returns:     Zero if it worked, nonzero on error.
396  *
397  * Use:         Hashes a file.
398  */
399
400 extern int fhash(fhashstate */*fh*/, const char */*file*/, void */*buf*/);
401
402 /* --- @fhash_junk@ --- *
403  *
404  * Arguments:   @fhashstate *fh@ = pointer to fhash state
405  *              @void (*func)(const char *, const struct stat *, void *)@
406  *              @void *p@ = pointer to pass to function
407  *
408  * Returns:     Positive if any junk was found, negative on error, zero if
409  *              everything was fine.
410  *
411  * Use:         Reports junk files in any directories covered by the hash
412  *              state.
413  */
414
415 extern int fhash_junk(fhashstate */*fh*/,
416                       int (*/*func*/)(const char *,
417                                       const struct stat *,
418                                       void *),
419                       void */*p*/);
420
421 /* --- @hfparse@ --- *
422  *
423  * Arguments:   @hfpctx *hfp@ = pointer to the context structure
424  *
425  * Returns:     A code indicating what happened.
426  *
427  * Use:         Parses a line from the input file.
428  */
429
430 enum {                                  /* Meaning and members set */
431   HF_FILE,                              /* File hash: @dline@ and @hbuf@ */
432   HF_ENC,                               /* Encoding: @ee@ */
433   HF_HASH,                              /* Hash function: @gch@ */
434   HF_ESC,                               /* Name escape: @f@ */
435   HF_EOF,                               /* End of file */
436   HF_BAD                                /* Unrecognized line */
437 };
438
439 typedef struct hfpctx {
440   unsigned f;                           /* Flags to read */
441 #define HFF_ESCAPE 1u                   /*   File names are escaped */
442   FILE *fp;                             /* Input file to read */
443   dstr *dline;                          /* Line contents, corrupted */
444   const gchash *gch;                    /* Hash function to use */
445   const encodeops *ee;                  /* Encoding to apply to hashes */
446   dstr *dfile;                          /* File name for @HF_FILE@ lines */
447   octet *hbuf;                          /* Output buffer for hash data */
448 } hfpctx;
449
450 extern int hfparse(hfpctx */*hfp*/);
451
452 /*----- String I/O --------------------------------------------------------*/
453
454 #define GSF_RAW 4096u
455 #define GSF_FILE 0u
456 #define GSF_STRING 8192u
457
458 #define GSF_MASK 61440u
459
460 /* --- @getstring@ --- *
461  *
462  * Arguments:   @void *in@ = input source
463  *              @dstr *d@ = destination string
464  *              @unsigned f@ = input flags
465  *
466  * Returns:     Zero if OK, nonzero on end-of-file.
467  *
468  * Use:         Reads a filename (or something similar) from a stream.
469  */
470
471 extern int getstring(void */*in*/, dstr */*d*/, unsigned /*f*/);
472
473 /* --- @putstring@ --- *
474  *
475  * Arguments:   @FILE *fp@ = stream to write on
476  *              @const char *p@ = pointer to text
477  *              @unsigned f@ = output flags
478  *
479  * Returns:     ---
480  *
481  * Use:         Emits a string to a stream.
482  */
483
484 extern void putstring(FILE */*fp*/, const char */*p*/, unsigned /*f*/);
485
486 /*----- Lists of things ---------------------------------------------------*/
487
488 /* --- @LIST(STRING, FP, END-TEST, NAME-EXPR)@ --- *
489  *
490  * Produce list of things.  Requires @i@ and @w@ variables in scope.
491  * END-TEST and NAME-EXPR are in terms of @i@.
492  */
493
494 #define LIST(what, fp, end, name) do {                                  \
495   fputs(what ":\n  ", fp);                                              \
496   w = 2;                                                                \
497   for (i = 0; end; i++) {                                               \
498     if (w == 2)                                                         \
499       w += strlen(name);                                                \
500     else {                                                              \
501       if (strlen(name) + w > 76) {                                      \
502         fputs("\n  ", fp);                                              \
503         w = 2 + strlen(name);                                           \
504       } else {                                                          \
505         fputc(' ', fp);                                                 \
506         w += strlen(name) + 1;                                          \
507       }                                                                 \
508     }                                                                   \
509     fputs(name, fp);                                                    \
510   }                                                                     \
511   fputc('\n', fp);                                                      \
512 } while (0)
513
514 #define STDLISTS(LI)                                                    \
515   LI("Hash functions", hash,                                            \
516      ghashtab[i], ghashtab[i]->name)                                    \
517   LI("Encryption schemes", enc,                                         \
518      gciphertab[i], gciphertab[i]->name)                                \
519   LI("Message authentication schemes", mac,                             \
520      gmactab[i], gmactab[i]->name)                                      \
521   LI("Elliptic curves", ec,                                             \
522      ectab[i].name, ectab[i].name)                                      \
523   LI("Diffie-Hellman groups", dh,                                       \
524      ptab[i].name, ptab[i].name)
525
526 #define LIDECL(text, tag, test, name)                                   \
527   static void show_##tag(void);
528
529 #define LIDEF(text, tag, test, name)                                    \
530   static void show_##tag(void)                                          \
531   {                                                                     \
532     unsigned i, w;                                                      \
533     LIST(text, stdout, test, name);                                     \
534   }
535
536 #define LIENT(text, tag, test, name)                                    \
537   { #tag, show_##tag },
538
539 struct listent {
540   const char *name;
541   void (*list)(void);
542 };
543
544 #define MAKELISTTAB(listtab, LISTS)                                     \
545   LISTS(LIDECL)                                                         \
546   static const struct listent listtab[] = {                             \
547     LISTS(LIENT)                                                        \
548     { 0, 0 }                                                            \
549   };                                                                    \
550   LISTS(LIDEF)
551
552 extern int displaylists(const struct listent */*listtab*/,
553                         char *const /*argv*/[]);
554
555 /*----- Progress indicators -----------------------------------------------*/
556
557 typedef struct fprogress {
558   const char *bp;
559   off_t o, sz, olast;
560   time_t start, last;
561   char name[24];
562 } fprogress;
563
564 /* --- @fprogress_init@ --- *
565  *
566  * Arguments:   @fprogress *f@ = progress context to be initialized
567  *              @const char *name@ = file name string to show
568  *              @FILE *fp@ = file we're reading from
569  *
570  * Returns:     Zero on success, nonzero if the file's state is now broken.
571  *
572  * Use:         Initializes a progress context.  Nothing is actually
573  *              displayed yet.
574  */
575
576 extern int fprogress_init(fprogress */*f*/,
577                           const char */*name*/, FILE */*fp*/);
578
579 /* --- @fprogress_update@ --- *
580  *
581  * Arguments:   @fprogress *f@ = progress context
582  *              @size_t n@ = how much progress has been made
583  *
584  * Returns:     ---
585  *
586  * Use:         Maybe updates the display to show that some progress has been
587  *              made.
588  */
589
590 extern void fprogress_update(fprogress */*f*/, size_t /*n*/);
591
592 /* --- @fprogress_clear@ --- *
593  *
594  * Arguments:   @fprogress *f@ = progress context
595  *
596  * Returns:     ---
597  *
598  * Use:         Clears the progress display from the screen.
599  */
600
601 extern void fprogress_clear(fprogress */*f*/);
602
603 /* --- @fprogress_done@ --- *
604  *
605  * Arguments:   @fprogress *f@ = progress context
606  *
607  * Returns:     ---
608  *
609  * Use:         Clear up the progress context and removes any display.
610  */
611
612 extern void fprogress_done(fprogress */*f*/);
613
614 /*----- Subcommand dispatch -----------------------------------------------*/
615
616 typedef struct cmd {
617   const char *name;
618   int (*cmd)(int /*argc*/, char */*argv*/[]);
619   const char *usage;
620   const char *help;
621 } cmd;
622
623 extern void version(FILE */*fp*/);
624 extern void help_global(FILE */*fp*/);
625
626 /* --- @findcmd@ --- *
627  *
628  * Arguments:   @const cmd *cmds@ = pointer to command table
629  *              @const char *name@ = a command name
630  *
631  * Returns:     Pointer to the command structure.
632  *
633  * Use:         Looks up a command by name.  If the command isn't found, an
634  *              error is reported and the program is terminated.
635  */
636
637 const cmd *findcmd(const cmd */*cmds*/, const char */*name*/);
638
639 /* --- @sc_help@ --- *
640  *
641  * Arguments:   @const cmd *cmds@ = pointer to command table
642  *              @FILE *fp@ = output file handle
643  *              @char *const *argv@ = remaining arguments
644  *
645  * Returns:     ---
646  *
647  * Use:         Prints a help message, maybe with help about subcommands.
648  */
649
650 extern void sc_help(const cmd */*cmds*/, FILE */*fp*/,
651                     char *const */*argv*/);
652
653 /*----- That's all, folks -------------------------------------------------*/
654
655 #ifdef __cplusplus
656   }
657 #endif
658
659 #endif