diff options
Diffstat (limited to 'src/lib/libcrypto/objects/o_names.c')
-rw-r--r-- | src/lib/libcrypto/objects/o_names.c | 354 |
1 files changed, 0 insertions, 354 deletions
diff --git a/src/lib/libcrypto/objects/o_names.c b/src/lib/libcrypto/objects/o_names.c deleted file mode 100644 index 81240db204..0000000000 --- a/src/lib/libcrypto/objects/o_names.c +++ /dev/null | |||
@@ -1,354 +0,0 @@ | |||
1 | /* $OpenBSD: o_names.c,v 1.21 2015/07/18 21:21:28 beck Exp $ */ | ||
2 | #include <stdio.h> | ||
3 | #include <stdlib.h> | ||
4 | #include <string.h> | ||
5 | |||
6 | #include <openssl/opensslconf.h> | ||
7 | |||
8 | #include <openssl/err.h> | ||
9 | #include <openssl/lhash.h> | ||
10 | #include <openssl/objects.h> | ||
11 | #include <openssl/safestack.h> | ||
12 | |||
13 | /* I use the ex_data stuff to manage the identifiers for the obj_name_types | ||
14 | * that applications may define. I only really use the free function field. | ||
15 | */ | ||
16 | DECLARE_LHASH_OF(OBJ_NAME); | ||
17 | static LHASH_OF(OBJ_NAME) *names_lh = NULL; | ||
18 | static int names_type_num = OBJ_NAME_TYPE_NUM; | ||
19 | |||
20 | typedef struct name_funcs_st { | ||
21 | unsigned long (*hash_func)(const char *name); | ||
22 | int (*cmp_func)(const char *a, const char *b); | ||
23 | void (*free_func)(const char *, int, const char *); | ||
24 | } NAME_FUNCS; | ||
25 | |||
26 | DECLARE_STACK_OF(NAME_FUNCS) | ||
27 | |||
28 | static STACK_OF(NAME_FUNCS) *name_funcs_stack; | ||
29 | |||
30 | /* The LHASH callbacks now use the raw "void *" prototypes and do per-variable | ||
31 | * casting in the functions. This prevents function pointer casting without the | ||
32 | * need for macro-generated wrapper functions. */ | ||
33 | |||
34 | /* static unsigned long obj_name_hash(OBJ_NAME *a); */ | ||
35 | static unsigned long obj_name_hash(const void *a_void); | ||
36 | /* static int obj_name_cmp(OBJ_NAME *a,OBJ_NAME *b); */ | ||
37 | static int obj_name_cmp(const void *a_void, const void *b_void); | ||
38 | |||
39 | static IMPLEMENT_LHASH_HASH_FN(obj_name, OBJ_NAME) | ||
40 | static IMPLEMENT_LHASH_COMP_FN(obj_name, OBJ_NAME) | ||
41 | |||
42 | int | ||
43 | OBJ_NAME_init(void) | ||
44 | { | ||
45 | if (names_lh != NULL) | ||
46 | return (1); | ||
47 | names_lh = lh_OBJ_NAME_new(); | ||
48 | return (names_lh != NULL); | ||
49 | } | ||
50 | |||
51 | int | ||
52 | OBJ_NAME_new_index(unsigned long (*hash_func)(const char *), | ||
53 | int (*cmp_func)(const char *, const char *), | ||
54 | void (*free_func)(const char *, int, const char *)) | ||
55 | { | ||
56 | int ret; | ||
57 | int i; | ||
58 | NAME_FUNCS *name_funcs; | ||
59 | |||
60 | if (name_funcs_stack == NULL) | ||
61 | name_funcs_stack = sk_NAME_FUNCS_new_null(); | ||
62 | if (name_funcs_stack == NULL) | ||
63 | return (0); | ||
64 | |||
65 | ret = names_type_num; | ||
66 | names_type_num++; | ||
67 | for (i = sk_NAME_FUNCS_num(name_funcs_stack); i < names_type_num; i++) { | ||
68 | name_funcs = malloc(sizeof(NAME_FUNCS)); | ||
69 | if (!name_funcs) { | ||
70 | OBJerr(OBJ_F_OBJ_NAME_NEW_INDEX, ERR_R_MALLOC_FAILURE); | ||
71 | return (0); | ||
72 | } | ||
73 | name_funcs->hash_func = lh_strhash; | ||
74 | name_funcs->cmp_func = strcmp; | ||
75 | name_funcs->free_func = NULL; | ||
76 | if (sk_NAME_FUNCS_push(name_funcs_stack, name_funcs) == 0) { | ||
77 | free(name_funcs); | ||
78 | OBJerr(OBJ_F_OBJ_NAME_NEW_INDEX, ERR_R_MALLOC_FAILURE); | ||
79 | return (0); | ||
80 | } | ||
81 | } | ||
82 | name_funcs = sk_NAME_FUNCS_value(name_funcs_stack, ret); | ||
83 | if (hash_func != NULL) | ||
84 | name_funcs->hash_func = hash_func; | ||
85 | if (cmp_func != NULL) | ||
86 | name_funcs->cmp_func = cmp_func; | ||
87 | if (free_func != NULL) | ||
88 | name_funcs->free_func = free_func; | ||
89 | return (ret); | ||
90 | } | ||
91 | |||
92 | /* static int obj_name_cmp(OBJ_NAME *a, OBJ_NAME *b) */ | ||
93 | static int | ||
94 | obj_name_cmp(const void *a_void, const void *b_void) | ||
95 | { | ||
96 | int ret; | ||
97 | const OBJ_NAME *a = (const OBJ_NAME *)a_void; | ||
98 | const OBJ_NAME *b = (const OBJ_NAME *)b_void; | ||
99 | |||
100 | ret = a->type - b->type; | ||
101 | if (ret == 0) { | ||
102 | if ((name_funcs_stack != NULL) && | ||
103 | (sk_NAME_FUNCS_num(name_funcs_stack) > a->type)) { | ||
104 | ret = sk_NAME_FUNCS_value(name_funcs_stack, | ||
105 | a->type)->cmp_func(a->name, b->name); | ||
106 | } else | ||
107 | ret = strcmp(a->name, b->name); | ||
108 | } | ||
109 | return (ret); | ||
110 | } | ||
111 | |||
112 | /* static unsigned long obj_name_hash(OBJ_NAME *a) */ | ||
113 | static unsigned long | ||
114 | obj_name_hash(const void *a_void) | ||
115 | { | ||
116 | unsigned long ret; | ||
117 | const OBJ_NAME *a = (const OBJ_NAME *)a_void; | ||
118 | |||
119 | if ((name_funcs_stack != NULL) && | ||
120 | (sk_NAME_FUNCS_num(name_funcs_stack) > a->type)) { | ||
121 | ret = sk_NAME_FUNCS_value(name_funcs_stack, | ||
122 | a->type)->hash_func(a->name); | ||
123 | } else { | ||
124 | ret = lh_strhash(a->name); | ||
125 | } | ||
126 | ret ^= a->type; | ||
127 | return (ret); | ||
128 | } | ||
129 | |||
130 | const char * | ||
131 | OBJ_NAME_get(const char *name, int type) | ||
132 | { | ||
133 | OBJ_NAME on, *ret; | ||
134 | int num = 0, alias; | ||
135 | |||
136 | if (name == NULL) | ||
137 | return (NULL); | ||
138 | if ((names_lh == NULL) && !OBJ_NAME_init()) | ||
139 | return (NULL); | ||
140 | |||
141 | alias = type&OBJ_NAME_ALIAS; | ||
142 | type&= ~OBJ_NAME_ALIAS; | ||
143 | |||
144 | on.name = name; | ||
145 | on.type = type; | ||
146 | |||
147 | for (;;) { | ||
148 | ret = lh_OBJ_NAME_retrieve(names_lh, &on); | ||
149 | if (ret == NULL) | ||
150 | return (NULL); | ||
151 | if ((ret->alias) && !alias) { | ||
152 | if (++num > 10) | ||
153 | return (NULL); | ||
154 | on.name = ret->data; | ||
155 | } else { | ||
156 | return (ret->data); | ||
157 | } | ||
158 | } | ||
159 | } | ||
160 | |||
161 | int | ||
162 | OBJ_NAME_add(const char *name, int type, const char *data) | ||
163 | { | ||
164 | OBJ_NAME *onp, *ret; | ||
165 | int alias; | ||
166 | |||
167 | if ((names_lh == NULL) && !OBJ_NAME_init()) | ||
168 | return (0); | ||
169 | |||
170 | alias = type & OBJ_NAME_ALIAS; | ||
171 | type &= ~OBJ_NAME_ALIAS; | ||
172 | |||
173 | onp = malloc(sizeof(OBJ_NAME)); | ||
174 | if (onp == NULL) { | ||
175 | /* ERROR */ | ||
176 | return (0); | ||
177 | } | ||
178 | |||
179 | onp->name = name; | ||
180 | onp->alias = alias; | ||
181 | onp->type = type; | ||
182 | onp->data = data; | ||
183 | |||
184 | ret = lh_OBJ_NAME_insert(names_lh, onp); | ||
185 | if (ret != NULL) { | ||
186 | /* free things */ | ||
187 | if ((name_funcs_stack != NULL) && | ||
188 | (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type)) { | ||
189 | /* XXX: I'm not sure I understand why the free | ||
190 | * function should get three arguments... | ||
191 | * -- Richard Levitte | ||
192 | */ | ||
193 | sk_NAME_FUNCS_value( | ||
194 | name_funcs_stack, ret->type)->free_func( | ||
195 | ret->name, ret->type, ret->data); | ||
196 | } | ||
197 | free(ret); | ||
198 | } else { | ||
199 | if (lh_OBJ_NAME_error(names_lh)) { | ||
200 | /* ERROR */ | ||
201 | return (0); | ||
202 | } | ||
203 | } | ||
204 | return (1); | ||
205 | } | ||
206 | |||
207 | int | ||
208 | OBJ_NAME_remove(const char *name, int type) | ||
209 | { | ||
210 | OBJ_NAME on, *ret; | ||
211 | |||
212 | if (names_lh == NULL) | ||
213 | return (0); | ||
214 | |||
215 | type &= ~OBJ_NAME_ALIAS; | ||
216 | on.name = name; | ||
217 | on.type = type; | ||
218 | ret = lh_OBJ_NAME_delete(names_lh, &on); | ||
219 | if (ret != NULL) { | ||
220 | /* free things */ | ||
221 | if ((name_funcs_stack != NULL) && | ||
222 | (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type)) { | ||
223 | /* XXX: I'm not sure I understand why the free | ||
224 | * function should get three arguments... | ||
225 | * -- Richard Levitte | ||
226 | */ | ||
227 | sk_NAME_FUNCS_value( | ||
228 | name_funcs_stack, ret->type)->free_func( | ||
229 | ret->name, ret->type, ret->data); | ||
230 | } | ||
231 | free(ret); | ||
232 | return (1); | ||
233 | } else | ||
234 | return (0); | ||
235 | } | ||
236 | |||
237 | struct doall { | ||
238 | int type; | ||
239 | void (*fn)(const OBJ_NAME *, void *arg); | ||
240 | void *arg; | ||
241 | }; | ||
242 | |||
243 | static void | ||
244 | do_all_fn_doall_arg(const OBJ_NAME *name, struct doall *d) | ||
245 | { | ||
246 | if (name->type == d->type) | ||
247 | d->fn(name, d->arg); | ||
248 | } | ||
249 | |||
250 | static IMPLEMENT_LHASH_DOALL_ARG_FN(do_all_fn, const OBJ_NAME, struct doall) | ||
251 | |||
252 | void | ||
253 | OBJ_NAME_do_all(int type, void (*fn)(const OBJ_NAME *, void *arg), void *arg) | ||
254 | { | ||
255 | struct doall d; | ||
256 | |||
257 | d.type = type; | ||
258 | d.fn = fn; | ||
259 | d.arg = arg; | ||
260 | |||
261 | lh_OBJ_NAME_doall_arg(names_lh, LHASH_DOALL_ARG_FN(do_all_fn), | ||
262 | struct doall, &d); | ||
263 | } | ||
264 | |||
265 | struct doall_sorted { | ||
266 | int type; | ||
267 | int n; | ||
268 | const OBJ_NAME **names; | ||
269 | }; | ||
270 | |||
271 | static void | ||
272 | do_all_sorted_fn(const OBJ_NAME *name, void *d_) | ||
273 | { | ||
274 | struct doall_sorted *d = d_; | ||
275 | |||
276 | if (name->type != d->type) | ||
277 | return; | ||
278 | |||
279 | d->names[d->n++] = name; | ||
280 | } | ||
281 | |||
282 | static int | ||
283 | do_all_sorted_cmp(const void *n1_, const void *n2_) | ||
284 | { | ||
285 | const OBJ_NAME * const *n1 = n1_; | ||
286 | const OBJ_NAME * const *n2 = n2_; | ||
287 | |||
288 | return strcmp((*n1)->name, (*n2)->name); | ||
289 | } | ||
290 | |||
291 | void | ||
292 | OBJ_NAME_do_all_sorted(int type, void (*fn)(const OBJ_NAME *, void *arg), | ||
293 | void *arg) | ||
294 | { | ||
295 | struct doall_sorted d; | ||
296 | int n; | ||
297 | |||
298 | d.type = type; | ||
299 | d.names = reallocarray(NULL, lh_OBJ_NAME_num_items(names_lh), | ||
300 | sizeof *d.names); | ||
301 | d.n = 0; | ||
302 | if (d.names != NULL) { | ||
303 | OBJ_NAME_do_all(type, do_all_sorted_fn, &d); | ||
304 | |||
305 | qsort((void *)d.names, d.n, sizeof *d.names, do_all_sorted_cmp); | ||
306 | |||
307 | for (n = 0; n < d.n; ++n) | ||
308 | fn(d.names[n], arg); | ||
309 | |||
310 | free(d.names); | ||
311 | } | ||
312 | } | ||
313 | |||
314 | static int free_type; | ||
315 | |||
316 | static void | ||
317 | names_lh_free_doall(OBJ_NAME *onp) | ||
318 | { | ||
319 | if (onp == NULL) | ||
320 | return; | ||
321 | |||
322 | if (free_type < 0 || free_type == onp->type) | ||
323 | OBJ_NAME_remove(onp->name, onp->type); | ||
324 | } | ||
325 | |||
326 | static IMPLEMENT_LHASH_DOALL_FN(names_lh_free, OBJ_NAME) | ||
327 | |||
328 | static void | ||
329 | name_funcs_free(NAME_FUNCS *ptr) | ||
330 | { | ||
331 | free(ptr); | ||
332 | } | ||
333 | |||
334 | void | ||
335 | OBJ_NAME_cleanup(int type) | ||
336 | { | ||
337 | unsigned long down_load; | ||
338 | |||
339 | if (names_lh == NULL) | ||
340 | return; | ||
341 | |||
342 | free_type = type; | ||
343 | down_load = lh_OBJ_NAME_down_load(names_lh); | ||
344 | lh_OBJ_NAME_down_load(names_lh) = 0; | ||
345 | |||
346 | lh_OBJ_NAME_doall(names_lh, LHASH_DOALL_FN(names_lh_free)); | ||
347 | if (type < 0) { | ||
348 | lh_OBJ_NAME_free(names_lh); | ||
349 | sk_NAME_FUNCS_pop_free(name_funcs_stack, name_funcs_free); | ||
350 | names_lh = NULL; | ||
351 | name_funcs_stack = NULL; | ||
352 | } else | ||
353 | lh_OBJ_NAME_down_load(names_lh) = down_load; | ||
354 | } | ||