summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/objects/o_names.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/objects/o_names.c')
-rw-r--r--src/lib/libcrypto/objects/o_names.c229
1 files changed, 175 insertions, 54 deletions
diff --git a/src/lib/libcrypto/objects/o_names.c b/src/lib/libcrypto/objects/o_names.c
index 4da5e45b9c..b4453b4a98 100644
--- a/src/lib/libcrypto/objects/o_names.c
+++ b/src/lib/libcrypto/objects/o_names.c
@@ -4,78 +4,119 @@
4 4
5#include <openssl/lhash.h> 5#include <openssl/lhash.h>
6#include <openssl/objects.h> 6#include <openssl/objects.h>
7#include <openssl/safestack.h>
8#include <openssl/e_os2.h>
9
10/* Later versions of DEC C has started to add lnkage information to certain
11 * functions, which makes it tricky to use them as values to regular function
12 * pointers. One way is to define a macro that takes care of casting them
13 * correctly.
14 */
15#ifdef OPENSSL_SYS_VMS_DECC
16# define OPENSSL_strcmp (int (*)(const char *,const char *))strcmp
17#else
18# define OPENSSL_strcmp strcmp
19#endif
7 20
8/* I use the ex_data stuff to manage the identifiers for the obj_name_types 21/* I use the ex_data stuff to manage the identifiers for the obj_name_types
9 * that applications may define. I only really use the free function field. 22 * that applications may define. I only really use the free function field.
10 */ 23 */
11static LHASH *names_lh=NULL; 24static LHASH *names_lh=NULL;
12static int names_type_num=OBJ_NAME_TYPE_NUM; 25static int names_type_num=OBJ_NAME_TYPE_NUM;
13static STACK *names_cmp=NULL;
14static STACK *names_hash=NULL;
15static STACK *names_free=NULL;
16 26
17static unsigned long obj_name_hash(OBJ_NAME *a); 27typedef struct name_funcs_st
18static int obj_name_cmp(OBJ_NAME *a,OBJ_NAME *b); 28 {
29 unsigned long (*hash_func)(const char *name);
30 int (*cmp_func)(const char *a,const char *b);
31 void (*free_func)(const char *, int, const char *);
32 } NAME_FUNCS;
33
34DECLARE_STACK_OF(NAME_FUNCS)
35IMPLEMENT_STACK_OF(NAME_FUNCS)
36
37static STACK_OF(NAME_FUNCS) *name_funcs_stack;
38
39/* The LHASH callbacks now use the raw "void *" prototypes and do per-variable
40 * casting in the functions. This prevents function pointer casting without the
41 * need for macro-generated wrapper functions. */
42
43/* static unsigned long obj_name_hash(OBJ_NAME *a); */
44static unsigned long obj_name_hash(const void *a_void);
45/* static int obj_name_cmp(OBJ_NAME *a,OBJ_NAME *b); */
46static int obj_name_cmp(const void *a_void,const void *b_void);
19 47
20int OBJ_NAME_init(void) 48int OBJ_NAME_init(void)
21 { 49 {
22 if (names_lh != NULL) return(1); 50 if (names_lh != NULL) return(1);
23 MemCheck_off(); 51 MemCheck_off();
24 names_lh=lh_new(obj_name_hash,obj_name_cmp); 52 names_lh=lh_new(obj_name_hash, obj_name_cmp);
25 MemCheck_on(); 53 MemCheck_on();
26 return(names_lh != NULL); 54 return(names_lh != NULL);
27 } 55 }
28 56
29int OBJ_NAME_new_index(unsigned long (*hash_func)(), int (*cmp_func)(), 57int OBJ_NAME_new_index(unsigned long (*hash_func)(const char *),
30 void (*free_func)()) 58 int (*cmp_func)(const char *, const char *),
59 void (*free_func)(const char *, int, const char *))
31 { 60 {
32 int ret; 61 int ret;
33 int i; 62 int i;
63 NAME_FUNCS *name_funcs;
34 64
35 if (names_free == NULL) 65 if (name_funcs_stack == NULL)
36 { 66 {
37 MemCheck_off(); 67 MemCheck_off();
38 names_hash=sk_new_null(); 68 name_funcs_stack=sk_NAME_FUNCS_new_null();
39 names_cmp=sk_new_null();
40 names_free=sk_new_null();
41 MemCheck_on(); 69 MemCheck_on();
42 } 70 }
43 if ((names_free == NULL) || (names_hash == NULL) || (names_cmp == NULL)) 71 if ((name_funcs_stack == NULL))
44 { 72 {
45 /* ERROR */ 73 /* ERROR */
46 return(0); 74 return(0);
47 } 75 }
48 ret=names_type_num; 76 ret=names_type_num;
49 names_type_num++; 77 names_type_num++;
50 for (i=sk_num(names_free); i<names_type_num; i++) 78 for (i=sk_NAME_FUNCS_num(name_funcs_stack); i<names_type_num; i++)
51 { 79 {
52 MemCheck_off(); 80 MemCheck_off();
53 sk_push(names_hash,(char *)strcmp); 81 name_funcs = OPENSSL_malloc(sizeof(NAME_FUNCS));
54 sk_push(names_cmp,(char *)lh_strhash); 82 MemCheck_on();
55 sk_push(names_free,NULL); 83 if (!name_funcs) return(0);
84 name_funcs->hash_func = lh_strhash;
85 name_funcs->cmp_func = OPENSSL_strcmp;
86 name_funcs->free_func = 0; /* NULL is often declared to
87 * ((void *)0), which according
88 * to Compaq C is not really
89 * compatible with a function
90 * pointer. -- Richard Levitte*/
91 MemCheck_off();
92 sk_NAME_FUNCS_push(name_funcs_stack,name_funcs);
56 MemCheck_on(); 93 MemCheck_on();
57 } 94 }
95 name_funcs = sk_NAME_FUNCS_value(name_funcs_stack, ret);
58 if (hash_func != NULL) 96 if (hash_func != NULL)
59 sk_set(names_hash,ret,(char *)hash_func); 97 name_funcs->hash_func = hash_func;
60 if (cmp_func != NULL) 98 if (cmp_func != NULL)
61 sk_set(names_cmp,ret,(char *)cmp_func); 99 name_funcs->cmp_func = cmp_func;
62 if (free_func != NULL) 100 if (free_func != NULL)
63 sk_set(names_free,ret,(char *)free_func); 101 name_funcs->free_func = free_func;
64 return(ret); 102 return(ret);
65 } 103 }
66 104
67static int obj_name_cmp(OBJ_NAME *a, OBJ_NAME *b) 105/* static int obj_name_cmp(OBJ_NAME *a, OBJ_NAME *b) */
106static int obj_name_cmp(const void *a_void, const void *b_void)
68 { 107 {
69 int ret; 108 int ret;
70 int (*cmp)(); 109 OBJ_NAME *a = (OBJ_NAME *)a_void;
110 OBJ_NAME *b = (OBJ_NAME *)b_void;
71 111
72 ret=a->type-b->type; 112 ret=a->type-b->type;
73 if (ret == 0) 113 if (ret == 0)
74 { 114 {
75 if ((names_cmp != NULL) && (sk_num(names_cmp) > a->type)) 115 if ((name_funcs_stack != NULL)
116 && (sk_NAME_FUNCS_num(name_funcs_stack) > a->type))
76 { 117 {
77 cmp=(int (*)())sk_value(names_cmp,a->type); 118 ret=sk_NAME_FUNCS_value(name_funcs_stack,
78 ret=cmp(a->name,b->name); 119 a->type)->cmp_func(a->name,b->name);
79 } 120 }
80 else 121 else
81 ret=strcmp(a->name,b->name); 122 ret=strcmp(a->name,b->name);
@@ -83,15 +124,16 @@ static int obj_name_cmp(OBJ_NAME *a, OBJ_NAME *b)
83 return(ret); 124 return(ret);
84 } 125 }
85 126
86static unsigned long obj_name_hash(OBJ_NAME *a) 127/* static unsigned long obj_name_hash(OBJ_NAME *a) */
128static unsigned long obj_name_hash(const void *a_void)
87 { 129 {
88 unsigned long ret; 130 unsigned long ret;
89 unsigned long (*hash)(); 131 OBJ_NAME *a = (OBJ_NAME *)a_void;
90 132
91 if ((names_hash != NULL) && (sk_num(names_hash) > a->type)) 133 if ((name_funcs_stack != NULL) && (sk_NAME_FUNCS_num(name_funcs_stack) > a->type))
92 { 134 {
93 hash=(unsigned long (*)())sk_value(names_hash,a->type); 135 ret=sk_NAME_FUNCS_value(name_funcs_stack,
94 ret=hash(a->name); 136 a->type)->hash_func(a->name);
95 } 137 }
96 else 138 else
97 { 139 {
@@ -116,8 +158,8 @@ const char *OBJ_NAME_get(const char *name, int type)
116 on.type=type; 158 on.type=type;
117 159
118 for (;;) 160 for (;;)
119 { 161 {
120 ret=(OBJ_NAME *)lh_retrieve(names_lh,(char *)&on); 162 ret=(OBJ_NAME *)lh_retrieve(names_lh,&on);
121 if (ret == NULL) return(NULL); 163 if (ret == NULL) return(NULL);
122 if ((ret->alias) && !alias) 164 if ((ret->alias) && !alias)
123 { 165 {
@@ -133,7 +175,6 @@ const char *OBJ_NAME_get(const char *name, int type)
133 175
134int OBJ_NAME_add(const char *name, int type, const char *data) 176int OBJ_NAME_add(const char *name, int type, const char *data)
135 { 177 {
136 void (*f)();
137 OBJ_NAME *onp,*ret; 178 OBJ_NAME *onp,*ret;
138 int alias; 179 int alias;
139 180
@@ -142,7 +183,7 @@ int OBJ_NAME_add(const char *name, int type, const char *data)
142 alias=type&OBJ_NAME_ALIAS; 183 alias=type&OBJ_NAME_ALIAS;
143 type&= ~OBJ_NAME_ALIAS; 184 type&= ~OBJ_NAME_ALIAS;
144 185
145 onp=(OBJ_NAME *)Malloc(sizeof(OBJ_NAME)); 186 onp=(OBJ_NAME *)OPENSSL_malloc(sizeof(OBJ_NAME));
146 if (onp == NULL) 187 if (onp == NULL)
147 { 188 {
148 /* ERROR */ 189 /* ERROR */
@@ -154,16 +195,20 @@ int OBJ_NAME_add(const char *name, int type, const char *data)
154 onp->type=type; 195 onp->type=type;
155 onp->data=data; 196 onp->data=data;
156 197
157 ret=(OBJ_NAME *)lh_insert(names_lh,(char *)onp); 198 ret=(OBJ_NAME *)lh_insert(names_lh,onp);
158 if (ret != NULL) 199 if (ret != NULL)
159 { 200 {
160 /* free things */ 201 /* free things */
161 if ((names_free != NULL) && (sk_num(names_free) > ret->type)) 202 if ((name_funcs_stack != NULL) && (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type))
162 { 203 {
163 f=(void (*)())sk_value(names_free,ret->type); 204 /* XXX: I'm not sure I understand why the free
164 f(ret->name,ret->type,ret->data); 205 * function should get three arguments...
206 * -- Richard Levitte
207 */
208 sk_NAME_FUNCS_value(name_funcs_stack,
209 ret->type)->free_func(ret->name,ret->type,ret->data);
165 } 210 }
166 Free((char *)ret); 211 OPENSSL_free(ret);
167 } 212 }
168 else 213 else
169 { 214 {
@@ -179,35 +224,108 @@ int OBJ_NAME_add(const char *name, int type, const char *data)
179int OBJ_NAME_remove(const char *name, int type) 224int OBJ_NAME_remove(const char *name, int type)
180 { 225 {
181 OBJ_NAME on,*ret; 226 OBJ_NAME on,*ret;
182 void (*f)();
183 227
184 if (names_lh == NULL) return(0); 228 if (names_lh == NULL) return(0);
185 229
186 type&= ~OBJ_NAME_ALIAS; 230 type&= ~OBJ_NAME_ALIAS;
187 on.name=name; 231 on.name=name;
188 on.type=type; 232 on.type=type;
189 ret=(OBJ_NAME *)lh_delete(names_lh,(char *)&on); 233 ret=(OBJ_NAME *)lh_delete(names_lh,&on);
190 if (ret != NULL) 234 if (ret != NULL)
191 { 235 {
192 /* free things */ 236 /* free things */
193 if ((names_free != NULL) && (sk_num(names_free) > type)) 237 if ((name_funcs_stack != NULL) && (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type))
194 { 238 {
195 f=(void (*)())sk_value(names_free,type); 239 /* XXX: I'm not sure I understand why the free
196 f(ret->name,ret->type,ret->data); 240 * function should get three arguments...
241 * -- Richard Levitte
242 */
243 sk_NAME_FUNCS_value(name_funcs_stack,
244 ret->type)->free_func(ret->name,ret->type,ret->data);
197 } 245 }
198 Free((char *)ret); 246 OPENSSL_free(ret);
199 return(1); 247 return(1);
200 } 248 }
201 else 249 else
202 return(0); 250 return(0);
203 } 251 }
204 252
253struct doall
254 {
255 int type;
256 void (*fn)(const OBJ_NAME *,void *arg);
257 void *arg;
258 };
259
260static void do_all_fn(const OBJ_NAME *name,struct doall *d)
261 {
262 if(name->type == d->type)
263 d->fn(name,d->arg);
264 }
265
266static IMPLEMENT_LHASH_DOALL_ARG_FN(do_all_fn, const OBJ_NAME *, struct doall *)
267
268void OBJ_NAME_do_all(int type,void (*fn)(const OBJ_NAME *,void *arg),void *arg)
269 {
270 struct doall d;
271
272 d.type=type;
273 d.fn=fn;
274 d.arg=arg;
275
276 lh_doall_arg(names_lh,LHASH_DOALL_ARG_FN(do_all_fn),&d);
277 }
278
279struct doall_sorted
280 {
281 int type;
282 int n;
283 const OBJ_NAME **names;
284 };
285
286static void do_all_sorted_fn(const OBJ_NAME *name,void *d_)
287 {
288 struct doall_sorted *d=d_;
289
290 if(name->type != d->type)
291 return;
292
293 d->names[d->n++]=name;
294 }
295
296static int do_all_sorted_cmp(const void *n1_,const void *n2_)
297 {
298 const OBJ_NAME * const *n1=n1_;
299 const OBJ_NAME * const *n2=n2_;
300
301 return strcmp((*n1)->name,(*n2)->name);
302 }
303
304void OBJ_NAME_do_all_sorted(int type,void (*fn)(const OBJ_NAME *,void *arg),
305 void *arg)
306 {
307 struct doall_sorted d;
308 int n;
309
310 d.type=type;
311 d.names=OPENSSL_malloc(lh_num_items(names_lh)*sizeof *d.names);
312 d.n=0;
313 OBJ_NAME_do_all(type,do_all_sorted_fn,&d);
314
315 qsort((void *)d.names,d.n,sizeof *d.names,do_all_sorted_cmp);
316
317 for(n=0 ; n < d.n ; ++n)
318 fn(d.names[n],arg);
319
320 OPENSSL_free((void *)d.names);
321 }
322
205static int free_type; 323static int free_type;
206 324
207static void names_lh_free(OBJ_NAME *onp, int type) 325static void names_lh_free(OBJ_NAME *onp)
208{ 326{
209 if(onp == NULL) 327 if(onp == NULL)
210 return; 328 return;
211 329
212 if ((free_type < 0) || (free_type == onp->type)) 330 if ((free_type < 0) || (free_type == onp->type))
213 { 331 {
@@ -215,6 +333,13 @@ static void names_lh_free(OBJ_NAME *onp, int type)
215 } 333 }
216 } 334 }
217 335
336static IMPLEMENT_LHASH_DOALL_FN(names_lh_free, OBJ_NAME *)
337
338static void name_funcs_free(NAME_FUNCS *ptr)
339 {
340 OPENSSL_free(ptr);
341 }
342
218void OBJ_NAME_cleanup(int type) 343void OBJ_NAME_cleanup(int type)
219 { 344 {
220 unsigned long down_load; 345 unsigned long down_load;
@@ -225,17 +350,13 @@ void OBJ_NAME_cleanup(int type)
225 down_load=names_lh->down_load; 350 down_load=names_lh->down_load;
226 names_lh->down_load=0; 351 names_lh->down_load=0;
227 352
228 lh_doall(names_lh,names_lh_free); 353 lh_doall(names_lh,LHASH_DOALL_FN(names_lh_free));
229 if (type < 0) 354 if (type < 0)
230 { 355 {
231 lh_free(names_lh); 356 lh_free(names_lh);
232 sk_free(names_hash); 357 sk_NAME_FUNCS_pop_free(name_funcs_stack,name_funcs_free);
233 sk_free(names_cmp);
234 sk_free(names_free);
235 names_lh=NULL; 358 names_lh=NULL;
236 names_hash=NULL; 359 name_funcs_stack = NULL;
237 names_cmp=NULL;
238 names_free=NULL;
239 } 360 }
240 else 361 else
241 names_lh->down_load=down_load; 362 names_lh->down_load=down_load;