123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- /* Copyright 2001-2004 Roger Dingledine.
- * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2019, The Tor Project, Inc. */
- /* See LICENSE for licensing information */
- #include "core/or/or.h"
- #include "core/or/circuitbuild.h"
- #define CIRCUITLIST_PRIVATE
- #include "core/or/circuitlist.h"
- #include "lib/crypt_ops/crypto_rand.h"
- #include "core/or/relay.h"
- #include "core/crypto/relay_crypto.h"
- #include "core/or/cell_st.h"
- #include "core/or/or_circuit_st.h"
- #include "core/or/origin_circuit_st.h"
- #include "test/test.h"
- static const char KEY_MATERIAL[3][CPATH_KEY_MATERIAL_LEN] = {
- " 'My public key is in this signed x509 object', said Tom assertively.",
- "'Let's chart the pedal phlanges in the tomb', said Tom cryptographically",
- " 'Segmentation fault bugs don't _just happen_', said Tom seethingly.",
- };
- typedef struct testing_circuitset_t {
- or_circuit_t *or_circ[3];
- origin_circuit_t *origin_circ;
- } testing_circuitset_t;
- static int testing_circuitset_teardown(const struct testcase_t *testcase,
- void *ptr);
- static void *
- testing_circuitset_setup(const struct testcase_t *testcase)
- {
- testing_circuitset_t *cs = tor_malloc_zero(sizeof(testing_circuitset_t));
- int i;
- for (i=0; i<3; ++i) {
- cs->or_circ[i] = or_circuit_new(0, NULL);
- tt_int_op(0, OP_EQ,
- relay_crypto_init(&cs->or_circ[i]->crypto,
- KEY_MATERIAL[i], sizeof(KEY_MATERIAL[i]),
- 0, 0));
- }
- cs->origin_circ = origin_circuit_new();
- cs->origin_circ->base_.purpose = CIRCUIT_PURPOSE_C_GENERAL;
- for (i=0; i<3; ++i) {
- crypt_path_t *hop = tor_malloc_zero(sizeof(*hop));
- relay_crypto_init(&hop->crypto, KEY_MATERIAL[i], sizeof(KEY_MATERIAL[i]),
- 0, 0);
- hop->state = CPATH_STATE_OPEN;
- onion_append_to_cpath(&cs->origin_circ->cpath, hop);
- tt_ptr_op(hop, OP_EQ, cs->origin_circ->cpath->prev);
- }
- return cs;
- done:
- testing_circuitset_teardown(testcase, cs);
- return NULL;
- }
- static int
- testing_circuitset_teardown(const struct testcase_t *testcase, void *ptr)
- {
- (void)testcase;
- testing_circuitset_t *cs = ptr;
- int i;
- for (i=0; i<3; ++i) {
- circuit_free_(TO_CIRCUIT(cs->or_circ[i]));
- }
- circuit_free_(TO_CIRCUIT(cs->origin_circ));
- tor_free(cs);
- return 1;
- }
- static const struct testcase_setup_t relaycrypt_setup = {
- testing_circuitset_setup, testing_circuitset_teardown
- };
- /* Test encrypting a cell to the final hop on a circuit, decrypting it
- * at each hop, and recognizing it at the other end. Then do it again
- * and again as the state evolves. */
- static void
- test_relaycrypt_outbound(void *arg)
- {
- testing_circuitset_t *cs = arg;
- tt_assert(cs);
- relay_header_t rh;
- cell_t orig;
- cell_t encrypted;
- int i, j;
- for (i = 0; i < 50; ++i) {
- crypto_rand((char *)&orig, sizeof(orig));
- relay_header_unpack(&rh, orig.payload);
- rh.recognized = 0;
- memset(rh.integrity, 0, sizeof(rh.integrity));
- relay_header_pack(orig.payload, &rh);
- memcpy(&encrypted, &orig, sizeof(orig));
- /* Encrypt the cell to the last hop */
- relay_encrypt_cell_outbound(&encrypted, cs->origin_circ,
- cs->origin_circ->cpath->prev);
- for (j = 0; j < 3; ++j) {
- crypt_path_t *layer_hint = NULL;
- char recognized = 0;
- int r = relay_decrypt_cell(TO_CIRCUIT(cs->or_circ[j]),
- &encrypted,
- CELL_DIRECTION_OUT,
- &layer_hint, &recognized);
- tt_int_op(r, OP_EQ, 0);
- tt_ptr_op(layer_hint, OP_EQ, NULL);
- tt_int_op(recognized != 0, OP_EQ, j == 2);
- }
- tt_mem_op(orig.payload, OP_EQ, encrypted.payload, CELL_PAYLOAD_SIZE);
- }
- done:
- ;
- }
- /* As above, but simulate inbound cells from the last hop. */
- static void
- test_relaycrypt_inbound(void *arg)
- {
- testing_circuitset_t *cs = arg;
- tt_assert(cs);
- relay_header_t rh;
- cell_t orig;
- cell_t encrypted;
- int i, j;
- for (i = 0; i < 50; ++i) {
- crypto_rand((char *)&orig, sizeof(orig));
- relay_header_unpack(&rh, orig.payload);
- rh.recognized = 0;
- memset(rh.integrity, 0, sizeof(rh.integrity));
- relay_header_pack(orig.payload, &rh);
- memcpy(&encrypted, &orig, sizeof(orig));
- /* Encrypt the cell to the last hop */
- relay_encrypt_cell_inbound(&encrypted, cs->or_circ[2]);
- crypt_path_t *layer_hint = NULL;
- char recognized = 0;
- int r;
- for (j = 1; j >= 0; --j) {
- r = relay_decrypt_cell(TO_CIRCUIT(cs->or_circ[j]),
- &encrypted,
- CELL_DIRECTION_IN,
- &layer_hint, &recognized);
- tt_int_op(r, OP_EQ, 0);
- tt_ptr_op(layer_hint, OP_EQ, NULL);
- tt_int_op(recognized, OP_EQ, 0);
- }
- relay_decrypt_cell(TO_CIRCUIT(cs->origin_circ),
- &encrypted,
- CELL_DIRECTION_IN,
- &layer_hint, &recognized);
- tt_int_op(r, OP_EQ, 0);
- tt_int_op(recognized, OP_EQ, 1);
- tt_ptr_op(layer_hint, OP_EQ, cs->origin_circ->cpath->prev);
- tt_mem_op(orig.payload, OP_EQ, encrypted.payload, CELL_PAYLOAD_SIZE);
- }
- done:
- ;
- }
- #define TEST(name) \
- { # name, test_relaycrypt_ ## name, 0, &relaycrypt_setup, NULL }
- struct testcase_t relaycrypt_tests[] = {
- TEST(outbound),
- TEST(inbound),
- END_OF_TESTCASES
- };
|