hs_client.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. /* Copyright (c) 2016-2017, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. /**
  4. * \file hs_client.c
  5. * \brief Implement next generation hidden service client functionality
  6. **/
  7. #include "or.h"
  8. #include "hs_circuit.h"
  9. #include "hs_ident.h"
  10. #include "connection_edge.h"
  11. #include "rendclient.h"
  12. #include "hs_descriptor.h"
  13. #include "hs_cache.h"
  14. #include "config.h"
  15. #include "directory.h"
  16. #include "hs_client.h"
  17. #include "router.h"
  18. /* A v3 HS circuit successfully connected to the hidden service. Update the
  19. * stream state at <b>hs_conn_ident</b> appropriately. */
  20. static void
  21. note_connection_attempt_succeeded(const hs_ident_edge_conn_t *hs_conn_ident)
  22. {
  23. (void) hs_conn_ident;
  24. /* TODO: When implementing client side */
  25. return;
  26. }
  27. /* Given the pubkey of a hidden service in <b>onion_identity_pk</b>, fetch its
  28. * descriptor by launching a dir connection to <b>hsdir</b>. Return 1 on
  29. * success or -1 on error. */
  30. static int
  31. directory_launch_v3_desc_fetch(const ed25519_public_key_t *onion_identity_pk,
  32. const routerstatus_t *hsdir)
  33. {
  34. uint64_t current_time_period = hs_get_time_period_num(approx_time());
  35. ed25519_public_key_t blinded_pubkey;
  36. char base64_blinded_pubkey[ED25519_BASE64_LEN + 1];
  37. hs_ident_dir_conn_t hs_conn_dir_ident;
  38. int retval;
  39. tor_assert(hsdir);
  40. tor_assert(onion_identity_pk);
  41. /* Get blinded pubkey */
  42. hs_build_blinded_pubkey(onion_identity_pk, NULL, 0,
  43. current_time_period, &blinded_pubkey);
  44. /* ...and base64 it. */
  45. retval = ed25519_public_to_base64(base64_blinded_pubkey, &blinded_pubkey);
  46. if (BUG(retval < 0)) {
  47. return -1;
  48. }
  49. /* Copy onion pk to a dir_ident so that we attach it to the dir conn */
  50. ed25519_pubkey_copy(&hs_conn_dir_ident.identity_pk, onion_identity_pk);
  51. /* Setup directory request */
  52. directory_request_t *req =
  53. directory_request_new(DIR_PURPOSE_FETCH_HSDESC);
  54. directory_request_set_routerstatus(req, hsdir);
  55. directory_request_set_indirection(req, DIRIND_ANONYMOUS);
  56. directory_request_set_resource(req, base64_blinded_pubkey);
  57. directory_request_upload_set_hs_ident(req, &hs_conn_dir_ident);
  58. directory_initiate_request(req);
  59. directory_request_free(req);
  60. log_info(LD_REND, "Descriptor fetch request for service %s with blinded "
  61. "key %s to directory %s",
  62. safe_str_client(ed25519_fmt(onion_identity_pk)),
  63. safe_str_client(base64_blinded_pubkey),
  64. safe_str_client(routerstatus_describe(hsdir)));
  65. /* Cleanup memory. */
  66. memwipe(&blinded_pubkey, 0, sizeof(blinded_pubkey));
  67. memwipe(base64_blinded_pubkey, 0, sizeof(base64_blinded_pubkey));
  68. memwipe(&hs_conn_dir_ident, 0, sizeof(hs_conn_dir_ident));
  69. return 1;
  70. }
  71. /** Return the HSDir we should use to fetch the descriptor of the hidden
  72. * service with identity key <b>onion_identity_pk</b>. */
  73. static routerstatus_t *
  74. pick_hsdir_v3(const ed25519_public_key_t *onion_identity_pk)
  75. {
  76. int retval;
  77. char base64_blinded_pubkey[ED25519_BASE64_LEN + 1];
  78. uint64_t current_time_period = hs_get_time_period_num(approx_time());
  79. smartlist_t *responsible_hsdirs;
  80. ed25519_public_key_t blinded_pubkey;
  81. routerstatus_t *hsdir_rs = NULL;
  82. tor_assert(onion_identity_pk);
  83. responsible_hsdirs = smartlist_new();
  84. /* Get blinded pubkey of hidden service */
  85. hs_build_blinded_pubkey(onion_identity_pk, NULL, 0,
  86. current_time_period, &blinded_pubkey);
  87. /* ...and base64 it. */
  88. retval = ed25519_public_to_base64(base64_blinded_pubkey, &blinded_pubkey);
  89. if (BUG(retval < 0)) {
  90. return NULL;
  91. }
  92. /* Get responsible hsdirs of service for this time period */
  93. hs_get_responsible_hsdirs(&blinded_pubkey, current_time_period, 0, 1,
  94. responsible_hsdirs);
  95. log_debug(LD_REND, "Found %d responsible HSDirs and about to pick one.",
  96. smartlist_len(responsible_hsdirs));
  97. /* Pick an HSDir from the responsible ones. The ownership of
  98. * responsible_hsdirs is given to this function so no need to free it. */
  99. hsdir_rs = hs_pick_hsdir(responsible_hsdirs, base64_blinded_pubkey);
  100. return hsdir_rs;
  101. }
  102. /** Fetch a v3 descriptor using the given <b>onion_identity_pk</b>.
  103. *
  104. * On success, 1 is returned. If no hidden service is left to ask, return 0.
  105. * On error, -1 is returned. */
  106. static int
  107. fetch_v3_desc(const ed25519_public_key_t *onion_identity_pk)
  108. {
  109. routerstatus_t *hsdir_rs =NULL;
  110. tor_assert(onion_identity_pk);
  111. hsdir_rs = pick_hsdir_v3(onion_identity_pk);
  112. if (!hsdir_rs) {
  113. log_info(LD_REND, "Couldn't pick a v3 hsdir.");
  114. return 0;
  115. }
  116. return directory_launch_v3_desc_fetch(onion_identity_pk, hsdir_rs);
  117. }
  118. #if 0
  119. /* Make sure that the given origin circuit circ is a valid correct
  120. * introduction circuit. This asserts on validation failure. */
  121. static void
  122. assert_intro_circ(const origin_circuit_t *circ)
  123. {
  124. tor_assert(circ);
  125. tor_assert(circ->base_.purpose == CIRCUIT_PURPOSE_C_INTRODUCING);
  126. tor_assert(circ->hs_ident);
  127. tor_assert(hs_ident_intro_circ_is_valid(circ->hs_ident));
  128. assert_circ_anonymity_ok(circ, get_options());
  129. }
  130. #endif
  131. /** A circuit just finished connecting to a hidden service that the stream
  132. * <b>conn</b> has been waiting for. Let the HS subsystem know about this. */
  133. void
  134. hs_client_note_connection_attempt_succeeded(const edge_connection_t *conn)
  135. {
  136. tor_assert(connection_edge_is_rendezvous_stream(conn));
  137. if (BUG(conn->rend_data && conn->hs_ident)) {
  138. log_warn(LD_BUG, "Stream had both rend_data and hs_ident..."
  139. "Prioritizing hs_ident");
  140. }
  141. if (conn->hs_ident) { /* It's v3: pass it to the prop224 handler */
  142. note_connection_attempt_succeeded(conn->hs_ident);
  143. return;
  144. } else if (conn->rend_data) { /* It's v2: pass it to the legacy handler */
  145. rend_client_note_connection_attempt_ended(conn->rend_data);
  146. return;
  147. }
  148. }
  149. /* With the given encoded descriptor in desc_str and the service key in
  150. * service_identity_pk, decode the descriptor and set the desc pointer with a
  151. * newly allocated descriptor object.
  152. *
  153. * Return 0 on success else a negative value and desc is set to NULL. */
  154. int
  155. hs_client_decode_descriptor(const char *desc_str,
  156. const ed25519_public_key_t *service_identity_pk,
  157. hs_descriptor_t **desc)
  158. {
  159. int ret;
  160. uint8_t subcredential[DIGEST256_LEN];
  161. tor_assert(desc_str);
  162. tor_assert(service_identity_pk);
  163. tor_assert(desc);
  164. /* Create subcredential for this HS so that we can decrypt */
  165. {
  166. ed25519_public_key_t blinded_pubkey;
  167. uint64_t current_time_period = hs_get_time_period_num(approx_time());
  168. hs_build_blinded_pubkey(service_identity_pk, NULL, 0, current_time_period,
  169. &blinded_pubkey);
  170. hs_get_subcredential(service_identity_pk, &blinded_pubkey, subcredential);
  171. }
  172. /* Parse descriptor */
  173. ret = hs_desc_decode_descriptor(desc_str, subcredential, desc);
  174. memwipe(subcredential, 0, sizeof(subcredential));
  175. if (ret < 0) {
  176. log_warn(LD_GENERAL, "Could not parse received descriptor as client");
  177. goto err;
  178. }
  179. return 0;
  180. err:
  181. return -1;
  182. }
  183. /** Return true if there are any usable intro points in the v3 HS descriptor
  184. * <b>desc</b>. */
  185. int
  186. hs_client_any_intro_points_usable(const hs_descriptor_t *desc)
  187. {
  188. /* XXX stub waiting for more client-side work:
  189. equivalent to v2 rend_client_any_intro_points_usable() */
  190. tor_assert(desc);
  191. return 1;
  192. }
  193. /** Launch a connection to a hidden service directory to fetch a hidden
  194. * service descriptor using <b>identity_pk</b> to get the necessary keys.
  195. *
  196. * On success, 1 is returned. If no hidden service is left to ask, return 0.
  197. * On error, -1 is returned. (retval is only used by unittests right now) */
  198. int
  199. hs_client_refetch_hsdesc(const ed25519_public_key_t *identity_pk)
  200. {
  201. tor_assert(identity_pk);
  202. /* Are we configured to fetch descriptors? */
  203. if (!get_options()->FetchHidServDescriptors) {
  204. log_warn(LD_REND, "We received an onion address for a hidden service "
  205. "descriptor but we are configured to not fetch.");
  206. return 0;
  207. }
  208. /* Check if fetching a desc for this HS is useful to us right now */
  209. {
  210. const hs_descriptor_t *cached_desc = NULL;
  211. cached_desc = hs_cache_lookup_as_client(identity_pk);
  212. if (cached_desc && hs_client_any_intro_points_usable(cached_desc)) {
  213. log_warn(LD_GENERAL, "We would fetch a v3 hidden service descriptor "
  214. "but we already have a useable descriprot.");
  215. return 0;
  216. }
  217. }
  218. return fetch_v3_desc(identity_pk);
  219. }