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]

Reply via email to