libasteriskssl.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2009-2012, Digium, Inc.
  5. *
  6. * Russell Bryant <russell@digium.com>
  7. *
  8. * See http://www.asterisk.org for more information about
  9. * the Asterisk project. Please do not directly contact
  10. * any of the maintainers of this project for assistance;
  11. * the project provides a web site, mailing lists and IRC
  12. * channels for your use.
  13. *
  14. * This program is free software, distributed under the terms of
  15. * the GNU General Public License Version 2. See the LICENSE file
  16. * at the top of the source tree.
  17. */
  18. /*!
  19. * \file
  20. * \brief Common OpenSSL support code
  21. *
  22. * \author Russell Bryant <russell@digium.com>
  23. */
  24. /*** MODULEINFO
  25. <support_level>core</support_level>
  26. ***/
  27. #include "asterisk.h"
  28. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  29. #ifdef HAVE_OPENSSL
  30. #include <openssl/ssl.h>
  31. #include <openssl/err.h>
  32. #endif
  33. #include <dlfcn.h>
  34. #include "asterisk/_private.h" /* ast_ssl_init() */
  35. #include "asterisk/utils.h"
  36. #include "asterisk/lock.h"
  37. #ifdef HAVE_OPENSSL
  38. #define get_OpenSSL_function(func) do { real_##func = dlsym(RTLD_NEXT, __stringify(func)); } while(0)
  39. static int startup_complete;
  40. static ast_mutex_t *ssl_locks;
  41. static int ssl_num_locks;
  42. static unsigned long ssl_threadid(void)
  43. {
  44. return (unsigned long) pthread_self();
  45. }
  46. static void ssl_lock(int mode, int n, const char *file, int line)
  47. {
  48. if (n < 0 || n >= ssl_num_locks) {
  49. ast_log(LOG_ERROR, "OpenSSL is full of LIES!!! - "
  50. "ssl_num_locks '%d' - n '%d'\n",
  51. ssl_num_locks, n);
  52. return;
  53. }
  54. if (mode & CRYPTO_LOCK) {
  55. ast_mutex_lock(&ssl_locks[n]);
  56. } else {
  57. ast_mutex_unlock(&ssl_locks[n]);
  58. }
  59. }
  60. int SSL_library_init(void)
  61. {
  62. #if defined(AST_DEVMODE)
  63. if (startup_complete) {
  64. ast_debug(1, "Called after startup... ignoring!\n");
  65. }
  66. #endif
  67. return 1;
  68. }
  69. void SSL_load_error_strings(void)
  70. {
  71. #if defined(AST_DEVMODE)
  72. if (startup_complete) {
  73. ast_debug(1, "Called after startup... ignoring!\n");
  74. }
  75. #endif
  76. }
  77. void ERR_load_SSL_strings(void)
  78. {
  79. #if defined(AST_DEVMODE)
  80. if (startup_complete) {
  81. ast_debug(1, "Called after startup... ignoring!\n");
  82. }
  83. #endif
  84. }
  85. void ERR_load_crypto_strings(void)
  86. {
  87. #if defined(AST_DEVMODE)
  88. if (startup_complete) {
  89. ast_debug(1, "Called after startup... ignoring!\n");
  90. }
  91. #endif
  92. }
  93. void ERR_load_BIO_strings(void)
  94. {
  95. #if defined(AST_DEVMODE)
  96. if (startup_complete) {
  97. ast_debug(1, "Called after startup... ignoring!\n");
  98. }
  99. #endif
  100. }
  101. void CRYPTO_set_id_callback(unsigned long (*func)(void))
  102. {
  103. #if defined(AST_DEVMODE)
  104. if (startup_complete) {
  105. ast_debug(1, "Called after startup... ignoring!\n");
  106. }
  107. #endif
  108. }
  109. void CRYPTO_set_locking_callback(void (*func)(int mode,int type, const char *file, int line))
  110. {
  111. #if defined(AST_DEVMODE)
  112. if (startup_complete) {
  113. ast_debug(1, "Called after startup... ignoring!\n");
  114. }
  115. #endif
  116. }
  117. void ERR_free_strings(void)
  118. {
  119. /* we can't allow this to be called, ever */
  120. }
  121. #endif /* HAVE_OPENSSL */
  122. /*!
  123. * \internal
  124. * \brief Common OpenSSL initialization for all of Asterisk.
  125. */
  126. int ast_ssl_init(void)
  127. {
  128. #ifdef HAVE_OPENSSL
  129. unsigned int i;
  130. int (*real_SSL_library_init)(void);
  131. void (*real_CRYPTO_set_id_callback)(unsigned long (*)(void));
  132. void (*real_CRYPTO_set_locking_callback)(void (*)(int, int, const char *, int));
  133. void (*real_SSL_load_error_strings)(void);
  134. void (*real_ERR_load_SSL_strings)(void);
  135. void (*real_ERR_load_BIO_strings)(void);
  136. const char *errstr;
  137. /* clear any previous dynamic linker errors */
  138. dlerror();
  139. get_OpenSSL_function(SSL_library_init);
  140. if ((errstr = dlerror()) != NULL) {
  141. ast_debug(1, "unable to get real address of SSL_library_init: %s\n", errstr);
  142. /* there is no way to continue in this situation... SSL will
  143. * likely be broken in this process
  144. */
  145. return -1;
  146. } else {
  147. real_SSL_library_init();
  148. }
  149. /* Make OpenSSL usage thread-safe. */
  150. dlerror();
  151. get_OpenSSL_function(CRYPTO_set_id_callback);
  152. if ((errstr = dlerror()) != NULL) {
  153. ast_debug(1, "unable to get real address of CRYPTO_set_id_callback: %s\n", errstr);
  154. /* there is no way to continue in this situation... SSL will
  155. * likely be broken in this process
  156. */
  157. return -1;
  158. } else {
  159. real_CRYPTO_set_id_callback(ssl_threadid);
  160. }
  161. dlerror();
  162. get_OpenSSL_function(CRYPTO_set_locking_callback);
  163. if ((errstr = dlerror()) != NULL) {
  164. ast_debug(1, "unable to get real address of CRYPTO_set_locking_callback: %s\n", errstr);
  165. /* there is no way to continue in this situation... SSL will
  166. * likely be broken in this process
  167. */
  168. return -1;
  169. } else {
  170. ssl_num_locks = CRYPTO_num_locks();
  171. if (!(ssl_locks = ast_calloc(ssl_num_locks, sizeof(ssl_locks[0])))) {
  172. return -1;
  173. }
  174. for (i = 0; i < ssl_num_locks; i++) {
  175. ast_mutex_init(&ssl_locks[i]);
  176. }
  177. real_CRYPTO_set_locking_callback(ssl_lock);
  178. }
  179. /* after this point, we don't check for errors from the dlsym() calls,
  180. * under the assumption that if the ones above were successful, all
  181. * the rest will be too. this assumption holds as long as OpenSSL still
  182. * provides all of these functions.
  183. */
  184. get_OpenSSL_function(SSL_load_error_strings);
  185. real_SSL_load_error_strings();
  186. get_OpenSSL_function(ERR_load_SSL_strings);
  187. real_ERR_load_SSL_strings();
  188. get_OpenSSL_function(ERR_load_BIO_strings);
  189. real_ERR_load_BIO_strings();
  190. startup_complete = 1;
  191. #endif /* HAVE_OPENSSL */
  192. return 0;
  193. }