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