chiark / gitweb /
Add some more vectors, and a whinge about how Skipjack test vectors are.
[catacomb] / key-flags.c
1 /* -*-c-*-
2  *
3  * $Id: key-flags.c,v 1.2 2000/02/12 18:21:02 mdw Exp $
4  *
5  * Reading and writing key flag strings
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-flags.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 <stdlib.h>
44 #include <string.h>
45
46 #include <mLib/bits.h>
47 #include <mLib/dstr.h>
48
49 #include "key.h"
50
51 /*----- Data structures ---------------------------------------------------*/
52
53 typedef struct key_flags {
54   unsigned f;
55   unsigned m;
56 } key_flags;
57
58 /*----- Flags table -------------------------------------------------------*/
59
60 typedef struct flagent {
61   const char *name;
62   unsigned f;
63   unsigned m;
64 } flagent;
65
66 static flagent flagtab[] = {
67
68   /* --- Encoding types --- */
69
70   { "binary",           KENC_BINARY,    KF_ENCMASK },
71   { "integer",          KENC_MP,        KF_ENCMASK },
72   { "struct",           KENC_STRUCT,    KF_ENCMASK },
73   { "encrypt",          KENC_ENCRYPT,   KF_ENCMASK },
74
75   /* --- Classes of keys --- */
76
77   { "shared",           KCAT_SHARE,     KF_CATMASK },
78   { "public",           KCAT_PUB,       KF_CATMASK },
79   { "private",          KCAT_PRIV,      KF_CATMASK },
80   { "symmetric",        KCAT_SYMM,      KF_CATMASK },
81   { "secret",           0,              KF_NONSECRET },
82   { "-secret",          KF_NONSECRET,   KF_NONSECRET },
83
84   /* --- Other flags --- */
85
86   { "burn",             KF_BURN,        KF_BURN },
87   { "-burn",            0,              KF_BURN },
88
89   /* --- End marker --- */
90
91   { 0,                  0,              0 }
92 };
93
94 /*----- Main code ---------------------------------------------------------*/
95
96 /* --- @key_readflags@ --- *
97  *
98  * Arguments:   @const char *p@ = pointer to string to read
99  *              @char **pp@ = where to store the end pointer
100  *              @unsigned *ff@ = where to store the flags
101  *              @unsigned *mm@ = where to store the mask
102  *
103  * Returns:     Zero if all went well, nonzero if there was an error.
104  *
105  * Use:         Reads a flag string.
106  */
107
108 int key_readflags(const char *p, char **pp, unsigned *ff, unsigned *mm)
109 {
110   unsigned f = 0, m = 0;
111
112   for (;;) {
113     size_t sz = strcspn(p, ",:");
114     flagent *e, *ee = 0;
115
116     /* --- Look up the string in the flags table --- */
117
118     for (e = flagtab; e->name; e++) {
119       if (strncmp(e->name, p, sz) == 0) {
120         if (e->name[sz] == 0) {
121           ee = e;
122           break;
123         } else if (ee)
124           return (KERR_BADFLAGS);
125         else
126           ee = e;
127       }
128     }
129     if (!ee)
130       return (KERR_BADFLAGS);
131
132     /* --- Adjust the flag words --- *
133      *
134      * Ensure that the flags set are disjoint.
135      */
136
137     if (m & ee->m)
138       return (KERR_BADFLAGS);
139     m |= ee->m;
140     f |= ee->f;
141     p += sz;
142     if (*p == 0 || *p == ':')
143       break;
144     p++;
145   }
146
147   /* --- Report the results --- */
148
149   if (ff) *ff = f;
150   if (mm) *mm = m;
151   if (pp) *pp = (char *)p;
152   return (0);
153 }
154
155 /* --- @key_writeflags@ --- *
156  *
157  * Arguments:   @unsigned f@ = flags to write
158  *              @dstr *d@ = pointer to destination string
159  *
160  * Returns:     ---
161  *
162  * Use:         Emits a flags word as a string representation.
163  */
164
165 void key_writeflags(unsigned f, dstr *d)
166 {
167   int del = 0;
168   flagent *e;
169   unsigned m = 0;
170
171   for (e = flagtab; e->name; e++) {
172     if (m & e->m || e->name[0] == '-' || (f & e->m) != e->f)
173       continue;
174     if (del)
175       DPUTC(d, ',');
176     DPUTS(d, e->name);
177     m |= e->m;
178     del = 1;
179   }
180 }
181
182 /* --- @key_match@ --- *
183  *
184  * Arguments:   @key_data *k@ = pointer to key data block
185  *              @const key_filter *kf@ = pointer to filter block
186  *
187  * Returns:     Nonzero if the key matches the filter.
188  *
189  * Use:         Checks whether a key matches a filter.
190  */
191
192 int key_match(key_data *k, const key_filter *kf)
193 {
194   sym_iter i;
195   key_struct *ks;
196
197   if (!kf)
198     return (1);
199   if ((k->e & KF_ENCMASK) != KENC_STRUCT)
200     return ((k->e & kf->m) == kf->f);
201
202   for (sym_mkiter(&i, &k->u.s); (ks = sym_next(&i)) != 0; ) {
203     if (key_match(&ks->k, kf))
204       return (1);
205   }
206   return (0);
207 }
208
209 /*----- That's all, folks -------------------------------------------------*/