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