Merge branch 'maint-0.2.9' into maint-0.3.3
[tor.git] / src / test / test_cell_formats.c
blob88cdef383fa62720e3d2f159f3b512a785147bb5
1 /* Copyright (c) 2001-2004, Roger Dingledine.
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2017, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
6 #include "orconfig.h"
8 #define CONNECTION_EDGE_PRIVATE
9 #define RELAY_PRIVATE
10 #include "or.h"
11 #include "channel.h"
12 #include "connection_edge.h"
13 #include "connection_or.h"
14 #include "config.h"
15 #include "onion.h"
16 #include "onion_tap.h"
17 #include "onion_fast.h"
18 #include "onion_ntor.h"
19 #include "relay.h"
20 #include "test.h"
22 #include <stdlib.h>
23 #include <string.h>
25 static void
26 test_cfmt_relay_header(void *arg)
28 relay_header_t rh;
29 const uint8_t hdr_1[RELAY_HEADER_SIZE] =
30 "\x03" "\x00\x00" "\x21\x22" "ABCD" "\x01\x03";
31 uint8_t hdr_out[RELAY_HEADER_SIZE];
32 (void)arg;
34 tt_int_op(sizeof(hdr_1), OP_EQ, RELAY_HEADER_SIZE);
35 relay_header_unpack(&rh, hdr_1);
36 tt_int_op(rh.command, OP_EQ, 3);
37 tt_int_op(rh.recognized, OP_EQ, 0);
38 tt_int_op(rh.stream_id, OP_EQ, 0x2122);
39 tt_mem_op(rh.integrity, OP_EQ, "ABCD", 4);
40 tt_int_op(rh.length, OP_EQ, 0x103);
42 relay_header_pack(hdr_out, &rh);
43 tt_mem_op(hdr_out, OP_EQ, hdr_1, RELAY_HEADER_SIZE);
45 done:
49 static void
50 make_relay_cell(cell_t *out, uint8_t command,
51 const void *body, size_t bodylen)
53 relay_header_t rh;
55 memset(&rh, 0, sizeof(rh));
56 rh.stream_id = 5;
57 rh.command = command;
58 rh.length = bodylen;
60 out->command = CELL_RELAY;
61 out->circ_id = 10;
62 relay_header_pack(out->payload, &rh);
64 memcpy(out->payload + RELAY_HEADER_SIZE, body, bodylen);
67 static void
68 test_cfmt_begin_cells(void *arg)
70 cell_t cell;
71 begin_cell_t bcell;
72 uint8_t end_reason;
73 (void)arg;
75 /* Try begindir. */
76 memset(&bcell, 0x7f, sizeof(bcell));
77 make_relay_cell(&cell, RELAY_COMMAND_BEGIN_DIR, "", 0);
78 tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
79 tt_ptr_op(NULL, OP_EQ, bcell.address);
80 tt_int_op(0, OP_EQ, bcell.flags);
81 tt_int_op(0, OP_EQ, bcell.port);
82 tt_int_op(5, OP_EQ, bcell.stream_id);
83 tt_int_op(1, OP_EQ, bcell.is_begindir);
85 /* A Begindir with extra stuff. */
86 memset(&bcell, 0x7f, sizeof(bcell));
87 make_relay_cell(&cell, RELAY_COMMAND_BEGIN_DIR, "12345", 5);
88 tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
89 tt_ptr_op(NULL, OP_EQ, bcell.address);
90 tt_int_op(0, OP_EQ, bcell.flags);
91 tt_int_op(0, OP_EQ, bcell.port);
92 tt_int_op(5, OP_EQ, bcell.stream_id);
93 tt_int_op(1, OP_EQ, bcell.is_begindir);
95 /* A short but valid begin cell */
96 memset(&bcell, 0x7f, sizeof(bcell));
97 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:9", 6);
98 tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
99 tt_str_op("a.b", OP_EQ, bcell.address);
100 tt_int_op(0, OP_EQ, bcell.flags);
101 tt_int_op(9, OP_EQ, bcell.port);
102 tt_int_op(5, OP_EQ, bcell.stream_id);
103 tt_int_op(0, OP_EQ, bcell.is_begindir);
104 tor_free(bcell.address);
106 /* A significantly loner begin cell */
107 memset(&bcell, 0x7f, sizeof(bcell));
109 const char c[] = "here-is-a-nice-long.hostname.com:65535";
110 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, c, strlen(c)+1);
112 tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
113 tt_str_op("here-is-a-nice-long.hostname.com", OP_EQ, bcell.address);
114 tt_int_op(0, OP_EQ, bcell.flags);
115 tt_int_op(65535, OP_EQ, bcell.port);
116 tt_int_op(5, OP_EQ, bcell.stream_id);
117 tt_int_op(0, OP_EQ, bcell.is_begindir);
118 tor_free(bcell.address);
120 /* An IPv4 begin cell. */
121 memset(&bcell, 0x7f, sizeof(bcell));
122 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "18.9.22.169:80", 15);
123 tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
124 tt_str_op("18.9.22.169", OP_EQ, bcell.address);
125 tt_int_op(0, OP_EQ, bcell.flags);
126 tt_int_op(80, OP_EQ, bcell.port);
127 tt_int_op(5, OP_EQ, bcell.stream_id);
128 tt_int_op(0, OP_EQ, bcell.is_begindir);
129 tor_free(bcell.address);
131 /* An IPv6 begin cell. Let's make sure we handle colons*/
132 memset(&bcell, 0x7f, sizeof(bcell));
133 make_relay_cell(&cell, RELAY_COMMAND_BEGIN,
134 "[2620::6b0:b:1a1a:0:26e5:480e]:80", 34);
135 tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
136 tt_str_op("[2620::6b0:b:1a1a:0:26e5:480e]", OP_EQ, bcell.address);
137 tt_int_op(0, OP_EQ, bcell.flags);
138 tt_int_op(80, OP_EQ, bcell.port);
139 tt_int_op(5, OP_EQ, bcell.stream_id);
140 tt_int_op(0, OP_EQ, bcell.is_begindir);
141 tor_free(bcell.address);
143 /* a begin cell with extra junk but not enough for flags. */
144 memset(&bcell, 0x7f, sizeof(bcell));
146 const char c[] = "another.example.com:80\x00\x01\x02";
147 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, c, sizeof(c)-1);
149 tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
150 tt_str_op("another.example.com", OP_EQ, bcell.address);
151 tt_int_op(0, OP_EQ, bcell.flags);
152 tt_int_op(80, OP_EQ, bcell.port);
153 tt_int_op(5, OP_EQ, bcell.stream_id);
154 tt_int_op(0, OP_EQ, bcell.is_begindir);
155 tor_free(bcell.address);
157 /* a begin cell with flags. */
158 memset(&bcell, 0x7f, sizeof(bcell));
160 const char c[] = "another.example.com:443\x00\x01\x02\x03\x04";
161 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, c, sizeof(c)-1);
163 tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
164 tt_str_op("another.example.com", OP_EQ, bcell.address);
165 tt_int_op(0x1020304, OP_EQ, bcell.flags);
166 tt_int_op(443, OP_EQ, bcell.port);
167 tt_int_op(5, OP_EQ, bcell.stream_id);
168 tt_int_op(0, OP_EQ, bcell.is_begindir);
169 tor_free(bcell.address);
171 /* a begin cell with flags and even more cruft after that. */
172 memset(&bcell, 0x7f, sizeof(bcell));
174 const char c[] = "a-further.example.com:22\x00\xee\xaa\x00\xffHi mom";
175 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, c, sizeof(c)-1);
177 tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
178 tt_str_op("a-further.example.com", OP_EQ, bcell.address);
179 tt_int_op(0xeeaa00ff, OP_EQ, bcell.flags);
180 tt_int_op(22, OP_EQ, bcell.port);
181 tt_int_op(5, OP_EQ, bcell.stream_id);
182 tt_int_op(0, OP_EQ, bcell.is_begindir);
183 tor_free(bcell.address);
185 /* bad begin cell: impossible length. */
186 memset(&bcell, 0x7f, sizeof(bcell));
187 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:80", 7);
188 cell.payload[9] = 0x01; /* Set length to 510 */
189 cell.payload[10] = 0xfe;
191 relay_header_t rh;
192 relay_header_unpack(&rh, cell.payload);
193 tt_int_op(rh.length, OP_EQ, 510);
195 tt_int_op(-2, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
197 /* Bad begin cell: no body. */
198 memset(&bcell, 0x7f, sizeof(bcell));
199 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "", 0);
200 tt_int_op(-1, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
202 /* bad begin cell: no body. */
203 memset(&bcell, 0x7f, sizeof(bcell));
204 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "", 0);
205 tt_int_op(-1, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
207 /* bad begin cell: no colon */
208 memset(&bcell, 0x7f, sizeof(bcell));
209 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b", 4);
210 tt_int_op(-1, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
212 /* bad begin cell: no ports */
213 memset(&bcell, 0x7f, sizeof(bcell));
214 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:", 5);
215 tt_int_op(-1, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
217 /* bad begin cell: bad port */
218 memset(&bcell, 0x7f, sizeof(bcell));
219 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:xyz", 8);
220 tt_int_op(-1, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
221 memset(&bcell, 0x7f, sizeof(bcell));
222 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:100000", 11);
223 tt_int_op(-1, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
225 /* bad begin cell: no nul */
226 memset(&bcell, 0x7f, sizeof(bcell));
227 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:80", 6);
228 tt_int_op(-1, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
230 done:
231 tor_free(bcell.address);
234 static void
235 test_cfmt_connected_cells(void *arg)
237 relay_header_t rh;
238 cell_t cell;
239 tor_addr_t addr;
240 int ttl, r;
241 char *mem_op_hex_tmp = NULL;
242 (void)arg;
244 /* Let's try an oldschool one with nothing in it. */
245 make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, "", 0);
246 relay_header_unpack(&rh, cell.payload);
247 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
248 tt_int_op(r, OP_EQ, 0);
249 tt_int_op(tor_addr_family(&addr), OP_EQ, AF_UNSPEC);
250 tt_int_op(ttl, OP_EQ, -1);
252 /* A slightly less oldschool one: only an IPv4 address */
253 make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, "\x20\x30\x40\x50", 4);
254 relay_header_unpack(&rh, cell.payload);
255 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
256 tt_int_op(r, OP_EQ, 0);
257 tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET);
258 tt_str_op(fmt_addr(&addr), OP_EQ, "32.48.64.80");
259 tt_int_op(ttl, OP_EQ, -1);
261 /* Bogus but understandable: truncated TTL */
262 make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, "\x11\x12\x13\x14\x15", 5);
263 relay_header_unpack(&rh, cell.payload);
264 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
265 tt_int_op(r, OP_EQ, 0);
266 tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET);
267 tt_str_op(fmt_addr(&addr), OP_EQ, "17.18.19.20");
268 tt_int_op(ttl, OP_EQ, -1);
270 /* Regular IPv4 one: address and TTL */
271 make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
272 "\x02\x03\x04\x05\x00\x00\x0e\x10", 8);
273 relay_header_unpack(&rh, cell.payload);
274 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
275 tt_int_op(r, OP_EQ, 0);
276 tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET);
277 tt_str_op(fmt_addr(&addr), OP_EQ, "2.3.4.5");
278 tt_int_op(ttl, OP_EQ, 3600);
280 /* IPv4 with too-big TTL */
281 make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
282 "\x02\x03\x04\x05\xf0\x00\x00\x00", 8);
283 relay_header_unpack(&rh, cell.payload);
284 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
285 tt_int_op(r, OP_EQ, 0);
286 tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET);
287 tt_str_op(fmt_addr(&addr), OP_EQ, "2.3.4.5");
288 tt_int_op(ttl, OP_EQ, -1);
290 /* IPv6 (ttl is mandatory) */
291 make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
292 "\x00\x00\x00\x00\x06"
293 "\x26\x07\xf8\xb0\x40\x0c\x0c\x02"
294 "\x00\x00\x00\x00\x00\x00\x00\x68"
295 "\x00\x00\x02\x58", 25);
296 relay_header_unpack(&rh, cell.payload);
297 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
298 tt_int_op(r, OP_EQ, 0);
299 tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET6);
300 tt_str_op(fmt_addr(&addr), OP_EQ, "2607:f8b0:400c:c02::68");
301 tt_int_op(ttl, OP_EQ, 600);
303 /* IPv6 (ttl too big) */
304 make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
305 "\x00\x00\x00\x00\x06"
306 "\x26\x07\xf8\xb0\x40\x0c\x0c\x02"
307 "\x00\x00\x00\x00\x00\x00\x00\x68"
308 "\x90\x00\x02\x58", 25);
309 relay_header_unpack(&rh, cell.payload);
310 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
311 tt_int_op(r, OP_EQ, 0);
312 tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET6);
313 tt_str_op(fmt_addr(&addr), OP_EQ, "2607:f8b0:400c:c02::68");
314 tt_int_op(ttl, OP_EQ, -1);
316 /* Bogus size: 3. */
317 make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
318 "\x00\x01\x02", 3);
319 relay_header_unpack(&rh, cell.payload);
320 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
321 tt_int_op(r, OP_EQ, -1);
323 /* Bogus family: 7. */
324 make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
325 "\x00\x00\x00\x00\x07"
326 "\x26\x07\xf8\xb0\x40\x0c\x0c\x02"
327 "\x00\x00\x00\x00\x00\x00\x00\x68"
328 "\x90\x00\x02\x58", 25);
329 relay_header_unpack(&rh, cell.payload);
330 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
331 tt_int_op(r, OP_EQ, -1);
333 /* Truncated IPv6. */
334 make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
335 "\x00\x00\x00\x00\x06"
336 "\x26\x07\xf8\xb0\x40\x0c\x0c\x02"
337 "\x00\x00\x00\x00\x00\x00\x00\x68"
338 "\x00\x00\x02", 24);
339 relay_header_unpack(&rh, cell.payload);
340 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
341 tt_int_op(r, OP_EQ, -1);
343 /* Now make sure we can generate connected cells correctly. */
344 /* Try an IPv4 address */
345 memset(&rh, 0, sizeof(rh));
346 memset(&cell, 0, sizeof(cell));
347 tor_addr_parse(&addr, "30.40.50.60");
348 rh.length = connected_cell_format_payload(cell.payload+RELAY_HEADER_SIZE,
349 &addr, 1024);
350 tt_int_op(rh.length, OP_EQ, 8);
351 test_memeq_hex(cell.payload+RELAY_HEADER_SIZE, "1e28323c" "00000e10");
353 /* Try parsing it. */
354 tor_addr_make_unspec(&addr);
355 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
356 tt_int_op(r, OP_EQ, 0);
357 tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET);
358 tt_str_op(fmt_addr(&addr), OP_EQ, "30.40.50.60");
359 tt_int_op(ttl, OP_EQ, 3600); /* not 1024, since we clipped to 3600 */
361 /* Try an IPv6 address */
362 memset(&rh, 0, sizeof(rh));
363 memset(&cell, 0, sizeof(cell));
364 tor_addr_parse(&addr, "2620::6b0:b:1a1a:0:26e5:480e");
365 rh.length = connected_cell_format_payload(cell.payload+RELAY_HEADER_SIZE,
366 &addr, 3600);
367 tt_int_op(rh.length, OP_EQ, 25);
368 test_memeq_hex(cell.payload + RELAY_HEADER_SIZE,
369 "00000000" "06"
370 "2620000006b0000b1a1a000026e5480e" "00000e10");
372 /* Try parsing it. */
373 tor_addr_make_unspec(&addr);
374 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
375 tt_int_op(r, OP_EQ, 0);
376 tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET6);
377 tt_str_op(fmt_addr(&addr), OP_EQ, "2620:0:6b0:b:1a1a:0:26e5:480e");
378 tt_int_op(ttl, OP_EQ, 3600);
380 done:
381 tor_free(mem_op_hex_tmp);
384 static void
385 test_cfmt_create_cells(void *arg)
387 uint8_t b[MAX_ONIONSKIN_CHALLENGE_LEN];
388 create_cell_t cc;
389 cell_t cell;
390 cell_t cell2;
392 (void)arg;
394 /* === Let's try parsing some good cells! */
396 /* A valid create cell. */
397 memset(&cell, 0, sizeof(cell));
398 memset(b, 0, sizeof(b));
399 crypto_rand((char*)b, TAP_ONIONSKIN_CHALLENGE_LEN);
400 cell.command = CELL_CREATE;
401 memcpy(cell.payload, b, TAP_ONIONSKIN_CHALLENGE_LEN);
402 tt_int_op(0, OP_EQ, create_cell_parse(&cc, &cell));
403 tt_int_op(CELL_CREATE, OP_EQ, cc.cell_type);
404 tt_int_op(ONION_HANDSHAKE_TYPE_TAP, OP_EQ, cc.handshake_type);
405 tt_int_op(TAP_ONIONSKIN_CHALLENGE_LEN, OP_EQ, cc.handshake_len);
406 tt_mem_op(cc.onionskin,OP_EQ, b, TAP_ONIONSKIN_CHALLENGE_LEN + 10);
407 tt_int_op(0, OP_EQ, create_cell_format(&cell2, &cc));
408 tt_int_op(cell.command, OP_EQ, cell2.command);
409 tt_mem_op(cell.payload,OP_EQ, cell2.payload, CELL_PAYLOAD_SIZE);
411 /* A valid create_fast cell. */
412 memset(&cell, 0, sizeof(cell));
413 memset(b, 0, sizeof(b));
414 crypto_rand((char*)b, CREATE_FAST_LEN);
415 cell.command = CELL_CREATE_FAST;
416 memcpy(cell.payload, b, CREATE_FAST_LEN);
417 tt_int_op(0, OP_EQ, create_cell_parse(&cc, &cell));
418 tt_int_op(CELL_CREATE_FAST, OP_EQ, cc.cell_type);
419 tt_int_op(ONION_HANDSHAKE_TYPE_FAST, OP_EQ, cc.handshake_type);
420 tt_int_op(CREATE_FAST_LEN, OP_EQ, cc.handshake_len);
421 tt_mem_op(cc.onionskin,OP_EQ, b, CREATE_FAST_LEN + 10);
422 tt_int_op(0, OP_EQ, create_cell_format(&cell2, &cc));
423 tt_int_op(cell.command, OP_EQ, cell2.command);
424 tt_mem_op(cell.payload,OP_EQ, cell2.payload, CELL_PAYLOAD_SIZE);
426 /* A valid create2 cell with a TAP payload */
427 memset(&cell, 0, sizeof(cell));
428 memset(b, 0, sizeof(b));
429 crypto_rand((char*)b, TAP_ONIONSKIN_CHALLENGE_LEN);
430 cell.command = CELL_CREATE2;
431 memcpy(cell.payload, "\x00\x00\x00\xBA", 4); /* TAP, 186 bytes long */
432 memcpy(cell.payload+4, b, TAP_ONIONSKIN_CHALLENGE_LEN);
433 tt_int_op(0, OP_EQ, create_cell_parse(&cc, &cell));
434 tt_int_op(CELL_CREATE2, OP_EQ, cc.cell_type);
435 tt_int_op(ONION_HANDSHAKE_TYPE_TAP, OP_EQ, cc.handshake_type);
436 tt_int_op(TAP_ONIONSKIN_CHALLENGE_LEN, OP_EQ, cc.handshake_len);
437 tt_mem_op(cc.onionskin,OP_EQ, b, TAP_ONIONSKIN_CHALLENGE_LEN + 10);
438 tt_int_op(0, OP_EQ, create_cell_format(&cell2, &cc));
439 tt_int_op(cell.command, OP_EQ, cell2.command);
440 tt_mem_op(cell.payload,OP_EQ, cell2.payload, CELL_PAYLOAD_SIZE);
442 /* A valid create2 cell with an ntor payload */
443 memset(&cell, 0, sizeof(cell));
444 memset(b, 0, sizeof(b));
445 crypto_rand((char*)b, NTOR_ONIONSKIN_LEN);
446 cell.command = CELL_CREATE2;
447 memcpy(cell.payload, "\x00\x02\x00\x54", 4); /* ntor, 84 bytes long */
448 memcpy(cell.payload+4, b, NTOR_ONIONSKIN_LEN);
449 tt_int_op(0, OP_EQ, create_cell_parse(&cc, &cell));
450 tt_int_op(CELL_CREATE2, OP_EQ, cc.cell_type);
451 tt_int_op(ONION_HANDSHAKE_TYPE_NTOR, OP_EQ, cc.handshake_type);
452 tt_int_op(NTOR_ONIONSKIN_LEN, OP_EQ, cc.handshake_len);
453 tt_mem_op(cc.onionskin,OP_EQ, b, NTOR_ONIONSKIN_LEN + 10);
454 tt_int_op(0, OP_EQ, create_cell_format(&cell2, &cc));
455 tt_int_op(cell.command, OP_EQ, cell2.command);
456 tt_mem_op(cell.payload,OP_EQ, cell2.payload, CELL_PAYLOAD_SIZE);
458 /* A valid create cell with an ntor payload, in legacy format. */
459 memset(&cell, 0, sizeof(cell));
460 memset(b, 0, sizeof(b));
461 crypto_rand((char*)b, NTOR_ONIONSKIN_LEN);
462 cell.command = CELL_CREATE;
463 memcpy(cell.payload, "ntorNTORntorNTOR", 16);
464 memcpy(cell.payload+16, b, NTOR_ONIONSKIN_LEN);
465 tt_int_op(0, OP_EQ, create_cell_parse(&cc, &cell));
466 tt_int_op(CELL_CREATE, OP_EQ, cc.cell_type);
467 tt_int_op(ONION_HANDSHAKE_TYPE_NTOR, OP_EQ, cc.handshake_type);
468 tt_int_op(NTOR_ONIONSKIN_LEN, OP_EQ, cc.handshake_len);
469 tt_mem_op(cc.onionskin,OP_EQ, b, NTOR_ONIONSKIN_LEN + 10);
470 tt_int_op(0, OP_EQ, create_cell_format(&cell2, &cc));
471 tt_int_op(cell.command, OP_EQ, cell2.command);
472 tt_mem_op(cell.payload,OP_EQ, cell2.payload, CELL_PAYLOAD_SIZE);
474 /* == Okay, now let's try to parse some impossible stuff. */
476 /* It has to be some kind of a create cell! */
477 cell.command = CELL_CREATED;
478 tt_int_op(-1, OP_EQ, create_cell_parse(&cc, &cell));
480 /* You can't actually make an unparseable CREATE or CREATE_FAST cell. */
482 /* Try some CREATE2 cells. First with a bad type. */
483 cell.command = CELL_CREATE2;
484 memcpy(cell.payload, "\x00\x50\x00\x99", 4); /* Type 0x50???? */
485 tt_int_op(-1, OP_EQ, create_cell_parse(&cc, &cell));
486 /* Now a good type with an incorrect length. */
487 memcpy(cell.payload, "\x00\x00\x00\xBC", 4); /* TAP, 187 bytes.*/
488 tt_int_op(-1, OP_EQ, create_cell_parse(&cc, &cell));
489 /* Now a good type with a ridiculous length. */
490 memcpy(cell.payload, "\x00\x00\x02\x00", 4); /* TAP, 512 bytes.*/
491 tt_int_op(-1, OP_EQ, create_cell_parse(&cc, &cell));
493 /* == Time to try formatting bad cells. The important thing is that
494 we reject big lengths, so just check that for now. */
495 cc.handshake_len = 512;
496 tt_int_op(-1, OP_EQ, create_cell_format(&cell2, &cc));
498 /* == Try formatting a create2 cell we don't understand. XXXX */
500 done:
504 static void
505 test_cfmt_created_cells(void *arg)
507 uint8_t b[512];
508 created_cell_t cc;
509 cell_t cell;
510 cell_t cell2;
512 (void)arg;
514 /* A good CREATED cell */
515 memset(&cell, 0, sizeof(cell));
516 memset(b, 0, sizeof(b));
517 crypto_rand((char*)b, TAP_ONIONSKIN_REPLY_LEN);
518 cell.command = CELL_CREATED;
519 memcpy(cell.payload, b, TAP_ONIONSKIN_REPLY_LEN);
520 tt_int_op(0, OP_EQ, created_cell_parse(&cc, &cell));
521 tt_int_op(CELL_CREATED, OP_EQ, cc.cell_type);
522 tt_int_op(TAP_ONIONSKIN_REPLY_LEN, OP_EQ, cc.handshake_len);
523 tt_mem_op(cc.reply,OP_EQ, b, TAP_ONIONSKIN_REPLY_LEN + 10);
524 tt_int_op(0, OP_EQ, created_cell_format(&cell2, &cc));
525 tt_int_op(cell.command, OP_EQ, cell2.command);
526 tt_mem_op(cell.payload,OP_EQ, cell2.payload, CELL_PAYLOAD_SIZE);
528 /* A good CREATED_FAST cell */
529 memset(&cell, 0, sizeof(cell));
530 memset(b, 0, sizeof(b));
531 crypto_rand((char*)b, CREATED_FAST_LEN);
532 cell.command = CELL_CREATED_FAST;
533 memcpy(cell.payload, b, CREATED_FAST_LEN);
534 tt_int_op(0, OP_EQ, created_cell_parse(&cc, &cell));
535 tt_int_op(CELL_CREATED_FAST, OP_EQ, cc.cell_type);
536 tt_int_op(CREATED_FAST_LEN, OP_EQ, cc.handshake_len);
537 tt_mem_op(cc.reply,OP_EQ, b, CREATED_FAST_LEN + 10);
538 tt_int_op(0, OP_EQ, created_cell_format(&cell2, &cc));
539 tt_int_op(cell.command, OP_EQ, cell2.command);
540 tt_mem_op(cell.payload,OP_EQ, cell2.payload, CELL_PAYLOAD_SIZE);
542 /* A good CREATED2 cell with short reply */
543 memset(&cell, 0, sizeof(cell));
544 memset(b, 0, sizeof(b));
545 crypto_rand((char*)b, 64);
546 cell.command = CELL_CREATED2;
547 memcpy(cell.payload, "\x00\x40", 2);
548 memcpy(cell.payload+2, b, 64);
549 tt_int_op(0, OP_EQ, created_cell_parse(&cc, &cell));
550 tt_int_op(CELL_CREATED2, OP_EQ, cc.cell_type);
551 tt_int_op(64, OP_EQ, cc.handshake_len);
552 tt_mem_op(cc.reply,OP_EQ, b, 80);
553 tt_int_op(0, OP_EQ, created_cell_format(&cell2, &cc));
554 tt_int_op(cell.command, OP_EQ, cell2.command);
555 tt_mem_op(cell.payload,OP_EQ, cell2.payload, CELL_PAYLOAD_SIZE);
557 /* A good CREATED2 cell with maximal reply */
558 memset(&cell, 0, sizeof(cell));
559 memset(b, 0, sizeof(b));
560 crypto_rand((char*)b, 496);
561 cell.command = CELL_CREATED2;
562 memcpy(cell.payload, "\x01\xF0", 2);
563 memcpy(cell.payload+2, b, 496);
564 tt_int_op(0, OP_EQ, created_cell_parse(&cc, &cell));
565 tt_int_op(CELL_CREATED2, OP_EQ, cc.cell_type);
566 tt_int_op(496, OP_EQ, cc.handshake_len);
567 tt_mem_op(cc.reply,OP_EQ, b, 496);
568 tt_int_op(0, OP_EQ, created_cell_format(&cell2, &cc));
569 tt_int_op(cell.command, OP_EQ, cell2.command);
570 tt_mem_op(cell.payload,OP_EQ, cell2.payload, CELL_PAYLOAD_SIZE);
572 /* Bogus CREATED2 cell: too long! */
573 memset(&cell, 0, sizeof(cell));
574 memset(b, 0, sizeof(b));
575 crypto_rand((char*)b, 496);
576 cell.command = CELL_CREATED2;
577 memcpy(cell.payload, "\x01\xF1", 2);
578 tt_int_op(-1, OP_EQ, created_cell_parse(&cc, &cell));
580 /* Unformattable CREATED2 cell: too long! */
581 cc.handshake_len = 497;
582 tt_int_op(-1, OP_EQ, created_cell_format(&cell2, &cc));
584 done:
588 static void
589 test_cfmt_extend_cells(void *arg)
591 cell_t cell;
592 uint8_t b[512];
593 extend_cell_t ec;
594 create_cell_t *cc = &ec.create_cell;
595 uint8_t p[RELAY_PAYLOAD_SIZE];
596 uint8_t p2[RELAY_PAYLOAD_SIZE];
597 uint8_t p2_cmd;
598 uint16_t p2_len;
599 char *mem_op_hex_tmp = NULL;
601 (void) arg;
603 /* Let's start with a simple EXTEND cell. */
604 memset(p, 0, sizeof(p));
605 memset(b, 0, sizeof(b));
606 crypto_rand((char*)b, TAP_ONIONSKIN_CHALLENGE_LEN);
607 memcpy(p, "\x12\xf4\x00\x01\x01\x02", 6); /* 18 244 0 1 : 258 */
608 memcpy(p+6,b,TAP_ONIONSKIN_CHALLENGE_LEN);
609 memcpy(p+6+TAP_ONIONSKIN_CHALLENGE_LEN, "electroencephalogram", 20);
610 tt_int_op(0, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND,
611 p, 26+TAP_ONIONSKIN_CHALLENGE_LEN));
612 tt_int_op(RELAY_COMMAND_EXTEND, OP_EQ, ec.cell_type);
613 tt_str_op("18.244.0.1", OP_EQ, fmt_addr(&ec.orport_ipv4.addr));
614 tt_int_op(258, OP_EQ, ec.orport_ipv4.port);
615 tt_int_op(AF_UNSPEC, OP_EQ, tor_addr_family(&ec.orport_ipv6.addr));
616 tt_mem_op(ec.node_id,OP_EQ, "electroencephalogram", 20);
617 tt_int_op(cc->cell_type, OP_EQ, CELL_CREATE);
618 tt_int_op(cc->handshake_type, OP_EQ, ONION_HANDSHAKE_TYPE_TAP);
619 tt_int_op(cc->handshake_len, OP_EQ, TAP_ONIONSKIN_CHALLENGE_LEN);
620 tt_mem_op(cc->onionskin,OP_EQ, b, TAP_ONIONSKIN_CHALLENGE_LEN+20);
621 tt_int_op(0, OP_EQ, extend_cell_format(&p2_cmd, &p2_len, p2, &ec));
622 tt_int_op(p2_cmd, OP_EQ, RELAY_COMMAND_EXTEND);
623 tt_int_op(p2_len, OP_EQ, 26+TAP_ONIONSKIN_CHALLENGE_LEN);
624 tt_mem_op(p2,OP_EQ, p, RELAY_PAYLOAD_SIZE);
626 /* Let's do an ntor stuffed in a legacy EXTEND cell */
627 memset(p, 0, sizeof(p));
628 memset(b, 0, sizeof(b));
629 crypto_rand((char*)b, NTOR_ONIONSKIN_LEN);
630 memcpy(p, "\x12\xf4\x00\x01\x01\x02", 6); /* 18 244 0 1 : 258 */
631 memcpy(p+6,"ntorNTORntorNTOR", 16);
632 memcpy(p+22, b, NTOR_ONIONSKIN_LEN);
633 memcpy(p+6+TAP_ONIONSKIN_CHALLENGE_LEN, "electroencephalogram", 20);
634 tt_int_op(0, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND,
635 p, 26+TAP_ONIONSKIN_CHALLENGE_LEN));
636 tt_int_op(RELAY_COMMAND_EXTEND, OP_EQ, ec.cell_type);
637 tt_str_op("18.244.0.1", OP_EQ, fmt_addr(&ec.orport_ipv4.addr));
638 tt_int_op(258, OP_EQ, ec.orport_ipv4.port);
639 tt_int_op(AF_UNSPEC, OP_EQ, tor_addr_family(&ec.orport_ipv6.addr));
640 tt_mem_op(ec.node_id,OP_EQ, "electroencephalogram", 20);
641 tt_int_op(cc->cell_type, OP_EQ, CELL_CREATE2);
642 tt_int_op(cc->handshake_type, OP_EQ, ONION_HANDSHAKE_TYPE_NTOR);
643 tt_int_op(cc->handshake_len, OP_EQ, NTOR_ONIONSKIN_LEN);
644 tt_mem_op(cc->onionskin,OP_EQ, b, NTOR_ONIONSKIN_LEN+20);
645 tt_int_op(0, OP_EQ, extend_cell_format(&p2_cmd, &p2_len, p2, &ec));
646 tt_int_op(p2_cmd, OP_EQ, RELAY_COMMAND_EXTEND);
647 tt_int_op(p2_len, OP_EQ, 26+TAP_ONIONSKIN_CHALLENGE_LEN);
648 tt_mem_op(p2,OP_EQ, p, RELAY_PAYLOAD_SIZE);
649 tt_int_op(0, OP_EQ, create_cell_format_relayed(&cell, cc));
651 /* Now let's do a minimal ntor EXTEND2 cell. */
652 memset(&ec, 0xff, sizeof(ec));
653 memset(p, 0, sizeof(p));
654 memset(b, 0, sizeof(b));
655 crypto_rand((char*)b, NTOR_ONIONSKIN_LEN);
656 /* 2 items; one 18.244.0.1:61681 */
657 memcpy(p, "\x02\x00\x06\x12\xf4\x00\x01\xf0\xf1", 9);
658 /* The other is a digest. */
659 memcpy(p+9, "\x02\x14" "anarchoindividualist", 22);
660 /* Prep for the handshake: type and length */
661 memcpy(p+31, "\x00\x02\x00\x54", 4);
662 memcpy(p+35, b, NTOR_ONIONSKIN_LEN);
663 tt_int_op(0, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
664 p, 35+NTOR_ONIONSKIN_LEN));
665 tt_int_op(RELAY_COMMAND_EXTEND2, OP_EQ, ec.cell_type);
666 tt_str_op("18.244.0.1", OP_EQ, fmt_addr(&ec.orport_ipv4.addr));
667 tt_int_op(61681, OP_EQ, ec.orport_ipv4.port);
668 tt_int_op(AF_UNSPEC, OP_EQ, tor_addr_family(&ec.orport_ipv6.addr));
669 tt_mem_op(ec.node_id,OP_EQ, "anarchoindividualist", 20);
670 tt_int_op(cc->cell_type, OP_EQ, CELL_CREATE2);
671 tt_int_op(cc->handshake_type, OP_EQ, ONION_HANDSHAKE_TYPE_NTOR);
672 tt_int_op(cc->handshake_len, OP_EQ, NTOR_ONIONSKIN_LEN);
673 tt_mem_op(cc->onionskin,OP_EQ, b, NTOR_ONIONSKIN_LEN+20);
674 tt_int_op(0, OP_EQ, extend_cell_format(&p2_cmd, &p2_len, p2, &ec));
675 tt_int_op(p2_cmd, OP_EQ, RELAY_COMMAND_EXTEND2);
676 tt_int_op(p2_len, OP_EQ, 35+NTOR_ONIONSKIN_LEN);
677 tt_mem_op(p2,OP_EQ, p, RELAY_PAYLOAD_SIZE);
679 /* Now let's do a fanciful EXTEND2 cell. */
680 memset(&ec, 0xff, sizeof(ec));
681 memset(p, 0, sizeof(p));
682 memset(b, 0, sizeof(b));
683 crypto_rand((char*)b, 99);
684 /* 4 items; one 18 244 0 1 61681 */
685 memcpy(p, "\x04\x00\x06\x12\xf4\x00\x01\xf0\xf1", 9);
686 /* One is a digest. */
687 memcpy(p+9, "\x02\x14" "anthropomorphization", 22);
688 /* One is an ipv6 address */
689 memcpy(p+31, "\x01\x12\x20\x02\x00\x00\x00\x00\x00\x00"
690 "\x00\x00\x00\x00\x00\xf0\xc5\x1e\x11\x12", 20);
691 /* One is the Konami code. */
692 memcpy(p+51, "\xf0\x20upupdowndownleftrightleftrightba", 34);
693 /* Prep for the handshake: weird type and length */
694 memcpy(p+85, "\x01\x05\x00\x63", 4);
695 memcpy(p+89, b, 99);
696 tt_int_op(0, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2, p, 89+99));
697 tt_int_op(RELAY_COMMAND_EXTEND2, OP_EQ, ec.cell_type);
698 tt_str_op("18.244.0.1", OP_EQ, fmt_addr(&ec.orport_ipv4.addr));
699 tt_int_op(61681, OP_EQ, ec.orport_ipv4.port);
700 tt_str_op("2002::f0:c51e", OP_EQ, fmt_addr(&ec.orport_ipv6.addr));
701 tt_int_op(4370, OP_EQ, ec.orport_ipv6.port);
702 tt_assert(ed25519_public_key_is_zero(&ec.ed_pubkey));
703 tt_mem_op(ec.node_id,OP_EQ, "anthropomorphization", 20);
704 tt_int_op(cc->cell_type, OP_EQ, CELL_CREATE2);
705 tt_int_op(cc->handshake_type, OP_EQ, 0x105);
706 tt_int_op(cc->handshake_len, OP_EQ, 99);
707 tt_mem_op(cc->onionskin,OP_EQ, b, 99+20);
708 tt_int_op(0, OP_EQ, extend_cell_format(&p2_cmd, &p2_len, p2, &ec));
709 tt_int_op(p2_cmd, OP_EQ, RELAY_COMMAND_EXTEND2);
710 /* We'll generate it minus the IPv6 address and minus the konami code */
711 tt_int_op(p2_len, OP_EQ, 89+99-34-20);
712 test_memeq_hex(p2,
713 /* Two items: one that same darn IP address. */
714 "02000612F40001F0F1"
715 /* The next is a digest : anthropomorphization */
716 "0214616e7468726f706f6d6f727068697a6174696f6e"
717 /* Now the handshake prologue */
718 "01050063");
719 tt_mem_op(p2+1+8+22+4,OP_EQ, b, 99+20);
720 tt_int_op(0, OP_EQ, create_cell_format_relayed(&cell, cc));
722 /* Now let's add an ed25519 key to that extend2 cell. */
723 memcpy(ec.ed_pubkey.pubkey,
724 "brownshoesdontmakeit/brownshoesd", 32);
726 /* As before, since we aren't extending by ed25519. */
727 get_options_mutable()->ExtendByEd25519ID = 0;
728 tt_int_op(0, OP_EQ, extend_cell_format(&p2_cmd, &p2_len, p2, &ec));
729 tt_int_op(p2_len, OP_EQ, 89+99-34-20);
730 test_memeq_hex(p2,
731 "02000612F40001F0F1"
732 "0214616e7468726f706f6d6f727068697a6174696f6e"
733 "01050063");
735 /* Now try with the ed25519 ID. */
736 get_options_mutable()->ExtendByEd25519ID = 1;
737 tt_int_op(0, OP_EQ, extend_cell_format(&p2_cmd, &p2_len, p2, &ec));
738 tt_int_op(p2_len, OP_EQ, 89+99-34-20 + 34);
739 test_memeq_hex(p2,
740 "03000612F40001F0F1"
741 "0214616e7468726f706f6d6f727068697a6174696f6e"
742 // ed digest follows:
743 "0320" "62726f776e73686f6573646f6e746d616b656"
744 "9742f62726f776e73686f657364"
745 "01050063");
746 /* Can we parse that? Did the key come through right? */
747 memset(&ec, 0, sizeof(ec));
748 tt_int_op(0, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
749 p2, p2_len));
750 tt_mem_op("brownshoesdontmakeit/brownshoesd", OP_EQ,
751 ec.ed_pubkey.pubkey, 32);
753 /* == Now try parsing some junk */
755 /* Try a too-long handshake */
756 memset(p, 0, sizeof(p));
757 memcpy(p, "\x02\x00\x06\x12\xf4\x00\x01\xf0\xf1", 9);
758 memcpy(p+9, "\x02\x14" "anarchoindividualist", 22);
759 memcpy(p+31, "\xff\xff\x01\xd0", 4);
760 tt_int_op(-1, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
761 p, sizeof(p)));
763 /* Try two identities. */
764 memset(p, 0, sizeof(p));
765 memcpy(p, "\x03\x00\x06\x12\xf4\x00\x01\xf0\xf1", 9);
766 memcpy(p+9, "\x02\x14" "anarchoindividualist", 22);
767 memcpy(p+31, "\x02\x14" "autodepolymerization", 22);
768 memcpy(p+53, "\xff\xff\x00\x10", 4);
769 tt_int_op(-1, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
770 p, sizeof(p)));
772 /* No identities. */
773 memset(p, 0, sizeof(p));
774 memcpy(p, "\x01\x00\x06\x12\xf4\x00\x01\xf0\xf1", 9);
775 memcpy(p+53, "\xff\xff\x00\x10", 4);
776 tt_int_op(-1, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
777 p, sizeof(p)));
779 /* Try a bad IPv4 address (too long, too short)*/
780 memset(p, 0, sizeof(p));
781 memcpy(p, "\x02\x00\x07\x12\xf4\x00\x01\xf0\xf1\xff", 10);
782 memcpy(p+10, "\x02\x14" "anarchoindividualist", 22);
783 memcpy(p+32, "\xff\xff\x00\x10", 4);
784 tt_int_op(-1, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
785 p, sizeof(p)));
786 memset(p, 0, sizeof(p));
787 memcpy(p, "\x02\x00\x05\x12\xf4\x00\x01\xf0", 8);
788 memcpy(p+8, "\x02\x14" "anarchoindividualist", 22);
789 memcpy(p+30, "\xff\xff\x00\x10", 4);
790 tt_int_op(-1, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
791 p, sizeof(p)));
793 /* IPv6 address (too long, too short, no IPv4)*/
794 memset(p, 0, sizeof(p));
795 memcpy(p, "\x03\x00\x06\x12\xf4\x00\x01\xf0\xf1", 9);
796 memcpy(p+9, "\x02\x14" "anarchoindividualist", 22);
797 memcpy(p+31, "\x01\x13" "xxxxxxxxxxxxxxxxYYZ", 19);
798 memcpy(p+50, "\xff\xff\x00\x20", 4);
799 tt_int_op(-1, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
800 p, sizeof(p)));
801 memset(p, 0, sizeof(p));
802 memcpy(p, "\x03\x00\x06\x12\xf4\x00\x01\xf0\xf1", 9);
803 memcpy(p+9, "\x02\x14" "anarchoindividualist", 22);
804 memcpy(p+31, "\x01\x11" "xxxxxxxxxxxxxxxxY", 17);
805 memcpy(p+48, "\xff\xff\x00\x20", 4);
806 tt_int_op(-1, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
807 p, sizeof(p)));
808 memset(p, 0, sizeof(p));
809 memcpy(p, "\x02", 1);
810 memcpy(p+1, "\x02\x14" "anarchoindividualist", 22);
811 memcpy(p+23, "\x01\x12" "xxxxxxxxxxxxxxxxYY", 18);
812 memcpy(p+41, "\xff\xff\x00\x20", 4);
813 tt_int_op(-1, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
814 p, sizeof(p)));
816 /* Running out of space in specifiers */
817 memset(p,0,sizeof(p));
818 memcpy(p, "\x05\x0a\xff", 3);
819 memcpy(p+3+255, "\x0a\xff", 2);
820 tt_int_op(-1, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
821 p, sizeof(p)));
823 /* Fuzz, because why not. */
824 memset(&ec, 0xff, sizeof(ec));
826 int i;
827 memset(p, 0, sizeof(p));
828 for (i = 0; i < 10000; ++i) {
829 int n = crypto_rand_int(sizeof(p));
830 crypto_rand((char *)p, n);
831 extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2, p, n);
835 done:
836 tor_free(mem_op_hex_tmp);
839 static void
840 test_cfmt_extended_cells(void *arg)
842 uint8_t b[512];
843 extended_cell_t ec;
844 created_cell_t *cc = &ec.created_cell;
845 uint8_t p[RELAY_PAYLOAD_SIZE];
846 uint8_t p2[RELAY_PAYLOAD_SIZE];
847 uint8_t p2_cmd;
848 uint16_t p2_len;
849 char *mem_op_hex_tmp = NULL;
851 (void) arg;
853 /* Try a regular EXTENDED cell. */
854 memset(&ec, 0xff, sizeof(ec));
855 memset(p, 0, sizeof(p));
856 memset(b, 0, sizeof(b));
857 crypto_rand((char*)b, TAP_ONIONSKIN_REPLY_LEN);
858 memcpy(p,b,TAP_ONIONSKIN_REPLY_LEN);
859 tt_int_op(0, OP_EQ, extended_cell_parse(&ec, RELAY_COMMAND_EXTENDED, p,
860 TAP_ONIONSKIN_REPLY_LEN));
861 tt_int_op(RELAY_COMMAND_EXTENDED, OP_EQ, ec.cell_type);
862 tt_int_op(cc->cell_type, OP_EQ, CELL_CREATED);
863 tt_int_op(cc->handshake_len, OP_EQ, TAP_ONIONSKIN_REPLY_LEN);
864 tt_mem_op(cc->reply,OP_EQ, b, TAP_ONIONSKIN_REPLY_LEN);
865 tt_int_op(0, OP_EQ, extended_cell_format(&p2_cmd, &p2_len, p2, &ec));
866 tt_int_op(RELAY_COMMAND_EXTENDED, OP_EQ, p2_cmd);
867 tt_int_op(TAP_ONIONSKIN_REPLY_LEN, OP_EQ, p2_len);
868 tt_mem_op(p2,OP_EQ, p, sizeof(p2));
870 /* Try an EXTENDED2 cell */
871 memset(&ec, 0xff, sizeof(ec));
872 memset(p, 0, sizeof(p));
873 memset(b, 0, sizeof(b));
874 crypto_rand((char*)b, 42);
875 memcpy(p,"\x00\x2a",2);
876 memcpy(p+2,b,42);
877 tt_int_op(0, OP_EQ,
878 extended_cell_parse(&ec, RELAY_COMMAND_EXTENDED2, p, 2+42));
879 tt_int_op(RELAY_COMMAND_EXTENDED2, OP_EQ, ec.cell_type);
880 tt_int_op(cc->cell_type, OP_EQ, CELL_CREATED2);
881 tt_int_op(cc->handshake_len, OP_EQ, 42);
882 tt_mem_op(cc->reply,OP_EQ, b, 42+10);
883 tt_int_op(0, OP_EQ, extended_cell_format(&p2_cmd, &p2_len, p2, &ec));
884 tt_int_op(RELAY_COMMAND_EXTENDED2, OP_EQ, p2_cmd);
885 tt_int_op(2+42, OP_EQ, p2_len);
886 tt_mem_op(p2,OP_EQ, p, sizeof(p2));
888 /* Try an almost-too-long EXTENDED2 cell */
889 memcpy(p, "\x01\xf0", 2);
890 tt_int_op(0, OP_EQ,
891 extended_cell_parse(&ec, RELAY_COMMAND_EXTENDED2, p, sizeof(p)));
893 /* Now try a too-long extended2 cell. That's the only misparse I can think
894 * of. */
895 memcpy(p, "\x01\xf1", 2);
896 tt_int_op(-1, OP_EQ,
897 extended_cell_parse(&ec, RELAY_COMMAND_EXTENDED2, p, sizeof(p)));
899 done:
900 tor_free(mem_op_hex_tmp);
903 static void
904 test_cfmt_resolved_cells(void *arg)
906 smartlist_t *addrs = smartlist_new();
907 relay_header_t rh;
908 cell_t cell;
909 int r, errcode;
910 address_ttl_t *a;
912 (void)arg;
913 #define CLEAR_CELL() do { \
914 memset(&cell, 0, sizeof(cell)); \
915 memset(&rh, 0, sizeof(rh)); \
916 } while (0)
917 #define CLEAR_ADDRS() do { \
918 SMARTLIST_FOREACH(addrs, address_ttl_t *, aa_, \
919 address_ttl_free(aa_); ); \
920 smartlist_clear(addrs); \
921 } while (0)
922 #define SET_CELL(s) do { \
923 CLEAR_CELL(); \
924 memcpy(cell.payload + RELAY_HEADER_SIZE, (s), sizeof((s))-1); \
925 rh.length = sizeof((s))-1; \
926 rh.command = RELAY_COMMAND_RESOLVED; \
927 errcode = -1; \
928 } while (0)
930 /* The cell format is one or more answers; each of the form
931 * type [1 byte---0:hostname, 4:ipv4, 6:ipv6, f0:err-transient, f1:err]
932 * length [1 byte]
933 * body [length bytes]
934 * ttl [4 bytes]
937 /* Let's try an empty cell */
938 SET_CELL("");
939 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
940 tt_int_op(errcode, OP_EQ, 0);
941 tt_int_op(r, OP_EQ, 0);
942 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
943 CLEAR_ADDRS(); /* redundant but let's be consistent */
945 /* Cell with one ipv4 addr */
946 SET_CELL("\x04\x04" "\x7f\x00\x02\x0a" "\x00\00\x01\x00");
947 tt_int_op(rh.length, OP_EQ, 10);
948 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
949 tt_int_op(errcode, OP_EQ, 0);
950 tt_int_op(r, OP_EQ, 0);
951 tt_int_op(smartlist_len(addrs), OP_EQ, 1);
952 a = smartlist_get(addrs, 0);
953 tt_str_op(fmt_addr(&a->addr), OP_EQ, "127.0.2.10");
954 tt_ptr_op(a->hostname, OP_EQ, NULL);
955 tt_int_op(a->ttl, OP_EQ, 256);
956 CLEAR_ADDRS();
958 /* Cell with one ipv6 addr */
959 SET_CELL("\x06\x10"
960 "\x20\x02\x90\x90\x00\x00\x00\x00"
961 "\x00\x00\x00\x00\xf0\xf0\xab\xcd"
962 "\x02\00\x00\x01");
963 tt_int_op(rh.length, OP_EQ, 22);
964 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
965 tt_int_op(errcode, OP_EQ, 0);
966 tt_int_op(r, OP_EQ, 0);
967 tt_int_op(smartlist_len(addrs), OP_EQ, 1);
968 a = smartlist_get(addrs, 0);
969 tt_str_op(fmt_addr(&a->addr), OP_EQ, "2002:9090::f0f0:abcd");
970 tt_ptr_op(a->hostname, OP_EQ, NULL);
971 tt_int_op(a->ttl, OP_EQ, 0x2000001);
972 CLEAR_ADDRS();
974 /* Cell with one hostname */
975 SET_CELL("\x00\x11"
976 "motherbrain.zebes"
977 "\x00\00\x00\x00");
978 tt_int_op(rh.length, OP_EQ, 23);
979 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
980 tt_int_op(errcode, OP_EQ, 0);
981 tt_int_op(r, OP_EQ, 0);
982 tt_int_op(smartlist_len(addrs), OP_EQ, 1);
983 a = smartlist_get(addrs, 0);
984 tt_assert(tor_addr_is_null(&a->addr));
985 tt_str_op(a->hostname, OP_EQ, "motherbrain.zebes");
986 tt_int_op(a->ttl, OP_EQ, 0);
987 CLEAR_ADDRS();
989 #define LONG_NAME \
990 "this-hostname-has-255-characters.in-order-to-test-whether-very-long.ho" \
991 "stnames-are-accepted.i-am-putting-it-in-a-macro-because-although.this-" \
992 "function-is-already-very-full.of-copy-and-pasted-stuff.having-this-app" \
993 "ear-more-than-once-would-bother-me-somehow.is"
995 tt_int_op(strlen(LONG_NAME), OP_EQ, 255);
996 SET_CELL("\x00\xff"
997 LONG_NAME
998 "\x00\01\x00\x00");
999 tt_int_op(rh.length, OP_EQ, 261);
1000 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1001 tt_int_op(errcode, OP_EQ, 0);
1002 tt_int_op(r, OP_EQ, 0);
1003 tt_int_op(smartlist_len(addrs), OP_EQ, 1);
1004 a = smartlist_get(addrs, 0);
1005 tt_assert(tor_addr_is_null(&a->addr));
1006 tt_str_op(a->hostname, OP_EQ, LONG_NAME);
1007 tt_int_op(a->ttl, OP_EQ, 65536);
1008 CLEAR_ADDRS();
1010 /* Cells with an error */
1011 SET_CELL("\xf0\x2b"
1012 "I'm sorry, Dave. I'm afraid I can't do that"
1013 "\x00\x11\x22\x33");
1014 tt_int_op(rh.length, OP_EQ, 49);
1015 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1016 tt_int_op(errcode, OP_EQ, RESOLVED_TYPE_ERROR_TRANSIENT);
1017 tt_int_op(r, OP_EQ, 0);
1018 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1019 CLEAR_ADDRS();
1021 SET_CELL("\xf1\x40"
1022 "This hostname is too important for me to allow you to resolve it"
1023 "\x00\x00\x00\x00");
1024 tt_int_op(rh.length, OP_EQ, 70);
1025 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1026 tt_int_op(errcode, OP_EQ, RESOLVED_TYPE_ERROR);
1027 tt_int_op(r, OP_EQ, 0);
1028 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1029 CLEAR_ADDRS();
1031 /* Cell with an unrecognized type */
1032 SET_CELL("\xee\x16"
1033 "fault in the AE35 unit"
1034 "\x09\x09\x01\x01");
1035 tt_int_op(rh.length, OP_EQ, 28);
1036 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1037 tt_int_op(errcode, OP_EQ, 0);
1038 tt_int_op(r, OP_EQ, 0);
1039 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1040 CLEAR_ADDRS();
1042 /* Cell with one of each */
1043 SET_CELL(/* unrecognized: */
1044 "\xee\x16"
1045 "fault in the AE35 unit"
1046 "\x09\x09\x01\x01"
1047 /* error: */
1048 "\xf0\x2b"
1049 "I'm sorry, Dave. I'm afraid I can't do that"
1050 "\x00\x11\x22\x33"
1051 /* IPv6: */
1052 "\x06\x10"
1053 "\x20\x02\x90\x90\x00\x00\x00\x00"
1054 "\x00\x00\x00\x00\xf0\xf0\xab\xcd"
1055 "\x02\00\x00\x01"
1056 /* IPv4: */
1057 "\x04\x04" "\x7f\x00\x02\x0a" "\x00\00\x01\x00"
1058 /* Hostname: */
1059 "\x00\x11"
1060 "motherbrain.zebes"
1061 "\x00\00\x00\x00"
1063 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1064 tt_int_op(errcode, OP_EQ, 0); /* no error reported; we got answers */
1065 tt_int_op(r, OP_EQ, 0);
1066 tt_int_op(smartlist_len(addrs), OP_EQ, 3);
1067 a = smartlist_get(addrs, 0);
1068 tt_str_op(fmt_addr(&a->addr), OP_EQ, "2002:9090::f0f0:abcd");
1069 tt_ptr_op(a->hostname, OP_EQ, NULL);
1070 tt_int_op(a->ttl, OP_EQ, 0x2000001);
1071 a = smartlist_get(addrs, 1);
1072 tt_str_op(fmt_addr(&a->addr), OP_EQ, "127.0.2.10");
1073 tt_ptr_op(a->hostname, OP_EQ, NULL);
1074 tt_int_op(a->ttl, OP_EQ, 256);
1075 a = smartlist_get(addrs, 2);
1076 tt_assert(tor_addr_is_null(&a->addr));
1077 tt_str_op(a->hostname, OP_EQ, "motherbrain.zebes");
1078 tt_int_op(a->ttl, OP_EQ, 0);
1079 CLEAR_ADDRS();
1081 /* Cell with several of similar type */
1082 SET_CELL(/* IPv4 */
1083 "\x04\x04" "\x7f\x00\x02\x0a" "\x00\00\x01\x00"
1084 "\x04\x04" "\x08\x08\x08\x08" "\x00\00\x01\x05"
1085 "\x04\x04" "\x7f\xb0\x02\xb0" "\x00\01\xff\xff"
1086 /* IPv6 */
1087 "\x06\x10"
1088 "\x20\x02\x90\x00\x00\x00\x00\x00"
1089 "\x00\x00\x00\x00\xca\xfe\xf0\x0d"
1090 "\x00\00\x00\x01"
1091 "\x06\x10"
1092 "\x20\x02\x90\x01\x00\x00\x00\x00"
1093 "\x00\x00\x00\x00\x00\xfa\xca\xde"
1094 "\x00\00\x00\x03");
1095 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1096 tt_int_op(errcode, OP_EQ, 0);
1097 tt_int_op(r, OP_EQ, 0);
1098 tt_int_op(smartlist_len(addrs), OP_EQ, 5);
1099 a = smartlist_get(addrs, 0);
1100 tt_str_op(fmt_addr(&a->addr), OP_EQ, "127.0.2.10");
1101 tt_ptr_op(a->hostname, OP_EQ, NULL);
1102 tt_int_op(a->ttl, OP_EQ, 256);
1103 a = smartlist_get(addrs, 1);
1104 tt_str_op(fmt_addr(&a->addr), OP_EQ, "8.8.8.8");
1105 tt_ptr_op(a->hostname, OP_EQ, NULL);
1106 tt_int_op(a->ttl, OP_EQ, 261);
1107 a = smartlist_get(addrs, 2);
1108 tt_str_op(fmt_addr(&a->addr), OP_EQ, "127.176.2.176");
1109 tt_ptr_op(a->hostname, OP_EQ, NULL);
1110 tt_int_op(a->ttl, OP_EQ, 131071);
1111 a = smartlist_get(addrs, 3);
1112 tt_str_op(fmt_addr(&a->addr), OP_EQ, "2002:9000::cafe:f00d");
1113 tt_ptr_op(a->hostname, OP_EQ, NULL);
1114 tt_int_op(a->ttl, OP_EQ, 1);
1115 a = smartlist_get(addrs, 4);
1116 tt_str_op(fmt_addr(&a->addr), OP_EQ, "2002:9001::fa:cade");
1117 tt_ptr_op(a->hostname, OP_EQ, NULL);
1118 tt_int_op(a->ttl, OP_EQ, 3);
1119 CLEAR_ADDRS();
1121 /* Full cell */
1122 #define LONG_NAME2 \
1123 "this-name-has-231-characters.so-that-it-plus-LONG_NAME-can-completely-" \
1124 "fill-up-the-payload-of-a-cell.its-important-to-check-for-the-full-thin" \
1125 "g-case.to-avoid-off-by-one-errors.where-full-things-are-misreported-as" \
1126 ".overflowing-by-one.z"
1128 tt_int_op(strlen(LONG_NAME2), OP_EQ, 231);
1129 SET_CELL("\x00\xff"
1130 LONG_NAME
1131 "\x00\01\x00\x00"
1132 "\x00\xe7"
1133 LONG_NAME2
1134 "\x00\01\x00\x00");
1135 tt_int_op(rh.length, OP_EQ, RELAY_PAYLOAD_SIZE);
1136 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1137 tt_int_op(errcode, OP_EQ, 0);
1138 tt_int_op(r, OP_EQ, 0);
1139 tt_int_op(smartlist_len(addrs), OP_EQ, 2);
1140 a = smartlist_get(addrs, 0);
1141 tt_str_op(a->hostname, OP_EQ, LONG_NAME);
1142 a = smartlist_get(addrs, 1);
1143 tt_str_op(a->hostname, OP_EQ, LONG_NAME2);
1144 CLEAR_ADDRS();
1146 /* BAD CELLS */
1148 /* Invalid length on an IPv4 */
1149 SET_CELL("\x04\x03zzz1234");
1150 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1151 tt_int_op(errcode, OP_EQ, 0);
1152 tt_int_op(r, OP_EQ, -1);
1153 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1154 SET_CELL("\x04\x04" "\x7f\x00\x02\x0a" "\x00\00\x01\x00"
1155 "\x04\x05zzzzz1234");
1156 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1157 tt_int_op(errcode, OP_EQ, 0);
1158 tt_int_op(r, OP_EQ, -1);
1159 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1161 /* Invalid length on an IPv6 */
1162 SET_CELL("\x06\x03zzz1234");
1163 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1164 tt_int_op(errcode, OP_EQ, 0);
1165 tt_int_op(r, OP_EQ, -1);
1166 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1167 SET_CELL("\x04\x04" "\x7f\x00\x02\x0a" "\x00\00\x01\x00"
1168 "\x06\x17wwwwwwwwwwwwwwwww1234");
1169 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1170 tt_int_op(errcode, OP_EQ, 0);
1171 tt_int_op(r, OP_EQ, -1);
1172 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1173 SET_CELL("\x04\x04" "\x7f\x00\x02\x0a" "\x00\00\x01\x00"
1174 "\x06\x10xxxx");
1175 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1176 tt_int_op(errcode, OP_EQ, 0);
1177 tt_int_op(r, OP_EQ, -1);
1178 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1180 /* Empty hostname */
1181 SET_CELL("\x00\x00xxxx");
1182 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1183 tt_int_op(errcode, OP_EQ, 0);
1184 tt_int_op(r, OP_EQ, -1);
1185 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1187 /* rh.length out of range */
1188 CLEAR_CELL();
1189 rh.length = 499;
1190 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1191 tt_int_op(errcode, OP_EQ, 0);
1192 tt_int_op(r, OP_EQ, -1);
1193 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1195 /* Item length extends beyond rh.length */
1196 CLEAR_CELL();
1197 SET_CELL("\x00\xff"
1198 LONG_NAME
1199 "\x00\01\x00\x00");
1200 rh.length -= 1;
1201 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1202 tt_int_op(r, OP_EQ, -1);
1203 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1204 rh.length -= 5;
1205 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1206 tt_int_op(r, OP_EQ, -1);
1207 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1209 SET_CELL("\x04\x04" "\x7f\x00\x02\x0a" "\x00\00\x01\x00");
1210 rh.length -= 1;
1211 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1212 tt_int_op(r, OP_EQ, -1);
1213 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1215 SET_CELL("\xee\x10"
1216 "\x20\x02\x90\x01\x00\x00\x00\x00"
1217 "\x00\x00\x00\x00\x00\xfa\xca\xde"
1218 "\x00\00\x00\x03");
1219 rh.length -= 1;
1220 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1221 tt_int_op(r, OP_EQ, -1);
1222 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1224 /* Truncated item after first character */
1225 SET_CELL("\x04");
1226 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1227 tt_int_op(r, OP_EQ, -1);
1228 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1230 SET_CELL("\xee");
1231 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1232 tt_int_op(r, OP_EQ, -1);
1233 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1235 done:
1236 CLEAR_ADDRS();
1237 CLEAR_CELL();
1238 smartlist_free(addrs);
1239 #undef CLEAR_ADDRS
1240 #undef CLEAR_CELL
1243 static void
1244 test_cfmt_is_destroy(void *arg)
1246 cell_t cell;
1247 packed_cell_t packed;
1248 circid_t circid = 0;
1249 channel_t *chan;
1250 (void)arg;
1252 chan = tor_malloc_zero(sizeof(channel_t));
1254 memset(&cell, 0xff, sizeof(cell));
1255 cell.circ_id = 3003;
1256 cell.command = CELL_RELAY;
1258 cell_pack(&packed, &cell, 0);
1259 chan->wide_circ_ids = 0;
1260 tt_assert(! packed_cell_is_destroy(chan, &packed, &circid));
1261 tt_int_op(circid, OP_EQ, 0);
1263 cell_pack(&packed, &cell, 1);
1264 chan->wide_circ_ids = 1;
1265 tt_assert(! packed_cell_is_destroy(chan, &packed, &circid));
1266 tt_int_op(circid, OP_EQ, 0);
1268 cell.command = CELL_DESTROY;
1270 cell_pack(&packed, &cell, 0);
1271 chan->wide_circ_ids = 0;
1272 tt_assert(packed_cell_is_destroy(chan, &packed, &circid));
1273 tt_int_op(circid, OP_EQ, 3003);
1275 circid = 0;
1276 cell_pack(&packed, &cell, 1);
1277 chan->wide_circ_ids = 1;
1278 tt_assert(packed_cell_is_destroy(chan, &packed, &circid));
1280 done:
1281 tor_free(chan);
1284 #define TEST(name, flags) \
1285 { #name, test_cfmt_ ## name, flags, 0, NULL }
1287 struct testcase_t cell_format_tests[] = {
1288 TEST(relay_header, 0),
1289 TEST(begin_cells, 0),
1290 TEST(connected_cells, 0),
1291 TEST(create_cells, 0),
1292 TEST(created_cells, 0),
1293 TEST(extend_cells, TT_FORK),
1294 TEST(extended_cells, 0),
1295 TEST(resolved_cells, 0),
1296 TEST(is_destroy, 0),
1297 END_OF_TESTCASES