Add an internal-representation no-op function.
[u/mdw/catacomb] / key-data.c
CommitLineData
d11a0bf7 1/* -*-c-*-
2 *
2cc51ff1 3 * $Id: key-data.c,v 1.4 2000/07/16 19:51:58 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
30/*----- Revision history --------------------------------------------------*
31 *
32 * $Log: key-data.c,v $
2cc51ff1 33 * Revision 1.4 2000/07/16 19:51:58 mdw
34 * Shut stupid compiler up.
35 *
380a6fdc 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 *
052b36d0 40 * Revision 1.2 2000/02/12 18:21:02 mdw
41 * Overhaul of key management (again).
42 *
d11a0bf7 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
d11a0bf7 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
052b36d0 60#include "key-data.h"
d11a0bf7 61#include "mp.h"
62#include "mptext.h"
63
d11a0bf7 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
77void 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
96void 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
114void 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
129void 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
145key_data *key_structfind(key_data *k, const char *tag)
146{
147 key_struct *ks;
380a6fdc 148 assert(((void)"Key is not structured",
149 (k->e & KF_ENCMASK) == KENC_STRUCT));
d11a0bf7 150 ks = sym_find(&k->u.s, tag, -1, 0, 0);
380a6fdc 151 if (!ks)
152 return (0);
d11a0bf7 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
166key_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);
052b36d0 175 ks->k.e = KF_TEMP;
d11a0bf7 176 return (&ks->k);
177}
178
052b36d0 179/*----- Miscellaneous operations ------------------------------------------*/
180
181/* --- @key_destroy@ --- *
d11a0bf7 182 *
052b36d0 183 * Arguments: @key_data *k@ = pointer to key data to destroy
d11a0bf7 184 *
052b36d0 185 * Returns: ---
d11a0bf7 186 *
052b36d0 187 * Use: Destroys a lump of key data.
d11a0bf7 188 */
189
052b36d0 190void key_destroy(key_data *k)
d11a0bf7 191{
052b36d0 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;
d11a0bf7 205
052b36d0 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;
d11a0bf7 212 }
d11a0bf7 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
228int 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;
2cc51ff1 239 size_t n = 0;
d11a0bf7 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
d11a0bf7 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
267int 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
d11a0bf7 317/*----- That's all, folks -------------------------------------------------*/