summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/ex_data.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lib/libcrypto/ex_data.c440
1 files changed, 220 insertions, 220 deletions
diff --git a/src/lib/libcrypto/ex_data.c b/src/lib/libcrypto/ex_data.c
index e2bc8298d0..44bad59527 100644
--- a/src/lib/libcrypto/ex_data.c
+++ b/src/lib/libcrypto/ex_data.c
@@ -142,8 +142,7 @@
142#include <openssl/lhash.h> 142#include <openssl/lhash.h>
143 143
144/* What an "implementation of ex_data functionality" looks like */ 144/* What an "implementation of ex_data functionality" looks like */
145struct st_CRYPTO_EX_DATA_IMPL 145struct st_CRYPTO_EX_DATA_IMPL {
146 {
147 /*********************/ 146 /*********************/
148 /* GLOBAL OPERATIONS */ 147 /* GLOBAL OPERATIONS */
149 /* Return a new class index */ 148 /* Return a new class index */
@@ -154,79 +153,83 @@ struct st_CRYPTO_EX_DATA_IMPL
154 /* PER-CLASS OPERATIONS */ 153 /* PER-CLASS OPERATIONS */
155 /* Get a new method index within a class */ 154 /* Get a new method index within a class */
156 int (*cb_get_new_index)(int class_index, long argl, void *argp, 155 int (*cb_get_new_index)(int class_index, long argl, void *argp,
157 CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, 156 CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
158 CRYPTO_EX_free *free_func); 157 CRYPTO_EX_free *free_func);
159 /* Initialise a new CRYPTO_EX_DATA of a given class */ 158 /* Initialise a new CRYPTO_EX_DATA of a given class */
160 int (*cb_new_ex_data)(int class_index, void *obj, 159 int (*cb_new_ex_data)(int class_index, void *obj,
161 CRYPTO_EX_DATA *ad); 160 CRYPTO_EX_DATA *ad);
162 /* Duplicate a CRYPTO_EX_DATA of a given class onto a copy */ 161 /* Duplicate a CRYPTO_EX_DATA of a given class onto a copy */
163 int (*cb_dup_ex_data)(int class_index, CRYPTO_EX_DATA *to, 162 int (*cb_dup_ex_data)(int class_index, CRYPTO_EX_DATA *to,
164 CRYPTO_EX_DATA *from); 163 CRYPTO_EX_DATA *from);
165 /* Cleanup a CRYPTO_EX_DATA of a given class */ 164 /* Cleanup a CRYPTO_EX_DATA of a given class */
166 void (*cb_free_ex_data)(int class_index, void *obj, 165 void (*cb_free_ex_data)(int class_index, void *obj,
167 CRYPTO_EX_DATA *ad); 166 CRYPTO_EX_DATA *ad);
168 }; 167};
169 168
170/* The implementation we use at run-time */ 169/* The implementation we use at run-time */
171static const CRYPTO_EX_DATA_IMPL *impl = NULL; 170static const CRYPTO_EX_DATA_IMPL *impl = NULL;
172 171
173/* To call "impl" functions, use this macro rather than referring to 'impl' directly, eg. 172/* To call "impl" functions, use this macro rather than referring to 'impl' directly, eg.
174 * EX_IMPL(get_new_index)(...); */ 173 * EX_IMPL(get_new_index)(...);
174*/
175#define EX_IMPL(a) impl->cb_##a 175#define EX_IMPL(a) impl->cb_##a
176 176
177/* Predeclare the "default" ex_data implementation */ 177/* Predeclare the "default" ex_data implementation */
178static int int_new_class(void); 178static int int_new_class(void);
179static void int_cleanup(void); 179static void int_cleanup(void);
180static int int_get_new_index(int class_index, long argl, void *argp, 180static int int_get_new_index(int class_index, long argl, void *argp,
181 CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, 181 CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
182 CRYPTO_EX_free *free_func); 182 CRYPTO_EX_free *free_func);
183static int int_new_ex_data(int class_index, void *obj, 183static int int_new_ex_data(int class_index, void *obj,
184 CRYPTO_EX_DATA *ad); 184 CRYPTO_EX_DATA *ad);
185static int int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, 185static int int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
186 CRYPTO_EX_DATA *from); 186 CRYPTO_EX_DATA *from);
187static void int_free_ex_data(int class_index, void *obj, 187static void int_free_ex_data(int class_index, void *obj,
188 CRYPTO_EX_DATA *ad); 188 CRYPTO_EX_DATA *ad);
189static CRYPTO_EX_DATA_IMPL impl_default = 189
190 { 190static CRYPTO_EX_DATA_IMPL impl_default = {
191 int_new_class, 191 int_new_class,
192 int_cleanup, 192 int_cleanup,
193 int_get_new_index, 193 int_get_new_index,
194 int_new_ex_data, 194 int_new_ex_data,
195 int_dup_ex_data, 195 int_dup_ex_data,
196 int_free_ex_data 196 int_free_ex_data
197 }; 197};
198 198
199/* Internal function that checks whether "impl" is set and if not, sets it to 199/* Internal function that checks whether "impl" is set and if not, sets it to
200 * the default. */ 200 * the default. */
201static void impl_check(void) 201static void
202 { 202impl_check(void)
203{
203 CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); 204 CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
204 if(!impl) 205 if (!impl)
205 impl = &impl_default; 206 impl = &impl_default;
206 CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); 207 CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
207 } 208}
208/* A macro wrapper for impl_check that first uses a non-locked test before 209/* A macro wrapper for impl_check that first uses a non-locked test before
209 * invoking the function (which checks again inside a lock). */ 210 * invoking the function (which checks again inside a lock). */
210#define IMPL_CHECK if(!impl) impl_check(); 211#define IMPL_CHECK if(!impl) impl_check();
211 212
212/* API functions to get/set the "ex_data" implementation */ 213/* API functions to get/set the "ex_data" implementation */
213const CRYPTO_EX_DATA_IMPL *CRYPTO_get_ex_data_implementation(void) 214const CRYPTO_EX_DATA_IMPL
214 { 215*CRYPTO_get_ex_data_implementation(void)
216{
215 IMPL_CHECK 217 IMPL_CHECK
216 return impl; 218 return impl;
217 } 219}
218int CRYPTO_set_ex_data_implementation(const CRYPTO_EX_DATA_IMPL *i) 220
219 { 221int
222CRYPTO_set_ex_data_implementation(const CRYPTO_EX_DATA_IMPL *i)
223{
220 int toret = 0; 224 int toret = 0;
221 CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); 225 CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
222 if(!impl) 226 if (!impl) {
223 {
224 impl = i; 227 impl = i;
225 toret = 1; 228 toret = 1;
226 } 229 }
227 CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); 230 CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
228 return toret; 231 return toret;
229 } 232}
230 233
231/****************************************************************************/ 234/****************************************************************************/
232/* Interal (default) implementation of "ex_data" support. API functions are 235/* Interal (default) implementation of "ex_data" support. API functions are
@@ -249,288 +252,283 @@ DECLARE_LHASH_OF(EX_CLASS_ITEM);
249static LHASH_OF(EX_CLASS_ITEM) *ex_data = NULL; 252static LHASH_OF(EX_CLASS_ITEM) *ex_data = NULL;
250 253
251/* The callbacks required in the "ex_data" hash table */ 254/* The callbacks required in the "ex_data" hash table */
252static unsigned long ex_class_item_hash(const EX_CLASS_ITEM *a) 255static unsigned long
253 { 256ex_class_item_hash(const EX_CLASS_ITEM *a)
257{
254 return a->class_index; 258 return a->class_index;
255 } 259}
260
256static IMPLEMENT_LHASH_HASH_FN(ex_class_item, EX_CLASS_ITEM) 261static IMPLEMENT_LHASH_HASH_FN(ex_class_item, EX_CLASS_ITEM)
257 262
258static int ex_class_item_cmp(const EX_CLASS_ITEM *a, const EX_CLASS_ITEM *b) 263static int
259 { 264ex_class_item_cmp(const EX_CLASS_ITEM *a, const EX_CLASS_ITEM *b)
265{
260 return a->class_index - b->class_index; 266 return a->class_index - b->class_index;
261 } 267}
268
262static IMPLEMENT_LHASH_COMP_FN(ex_class_item, EX_CLASS_ITEM) 269static IMPLEMENT_LHASH_COMP_FN(ex_class_item, EX_CLASS_ITEM)
263 270
264/* Internal functions used by the "impl_default" implementation to access the 271/* Internal functions used by the "impl_default" implementation to access the
265 * state */ 272 * state */
266 273
267static int ex_data_check(void) 274static int
268 { 275ex_data_check(void)
276{
269 int toret = 1; 277 int toret = 1;
270 CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); 278 CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
271 if(!ex_data 279 if (!ex_data
272 && (ex_data = lh_EX_CLASS_ITEM_new()) == NULL) 280 && (ex_data = lh_EX_CLASS_ITEM_new()) == NULL)
273 toret = 0; 281 toret = 0;
274 CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); 282 CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
275 return toret; 283 return toret;
276 } 284}
277/* This macros helps reduce the locking from repeated checks because the 285/* This macros helps reduce the locking from repeated checks because the
278 * ex_data_check() function checks ex_data again inside a lock. */ 286 * ex_data_check() function checks ex_data again inside a lock. */
279#define EX_DATA_CHECK(iffail) if(!ex_data && !ex_data_check()) {iffail} 287#define EX_DATA_CHECK(iffail) if(!ex_data && !ex_data_check()) {iffail}
280 288
281/* This "inner" callback is used by the callback function that follows it */ 289/* This "inner" callback is used by the callback function that follows it */
282static void def_cleanup_util_cb(CRYPTO_EX_DATA_FUNCS *funcs) 290static void
283 { 291def_cleanup_util_cb(CRYPTO_EX_DATA_FUNCS *funcs)
292{
284 OPENSSL_free(funcs); 293 OPENSSL_free(funcs);
285 } 294}
286 295
287/* This callback is used in lh_doall to destroy all EX_CLASS_ITEM values from 296/* This callback is used in lh_doall to destroy all EX_CLASS_ITEM values from
288 * "ex_data" prior to the ex_data hash table being itself destroyed. Doesn't do 297 * "ex_data" prior to the ex_data hash table being itself destroyed. Doesn't do
289 * any locking. */ 298 * any locking. */
290static void def_cleanup_cb(void *a_void) 299static void
291 { 300def_cleanup_cb(void *a_void)
301{
292 EX_CLASS_ITEM *item = (EX_CLASS_ITEM *)a_void; 302 EX_CLASS_ITEM *item = (EX_CLASS_ITEM *)a_void;
293 sk_CRYPTO_EX_DATA_FUNCS_pop_free(item->meth, def_cleanup_util_cb); 303 sk_CRYPTO_EX_DATA_FUNCS_pop_free(item->meth, def_cleanup_util_cb);
294 OPENSSL_free(item); 304 OPENSSL_free(item);
295 } 305}
296 306
297/* Return the EX_CLASS_ITEM from the "ex_data" hash table that corresponds to a 307/* Return the EX_CLASS_ITEM from the "ex_data" hash table that corresponds to a
298 * given class. Handles locking. */ 308 * given class. Handles locking. */
299static EX_CLASS_ITEM *def_get_class(int class_index) 309static EX_CLASS_ITEM
300 { 310*def_get_class(int class_index)
311{
301 EX_CLASS_ITEM d, *p, *gen; 312 EX_CLASS_ITEM d, *p, *gen;
302 EX_DATA_CHECK(return NULL;) 313 EX_DATA_CHECK(return NULL;)
303 d.class_index = class_index; 314 d.class_index = class_index;
304 CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); 315 CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
305 p = lh_EX_CLASS_ITEM_retrieve(ex_data, &d); 316 p = lh_EX_CLASS_ITEM_retrieve(ex_data, &d);
306 if(!p) 317 if (!p) {
307 {
308 gen = OPENSSL_malloc(sizeof(EX_CLASS_ITEM)); 318 gen = OPENSSL_malloc(sizeof(EX_CLASS_ITEM));
309 if(gen) 319 if (gen) {
310 {
311 gen->class_index = class_index; 320 gen->class_index = class_index;
312 gen->meth_num = 0; 321 gen->meth_num = 0;
313 gen->meth = sk_CRYPTO_EX_DATA_FUNCS_new_null(); 322 gen->meth = sk_CRYPTO_EX_DATA_FUNCS_new_null();
314 if(!gen->meth) 323 if (!gen->meth)
315 OPENSSL_free(gen); 324 OPENSSL_free(gen);
316 else 325 else {
317 {
318 /* Because we're inside the ex_data lock, the 326 /* Because we're inside the ex_data lock, the
319 * return value from the insert will be NULL */ 327 * return value from the insert will be NULL */
320 (void)lh_EX_CLASS_ITEM_insert(ex_data, gen); 328 (void)lh_EX_CLASS_ITEM_insert(ex_data, gen);
321 p = gen; 329 p = gen;
322 }
323 } 330 }
324 } 331 }
332 }
325 CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); 333 CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
326 if(!p) 334 if (!p)
327 CRYPTOerr(CRYPTO_F_DEF_GET_CLASS,ERR_R_MALLOC_FAILURE); 335 CRYPTOerr(CRYPTO_F_DEF_GET_CLASS, ERR_R_MALLOC_FAILURE);
328 return p; 336 return p;
329 } 337}
330 338
331/* Add a new method to the given EX_CLASS_ITEM and return the corresponding 339/* Add a new method to the given EX_CLASS_ITEM and return the corresponding
332 * index (or -1 for error). Handles locking. */ 340 * index (or -1 for error). Handles locking. */
333static int def_add_index(EX_CLASS_ITEM *item, long argl, void *argp, 341static int
334 CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, 342def_add_index(EX_CLASS_ITEM *item, long argl, void *argp,
335 CRYPTO_EX_free *free_func) 343 CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
336 { 344{
337 int toret = -1; 345 int toret = -1;
338 CRYPTO_EX_DATA_FUNCS *a = (CRYPTO_EX_DATA_FUNCS *)OPENSSL_malloc( 346 CRYPTO_EX_DATA_FUNCS *a = (CRYPTO_EX_DATA_FUNCS *)OPENSSL_malloc(
339 sizeof(CRYPTO_EX_DATA_FUNCS)); 347 sizeof(CRYPTO_EX_DATA_FUNCS));
340 if(!a) 348 if (!a) {
341 { 349 CRYPTOerr(CRYPTO_F_DEF_ADD_INDEX, ERR_R_MALLOC_FAILURE);
342 CRYPTOerr(CRYPTO_F_DEF_ADD_INDEX,ERR_R_MALLOC_FAILURE);
343 return -1; 350 return -1;
344 } 351 }
345 a->argl=argl; 352 a->argl = argl;
346 a->argp=argp; 353 a->argp = argp;
347 a->new_func=new_func; 354 a->new_func = new_func;
348 a->dup_func=dup_func; 355 a->dup_func = dup_func;
349 a->free_func=free_func; 356 a->free_func = free_func;
350 CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); 357 CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
351 while (sk_CRYPTO_EX_DATA_FUNCS_num(item->meth) <= item->meth_num) 358 while (sk_CRYPTO_EX_DATA_FUNCS_num(item->meth) <= item->meth_num) {
352 { 359 if (!sk_CRYPTO_EX_DATA_FUNCS_push(item->meth, NULL)) {
353 if (!sk_CRYPTO_EX_DATA_FUNCS_push(item->meth, NULL)) 360 CRYPTOerr(CRYPTO_F_DEF_ADD_INDEX, ERR_R_MALLOC_FAILURE);
354 {
355 CRYPTOerr(CRYPTO_F_DEF_ADD_INDEX,ERR_R_MALLOC_FAILURE);
356 OPENSSL_free(a); 361 OPENSSL_free(a);
357 goto err; 362 goto err;
358 }
359 } 363 }
364 }
360 toret = item->meth_num++; 365 toret = item->meth_num++;
361 (void)sk_CRYPTO_EX_DATA_FUNCS_set(item->meth, toret, a); 366 (void)sk_CRYPTO_EX_DATA_FUNCS_set(item->meth, toret, a);
362err: 367err:
363 CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); 368 CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
364 return toret; 369 return toret;
365 } 370}
366 371
367/**************************************************************/ 372/**************************************************************/
368/* The functions in the default CRYPTO_EX_DATA_IMPL structure */ 373/* The functions in the default CRYPTO_EX_DATA_IMPL structure */
369 374
370static int int_new_class(void) 375static int
371 { 376int_new_class(void)
377{
372 int toret; 378 int toret;
373 CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); 379 CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
374 toret = ex_class++; 380 toret = ex_class++;
375 CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); 381 CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
376 return toret; 382 return toret;
377 } 383}
378 384
379static void int_cleanup(void) 385static void
380 { 386int_cleanup(void)
387{
381 EX_DATA_CHECK(return;) 388 EX_DATA_CHECK(return;)
382 lh_EX_CLASS_ITEM_doall(ex_data, def_cleanup_cb); 389 lh_EX_CLASS_ITEM_doall(ex_data, def_cleanup_cb);
383 lh_EX_CLASS_ITEM_free(ex_data); 390 lh_EX_CLASS_ITEM_free(ex_data);
384 ex_data = NULL; 391 ex_data = NULL;
385 impl = NULL; 392 impl = NULL;
386 } 393}
387 394
388static int int_get_new_index(int class_index, long argl, void *argp, 395static int
389 CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, 396int_get_new_index(int class_index, long argl, void *argp,
390 CRYPTO_EX_free *free_func) 397 CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
391 { 398CRYPTO_EX_free *free_func)
399{
392 EX_CLASS_ITEM *item = def_get_class(class_index); 400 EX_CLASS_ITEM *item = def_get_class(class_index);
393 if(!item) 401 if (!item)
394 return -1; 402 return -1;
395 return def_add_index(item, argl, argp, new_func, dup_func, free_func); 403 return def_add_index(item, argl, argp, new_func, dup_func, free_func);
396 } 404}
397 405
398/* Thread-safe by copying a class's array of "CRYPTO_EX_DATA_FUNCS" entries in 406/* Thread-safe by copying a class's array of "CRYPTO_EX_DATA_FUNCS" entries in
399 * the lock, then using them outside the lock. NB: Thread-safety only applies to 407 * the lock, then using them outside the lock. NB: Thread-safety only applies to
400 * the global "ex_data" state (ie. class definitions), not thread-safe on 'ad' 408 * the global "ex_data" state (ie. class definitions), not thread-safe on 'ad'
401 * itself. */ 409 * itself. */
402static int int_new_ex_data(int class_index, void *obj, 410static int
403 CRYPTO_EX_DATA *ad) 411int_new_ex_data(int class_index, void *obj,
404 { 412 CRYPTO_EX_DATA *ad)
405 int mx,i; 413{
414 int mx, i;
406 void *ptr; 415 void *ptr;
407 CRYPTO_EX_DATA_FUNCS **storage = NULL; 416 CRYPTO_EX_DATA_FUNCS **storage = NULL;
408 EX_CLASS_ITEM *item = def_get_class(class_index); 417 EX_CLASS_ITEM *item = def_get_class(class_index);
409 if(!item) 418 if (!item)
410 /* error is already set */ 419 /* error is already set */
411 return 0; 420 return 0;
412 ad->sk = NULL; 421 ad->sk = NULL;
413 CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA); 422 CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA);
414 mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth); 423 mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth);
415 if(mx > 0) 424 if (mx > 0) {
416 {
417 storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS*)); 425 storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS*));
418 if(!storage) 426 if (!storage)
419 goto skip; 427 goto skip;
420 for(i = 0; i < mx; i++) 428 for (i = 0; i < mx; i++)
421 storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth,i); 429 storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth, i);
422 } 430 }
423skip: 431skip:
424 CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA); 432 CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA);
425 if((mx > 0) && !storage) 433 if ((mx > 0) && !storage) {
426 { 434 CRYPTOerr(CRYPTO_F_INT_NEW_EX_DATA, ERR_R_MALLOC_FAILURE);
427 CRYPTOerr(CRYPTO_F_INT_NEW_EX_DATA,ERR_R_MALLOC_FAILURE);
428 return 0; 435 return 0;
429 } 436 }
430 for(i = 0; i < mx; i++) 437 for (i = 0; i < mx; i++) {
431 { 438 if (storage[i] && storage[i]->new_func) {
432 if(storage[i] && storage[i]->new_func)
433 {
434 ptr = CRYPTO_get_ex_data(ad, i); 439 ptr = CRYPTO_get_ex_data(ad, i);
435 storage[i]->new_func(obj,ptr,ad,i, 440 storage[i]->new_func(obj, ptr, ad, i,
436 storage[i]->argl,storage[i]->argp); 441 storage[i]->argl, storage[i]->argp);
437 }
438 } 442 }
439 if(storage) 443 }
444 if (storage)
440 OPENSSL_free(storage); 445 OPENSSL_free(storage);
441 return 1; 446 return 1;
442 } 447}
443 448
444/* Same thread-safety notes as for "int_new_ex_data" */ 449/* Same thread-safety notes as for "int_new_ex_data" */
445static int int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, 450static int
446 CRYPTO_EX_DATA *from) 451int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
447 { 452 CRYPTO_EX_DATA *from)
453{
448 int mx, j, i; 454 int mx, j, i;
449 char *ptr; 455 char *ptr;
450 CRYPTO_EX_DATA_FUNCS **storage = NULL; 456 CRYPTO_EX_DATA_FUNCS **storage = NULL;
451 EX_CLASS_ITEM *item; 457 EX_CLASS_ITEM *item;
452 if(!from->sk) 458 if (!from->sk)
453 /* 'to' should be "blank" which *is* just like 'from' */ 459 /* 'to' should be "blank" which *is* just like 'from' */
454 return 1; 460 return 1;
455 if((item = def_get_class(class_index)) == NULL) 461 if ((item = def_get_class(class_index)) == NULL)
456 return 0; 462 return 0;
457 CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA); 463 CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA);
458 mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth); 464 mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth);
459 j = sk_void_num(from->sk); 465 j = sk_void_num(from->sk);
460 if(j < mx) 466 if (j < mx)
461 mx = j; 467 mx = j;
462 if(mx > 0) 468 if (mx > 0) {
463 {
464 storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS*)); 469 storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS*));
465 if(!storage) 470 if (!storage)
466 goto skip; 471 goto skip;
467 for(i = 0; i < mx; i++) 472 for (i = 0; i < mx; i++)
468 storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth,i); 473 storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth, i);
469 } 474 }
470skip: 475skip:
471 CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA); 476 CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA);
472 if((mx > 0) && !storage) 477 if ((mx > 0) && !storage) {
473 { 478 CRYPTOerr(CRYPTO_F_INT_DUP_EX_DATA, ERR_R_MALLOC_FAILURE);
474 CRYPTOerr(CRYPTO_F_INT_DUP_EX_DATA,ERR_R_MALLOC_FAILURE);
475 return 0; 479 return 0;
476 } 480 }
477 for(i = 0; i < mx; i++) 481 for (i = 0; i < mx; i++) {
478 {
479 ptr = CRYPTO_get_ex_data(from, i); 482 ptr = CRYPTO_get_ex_data(from, i);
480 if(storage[i] && storage[i]->dup_func) 483 if (storage[i] && storage[i]->dup_func)
481 storage[i]->dup_func(to,from,&ptr,i, 484 storage[i]->dup_func(to, from, &ptr, i,
482 storage[i]->argl,storage[i]->argp); 485 storage[i]->argl, storage[i]->argp);
483 CRYPTO_set_ex_data(to,i,ptr); 486 CRYPTO_set_ex_data(to, i, ptr);
484 } 487 }
485 if(storage) 488 if (storage)
486 OPENSSL_free(storage); 489 OPENSSL_free(storage);
487 return 1; 490 return 1;
488 } 491}
489 492
490/* Same thread-safety notes as for "int_new_ex_data" */ 493/* Same thread-safety notes as for "int_new_ex_data" */
491static void int_free_ex_data(int class_index, void *obj, 494static void
492 CRYPTO_EX_DATA *ad) 495int_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
493 { 496{
494 int mx,i; 497 int mx, i;
495 EX_CLASS_ITEM *item; 498 EX_CLASS_ITEM *item;
496 void *ptr; 499 void *ptr;
497 CRYPTO_EX_DATA_FUNCS **storage = NULL; 500 CRYPTO_EX_DATA_FUNCS **storage = NULL;
498 if((item = def_get_class(class_index)) == NULL) 501 if ((item = def_get_class(class_index)) == NULL)
499 return; 502 return;
500 CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA); 503 CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA);
501 mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth); 504 mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth);
502 if(mx > 0) 505 if (mx > 0) {
503 {
504 storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS*)); 506 storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS*));
505 if(!storage) 507 if (!storage)
506 goto skip; 508 goto skip;
507 for(i = 0; i < mx; i++) 509 for (i = 0; i < mx; i++)
508 storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth,i); 510 storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth, i);
509 } 511 }
510skip: 512skip:
511 CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA); 513 CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA);
512 if((mx > 0) && !storage) 514 if ((mx > 0) && !storage) {
513 { 515 CRYPTOerr(CRYPTO_F_INT_FREE_EX_DATA, ERR_R_MALLOC_FAILURE);
514 CRYPTOerr(CRYPTO_F_INT_FREE_EX_DATA,ERR_R_MALLOC_FAILURE);
515 return; 516 return;
517 }
518 for (i = 0; i < mx; i++) {
519 if (storage[i] && storage[i]->free_func) {
520 ptr = CRYPTO_get_ex_data(ad, i);
521 storage[i]->free_func(obj, ptr, ad, i,
522 storage[i]->argl, storage[i]->argp);
516 } 523 }
517 for(i = 0; i < mx; i++) 524 }
518 { 525 if (storage)
519 if(storage[i] && storage[i]->free_func)
520 {
521 ptr = CRYPTO_get_ex_data(ad,i);
522 storage[i]->free_func(obj,ptr,ad,i,
523 storage[i]->argl,storage[i]->argp);
524 }
525 }
526 if(storage)
527 OPENSSL_free(storage); 526 OPENSSL_free(storage);
528 if(ad->sk) 527 if (ad->sk) {
529 {
530 sk_void_free(ad->sk); 528 sk_void_free(ad->sk);
531 ad->sk=NULL; 529 ad->sk = NULL;
532 }
533 } 530 }
531}
534 532
535/********************************************************************/ 533/********************************************************************/
536/* API functions that defer all "state" operations to the "ex_data" 534/* API functions that defer all "state" operations to the "ex_data"
@@ -538,99 +536,101 @@ skip:
538 536
539/* Obtain an index for a new class (not the same as getting a new index within 537/* Obtain an index for a new class (not the same as getting a new index within
540 * an existing class - this is actually getting a new *class*) */ 538 * an existing class - this is actually getting a new *class*) */
541int CRYPTO_ex_data_new_class(void) 539int
542 { 540CRYPTO_ex_data_new_class(void)
541{
543 IMPL_CHECK 542 IMPL_CHECK
544 return EX_IMPL(new_class)(); 543 return EX_IMPL(new_class)();
545 } 544}
546 545
547/* Release all "ex_data" state to prevent memory leaks. This can't be made 546/* Release all "ex_data" state to prevent memory leaks. This can't be made
548 * thread-safe without overhauling a lot of stuff, and shouldn't really be 547 * thread-safe without overhauling a lot of stuff, and shouldn't really be
549 * called under potential race-conditions anyway (it's for program shutdown 548 * called under potential race-conditions anyway (it's for program shutdown
550 * after all). */ 549 * after all). */
551void CRYPTO_cleanup_all_ex_data(void) 550void
552 { 551CRYPTO_cleanup_all_ex_data(void)
552{
553 IMPL_CHECK 553 IMPL_CHECK
554 EX_IMPL(cleanup)(); 554 EX_IMPL(cleanup)();
555 } 555}
556 556
557/* Inside an existing class, get/register a new index. */ 557/* Inside an existing class, get/register a new index. */
558int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp, 558int
559 CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, 559CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
560 CRYPTO_EX_free *free_func) 560 CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
561 { 561{
562 int ret = -1; 562 int ret = -1;
563 563
564 IMPL_CHECK 564 IMPL_CHECK
565 ret = EX_IMPL(get_new_index)(class_index, 565 ret = EX_IMPL(get_new_index)(class_index,
566 argl, argp, new_func, dup_func, free_func); 566 argl, argp, new_func, dup_func, free_func);
567 return ret; 567 return ret;
568 } 568}
569 569
570/* Initialise a new CRYPTO_EX_DATA for use in a particular class - including 570/* Initialise a new CRYPTO_EX_DATA for use in a particular class - including
571 * calling new() callbacks for each index in the class used by this variable */ 571 * calling new() callbacks for each index in the class used by this variable */
572int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) 572int
573 { 573CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
574{
574 IMPL_CHECK 575 IMPL_CHECK
575 return EX_IMPL(new_ex_data)(class_index, obj, ad); 576 return EX_IMPL(new_ex_data)(class_index, obj, ad);
576 } 577}
577 578
578/* Duplicate a CRYPTO_EX_DATA variable - including calling dup() callbacks for 579/* Duplicate a CRYPTO_EX_DATA variable - including calling dup() callbacks for
579 * each index in the class used by this variable */ 580 * each index in the class used by this variable */
580int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, 581int
581 CRYPTO_EX_DATA *from) 582CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from)
582 { 583{
583 IMPL_CHECK 584 IMPL_CHECK
584 return EX_IMPL(dup_ex_data)(class_index, to, from); 585 return EX_IMPL(dup_ex_data)(class_index, to, from);
585 } 586}
586 587
587/* Cleanup a CRYPTO_EX_DATA variable - including calling free() callbacks for 588/* Cleanup a CRYPTO_EX_DATA variable - including calling free() callbacks for
588 * each index in the class used by this variable */ 589 * each index in the class used by this variable */
589void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) 590void
590 { 591CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
592{
591 IMPL_CHECK 593 IMPL_CHECK
592 EX_IMPL(free_ex_data)(class_index, obj, ad); 594 EX_IMPL(free_ex_data)(class_index, obj, ad);
593 } 595}
594 596
595/* For a given CRYPTO_EX_DATA variable, set the value corresponding to a 597/* For a given CRYPTO_EX_DATA variable, set the value corresponding to a
596 * particular index in the class used by this variable */ 598 * particular index in the class used by this variable */
597int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val) 599int
598 { 600CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val)
601{
599 int i; 602 int i;
600 603
601 if (ad->sk == NULL) 604 if (ad->sk == NULL) {
602 { 605 if ((ad->sk = sk_void_new_null()) == NULL) {
603 if ((ad->sk=sk_void_new_null()) == NULL) 606 CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA, ERR_R_MALLOC_FAILURE);
604 { 607 return (0);
605 CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA,ERR_R_MALLOC_FAILURE);
606 return(0);
607 }
608 } 608 }
609 i=sk_void_num(ad->sk); 609 }
610 610 i = sk_void_num(ad->sk);
611 while (i <= idx) 611
612 { 612 while (i <= idx) {
613 if (!sk_void_push(ad->sk,NULL)) 613 if (!sk_void_push(ad->sk, NULL)) {
614 { 614 CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA, ERR_R_MALLOC_FAILURE);
615 CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA,ERR_R_MALLOC_FAILURE); 615 return (0);
616 return(0);
617 }
618 i++;
619 } 616 }
620 sk_void_set(ad->sk,idx,val); 617 i++;
621 return(1);
622 } 618 }
619 sk_void_set(ad->sk, idx, val);
620 return (1);
621}
623 622
624/* For a given CRYPTO_EX_DATA_ variable, get the value corresponding to a 623/* For a given CRYPTO_EX_DATA_ variable, get the value corresponding to a
625 * particular index in the class used by this variable */ 624 * particular index in the class used by this variable */
626void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx) 625void
627 { 626*CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx)
627{
628 if (ad->sk == NULL) 628 if (ad->sk == NULL)
629 return(0); 629 return (0);
630 else if (idx >= sk_void_num(ad->sk)) 630 else if (idx >= sk_void_num(ad->sk))
631 return(0); 631 return (0);
632 else 632 else
633 return(sk_void_value(ad->sk,idx)); 633 return (sk_void_value(ad->sk, idx));
634 } 634}
635 635
636IMPLEMENT_STACK_OF(CRYPTO_EX_DATA_FUNCS) 636IMPLEMENT_STACK_OF(CRYPTO_EX_DATA_FUNCS)