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