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