diff options
-rw-r--r-- | src/lib/libcrypto/objects/o_names.c | 255 |
1 files changed, 11 insertions, 244 deletions
diff --git a/src/lib/libcrypto/objects/o_names.c b/src/lib/libcrypto/objects/o_names.c index 1007c5e23a..566ada4d49 100644 --- a/src/lib/libcrypto/objects/o_names.c +++ b/src/lib/libcrypto/objects/o_names.c | |||
@@ -1,51 +1,12 @@ | |||
1 | /* $OpenBSD: o_names.c,v 1.25 2024/01/13 11:08:39 tb Exp $ */ | 1 | /* $OpenBSD: o_names.c,v 1.26 2024/01/13 11:38:45 tb 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> | 2 | #include <openssl/err.h> |
9 | #include <openssl/lhash.h> | ||
10 | #include <openssl/objects.h> | 3 | #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 | 4 | ||
42 | int | 5 | int |
43 | OBJ_NAME_init(void) | 6 | OBJ_NAME_init(void) |
44 | { | 7 | { |
45 | if (names_lh != NULL) | 8 | OBJerror(ERR_R_DISABLED); |
46 | return (1); | 9 | return 0; |
47 | names_lh = lh_OBJ_NAME_new(); | ||
48 | return (names_lh != NULL); | ||
49 | } | 10 | } |
50 | LCRYPTO_ALIAS(OBJ_NAME_init); | 11 | LCRYPTO_ALIAS(OBJ_NAME_init); |
51 | 12 | ||
@@ -54,231 +15,37 @@ OBJ_NAME_new_index(unsigned long (*hash_func)(const char *), | |||
54 | int (*cmp_func)(const char *, const char *), | 15 | int (*cmp_func)(const char *, const char *), |
55 | void (*free_func)(const char *, int, const char *)) | 16 | void (*free_func)(const char *, int, const char *)) |
56 | { | 17 | { |
57 | int ret; | 18 | OBJerror(ERR_R_DISABLED); |
58 | int i; | 19 | return 0; |
59 | NAME_FUNCS *name_funcs; | ||
60 | |||
61 | if (name_funcs_stack == NULL) | ||
62 | name_funcs_stack = sk_NAME_FUNCS_new_null(); | ||
63 | if (name_funcs_stack == NULL) | ||
64 | return (0); | ||
65 | |||
66 | ret = names_type_num; | ||
67 | names_type_num++; | ||
68 | for (i = sk_NAME_FUNCS_num(name_funcs_stack); i < names_type_num; i++) { | ||
69 | name_funcs = malloc(sizeof(NAME_FUNCS)); | ||
70 | if (!name_funcs) { | ||
71 | OBJerror(ERR_R_MALLOC_FAILURE); | ||
72 | return (0); | ||
73 | } | ||
74 | name_funcs->hash_func = lh_strhash; | ||
75 | name_funcs->cmp_func = strcmp; | ||
76 | name_funcs->free_func = NULL; | ||
77 | if (sk_NAME_FUNCS_push(name_funcs_stack, name_funcs) == 0) { | ||
78 | free(name_funcs); | ||
79 | OBJerror(ERR_R_MALLOC_FAILURE); | ||
80 | return (0); | ||
81 | } | ||
82 | } | ||
83 | name_funcs = sk_NAME_FUNCS_value(name_funcs_stack, ret); | ||
84 | if (hash_func != NULL) | ||
85 | name_funcs->hash_func = hash_func; | ||
86 | if (cmp_func != NULL) | ||
87 | name_funcs->cmp_func = cmp_func; | ||
88 | if (free_func != NULL) | ||
89 | name_funcs->free_func = free_func; | ||
90 | return (ret); | ||
91 | } | 20 | } |
92 | LCRYPTO_ALIAS(OBJ_NAME_new_index); | 21 | LCRYPTO_ALIAS(OBJ_NAME_new_index); |
93 | 22 | ||
94 | /* static int obj_name_cmp(OBJ_NAME *a, OBJ_NAME *b) */ | ||
95 | static int | ||
96 | obj_name_cmp(const void *a_void, const void *b_void) | ||
97 | { | ||
98 | int ret; | ||
99 | const OBJ_NAME *a = (const OBJ_NAME *)a_void; | ||
100 | const OBJ_NAME *b = (const OBJ_NAME *)b_void; | ||
101 | |||
102 | ret = a->type - b->type; | ||
103 | if (ret == 0) { | ||
104 | if ((name_funcs_stack != NULL) && | ||
105 | (sk_NAME_FUNCS_num(name_funcs_stack) > a->type)) { | ||
106 | ret = sk_NAME_FUNCS_value(name_funcs_stack, | ||
107 | a->type)->cmp_func(a->name, b->name); | ||
108 | } else | ||
109 | ret = strcmp(a->name, b->name); | ||
110 | } | ||
111 | return (ret); | ||
112 | } | ||
113 | |||
114 | /* static unsigned long obj_name_hash(OBJ_NAME *a) */ | ||
115 | static unsigned long | ||
116 | obj_name_hash(const void *a_void) | ||
117 | { | ||
118 | unsigned long ret; | ||
119 | const OBJ_NAME *a = (const OBJ_NAME *)a_void; | ||
120 | |||
121 | if ((name_funcs_stack != NULL) && | ||
122 | (sk_NAME_FUNCS_num(name_funcs_stack) > a->type)) { | ||
123 | ret = sk_NAME_FUNCS_value(name_funcs_stack, | ||
124 | a->type)->hash_func(a->name); | ||
125 | } else { | ||
126 | ret = lh_strhash(a->name); | ||
127 | } | ||
128 | ret ^= a->type; | ||
129 | return (ret); | ||
130 | } | ||
131 | |||
132 | const char * | 23 | const char * |
133 | OBJ_NAME_get(const char *name, int type) | 24 | OBJ_NAME_get(const char *name, int type) |
134 | { | 25 | { |
135 | OBJ_NAME on, *ret; | 26 | OBJerror(ERR_R_DISABLED); |
136 | int num = 0, alias; | 27 | return NULL; |
137 | |||
138 | if (name == NULL) | ||
139 | return (NULL); | ||
140 | if ((names_lh == NULL) && !OBJ_NAME_init()) | ||
141 | return (NULL); | ||
142 | |||
143 | alias = type&OBJ_NAME_ALIAS; | ||
144 | type&= ~OBJ_NAME_ALIAS; | ||
145 | |||
146 | on.name = name; | ||
147 | on.type = type; | ||
148 | |||
149 | for (;;) { | ||
150 | ret = lh_OBJ_NAME_retrieve(names_lh, &on); | ||
151 | if (ret == NULL) | ||
152 | return (NULL); | ||
153 | if ((ret->alias) && !alias) { | ||
154 | if (++num > 10) | ||
155 | return (NULL); | ||
156 | on.name = ret->data; | ||
157 | } else { | ||
158 | return (ret->data); | ||
159 | } | ||
160 | } | ||
161 | } | 28 | } |
162 | LCRYPTO_ALIAS(OBJ_NAME_get); | 29 | LCRYPTO_ALIAS(OBJ_NAME_get); |
163 | 30 | ||
164 | int | 31 | int |
165 | OBJ_NAME_add(const char *name, int type, const char *data) | 32 | OBJ_NAME_add(const char *name, int type, const char *data) |
166 | { | 33 | { |
167 | OBJ_NAME *onp, *ret; | 34 | /* No error to avoid polluting xca's error stack. */ |
168 | int alias; | 35 | return 0; |
169 | |||
170 | if ((names_lh == NULL) && !OBJ_NAME_init()) | ||
171 | return (0); | ||
172 | |||
173 | alias = type & OBJ_NAME_ALIAS; | ||
174 | type &= ~OBJ_NAME_ALIAS; | ||
175 | |||
176 | onp = malloc(sizeof(OBJ_NAME)); | ||
177 | if (onp == NULL) { | ||
178 | /* ERROR */ | ||
179 | return (0); | ||
180 | } | ||
181 | |||
182 | onp->name = name; | ||
183 | onp->alias = alias; | ||
184 | onp->type = type; | ||
185 | onp->data = data; | ||
186 | |||
187 | ret = lh_OBJ_NAME_insert(names_lh, onp); | ||
188 | if (ret != NULL) { | ||
189 | /* free things */ | ||
190 | if ((name_funcs_stack != NULL) && | ||
191 | (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type)) { | ||
192 | /* XXX: I'm not sure I understand why the free | ||
193 | * function should get three arguments... | ||
194 | * -- Richard Levitte | ||
195 | */ | ||
196 | sk_NAME_FUNCS_value( | ||
197 | name_funcs_stack, ret->type)->free_func( | ||
198 | ret->name, ret->type, ret->data); | ||
199 | } | ||
200 | free(ret); | ||
201 | } else { | ||
202 | if (lh_OBJ_NAME_error(names_lh)) { | ||
203 | free(onp); | ||
204 | /* ERROR */ | ||
205 | return (0); | ||
206 | } | ||
207 | } | ||
208 | return (1); | ||
209 | } | 36 | } |
210 | LCRYPTO_ALIAS(OBJ_NAME_add); | 37 | LCRYPTO_ALIAS(OBJ_NAME_add); |
211 | 38 | ||
212 | int | 39 | int |
213 | OBJ_NAME_remove(const char *name, int type) | 40 | OBJ_NAME_remove(const char *name, int type) |
214 | { | 41 | { |
215 | OBJ_NAME on, *ret; | 42 | OBJerror(ERR_R_DISABLED); |
216 | 43 | return 0; | |
217 | if (names_lh == NULL) | ||
218 | return (0); | ||
219 | |||
220 | type &= ~OBJ_NAME_ALIAS; | ||
221 | on.name = name; | ||
222 | on.type = type; | ||
223 | ret = lh_OBJ_NAME_delete(names_lh, &on); | ||
224 | if (ret != NULL) { | ||
225 | /* free things */ | ||
226 | if ((name_funcs_stack != NULL) && | ||
227 | (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type)) { | ||
228 | /* XXX: I'm not sure I understand why the free | ||
229 | * function should get three arguments... | ||
230 | * -- Richard Levitte | ||
231 | */ | ||
232 | sk_NAME_FUNCS_value( | ||
233 | name_funcs_stack, ret->type)->free_func( | ||
234 | ret->name, ret->type, ret->data); | ||
235 | } | ||
236 | free(ret); | ||
237 | return (1); | ||
238 | } else | ||
239 | return (0); | ||
240 | } | 44 | } |
241 | LCRYPTO_ALIAS(OBJ_NAME_remove); | 45 | LCRYPTO_ALIAS(OBJ_NAME_remove); |
242 | 46 | ||
243 | static int free_type; | ||
244 | |||
245 | static void | ||
246 | names_lh_free_doall(OBJ_NAME *onp) | ||
247 | { | ||
248 | if (onp == NULL) | ||
249 | return; | ||
250 | |||
251 | if (free_type < 0 || free_type == onp->type) | ||
252 | OBJ_NAME_remove(onp->name, onp->type); | ||
253 | } | ||
254 | |||
255 | static IMPLEMENT_LHASH_DOALL_FN(names_lh_free, OBJ_NAME) | ||
256 | |||
257 | static void | ||
258 | name_funcs_free(NAME_FUNCS *ptr) | ||
259 | { | ||
260 | free(ptr); | ||
261 | } | ||
262 | |||
263 | void | 47 | void |
264 | OBJ_NAME_cleanup(int type) | 48 | OBJ_NAME_cleanup(int type) |
265 | { | 49 | { |
266 | unsigned long down_load; | ||
267 | |||
268 | if (names_lh == NULL) | ||
269 | return; | ||
270 | |||
271 | free_type = type; | ||
272 | down_load = lh_OBJ_NAME_down_load(names_lh); | ||
273 | lh_OBJ_NAME_down_load(names_lh) = 0; | ||
274 | |||
275 | lh_OBJ_NAME_doall(names_lh, LHASH_DOALL_FN(names_lh_free)); | ||
276 | if (type < 0) { | ||
277 | lh_OBJ_NAME_free(names_lh); | ||
278 | sk_NAME_FUNCS_pop_free(name_funcs_stack, name_funcs_free); | ||
279 | names_lh = NULL; | ||
280 | name_funcs_stack = NULL; | ||
281 | } else | ||
282 | lh_OBJ_NAME_down_load(names_lh) = down_load; | ||
283 | } | 50 | } |
284 | LCRYPTO_ALIAS(OBJ_NAME_cleanup); | 51 | LCRYPTO_ALIAS(OBJ_NAME_cleanup); |