diff options
| author | markus <> | 2002-09-05 12:51:50 +0000 |
|---|---|---|
| committer | markus <> | 2002-09-05 12:51:50 +0000 |
| commit | 15b5d84f9da2ce4bfae8580e56e34a859f74ad71 (patch) | |
| tree | bf939e82d7fd73cc8a01cf6959002209972091bc /src/lib/libcrypto/objects/o_names.c | |
| parent | 027351f729b9e837200dae6e1520cda6577ab930 (diff) | |
| download | openbsd-15b5d84f9da2ce4bfae8580e56e34a859f74ad71.tar.gz openbsd-15b5d84f9da2ce4bfae8580e56e34a859f74ad71.tar.bz2 openbsd-15b5d84f9da2ce4bfae8580e56e34a859f74ad71.zip | |
import openssl-0.9.7-beta1
Diffstat (limited to 'src/lib/libcrypto/objects/o_names.c')
| -rw-r--r-- | src/lib/libcrypto/objects/o_names.c | 229 |
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 | */ |
| 11 | static LHASH *names_lh=NULL; | 24 | static LHASH *names_lh=NULL; |
| 12 | static int names_type_num=OBJ_NAME_TYPE_NUM; | 25 | static int names_type_num=OBJ_NAME_TYPE_NUM; |
| 13 | static STACK *names_cmp=NULL; | ||
| 14 | static STACK *names_hash=NULL; | ||
| 15 | static STACK *names_free=NULL; | ||
| 16 | 26 | ||
| 17 | static unsigned long obj_name_hash(OBJ_NAME *a); | 27 | typedef struct name_funcs_st |
| 18 | static 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 | |||
| 34 | DECLARE_STACK_OF(NAME_FUNCS) | ||
| 35 | IMPLEMENT_STACK_OF(NAME_FUNCS) | ||
| 36 | |||
| 37 | static 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); */ | ||
| 44 | static unsigned long obj_name_hash(const void *a_void); | ||
| 45 | /* static int obj_name_cmp(OBJ_NAME *a,OBJ_NAME *b); */ | ||
| 46 | static int obj_name_cmp(const void *a_void,const void *b_void); | ||
| 19 | 47 | ||
| 20 | int OBJ_NAME_init(void) | 48 | int 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 | ||
| 29 | int OBJ_NAME_new_index(unsigned long (*hash_func)(), int (*cmp_func)(), | 57 | int 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 | ||
| 67 | static int obj_name_cmp(OBJ_NAME *a, OBJ_NAME *b) | 105 | /* static int obj_name_cmp(OBJ_NAME *a, OBJ_NAME *b) */ |
| 106 | static 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 | ||
| 86 | static unsigned long obj_name_hash(OBJ_NAME *a) | 127 | /* static unsigned long obj_name_hash(OBJ_NAME *a) */ |
| 128 | static 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 | ||
| 134 | int OBJ_NAME_add(const char *name, int type, const char *data) | 176 | int 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) | |||
| 179 | int OBJ_NAME_remove(const char *name, int type) | 224 | int 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 | ||
| 253 | struct doall | ||
| 254 | { | ||
| 255 | int type; | ||
| 256 | void (*fn)(const OBJ_NAME *,void *arg); | ||
| 257 | void *arg; | ||
| 258 | }; | ||
| 259 | |||
| 260 | static 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 | |||
| 266 | static IMPLEMENT_LHASH_DOALL_ARG_FN(do_all_fn, const OBJ_NAME *, struct doall *) | ||
| 267 | |||
| 268 | void 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 | |||
| 279 | struct doall_sorted | ||
| 280 | { | ||
| 281 | int type; | ||
| 282 | int n; | ||
| 283 | const OBJ_NAME **names; | ||
| 284 | }; | ||
| 285 | |||
| 286 | static 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 | |||
| 296 | static 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 | |||
| 304 | void 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 | |||
| 205 | static int free_type; | 323 | static int free_type; |
| 206 | 324 | ||
| 207 | static void names_lh_free(OBJ_NAME *onp, int type) | 325 | static 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 | ||
| 336 | static IMPLEMENT_LHASH_DOALL_FN(names_lh_free, OBJ_NAME *) | ||
| 337 | |||
| 338 | static void name_funcs_free(NAME_FUNCS *ptr) | ||
| 339 | { | ||
| 340 | OPENSSL_free(ptr); | ||
| 341 | } | ||
| 342 | |||
| 218 | void OBJ_NAME_cleanup(int type) | 343 | void 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; |
