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