Split the authority-cert and signature/hash code from routerparse
[tor.git] / src / test / test_relaycrypt.c
blobc3cfb7d10b84c0456028c3d112813d78f154db67
1 /* Copyright 2001-2004 Roger Dingledine.
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2018, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
6 #include "core/or/or.h"
7 #include "core/or/circuitbuild.h"
8 #define CIRCUITLIST_PRIVATE
9 #include "core/or/circuitlist.h"
10 #include "lib/crypt_ops/crypto_rand.h"
11 #include "core/or/relay.h"
12 #include "core/crypto/relay_crypto.h"
14 #include "core/or/cell_st.h"
15 #include "core/or/or_circuit_st.h"
16 #include "core/or/origin_circuit_st.h"
18 #include "test/test.h"
20 static const char KEY_MATERIAL[3][CPATH_KEY_MATERIAL_LEN] = {
21 " 'My public key is in this signed x509 object', said Tom assertively.",
22 "'Let's chart the pedal phlanges in the tomb', said Tom cryptographically",
23 " 'Segmentation fault bugs don't _just happen_', said Tom seethingly.",
26 typedef struct testing_circuitset_t {
27 or_circuit_t *or_circ[3];
28 origin_circuit_t *origin_circ;
29 } testing_circuitset_t;
31 static int testing_circuitset_teardown(const struct testcase_t *testcase,
32 void *ptr);
34 static void *
35 testing_circuitset_setup(const struct testcase_t *testcase)
37 testing_circuitset_t *cs = tor_malloc_zero(sizeof(testing_circuitset_t));
38 int i;
40 for (i=0; i<3; ++i) {
41 cs->or_circ[i] = or_circuit_new(0, NULL);
42 tt_int_op(0, OP_EQ,
43 relay_crypto_init(&cs->or_circ[i]->crypto,
44 KEY_MATERIAL[i], sizeof(KEY_MATERIAL[i]),
45 0, 0));
48 cs->origin_circ = origin_circuit_new();
49 cs->origin_circ->base_.purpose = CIRCUIT_PURPOSE_C_GENERAL;
50 for (i=0; i<3; ++i) {
51 crypt_path_t *hop = tor_malloc_zero(sizeof(*hop));
52 relay_crypto_init(&hop->crypto, KEY_MATERIAL[i], sizeof(KEY_MATERIAL[i]),
53 0, 0);
54 hop->state = CPATH_STATE_OPEN;
55 onion_append_to_cpath(&cs->origin_circ->cpath, hop);
56 tt_ptr_op(hop, OP_EQ, cs->origin_circ->cpath->prev);
59 return cs;
60 done:
61 testing_circuitset_teardown(testcase, cs);
62 return NULL;
65 static int
66 testing_circuitset_teardown(const struct testcase_t *testcase, void *ptr)
68 (void)testcase;
69 testing_circuitset_t *cs = ptr;
70 int i;
71 for (i=0; i<3; ++i) {
72 circuit_free_(TO_CIRCUIT(cs->or_circ[i]));
74 circuit_free_(TO_CIRCUIT(cs->origin_circ));
75 tor_free(cs);
76 return 1;
79 static const struct testcase_setup_t relaycrypt_setup = {
80 testing_circuitset_setup, testing_circuitset_teardown
83 /* Test encrypting a cell to the final hop on a circuit, decrypting it
84 * at each hop, and recognizing it at the other end. Then do it again
85 * and again as the state evolves. */
86 static void
87 test_relaycrypt_outbound(void *arg)
89 testing_circuitset_t *cs = arg;
90 tt_assert(cs);
92 relay_header_t rh;
93 cell_t orig;
94 cell_t encrypted;
95 int i, j;
97 for (i = 0; i < 50; ++i) {
98 crypto_rand((char *)&orig, sizeof(orig));
100 relay_header_unpack(&rh, orig.payload);
101 rh.recognized = 0;
102 memset(rh.integrity, 0, sizeof(rh.integrity));
103 relay_header_pack(orig.payload, &rh);
105 memcpy(&encrypted, &orig, sizeof(orig));
107 /* Encrypt the cell to the last hop */
108 relay_encrypt_cell_outbound(&encrypted, cs->origin_circ,
109 cs->origin_circ->cpath->prev);
111 for (j = 0; j < 3; ++j) {
112 crypt_path_t *layer_hint = NULL;
113 char recognized = 0;
114 int r = relay_decrypt_cell(TO_CIRCUIT(cs->or_circ[j]),
115 &encrypted,
116 CELL_DIRECTION_OUT,
117 &layer_hint, &recognized);
118 tt_int_op(r, OP_EQ, 0);
119 tt_ptr_op(layer_hint, OP_EQ, NULL);
120 tt_int_op(recognized != 0, OP_EQ, j == 2);
123 tt_mem_op(orig.payload, OP_EQ, encrypted.payload, CELL_PAYLOAD_SIZE);
126 done:
130 /* As above, but simulate inbound cells from the last hop. */
131 static void
132 test_relaycrypt_inbound(void *arg)
134 testing_circuitset_t *cs = arg;
135 tt_assert(cs);
137 relay_header_t rh;
138 cell_t orig;
139 cell_t encrypted;
140 int i, j;
142 for (i = 0; i < 50; ++i) {
143 crypto_rand((char *)&orig, sizeof(orig));
145 relay_header_unpack(&rh, orig.payload);
146 rh.recognized = 0;
147 memset(rh.integrity, 0, sizeof(rh.integrity));
148 relay_header_pack(orig.payload, &rh);
150 memcpy(&encrypted, &orig, sizeof(orig));
152 /* Encrypt the cell to the last hop */
153 relay_encrypt_cell_inbound(&encrypted, cs->or_circ[2]);
155 crypt_path_t *layer_hint = NULL;
156 char recognized = 0;
157 int r;
158 for (j = 1; j >= 0; --j) {
159 r = relay_decrypt_cell(TO_CIRCUIT(cs->or_circ[j]),
160 &encrypted,
161 CELL_DIRECTION_IN,
162 &layer_hint, &recognized);
163 tt_int_op(r, OP_EQ, 0);
164 tt_ptr_op(layer_hint, OP_EQ, NULL);
165 tt_int_op(recognized, OP_EQ, 0);
168 relay_decrypt_cell(TO_CIRCUIT(cs->origin_circ),
169 &encrypted,
170 CELL_DIRECTION_IN,
171 &layer_hint, &recognized);
172 tt_int_op(r, OP_EQ, 0);
173 tt_int_op(recognized, OP_EQ, 1);
174 tt_ptr_op(layer_hint, OP_EQ, cs->origin_circ->cpath->prev);
176 tt_mem_op(orig.payload, OP_EQ, encrypted.payload, CELL_PAYLOAD_SIZE);
178 done:
182 #define TEST(name) \
183 { # name, test_relaycrypt_ ## name, 0, &relaycrypt_setup, NULL }
185 struct testcase_t relaycrypt_tests[] = {
186 TEST(outbound),
187 TEST(inbound),
188 END_OF_TESTCASES