openssl-tls.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /*
  2. * libwebsockets - small server side websockets and web server implementation
  3. *
  4. * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to
  8. * deal in the Software without restriction, including without limitation the
  9. * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  10. * sell copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  22. * IN THE SOFTWARE.
  23. */
  24. #include "private-lib-core.h"
  25. #include "private-lib-tls-openssl.h"
  26. extern int openssl_websocket_private_data_index,
  27. openssl_SSL_CTX_private_data_index;
  28. char* lws_ssl_get_error_string(int status, int ret, char *buf, size_t len) {
  29. switch (status) {
  30. case SSL_ERROR_NONE:
  31. return lws_strncpy(buf, "SSL_ERROR_NONE", len);
  32. case SSL_ERROR_ZERO_RETURN:
  33. return lws_strncpy(buf, "SSL_ERROR_ZERO_RETURN", len);
  34. case SSL_ERROR_WANT_READ:
  35. return lws_strncpy(buf, "SSL_ERROR_WANT_READ", len);
  36. case SSL_ERROR_WANT_WRITE:
  37. return lws_strncpy(buf, "SSL_ERROR_WANT_WRITE", len);
  38. case SSL_ERROR_WANT_CONNECT:
  39. return lws_strncpy(buf, "SSL_ERROR_WANT_CONNECT", len);
  40. case SSL_ERROR_WANT_ACCEPT:
  41. return lws_strncpy(buf, "SSL_ERROR_WANT_ACCEPT", len);
  42. case SSL_ERROR_WANT_X509_LOOKUP:
  43. return lws_strncpy(buf, "SSL_ERROR_WANT_X509_LOOKUP", len);
  44. case SSL_ERROR_SYSCALL:
  45. switch (ret) {
  46. case 0:
  47. lws_snprintf(buf, len, "SSL_ERROR_SYSCALL: EOF");
  48. return buf;
  49. case -1:
  50. #ifndef LWS_PLAT_OPTEE
  51. lws_snprintf(buf, len, "SSL_ERROR_SYSCALL: %s",
  52. strerror(errno));
  53. #else
  54. lws_snprintf(buf, len, "SSL_ERROR_SYSCALL: %d", errno);
  55. #endif
  56. return buf;
  57. default:
  58. return strncpy(buf, "SSL_ERROR_SYSCALL", len);
  59. }
  60. case SSL_ERROR_SSL:
  61. return "SSL_ERROR_SSL";
  62. default:
  63. return "SSL_ERROR_UNKNOWN";
  64. }
  65. }
  66. void
  67. lws_tls_err_describe_clear(void)
  68. {
  69. char buf[160];
  70. unsigned long l;
  71. do {
  72. l = ERR_get_error();
  73. if (!l)
  74. break;
  75. ERR_error_string_n(l, buf, sizeof(buf));
  76. lwsl_info(" openssl error: %s\n", buf);
  77. } while (l);
  78. lwsl_info("\n");
  79. }
  80. #if LWS_MAX_SMP != 1
  81. static pthread_mutex_t *openssl_mutexes;
  82. static void
  83. lws_openssl_lock_callback(int mode, int type, const char *file, int line)
  84. {
  85. (void)file;
  86. (void)line;
  87. if (mode & CRYPTO_LOCK)
  88. pthread_mutex_lock(&openssl_mutexes[type]);
  89. else
  90. pthread_mutex_unlock(&openssl_mutexes[type]);
  91. }
  92. static unsigned long
  93. lws_openssl_thread_id(void)
  94. {
  95. return (unsigned long)pthread_self();
  96. }
  97. #endif
  98. int
  99. lws_context_init_ssl_library(const struct lws_context_creation_info *info)
  100. {
  101. #ifdef USE_WOLFSSL
  102. #ifdef USE_OLD_CYASSL
  103. lwsl_info(" Compiled with CyaSSL support\n");
  104. #else
  105. lwsl_info(" Compiled with wolfSSL support\n");
  106. #endif
  107. #else
  108. #if defined(LWS_WITH_BORINGSSL)
  109. lwsl_info(" Compiled with BoringSSL support\n");
  110. #else
  111. lwsl_info(" Compiled with OpenSSL support\n");
  112. #endif
  113. #endif
  114. if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT)) {
  115. lwsl_info(" SSL disabled: no "
  116. "LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT\n");
  117. return 0;
  118. }
  119. /* basic openssl init */
  120. lwsl_info("Doing SSL library init\n");
  121. #if OPENSSL_VERSION_NUMBER < 0x10100000L
  122. SSL_library_init();
  123. OpenSSL_add_all_algorithms();
  124. SSL_load_error_strings();
  125. #else
  126. OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
  127. #endif
  128. #if defined(LWS_WITH_NETWORK)
  129. openssl_websocket_private_data_index =
  130. SSL_get_ex_new_index(0, "lws", NULL, NULL, NULL);
  131. openssl_SSL_CTX_private_data_index = SSL_CTX_get_ex_new_index(0,
  132. NULL, NULL, NULL, NULL);
  133. #endif
  134. #if LWS_MAX_SMP != 1
  135. {
  136. int n;
  137. openssl_mutexes = (pthread_mutex_t *)
  138. OPENSSL_malloc(CRYPTO_num_locks() *
  139. sizeof(openssl_mutexes[0]));
  140. for (n = 0; n < CRYPTO_num_locks(); n++)
  141. pthread_mutex_init(&openssl_mutexes[n], NULL);
  142. /*
  143. * These "functions" disappeared in later OpenSSL which is
  144. * already threadsafe.
  145. */
  146. (void)lws_openssl_thread_id;
  147. (void)lws_openssl_lock_callback;
  148. CRYPTO_set_id_callback(lws_openssl_thread_id);
  149. CRYPTO_set_locking_callback(lws_openssl_lock_callback);
  150. }
  151. #endif
  152. return 0;
  153. }
  154. void
  155. lws_context_deinit_ssl_library(struct lws_context *context)
  156. {
  157. #if LWS_MAX_SMP != 1
  158. int n;
  159. if (!lws_check_opt(context->options,
  160. LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT))
  161. return;
  162. CRYPTO_set_locking_callback(NULL);
  163. for (n = 0; n < CRYPTO_num_locks(); n++)
  164. pthread_mutex_destroy(&openssl_mutexes[n]);
  165. OPENSSL_free(openssl_mutexes);
  166. #endif
  167. }