db98e37e0455c7922ca45a1fd63ef1be7484feb0
[tripe] / server / test.c
1 /* -*-c-*-
2 *
3 * Various unit-level tests
4 *
5 * (c) 2017 Straylight/Edgeware
6 */
7
8 /*----- Licensing notice --------------------------------------------------*
9 *
10 * This file is part of Trivial IP Encryption (TrIPE).
11 *
12 * TrIPE is free software: you can redistribute it and/or modify it under
13 * the terms of the GNU General Public License as published by the Free
14 * Software Foundation; either version 3 of the License, or (at your
15 * option) any later version.
16 *
17 * TrIPE is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with TrIPE. If not, see <https://www.gnu.org/licenses/>.
24 */
25
26 /*----- Header files ------------------------------------------------------*/
27
28 #include "tripe.h"
29
30 /*----- Data structures ---------------------------------------------------*/
31
32 /*----- Global variables --------------------------------------------------*/
33
34 sel_state sel;
35
36 /*----- Static variables --------------------------------------------------*/
37
38 static char **args;
39
40 /*----- Main code ---------------------------------------------------------*/
41
42 static void usage(FILE *fp)
43 {
44 pquis(fp,
45 "Usage: $ [-k FILE] [-t KEYTAG] [-T TRACE-OPTS] COMMAND [ARGS...]\n");
46 }
47
48 static void version(FILE *fp)
49 { pquis(fp, "$, TrIPE version " VERSION "\n"); }
50
51 static void help(FILE *fp)
52 {
53 version(fp); fputc('\n', fp);
54 usage(fp); fputc('\n', fp);
55 fputs("\
56 Options in full:\n\
57 \n\
58 -h, --help Show this help text.\n\
59 -v, --version Show version number.\n\
60 -u, --usage Show brief usage message.\n\
61 \n\
62 -k, --keyring=FILE Get keys from FILE.\n\
63 -t, --tag=KEYTAG Use KEYTAG as master private key.\n\
64 -T, --trace=TRACE-OPTS Turn on tracing options.\n\
65 \n\
66 Commands:\n\
67 \n\
68 ies-encrypt TY MESSAGE\n\
69 ies-decrypt TY CIPHERTEXT\n\
70 ", fp);
71 }
72
73 static uint32 parseu32(const char *p)
74 {
75 int e = errno;
76 unsigned long i;
77 char *q;
78
79 errno = 0;
80 i = strtoul(p, &q, 0);
81 while (*q && isspace((unsigned char)*q)) q++;
82 if (errno || *q || i > 0xffffffffu) die(2, "bad 32-bit integer `%s'", p);
83 errno = e;
84 return (i);
85 }
86
87 static const char *getarg(void)
88 { if (!*args) die(2, "missing argument"); else return (*args++); }
89
90 static void lastarg(void)
91 { if (*args) die(2, "unexpected argument `%s'", *args); }
92
93 void iv_addreason(void) { ; }
94 void iv_rmreason(void) { ; }
95
96 void lp_end(void) { ; }
97
98 int main(int argc, char *argv[])
99 {
100 const char *kr = "keyring";
101 const char *tag = "tripe";
102 const char *arg;
103 codec *b64;
104 int i, err;
105 uint32 ty;
106 buf b, bb;
107 dstr d = DSTR_INIT;
108 unsigned f = 0;
109 #define f_bogus 1u
110
111 ego(argv[0]);
112 for (;;) {
113 static const struct option opts[] = {
114 { "help", 0, 0, 'h' },
115 { "version", 0, 0, 'v' },
116 { "usage", 0, 0, 'u' },
117 { "keyring", OPTF_ARGREQ, 0, 'k' },
118 { "tag", OPTF_ARGREQ, 0, 't' },
119 { "trace", OPTF_ARGREQ, 0, 'T' },
120 { 0, 0, 0, 0 }
121 };
122
123 i = mdwopt(argc, argv, "hvuk:t:T:", opts, 0, 0, 0); if (i < 0) break;
124 switch (i) {
125 case 'h': help(stdout); exit(0);
126 case 'v': version(stdout); exit(0);
127 case 'u': usage(stdout); exit(0);
128 case 'k': kr = optarg; break;
129 case 't': tag = optarg; break;
130 case 'T':
131 tr_flags = traceopt(tr_opts, optarg, tr_flags, 0);
132 break;
133 default: f |= f_bogus; break;
134 }
135 }
136 if (f&f_bogus) { usage(stderr); exit(2); }
137 args = argv + optind;
138
139 km_init(kr, kr, tag);
140 trace_on(stderr, tr_flags);
141
142 arg = getarg();
143 if (strcmp(arg, "ies-encrypt") == 0) {
144 arg = getarg(); ty = parseu32(arg);
145 arg = getarg(); buf_init(&b, (/*unconst*/ octet *)arg, strlen(arg));
146 buf_init(&bb, buf_t, sizeof(buf_t));
147 lastarg();
148 if ((err = ies_encrypt(master, ty, &b, &bb)) != 0)
149 die(3, "ies_encrypt failed: err = %d", err);
150 b64 = base64_class.encoder(0, "\n", 72);
151 if ((err = b64->ops->code(b64, BBASE(&bb), BLEN(&bb), &d)) != 0 ||
152 (err = b64->ops->code(b64, 0, 0, &d)) != 0)
153 die(3, "base64 encoding failed: %s", codec_strerror(err));
154 b64->ops->destroy(b64);
155 DPUTC(&d, '\n');
156 fwrite(d.buf, 1, d.len, stdout);
157 dstr_destroy(&d);
158 } else if (strcmp(arg, "ies-decrypt") == 0) {
159 arg = getarg(); ty = parseu32(arg);
160 arg = getarg();
161 b64 = base64_class.decoder(CDCF_IGNSPC | CDCF_IGNNEWL);
162 if ((err = b64->ops->code(b64, arg, strlen(arg), &d)) != 0 ||
163 (err = b64->ops->code(b64, 0, 0, &d)) != 0)
164 die(3, "base64 decoding failed: %s", codec_strerror(err));
165 b64->ops->destroy(b64);
166 lastarg();
167 buf_init(&b, d.buf, d.len); buf_init(&bb, buf_t, sizeof(buf_t));
168 if ((err = ies_decrypt(master, ty, &b, &bb)) != 0)
169 die(3, "ies_decrypt failed: err = %d", err);
170 fwrite(BBASE(&bb), 1, BLEN(&bb), stdout);
171 dstr_destroy(&d);
172 } else
173 die(2, "unknown command `%s'", arg);
174
175 return (0);
176 }
177
178 /*----- That's all, folks -------------------------------------------------*/