Update manuals.
[u/mdw/catacomb] / key-data.c
1 /* -*-c-*-
2 *
3 * $Id: key-data.c,v 1.5 2004/03/28 01:58:47 mdw Exp $
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 $
33 * Revision 1.5 2004/03/28 01:58:47 mdw
34 * Generate, store and retreive elliptic curve keys.
35 *
36 * Revision 1.4 2000/07/16 19:51:58 mdw
37 * Shut stupid compiler up.
38 *
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 *
43 * Revision 1.2 2000/02/12 18:21:02 mdw
44 * Overhaul of key management (again).
45 *
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
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
63 #include "key-data.h"
64 #include "mp.h"
65 #include "mptext.h"
66
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
80 void 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
99 void 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
117 void 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
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
133 void 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
149 void 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
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
165 void 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
181 key_data *key_structfind(key_data *k, const char *tag)
182 {
183 key_struct *ks;
184 assert(((void)"Key is not structured",
185 (k->e & KF_ENCMASK) == KENC_STRUCT));
186 ks = sym_find(&k->u.s, tag, -1, 0, 0);
187 if (!ks)
188 return (0);
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
202 key_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);
211 ks->k.e = KF_TEMP;
212 return (&ks->k);
213 }
214
215 /*----- Miscellaneous operations ------------------------------------------*/
216
217 /* --- @key_destroy@ --- *
218 *
219 * Arguments: @key_data *k@ = pointer to key data to destroy
220 *
221 * Returns: ---
222 *
223 * Use: Destroys a lump of key data.
224 */
225
226 void key_destroy(key_data *k)
227 {
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;
238 case KENC_STRING:
239 xfree(k->u.p);
240 break;
241 case KENC_EC:
242 EC_DESTROY(&k->u.e);
243 break;
244 case KENC_STRUCT: {
245 sym_iter i;
246 key_struct *ks;
247
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;
254 }
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
270 int 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;
281 size_t n = 0;
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
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
309 int 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
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
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
372 /*----- That's all, folks -------------------------------------------------*/