hs_cache.c 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144
  1. /* Copyright (c) 2016-2019, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. /**
  4. * \file hs_cache.c
  5. * \brief Handle hidden service descriptor caches.
  6. **/
  7. /* For unit tests.*/
  8. #define HS_CACHE_PRIVATE
  9. #include "core/or/or.h"
  10. #include "app/config/config.h"
  11. #include "lib/crypt_ops/crypto_format.h"
  12. #include "lib/crypt_ops/crypto_util.h"
  13. #include "feature/hs/hs_ident.h"
  14. #include "feature/hs/hs_common.h"
  15. #include "feature/hs/hs_client.h"
  16. #include "feature/hs/hs_descriptor.h"
  17. #include "feature/nodelist/networkstatus.h"
  18. #include "feature/rend/rendcache.h"
  19. #include "feature/hs/hs_cache.h"
  20. #include "feature/dircache/dircache.h"
  21. #include "feature/nodelist/networkstatus_st.h"
  22. #include "feature/hs/hs_pirprocess.h"
  23. static int cached_client_descriptor_has_expired(time_t now,
  24. const hs_cache_client_descriptor_t *cached_desc);
  25. /********************** Directory HS cache ******************/
  26. /* Directory descriptor cache. Map indexed by blinded key. */
  27. static digest256map_t *hs_cache_v3_dir;
  28. /* Remove a given descriptor from our cache. */
  29. static void
  30. remove_v3_desc_as_dir(const hs_cache_dir_descriptor_t *desc)
  31. {
  32. tor_assert(desc);
  33. digest256map_remove(hs_cache_v3_dir, desc->key);
  34. }
  35. /* Store a given descriptor in our cache. */
  36. static void
  37. store_v3_desc_as_dir(hs_cache_dir_descriptor_t *desc)
  38. {
  39. tor_assert(desc);
  40. digest256map_set(hs_cache_v3_dir, desc->key, desc);
  41. }
  42. /* Query our cache and return the entry or NULL if not found. */
  43. static hs_cache_dir_descriptor_t *
  44. lookup_v3_desc_as_dir(const uint8_t *key)
  45. {
  46. tor_assert(key);
  47. return digest256map_get(hs_cache_v3_dir, key);
  48. }
  49. #define cache_dir_desc_free(val) \
  50. FREE_AND_NULL(hs_cache_dir_descriptor_t, cache_dir_desc_free_, (val))
  51. /* Free a directory descriptor object. */
  52. static void
  53. cache_dir_desc_free_(hs_cache_dir_descriptor_t *desc)
  54. {
  55. if (desc == NULL) {
  56. return;
  57. }
  58. hs_desc_plaintext_data_free(desc->plaintext_data);
  59. tor_free(desc->encoded_desc);
  60. tor_free(desc);
  61. }
  62. /* Helper function: Use by the free all function using the digest256map
  63. * interface to cache entries. */
  64. static void
  65. cache_dir_desc_free_void(void *ptr)
  66. {
  67. cache_dir_desc_free_(ptr);
  68. }
  69. /* Create a new directory cache descriptor object from a encoded descriptor.
  70. * On success, return the heap-allocated cache object, otherwise return NULL if
  71. * we can't decode the descriptor. */
  72. static hs_cache_dir_descriptor_t *
  73. cache_dir_desc_new(const char *desc)
  74. {
  75. hs_cache_dir_descriptor_t *dir_desc;
  76. tor_assert(desc);
  77. dir_desc = tor_malloc_zero(sizeof(hs_cache_dir_descriptor_t));
  78. dir_desc->plaintext_data =
  79. tor_malloc_zero(sizeof(hs_desc_plaintext_data_t));
  80. dir_desc->encoded_desc = tor_strdup(desc);
  81. if (hs_desc_decode_plaintext(desc, dir_desc->plaintext_data) < 0) {
  82. log_debug(LD_DIR, "Unable to decode descriptor. Rejecting.");
  83. goto err;
  84. }
  85. /* The blinded pubkey is the indexed key. */
  86. dir_desc->key = dir_desc->plaintext_data->blinded_pubkey.pubkey;
  87. dir_desc->created_ts = time(NULL);
  88. return dir_desc;
  89. err:
  90. cache_dir_desc_free(dir_desc);
  91. return NULL;
  92. }
  93. /* Return the size of a cache entry in bytes. */
  94. static size_t
  95. cache_get_dir_entry_size(const hs_cache_dir_descriptor_t *entry)
  96. {
  97. return (sizeof(*entry) + hs_desc_plaintext_obj_size(entry->plaintext_data)
  98. + strlen(entry->encoded_desc));
  99. }
  100. // PIRONION: v3 store
  101. static int
  102. hs_cache_pirserver_insert_desc(hs_cache_dir_descriptor_t *desc);
  103. /* Try to store a valid version 3 descriptor in the directory cache. Return 0
  104. * on success else a negative value is returned indicating that we have a
  105. * newer version in our cache. On error, caller is responsible to free the
  106. * given descriptor desc. */
  107. static int
  108. cache_store_v3_as_dir(hs_cache_dir_descriptor_t *desc)
  109. {
  110. hs_cache_dir_descriptor_t *cache_entry;
  111. tor_assert(desc);
  112. /* Verify if we have an entry in the cache for that key and if yes, check
  113. * if we should replace it? */
  114. cache_entry = lookup_v3_desc_as_dir(desc->key);
  115. if (cache_entry != NULL) {
  116. /* Only replace descriptor if revision-counter is greater than the one
  117. * in our cache */
  118. if (cache_entry->plaintext_data->revision_counter >=
  119. desc->plaintext_data->revision_counter) {
  120. log_info(LD_REND, "Descriptor revision counter in our cache is "
  121. "greater or equal than the one we received (%d/%d). "
  122. "Rejecting!",
  123. (int)cache_entry->plaintext_data->revision_counter,
  124. (int)desc->plaintext_data->revision_counter);
  125. goto err;
  126. }
  127. /* We now know that the descriptor we just received is a new one so
  128. * remove the entry we currently have from our cache so we can then
  129. * store the new one. */
  130. remove_v3_desc_as_dir(cache_entry);
  131. rend_cache_decrement_allocation(cache_get_dir_entry_size(cache_entry));
  132. cache_dir_desc_free(cache_entry);
  133. }
  134. /* Store the descriptor we just got. We are sure here that either we
  135. * don't have the entry or we have a newer descriptor and the old one
  136. * has been removed from the cache. */
  137. store_v3_desc_as_dir(desc);
  138. /* Also send it to the PIR server if we have one. */
  139. hs_cache_pirserver_insert_desc(desc);
  140. /* Update our total cache size with this entry for the OOM. This uses the
  141. * old HS protocol cache subsystem for which we are tied with. */
  142. rend_cache_increment_allocation(cache_get_dir_entry_size(desc));
  143. /* XXX: Update HS statistics. We should have specific stats for v3. */
  144. return 0;
  145. err:
  146. return -1;
  147. }
  148. // PIRONION: v3 lookup
  149. /* Using the query which is the base64 encoded blinded key of a version 3
  150. * descriptor, lookup in our directory cache the entry. If found, 1 is
  151. * returned and desc_out is populated with a newly allocated string being the
  152. * encoded descriptor. If not found, 0 is returned and desc_out is untouched.
  153. * On error, a negative value is returned and desc_out is untouched. */
  154. static int
  155. cache_lookup_v3_as_dir(const char *query, const char **desc_out)
  156. {
  157. int found = 0;
  158. ed25519_public_key_t blinded_key;
  159. const hs_cache_dir_descriptor_t *entry;
  160. tor_assert(query);
  161. /* Decode blinded key using the given query value. */
  162. if (ed25519_public_from_base64(&blinded_key, query) < 0) {
  163. log_info(LD_REND, "Unable to decode the v3 HSDir query %s.",
  164. safe_str_client(query));
  165. goto err;
  166. }
  167. entry = lookup_v3_desc_as_dir(blinded_key.pubkey);
  168. if (entry != NULL) {
  169. found = 1;
  170. if (desc_out) {
  171. *desc_out = entry->encoded_desc;
  172. }
  173. }
  174. return found;
  175. err:
  176. return -1;
  177. }
  178. /* Clean the v3 cache by removing any entry that has expired using the
  179. * <b>global_cutoff</b> value. If <b>global_cutoff</b> is 0, the cleaning
  180. * process will use the lifetime found in the plaintext data section. Return
  181. * the number of bytes cleaned. */
  182. STATIC size_t
  183. cache_clean_v3_as_dir(time_t now, time_t global_cutoff)
  184. {
  185. size_t bytes_removed = 0;
  186. /* Code flow error if this ever happens. */
  187. tor_assert(global_cutoff >= 0);
  188. if (!hs_cache_v3_dir) { /* No cache to clean. Just return. */
  189. return 0;
  190. }
  191. DIGEST256MAP_FOREACH_MODIFY(hs_cache_v3_dir, key,
  192. hs_cache_dir_descriptor_t *, entry) {
  193. size_t entry_size;
  194. time_t cutoff = global_cutoff;
  195. if (!cutoff) {
  196. /* Cutoff is the lifetime of the entry found in the descriptor. */
  197. cutoff = now - entry->plaintext_data->lifetime_sec;
  198. }
  199. /* If the entry has been created _after_ the cutoff, not expired so
  200. * continue to the next entry in our v3 cache. */
  201. if (entry->created_ts > cutoff) {
  202. continue;
  203. }
  204. /* Here, our entry has expired, remove and free. */
  205. MAP_DEL_CURRENT(key);
  206. entry_size = cache_get_dir_entry_size(entry);
  207. bytes_removed += entry_size;
  208. /* Entry is not in the cache anymore, destroy it. */
  209. cache_dir_desc_free(entry);
  210. /* Update our cache entry allocation size for the OOM. */
  211. rend_cache_decrement_allocation(entry_size);
  212. /* Logging. */
  213. {
  214. char key_b64[BASE64_DIGEST256_LEN + 1];
  215. digest256_to_base64(key_b64, (const char *) key);
  216. log_info(LD_REND, "Removing v3 descriptor '%s' from HSDir cache",
  217. safe_str_client(key_b64));
  218. }
  219. } DIGEST256MAP_FOREACH_END;
  220. return bytes_removed;
  221. }
  222. /* Given an encoded descriptor, store it in the directory cache depending on
  223. * which version it is. Return a negative value on error. On success, 0 is
  224. * returned. */
  225. int
  226. hs_cache_store_as_dir(const char *desc)
  227. {
  228. hs_cache_dir_descriptor_t *dir_desc = NULL;
  229. tor_assert(desc);
  230. /* Create a new cache object. This can fail if the descriptor plaintext data
  231. * is unparseable which in this case a log message will be triggered. */
  232. dir_desc = cache_dir_desc_new(desc);
  233. if (dir_desc == NULL) {
  234. goto err;
  235. }
  236. /* Call the right function against the descriptor version. At this point,
  237. * we are sure that the descriptor's version is supported else the
  238. * decoding would have failed. */
  239. switch (dir_desc->plaintext_data->version) {
  240. case HS_VERSION_THREE:
  241. default:
  242. if (cache_store_v3_as_dir(dir_desc) < 0) {
  243. goto err;
  244. }
  245. break;
  246. }
  247. return 0;
  248. err:
  249. cache_dir_desc_free(dir_desc);
  250. return -1;
  251. }
  252. /* Using the query, lookup in our directory cache the entry. If found, 1 is
  253. * returned and desc_out is populated with a newly allocated string being
  254. * the encoded descriptor. If not found, 0 is returned and desc_out is
  255. * untouched. On error, a negative value is returned and desc_out is
  256. * untouched. */
  257. int
  258. hs_cache_lookup_as_dir(uint32_t version, const char *query,
  259. const char **desc_out)
  260. {
  261. int found;
  262. tor_assert(query);
  263. /* This should never be called with an unsupported version. */
  264. tor_assert(hs_desc_is_supported_version(version));
  265. switch (version) {
  266. case HS_VERSION_THREE:
  267. default:
  268. found = cache_lookup_v3_as_dir(query, desc_out);
  269. break;
  270. }
  271. return found;
  272. }
  273. /* Clean all directory caches using the current time now. */
  274. void
  275. hs_cache_clean_as_dir(time_t now)
  276. {
  277. time_t cutoff;
  278. /* Start with v2 cache cleaning. */
  279. cutoff = now - rend_cache_max_entry_lifetime();
  280. rend_cache_clean_v2_descs_as_dir(cutoff);
  281. /* Now, clean the v3 cache. Set the cutoff to 0 telling the cleanup function
  282. * to compute the cutoff by itself using the lifetime value. */
  283. cache_clean_v3_as_dir(now, 0);
  284. }
  285. /********************** Client-side HS cache ******************/
  286. /* Client-side HS descriptor cache. Map indexed by service identity key. */
  287. static digest256map_t *hs_cache_v3_client;
  288. /* Client-side introduction point state cache. Map indexed by service public
  289. * identity key (onion address). It contains hs_cache_client_intro_state_t
  290. * objects all related to a specific service. */
  291. static digest256map_t *hs_cache_client_intro_state;
  292. /* Return the size of a client cache entry in bytes. */
  293. static size_t
  294. cache_get_client_entry_size(const hs_cache_client_descriptor_t *entry)
  295. {
  296. return sizeof(*entry) +
  297. strlen(entry->encoded_desc) + hs_desc_obj_size(entry->desc);
  298. }
  299. /* Remove a given descriptor from our cache. */
  300. static void
  301. remove_v3_desc_as_client(const hs_cache_client_descriptor_t *desc)
  302. {
  303. tor_assert(desc);
  304. digest256map_remove(hs_cache_v3_client, desc->key.pubkey);
  305. /* Update cache size with this entry for the OOM handler. */
  306. rend_cache_decrement_allocation(cache_get_client_entry_size(desc));
  307. }
  308. /* Store a given descriptor in our cache. */
  309. static void
  310. store_v3_desc_as_client(hs_cache_client_descriptor_t *desc)
  311. {
  312. tor_assert(desc);
  313. digest256map_set(hs_cache_v3_client, desc->key.pubkey, desc);
  314. /* Update cache size with this entry for the OOM handler. */
  315. rend_cache_increment_allocation(cache_get_client_entry_size(desc));
  316. }
  317. /* Query our cache and return the entry or NULL if not found or if expired. */
  318. STATIC hs_cache_client_descriptor_t *
  319. lookup_v3_desc_as_client(const uint8_t *key)
  320. {
  321. time_t now = approx_time();
  322. hs_cache_client_descriptor_t *cached_desc;
  323. tor_assert(key);
  324. /* Do the lookup */
  325. cached_desc = digest256map_get(hs_cache_v3_client, key);
  326. if (!cached_desc) {
  327. return NULL;
  328. }
  329. /* Don't return expired entries */
  330. if (cached_client_descriptor_has_expired(now, cached_desc)) {
  331. return NULL;
  332. }
  333. return cached_desc;
  334. }
  335. /* Parse the encoded descriptor in <b>desc_str</b> using
  336. * <b>service_identity_pk<b> to decrypt it first.
  337. *
  338. * If everything goes well, allocate and return a new
  339. * hs_cache_client_descriptor_t object. In case of error, return NULL. */
  340. static hs_cache_client_descriptor_t *
  341. cache_client_desc_new(const char *desc_str,
  342. const ed25519_public_key_t *service_identity_pk)
  343. {
  344. hs_descriptor_t *desc = NULL;
  345. hs_cache_client_descriptor_t *client_desc = NULL;
  346. tor_assert(desc_str);
  347. tor_assert(service_identity_pk);
  348. /* Decode the descriptor we just fetched. */
  349. if (hs_client_decode_descriptor(desc_str, service_identity_pk, &desc) < 0) {
  350. goto end;
  351. }
  352. tor_assert(desc);
  353. /* All is good: make a cache object for this descriptor */
  354. client_desc = tor_malloc_zero(sizeof(hs_cache_client_descriptor_t));
  355. ed25519_pubkey_copy(&client_desc->key, service_identity_pk);
  356. /* Set expiration time for this cached descriptor to be the start of the next
  357. * time period since that's when clients need to start using the next blinded
  358. * pk of the service (and hence will need its next descriptor). */
  359. client_desc->expiration_ts = hs_get_start_time_of_next_time_period(0);
  360. client_desc->desc = desc;
  361. client_desc->encoded_desc = tor_strdup(desc_str);
  362. end:
  363. return client_desc;
  364. }
  365. #define cache_client_desc_free(val) \
  366. FREE_AND_NULL(hs_cache_client_descriptor_t, cache_client_desc_free_, (val))
  367. /** Free memory allocated by <b>desc</b>. */
  368. static void
  369. cache_client_desc_free_(hs_cache_client_descriptor_t *desc)
  370. {
  371. if (desc == NULL) {
  372. return;
  373. }
  374. hs_descriptor_free(desc->desc);
  375. memwipe(&desc->key, 0, sizeof(desc->key));
  376. memwipe(desc->encoded_desc, 0, strlen(desc->encoded_desc));
  377. tor_free(desc->encoded_desc);
  378. tor_free(desc);
  379. }
  380. /** Helper function: Use by the free all function to clear the client cache */
  381. static void
  382. cache_client_desc_free_void(void *ptr)
  383. {
  384. hs_cache_client_descriptor_t *desc = ptr;
  385. cache_client_desc_free(desc);
  386. }
  387. /* Return a newly allocated and initialized hs_cache_intro_state_t object. */
  388. static hs_cache_intro_state_t *
  389. cache_intro_state_new(void)
  390. {
  391. hs_cache_intro_state_t *state = tor_malloc_zero(sizeof(*state));
  392. state->created_ts = approx_time();
  393. return state;
  394. }
  395. #define cache_intro_state_free(val) \
  396. FREE_AND_NULL(hs_cache_intro_state_t, cache_intro_state_free_, (val))
  397. /* Free an hs_cache_intro_state_t object. */
  398. static void
  399. cache_intro_state_free_(hs_cache_intro_state_t *state)
  400. {
  401. tor_free(state);
  402. }
  403. /* Helper function: used by the free all function. */
  404. static void
  405. cache_intro_state_free_void(void *state)
  406. {
  407. cache_intro_state_free_(state);
  408. }
  409. /* Return a newly allocated and initialized hs_cache_client_intro_state_t
  410. * object. */
  411. static hs_cache_client_intro_state_t *
  412. cache_client_intro_state_new(void)
  413. {
  414. hs_cache_client_intro_state_t *cache = tor_malloc_zero(sizeof(*cache));
  415. cache->intro_points = digest256map_new();
  416. return cache;
  417. }
  418. #define cache_client_intro_state_free(val) \
  419. FREE_AND_NULL(hs_cache_client_intro_state_t, \
  420. cache_client_intro_state_free_, (val))
  421. /* Free a cache_client_intro_state object. */
  422. static void
  423. cache_client_intro_state_free_(hs_cache_client_intro_state_t *cache)
  424. {
  425. if (cache == NULL) {
  426. return;
  427. }
  428. digest256map_free(cache->intro_points, cache_intro_state_free_void);
  429. tor_free(cache);
  430. }
  431. /* Helper function: used by the free all function. */
  432. static void
  433. cache_client_intro_state_free_void(void *entry)
  434. {
  435. cache_client_intro_state_free_(entry);
  436. }
  437. /* For the given service identity key service_pk and an introduction
  438. * authentication key auth_key, lookup the intro state object. Return 1 if
  439. * found and put it in entry if not NULL. Return 0 if not found and entry is
  440. * untouched. */
  441. static int
  442. cache_client_intro_state_lookup(const ed25519_public_key_t *service_pk,
  443. const ed25519_public_key_t *auth_key,
  444. hs_cache_intro_state_t **entry)
  445. {
  446. hs_cache_intro_state_t *state;
  447. hs_cache_client_intro_state_t *cache;
  448. tor_assert(service_pk);
  449. tor_assert(auth_key);
  450. /* Lookup the intro state cache for this service key. */
  451. cache = digest256map_get(hs_cache_client_intro_state, service_pk->pubkey);
  452. if (cache == NULL) {
  453. goto not_found;
  454. }
  455. /* From the cache we just found for the service, lookup in the introduction
  456. * points map for the given authentication key. */
  457. state = digest256map_get(cache->intro_points, auth_key->pubkey);
  458. if (state == NULL) {
  459. goto not_found;
  460. }
  461. if (entry) {
  462. *entry = state;
  463. }
  464. return 1;
  465. not_found:
  466. return 0;
  467. }
  468. /* Note the given failure in state. */
  469. static void
  470. cache_client_intro_state_note(hs_cache_intro_state_t *state,
  471. rend_intro_point_failure_t failure)
  472. {
  473. tor_assert(state);
  474. switch (failure) {
  475. case INTRO_POINT_FAILURE_GENERIC:
  476. state->error = 1;
  477. break;
  478. case INTRO_POINT_FAILURE_TIMEOUT:
  479. state->timed_out = 1;
  480. break;
  481. case INTRO_POINT_FAILURE_UNREACHABLE:
  482. state->unreachable_count++;
  483. break;
  484. default:
  485. tor_assert_nonfatal_unreached();
  486. return;
  487. }
  488. }
  489. /* For the given service identity key service_pk and an introduction
  490. * authentication key auth_key, add an entry in the client intro state cache
  491. * If no entry exists for the service, it will create one. If state is non
  492. * NULL, it will point to the new intro state entry. */
  493. static void
  494. cache_client_intro_state_add(const ed25519_public_key_t *service_pk,
  495. const ed25519_public_key_t *auth_key,
  496. hs_cache_intro_state_t **state)
  497. {
  498. hs_cache_intro_state_t *entry, *old_entry;
  499. hs_cache_client_intro_state_t *cache;
  500. tor_assert(service_pk);
  501. tor_assert(auth_key);
  502. /* Lookup the state cache for this service key. */
  503. cache = digest256map_get(hs_cache_client_intro_state, service_pk->pubkey);
  504. if (cache == NULL) {
  505. cache = cache_client_intro_state_new();
  506. digest256map_set(hs_cache_client_intro_state, service_pk->pubkey, cache);
  507. }
  508. entry = cache_intro_state_new();
  509. old_entry = digest256map_set(cache->intro_points, auth_key->pubkey, entry);
  510. /* This should never happened because the code flow is to lookup the entry
  511. * before adding it. But, just in case, non fatal assert and free it. */
  512. tor_assert_nonfatal(old_entry == NULL);
  513. tor_free(old_entry);
  514. if (state) {
  515. *state = entry;
  516. }
  517. }
  518. /* Remove every intro point state entry from cache that has been created
  519. * before or at the cutoff. */
  520. static void
  521. cache_client_intro_state_clean(time_t cutoff,
  522. hs_cache_client_intro_state_t *cache)
  523. {
  524. tor_assert(cache);
  525. DIGEST256MAP_FOREACH_MODIFY(cache->intro_points, key,
  526. hs_cache_intro_state_t *, entry) {
  527. if (entry->created_ts <= cutoff) {
  528. cache_intro_state_free(entry);
  529. MAP_DEL_CURRENT(key);
  530. }
  531. } DIGEST256MAP_FOREACH_END;
  532. }
  533. /* Return true iff no intro points are in this cache. */
  534. static int
  535. cache_client_intro_state_is_empty(const hs_cache_client_intro_state_t *cache)
  536. {
  537. return digest256map_isempty(cache->intro_points);
  538. }
  539. /** Check whether <b>client_desc</b> is useful for us, and store it in the
  540. * client-side HS cache if so. The client_desc is freed if we already have a
  541. * fresher (higher revision counter count) in the cache. */
  542. static int
  543. cache_store_as_client(hs_cache_client_descriptor_t *client_desc)
  544. {
  545. hs_cache_client_descriptor_t *cache_entry;
  546. /* TODO: Heavy code duplication with cache_store_as_dir(). Consider
  547. * refactoring and uniting! */
  548. tor_assert(client_desc);
  549. /* Check if we already have a descriptor from this HS in cache. If we do,
  550. * check if this descriptor is newer than the cached one */
  551. cache_entry = lookup_v3_desc_as_client(client_desc->key.pubkey);
  552. if (cache_entry != NULL) {
  553. /* If we have an entry in our cache that has a revision counter greater
  554. * than the one we just fetched, discard the one we fetched. */
  555. if (cache_entry->desc->plaintext_data.revision_counter >
  556. client_desc->desc->plaintext_data.revision_counter) {
  557. cache_client_desc_free(client_desc);
  558. goto done;
  559. }
  560. /* Remove old entry. Make space for the new one! */
  561. remove_v3_desc_as_client(cache_entry);
  562. /* We just removed an old descriptor and will replace it. We'll close all
  563. * intro circuits related to this old one so we don't have leftovers. We
  564. * leave the rendezvous circuits opened because they could be in use. */
  565. hs_client_close_intro_circuits_from_desc(cache_entry->desc);
  566. /* Free it. */
  567. cache_client_desc_free(cache_entry);
  568. }
  569. /* Store descriptor in cache */
  570. store_v3_desc_as_client(client_desc);
  571. done:
  572. return 0;
  573. }
  574. /* Return true iff the cached client descriptor at <b>cached_desc</b has
  575. * expired. */
  576. static int
  577. cached_client_descriptor_has_expired(time_t now,
  578. const hs_cache_client_descriptor_t *cached_desc)
  579. {
  580. /* We use the current consensus time to see if we should expire this
  581. * descriptor since we use consensus time for all other parts of the protocol
  582. * as well (e.g. to build the blinded key and compute time periods). */
  583. const networkstatus_t *ns = networkstatus_get_live_consensus(now);
  584. /* If we don't have a recent consensus, consider this entry expired since we
  585. * will want to fetch a new HS desc when we get a live consensus. */
  586. if (!ns) {
  587. return 1;
  588. }
  589. if (cached_desc->expiration_ts <= ns->valid_after) {
  590. return 1;
  591. }
  592. return 0;
  593. }
  594. /* clean the client cache using now as the current time. Return the total size
  595. * of removed bytes from the cache. */
  596. static size_t
  597. cache_clean_v3_as_client(time_t now)
  598. {
  599. size_t bytes_removed = 0;
  600. if (!hs_cache_v3_client) { /* No cache to clean. Just return. */
  601. return 0;
  602. }
  603. DIGEST256MAP_FOREACH_MODIFY(hs_cache_v3_client, key,
  604. hs_cache_client_descriptor_t *, entry) {
  605. size_t entry_size;
  606. /* If the entry has not expired, continue to the next cached entry */
  607. if (!cached_client_descriptor_has_expired(now, entry)) {
  608. continue;
  609. }
  610. /* Here, our entry has expired, remove and free. */
  611. MAP_DEL_CURRENT(key);
  612. entry_size = cache_get_client_entry_size(entry);
  613. bytes_removed += entry_size;
  614. /* Entry is not in the cache anymore, destroy it. */
  615. cache_client_desc_free(entry);
  616. /* Update our OOM. We didn't use the remove() function because we are in
  617. * a loop so we have to explicitly decrement. */
  618. rend_cache_decrement_allocation(entry_size);
  619. /* Logging. */
  620. {
  621. char key_b64[BASE64_DIGEST256_LEN + 1];
  622. digest256_to_base64(key_b64, (const char *) key);
  623. log_info(LD_REND, "Removing hidden service v3 descriptor '%s' "
  624. "from client cache",
  625. safe_str_client(key_b64));
  626. }
  627. } DIGEST256MAP_FOREACH_END;
  628. return bytes_removed;
  629. }
  630. /** Public API: Given the HS ed25519 identity public key in <b>key</b>, return
  631. * its HS encoded descriptor if it's stored in our cache, or NULL if not. */
  632. const char *
  633. hs_cache_lookup_encoded_as_client(const ed25519_public_key_t *key)
  634. {
  635. hs_cache_client_descriptor_t *cached_desc = NULL;
  636. tor_assert(key);
  637. cached_desc = lookup_v3_desc_as_client(key->pubkey);
  638. if (cached_desc) {
  639. tor_assert(cached_desc->encoded_desc);
  640. return cached_desc->encoded_desc;
  641. }
  642. return NULL;
  643. }
  644. /** Public API: Given the HS ed25519 identity public key in <b>key</b>, return
  645. * its HS descriptor if it's stored in our cache, or NULL if not. */
  646. const hs_descriptor_t *
  647. hs_cache_lookup_as_client(const ed25519_public_key_t *key)
  648. {
  649. hs_cache_client_descriptor_t *cached_desc = NULL;
  650. tor_assert(key);
  651. cached_desc = lookup_v3_desc_as_client(key->pubkey);
  652. if (cached_desc) {
  653. tor_assert(cached_desc->desc);
  654. return cached_desc->desc;
  655. }
  656. return NULL;
  657. }
  658. /** Public API: Given an encoded descriptor, store it in the client HS
  659. * cache. Return -1 on error, 0 on success .*/
  660. int
  661. hs_cache_store_as_client(const char *desc_str,
  662. const ed25519_public_key_t *identity_pk)
  663. {
  664. hs_cache_client_descriptor_t *client_desc = NULL;
  665. tor_assert(desc_str);
  666. tor_assert(identity_pk);
  667. /* Create client cache descriptor object */
  668. client_desc = cache_client_desc_new(desc_str, identity_pk);
  669. if (!client_desc) {
  670. log_warn(LD_GENERAL, "HSDesc parsing failed!");
  671. log_debug(LD_GENERAL, "Failed to parse HSDesc: %s.", escaped(desc_str));
  672. goto err;
  673. }
  674. /* Push it to the cache */
  675. if (cache_store_as_client(client_desc) < 0) {
  676. goto err;
  677. }
  678. return 0;
  679. err:
  680. cache_client_desc_free(client_desc);
  681. return -1;
  682. }
  683. /* Clean all client caches using the current time now. */
  684. void
  685. hs_cache_clean_as_client(time_t now)
  686. {
  687. /* Start with v2 cache cleaning. */
  688. rend_cache_clean(now, REND_CACHE_TYPE_CLIENT);
  689. /* Now, clean the v3 cache. Set the cutoff to 0 telling the cleanup function
  690. * to compute the cutoff by itself using the lifetime value. */
  691. cache_clean_v3_as_client(now);
  692. }
  693. /* Purge the client descriptor cache. */
  694. void
  695. hs_cache_purge_as_client(void)
  696. {
  697. DIGEST256MAP_FOREACH_MODIFY(hs_cache_v3_client, key,
  698. hs_cache_client_descriptor_t *, entry) {
  699. size_t entry_size = cache_get_client_entry_size(entry);
  700. MAP_DEL_CURRENT(key);
  701. cache_client_desc_free(entry);
  702. /* Update our OOM. We didn't use the remove() function because we are in
  703. * a loop so we have to explicitly decrement. */
  704. rend_cache_decrement_allocation(entry_size);
  705. } DIGEST256MAP_FOREACH_END;
  706. log_info(LD_REND, "Hidden service client descriptor cache purged.");
  707. }
  708. /* For a given service identity public key and an introduction authentication
  709. * key, note the given failure in the client intro state cache. */
  710. void
  711. hs_cache_client_intro_state_note(const ed25519_public_key_t *service_pk,
  712. const ed25519_public_key_t *auth_key,
  713. rend_intro_point_failure_t failure)
  714. {
  715. int found;
  716. hs_cache_intro_state_t *entry;
  717. tor_assert(service_pk);
  718. tor_assert(auth_key);
  719. found = cache_client_intro_state_lookup(service_pk, auth_key, &entry);
  720. if (!found) {
  721. /* Create a new entry and add it to the cache. */
  722. cache_client_intro_state_add(service_pk, auth_key, &entry);
  723. }
  724. /* Note down the entry. */
  725. cache_client_intro_state_note(entry, failure);
  726. }
  727. /* For a given service identity public key and an introduction authentication
  728. * key, return true iff it is present in the failure cache. */
  729. const hs_cache_intro_state_t *
  730. hs_cache_client_intro_state_find(const ed25519_public_key_t *service_pk,
  731. const ed25519_public_key_t *auth_key)
  732. {
  733. hs_cache_intro_state_t *state = NULL;
  734. cache_client_intro_state_lookup(service_pk, auth_key, &state);
  735. return state;
  736. }
  737. /* Cleanup the client introduction state cache. */
  738. void
  739. hs_cache_client_intro_state_clean(time_t now)
  740. {
  741. time_t cutoff = now - HS_CACHE_CLIENT_INTRO_STATE_MAX_AGE;
  742. DIGEST256MAP_FOREACH_MODIFY(hs_cache_client_intro_state, key,
  743. hs_cache_client_intro_state_t *, cache) {
  744. /* Cleanup intro points failure. */
  745. cache_client_intro_state_clean(cutoff, cache);
  746. /* Is this cache empty for this service key? If yes, remove it from the
  747. * cache. Else keep it. */
  748. if (cache_client_intro_state_is_empty(cache)) {
  749. cache_client_intro_state_free(cache);
  750. MAP_DEL_CURRENT(key);
  751. }
  752. } DIGEST256MAP_FOREACH_END;
  753. }
  754. /* Purge the client introduction state cache. */
  755. void
  756. hs_cache_client_intro_state_purge(void)
  757. {
  758. DIGEST256MAP_FOREACH_MODIFY(hs_cache_client_intro_state, key,
  759. hs_cache_client_intro_state_t *, cache) {
  760. MAP_DEL_CURRENT(key);
  761. cache_client_intro_state_free(cache);
  762. } DIGEST256MAP_FOREACH_END;
  763. log_info(LD_REND, "Hidden service client introduction point state "
  764. "cache purged.");
  765. }
  766. /**************** Generics *********************************/
  767. /* Do a round of OOM cleanup on all directory caches. Return the amount of
  768. * removed bytes. It is possible that the returned value is lower than
  769. * min_remove_bytes if the caches get emptied out so the caller should be
  770. * aware of this. */
  771. size_t
  772. hs_cache_handle_oom(time_t now, size_t min_remove_bytes)
  773. {
  774. time_t k;
  775. size_t bytes_removed = 0;
  776. /* Our OOM handler called with 0 bytes to remove is a code flow error. */
  777. tor_assert(min_remove_bytes != 0);
  778. /* The algorithm is as follow. K is the oldest expected descriptor age.
  779. *
  780. * 1) Deallocate all entries from v2 cache that are older than K hours.
  781. * 1.1) If the amount of remove bytes has been reached, stop.
  782. * 2) Deallocate all entries from v3 cache that are older than K hours
  783. * 2.1) If the amount of remove bytes has been reached, stop.
  784. * 3) Set K = K - RendPostPeriod and repeat process until K is < 0.
  785. *
  786. * This ends up being O(Kn).
  787. */
  788. /* Set K to the oldest expected age in seconds which is the maximum
  789. * lifetime of a cache entry. We'll use the v2 lifetime because it's much
  790. * bigger than the v3 thus leading to cleaning older descriptors. */
  791. k = rend_cache_max_entry_lifetime();
  792. do {
  793. time_t cutoff;
  794. /* If K becomes negative, it means we've empty the caches so stop and
  795. * return what we were able to cleanup. */
  796. if (k < 0) {
  797. break;
  798. }
  799. /* Compute a cutoff value with K and the current time. */
  800. cutoff = now - k;
  801. /* Start by cleaning the v2 cache with that cutoff. */
  802. bytes_removed += rend_cache_clean_v2_descs_as_dir(cutoff);
  803. if (bytes_removed < min_remove_bytes) {
  804. /* We haven't remove enough bytes so clean v3 cache. */
  805. bytes_removed += cache_clean_v3_as_dir(now, cutoff);
  806. /* Decrement K by a post period to shorten the cutoff. */
  807. k -= get_options()->RendPostPeriod;
  808. }
  809. } while (bytes_removed < min_remove_bytes);
  810. return bytes_removed;
  811. }
  812. /* Return the maximum size of a v3 HS descriptor. */
  813. unsigned int
  814. hs_cache_get_max_descriptor_size(void)
  815. {
  816. return (unsigned) networkstatus_get_param(NULL,
  817. "HSV3MaxDescriptorSize",
  818. HS_DESC_MAX_LEN, 1, INT32_MAX);
  819. }
  820. #define PIRSERVER_REQUEST_PARAMS 0x01
  821. #define PIRSERVER_REQUEST_STORE 0x02
  822. #define PIRSERVER_REQUEST_LOOKUP 0x03
  823. #define PIRSERVER_RESPONSE_PARAMS 0xFF
  824. #define PIRSERVER_RESPONSE_LOOKUP_SUCCESS 0xFE
  825. #define PIRSERVER_RESPONSE_LOOKUP_FAILURE 0xFD
  826. static void
  827. hs_cache_pirserver_received(const unsigned char *hdrbuf,
  828. const char *bodybuf, size_t bodylen)
  829. {
  830. dir_connection_t *conn;
  831. uint64_t reqid;
  832. log_info(LD_DIRSERV,"PIRSERVER response header %p type %02x body len %ld",
  833. *(void**)hdrbuf, hdrbuf[8], bodylen);
  834. memmove(&reqid, hdrbuf, sizeof(reqid));
  835. conn = hs_pirprocess_lookup_reqid(reqid);
  836. if (!conn) {
  837. /* The dir_connection_t has closed between the time we received
  838. * the request and now (when we are ready to send back the
  839. * response). */
  840. return;
  841. }
  842. if (hdrbuf[8] == PIRSERVER_RESPONSE_PARAMS) {
  843. /* Send the params back to the client */
  844. dircache_pirserver_reply_params(conn, bodybuf, bodylen);
  845. } else if (hdrbuf[8] == PIRSERVER_RESPONSE_LOOKUP_SUCCESS) {
  846. /* Send the PIR response back to the client */
  847. dircache_pirserver_reply_lookup(conn, bodybuf, bodylen);
  848. } else if (hdrbuf[8] == PIRSERVER_RESPONSE_LOOKUP_FAILURE) {
  849. /* Send an error response back to the client */
  850. dircache_pirserver_reply_lookup(conn, NULL, 0);
  851. }
  852. hs_pirprocess_dealloc_reqid(conn);
  853. }
  854. static pir_process_t pirserver;
  855. /* Poke the hidden service cache PIR subsystem to launch the PIR
  856. server if needed. */
  857. static void
  858. hs_cache_pir_poke(void)
  859. {
  860. hs_pirprocess_poke(getenv("PIR_SERVER_PATH"), "PIRSERVER",
  861. hs_cache_pirserver_received, &pirserver);
  862. }
  863. /* Initialize the hidden service cache PIR subsystem. */
  864. static void
  865. hs_cache_pir_init(void)
  866. {
  867. pirserver = NULL;
  868. }
  869. static int
  870. hs_cache_pirserver_send(const unsigned char *buf, size_t len)
  871. {
  872. hs_cache_pir_poke();
  873. return hs_pirprocess_send(pirserver, buf, len);
  874. }
  875. static int
  876. hs_cache_pirserver_insert_desc(hs_cache_dir_descriptor_t *desc)
  877. {
  878. unsigned char hdr[13];
  879. size_t encoded_desc_len;
  880. size_t len;
  881. int res;
  882. int written = 0;
  883. static uint32_t inscounter = 0;
  884. memmove(hdr, "\0\0\0\0", 4);
  885. ++inscounter;
  886. *(uint32_t*)(hdr+4) = htonl(inscounter);
  887. hdr[8] = PIRSERVER_REQUEST_STORE;
  888. encoded_desc_len = strlen(desc->encoded_desc);
  889. len = DIGEST256_LEN + encoded_desc_len;
  890. *(uint32_t*)(hdr+9) = htonl(len);
  891. res = hs_cache_pirserver_send(hdr, PIRPROCESS_HDR_SIZE);
  892. if (res <= 0) return -1;
  893. written += res;
  894. res = hs_cache_pirserver_send(desc->key, DIGEST256_LEN);
  895. if (res <= 0) return -1;
  896. written += res;
  897. res = hs_cache_pirserver_send(
  898. (const unsigned char *)desc->encoded_desc,
  899. encoded_desc_len);
  900. if (res <= 0) return -1;
  901. written += res;
  902. return written;
  903. }
  904. /** Helper function for GET /tor/pironion/params.
  905. */
  906. int
  907. hs_cache_pirserver_get_params(dir_connection_t *conn)
  908. {
  909. /* Ask the pirserver for the params */
  910. int res;
  911. unsigned char hdr[PIRPROCESS_HDR_SIZE];
  912. uint64_t reqid = hs_pirprocess_alloc_reqid(conn);
  913. memmove(hdr, &reqid, sizeof(reqid));
  914. hdr[8] = PIRSERVER_REQUEST_PARAMS;
  915. memmove(hdr+9, "\0\0\0\0", 4);
  916. res = hs_cache_pirserver_send(hdr, PIRPROCESS_HDR_SIZE);
  917. if (res < PIRPROCESS_HDR_SIZE) {
  918. return -1;
  919. }
  920. return 0;
  921. }
  922. /* Helper function for POST /tor/pironion/query */
  923. int
  924. hs_cache_pirserver_query(dir_connection_t *conn, const char *body,
  925. size_t body_len)
  926. {
  927. int res;
  928. unsigned char hdr[PIRPROCESS_HDR_SIZE];
  929. uint64_t reqid = hs_pirprocess_alloc_reqid(conn);
  930. memmove(hdr, &reqid, sizeof(reqid));
  931. hdr[8] = PIRSERVER_REQUEST_LOOKUP;
  932. *(uint32_t*)(hdr+9) = htonl(body_len);
  933. res = hs_cache_pirserver_send(hdr, PIRPROCESS_HDR_SIZE);
  934. if (res < PIRPROCESS_HDR_SIZE) {
  935. return -1;
  936. }
  937. res = hs_cache_pirserver_send((const unsigned char *)body, body_len);
  938. if (res < (int)body_len) {
  939. return -1;
  940. }
  941. return 0;
  942. }
  943. /* Initialize the hidden service cache subsystem. */
  944. void
  945. hs_cache_init(void)
  946. {
  947. /* Calling this twice is very wrong code flow. */
  948. tor_assert(!hs_cache_v3_dir);
  949. hs_cache_v3_dir = digest256map_new();
  950. tor_assert(!hs_cache_v3_client);
  951. hs_cache_v3_client = digest256map_new();
  952. tor_assert(!hs_cache_client_intro_state);
  953. hs_cache_client_intro_state = digest256map_new();
  954. hs_cache_pir_init();
  955. }
  956. /* Cleanup the hidden service cache subsystem. */
  957. void
  958. hs_cache_free_all(void)
  959. {
  960. digest256map_free(hs_cache_v3_dir, cache_dir_desc_free_void);
  961. hs_cache_v3_dir = NULL;
  962. digest256map_free(hs_cache_v3_client, cache_client_desc_free_void);
  963. hs_cache_v3_client = NULL;
  964. digest256map_free(hs_cache_client_intro_state,
  965. cache_client_intro_state_free_void);
  966. hs_cache_client_intro_state = NULL;
  967. }