Hi Joe I'm using OpenSSL in Win32 environment and the locking issues I've addressed using critical section objects (lightweight compared to mutexes) like this:
... SSL_library_init(); CCCriticalSection g_pOpenSSLCritSections; // this class uses InitializeCriticalSection/EnterCriticalSection/LeaveCriticalSection // set of apis. Class from MFC g_pOpenSSLCritSections = new CCCriticalSection[CRYPTO_num_locks()]; CRYPTO_set_locking_callback(OpenSSLLockingCallback); // set locking callback function ... void OpenSSLLockingCallback(int mode, int type, const char *file, int line) { UNUSED_ALWAYS(line); UNUSED_ALWAYS(file); if (mode & CRYPTO_LOCK) m_pOpenSSLCritSections[type].Lock(); else m_pOpenSSLCritSections[type].Unlock(); } This is a simplest way than uses dynamic lock creation and is working fine. At program termination, before destruct the g_pOpenSSLCritSections array, I'm calling CRYPTO_set_locking_callback(NULL); I hope this helps (And that I'm not doing wrong ;-). Best Regards Leandro Gustavo Biss Becker Engenheiro Eletrônico / Electronic Engineer ________________________________ eSysTech - Embedded Systems Technologies Travessa da Lapa, 96 conjunto 73 Curitiba - Paraná - Brasil http://www.esystech.com.br Telefone: +55 (41) 3029-2960 Esta mensagem e seus anexos podem conter informações confidenciais ou privilegiadas. Se você não é o destinatário dos mesmos você não está autorizado a utilizar o material para qualquer fim. Solicitamos que você apague a mensagem e avise imediatamente ao remetente. O conteúdo desta mensagem e seus anexos não representam necessariamente a opinião e a intenção da empresa, não implicando em qualquer obrigação ou responsabilidade da parte da mesma. This message may contain confidential and/or privileged information. If you are not the addressee or authorized to receive this for the addressee, you must not use, copy, disclose or take any action based on this message or any information herein. If you have received this message in error, please advise the sender immediately by reply e-mail and delete this message. The contents of this message and its attachments do not necessarily express the opinion or the intention of the company, and do not implies any legal obligation or responsabilities from this company. -----Mensagem original----- De: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] Em nome de Joe Flowers Enviada em: sexta-feira, 15 de setembro de 2006 17:57 Para: openssl-users@openssl.org Assunto: Re: When to use CRYPTO_set_locking_callback() and Marek, I really appreciate this code snippet **a lot**. It looks like an excellent snippet of code...as best as I can tell. Can anyone else please confirm that these functions (listed below) are what I need to implement for making OpenSSL thead-safe? No offense intended Marek. I'm just looking for a second confirming source. I'm running this on a Win32 platform, so I'm going to have to convert from pthreads to Win32 speak, but I think I can do that. Any gotchas will be appreciated though. For example, do I need the Win32 keyword CALLBACK or EXPORT in the function prototypes? I'm also wondering if there is someway I can test this to make sure this is working correctly? Thanks a million.....again! Joe ---------------------------------------------------------------------------- -------------------------------------------------------- Marek Marcola wrote: You may use something like that: -------------------------------- struct CRYPTO_dynlock_value { pthread_mutex_t mutex; }; static pthread_mutex_t *mutex_buf = NULL; /** * OpenSSL locking function. * * @param mode lock mode * @param n lock number * @param file source file name * @param line source file line number * @return none */ static void locking_function(int mode, int n, const char *file, int line) { if (mode & CRYPTO_LOCK) { pthread_mutex_lock(&mutex_buf[n]); } else { pthread_mutex_unlock(&mutex_buf[n]); } } /** * OpenSSL uniq id function. * * @return thread id */ static unsigned long id_function(void) { return ((unsigned long) pthread_self()); } /** * OpenSSL allocate and initialize dynamic crypto lock. * * @param file source file name * @param line source file line number */ static struct CRYPTO_dynlock_value *dyn_create_function(const char *file, int line) { struct CRYPTO_dynlock_value *value; value = (struct CRYPTO_dynlock_value *) malloc(sizeof(struct CRYPTO_dynlock_value)); if (!value) { goto err; } pthread_mutex_init(&value->mutex, NULL); return value; err: return (NULL); } /** * OpenSSL dynamic locking function. * * @param mode lock mode * @param l lock structure pointer * @param file source file name * @param line source file line number * @return none */ static void dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line) { if (mode & CRYPTO_LOCK) { pthread_mutex_lock(&l->mutex); } else { pthread_mutex_unlock(&l->mutex); } } /** * OpenSSL destroy dynamic crypto lock. * * @param l lock structure pointer * @param file source file name * @param line source file line number * @return none */ static void dyn_destroy_function(struct CRYPTO_dynlock_value *l, const char *file, int line) { pthread_mutex_destroy(&l->mutex); free(l); } /** * Initialize TLS library. * * @return 0 on success, -1 on error */ int tls_init(void) { int i; /* static locks area */ mutex_buf = malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t)); if (mutex_buf == NULL) { return (-1); } for (i = 0; i < CRYPTO_num_locks(); i++) { pthread_mutex_init(&mutex_buf[i], NULL); } /* static locks callbacks */ CRYPTO_set_locking_callback(locking_function); CRYPTO_set_id_callback(id_function); /* dynamic locks callbacks */ CRYPTO_set_dynlock_create_callback(dyn_create_function); CRYPTO_set_dynlock_lock_callback(dyn_lock_function); CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function); SSL_load_error_strings(); SSLeay_add_ssl_algorithms(); RAND_load_file("/dev/urandom", 1024); return (0); } /** * Cleanup TLS library. * * @return 0 */ int tls_cleanup(void) { int i; if (mutex_buf == NULL) { return (0); } CRYPTO_set_dynlock_create_callback(NULL); CRYPTO_set_dynlock_lock_callback(NULL); CRYPTO_set_dynlock_destroy_callback(NULL); CRYPTO_set_locking_callback(NULL); CRYPTO_set_id_callback(NULL); for (i = 0; i < CRYPTO_num_locks(); i++) { pthread_mutex_destroy(&mutex_buf[i]); } free(mutex_buf); mutex_buf = NULL; return (0); } Best regards, -- Marek Marcola <[EMAIL PROTECTED]> ---------------------------------------------------------------------------- -------------------------------------------------------- ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List openssl-users@openssl.org Automated List Manager [EMAIL PROTECTED] ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List openssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]