290 lines
5.9 KiB
C
Executable File
290 lines
5.9 KiB
C
Executable File
#include"bio.h"
|
|
#include"errno.h"
|
|
#include"cryptlib.h"
|
|
#include"lhash.h"
|
|
#include"myfunction.h"
|
|
|
|
static int ex_data_check(void);
|
|
|
|
#define EX_IMPL(a) impl->cb_##a
|
|
#define IMPL_CHECK if(!impl) impl_check();
|
|
#define EX_DATA_CHECK(iffail) if(!ex_data && !ex_data_check()) {iffail}
|
|
|
|
typedef struct st_ex_class_item {
|
|
int class_index;
|
|
STACK_OF(CRYPTO_EX_DATA_FUNCS) *meth;
|
|
int meth_num;
|
|
} EX_CLASS_ITEM;
|
|
|
|
typedef struct st_CRYPTO_EX_DATA_IMPL CRYPTO_EX_DATA_IMPL;
|
|
|
|
static const CRYPTO_EX_DATA_IMPL *impl = NULL;
|
|
static LHASH *ex_data = NULL;
|
|
|
|
struct st_CRYPTO_EX_DATA_IMPL
|
|
{
|
|
|
|
int (*cb_new_ex_data)(int class_index, void *obj,
|
|
CRYPTO_EX_DATA *ad);
|
|
void (*cb_free_ex_data)(int class_index, void *obj,
|
|
CRYPTO_EX_DATA *ad);
|
|
};
|
|
|
|
|
|
///////////////////impl_default/////////////
|
|
|
|
static int int_new_ex_data(int class_index, void *obj,
|
|
CRYPTO_EX_DATA *ad);
|
|
|
|
static void int_free_ex_data(int class_index, void *obj,
|
|
CRYPTO_EX_DATA *ad);
|
|
|
|
static CRYPTO_EX_DATA_IMPL impl_default =
|
|
{
|
|
int_new_ex_data,
|
|
int_free_ex_data
|
|
};
|
|
|
|
///////////////ex_hash_cb//////////////////////ok
|
|
|
|
static unsigned long ex_hash_cb(const void *a_void)
|
|
{
|
|
|
|
return ((const EX_CLASS_ITEM *)a_void)->class_index;
|
|
}
|
|
|
|
///////////////ex_cmp_cb/////////////////////////////ok
|
|
|
|
static int ex_cmp_cb(const void *a_void, const void *b_void)
|
|
{
|
|
|
|
return (((const EX_CLASS_ITEM *)a_void)->class_index -
|
|
((const EX_CLASS_ITEM *)b_void)->class_index);
|
|
}
|
|
|
|
|
|
///////////IMPL_CHECK///////////////////////ok
|
|
|
|
static void impl_check(void)
|
|
{
|
|
|
|
//CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
|
|
if(!impl)
|
|
impl = &impl_default;
|
|
//CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
|
|
}
|
|
|
|
////////////////CRYPTO_new_ex_data/////////////////ok
|
|
|
|
int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
|
|
{
|
|
|
|
IMPL_CHECK
|
|
return EX_IMPL(new_ex_data)(class_index, obj, ad);
|
|
}
|
|
|
|
/////////////////CRYPTO_free_ex_data///////////////////////////ok
|
|
|
|
void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
|
|
{
|
|
|
|
IMPL_CHECK
|
|
EX_IMPL(free_ex_data)(class_index, obj, ad);
|
|
}
|
|
|
|
//////////bio_set////////////////////////ok
|
|
|
|
int BIO_set(BIO *bio, BIO_METHOD *method)
|
|
{
|
|
bio->method=method;
|
|
bio->callback=NULL;
|
|
bio->cb_arg=NULL;
|
|
bio->init=0;
|
|
bio->shutdown=1;
|
|
bio->flags=0;
|
|
bio->retry_reason=0;
|
|
bio->num=0;
|
|
bio->ptr=NULL;
|
|
bio->prev_bio=NULL;
|
|
bio->next_bio=NULL;
|
|
bio->references=1;
|
|
bio->num_read=0L;
|
|
bio->num_write=0L;
|
|
|
|
CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
|
|
if (method->create != NULL)
|
|
if (!method->create(bio))
|
|
{
|
|
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio,
|
|
&bio->ex_data);
|
|
return(0);
|
|
}
|
|
return(1);
|
|
}
|
|
|
|
|
|
/////////////////BI0_new//////////////ok
|
|
|
|
BIO *BIO_new(BIO_METHOD *method)
|
|
{
|
|
BIO *ret=NULL;
|
|
|
|
ret=(BIO *)OPENSSL_malloc(sizeof(BIO));
|
|
if (ret == NULL)
|
|
{
|
|
|
|
return(NULL);
|
|
}
|
|
if (!BIO_set(ret,method))
|
|
{
|
|
OPENSSL_free(ret);
|
|
ret=NULL;
|
|
}
|
|
return(ret);
|
|
}
|
|
|
|
|
|
///////////////////def_get_class////////////////////////////////////////ok
|
|
|
|
static EX_CLASS_ITEM *def_get_class(int class_index)
|
|
{
|
|
EX_CLASS_ITEM d, *p, *gen;
|
|
|
|
EX_DATA_CHECK(return NULL;)
|
|
d.class_index = class_index;
|
|
//CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
|
|
p = lh_retrieve(ex_data, &d);
|
|
if(!p)
|
|
{
|
|
gen = OPENSSL_malloc(sizeof(EX_CLASS_ITEM));
|
|
if(gen)
|
|
{
|
|
gen->class_index = class_index;
|
|
gen->meth_num = 0;
|
|
gen->meth = sk_CRYPTO_EX_DATA_FUNCS_new_null();
|
|
if(!gen->meth)
|
|
OPENSSL_free(gen);
|
|
else
|
|
{
|
|
|
|
lh_insert(ex_data, gen);
|
|
p = gen;
|
|
}
|
|
}
|
|
}
|
|
//CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
|
|
if(!p)
|
|
CRYPTOerr(CRYPTO_F_DEF_GET_CLASS,ERR_R_MALLOC_FAILURE);
|
|
return p;
|
|
}
|
|
|
|
|
|
|
|
///////////////////int_new_ex_data/////////////////////////////////////////ok
|
|
|
|
static int int_new_ex_data(int class_index, void *obj,
|
|
CRYPTO_EX_DATA *ad)
|
|
{
|
|
int mx,i;
|
|
CRYPTO_EX_DATA_FUNCS **storage = NULL;
|
|
|
|
EX_CLASS_ITEM *item = def_get_class(class_index);
|
|
|
|
if(!item)
|
|
/* error is already set */
|
|
return 0;
|
|
ad->sk = NULL;
|
|
//CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA);
|
|
mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth);
|
|
if(mx > 0)
|
|
{
|
|
storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS*));
|
|
if(!storage)
|
|
goto skip;
|
|
for(i = 0; i < mx; i++)
|
|
storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth,i);
|
|
}
|
|
skip:
|
|
//CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA);
|
|
if((mx > 0) && !storage)
|
|
{
|
|
CRYPTOerr(CRYPTO_F_INT_NEW_EX_DATA,ERR_R_MALLOC_FAILURE);
|
|
return 0;
|
|
}
|
|
for(i = 0; i < mx; i++)
|
|
{
|
|
if(storage[i] && storage[i]->new_func)
|
|
{
|
|
;
|
|
}
|
|
}
|
|
if(storage)
|
|
OPENSSL_free(storage);
|
|
return 1;
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////ex_data_check//////////////////////////////////////////ok
|
|
|
|
static int ex_data_check(void)
|
|
{
|
|
int toret = 1;
|
|
|
|
//CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
|
|
if(!ex_data && ((ex_data = lh_new(ex_hash_cb, ex_cmp_cb)) == NULL))
|
|
toret = 0;
|
|
//CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
|
|
return toret;
|
|
}
|
|
|
|
///////////////int_free_ex_data/////////////////////////////////////////ok
|
|
|
|
static void int_free_ex_data(int class_index, void *obj,
|
|
CRYPTO_EX_DATA *ad)
|
|
{
|
|
int mx,i;
|
|
EX_CLASS_ITEM *item;
|
|
CRYPTO_EX_DATA_FUNCS **storage = NULL;
|
|
|
|
if((item = def_get_class(class_index)) == NULL)
|
|
return;
|
|
//CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA);
|
|
mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth);
|
|
if(mx > 0)
|
|
{
|
|
storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS*));
|
|
if(!storage)
|
|
goto skip;
|
|
for(i = 0; i < mx; i++)
|
|
storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth,i);
|
|
}
|
|
skip:
|
|
//CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA);
|
|
if((mx > 0) && !storage)
|
|
{
|
|
CRYPTOerr(CRYPTO_F_INT_FREE_EX_DATA,ERR_R_MALLOC_FAILURE);
|
|
return;
|
|
}
|
|
for(i = 0; i < mx; i++)
|
|
{
|
|
if(storage[i] && storage[i]->free_func)
|
|
{
|
|
;
|
|
}
|
|
}
|
|
if(storage)
|
|
OPENSSL_free(storage);
|
|
if(ad->sk)
|
|
{
|
|
sk_free(ad->sk);
|
|
ad->sk=NULL;
|
|
}
|
|
}
|
|
|
|
void reset_BIO_reset(void)
|
|
{
|
|
impl = NULL;
|
|
ex_data = NULL;
|
|
} |