test_sendme.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /* Copyright (c) 2014-2019, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. /* Unit tests for handling different kinds of relay cell */
  4. #define CIRCUITLIST_PRIVATE
  5. #define NETWORKSTATUS_PRIVATE
  6. #define SENDME_PRIVATE
  7. #define RELAY_PRIVATE
  8. #include "core/or/circuit_st.h"
  9. #include "core/or/or_circuit_st.h"
  10. #include "core/or/origin_circuit_st.h"
  11. #include "core/or/circuitlist.h"
  12. #include "core/or/relay.h"
  13. #include "core/or/sendme.h"
  14. #include "feature/nodelist/networkstatus.h"
  15. #include "feature/nodelist/networkstatus_st.h"
  16. #include "lib/crypt_ops/crypto_digest.h"
  17. #include "test/test.h"
  18. #include "test/log_test_helpers.h"
  19. static void
  20. setup_mock_consensus(void)
  21. {
  22. current_md_consensus = current_ns_consensus =
  23. tor_malloc_zero(sizeof(networkstatus_t));
  24. current_md_consensus->net_params = smartlist_new();
  25. current_md_consensus->routerstatus_list = smartlist_new();
  26. }
  27. static void
  28. free_mock_consensus(void)
  29. {
  30. SMARTLIST_FOREACH(current_md_consensus->routerstatus_list, void *, r,
  31. tor_free(r));
  32. smartlist_free(current_md_consensus->routerstatus_list);
  33. smartlist_free(current_ns_consensus->net_params);
  34. tor_free(current_ns_consensus);
  35. }
  36. static void
  37. test_v1_record_digest(void *arg)
  38. {
  39. or_circuit_t *or_circ = NULL;
  40. origin_circuit_t *orig_circ = NULL;
  41. circuit_t *circ = NULL;
  42. (void) arg;
  43. /* Create our dummy circuits. */
  44. orig_circ = origin_circuit_new();
  45. tt_assert(orig_circ);
  46. or_circ = or_circuit_new(1, NULL);
  47. /* Start by pointing to the origin circuit. */
  48. circ = TO_CIRCUIT(orig_circ);
  49. circ->purpose = CIRCUIT_PURPOSE_S_REND_JOINED;
  50. /* We should never note SENDME digest on origin circuit. */
  51. sendme_record_cell_digest(circ);
  52. tt_assert(!circ->sendme_last_digests);
  53. /* We do not need the origin circuit for now. */
  54. orig_circ = NULL;
  55. circuit_free_(circ);
  56. /* Points it to the OR circuit now. */
  57. circ = TO_CIRCUIT(or_circ);
  58. /* The package window has to be a multiple of CIRCWINDOW_INCREMENT minus 1
  59. * in order to catched the CIRCWINDOW_INCREMENT-nth cell. Try something that
  60. * shouldn't be noted. */
  61. circ->package_window = CIRCWINDOW_INCREMENT;
  62. sendme_record_cell_digest(circ);
  63. tt_assert(!circ->sendme_last_digests);
  64. /* This should work now. Package window at CIRCWINDOW_INCREMENT + 1. */
  65. circ->package_window++;
  66. sendme_record_cell_digest(circ);
  67. tt_assert(circ->sendme_last_digests);
  68. tt_int_op(smartlist_len(circ->sendme_last_digests), OP_EQ, 1);
  69. /* Next cell in the package window shouldn't do anything. */
  70. circ->package_window++;
  71. sendme_record_cell_digest(circ);
  72. tt_int_op(smartlist_len(circ->sendme_last_digests), OP_EQ, 1);
  73. /* The next CIRCWINDOW_INCREMENT should add one more digest. */
  74. circ->package_window = (CIRCWINDOW_INCREMENT * 2) + 1;
  75. sendme_record_cell_digest(circ);
  76. tt_int_op(smartlist_len(circ->sendme_last_digests), OP_EQ, 2);
  77. done:
  78. circuit_free_(circ);
  79. }
  80. static void
  81. test_v1_consensus_params(void *arg)
  82. {
  83. (void) arg;
  84. setup_mock_consensus();
  85. tt_assert(current_md_consensus);
  86. /* Both zeroes. */
  87. smartlist_add(current_md_consensus->net_params,
  88. (void *) "sendme_emit_min_version=0");
  89. smartlist_add(current_md_consensus->net_params,
  90. (void *) "sendme_accept_min_version=0");
  91. tt_int_op(get_emit_min_version(), OP_EQ, 0);
  92. tt_int_op(get_accept_min_version(), OP_EQ, 0);
  93. smartlist_clear(current_md_consensus->net_params);
  94. /* Both ones. */
  95. smartlist_add(current_md_consensus->net_params,
  96. (void *) "sendme_emit_min_version=1");
  97. smartlist_add(current_md_consensus->net_params,
  98. (void *) "sendme_accept_min_version=1");
  99. tt_int_op(get_emit_min_version(), OP_EQ, 1);
  100. tt_int_op(get_accept_min_version(), OP_EQ, 1);
  101. smartlist_clear(current_md_consensus->net_params);
  102. /* Different values from each other. */
  103. smartlist_add(current_md_consensus->net_params,
  104. (void *) "sendme_emit_min_version=1");
  105. smartlist_add(current_md_consensus->net_params,
  106. (void *) "sendme_accept_min_version=0");
  107. tt_int_op(get_emit_min_version(), OP_EQ, 1);
  108. tt_int_op(get_accept_min_version(), OP_EQ, 0);
  109. smartlist_clear(current_md_consensus->net_params);
  110. /* Validate is the cell version is coherent with our internal default value
  111. * and the one in the consensus. */
  112. smartlist_add(current_md_consensus->net_params,
  113. (void *) "sendme_accept_min_version=1");
  114. /* Minimum acceptable value is 1. */
  115. tt_int_op(cell_version_is_valid(1), OP_EQ, true);
  116. /* Minimum acceptable value is 1 so a cell version of 0 is refused. */
  117. tt_int_op(cell_version_is_valid(0), OP_EQ, false);
  118. done:
  119. free_mock_consensus();
  120. }
  121. static void
  122. test_v1_build_cell(void *arg)
  123. {
  124. uint8_t payload[RELAY_PAYLOAD_SIZE], digest[DIGEST_LEN];
  125. ssize_t ret;
  126. crypto_digest_t *cell_digest = NULL;
  127. or_circuit_t *or_circ = NULL;
  128. circuit_t *circ = NULL;
  129. (void) arg;
  130. or_circ = or_circuit_new(1, NULL);
  131. circ = TO_CIRCUIT(or_circ);
  132. cell_digest = crypto_digest_new();
  133. tt_assert(cell_digest);
  134. crypto_digest_add_bytes(cell_digest, "AAAAAAAAAAAAAAAAAAAA", 20);
  135. crypto_digest_get_digest(cell_digest, (char *) digest, sizeof(digest));
  136. /* SENDME v1 payload is 3 bytes + 20 bytes digest. See spec. */
  137. ret = build_cell_payload_v1(digest, payload);
  138. tt_int_op(ret, OP_EQ, 23);
  139. /* Validation. */
  140. /* An empty payload means SENDME version 0 thus valid. */
  141. tt_int_op(sendme_is_valid(circ, payload, 0), OP_EQ, true);
  142. /* An unparseable cell means invalid. */
  143. setup_full_capture_of_logs(LOG_INFO);
  144. tt_int_op(sendme_is_valid(circ, (const uint8_t *) "A", 1), OP_EQ, false);
  145. expect_log_msg_containing("Unparseable SENDME cell received. "
  146. "Closing circuit.");
  147. teardown_capture_of_logs();
  148. /* No cell digest recorded for this. */
  149. setup_full_capture_of_logs(LOG_INFO);
  150. tt_int_op(sendme_is_valid(circ, payload, sizeof(payload)), OP_EQ, false);
  151. expect_log_msg_containing("We received a SENDME but we have no cell digests "
  152. "to match. Closing circuit.");
  153. teardown_capture_of_logs();
  154. /* Note the wrong digest in the circuit, cell should fail validation. */
  155. circ->package_window = CIRCWINDOW_INCREMENT + 1;
  156. sendme_record_cell_digest(circ);
  157. tt_int_op(smartlist_len(circ->sendme_last_digests), OP_EQ, 1);
  158. setup_full_capture_of_logs(LOG_INFO);
  159. tt_int_op(sendme_is_valid(circ, payload, sizeof(payload)), OP_EQ, false);
  160. /* After a validation, the last digests is always popped out. */
  161. tt_int_op(smartlist_len(circ->sendme_last_digests), OP_EQ, 0);
  162. expect_log_msg_containing("SENDME v1 cell digest do not match.");
  163. teardown_capture_of_logs();
  164. /* Record the cell digest into the circuit, cell should validate. */
  165. memcpy(or_circ->crypto.sendme_digest, digest, sizeof(digest));
  166. circ->package_window = CIRCWINDOW_INCREMENT + 1;
  167. sendme_record_cell_digest(circ);
  168. tt_int_op(smartlist_len(circ->sendme_last_digests), OP_EQ, 1);
  169. tt_int_op(sendme_is_valid(circ, payload, sizeof(payload)), OP_EQ, true);
  170. /* After a validation, the last digests is always popped out. */
  171. tt_int_op(smartlist_len(circ->sendme_last_digests), OP_EQ, 0);
  172. done:
  173. crypto_digest_free(cell_digest);
  174. circuit_free_(circ);
  175. }
  176. static void
  177. test_cell_payload_pad(void *arg)
  178. {
  179. size_t pad_offset, payload_len, expected_offset;
  180. (void) arg;
  181. /* Offset should be 0, not enough room for padding. */
  182. payload_len = RELAY_PAYLOAD_SIZE;
  183. pad_offset = get_pad_cell_offset(payload_len);
  184. tt_int_op(pad_offset, OP_EQ, 0);
  185. tt_int_op(CELL_PAYLOAD_SIZE - pad_offset, OP_LE, CELL_PAYLOAD_SIZE);
  186. /* Still no room because we keep 4 extra bytes. */
  187. pad_offset = get_pad_cell_offset(payload_len - 4);
  188. tt_int_op(pad_offset, OP_EQ, 0);
  189. tt_int_op(CELL_PAYLOAD_SIZE - pad_offset, OP_LE, CELL_PAYLOAD_SIZE);
  190. /* We should have 1 byte of padding. Meaning, the offset should be the
  191. * CELL_PAYLOAD_SIZE minus 1 byte. */
  192. expected_offset = CELL_PAYLOAD_SIZE - 1;
  193. pad_offset = get_pad_cell_offset(payload_len - 5);
  194. tt_int_op(pad_offset, OP_EQ, expected_offset);
  195. tt_int_op(CELL_PAYLOAD_SIZE - pad_offset, OP_LE, CELL_PAYLOAD_SIZE);
  196. /* Now some arbitrary small payload length. The cell size is header + 10 +
  197. * extra 4 bytes we keep so the offset should be there. */
  198. expected_offset = RELAY_HEADER_SIZE + 10 + 4;
  199. pad_offset = get_pad_cell_offset(10);
  200. tt_int_op(pad_offset, OP_EQ, expected_offset);
  201. tt_int_op(CELL_PAYLOAD_SIZE - pad_offset, OP_LE, CELL_PAYLOAD_SIZE);
  202. /* Data length of 0. */
  203. expected_offset = RELAY_HEADER_SIZE + 4;
  204. pad_offset = get_pad_cell_offset(0);
  205. tt_int_op(pad_offset, OP_EQ, expected_offset);
  206. tt_int_op(CELL_PAYLOAD_SIZE - pad_offset, OP_LE, CELL_PAYLOAD_SIZE);
  207. done:
  208. ;
  209. }
  210. struct testcase_t sendme_tests[] = {
  211. { "v1_record_digest", test_v1_record_digest, TT_FORK,
  212. NULL, NULL },
  213. { "v1_consensus_params", test_v1_consensus_params, TT_FORK,
  214. NULL, NULL },
  215. { "v1_build_cell", test_v1_build_cell, TT_FORK,
  216. NULL, NULL },
  217. { "cell_payload_pad", test_cell_payload_pad, TT_FORK,
  218. NULL, NULL },
  219. END_OF_TESTCASES
  220. };