Support This Project

Changeset 2028

Show
Ignore:
Timestamp:
11/02/08 15:19:07 (2 months ago)
Author:
virdiq
Message:

Implement OpenSSL static locking callback function, required for correct multithreaded OpenSSL usage. See http://www.openssl.org/docs/crypto/threads.html for more information. Thanks to JGS for reporting this problem and providing sample code.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/libwzd-core/wzd_tls.c

    r1994 r2028  
    4949#include "wzd_structs.h" 
    5050#include "wzd_log.h" 
     51#include "wzd_mutex.h" 
    5152 
    5253#include "wzd_tls.h" 
     
    5657 
    5758#include "wzd_debug.h" 
     59 
     60 
     61static int _tls_init_threads(void); 
     62static void _tls_exit_threads(void); 
     63static void _openssl_static_lock_callback(int, int, const char *, int); 
    5864 
    5965 
     
    6571}; 
    6672 
    67  
    68  
     73/* pointers to OpenSSL lock arrays */ 
     74wzd_mutex_t **openssl_static_lock = NULL; 
     75ssize_t openssl_static_lock_num = 0; 
     76wzd_mutex_t **openssl_dynamic_lock = NULL; 
     77ssize_t openssl_dynamic_lock_num = 0; 
     78 
     79 
     80/*************** tls_context_init ***********************/ 
    6981void tls_context_init(wzd_context_t * context) 
    7082{ 
     
    188200{ 
    189201  int status; 
     202  int ret; 
    190203  SSL_CTX * tls_ctx; 
    191204  wzd_string_t * tls_certificate=NULL; 
     
    292305  SSL_CTX_set_session_id_context(tls_ctx, (const unsigned char *) "1", 1); 
    293306 
     307  ret = _tls_init_threads(); 
     308  if (ret) { 
     309    out_log(LEVEL_CRITICAL, "_tls_init_threads failed (out of memory?)"); 
     310    str_deallocate(tls_certificate); 
     311    str_deallocate(tls_certificate_key); 
     312    str_deallocate(tls_ca_file); 
     313    str_deallocate(tls_ca_path); 
     314    return 1; 
     315  } 
     316 
     317  CRYPTO_set_locking_callback((void(*)(int, int, const char *, int))_openssl_static_lock_callback); 
     318  /* TODO: set dynamic locking callbacks */ 
     319 
    294320  out_log(LEVEL_INFO,"TLS initialization successful (%s).\n",OPENSSL_VERSION_TEXT); 
    295321 
     
    300326} 
    301327 
     328/*************** _tls_init_threads *******************/ 
     329static int _tls_init_threads(void) { 
     330  int static_locks_req; 
     331  int i; 
     332  int j; 
     333 
     334  /* determine how many static locks OpenSSL requires */ 
     335  static_locks_req = CRYPTO_num_locks(); 
     336  if (static_locks_req > 0) { 
     337    openssl_static_lock = wzd_malloc(sizeof(wzd_mutex_t *) * static_locks_req); 
     338    if (!openssl_static_lock) 
     339      return -1; 
     340    /* create each mutex so it is ready to be used */ 
     341    for (i = 0; i < static_locks_req; i++) { 
     342      openssl_static_lock[i] = wzd_mutex_create(0); 
     343      if (!openssl_static_lock[i]) { 
     344        for (j = 0; j < i; j++) 
     345          wzd_mutex_destroy(openssl_static_lock[j]); 
     346        wzd_free(openssl_static_lock); 
     347        openssl_static_lock = NULL; 
     348        return -1; 
     349      } 
     350    } 
     351  } 
     352   
     353  /* TODO: init dynamic lock array (it can grow/shrink later) */ 
     354 
     355  openssl_static_lock_num = static_locks_req; 
     356  return 0; 
     357} 
     358   
     359 
    302360/*************** tls_exit ****************************/ 
    303361 
     
    315373  ERR_free_strings(); 
    316374 
     375  CRYPTO_set_locking_callback(NULL); 
     376  /* TODO: unset dynamic locking callbacks */ 
     377  _tls_exit_threads(); 
     378 
    317379  SSL_CTX_free(mainConfig->tls_ctx); 
    318380  return 0; 
    319381} 
    320382 
     383/*************** _tls_exit_threads *******************/ 
     384static void _tls_exit_threads(void) { 
     385  int i; 
     386 
     387  for (i = 0; i < openssl_static_lock_num; i++) 
     388    wzd_mutex_destroy(openssl_static_lock[i]); 
     389  wzd_free(openssl_static_lock); 
     390 
     391  /* TODO: free up dynamic lock array */ 
     392  return; 
     393} 
     394 
     395/*************** _openssl_static_lock_callback *******/ 
     396static void _openssl_static_lock_callback(int mode, int n, const char *file, int line) { 
     397  if (mode & CRYPTO_LOCK) 
     398    wzd_mutex_lock(openssl_static_lock[n]); 
     399  else if (mode & CRYPTO_UNLOCK) 
     400    wzd_mutex_unlock(openssl_static_lock[n]); 
     401  return; 
     402} 
    321403 
    322404/*************** tls_read ****************************/