reSIProcate/rutil  9694
OpenSSLInit.cxx
Go to the documentation of this file.
00001 #if defined(HAVE_CONFIG_H)
00002   #include "config.h"
00003 #endif
00004 
00005 #include "rutil/Mutex.hxx"
00006 #include "rutil/Lock.hxx"
00007 #include "rutil/Logger.hxx"
00008 
00009 #ifdef USE_SSL
00010 
00011 #include "rutil/ssl/OpenSSLInit.hxx"
00012 
00013 #include <openssl/e_os2.h>
00014 #include <openssl/rand.h>
00015 #include <openssl/err.h>
00016 #include <openssl/crypto.h>
00017 #include <openssl/ssl.h>
00018 
00019 #define OPENSSL_THREAD_DEFINES
00020 #include <openssl/opensslconf.h>
00021 
00022 #define RESIPROCATE_SUBSYSTEM Subsystem::SIP
00023 
00024 using namespace resip;
00025 using namespace std;
00026 
00027 #include <iostream>
00028 
00029 static bool invokeOpenSSLInit = OpenSSLInit::init(); //.dcm. - only in hxx
00030 volatile bool OpenSSLInit::mInitialized = false;
00031 Mutex* OpenSSLInit::mMutexes;
00032 
00033 bool
00034 OpenSSLInit::init()
00035 {
00036         static OpenSSLInit instance;
00037         return true;
00038 }
00039 
00040 OpenSSLInit::OpenSSLInit()
00041 {
00042         int locks = CRYPTO_num_locks();
00043         mMutexes = new Mutex[locks];
00044         CRYPTO_set_locking_callback(::resip_OpenSSLInit_lockingFunction);
00045 
00046 #if !defined(WIN32)
00047 #if defined(_POSIX_THREADS)
00048         CRYPTO_set_id_callback(::resip_OpenSSLInit_threadIdFunction);
00049 #else
00050 #error Cannot set OpenSSL up to be threadsafe!
00051 #endif
00052 #endif
00053 
00054 #if 0 //?dcm? -- not used by OpenSSL yet?
00055         CRYPTO_set_dynlock_create_callback(::resip_OpenSSLInit_dynCreateFunction);
00056         CRYPTO_set_dynlock_destroy_callback(::resip_OpenSSLInit_dynDestroyFunction);
00057         CRYPTO_set_dynlock_lock_callback(::resip_OpenSSLInit_dynLockFunction);
00058 #endif
00059 
00060         CRYPTO_malloc_debug_init();
00061         CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
00062         CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
00063 
00064         SSL_library_init();
00065         SSL_load_error_strings();
00066         OpenSSL_add_all_algorithms();
00067         assert(EVP_des_ede3_cbc());
00068    mInitialized = true;
00069 }
00070 
00071 OpenSSLInit::~OpenSSLInit()
00072 {
00073    mInitialized = false;
00074         ERR_free_strings();// Clean up data allocated during SSL_load_error_strings
00075         ERR_remove_state(0);// free thread error queue
00076         CRYPTO_cleanup_all_ex_data();
00077         EVP_cleanup();// Clean up data allocated during OpenSSL_add_all_algorithms
00078 
00081 //      CRYPTO_mem_leaks_fp(stderr);
00082 
00083         delete [] mMutexes;
00084 }
00085 
00086 void
00087 resip_OpenSSLInit_lockingFunction(int mode, int n, const char* file, int line)
00088 {
00089    if(!resip::OpenSSLInit::mInitialized) return;
00090    if (mode & CRYPTO_LOCK)
00091    {
00092       OpenSSLInit::mMutexes[n].lock();
00093    }
00094    else
00095    {      
00096       OpenSSLInit::mMutexes[n].unlock();
00097    }
00098 }
00099 
00100 unsigned long 
00101 resip_OpenSSLInit_threadIdFunction()
00102 {
00103 #if defined(WIN32)
00104    assert(0);
00105 #else
00106 #ifndef _POSIX_THREADS
00107    assert(0);
00108 #endif
00109    unsigned long ret;
00110    ret= (unsigned long)pthread_self();
00111    return ret;
00112 #endif
00113    return 0;
00114 }
00115 
00116 CRYPTO_dynlock_value* 
00117 resip_OpenSSLInit_dynCreateFunction(char* file, int line)
00118 {
00119    CRYPTO_dynlock_value* dynLock = new CRYPTO_dynlock_value;
00120    dynLock->mutex = new Mutex;
00121    return dynLock;   
00122 }
00123 
00124 void
00125 resip_OpenSSLInit_dynDestroyFunction(CRYPTO_dynlock_value* dynlock, const char* file, int line)
00126 {
00127    delete dynlock->mutex;
00128    delete dynlock;
00129 }
00130 
00131 void 
00132 resip_OpenSSLInit_dynLockFunction(int mode, struct CRYPTO_dynlock_value* dynlock, const char* file, int line)
00133 {
00134    if (mode & CRYPTO_LOCK)
00135    {
00136       dynlock->mutex->lock();
00137    }
00138    else
00139    {
00140       dynlock->mutex->unlock();
00141    }
00142 }
00143 
00144 #endif