test_relaycrypt.c (5728B)
1 /* Copyright 2001-2004 Roger Dingledine. 2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. 3 * Copyright (c) 2007-2021, The Tor Project, Inc. */ 4 /* See LICENSE for licensing information */ 5 6 #define CRYPT_PATH_PRIVATE 7 8 #include "core/or/or.h" 9 #include "core/or/circuitbuild.h" 10 #define CIRCUITLIST_PRIVATE 11 #include "core/or/circuitlist.h" 12 #include "lib/crypt_ops/crypto_rand.h" 13 #include "core/or/relay.h" 14 #include "core/crypto/relay_crypto.h" 15 #include "core/or/crypt_path.h" 16 #include "core/or/cell_st.h" 17 #include "core/or/or_circuit_st.h" 18 #include "core/or/origin_circuit_st.h" 19 20 #include "test/test.h" 21 22 #ifdef __GNUC__ 23 #pragma GCC diagnostic push 24 #pragma GCC diagnostic ignored "-Wattributes" 25 #endif 26 NONSTRING static const char KEY_MATERIAL[3][CPATH_KEY_MATERIAL_LEN] = { 27 " 'My public key is in this signed x509 object', said Tom assertively.", 28 "'Let's chart the pedal phlanges in the tomb', said Tom cryptographically", 29 " 'Segmentation fault bugs don't _just happen_', said Tom seethingly.", 30 }; 31 #ifdef __GNUC__ 32 #pragma GCC diagnostic pop 33 #endif 34 35 typedef struct testing_circuitset_t { 36 or_circuit_t *or_circ[3]; 37 origin_circuit_t *origin_circ; 38 } testing_circuitset_t; 39 40 static int testing_circuitset_teardown(const struct testcase_t *testcase, 41 void *ptr); 42 43 static void * 44 testing_circuitset_setup(const struct testcase_t *testcase) 45 { 46 testing_circuitset_t *cs = tor_malloc_zero(sizeof(testing_circuitset_t)); 47 int i; 48 49 for (i=0; i<3; ++i) { 50 cs->or_circ[i] = or_circuit_new(0, NULL); 51 tt_int_op(0, OP_EQ, 52 relay_crypto_init(RELAY_CRYPTO_ALG_TOR1, 53 &cs->or_circ[i]->crypto, 54 KEY_MATERIAL[i], sizeof(KEY_MATERIAL[i]))); 55 } 56 57 cs->origin_circ = origin_circuit_new(); 58 cs->origin_circ->base_.purpose = CIRCUIT_PURPOSE_C_GENERAL; 59 for (i=0; i<3; ++i) { 60 crypt_path_t *hop = tor_malloc_zero(sizeof(*hop)); 61 relay_crypto_init(RELAY_CRYPTO_ALG_TOR1, 62 &hop->pvt_crypto, KEY_MATERIAL[i], 63 sizeof(KEY_MATERIAL[i])); 64 hop->state = CPATH_STATE_OPEN; 65 cpath_extend_linked_list(&cs->origin_circ->cpath, hop); 66 tt_ptr_op(hop, OP_EQ, cs->origin_circ->cpath->prev); 67 } 68 69 return cs; 70 done: 71 testing_circuitset_teardown(testcase, cs); 72 return NULL; 73 } 74 75 static int 76 testing_circuitset_teardown(const struct testcase_t *testcase, void *ptr) 77 { 78 (void)testcase; 79 testing_circuitset_t *cs = ptr; 80 int i; 81 for (i=0; i<3; ++i) { 82 circuit_free_(TO_CIRCUIT(cs->or_circ[i])); 83 } 84 circuit_free_(TO_CIRCUIT(cs->origin_circ)); 85 tor_free(cs); 86 return 1; 87 } 88 89 static const struct testcase_setup_t relaycrypt_setup = { 90 testing_circuitset_setup, testing_circuitset_teardown 91 }; 92 93 /* Test encrypting a cell to the final hop on a circuit, decrypting it 94 * at each hop, and recognizing it at the other end. Then do it again 95 * and again as the state evolves. */ 96 static void 97 test_relaycrypt_outbound(void *arg) 98 { 99 testing_circuitset_t *cs = arg; 100 tt_assert(cs); 101 102 relay_header_t rh; 103 cell_t orig; 104 cell_t encrypted; 105 int i, j; 106 107 for (i = 0; i < 50; ++i) { 108 crypto_rand((char *)&orig, sizeof(orig)); 109 110 relay_header_unpack(&rh, orig.payload); 111 rh.recognized = 0; 112 memset(rh.integrity, 0, sizeof(rh.integrity)); 113 relay_header_pack(orig.payload, &rh); 114 115 memcpy(&encrypted, &orig, sizeof(orig)); 116 117 /* Encrypt the cell to the last hop */ 118 relay_encrypt_cell_outbound(&encrypted, cs->origin_circ, 119 cs->origin_circ->cpath->prev); 120 121 for (j = 0; j < 3; ++j) { 122 crypt_path_t *layer_hint = NULL; 123 char recognized = 0; 124 int r = relay_decrypt_cell(TO_CIRCUIT(cs->or_circ[j]), 125 &encrypted, 126 CELL_DIRECTION_OUT, 127 &layer_hint, &recognized); 128 tt_int_op(r, OP_EQ, 0); 129 tt_ptr_op(layer_hint, OP_EQ, NULL); 130 tt_int_op(recognized != 0, OP_EQ, j == 2); 131 } 132 133 tt_mem_op(orig.payload, OP_EQ, encrypted.payload, CELL_PAYLOAD_SIZE); 134 } 135 136 done: 137 ; 138 } 139 140 /* As above, but simulate inbound cells from the last hop. */ 141 static void 142 test_relaycrypt_inbound(void *arg) 143 { 144 testing_circuitset_t *cs = arg; 145 tt_assert(cs); 146 147 relay_header_t rh; 148 cell_t orig; 149 cell_t encrypted; 150 int i, j; 151 152 for (i = 0; i < 50; ++i) { 153 crypto_rand((char *)&orig, sizeof(orig)); 154 155 relay_header_unpack(&rh, orig.payload); 156 rh.recognized = 0; 157 memset(rh.integrity, 0, sizeof(rh.integrity)); 158 relay_header_pack(orig.payload, &rh); 159 160 memcpy(&encrypted, &orig, sizeof(orig)); 161 162 /* Encrypt the cell to the last hop */ 163 relay_encrypt_cell_inbound(&encrypted, cs->or_circ[2]); 164 165 crypt_path_t *layer_hint = NULL; 166 char recognized = 0; 167 int r; 168 for (j = 1; j >= 0; --j) { 169 r = relay_decrypt_cell(TO_CIRCUIT(cs->or_circ[j]), 170 &encrypted, 171 CELL_DIRECTION_IN, 172 &layer_hint, &recognized); 173 tt_int_op(r, OP_EQ, 0); 174 tt_ptr_op(layer_hint, OP_EQ, NULL); 175 tt_int_op(recognized, OP_EQ, 0); 176 } 177 178 relay_decrypt_cell(TO_CIRCUIT(cs->origin_circ), 179 &encrypted, 180 CELL_DIRECTION_IN, 181 &layer_hint, &recognized); 182 tt_int_op(r, OP_EQ, 0); 183 tt_int_op(recognized, OP_EQ, 1); 184 tt_ptr_op(layer_hint, OP_EQ, cs->origin_circ->cpath->prev); 185 186 tt_mem_op(orig.payload, OP_EQ, encrypted.payload, CELL_PAYLOAD_SIZE); 187 } 188 done: 189 ; 190 } 191 192 #define TEST(name) \ 193 { # name, test_relaycrypt_ ## name, 0, &relaycrypt_setup, NULL } 194 195 struct testcase_t relaycrypt_tests[] = { 196 TEST(outbound), 197 TEST(inbound), 198 END_OF_TESTCASES 199 };