Make tables of standard encryption schemes etc.
[u/mdw/catacomb] / key-data.c
CommitLineData
d11a0bf7 1/* -*-c-*-
2 *
1ba83484 3 * $Id: key-data.c,v 1.5 2004/03/28 01:58:47 mdw Exp $
d11a0bf7 4 *
5 * Encoding and decoding of key data
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/*----- Revision history --------------------------------------------------*
31 *
32 * $Log: key-data.c,v $
1ba83484 33 * Revision 1.5 2004/03/28 01:58:47 mdw
34 * Generate, store and retreive elliptic curve keys.
35 *
2cc51ff1 36 * Revision 1.4 2000/07/16 19:51:58 mdw
37 * Shut stupid compiler up.
38 *
380a6fdc 39 * Revision 1.3 2000/06/17 11:26:03 mdw
40 * key_structfind: track minor data structure change, and cope if the
41 * subkey isn't available.
42 *
052b36d0 43 * Revision 1.2 2000/02/12 18:21:02 mdw
44 * Overhaul of key management (again).
45 *
d11a0bf7 46 * Revision 1.1 1999/12/22 15:47:48 mdw
47 * Major key-management revision.
48 *
49 */
50
51/*----- Header files ------------------------------------------------------*/
52
53#include <assert.h>
54#include <stdlib.h>
55#include <string.h>
56
d11a0bf7 57#include <mLib/base64.h>
58#include <mLib/bits.h>
59#include <mLib/dstr.h>
60#include <mLib/sub.h>
61#include <mLib/sym.h>
62
052b36d0 63#include "key-data.h"
d11a0bf7 64#include "mp.h"
65#include "mptext.h"
66
d11a0bf7 67/*----- Setting new values ------------------------------------------------*/
68
69/* --- @key_binary@ --- *
70 *
71 * Arguments: @key_data *k@ = pointer to key data block
72 * @const void *p@ = pointer to key data
73 * @size_t sz@ = size of the key data
74 *
75 * Returns: ---
76 *
77 * Use: Sets a binary key in a key data block.
78 */
79
80void key_binary(key_data *k, const void *p, size_t sz)
81{
82 k->e = (k->e & ~KF_ENCMASK) | KENC_BINARY;
83 k->u.k.k = sub_alloc(sz);
84 memcpy(k->u.k.k, p, sz);
85 k->u.k.sz = sz;
86}
87
88/* --- @key_encrypted@ --- *
89 *
90 * Arguments: @key_data *k@ = pointer to key data block
91 * @const void *p@ = pointer to key data
92 * @size_t sz@ = size of the key data
93 *
94 * Returns: ---
95 *
96 * Use: Sets an encrypted key in a key data block.
97 */
98
99void key_encrypted(key_data *k, const void *p, size_t sz)
100{
101 k->e = (k->e & ~KF_ENCMASK) | KENC_ENCRYPT;
102 k->u.k.k = sub_alloc(sz);
103 memcpy(k->u.k.k, p, sz);
104 k->u.k.sz = sz;
105}
106
107/* --- @key_mp@ --- *
108 *
109 * Arguments: @key_data *k@ = pointer to key data block
110 * @mp *m@ = pointer to the value to set
111 *
112 * Returns: ---
113 *
114 * Use: Sets a multiprecision integer key in a key block.
115 */
116
117void key_mp(key_data *k, mp *m)
118{
119 k->e = (k->e & ~KF_ENCMASK) | KENC_MP;
120 k->u.m = MP_COPY(m);
121}
122
1ba83484 123/* --- @key_string@ --- *
124 *
125 * Arguments: @key_data *k@ = pointer to key data block
126 * @const char *p@ = pointer to the value to set
127 *
128 * Returns: ---
129 *
130 * Use: Sets a plain string in a key block.
131 */
132
133void key_string(key_data *k, const char *p)
134{
135 k->e = (k->e & ~KF_ENCMASK) | KENC_STRING;
136 k->u.p = xstrdup(p);
137}
138
139/* --- @key_ec@ --- *
140 *
141 * Arguments: @key_data *k@ = pointer to key data block
142 * @const ec *e@ = pointer to the value to set
143 *
144 * Returns: ---
145 *
146 * Use: Sets an elliptic curve point in a key block.
147 */
148
149void key_ec(key_data *k, const ec *e)
150{
151 k->e = (k->e & ~KF_ENCMASK) | KENC_EC;
152 EC_CREATE(&k->u.e);
153 EC_COPY(&k->u.e, e);
154}
155
d11a0bf7 156/* --- @key_structure@ --- *
157 *
158 * Arguments: @key_data *k@ = pointer to key data block
159 *
160 * Returns: ---
161 *
162 * Use: Initializes a structured key type.
163 */
164
165void key_structure(key_data *k)
166{
167 k->e = KENC_STRUCT;
168 sym_create(&k->u.s);
169}
170
171/* --- @key_structfind@ --- *
172 *
173 * Arguments: @key_data *k@ = pointer to key data block
174 * @const char *tag@ = pointer to tag string
175 *
176 * Returns: Pointer to key data block, or null.
177 *
178 * Use: Looks up the tag in a structured key.
179 */
180
181key_data *key_structfind(key_data *k, const char *tag)
182{
183 key_struct *ks;
380a6fdc 184 assert(((void)"Key is not structured",
185 (k->e & KF_ENCMASK) == KENC_STRUCT));
d11a0bf7 186 ks = sym_find(&k->u.s, tag, -1, 0, 0);
380a6fdc 187 if (!ks)
188 return (0);
d11a0bf7 189 return (&ks->k);
190}
191
192/* --- @key_structcreate@ --- *
193 *
194 * Arguments: @key_data *k@ = pointer to key data block
195 * @const char *tag@ = pointer to tag string
196 *
197 * Returns: Pointer to newly created key data.
198 *
199 * Use: Creates a new uninitialized subkey.
200 */
201
202key_data *key_structcreate(key_data *k, const char *tag)
203{
204 key_struct *ks;
205 unsigned f;
206
207 assert(((void)"Key is not structured", k->e == KENC_STRUCT));
208 ks = sym_find(&k->u.s, tag, -1, sizeof(*ks), &f);
209 if (f)
210 key_destroy(&ks->k);
052b36d0 211 ks->k.e = KF_TEMP;
d11a0bf7 212 return (&ks->k);
213}
214
052b36d0 215/*----- Miscellaneous operations ------------------------------------------*/
216
217/* --- @key_destroy@ --- *
d11a0bf7 218 *
052b36d0 219 * Arguments: @key_data *k@ = pointer to key data to destroy
d11a0bf7 220 *
052b36d0 221 * Returns: ---
d11a0bf7 222 *
052b36d0 223 * Use: Destroys a lump of key data.
d11a0bf7 224 */
225
052b36d0 226void key_destroy(key_data *k)
d11a0bf7 227{
052b36d0 228 switch (k->e & KF_ENCMASK) {
229 case KENC_BINARY:
230 case KENC_ENCRYPT:
231 if (k->e & KF_BURN)
232 memset(k->u.k.k, 0, k->u.k.sz);
233 sub_free(k->u.k.k, k->u.k.sz);
234 break;
235 case KENC_MP:
236 mp_drop(k->u.m);
237 break;
1ba83484 238 case KENC_STRING:
239 xfree(k->u.p);
240 break;
241 case KENC_EC:
242 EC_DESTROY(&k->u.e);
243 break;
052b36d0 244 case KENC_STRUCT: {
245 sym_iter i;
246 key_struct *ks;
d11a0bf7 247
052b36d0 248 for (sym_mkiter(&i, &k->u.s); (ks = sym_next(&i)) != 0; ) {
249 if (!(ks->k.e & KF_TEMP))
250 key_destroy(&ks->k);
251 }
252 sym_destroy(&k->u.s);
253 } break;
d11a0bf7 254 }
d11a0bf7 255}
256
257/* --- @key_do@ --- *
258 *
259 * Arguments: @key_data *k@ = pointer to key data block
260 * @const key_filter *kf@ = pointer to filter block
261 * @dstr *d@ = pointer to base string
262 * @int (*func)(key_data *kd, dstr *d, void *p@ = function
263 * @void *p@ = argument to function
264 *
265 * Returns: Nonzero return code from function, or zero.
266 *
267 * Use: Runs a function over all the leaves of a key.
268 */
269
270int key_do(key_data *k, const key_filter *kf, dstr *d,
271 int (*func)(key_data */*kd*/, dstr */*d*/, void */*p*/),
272 void *p)
273{
274 if (!KEY_MATCH(k, kf))
275 return (0);
276 if ((k->e & KF_ENCMASK) != KENC_STRUCT)
277 return (func(k, d, p));
278 else {
279 sym_iter i;
280 key_struct *ks;
2cc51ff1 281 size_t n = 0;
d11a0bf7 282 int rc;
283
284 if (d)
285 n = d->len;
286 for (sym_mkiter(&i, &k->u.s); (ks = sym_next(&i)) != 0; ) {
287 if (d) {
288 d->len = n;
289 dstr_putf(d, ".%s", SYM_NAME(ks));
290 }
291 if ((rc = key_do(&ks->k, kf, d, func, p)) != 0)
292 return (rc);
293 }
294 return (0);
295 }
296}
297
d11a0bf7 298/* --- @key_copy@ --- *
299 *
300 * Arguments: @key_data *kd@ = pointer to destination data block
301 * @key_data *k@ = pointer to source data block
302 * @const key_filter *kf@ = pointer to filter block
303 *
304 * Returns: Nonzero if an item was actually copied.
305 *
306 * Use: Copies a chunk of key data from one place to another.
307 */
308
309int key_copy(key_data *kd, key_data *k, const key_filter *kf)
310{
311 kd->e = k->e;
312
313 if (!KEY_MATCH(kd, kf))
314 return (0);
315 switch (k->e & KF_ENCMASK) {
316
317 /* --- Plain binary data --- */
318
319 case KENC_BINARY:
320 case KENC_ENCRYPT:
321 kd->u.k.k = sub_alloc(k->u.k.sz);
322 memcpy(kd->u.k.k, k->u.k.k, k->u.k.sz);
323 kd->u.k.sz = k->u.k.sz;
324 break;
325
326 /* --- Multiprecision integers --- */
327
328 case KENC_MP:
329 kd->u.m = MP_COPY(k->u.m);
330 break;
331
1ba83484 332 /* --- Strings --- */
333
334 case KENC_STRING:
335 kd->u.p = xstrdup(k->u.p);
336 break;
337
338 /* --- Elliptic curve points --- */
339
340 case KENC_EC:
341 EC_CREATE(&kd->u.e);
342 EC_COPY(&kd->u.e, &k->u.e);
343 break;
344
d11a0bf7 345 /* --- Structured key data --- */
346
347 case KENC_STRUCT: {
348 sym_iter i;
349 key_struct *ks;
350 int rc = 0;
351
352 sym_create(&kd->u.s);
353 for (sym_mkiter(&i, &k->u.s); (ks = sym_next(&i)) != 0; ) {
354 unsigned f;
355 key_struct *kks = sym_find(&kd->u.s, SYM_NAME(ks), -1,
356 sizeof(*kks), &f);
357 assert(((void)"Duplicate subkey tags", !f));
358 if (key_copy(&kks->k, &ks->k, kf))
359 rc = 1;
360 else
361 sym_remove(&kd->u.s, kks);
362 }
363 if (!rc) {
364 sym_destroy(&kd->u.s);
365 return (0);
366 }
367 } break;
368 }
369 return (1);
370}
371
d11a0bf7 372/*----- That's all, folks -------------------------------------------------*/