tortls.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /* Copyright (c) 2003, Roger Dingledine.
  2. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  3. * Copyright (c) 2007-2018, The Tor Project, Inc. */
  4. /* See LICENSE for licensing information */
  5. #define TORTLS_PRIVATE
  6. #include "lib/tls/x509.h"
  7. #include "lib/tls/tortls.h"
  8. #include "lib/tls/tortls_st.h"
  9. #include "lib/tls/tortls_internal.h"
  10. #include "lib/log/util_bug.h"
  11. #include "lib/intmath/cmp.h"
  12. /** Global TLS contexts. We keep them here because nobody else needs
  13. * to touch them.
  14. *
  15. * @{ */
  16. STATIC tor_tls_context_t *server_tls_context = NULL;
  17. STATIC tor_tls_context_t *client_tls_context = NULL;
  18. /**@}*/
  19. /**
  20. * Return the appropriate TLS context.
  21. */
  22. tor_tls_context_t *
  23. tor_tls_context_get(int is_server)
  24. {
  25. return is_server ? server_tls_context : client_tls_context;
  26. }
  27. /** Increase the reference count of <b>ctx</b>. */
  28. void
  29. tor_tls_context_incref(tor_tls_context_t *ctx)
  30. {
  31. ++ctx->refcnt;
  32. }
  33. /** Remove a reference to <b>ctx</b>, and free it if it has no more
  34. * references. */
  35. void
  36. tor_tls_context_decref(tor_tls_context_t *ctx)
  37. {
  38. tor_assert(ctx);
  39. if (--ctx->refcnt == 0) {
  40. tor_tls_context_impl_free(ctx->ctx);
  41. tor_x509_cert_free(ctx->my_link_cert);
  42. tor_x509_cert_free(ctx->my_id_cert);
  43. tor_x509_cert_free(ctx->my_auth_cert);
  44. crypto_pk_free(ctx->link_key);
  45. crypto_pk_free(ctx->auth_key);
  46. /* LCOV_EXCL_BR_START since ctx will never be NULL here */
  47. tor_free(ctx);
  48. /* LCOV_EXCL_BR_STOP */
  49. }
  50. }
  51. /** Free all global TLS structures. */
  52. void
  53. tor_tls_free_all(void)
  54. {
  55. check_no_tls_errors();
  56. if (server_tls_context) {
  57. tor_tls_context_t *ctx = server_tls_context;
  58. server_tls_context = NULL;
  59. tor_tls_context_decref(ctx);
  60. }
  61. if (client_tls_context) {
  62. tor_tls_context_t *ctx = client_tls_context;
  63. client_tls_context = NULL;
  64. tor_tls_context_decref(ctx);
  65. }
  66. }
  67. /** Given a TOR_TLS_* error code, return a string equivalent. */
  68. const char *
  69. tor_tls_err_to_string(int err)
  70. {
  71. if (err >= 0)
  72. return "[Not an error.]";
  73. switch (err) {
  74. case TOR_TLS_ERROR_MISC: return "misc error";
  75. case TOR_TLS_ERROR_IO: return "unexpected close";
  76. case TOR_TLS_ERROR_CONNREFUSED: return "connection refused";
  77. case TOR_TLS_ERROR_CONNRESET: return "connection reset";
  78. case TOR_TLS_ERROR_NO_ROUTE: return "host unreachable";
  79. case TOR_TLS_ERROR_TIMEOUT: return "connection timed out";
  80. case TOR_TLS_CLOSE: return "closed";
  81. case TOR_TLS_WANTREAD: return "want to read";
  82. case TOR_TLS_WANTWRITE: return "want to write";
  83. default: return "(unknown error code)";
  84. }
  85. }
  86. /** Create new global client and server TLS contexts.
  87. *
  88. * If <b>server_identity</b> is NULL, this will not generate a server
  89. * TLS context. If TOR_TLS_CTX_IS_PUBLIC_SERVER is set in <b>flags</b>, use
  90. * the same TLS context for incoming and outgoing connections, and
  91. * ignore <b>client_identity</b>. If one of TOR_TLS_CTX_USE_ECDHE_P{224,256}
  92. * is set in <b>flags</b>, use that ECDHE group if possible; otherwise use
  93. * the default ECDHE group. */
  94. int
  95. tor_tls_context_init(unsigned flags,
  96. crypto_pk_t *client_identity,
  97. crypto_pk_t *server_identity,
  98. unsigned int key_lifetime)
  99. {
  100. int rv1 = 0;
  101. int rv2 = 0;
  102. const int is_public_server = flags & TOR_TLS_CTX_IS_PUBLIC_SERVER;
  103. check_no_tls_errors();
  104. if (is_public_server) {
  105. tor_tls_context_t *new_ctx;
  106. tor_tls_context_t *old_ctx;
  107. tor_assert(server_identity != NULL);
  108. rv1 = tor_tls_context_init_one(&server_tls_context,
  109. server_identity,
  110. key_lifetime, flags, 0);
  111. if (rv1 >= 0) {
  112. new_ctx = server_tls_context;
  113. tor_tls_context_incref(new_ctx);
  114. old_ctx = client_tls_context;
  115. client_tls_context = new_ctx;
  116. if (old_ctx != NULL) {
  117. tor_tls_context_decref(old_ctx);
  118. }
  119. }
  120. } else {
  121. if (server_identity != NULL) {
  122. rv1 = tor_tls_context_init_one(&server_tls_context,
  123. server_identity,
  124. key_lifetime,
  125. flags,
  126. 0);
  127. } else {
  128. tor_tls_context_t *old_ctx = server_tls_context;
  129. server_tls_context = NULL;
  130. if (old_ctx != NULL) {
  131. tor_tls_context_decref(old_ctx);
  132. }
  133. }
  134. rv2 = tor_tls_context_init_one(&client_tls_context,
  135. client_identity,
  136. key_lifetime,
  137. flags,
  138. 1);
  139. }
  140. tls_log_errors(NULL, LOG_WARN, LD_CRYPTO, "constructing a TLS context");
  141. return MIN(rv1, rv2);
  142. }
  143. /** Make future log messages about <b>tls</b> display the address
  144. * <b>address</b>.
  145. */
  146. void
  147. tor_tls_set_logged_address(tor_tls_t *tls, const char *address)
  148. {
  149. tor_assert(tls);
  150. tor_free(tls->address);
  151. tls->address = tor_strdup(address);
  152. }
  153. /** Return whether this tls initiated the connect (client) or
  154. * received it (server). */
  155. int
  156. tor_tls_is_server(tor_tls_t *tls)
  157. {
  158. tor_assert(tls);
  159. return tls->isServer;
  160. }