crypto_openssl_mgt.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /* Copyright (c) 2001, Matej Pfajfar.
  2. * Copyright (c) 2001-2004, Roger Dingledine.
  3. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  4. * Copyright (c) 2007-2018, The Tor Project, Inc. */
  5. /* See LICENSE for licensing information */
  6. /**
  7. * \file crypto_openssl_mgt.c
  8. *
  9. * \brief Block of functions related to operations from OpenSSL.
  10. **/
  11. #include "lib/crypt_ops/compat_openssl.h"
  12. #include "lib/crypt_ops/crypto_openssl_mgt.h"
  13. #include "lib/string/util_string.h"
  14. #include "lib/lock/compat_mutex.h"
  15. #include "lib/testsupport/testsupport.h"
  16. #include "lib/thread/threads.h"
  17. DISABLE_GCC_WARNING(redundant-decls)
  18. #include <openssl/err.h>
  19. #include <openssl/rsa.h>
  20. #include <openssl/pem.h>
  21. #include <openssl/evp.h>
  22. #include <openssl/engine.h>
  23. #include <openssl/rand.h>
  24. #include <openssl/bn.h>
  25. #include <openssl/dh.h>
  26. #include <openssl/conf.h>
  27. #include <openssl/hmac.h>
  28. #include <openssl/crypto.h>
  29. ENABLE_GCC_WARNING(redundant-decls)
  30. #include <string.h>
  31. #ifndef NEW_THREAD_API
  32. /** A number of preallocated mutexes for use by OpenSSL. */
  33. static tor_mutex_t **openssl_mutexes_ = NULL;
  34. /** How many mutexes have we allocated for use by OpenSSL? */
  35. static int n_openssl_mutexes_ = 0;
  36. #endif /* !defined(NEW_THREAD_API) */
  37. /** Declare STATIC functions */
  38. STATIC char * parse_openssl_version_str(const char *raw_version);
  39. #ifndef NEW_THREAD_API
  40. STATIC void openssl_locking_cb_(int mode, int n, const char *file, int line);
  41. STATIC void tor_set_openssl_thread_id(CRYPTO_THREADID *threadid);
  42. #endif
  43. /* Returns a trimmed and human-readable version of an openssl version string
  44. * <b>raw_version</b>. They are usually in the form of 'OpenSSL 1.0.0b 10
  45. * May 2012' and this will parse them into a form similar to '1.0.0b' */
  46. STATIC char *
  47. parse_openssl_version_str(const char *raw_version)
  48. {
  49. const char *end_of_version = NULL;
  50. /* The output should be something like "OpenSSL 1.0.0b 10 May 2012. Let's
  51. trim that down. */
  52. if (!strcmpstart(raw_version, "OpenSSL ")) {
  53. raw_version += strlen("OpenSSL ");
  54. end_of_version = strchr(raw_version, ' ');
  55. }
  56. if (end_of_version)
  57. return tor_strndup(raw_version,
  58. end_of_version-raw_version);
  59. else
  60. return tor_strdup(raw_version);
  61. }
  62. static char *crypto_openssl_version_str = NULL;
  63. /* Return a human-readable version of the run-time openssl version number. */
  64. const char *
  65. crypto_openssl_get_version_str(void)
  66. {
  67. if (crypto_openssl_version_str == NULL) {
  68. const char *raw_version = OpenSSL_version(OPENSSL_VERSION);
  69. crypto_openssl_version_str = parse_openssl_version_str(raw_version);
  70. }
  71. return crypto_openssl_version_str;
  72. }
  73. static char *crypto_openssl_header_version_str = NULL;
  74. /* Return a human-readable version of the compile-time openssl version
  75. * number. */
  76. const char *
  77. crypto_openssl_get_header_version_str(void)
  78. {
  79. if (crypto_openssl_header_version_str == NULL) {
  80. crypto_openssl_header_version_str =
  81. parse_openssl_version_str(OPENSSL_VERSION_TEXT);
  82. }
  83. return crypto_openssl_header_version_str;
  84. }
  85. #ifndef OPENSSL_THREADS
  86. #error OpenSSL has been built without thread support. Tor requires an \
  87. OpenSSL library with thread support enabled.
  88. #endif
  89. #ifndef NEW_THREAD_API
  90. /** Helper: OpenSSL uses this callback to manipulate mutexes. */
  91. STATIC void
  92. openssl_locking_cb_(int mode, int n, const char *file, int line)
  93. {
  94. (void)file;
  95. (void)line;
  96. if (!openssl_mutexes_)
  97. /* This is not a really good fix for the
  98. * "release-freed-lock-from-separate-thread-on-shutdown" problem, but
  99. * it can't hurt. */
  100. return;
  101. if (mode & CRYPTO_LOCK)
  102. tor_mutex_acquire(openssl_mutexes_[n]);
  103. else
  104. tor_mutex_release(openssl_mutexes_[n]);
  105. }
  106. STATIC void
  107. tor_set_openssl_thread_id(CRYPTO_THREADID *threadid)
  108. {
  109. CRYPTO_THREADID_set_numeric(threadid, tor_get_thread_id());
  110. }
  111. #endif /* !defined(NEW_THREAD_API) */
  112. /** Helper: Construct mutexes, and set callbacks to help OpenSSL handle being
  113. * multithreaded. Returns 0. */
  114. int
  115. setup_openssl_threading(void)
  116. {
  117. #ifndef NEW_THREAD_API
  118. int i;
  119. int n = CRYPTO_num_locks();
  120. n_openssl_mutexes_ = n;
  121. openssl_mutexes_ = tor_calloc(n, sizeof(tor_mutex_t *));
  122. for (i=0; i < n; ++i)
  123. openssl_mutexes_[i] = tor_mutex_new();
  124. CRYPTO_set_locking_callback(openssl_locking_cb_);
  125. CRYPTO_THREADID_set_callback(tor_set_openssl_thread_id);
  126. #endif /* !defined(NEW_THREAD_API) */
  127. return 0;
  128. }
  129. /** free OpenSSL variables */
  130. void
  131. crypto_openssl_free_all(void)
  132. {
  133. tor_free(crypto_openssl_version_str);
  134. tor_free(crypto_openssl_header_version_str);
  135. #ifndef NEW_THREAD_API
  136. if (n_openssl_mutexes_) {
  137. int n = n_openssl_mutexes_;
  138. tor_mutex_t **ms = openssl_mutexes_;
  139. int i;
  140. openssl_mutexes_ = NULL;
  141. n_openssl_mutexes_ = 0;
  142. for (i=0;i<n;++i) {
  143. tor_mutex_free(ms[i]);
  144. }
  145. tor_free(ms);
  146. }
  147. #endif /* !defined(NEW_THREAD_API) */
  148. }