Remove the dual-callback scheme for numeric and pointer thread IDs,
deprecate the original (numeric-only) scheme, and replace with the CRYPTO_THREADID object. This hides the platform-specifics and should reduce the possibility for programming errors (where failing to explicitly check both thread ID forms could create subtle, platform-specific bugs). Thanks to Bodo, for invaluable review and feedback.
This commit is contained in:
parent
96826bfc84
commit
4c3296960d
48
CHANGES
48
CHANGES
@ -4,6 +4,30 @@
|
||||
|
||||
Changes between 0.9.8i and 0.9.9 [xx XXX xxxx]
|
||||
|
||||
*) To cater for systems that provide a pointer-based thread ID rather
|
||||
than numeric, deprecate the current numeric thread ID mechanism and
|
||||
replace it with a structure and associated callback type. This
|
||||
mechanism allows a numeric "hash" to be extracted from a thread ID in
|
||||
either case, and on platforms where pointers are larger than 'long',
|
||||
mixing is done to help ensure the numeric 'hash' is usable even if it
|
||||
can't be guaranteed unique. The default mechanism is to use "&errno"
|
||||
as a pointer-based thread ID to distinguish between threads.
|
||||
|
||||
Applications that want to provide their own thread IDs should now use
|
||||
CRYPTO_THREADID_set_callback() to register a callback that will call
|
||||
either CRYPTO_THREADID_set_numeric() or CRYPTO_THREADID_set_pointer().
|
||||
|
||||
(This new approach replaces the functions CRYPTO_set_idptr_callback(),
|
||||
CRYPTO_get_idptr_callback(), and CRYPTO_thread_idptr() that existed in
|
||||
OpenSSL 0.9.9-dev between June 2006 and August 2008. Also, if an
|
||||
application was previously providing a numeric thread callback that
|
||||
was inappropriate for distinguishing threads, then uniqueness might
|
||||
have been obtained with &errno that happened immediately in the
|
||||
intermediate development versions of OpenSSL; this is no longer the
|
||||
case, the numeric thread callback will now override the automatic use
|
||||
of &errno.)
|
||||
[Geoff Thorpe, with help from Bodo Moeller]
|
||||
|
||||
*) Initial support for different CRL issuing certificates. This covers a
|
||||
simple case where the self issued certificates in the chain exist and
|
||||
the real CRL issuer is higher in the existing chain.
|
||||
@ -307,30 +331,6 @@
|
||||
list-message-digest-algorithms and list-cipher-algorithms.
|
||||
[Steve Henson]
|
||||
|
||||
*) In addition to the numerical (unsigned long) thread ID, provide
|
||||
for a pointer (void *) thread ID. This helps accomodate systems
|
||||
that do not provide an unsigned long thread ID. OpenSSL assumes
|
||||
it is in the same thread iff both the numerical and the pointer
|
||||
thread ID agree; so applications are just required to define one
|
||||
of them appropriately (e.g., by using a pointer to a per-thread
|
||||
memory object malloc()ed by the application for the pointer-type
|
||||
thread ID). Exactly analoguous to the existing functions
|
||||
|
||||
void CRYPTO_set_id_callback(unsigned long (*func)(void));
|
||||
unsigned long (*CRYPTO_get_id_callback(void))(void);
|
||||
unsigned long CRYPTO_thread_id(void);
|
||||
|
||||
we now have additional functions
|
||||
|
||||
void CRYPTO_set_idptr_callback(void *(*func)(void));
|
||||
void *(*CRYPTO_get_idptr_callback(void))(void);
|
||||
void *CRYPTO_thread_idptr(void);
|
||||
|
||||
also in <openssl/crypto.h>. The default value for
|
||||
CRYPTO_thread_idptr() if the application has not provided its own
|
||||
callback is &errno.
|
||||
[Bodo Moeller]
|
||||
|
||||
*) Change the array representation of binary polynomials: the list
|
||||
of degrees of non-zero coefficients is now terminated with -1.
|
||||
Previously it was terminated with 0, which was also part of the
|
||||
|
4
FAQ
4
FAQ
@ -717,9 +717,7 @@ file.
|
||||
|
||||
Multi-threaded applications must provide two callback functions to
|
||||
OpenSSL by calling CRYPTO_set_locking_callback() and
|
||||
CRYPTO_set_id_callback(). (For OpenSSL 0.9.9 or later, the new
|
||||
function CRYPTO_set_idptr_callback() may be used in place of
|
||||
CRYPTO_set_id_callback().) This is described in the threads(3)
|
||||
CRYPTO_set_id_callback(). This is described in the threads(3)
|
||||
manpage.
|
||||
|
||||
* I've compiled a program under Windows and it crashes: why?
|
||||
|
@ -181,7 +181,7 @@ extern BIO *bio_err;
|
||||
# define apps_shutdown() \
|
||||
do { CONF_modules_unload(1); destroy_ui_method(); \
|
||||
OBJ_cleanup(); EVP_cleanup(); ENGINE_cleanup(); \
|
||||
CRYPTO_cleanup_all_ex_data(); ERR_remove_state(0); \
|
||||
CRYPTO_cleanup_all_ex_data(); ERR_remove_thread_state(NULL); \
|
||||
ERR_free_strings(); COMP_zlib_cleanup();} while(0)
|
||||
# else
|
||||
# define apps_startup() \
|
||||
@ -191,7 +191,7 @@ extern BIO *bio_err;
|
||||
# define apps_shutdown() \
|
||||
do { CONF_modules_unload(1); destroy_ui_method(); \
|
||||
OBJ_cleanup(); EVP_cleanup(); \
|
||||
CRYPTO_cleanup_all_ex_data(); ERR_remove_state(0); \
|
||||
CRYPTO_cleanup_all_ex_data(); ERR_remove_thread_state(NULL); \
|
||||
ERR_free_strings(); } while(0)
|
||||
# endif
|
||||
#endif
|
||||
|
@ -130,6 +130,7 @@
|
||||
#include <stdio.h> /* FILE */
|
||||
#endif
|
||||
#include <openssl/ossl_typ.h>
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -564,10 +565,11 @@ int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
|
||||
int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
|
||||
int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *);
|
||||
int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *);
|
||||
#ifndef OPENSSL_NO_DEPRECATED
|
||||
unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *);
|
||||
void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long);
|
||||
void *BN_BLINDING_get_thread_idptr(const BN_BLINDING *);
|
||||
void BN_BLINDING_set_thread_idptr(BN_BLINDING *, void *);
|
||||
#endif
|
||||
CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *);
|
||||
unsigned long BN_BLINDING_get_flags(const BN_BLINDING *);
|
||||
void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long);
|
||||
BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
|
||||
|
@ -121,10 +121,11 @@ struct bn_blinding_st
|
||||
BIGNUM *Ai;
|
||||
BIGNUM *e;
|
||||
BIGNUM *mod; /* just a reference */
|
||||
#ifndef OPENSSL_NO_DEPRECATED
|
||||
unsigned long thread_id; /* added in OpenSSL 0.9.6j and 0.9.7b;
|
||||
* used only by crypto/rsa/rsa_eay.c, rsa_lib.c */
|
||||
void *thread_idptr; /* added in OpenSSL 0.9.9;
|
||||
* used only by crypto/rsa/rsa_eay.c, rsa_lib.c */
|
||||
#endif
|
||||
CRYPTO_THREADID tid;
|
||||
unsigned int counter;
|
||||
unsigned long flags;
|
||||
BN_MONT_CTX *m_ctx;
|
||||
@ -160,6 +161,7 @@ BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod)
|
||||
BN_set_flags(ret->mod, BN_FLG_CONSTTIME);
|
||||
|
||||
ret->counter = BN_BLINDING_COUNTER;
|
||||
CRYPTO_THREADID_current(&ret->tid);
|
||||
return(ret);
|
||||
err:
|
||||
if (ret != NULL) BN_BLINDING_free(ret);
|
||||
@ -265,6 +267,7 @@ int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *ct
|
||||
return(ret);
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_DEPRECATED
|
||||
unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *b)
|
||||
{
|
||||
return b->thread_id;
|
||||
@ -274,15 +277,11 @@ void BN_BLINDING_set_thread_id(BN_BLINDING *b, unsigned long n)
|
||||
{
|
||||
b->thread_id = n;
|
||||
}
|
||||
#endif
|
||||
|
||||
void *BN_BLINDING_get_thread_idptr(const BN_BLINDING *b)
|
||||
CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *b)
|
||||
{
|
||||
return b->thread_idptr;
|
||||
}
|
||||
|
||||
void BN_BLINDING_set_thread_idptr(BN_BLINDING *b, void *p)
|
||||
{
|
||||
b->thread_idptr = p;
|
||||
return &b->tid;
|
||||
}
|
||||
|
||||
unsigned long BN_BLINDING_get_flags(const BN_BLINDING *b)
|
||||
|
@ -187,7 +187,7 @@ int main(int argc, char *argv[])
|
||||
BN_free(b);
|
||||
BN_free(m);
|
||||
BN_CTX_free(ctx);
|
||||
ERR_remove_state(0);
|
||||
ERR_remove_thread_state(NULL);
|
||||
CRYPTO_mem_leaks(out);
|
||||
BIO_free(out);
|
||||
printf(" done\n");
|
||||
|
@ -184,8 +184,10 @@ static void (MS_FAR *locking_callback)(int mode,int type,
|
||||
const char *file,int line)=0;
|
||||
static int (MS_FAR *add_lock_callback)(int *pointer,int amount,
|
||||
int type,const char *file,int line)=0;
|
||||
#ifndef OPENSSL_NO_DEPRECATED
|
||||
static unsigned long (MS_FAR *id_callback)(void)=0;
|
||||
static void *(MS_FAR *idptr_callback)(void)=0;
|
||||
#endif
|
||||
static void (MS_FAR *threadid_callback)(CRYPTO_THREADID *)=0;
|
||||
static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback)
|
||||
(const char *file,int line)=0;
|
||||
static void (MS_FAR *dynlock_lock_callback)(int mode,
|
||||
@ -414,6 +416,108 @@ void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type,
|
||||
add_lock_callback=func;
|
||||
}
|
||||
|
||||
/* the memset() here and in set_pointer() seem overkill, but for the sake of
|
||||
* CRYPTO_THREADID_cmp() this avoids any platform silliness that might cause two
|
||||
* "equal" THREADID structs to not be memcmp()-identical. */
|
||||
void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val)
|
||||
{
|
||||
memset(id, 0, sizeof(*id));
|
||||
id->val = val;
|
||||
}
|
||||
|
||||
static const unsigned char hash_coeffs[] = { 3, 5, 7, 11, 13, 17, 19, 23 };
|
||||
void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr)
|
||||
{
|
||||
unsigned char *dest = (void *)&id->val;
|
||||
unsigned int accum = 0;
|
||||
unsigned char dnum = sizeof(id->val);
|
||||
|
||||
memset(id, 0, sizeof(*id));
|
||||
id->ptr = ptr;
|
||||
if (sizeof(id->val) >= sizeof(id->ptr))
|
||||
{
|
||||
/* 'ptr' can be embedded in 'val' without loss of uniqueness */
|
||||
id->val = (unsigned long)id->ptr;
|
||||
return;
|
||||
}
|
||||
/* hash ptr ==> val. Each byte of 'val' gets the mod-256 total of a
|
||||
* linear function over the bytes in 'ptr', the co-efficients of which
|
||||
* are a sequence of low-primes (hash_coeffs is an 8-element cycle) -
|
||||
* the starting prime for the sequence varies for each byte of 'val'
|
||||
* (unique polynomials unless pointers are >64-bit). For added spice,
|
||||
* the totals accumulate rather than restarting from zero, and the index
|
||||
* of the 'val' byte is added each time (position dependence). If I was
|
||||
* a black-belt, I'd scan big-endian pointers in reverse to give
|
||||
* low-order bits more play, but this isn't crypto and I'd prefer nobody
|
||||
* mistake it as such. Plus I'm lazy. */
|
||||
while (dnum--)
|
||||
{
|
||||
const unsigned char *src = (void *)&id->ptr;
|
||||
unsigned char snum = sizeof(id->ptr);
|
||||
while (snum--)
|
||||
accum += *(src++) * hash_coeffs[(snum + dnum) & 7];
|
||||
accum += dnum;
|
||||
*(dest++) = accum & 255;
|
||||
}
|
||||
}
|
||||
|
||||
int CRYPTO_THREADID_set_callback(void (*func)(CRYPTO_THREADID *))
|
||||
{
|
||||
if (threadid_callback)
|
||||
return 0;
|
||||
threadid_callback = func;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *)
|
||||
{
|
||||
return threadid_callback;
|
||||
}
|
||||
|
||||
void CRYPTO_THREADID_current(CRYPTO_THREADID *id)
|
||||
{
|
||||
if (threadid_callback)
|
||||
{
|
||||
threadid_callback(id);
|
||||
return;
|
||||
}
|
||||
#ifndef OPENSSL_NO_DEPRECATED
|
||||
/* If the deprecated callback was set, fall back to that */
|
||||
if (id_callback)
|
||||
{
|
||||
CRYPTO_THREADID_set_numeric(id, id_callback());
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
/* Else pick a backup */
|
||||
#ifdef OPENSSL_SYS_WIN16
|
||||
CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentTask());
|
||||
#elif defined(OPENSSL_SYS_WIN32)
|
||||
CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentThreadId());
|
||||
#elif defined(OPENSSL_SYS_BEOS)
|
||||
CRYPTO_THREADID_set_numeric(id, (unsigned long)find_thread(NULL));
|
||||
#else
|
||||
/* For everything else, default to using the address of 'errno' */
|
||||
CRYPTO_THREADID_set_pointer(id, &errno);
|
||||
#endif
|
||||
}
|
||||
|
||||
int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b)
|
||||
{
|
||||
return memcmp(a, b, sizeof(*a));
|
||||
}
|
||||
|
||||
void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src)
|
||||
{
|
||||
memcpy(dest, src, sizeof(*src));
|
||||
}
|
||||
|
||||
unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id)
|
||||
{
|
||||
return id->val;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_DEPRECATED
|
||||
unsigned long (*CRYPTO_get_id_callback(void))(void)
|
||||
{
|
||||
return(id_callback);
|
||||
@ -446,33 +550,13 @@ unsigned long CRYPTO_thread_id(void)
|
||||
ret=id_callback();
|
||||
return(ret);
|
||||
}
|
||||
|
||||
void *(*CRYPTO_get_idptr_callback(void))(void)
|
||||
{
|
||||
return(idptr_callback);
|
||||
}
|
||||
|
||||
void CRYPTO_set_idptr_callback(void *(*func)(void))
|
||||
{
|
||||
idptr_callback=func;
|
||||
}
|
||||
|
||||
void *CRYPTO_thread_idptr(void)
|
||||
{
|
||||
void *ret=NULL;
|
||||
|
||||
if (idptr_callback == NULL)
|
||||
ret = &errno;
|
||||
else
|
||||
ret = idptr_callback();
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
void CRYPTO_lock(int mode, int type, const char *file, int line)
|
||||
{
|
||||
#ifdef LOCK_DEBUG
|
||||
{
|
||||
CRYPTO_THREADID id;
|
||||
char *rw_text,*operation_text;
|
||||
|
||||
if (mode & CRYPTO_LOCK)
|
||||
@ -489,8 +573,9 @@ void CRYPTO_lock(int mode, int type, const char *file, int line)
|
||||
else
|
||||
rw_text="ERROR";
|
||||
|
||||
fprintf(stderr,"lock:%08lx/%08p:(%s)%s %-18s %s:%d\n",
|
||||
CRYPTO_thread_id(), CRYPTO_thread_idptr(), rw_text, operation_text,
|
||||
CRYPTO_THREADID_current(&id);
|
||||
fprintf(stderr,"lock:%08lx:(%s)%s %-18s %s:%d\n",
|
||||
CRYPTO_THREADID_hash(&id), rw_text, operation_text,
|
||||
CRYPTO_get_lock_name(type), file, line);
|
||||
}
|
||||
#endif
|
||||
@ -526,11 +611,14 @@ int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
|
||||
|
||||
ret=add_lock_callback(pointer,amount,type,file,line);
|
||||
#ifdef LOCK_DEBUG
|
||||
fprintf(stderr,"ladd:%08lx/%0xp:%2d+%2d->%2d %-18s %s:%d\n",
|
||||
CRYPTO_thread_id(), CRYPTO_thread_idptr(),
|
||||
before,amount,ret,
|
||||
{
|
||||
CRYPTO_THREADID id;
|
||||
CRYPTO_THREADID_current(&id);
|
||||
fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
|
||||
CRYPTO_THREADID_hash(&id), before,amount,ret,
|
||||
CRYPTO_get_lock_name(type),
|
||||
file,line);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@ -539,11 +627,15 @@ int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
|
||||
|
||||
ret= *pointer+amount;
|
||||
#ifdef LOCK_DEBUG
|
||||
fprintf(stderr,"ladd:%08lx/%0xp:%2d+%2d->%2d %-18s %s:%d\n",
|
||||
CRYPTO_thread_id(), CRYPTO_thread_idptr(),
|
||||
{
|
||||
CRYPTO_THREADID id;
|
||||
CRYPTO_THREADID_current(&id);
|
||||
fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
|
||||
CRYPTO_THREADID_hash(&id),
|
||||
*pointer,amount,ret,
|
||||
CRYPTO_get_lock_name(type),
|
||||
file,line);
|
||||
}
|
||||
#endif
|
||||
*pointer=ret;
|
||||
CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,file,line);
|
||||
|
@ -421,12 +421,27 @@ void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type,
|
||||
const char *file, int line));
|
||||
int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type,
|
||||
const char *file,int line);
|
||||
|
||||
/* Don't use this structure directly. */
|
||||
typedef struct crypto_threadid_st
|
||||
{
|
||||
void *ptr;
|
||||
unsigned long val;
|
||||
} CRYPTO_THREADID;
|
||||
/* Only use CRYPTO_THREADID_set_[numeric|pointer]() within callbacks */
|
||||
void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val);
|
||||
void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr);
|
||||
int CRYPTO_THREADID_set_callback(void (*threadid_func)(CRYPTO_THREADID *));
|
||||
void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *);
|
||||
void CRYPTO_THREADID_current(CRYPTO_THREADID *id);
|
||||
int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b);
|
||||
void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src);
|
||||
unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id);
|
||||
#ifndef OPENSSL_NO_DEPRECATED
|
||||
void CRYPTO_set_id_callback(unsigned long (*func)(void));
|
||||
unsigned long (*CRYPTO_get_id_callback(void))(void);
|
||||
unsigned long CRYPTO_thread_id(void);
|
||||
void CRYPTO_set_idptr_callback(void *(*func)(void));
|
||||
void *(*CRYPTO_get_idptr_callback(void))(void);
|
||||
void *CRYPTO_thread_idptr(void);
|
||||
#endif
|
||||
|
||||
const char *CRYPTO_get_lock_name(int type);
|
||||
int CRYPTO_add_lock(int *pointer,int amount,int type, const char *file,
|
||||
|
@ -222,7 +222,7 @@ end:
|
||||
ERR_print_errors(bio_err);
|
||||
if (dsa != NULL) DSA_free(dsa);
|
||||
CRYPTO_cleanup_all_ex_data();
|
||||
ERR_remove_state(0);
|
||||
ERR_remove_thread_state(NULL);
|
||||
ERR_free_strings();
|
||||
CRYPTO_mem_leaks(bio_err);
|
||||
if (bio_err != NULL)
|
||||
|
@ -1326,7 +1326,7 @@ int main(int argc, char *argv[])
|
||||
#endif
|
||||
CRYPTO_cleanup_all_ex_data();
|
||||
ERR_free_strings();
|
||||
ERR_remove_state(0);
|
||||
ERR_remove_thread_state(NULL);
|
||||
CRYPTO_mem_leaks_fp(stderr);
|
||||
|
||||
return 0;
|
||||
|
@ -343,7 +343,7 @@ err:
|
||||
if (ctx) BN_CTX_free(ctx);
|
||||
BIO_free(out);
|
||||
CRYPTO_cleanup_all_ex_data();
|
||||
ERR_remove_state(0);
|
||||
ERR_remove_thread_state(NULL);
|
||||
CRYPTO_mem_leaks_fp(stderr);
|
||||
EXIT(ret);
|
||||
return(ret);
|
||||
|
@ -490,7 +490,7 @@ err:
|
||||
if (ret)
|
||||
ERR_print_errors(out);
|
||||
CRYPTO_cleanup_all_ex_data();
|
||||
ERR_remove_state(0);
|
||||
ERR_remove_thread_state(NULL);
|
||||
ERR_free_strings();
|
||||
CRYPTO_mem_leaks(out);
|
||||
if (out != NULL)
|
||||
|
@ -276,7 +276,7 @@ end:
|
||||
ENGINE_cleanup();
|
||||
CRYPTO_cleanup_all_ex_data();
|
||||
ERR_free_strings();
|
||||
ERR_remove_state(0);
|
||||
ERR_remove_thread_state(NULL);
|
||||
CRYPTO_mem_leaks_fp(stderr);
|
||||
return to_return;
|
||||
}
|
||||
|
@ -429,13 +429,13 @@ static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *d)
|
||||
|
||||
static unsigned long err_state_hash(const ERR_STATE *a)
|
||||
{
|
||||
return (a->pid + (unsigned long)a->pidptr) * 13;
|
||||
return CRYPTO_THREADID_hash(&a->tid) * 13;
|
||||
}
|
||||
static IMPLEMENT_LHASH_HASH_FN(err_state, ERR_STATE)
|
||||
|
||||
static int err_state_cmp(const ERR_STATE *a, const ERR_STATE *b)
|
||||
{
|
||||
return (a->pid != b->pid) || (a->pidptr != b->pidptr);
|
||||
return CRYPTO_THREADID_cmp(&a->tid, &b->tid);
|
||||
}
|
||||
static IMPLEMENT_LHASH_COMP_FN(err_state, ERR_STATE)
|
||||
|
||||
@ -980,40 +980,37 @@ const char *ERR_reason_error_string(unsigned long e)
|
||||
return((p == NULL)?NULL:p->string);
|
||||
}
|
||||
|
||||
void ERR_remove_state(unsigned long pid)
|
||||
void ERR_remove_thread_state(const CRYPTO_THREADID *id)
|
||||
{
|
||||
ERR_STATE tmp;
|
||||
void *pidptr;
|
||||
|
||||
err_fns_check();
|
||||
if (pid != 0)
|
||||
pidptr = &errno;
|
||||
if (id)
|
||||
CRYPTO_THREADID_cpy(&tmp.tid, id);
|
||||
else
|
||||
{
|
||||
pid = CRYPTO_thread_id();
|
||||
pidptr = CRYPTO_thread_idptr();
|
||||
}
|
||||
|
||||
tmp.pid=pid;
|
||||
tmp.pidptr=pidptr;
|
||||
CRYPTO_THREADID_current(&tmp.tid);
|
||||
err_fns_check();
|
||||
/* thread_del_item automatically destroys the LHASH if the number of
|
||||
* items reaches zero. */
|
||||
ERRFN(thread_del_item)(&tmp);
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_DEPRECATED
|
||||
void ERR_remove_state(unsigned long pid)
|
||||
{
|
||||
ERR_remove_thread_state(NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
ERR_STATE *ERR_get_state(void)
|
||||
{
|
||||
static ERR_STATE fallback;
|
||||
ERR_STATE *ret,tmp,*tmpp=NULL;
|
||||
int i;
|
||||
unsigned long pid;
|
||||
void *pidptr;
|
||||
CRYPTO_THREADID tid;
|
||||
|
||||
err_fns_check();
|
||||
pid = CRYPTO_thread_id();
|
||||
pidptr = CRYPTO_thread_idptr();
|
||||
tmp.pid = pid;
|
||||
tmp.pidptr = pidptr;
|
||||
CRYPTO_THREADID_current(&tid);
|
||||
CRYPTO_THREADID_cpy(&tmp.tid, &tid);
|
||||
ret=ERRFN(thread_get_item)(&tmp);
|
||||
|
||||
/* ret == the error state, if NULL, make a new one */
|
||||
@ -1021,8 +1018,7 @@ ERR_STATE *ERR_get_state(void)
|
||||
{
|
||||
ret=(ERR_STATE *)OPENSSL_malloc(sizeof(ERR_STATE));
|
||||
if (ret == NULL) return(&fallback);
|
||||
ret->pid=pid;
|
||||
ret->pidptr=pidptr;
|
||||
CRYPTO_THREADID_cpy(&ret->tid, &tid);
|
||||
ret->top=0;
|
||||
ret->bottom=0;
|
||||
for (i=0; i<ERR_NUM_ERRORS; i++)
|
||||
|
@ -147,8 +147,7 @@ extern "C" {
|
||||
#define ERR_NUM_ERRORS 16
|
||||
typedef struct err_state_st
|
||||
{
|
||||
unsigned long pid;
|
||||
void *pidptr; /* new in OpenSSL 0.9.9 */
|
||||
CRYPTO_THREADID tid;
|
||||
int err_flags[ERR_NUM_ERRORS];
|
||||
unsigned long err_buffer[ERR_NUM_ERRORS];
|
||||
char *err_data[ERR_NUM_ERRORS];
|
||||
@ -351,7 +350,10 @@ void ERR_load_ERR_strings(void);
|
||||
void ERR_load_crypto_strings(void);
|
||||
void ERR_free_strings(void);
|
||||
|
||||
void ERR_remove_thread_state(const CRYPTO_THREADID *tid);
|
||||
#ifndef OPENSSL_NO_DEPRECATED
|
||||
void ERR_remove_state(unsigned long pid); /* if zero we look it up */
|
||||
#endif
|
||||
ERR_STATE *ERR_get_state(void);
|
||||
|
||||
#ifndef OPENSSL_NO_LHASH
|
||||
|
@ -72,8 +72,10 @@ void ERR_print_errors_cb(int (*cb)(const char *str, size_t len, void *u),
|
||||
const char *file,*data;
|
||||
int line,flags;
|
||||
unsigned long es;
|
||||
CRYPTO_THREADID cur;
|
||||
|
||||
es=CRYPTO_thread_id();
|
||||
CRYPTO_THREADID_current(&cur);
|
||||
es=CRYPTO_THREADID_hash(&cur);
|
||||
while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0)
|
||||
{
|
||||
ERR_error_string_n(l, buf, sizeof buf);
|
||||
|
@ -441,7 +441,7 @@ int main(int argc,char **argv)
|
||||
#endif
|
||||
EVP_cleanup();
|
||||
CRYPTO_cleanup_all_ex_data();
|
||||
ERR_remove_state(0);
|
||||
ERR_remove_thread_state(NULL);
|
||||
ERR_free_strings();
|
||||
CRYPTO_mem_leaks_fp(stderr);
|
||||
|
||||
|
@ -150,8 +150,7 @@ typedef struct app_mem_info_st
|
||||
* CRYPTO_remove_all_info() to pop all entries.
|
||||
*/
|
||||
{
|
||||
unsigned long thread_id;
|
||||
void *thread_idptr;
|
||||
CRYPTO_THREADID threadid;
|
||||
const char *file;
|
||||
int line;
|
||||
const char *info;
|
||||
@ -176,8 +175,7 @@ typedef struct mem_st
|
||||
int num;
|
||||
const char *file;
|
||||
int line;
|
||||
unsigned long thread_id;
|
||||
void *thread_idptr;
|
||||
CRYPTO_THREADID threadid;
|
||||
unsigned long order;
|
||||
time_t time;
|
||||
APP_INFO *app_info;
|
||||
@ -198,12 +196,10 @@ static unsigned int num_disable = 0; /* num_disable > 0
|
||||
* mh_mode == CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE)
|
||||
*/
|
||||
|
||||
/* The following two variables, disabling_thread_id and disabling_thread_idptr,
|
||||
* are valid iff num_disable > 0. CRYPTO_LOCK_MALLOC2 is locked exactly in
|
||||
* this case (by the thread named in disabling_thread_id / disabling_thread_idptr).
|
||||
/* Valid iff num_disable > 0. CRYPTO_LOCK_MALLOC2 is locked exactly in this
|
||||
* case (by the thread named in disabling_thread).
|
||||
*/
|
||||
static unsigned long disabling_thread_id = 0;
|
||||
static void *disabling_thread_idptr = NULL;
|
||||
static CRYPTO_THREADID disabling_threadid;
|
||||
|
||||
static void app_info_free(APP_INFO *inf)
|
||||
{
|
||||
@ -240,9 +236,9 @@ int CRYPTO_mem_ctrl(int mode)
|
||||
case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */
|
||||
if (mh_mode & CRYPTO_MEM_CHECK_ON)
|
||||
{
|
||||
if (!num_disable
|
||||
|| (disabling_thread_id != CRYPTO_thread_id())
|
||||
|| (disabling_thread_idptr != CRYPTO_thread_idptr())) /* otherwise we already have the MALLOC2 lock */
|
||||
CRYPTO_THREADID cur;
|
||||
CRYPTO_THREADID_current(&cur);
|
||||
if (!num_disable || CRYPTO_THREADID_cmp(&disabling_threadid, &cur)) /* otherwise we already have the MALLOC2 lock */
|
||||
{
|
||||
/* Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed while
|
||||
* we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock if
|
||||
@ -260,8 +256,7 @@ int CRYPTO_mem_ctrl(int mode)
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
|
||||
mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE;
|
||||
disabling_thread_id=CRYPTO_thread_id();
|
||||
disabling_thread_idptr=CRYPTO_thread_idptr();
|
||||
CRYPTO_THREADID_cpy(&disabling_threadid, &cur);
|
||||
}
|
||||
num_disable++;
|
||||
}
|
||||
@ -294,11 +289,12 @@ int CRYPTO_is_mem_check_on(void)
|
||||
|
||||
if (mh_mode & CRYPTO_MEM_CHECK_ON)
|
||||
{
|
||||
CRYPTO_THREADID cur;
|
||||
CRYPTO_THREADID_current(&cur);
|
||||
CRYPTO_r_lock(CRYPTO_LOCK_MALLOC);
|
||||
|
||||
ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE)
|
||||
|| (disabling_thread_id != CRYPTO_thread_id())
|
||||
|| (disabling_thread_idptr != CRYPTO_thread_idptr());
|
||||
|| CRYPTO_THREADID_cmp(&disabling_threadid, &cur);
|
||||
|
||||
CRYPTO_r_unlock(CRYPTO_LOCK_MALLOC);
|
||||
}
|
||||
@ -344,20 +340,17 @@ static IMPLEMENT_LHASH_HASH_FN(mem, MEM)
|
||||
/* static int app_info_cmp(APP_INFO *a, APP_INFO *b) */
|
||||
static int app_info_cmp(const void *a_void, const void *b_void)
|
||||
{
|
||||
return (((const APP_INFO *)a_void)->thread_id != ((const APP_INFO *)b_void)->thread_id)
|
||||
|| (((const APP_INFO *)a_void)->thread_idptr != ((const APP_INFO *)b_void)->thread_idptr);
|
||||
return CRYPTO_THREADID_cmp(&((const APP_INFO *)a_void)->threadid,
|
||||
&((const APP_INFO *)b_void)->threadid);
|
||||
}
|
||||
static IMPLEMENT_LHASH_COMP_FN(app_info, APP_INFO)
|
||||
|
||||
static unsigned long app_info_hash(const APP_INFO *a)
|
||||
{
|
||||
unsigned long id1, id2;
|
||||
unsigned long ret;
|
||||
|
||||
id1=(unsigned long)a->thread_id;
|
||||
id2=(unsigned long)a->thread_idptr;
|
||||
ret = id1 + id2;
|
||||
|
||||
ret = CRYPTO_THREADID_hash(&a->threadid);
|
||||
/* This is left in as a "who am I to question legacy?" measure */
|
||||
ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
|
||||
return(ret);
|
||||
}
|
||||
@ -370,8 +363,7 @@ static APP_INFO *pop_info(void)
|
||||
|
||||
if (amih != NULL)
|
||||
{
|
||||
tmp.thread_id=CRYPTO_thread_id();
|
||||
tmp.thread_idptr=CRYPTO_thread_idptr();
|
||||
CRYPTO_THREADID_current(&tmp.threadid);
|
||||
if ((ret=lh_APP_INFO_delete(amih,&tmp)) != NULL)
|
||||
{
|
||||
APP_INFO *next=ret->next;
|
||||
@ -382,10 +374,11 @@ static APP_INFO *pop_info(void)
|
||||
(void)lh_APP_INFO_insert(amih,next);
|
||||
}
|
||||
#ifdef LEVITTE_DEBUG_MEM
|
||||
if (ret->thread_id != tmp.thread_id || ret->thread_idptr != tmp.thread_idptr)
|
||||
if (CRYPTO_THREADID_cmp(&ret->threadid, &tmp.threadid))
|
||||
{
|
||||
fprintf(stderr, "pop_info(): deleted info has other thread ID (%lu/%p) than the current thread (%lu/%p)!!!!\n",
|
||||
ret->thread_id, ret->thread_idptr, tmp.thread_id, tmp.thread_idptr);
|
||||
fprintf(stderr, "pop_info(): deleted info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
|
||||
CRYPTO_THREADID_hash(&ret->threadid),
|
||||
CRYPTO_THREADID_hash(&tmp.threadid));
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
@ -425,8 +418,7 @@ int CRYPTO_push_info_(const char *info, const char *file, int line)
|
||||
}
|
||||
}
|
||||
|
||||
ami->thread_id=CRYPTO_thread_id();
|
||||
ami->thread_idptr=CRYPTO_thread_idptr();
|
||||
CRYPTO_THREADID_current(&ami->threadid);
|
||||
ami->file=file;
|
||||
ami->line=line;
|
||||
ami->info=info;
|
||||
@ -436,10 +428,11 @@ int CRYPTO_push_info_(const char *info, const char *file, int line)
|
||||
if ((amim=lh_APP_INFO_insert(amih,ami)) != NULL)
|
||||
{
|
||||
#ifdef LEVITTE_DEBUG_MEM
|
||||
if (ami->thread_id != amim->thread_id || ami->thread_idptr != amim->thread_idptr)
|
||||
if (CRYPTO_THREADID_cmp(&ami->threadid, &amim->threadid))
|
||||
{
|
||||
fprintf(stderr, "CRYPTO_push_info(): previous info has other thread ID (%lu/%p) than the current thread (%lu/%p)!!!!\n",
|
||||
amim->thread_id, amim->thread_idptr, ami->thread_id, ami->thread_idptr);
|
||||
fprintf(stderr, "CRYPTO_push_info(): previous info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
|
||||
CRYPTO_THREADID_hash(&amim->threadid),
|
||||
CRYPTO_THREADID_hash(&ami->threadid));
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
@ -525,15 +518,9 @@ void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
|
||||
m->line=line;
|
||||
m->num=num;
|
||||
if (options & V_CRYPTO_MDEBUG_THREAD)
|
||||
{
|
||||
m->thread_id=CRYPTO_thread_id();
|
||||
m->thread_idptr=CRYPTO_thread_idptr();
|
||||
}
|
||||
CRYPTO_THREADID_current(&m->threadid);
|
||||
else
|
||||
{
|
||||
m->thread_id=0;
|
||||
m->thread_idptr=NULL;
|
||||
}
|
||||
memset(&m->threadid, 0, sizeof(m->threadid));
|
||||
|
||||
if (order == break_order_num)
|
||||
{
|
||||
@ -552,8 +539,7 @@ void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
|
||||
else
|
||||
m->time=0;
|
||||
|
||||
tmp.thread_id=CRYPTO_thread_id();
|
||||
tmp.thread_idptr=CRYPTO_thread_idptr();
|
||||
CRYPTO_THREADID_current(&tmp.threadid);
|
||||
m->app_info=NULL;
|
||||
if (amih != NULL
|
||||
&& (amim=lh_APP_INFO_retrieve(amih,&tmp)) != NULL)
|
||||
@ -682,8 +668,7 @@ static void print_leak_doall_arg(const MEM *m, MEM_LEAK *l)
|
||||
APP_INFO *amip;
|
||||
int ami_cnt;
|
||||
struct tm *lcl = NULL;
|
||||
unsigned long ti;
|
||||
void *tip;
|
||||
CRYPTO_THREADID ti;
|
||||
|
||||
#define BUF_REMAIN (sizeof buf - (size_t)(bufp - buf))
|
||||
|
||||
@ -705,7 +690,8 @@ static void print_leak_doall_arg(const MEM *m, MEM_LEAK *l)
|
||||
|
||||
if (options & V_CRYPTO_MDEBUG_THREAD)
|
||||
{
|
||||
BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu/%p, ", m->thread_id, m->thread_idptr);
|
||||
BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu, ",
|
||||
CRYPTO_THREADID_hash(&m->threadid));
|
||||
bufp += strlen(bufp);
|
||||
}
|
||||
|
||||
@ -722,9 +708,8 @@ static void print_leak_doall_arg(const MEM *m, MEM_LEAK *l)
|
||||
ami_cnt=0;
|
||||
if (!amip)
|
||||
return;
|
||||
ti=amip->thread_id;
|
||||
tip=amip->thread_idptr;
|
||||
|
||||
CRYPTO_THREADID_cpy(&ti, &amip->threadid);
|
||||
|
||||
do
|
||||
{
|
||||
int buf_len;
|
||||
@ -733,8 +718,9 @@ static void print_leak_doall_arg(const MEM *m, MEM_LEAK *l)
|
||||
ami_cnt++;
|
||||
memset(buf,'>',ami_cnt);
|
||||
BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt,
|
||||
" thread=%lu/%p, file=%s, line=%d, info=\"",
|
||||
amip->thread_id, amip->thread_idptr, amip->file, amip->line);
|
||||
" thread=%lu, file=%s, line=%d, info=\"",
|
||||
CRYPTO_THREADID_hash(&amip->threadid), amip->file,
|
||||
amip->line);
|
||||
buf_len=strlen(buf);
|
||||
info_len=strlen(amip->info);
|
||||
if (128 - buf_len - 3 < info_len)
|
||||
@ -754,7 +740,7 @@ static void print_leak_doall_arg(const MEM *m, MEM_LEAK *l)
|
||||
|
||||
amip = amip->next;
|
||||
}
|
||||
while(amip && amip->thread_id == ti && amip->thread_idptr == tip);
|
||||
while(amip && !CRYPTO_THREADID_cmp(&amip->threadid, &ti));
|
||||
|
||||
#ifdef LEVITTE_DEBUG_MEM
|
||||
if (amip)
|
||||
|
@ -145,8 +145,7 @@ static unsigned int crypto_lock_rand = 0; /* may be set only when a thread
|
||||
* holds CRYPTO_LOCK_RAND
|
||||
* (to prevent double locking) */
|
||||
/* access to lockin_thread is synchronized by CRYPTO_LOCK_RAND2 */
|
||||
static unsigned long locking_thread_id = 0; /* valid iff crypto_lock_rand is set */
|
||||
static void *locking_thread_idptr = NULL; /* valid iff crypto_lock_rand is set */
|
||||
static CRYPTO_THREADID locking_threadid; /* valid iff crypto_lock_rand is set */
|
||||
|
||||
|
||||
#ifdef PREDICT
|
||||
@ -214,8 +213,10 @@ static void ssleay_rand_add(const void *buf, int num, double add)
|
||||
/* check if we already have the lock */
|
||||
if (crypto_lock_rand)
|
||||
{
|
||||
CRYPTO_THREADID cur;
|
||||
CRYPTO_THREADID_current(&cur);
|
||||
CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
|
||||
do_not_lock = (locking_thread_id == CRYPTO_thread_id()) && (locking_thread_idptr == CRYPTO_thread_idptr());
|
||||
do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur);
|
||||
CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
|
||||
}
|
||||
else
|
||||
@ -373,8 +374,7 @@ static int ssleay_rand_bytes(unsigned char *buf, int num)
|
||||
|
||||
/* prevent ssleay_rand_bytes() from trying to obtain the lock again */
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
|
||||
locking_thread_id = CRYPTO_thread_id();
|
||||
locking_thread_idptr = CRYPTO_thread_idptr();
|
||||
CRYPTO_THREADID_current(&locking_threadid);
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
|
||||
crypto_lock_rand = 1;
|
||||
|
||||
@ -529,15 +529,17 @@ static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num)
|
||||
|
||||
static int ssleay_rand_status(void)
|
||||
{
|
||||
CRYPTO_THREADID cur;
|
||||
int ret;
|
||||
int do_not_lock;
|
||||
|
||||
CRYPTO_THREADID_current(&cur);
|
||||
/* check if we already have the lock
|
||||
* (could happen if a RAND_poll() implementation calls RAND_status()) */
|
||||
if (crypto_lock_rand)
|
||||
{
|
||||
CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
|
||||
do_not_lock = (locking_thread_id == CRYPTO_thread_id()) && (locking_thread_idptr == CRYPTO_thread_idptr());
|
||||
do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur);
|
||||
CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
|
||||
}
|
||||
else
|
||||
@ -549,8 +551,7 @@ static int ssleay_rand_status(void)
|
||||
|
||||
/* prevent ssleay_rand_bytes() from trying to obtain the lock again */
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
|
||||
locking_thread_id = CRYPTO_thread_id();
|
||||
locking_thread_idptr = CRYPTO_thread_idptr();
|
||||
CRYPTO_THREADID_cpy(&locking_threadid, &cur);
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
|
||||
crypto_lock_rand = 1;
|
||||
}
|
||||
|
@ -264,6 +264,7 @@ static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx)
|
||||
{
|
||||
BN_BLINDING *ret;
|
||||
int got_write_lock = 0;
|
||||
CRYPTO_THREADID cur;
|
||||
|
||||
CRYPTO_r_lock(CRYPTO_LOCK_RSA);
|
||||
|
||||
@ -281,7 +282,8 @@ static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx)
|
||||
if (ret == NULL)
|
||||
goto err;
|
||||
|
||||
if ((BN_BLINDING_get_thread_id(ret) == CRYPTO_thread_id()) && (BN_BLINDING_get_thread_idptr(ret) == CRYPTO_thread_idptr()))
|
||||
CRYPTO_THREADID_current(&cur);
|
||||
if (!CRYPTO_THREADID_cmp(&cur, BN_BLINDING_thread_id(ret)))
|
||||
{
|
||||
/* rsa->blinding is ours! */
|
||||
|
||||
|
@ -417,8 +417,7 @@ BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx)
|
||||
RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
BN_BLINDING_set_thread_id(ret, CRYPTO_thread_id());
|
||||
BN_BLINDING_set_thread_idptr(ret, CRYPTO_thread_idptr());
|
||||
CRYPTO_THREADID_current(BN_BLINDING_thread_id(ret));
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
if (in_ctx == NULL)
|
||||
|
@ -328,7 +328,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
CRYPTO_cleanup_all_ex_data();
|
||||
ERR_remove_state(0);
|
||||
ERR_remove_thread_state(NULL);
|
||||
|
||||
CRYPTO_mem_leaks_fp(stderr);
|
||||
|
||||
|
@ -22,8 +22,11 @@ functions.
|
||||
BN_CTX *ctx);
|
||||
int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b,
|
||||
BN_CTX *ctx);
|
||||
#ifndef OPENSSL_NO_DEPRECATED
|
||||
unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *);
|
||||
void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long);
|
||||
#endif
|
||||
CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *);
|
||||
unsigned long BN_BLINDING_get_flags(const BN_BLINDING *);
|
||||
void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long);
|
||||
BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
|
||||
@ -54,11 +57,11 @@ BN_BLINDING_convert() and BN_BLINDING_invert() are wrapper
|
||||
functions for BN_BLINDING_convert_ex() and BN_BLINDING_invert_ex()
|
||||
with B<r> set to NULL.
|
||||
|
||||
BN_BLINDING_set_thread_id() and BN_BLINDING_get_thread_id()
|
||||
set and get the "thread id" value of the B<BN_BLINDING> structure,
|
||||
a field provided to users of B<BN_BLINDING> structure to help them
|
||||
provide proper locking if needed for multi-threaded use. The
|
||||
"thread id" of a newly allocated B<BN_BLINDING> structure is zero.
|
||||
BN_BLINDING_thread_id() provides access to the B<CRYPTO_THREADID>
|
||||
object within the B<BN_BLINDING> structure. This is to help users
|
||||
provide proper locking if needed for multi-threaded use. The "thread
|
||||
id" object of a newly allocated B<BN_BLINDING> structure is
|
||||
initialised to the thread id in which BN_BLINDING_new() was called.
|
||||
|
||||
BN_BLINDING_get_flags() returns the BN_BLINDING flags. Currently
|
||||
there are two supported flags: B<BN_BLINDING_NO_UPDATE> and
|
||||
@ -83,8 +86,8 @@ BN_BLINDING_update(), BN_BLINDING_convert(), BN_BLINDING_invert(),
|
||||
BN_BLINDING_convert_ex() and BN_BLINDING_invert_ex() return 1 on
|
||||
success and 0 if an error occured.
|
||||
|
||||
BN_BLINDING_get_thread_id() returns the thread id (a B<unsigned long>
|
||||
value) or 0 if not set.
|
||||
BN_BLINDING_thread_id() returns a pointer to the thread id object
|
||||
within a B<BN_BLINDING> object.
|
||||
|
||||
BN_BLINDING_get_flags() returns the currently set B<BN_BLINDING> flags
|
||||
(a B<unsigned long> value).
|
||||
@ -98,6 +101,9 @@ L<bn(3)|bn(3)>
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
BN_BLINDING_thread_id was first introduced in OpenSSL 0.9.9, and it
|
||||
deprecates BN_BLINDING_set_thread_id and BN_BLINDING_get_thread_id.
|
||||
|
||||
BN_BLINDING_convert_ex, BN_BLINDIND_invert_ex, BN_BLINDING_get_thread_id,
|
||||
BN_BLINDING_set_thread_id, BN_BLINDING_set_flags, BN_BLINDING_get_flags
|
||||
and BN_BLINDING_create_param were first introduced in OpenSSL 0.9.8
|
||||
|
@ -2,8 +2,9 @@
|
||||
|
||||
=head1 NAME
|
||||
|
||||
CRYPTO_set_locking_callback, CRYPTO_set_id_callback,
|
||||
CRYPTO_set_idptr_callback, CRYPTO_num_locks,
|
||||
CRYPTO_THREADID_set_callback, CRYPTO_THREADID_get_callback,
|
||||
CRYPTO_THREADID_current, CRYPTO_THREADID_cmp, CRYPTO_THREADID_cpy,
|
||||
CRYPTO_THREADID_hash, CRYPTO_set_locking_callback, CRYPTO_num_locks,
|
||||
CRYPTO_set_dynlock_create_callback, CRYPTO_set_dynlock_lock_callback,
|
||||
CRYPTO_set_dynlock_destroy_callback, CRYPTO_get_new_dynlockid,
|
||||
CRYPTO_destroy_dynlockid, CRYPTO_lock - OpenSSL thread support
|
||||
@ -12,16 +13,26 @@ CRYPTO_destroy_dynlockid, CRYPTO_lock - OpenSSL thread support
|
||||
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
void CRYPTO_set_locking_callback(void (*locking_function)(int mode,
|
||||
int n, const char *file, int line));
|
||||
|
||||
void CRYPTO_set_id_callback(unsigned long (*id_function)(void));
|
||||
|
||||
void CRYPTO_set_idptr_callback(void *(*idptr_function)(void));
|
||||
/* Don't use this structure directly. */
|
||||
typedef struct crypto_threadid_st
|
||||
{
|
||||
void *ptr;
|
||||
unsigned long val;
|
||||
} CRYPTO_THREADID;
|
||||
/* Only use CRYPTO_THREADID_set_[numeric|pointer]() within callbacks */
|
||||
void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val);
|
||||
void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr);
|
||||
int CRYPTO_THREADID_set_callback(void (*threadid_func)(CRYPTO_THREADID *));
|
||||
void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *);
|
||||
void CRYPTO_THREADID_current(CRYPTO_THREADID *id);
|
||||
int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a,
|
||||
const CRYPTO_THREADID *b);
|
||||
void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest,
|
||||
const CRYPTO_THREADID *src);
|
||||
unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id);
|
||||
|
||||
int CRYPTO_num_locks(void);
|
||||
|
||||
|
||||
/* struct CRYPTO_dynlock_value needs to be defined by the user */
|
||||
struct CRYPTO_dynlock_value;
|
||||
|
||||
@ -53,7 +64,8 @@ CRYPTO_destroy_dynlockid, CRYPTO_lock - OpenSSL thread support
|
||||
=head1 DESCRIPTION
|
||||
|
||||
OpenSSL can safely be used in multi-threaded applications provided
|
||||
that at least two callback functions are set.
|
||||
that at least two callback functions are set, locking_function and
|
||||
threadid_func.
|
||||
|
||||
locking_function(int mode, int n, const char *file, int line) is
|
||||
needed to perform locking on shared data structures.
|
||||
@ -68,17 +80,42 @@ B<CRYPTO_LOCK>, and releases it otherwise.
|
||||
B<file> and B<line> are the file number of the function setting the
|
||||
lock. They can be useful for debugging.
|
||||
|
||||
id_function(void) is a function that returns a numerical thread ID,
|
||||
for example pthread_self() if it returns an integer (see NOTES below).
|
||||
By OpenSSL's defaults, this is not needed on Windows nor on platforms
|
||||
where getpid() returns a different ID for each thread (see NOTES
|
||||
below).
|
||||
threadid_func(CRYPTO_THREADID *id) is needed to record the currently-executing
|
||||
thread's identifier into B<id>. The implementation of this callback should not
|
||||
fill in B<id> directly, but should use CRYPTO_THREADID_set_numeric() if thread
|
||||
IDs are numeric, or CRYPTO_THREADID_set_pointer() if they are pointer-based.
|
||||
If the application does not register such a callback using
|
||||
CRYPTO_THREADID_set_callback(), then a default implementation is used - on
|
||||
Windows and BeOS this uses the system's default thread identifying APIs, and on
|
||||
all other platforms it uses the address of B<errno>. The latter is satisfactory
|
||||
for thread-safety if and only if the platform has a thread-local error number
|
||||
facility.
|
||||
|
||||
idptr_function(void) is a function that similarly returns a thread ID,
|
||||
but of type void *. This is not needed on platforms where &errno is
|
||||
different for each thread. OpenSSL assumes that it is in the same
|
||||
thread iff both the numerical and the pointer thread ID agree, so it
|
||||
suffices to define one of these two callback functions appropriately.
|
||||
Once threadid_func() is registered, or if the built-in default implementation is
|
||||
to be used;
|
||||
|
||||
=over 4
|
||||
|
||||
=item *
|
||||
CRYPTO_THREADID_current() records the currently-executing thread ID into the
|
||||
given B<id> object.
|
||||
|
||||
=item *
|
||||
CRYPTO_THREADID_cmp() compares two thread IDs (returning zero for equality, ie.
|
||||
the same semantics as memcmp()).
|
||||
|
||||
=item *
|
||||
CRYPTO_THREADID_cpy() duplicates a thread ID value,
|
||||
|
||||
=item *
|
||||
CRYPTO_THREADID_hash() returns a numeric value usable as a hash-table key. This
|
||||
is usually the exact numeric or pointer-based thread ID used internally, however
|
||||
this also handles the unusual case where pointers are larger than 'long'
|
||||
variables and the platform's thread IDs are pointer-based - in this case, mixing
|
||||
is done to attempt to produce a unique numeric value even though it is not as
|
||||
wide as the platform's true thread IDs.
|
||||
|
||||
=back
|
||||
|
||||
Additionally, OpenSSL supports dynamic locks, and sometimes, some parts
|
||||
of OpenSSL need it for better performance. To enable this, the following
|
||||
@ -150,24 +187,6 @@ You can find out if OpenSSL was configured with thread support:
|
||||
Also, dynamic locks are currently not used internally by OpenSSL, but
|
||||
may do so in the future.
|
||||
|
||||
Defining id_function(void) has it's own issues. Generally speaking,
|
||||
pthread_self() should be used, even on platforms where getpid() gives
|
||||
different answers in each thread, since that may depend on the machine
|
||||
the program is run on, not the machine where the program is being
|
||||
compiled. For instance, Red Hat 8 Linux and earlier used
|
||||
LinuxThreads, whose getpid() returns a different value for each
|
||||
thread. Red Hat 9 Linux and later use NPTL, which is
|
||||
Posix-conformant, and has a getpid() that returns the same value for
|
||||
all threads in a process. A program compiled on Red Hat 8 and run on
|
||||
Red Hat 9 will therefore see getpid() returning the same value for
|
||||
all threads.
|
||||
|
||||
There is still the issue of platforms where pthread_self() returns
|
||||
something other than an integer. It is for cases like this that
|
||||
CRYPTO_set_idptr_callback() comes in handy. (E.g., call malloc(1)
|
||||
once in each thread, and have idptr_function() return a pointer to
|
||||
this object.)
|
||||
|
||||
=head1 EXAMPLES
|
||||
|
||||
B<crypto/threads/mttest.c> shows examples of the callback functions on
|
||||
@ -179,8 +198,10 @@ CRYPTO_set_locking_callback() and CRYPTO_set_id_callback() are
|
||||
available in all versions of SSLeay and OpenSSL.
|
||||
CRYPTO_num_locks() was added in OpenSSL 0.9.4.
|
||||
All functions dealing with dynamic locks were added in OpenSSL 0.9.5b-dev.
|
||||
|
||||
CRYPTO_set_idptr_callback() was added in OpenSSL 0.9.9.
|
||||
B<CRYPTO_THREADID> and associated functions were introduced in OpenSSL 0.9.9
|
||||
to replace (actually, deprecate) the previous CRYPTO_set_id_callback(),
|
||||
CRYPTO_get_id_callback(), and CRYPTO_thread_id() functions which assumed
|
||||
thread IDs to always be represented by 'unsigned long'.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
@ -1014,7 +1014,7 @@ end:
|
||||
#endif
|
||||
CRYPTO_cleanup_all_ex_data();
|
||||
ERR_free_strings();
|
||||
ERR_remove_state(0);
|
||||
ERR_remove_thread_state(NULL);
|
||||
EVP_cleanup();
|
||||
CRYPTO_mem_leaks(bio_err);
|
||||
if (bio_err != NULL) BIO_free(bio_err);
|
||||
|
Loading…
Reference in New Issue
Block a user