hs_common.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. /* Copyright (c) 2016-2017, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. /**
  4. * \file hs_common.c
  5. * \brief Contains code shared between different HS protocol version as well
  6. * as useful data structures and accessors used by other subsystems.
  7. * The rendcommon.c should only contains code relating to the v2
  8. * protocol.
  9. **/
  10. #define HS_COMMON_PRIVATE
  11. #include "or.h"
  12. #include "config.h"
  13. #include "networkstatus.h"
  14. #include "hs_cache.h"
  15. #include "hs_common.h"
  16. #include "hs_service.h"
  17. #include "rendcommon.h"
  18. /* Make sure that the directory for <b>service</b> is private, using the config
  19. * <b>username</b>.
  20. * If <b>create</b> is true:
  21. * - if the directory exists, change permissions if needed,
  22. * - if the directory does not exist, create it with the correct permissions.
  23. * If <b>create</b> is false:
  24. * - if the directory exists, check permissions,
  25. * - if the directory does not exist, check if we think we can create it.
  26. * Return 0 on success, -1 on failure. */
  27. int
  28. hs_check_service_private_dir(const char *username, const char *path,
  29. unsigned int dir_group_readable,
  30. unsigned int create)
  31. {
  32. cpd_check_t check_opts = CPD_NONE;
  33. tor_assert(path);
  34. if (create) {
  35. check_opts |= CPD_CREATE;
  36. } else {
  37. check_opts |= CPD_CHECK_MODE_ONLY;
  38. check_opts |= CPD_CHECK;
  39. }
  40. if (dir_group_readable) {
  41. check_opts |= CPD_GROUP_READ;
  42. }
  43. /* Check/create directory */
  44. if (check_private_dir(path, check_opts, username) < 0) {
  45. return -1;
  46. }
  47. return 0;
  48. }
  49. /** Get the default HS time period length in minutes from the consensus. */
  50. STATIC uint64_t
  51. get_time_period_length(void)
  52. {
  53. int32_t time_period_length = networkstatus_get_param(NULL, "hsdir-interval",
  54. HS_TIME_PERIOD_LENGTH_DEFAULT,
  55. HS_TIME_PERIOD_LENGTH_MIN,
  56. HS_TIME_PERIOD_LENGTH_MAX);
  57. /* Make sure it's a positive value. */
  58. tor_assert(time_period_length >= 0);
  59. /* uint64_t will always be able to contain a int32_t */
  60. return (uint64_t) time_period_length;
  61. }
  62. /** Get the HS time period number at time <b>now</b> */
  63. STATIC uint64_t
  64. get_time_period_num(time_t now)
  65. {
  66. uint64_t time_period_num;
  67. uint64_t time_period_length = get_time_period_length();
  68. uint64_t minutes_since_epoch = now / 60;
  69. /* Now subtract half a day to fit the prop224 time period schedule (see
  70. * section [TIME-PERIODS]). */
  71. tor_assert(minutes_since_epoch > HS_TIME_PERIOD_ROTATION_OFFSET);
  72. minutes_since_epoch -= HS_TIME_PERIOD_ROTATION_OFFSET;
  73. /* Calculate the time period */
  74. time_period_num = minutes_since_epoch / time_period_length;
  75. return time_period_num;
  76. }
  77. /** Get the number of the _upcoming_ HS time period, given that the current
  78. * time is <b>now</b>. */
  79. uint64_t
  80. hs_get_next_time_period_num(time_t now)
  81. {
  82. return get_time_period_num(now) + 1;
  83. }
  84. /* Create a new rend_data_t for a specific given <b>version</b>.
  85. * Return a pointer to the newly allocated data structure. */
  86. static rend_data_t *
  87. rend_data_alloc(uint32_t version)
  88. {
  89. rend_data_t *rend_data = NULL;
  90. switch (version) {
  91. case HS_VERSION_TWO:
  92. {
  93. rend_data_v2_t *v2 = tor_malloc_zero(sizeof(*v2));
  94. v2->base_.version = HS_VERSION_TWO;
  95. v2->base_.hsdirs_fp = smartlist_new();
  96. rend_data = &v2->base_;
  97. break;
  98. }
  99. default:
  100. tor_assert(0);
  101. break;
  102. }
  103. return rend_data;
  104. }
  105. /** Free all storage associated with <b>data</b> */
  106. void
  107. rend_data_free(rend_data_t *data)
  108. {
  109. if (!data) {
  110. return;
  111. }
  112. /* By using our allocation function, this should always be set. */
  113. tor_assert(data->hsdirs_fp);
  114. /* Cleanup the HSDir identity digest. */
  115. SMARTLIST_FOREACH(data->hsdirs_fp, char *, d, tor_free(d));
  116. smartlist_free(data->hsdirs_fp);
  117. /* Depending on the version, cleanup. */
  118. switch (data->version) {
  119. case HS_VERSION_TWO:
  120. {
  121. rend_data_v2_t *v2_data = TO_REND_DATA_V2(data);
  122. tor_free(v2_data);
  123. break;
  124. }
  125. default:
  126. tor_assert(0);
  127. }
  128. }
  129. /* Allocate and return a deep copy of <b>data</b>. */
  130. rend_data_t *
  131. rend_data_dup(const rend_data_t *data)
  132. {
  133. rend_data_t *data_dup = NULL;
  134. smartlist_t *hsdirs_fp = smartlist_new();
  135. tor_assert(data);
  136. tor_assert(data->hsdirs_fp);
  137. SMARTLIST_FOREACH(data->hsdirs_fp, char *, fp,
  138. smartlist_add(hsdirs_fp, tor_memdup(fp, DIGEST_LEN)));
  139. switch (data->version) {
  140. case HS_VERSION_TWO:
  141. {
  142. rend_data_v2_t *v2_data = tor_memdup(TO_REND_DATA_V2(data),
  143. sizeof(*v2_data));
  144. data_dup = &v2_data->base_;
  145. data_dup->hsdirs_fp = hsdirs_fp;
  146. break;
  147. }
  148. default:
  149. tor_assert(0);
  150. break;
  151. }
  152. return data_dup;
  153. }
  154. /* Compute the descriptor ID for each HS descriptor replica and save them. A
  155. * valid onion address must be present in the <b>rend_data</b>.
  156. *
  157. * Return 0 on success else -1. */
  158. static int
  159. compute_desc_id(rend_data_t *rend_data)
  160. {
  161. int ret = 0;
  162. unsigned replica;
  163. time_t now = time(NULL);
  164. tor_assert(rend_data);
  165. switch (rend_data->version) {
  166. case HS_VERSION_TWO:
  167. {
  168. rend_data_v2_t *v2_data = TO_REND_DATA_V2(rend_data);
  169. /* Compute descriptor ID for each replicas. */
  170. for (replica = 0; replica < ARRAY_LENGTH(v2_data->descriptor_id);
  171. replica++) {
  172. ret = rend_compute_v2_desc_id(v2_data->descriptor_id[replica],
  173. v2_data->onion_address,
  174. v2_data->descriptor_cookie,
  175. now, replica);
  176. if (ret < 0) {
  177. goto end;
  178. }
  179. }
  180. break;
  181. }
  182. default:
  183. tor_assert(0);
  184. }
  185. end:
  186. return ret;
  187. }
  188. /* Allocate and initialize a rend_data_t object for a service using the
  189. * provided arguments. All arguments are optional (can be NULL), except from
  190. * <b>onion_address</b> which MUST be set. The <b>pk_digest</b> is the hash of
  191. * the service private key. The <b>cookie</b> is the rendezvous cookie and
  192. * <b>auth_type</b> is which authentiation this service is configured with.
  193. *
  194. * Return a valid rend_data_t pointer. This only returns a version 2 object of
  195. * rend_data_t. */
  196. rend_data_t *
  197. rend_data_service_create(const char *onion_address, const char *pk_digest,
  198. const uint8_t *cookie, rend_auth_type_t auth_type)
  199. {
  200. /* Create a rend_data_t object for version 2. */
  201. rend_data_t *rend_data = rend_data_alloc(HS_VERSION_TWO);
  202. rend_data_v2_t *v2= TO_REND_DATA_V2(rend_data);
  203. /* We need at least one else the call is wrong. */
  204. tor_assert(onion_address != NULL);
  205. if (pk_digest) {
  206. memcpy(v2->rend_pk_digest, pk_digest, sizeof(v2->rend_pk_digest));
  207. }
  208. if (cookie) {
  209. memcpy(rend_data->rend_cookie, cookie, sizeof(rend_data->rend_cookie));
  210. }
  211. strlcpy(v2->onion_address, onion_address, sizeof(v2->onion_address));
  212. v2->auth_type = auth_type;
  213. return rend_data;
  214. }
  215. /* Allocate and initialize a rend_data_t object for a client request using the
  216. * given arguments. Either an onion address or a descriptor ID is needed. Both
  217. * can be given but in this case only the onion address will be used to make
  218. * the descriptor fetch. The <b>cookie</b> is the rendezvous cookie and
  219. * <b>auth_type</b> is which authentiation the service is configured with.
  220. *
  221. * Return a valid rend_data_t pointer or NULL on error meaning the
  222. * descriptor IDs couldn't be computed from the given data. */
  223. rend_data_t *
  224. rend_data_client_create(const char *onion_address, const char *desc_id,
  225. const char *cookie, rend_auth_type_t auth_type)
  226. {
  227. /* Create a rend_data_t object for version 2. */
  228. rend_data_t *rend_data = rend_data_alloc(HS_VERSION_TWO);
  229. rend_data_v2_t *v2= TO_REND_DATA_V2(rend_data);
  230. /* We need at least one else the call is wrong. */
  231. tor_assert(onion_address != NULL || desc_id != NULL);
  232. if (cookie) {
  233. memcpy(v2->descriptor_cookie, cookie, sizeof(v2->descriptor_cookie));
  234. }
  235. if (desc_id) {
  236. memcpy(v2->desc_id_fetch, desc_id, sizeof(v2->desc_id_fetch));
  237. }
  238. if (onion_address) {
  239. strlcpy(v2->onion_address, onion_address, sizeof(v2->onion_address));
  240. if (compute_desc_id(rend_data) < 0) {
  241. goto error;
  242. }
  243. }
  244. v2->auth_type = auth_type;
  245. return rend_data;
  246. error:
  247. rend_data_free(rend_data);
  248. return NULL;
  249. }
  250. /* Return the onion address from the rend data. Depending on the version,
  251. * the size of the address can vary but it's always NUL terminated. */
  252. const char *
  253. rend_data_get_address(const rend_data_t *rend_data)
  254. {
  255. tor_assert(rend_data);
  256. switch (rend_data->version) {
  257. case HS_VERSION_TWO:
  258. return TO_REND_DATA_V2(rend_data)->onion_address;
  259. default:
  260. /* We should always have a supported version. */
  261. tor_assert(0);
  262. }
  263. }
  264. /* Return the descriptor ID for a specific replica number from the rend
  265. * data. The returned data is a binary digest and depending on the version its
  266. * size can vary. The size of the descriptor ID is put in <b>len_out</b> if
  267. * non NULL. */
  268. const char *
  269. rend_data_get_desc_id(const rend_data_t *rend_data, uint8_t replica,
  270. size_t *len_out)
  271. {
  272. tor_assert(rend_data);
  273. switch (rend_data->version) {
  274. case HS_VERSION_TWO:
  275. tor_assert(replica < REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS);
  276. if (len_out) {
  277. *len_out = DIGEST_LEN;
  278. }
  279. return TO_REND_DATA_V2(rend_data)->descriptor_id[replica];
  280. default:
  281. /* We should always have a supported version. */
  282. tor_assert(0);
  283. }
  284. }
  285. /* Return the public key digest using the given <b>rend_data</b>. The size of
  286. * the digest is put in <b>len_out</b> (if set) which can differ depending on
  287. * the version. */
  288. const uint8_t *
  289. rend_data_get_pk_digest(const rend_data_t *rend_data, size_t *len_out)
  290. {
  291. tor_assert(rend_data);
  292. switch (rend_data->version) {
  293. case HS_VERSION_TWO:
  294. {
  295. const rend_data_v2_t *v2_data = TO_REND_DATA_V2(rend_data);
  296. if (len_out) {
  297. *len_out = sizeof(v2_data->rend_pk_digest);
  298. }
  299. return (const uint8_t *) v2_data->rend_pk_digest;
  300. }
  301. default:
  302. /* We should always have a supported version. */
  303. tor_assert(0);
  304. }
  305. }
  306. /* Initialize the entire HS subsytem. This is called in tor_init() before any
  307. * torrc options are loaded. Only for >= v3. */
  308. void
  309. hs_init(void)
  310. {
  311. hs_circuitmap_init();
  312. hs_service_init();
  313. hs_cache_init();
  314. }
  315. /* Release and cleanup all memory of the HS subsystem (all version). This is
  316. * called by tor_free_all(). */
  317. void
  318. hs_free_all(void)
  319. {
  320. hs_circuitmap_free_all();
  321. hs_service_free_all();
  322. hs_cache_free_all();
  323. }