chiark / gitweb /
rand/rand-x86ish.S: Hoist argument register allocation outside.
[catacomb] / key / key-flags.c
1 /* -*-c-*-
2  *
3  * Reading and writing key flag strings
4  *
5  * (c) 1999 Straylight/Edgeware
6  */
7
8 /*----- Licensing notice --------------------------------------------------*
9  *
10  * This file is part of Catacomb.
11  *
12  * Catacomb is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU Library General Public License as
14  * published by the Free Software Foundation; either version 2 of the
15  * License, or (at your option) any later version.
16  *
17  * Catacomb is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU Library General Public License for more details.
21  *
22  * You should have received a copy of the GNU Library General Public
23  * License along with Catacomb; if not, write to the Free
24  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25  * MA 02111-1307, USA.
26  */
27
28 /*----- Header files ------------------------------------------------------*/
29
30 #include <stdlib.h>
31 #include <string.h>
32
33 #include <mLib/bits.h>
34 #include <mLib/dstr.h>
35 #include <mLib/macros.h>
36
37 #include "key-data.h"
38
39 /*----- Data structures ---------------------------------------------------*/
40
41 typedef struct key_flags {
42   unsigned f;
43   unsigned m;
44 } key_flags;
45
46 /*----- Flags table -------------------------------------------------------*/
47
48 typedef struct flagent {
49   const char *name;
50   unsigned f;
51   unsigned m;
52 } flagent;
53
54 static const flagent flagtab[] = {
55
56   /* --- Encoding types --- */
57
58   { "binary",           KENC_BINARY,    KF_ENCMASK },
59   { "integer",          KENC_MP,        KF_ENCMASK },
60   { "struct",           KENC_STRUCT,    KF_ENCMASK },
61   { "encrypt",          KENC_ENCRYPT,   KF_ENCMASK },
62   { "string",           KENC_STRING,    KF_ENCMASK },
63   { "ec",               KENC_EC,        KF_ENCMASK },
64
65   /* --- Classes of keys --- */
66
67   { "shared",           KCAT_SHARE,     KF_CATMASK },
68   { "public",           KCAT_PUB,       KF_CATMASK },
69   { "private",          KCAT_PRIV,      KF_CATMASK },
70   { "symmetric",        KCAT_SYMM,      KF_CATMASK },
71   { "secret",           0,              KF_NONSECRET },
72   { "-secret",          KF_NONSECRET,   KF_NONSECRET },
73
74   /* --- Other flags --- */
75
76   { "burn",             KF_BURN,        KF_BURN },
77   { "-burn",            0,              KF_BURN },
78
79   /* --- End marker --- */
80
81   { 0,                  0,              0 }
82 };
83
84 /*----- Main code ---------------------------------------------------------*/
85
86 /* --- @key_readflags@ --- *
87  *
88  * Arguments:   @const char *p@ = pointer to string to read
89  *              @char **pp@ = where to store the end pointer
90  *              @unsigned *ff@ = where to store the flags
91  *              @unsigned *mm@ = where to store the mask
92  *
93  * Returns:     Zero if all went well, nonzero if there was an error.
94  *
95  * Use:         Reads a flag string.
96  */
97
98 int key_readflags(const char *p, char **pp, unsigned *ff, unsigned *mm)
99 {
100   unsigned f = 0, m = 0;
101
102   for (;;) {
103     size_t sz = strcspn(p, ",:");
104     const flagent *e, *ee = 0;
105
106     /* --- Look up the string in the flags table --- */
107
108     if (sz == 4 && STRNCMP(p, ==, "none", 4))
109       goto next;
110     for (e = flagtab; e->name; e++) {
111       if (STRNCMP(e->name, ==, p, sz)) {
112         if (e->name[sz] == 0) {
113           ee = e;
114           break;
115         } else if (ee)
116           return (KERR_BADFLAGS);
117         else
118           ee = e;
119       }
120     }
121     if (!ee)
122       return (KERR_BADFLAGS);
123
124     /* --- Adjust the flag words --- *
125      *
126      * Ensure that the flags set are disjoint.
127      */
128
129     if (m & ee->m)
130       return (KERR_BADFLAGS);
131     m |= ee->m;
132     f |= ee->f;
133   next:
134     p += sz;
135     if (*p == 0 || *p == ':')
136       break;
137     p++;
138   }
139
140   /* --- Report the results --- */
141
142   if (ff) *ff = f;
143   if (mm) *mm = m;
144   if (pp) *pp = (char *)p;
145   return (0);
146 }
147
148 /* --- @key_writeflags@ --- *
149  *
150  * Arguments:   @unsigned f@ = flags to write
151  *              @dstr *d@ = pointer to destination string
152  *
153  * Returns:     ---
154  *
155  * Use:         Emits a flags word as a string representation.
156  */
157
158 void key_writeflags(unsigned f, dstr *d)
159 {
160   int del = 0;
161   const flagent *e;
162   unsigned m = 0;
163
164   for (e = flagtab; e->name; e++) {
165     if (m & e->m || e->name[0] == '-' || (f & e->m) != e->f)
166       continue;
167     if (del)
168       DPUTC(d, ',');
169     DPUTS(d, e->name);
170     m |= e->m;
171     del = 1;
172   }
173 }
174
175 /* --- @key_match@ --- *
176  *
177  * Arguments:   @key_data *k@ = pointer to key data block
178  *              @const key_filter *kf@ = pointer to filter block
179  *
180  * Returns:     Nonzero if the key matches the filter.
181  *
182  * Use:         Checks whether a key matches a filter.
183  */
184
185 int key_match(key_data *k, const key_filter *kf)
186 {
187   key_subkeyiter i;
188   const char *tag;
189   key_data *kd;
190
191   if (!kf)
192     return (1);
193   if ((k->e & KF_ENCMASK) != KENC_STRUCT)
194     return ((k->e & kf->m) == kf->f);
195
196   for (key_mksubkeyiter(&i, k); key_nextsubkey(&i, &tag, &kd); ) {
197     if (key_match(kd, kf))
198       return (1);
199   }
200   return (0);
201 }
202
203 /*----- That's all, folks -------------------------------------------------*/