chiark / gitweb /
Add some more vectors, and a whinge about how Skipjack test vectors are.
[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 -------------------------------------------------*/