chiark / gitweb /
server/keymgmt.c: Track and find keys by their 32-bit IDs.
[tripe] / server / test.c
CommitLineData
19220671
MW
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
34sel_state sel;
35
36/*----- Static variables --------------------------------------------------*/
37
38static char **args;
39
40/*----- Main code ---------------------------------------------------------*/
41
42static void usage(FILE *fp)
43{
44 pquis(fp,
45"Usage: $ [-k FILE] [-t KEYTAG] [-T TRACE-OPTS] COMMAND [ARGS...]\n");
46}
47
48static void version(FILE *fp)
49 { pquis(fp, "$, TrIPE version " VERSION "\n"); }
50
51static void help(FILE *fp)
52{
53 version(fp); fputc('\n', fp);
54 usage(fp); fputc('\n', fp);
55 fputs("\
56Options 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\
66Commands:\n\
67\n\
68ies-encrypt TY MESSAGE\n\
69ies-decrypt TY CIPHERTEXT\n\
70", fp);
71}
72
73static 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
87static const char *getarg(void)
88 { if (!*args) die(2, "missing argument"); else return (*args++); }
89
90static void lastarg(void)
91 { if (*args) die(2, "unexpected argument `%s'", *args); }
92
93int main(int argc, char *argv[])
94{
95 const char *kr = "keyring";
96 const char *tag = "tripe";
97 const char *arg;
98 codec *b64;
99 int i, err;
100 uint32 ty;
101 buf b, bb;
102 dstr d = DSTR_INIT;
103 unsigned f = 0;
104#define f_bogus 1u
105
106 ego(argv[0]);
107 for (;;) {
108 static const struct option opts[] = {
109 { "help", 0, 0, 'h' },
110 { "version", 0, 0, 'v' },
111 { "usage", 0, 0, 'u' },
112 { "keyring", OPTF_ARGREQ, 0, 'k' },
113 { "tag", OPTF_ARGREQ, 0, 't' },
114 { "trace", OPTF_ARGREQ, 0, 'T' },
115 { 0, 0, 0, 0 }
116 };
117
118 i = mdwopt(argc, argv, "hvuk:t:T:", opts, 0, 0, 0); if (i < 0) break;
119 switch (i) {
120 case 'h': help(stdout); exit(0);
121 case 'v': version(stdout); exit(0);
122 case 'u': usage(stdout); exit(0);
123 case 'k': kr = optarg; break;
124 case 't': tag = optarg; break;
125 case 'T':
126 tr_flags = traceopt(tr_opts, optarg, tr_flags, 0);
127 break;
128 default: f |= f_bogus; break;
129 }
130 }
131 if (f&f_bogus) { usage(stderr); exit(2); }
132 args = argv + optind;
133
134 km_init(kr, kr, tag);
135 trace_on(stderr, tr_flags);
136
137 arg = getarg();
138 if (strcmp(arg, "ies-encrypt") == 0) {
139 arg = getarg(); ty = parseu32(arg);
140 arg = getarg(); buf_init(&b, (/*unconst*/ octet *)arg, strlen(arg));
141 buf_init(&bb, buf_t, sizeof(buf_t));
142 lastarg();
143 if ((err = ies_encrypt(master, ty, &b, &bb)) != 0)
144 die(3, "ies_encrypt failed: err = %d", err);
145 b64 = base64_class.encoder(0, "\n", 72);
146 if ((err = b64->ops->code(b64, BBASE(&bb), BLEN(&bb), &d)) != 0 ||
147 (err = b64->ops->code(b64, 0, 0, &d)) != 0)
148 die(3, "base64 encoding failed: %s", codec_strerror(err));
149 b64->ops->destroy(b64);
150 DPUTC(&d, '\n');
151 fwrite(d.buf, 1, d.len, stdout);
152 dstr_destroy(&d);
153 } else if (strcmp(arg, "ies-decrypt") == 0) {
154 arg = getarg(); ty = parseu32(arg);
155 arg = getarg();
156 b64 = base64_class.decoder(CDCF_IGNSPC | CDCF_IGNNEWL);
157 if ((err = b64->ops->code(b64, arg, strlen(arg), &d)) != 0 ||
158 (err = b64->ops->code(b64, 0, 0, &d)) != 0)
159 die(3, "base64 decoding failed: %s", codec_strerror(err));
160 b64->ops->destroy(b64);
161 lastarg();
162 buf_init(&b, d.buf, d.len); buf_init(&bb, buf_t, sizeof(buf_t));
163 if ((err = ies_decrypt(master, ty, &b, &bb)) != 0)
164 die(3, "ies_decrypt failed: err = %d", err);
165 fwrite(BBASE(&bb), 1, BLEN(&bb), stdout);
166 dstr_destroy(&d);
167 } else
168 die(2, "unknown command `%s'", arg);
169
170 return (0);
171}
172
173/*----- That's all, folks -------------------------------------------------*/