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