tortls.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  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. /** Free all global TLS structures. */
  34. void
  35. tor_tls_free_all(void)
  36. {
  37. check_no_tls_errors();
  38. if (server_tls_context) {
  39. tor_tls_context_t *ctx = server_tls_context;
  40. server_tls_context = NULL;
  41. tor_tls_context_decref(ctx);
  42. }
  43. if (client_tls_context) {
  44. tor_tls_context_t *ctx = client_tls_context;
  45. client_tls_context = NULL;
  46. tor_tls_context_decref(ctx);
  47. }
  48. }
  49. /** Given a TOR_TLS_* error code, return a string equivalent. */
  50. const char *
  51. tor_tls_err_to_string(int err)
  52. {
  53. if (err >= 0)
  54. return "[Not an error.]";
  55. switch (err) {
  56. case TOR_TLS_ERROR_MISC: return "misc error";
  57. case TOR_TLS_ERROR_IO: return "unexpected close";
  58. case TOR_TLS_ERROR_CONNREFUSED: return "connection refused";
  59. case TOR_TLS_ERROR_CONNRESET: return "connection reset";
  60. case TOR_TLS_ERROR_NO_ROUTE: return "host unreachable";
  61. case TOR_TLS_ERROR_TIMEOUT: return "connection timed out";
  62. case TOR_TLS_CLOSE: return "closed";
  63. case TOR_TLS_WANTREAD: return "want to read";
  64. case TOR_TLS_WANTWRITE: return "want to write";
  65. default: return "(unknown error code)";
  66. }
  67. }
  68. /** Create new global client and server TLS contexts.
  69. *
  70. * If <b>server_identity</b> is NULL, this will not generate a server
  71. * TLS context. If TOR_TLS_CTX_IS_PUBLIC_SERVER is set in <b>flags</b>, use
  72. * the same TLS context for incoming and outgoing connections, and
  73. * ignore <b>client_identity</b>. If one of TOR_TLS_CTX_USE_ECDHE_P{224,256}
  74. * is set in <b>flags</b>, use that ECDHE group if possible; otherwise use
  75. * the default ECDHE group. */
  76. int
  77. tor_tls_context_init(unsigned flags,
  78. crypto_pk_t *client_identity,
  79. crypto_pk_t *server_identity,
  80. unsigned int key_lifetime)
  81. {
  82. int rv1 = 0;
  83. int rv2 = 0;
  84. const int is_public_server = flags & TOR_TLS_CTX_IS_PUBLIC_SERVER;
  85. check_no_tls_errors();
  86. if (is_public_server) {
  87. tor_tls_context_t *new_ctx;
  88. tor_tls_context_t *old_ctx;
  89. tor_assert(server_identity != NULL);
  90. rv1 = tor_tls_context_init_one(&server_tls_context,
  91. server_identity,
  92. key_lifetime, flags, 0);
  93. if (rv1 >= 0) {
  94. new_ctx = server_tls_context;
  95. tor_tls_context_incref(new_ctx);
  96. old_ctx = client_tls_context;
  97. client_tls_context = new_ctx;
  98. if (old_ctx != NULL) {
  99. tor_tls_context_decref(old_ctx);
  100. }
  101. }
  102. } else {
  103. if (server_identity != NULL) {
  104. rv1 = tor_tls_context_init_one(&server_tls_context,
  105. server_identity,
  106. key_lifetime,
  107. flags,
  108. 0);
  109. } else {
  110. tor_tls_context_t *old_ctx = server_tls_context;
  111. server_tls_context = NULL;
  112. if (old_ctx != NULL) {
  113. tor_tls_context_decref(old_ctx);
  114. }
  115. }
  116. rv2 = tor_tls_context_init_one(&client_tls_context,
  117. client_identity,
  118. key_lifetime,
  119. flags,
  120. 1);
  121. }
  122. tls_log_errors(NULL, LOG_WARN, LD_CRYPTO, "constructing a TLS context");
  123. return MIN(rv1, rv2);
  124. }
  125. /** Make future log messages about <b>tls</b> display the address
  126. * <b>address</b>.
  127. */
  128. void
  129. tor_tls_set_logged_address(tor_tls_t *tls, const char *address)
  130. {
  131. tor_assert(tls);
  132. tor_free(tls->address);
  133. tls->address = tor_strdup(address);
  134. }
  135. /** Return whether this tls initiated the connect (client) or
  136. * received it (server). */
  137. int
  138. tor_tls_is_server(tor_tls_t *tls)
  139. {
  140. tor_assert(tls);
  141. return tls->isServer;
  142. }