hs_common.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  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. /* Allocate and return a string containing the path to filename in directory.
  19. * This function will never return NULL. The caller must free this path. */
  20. char *
  21. hs_path_from_filename(const char *directory, const char *filename)
  22. {
  23. char *file_path = NULL;
  24. tor_assert(directory);
  25. tor_assert(filename);
  26. tor_asprintf(&file_path, "%s%s%s", directory, PATH_SEPARATOR, filename);
  27. return file_path;
  28. }
  29. /* Make sure that the directory for <b>service</b> is private, using the config
  30. * <b>username</b>.
  31. * If <b>create</b> is true:
  32. * - if the directory exists, change permissions if needed,
  33. * - if the directory does not exist, create it with the correct permissions.
  34. * If <b>create</b> is false:
  35. * - if the directory exists, check permissions,
  36. * - if the directory does not exist, check if we think we can create it.
  37. * Return 0 on success, -1 on failure. */
  38. int
  39. hs_check_service_private_dir(const char *username, const char *path,
  40. unsigned int dir_group_readable,
  41. unsigned int create)
  42. {
  43. cpd_check_t check_opts = CPD_NONE;
  44. tor_assert(path);
  45. if (create) {
  46. check_opts |= CPD_CREATE;
  47. } else {
  48. check_opts |= CPD_CHECK_MODE_ONLY;
  49. check_opts |= CPD_CHECK;
  50. }
  51. if (dir_group_readable) {
  52. check_opts |= CPD_GROUP_READ;
  53. }
  54. /* Check/create directory */
  55. if (check_private_dir(path, check_opts, username) < 0) {
  56. return -1;
  57. }
  58. return 0;
  59. }
  60. /** Get the default HS time period length in minutes from the consensus. */
  61. STATIC uint64_t
  62. get_time_period_length(void)
  63. {
  64. int32_t time_period_length = networkstatus_get_param(NULL, "hsdir-interval",
  65. HS_TIME_PERIOD_LENGTH_DEFAULT,
  66. HS_TIME_PERIOD_LENGTH_MIN,
  67. HS_TIME_PERIOD_LENGTH_MAX);
  68. /* Make sure it's a positive value. */
  69. tor_assert(time_period_length >= 0);
  70. /* uint64_t will always be able to contain a int32_t */
  71. return (uint64_t) time_period_length;
  72. }
  73. /** Get the HS time period number at time <b>now</b> */
  74. STATIC uint64_t
  75. get_time_period_num(time_t now)
  76. {
  77. uint64_t time_period_num;
  78. uint64_t time_period_length = get_time_period_length();
  79. uint64_t minutes_since_epoch = now / 60;
  80. /* Now subtract half a day to fit the prop224 time period schedule (see
  81. * section [TIME-PERIODS]). */
  82. tor_assert(minutes_since_epoch > HS_TIME_PERIOD_ROTATION_OFFSET);
  83. minutes_since_epoch -= HS_TIME_PERIOD_ROTATION_OFFSET;
  84. /* Calculate the time period */
  85. time_period_num = minutes_since_epoch / time_period_length;
  86. return time_period_num;
  87. }
  88. /** Get the number of the _upcoming_ HS time period, given that the current
  89. * time is <b>now</b>. */
  90. uint64_t
  91. hs_get_next_time_period_num(time_t now)
  92. {
  93. return get_time_period_num(now) + 1;
  94. }
  95. /* Create a new rend_data_t for a specific given <b>version</b>.
  96. * Return a pointer to the newly allocated data structure. */
  97. static rend_data_t *
  98. rend_data_alloc(uint32_t version)
  99. {
  100. rend_data_t *rend_data = NULL;
  101. switch (version) {
  102. case HS_VERSION_TWO:
  103. {
  104. rend_data_v2_t *v2 = tor_malloc_zero(sizeof(*v2));
  105. v2->base_.version = HS_VERSION_TWO;
  106. v2->base_.hsdirs_fp = smartlist_new();
  107. rend_data = &v2->base_;
  108. break;
  109. }
  110. default:
  111. tor_assert(0);
  112. break;
  113. }
  114. return rend_data;
  115. }
  116. /** Free all storage associated with <b>data</b> */
  117. void
  118. rend_data_free(rend_data_t *data)
  119. {
  120. if (!data) {
  121. return;
  122. }
  123. /* By using our allocation function, this should always be set. */
  124. tor_assert(data->hsdirs_fp);
  125. /* Cleanup the HSDir identity digest. */
  126. SMARTLIST_FOREACH(data->hsdirs_fp, char *, d, tor_free(d));
  127. smartlist_free(data->hsdirs_fp);
  128. /* Depending on the version, cleanup. */
  129. switch (data->version) {
  130. case HS_VERSION_TWO:
  131. {
  132. rend_data_v2_t *v2_data = TO_REND_DATA_V2(data);
  133. tor_free(v2_data);
  134. break;
  135. }
  136. default:
  137. tor_assert(0);
  138. }
  139. }
  140. /* Allocate and return a deep copy of <b>data</b>. */
  141. rend_data_t *
  142. rend_data_dup(const rend_data_t *data)
  143. {
  144. rend_data_t *data_dup = NULL;
  145. smartlist_t *hsdirs_fp = smartlist_new();
  146. tor_assert(data);
  147. tor_assert(data->hsdirs_fp);
  148. SMARTLIST_FOREACH(data->hsdirs_fp, char *, fp,
  149. smartlist_add(hsdirs_fp, tor_memdup(fp, DIGEST_LEN)));
  150. switch (data->version) {
  151. case HS_VERSION_TWO:
  152. {
  153. rend_data_v2_t *v2_data = tor_memdup(TO_REND_DATA_V2(data),
  154. sizeof(*v2_data));
  155. data_dup = &v2_data->base_;
  156. data_dup->hsdirs_fp = hsdirs_fp;
  157. break;
  158. }
  159. default:
  160. tor_assert(0);
  161. break;
  162. }
  163. return data_dup;
  164. }
  165. /* Compute the descriptor ID for each HS descriptor replica and save them. A
  166. * valid onion address must be present in the <b>rend_data</b>.
  167. *
  168. * Return 0 on success else -1. */
  169. static int
  170. compute_desc_id(rend_data_t *rend_data)
  171. {
  172. int ret = 0;
  173. unsigned replica;
  174. time_t now = time(NULL);
  175. tor_assert(rend_data);
  176. switch (rend_data->version) {
  177. case HS_VERSION_TWO:
  178. {
  179. rend_data_v2_t *v2_data = TO_REND_DATA_V2(rend_data);
  180. /* Compute descriptor ID for each replicas. */
  181. for (replica = 0; replica < ARRAY_LENGTH(v2_data->descriptor_id);
  182. replica++) {
  183. ret = rend_compute_v2_desc_id(v2_data->descriptor_id[replica],
  184. v2_data->onion_address,
  185. v2_data->descriptor_cookie,
  186. now, replica);
  187. if (ret < 0) {
  188. goto end;
  189. }
  190. }
  191. break;
  192. }
  193. default:
  194. tor_assert(0);
  195. }
  196. end:
  197. return ret;
  198. }
  199. /* Allocate and initialize a rend_data_t object for a service using the
  200. * provided arguments. All arguments are optional (can be NULL), except from
  201. * <b>onion_address</b> which MUST be set. The <b>pk_digest</b> is the hash of
  202. * the service private key. The <b>cookie</b> is the rendezvous cookie and
  203. * <b>auth_type</b> is which authentiation this service is configured with.
  204. *
  205. * Return a valid rend_data_t pointer. This only returns a version 2 object of
  206. * rend_data_t. */
  207. rend_data_t *
  208. rend_data_service_create(const char *onion_address, const char *pk_digest,
  209. const uint8_t *cookie, rend_auth_type_t auth_type)
  210. {
  211. /* Create a rend_data_t object for version 2. */
  212. rend_data_t *rend_data = rend_data_alloc(HS_VERSION_TWO);
  213. rend_data_v2_t *v2= TO_REND_DATA_V2(rend_data);
  214. /* We need at least one else the call is wrong. */
  215. tor_assert(onion_address != NULL);
  216. if (pk_digest) {
  217. memcpy(v2->rend_pk_digest, pk_digest, sizeof(v2->rend_pk_digest));
  218. }
  219. if (cookie) {
  220. memcpy(rend_data->rend_cookie, cookie, sizeof(rend_data->rend_cookie));
  221. }
  222. strlcpy(v2->onion_address, onion_address, sizeof(v2->onion_address));
  223. v2->auth_type = auth_type;
  224. return rend_data;
  225. }
  226. /* Allocate and initialize a rend_data_t object for a client request using the
  227. * given arguments. Either an onion address or a descriptor ID is needed. Both
  228. * can be given but in this case only the onion address will be used to make
  229. * the descriptor fetch. The <b>cookie</b> is the rendezvous cookie and
  230. * <b>auth_type</b> is which authentiation the service is configured with.
  231. *
  232. * Return a valid rend_data_t pointer or NULL on error meaning the
  233. * descriptor IDs couldn't be computed from the given data. */
  234. rend_data_t *
  235. rend_data_client_create(const char *onion_address, const char *desc_id,
  236. const char *cookie, rend_auth_type_t auth_type)
  237. {
  238. /* Create a rend_data_t object for version 2. */
  239. rend_data_t *rend_data = rend_data_alloc(HS_VERSION_TWO);
  240. rend_data_v2_t *v2= TO_REND_DATA_V2(rend_data);
  241. /* We need at least one else the call is wrong. */
  242. tor_assert(onion_address != NULL || desc_id != NULL);
  243. if (cookie) {
  244. memcpy(v2->descriptor_cookie, cookie, sizeof(v2->descriptor_cookie));
  245. }
  246. if (desc_id) {
  247. memcpy(v2->desc_id_fetch, desc_id, sizeof(v2->desc_id_fetch));
  248. }
  249. if (onion_address) {
  250. strlcpy(v2->onion_address, onion_address, sizeof(v2->onion_address));
  251. if (compute_desc_id(rend_data) < 0) {
  252. goto error;
  253. }
  254. }
  255. v2->auth_type = auth_type;
  256. return rend_data;
  257. error:
  258. rend_data_free(rend_data);
  259. return NULL;
  260. }
  261. /* Return the onion address from the rend data. Depending on the version,
  262. * the size of the address can vary but it's always NUL terminated. */
  263. const char *
  264. rend_data_get_address(const rend_data_t *rend_data)
  265. {
  266. tor_assert(rend_data);
  267. switch (rend_data->version) {
  268. case HS_VERSION_TWO:
  269. return TO_REND_DATA_V2(rend_data)->onion_address;
  270. default:
  271. /* We should always have a supported version. */
  272. tor_assert(0);
  273. }
  274. }
  275. /* Return the descriptor ID for a specific replica number from the rend
  276. * data. The returned data is a binary digest and depending on the version its
  277. * size can vary. The size of the descriptor ID is put in <b>len_out</b> if
  278. * non NULL. */
  279. const char *
  280. rend_data_get_desc_id(const rend_data_t *rend_data, uint8_t replica,
  281. size_t *len_out)
  282. {
  283. tor_assert(rend_data);
  284. switch (rend_data->version) {
  285. case HS_VERSION_TWO:
  286. tor_assert(replica < REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS);
  287. if (len_out) {
  288. *len_out = DIGEST_LEN;
  289. }
  290. return TO_REND_DATA_V2(rend_data)->descriptor_id[replica];
  291. default:
  292. /* We should always have a supported version. */
  293. tor_assert(0);
  294. }
  295. }
  296. /* Return the public key digest using the given <b>rend_data</b>. The size of
  297. * the digest is put in <b>len_out</b> (if set) which can differ depending on
  298. * the version. */
  299. const uint8_t *
  300. rend_data_get_pk_digest(const rend_data_t *rend_data, size_t *len_out)
  301. {
  302. tor_assert(rend_data);
  303. switch (rend_data->version) {
  304. case HS_VERSION_TWO:
  305. {
  306. const rend_data_v2_t *v2_data = TO_REND_DATA_V2(rend_data);
  307. if (len_out) {
  308. *len_out = sizeof(v2_data->rend_pk_digest);
  309. }
  310. return (const uint8_t *) v2_data->rend_pk_digest;
  311. }
  312. default:
  313. /* We should always have a supported version. */
  314. tor_assert(0);
  315. }
  316. }
  317. /* Using an ed25519 public key and version to build the checksum of an
  318. * address. Put in checksum_out. Format is:
  319. * SHA3-256(".onion checksum" || PUBKEY || VERSION)
  320. *
  321. * checksum_out must be large enough to receive 32 bytes (DIGEST256_LEN). */
  322. static void
  323. build_hs_checksum(const ed25519_public_key_t *key, uint8_t version,
  324. uint8_t *checksum_out)
  325. {
  326. size_t offset = 0;
  327. char data[HS_SERVICE_ADDR_CHECKSUM_INPUT_LEN];
  328. /* Build checksum data. */
  329. memcpy(data, HS_SERVICE_ADDR_CHECKSUM_PREFIX,
  330. HS_SERVICE_ADDR_CHECKSUM_PREFIX_LEN);
  331. offset += HS_SERVICE_ADDR_CHECKSUM_PREFIX_LEN;
  332. memcpy(data + offset, key->pubkey, ED25519_PUBKEY_LEN);
  333. offset += ED25519_PUBKEY_LEN;
  334. set_uint8(data + offset, version);
  335. offset += sizeof(version);
  336. tor_assert(offset == HS_SERVICE_ADDR_CHECKSUM_INPUT_LEN);
  337. /* Hash the data payload to create the checksum. */
  338. crypto_digest256((char *) checksum_out, data, sizeof(data),
  339. DIGEST_SHA3_256);
  340. }
  341. /* Using an ed25519 public key, checksum and version to build the binary
  342. * representation of a service address. Put in addr_out. Format is:
  343. * addr_out = PUBKEY || CHECKSUM || VERSION
  344. *
  345. * addr_out must be large enough to receive HS_SERVICE_ADDR_LEN bytes. */
  346. static void
  347. build_hs_address(const ed25519_public_key_t *key, const uint8_t *checksum,
  348. uint8_t version, char *addr_out)
  349. {
  350. size_t offset = 0;
  351. tor_assert(key);
  352. tor_assert(checksum);
  353. memcpy(addr_out, key->pubkey, ED25519_PUBKEY_LEN);
  354. offset += ED25519_PUBKEY_LEN;
  355. memcpy(addr_out + offset, checksum, HS_SERVICE_ADDR_CHECKSUM_LEN_USED);
  356. offset += HS_SERVICE_ADDR_CHECKSUM_LEN_USED;
  357. set_uint8(addr_out + offset, version);
  358. offset += sizeof(uint8_t);
  359. tor_assert(offset == HS_SERVICE_ADDR_LEN);
  360. }
  361. /* Helper for hs_parse_address(): Using a binary representation of a service
  362. * address, parse its content into the key_out, checksum_out and version_out.
  363. * Any out variable can be NULL in case the caller would want only one field.
  364. * checksum_out MUST at least be 2 bytes long. address must be at least
  365. * HS_SERVICE_ADDR_LEN bytes but doesn't need to be NUL terminated. */
  366. static void
  367. hs_parse_address_impl(const char *address, ed25519_public_key_t *key_out,
  368. uint8_t *checksum_out, uint8_t *version_out)
  369. {
  370. size_t offset = 0;
  371. tor_assert(address);
  372. if (key_out) {
  373. /* First is the key. */
  374. memcpy(key_out->pubkey, address, ED25519_PUBKEY_LEN);
  375. }
  376. offset += ED25519_PUBKEY_LEN;
  377. if (checksum_out) {
  378. /* Followed by a 2 bytes checksum. */
  379. memcpy(checksum_out, address + offset, HS_SERVICE_ADDR_CHECKSUM_LEN_USED);
  380. }
  381. offset += HS_SERVICE_ADDR_CHECKSUM_LEN_USED;
  382. if (version_out) {
  383. /* Finally, version value is 1 byte. */
  384. *version_out = get_uint8(address + offset);
  385. }
  386. offset += sizeof(uint8_t);
  387. /* Extra safety. */
  388. tor_assert(offset == HS_SERVICE_ADDR_LEN);
  389. }
  390. /* Using a base32 representation of a service address, parse its content into
  391. * the key_out, checksum_out and version_out. Any out variable can be NULL in
  392. * case the caller would want only one field. checksum_out MUST at least be 2
  393. * bytes long.
  394. *
  395. * Return 0 if parsing went well; return -1 in case of error. */
  396. int
  397. hs_parse_address(const char *address, ed25519_public_key_t *key_out,
  398. uint8_t *checksum_out, uint8_t *version_out)
  399. {
  400. char decoded[HS_SERVICE_ADDR_LEN];
  401. tor_assert(address);
  402. /* Obvious length check. */
  403. if (strlen(address) != HS_SERVICE_ADDR_LEN_BASE32) {
  404. log_warn(LD_REND, "Service address %s has an invalid length. "
  405. "Expected %ld but got %lu.",
  406. escaped_safe_str(address), HS_SERVICE_ADDR_LEN_BASE32,
  407. strlen(address));
  408. goto invalid;
  409. }
  410. /* Decode address so we can extract needed fields. */
  411. if (base32_decode(decoded, sizeof(decoded), address, strlen(address)) < 0) {
  412. log_warn(LD_REND, "Service address %s can't be decoded.",
  413. escaped_safe_str(address));
  414. goto invalid;
  415. }
  416. /* Parse the decoded address into the fields we need. */
  417. hs_parse_address_impl(decoded, key_out, checksum_out, version_out);
  418. return 0;
  419. invalid:
  420. return -1;
  421. }
  422. /* Validate a given onion address. The length, the base32 decoding and
  423. * checksum are validated. Return 1 if valid else 0. */
  424. int
  425. hs_address_is_valid(const char *address)
  426. {
  427. uint8_t version;
  428. uint8_t checksum[HS_SERVICE_ADDR_CHECKSUM_LEN_USED];
  429. uint8_t target_checksum[DIGEST256_LEN];
  430. ed25519_public_key_t key;
  431. /* Parse the decoded address into the fields we need. */
  432. if (hs_parse_address(address, &key, checksum, &version) < 0) {
  433. goto invalid;
  434. }
  435. /* Get the checksum it's suppose to be and compare it with what we have
  436. * encoded in the address. */
  437. build_hs_checksum(&key, version, target_checksum);
  438. if (tor_memcmp(checksum, target_checksum, sizeof(checksum))) {
  439. log_warn(LD_REND, "Service address %s invalid checksum.",
  440. escaped_safe_str(address));
  441. goto invalid;
  442. }
  443. /* Valid address. */
  444. return 1;
  445. invalid:
  446. return 0;
  447. }
  448. /* Build a service address using an ed25519 public key and a given version.
  449. * The returned address is base32 encoded and put in addr_out. The caller MUST
  450. * make sure the addr_out is at least HS_SERVICE_ADDR_LEN_BASE32 + 1 long.
  451. *
  452. * Format is as follow:
  453. * base32(PUBKEY || CHECKSUM || VERSION)
  454. * CHECKSUM = H(".onion checksum" || PUBKEY || VERSION)
  455. * */
  456. void
  457. hs_build_address(const ed25519_public_key_t *key, uint8_t version,
  458. char *addr_out)
  459. {
  460. uint8_t checksum[DIGEST256_LEN];
  461. char address[HS_SERVICE_ADDR_LEN];
  462. tor_assert(key);
  463. tor_assert(addr_out);
  464. /* Get the checksum of the address. */
  465. build_hs_checksum(key, version, checksum);
  466. /* Get the binary address representation. */
  467. build_hs_address(key, checksum, version, address);
  468. /* Encode the address. addr_out will be NUL terminated after this. */
  469. base32_encode(addr_out, HS_SERVICE_ADDR_LEN_BASE32 + 1, address,
  470. sizeof(address));
  471. /* Validate what we just built. */
  472. tor_assert(hs_address_is_valid(addr_out));
  473. }
  474. /* Initialize the entire HS subsytem. This is called in tor_init() before any
  475. * torrc options are loaded. Only for >= v3. */
  476. void
  477. hs_init(void)
  478. {
  479. hs_circuitmap_init();
  480. hs_service_init();
  481. hs_cache_init();
  482. }
  483. /* Release and cleanup all memory of the HS subsystem (all version). This is
  484. * called by tor_free_all(). */
  485. void
  486. hs_free_all(void)
  487. {
  488. hs_circuitmap_free_all();
  489. hs_service_free_all();
  490. hs_cache_free_all();
  491. }