Merge branch 'maint-0.2.9' into maint-0.3.3
[tor.git] / src / test / test_hs_cell.c
blobaed28d3bd26df2db0c54846c7dc1c5804f8ac2cc
1 /* Copyright (c) 2017, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
4 /**
5 * \file test_hs_cell.c
6 * \brief Test hidden service cell functionality.
7 */
9 #define HS_INTROPOINT_PRIVATE
10 #define HS_SERVICE_PRIVATE
12 #include "test.h"
13 #include "test_helpers.h"
14 #include "log_test_helpers.h"
16 #include "crypto_ed25519.h"
17 #include "hs_cell.h"
18 #include "hs_intropoint.h"
19 #include "hs_service.h"
21 /* Trunnel. */
22 #include "hs/cell_establish_intro.h"
24 /** We simulate the creation of an outgoing ESTABLISH_INTRO cell, and then we
25 * parse it from the receiver side. */
26 static void
27 test_gen_establish_intro_cell(void *arg)
29 (void) arg;
30 ssize_t ret;
31 char circ_nonce[DIGEST_LEN] = {0};
32 uint8_t buf[RELAY_PAYLOAD_SIZE];
33 trn_cell_establish_intro_t *cell_in = NULL;
35 crypto_rand(circ_nonce, sizeof(circ_nonce));
37 /* Create outgoing ESTABLISH_INTRO cell and extract its payload so that we
38 attempt to parse it. */
40 /* We only need the auth key pair here. */
41 hs_service_intro_point_t *ip = service_intro_point_new(NULL, 0, 0);
42 /* Auth key pair is generated in the constructor so we are all set for
43 * using this IP object. */
44 ret = hs_cell_build_establish_intro(circ_nonce, ip, buf);
45 service_intro_point_free(ip);
46 tt_u64_op(ret, OP_GT, 0);
49 /* Check the contents of the cell */
51 /* First byte is the auth key type: make sure its correct */
52 tt_int_op(buf[0], OP_EQ, HS_INTRO_AUTH_KEY_TYPE_ED25519);
53 /* Next two bytes is auth key len */
54 tt_int_op(ntohs(get_uint16(buf+1)), OP_EQ, ED25519_PUBKEY_LEN);
55 /* Skip to the number of extensions: no extensions */
56 tt_int_op(buf[35], OP_EQ, 0);
57 /* Skip to the sig len. Make sure it's the size of an ed25519 sig */
58 tt_int_op(ntohs(get_uint16(buf+35+1+32)), OP_EQ, ED25519_SIG_LEN);
61 /* Parse it as the receiver */
63 ret = trn_cell_establish_intro_parse(&cell_in, buf, sizeof(buf));
64 tt_u64_op(ret, OP_GT, 0);
66 ret = verify_establish_intro_cell(cell_in,
67 (const uint8_t *) circ_nonce,
68 sizeof(circ_nonce));
69 tt_u64_op(ret, OP_EQ, 0);
72 done:
73 trn_cell_establish_intro_free(cell_in);
76 /* Mocked ed25519_sign_prefixed() function that always fails :) */
77 static int
78 mock_ed25519_sign_prefixed(ed25519_signature_t *signature_out,
79 const uint8_t *msg, size_t msg_len,
80 const char *prefix_str,
81 const ed25519_keypair_t *keypair) {
82 (void) signature_out;
83 (void) msg;
84 (void) msg_len;
85 (void) prefix_str;
86 (void) keypair;
87 return -1;
90 /** We simulate a failure to create an ESTABLISH_INTRO cell */
91 static void
92 test_gen_establish_intro_cell_bad(void *arg)
94 (void) arg;
95 ssize_t cell_len = 0;
96 trn_cell_establish_intro_t *cell = NULL;
97 char circ_nonce[DIGEST_LEN] = {0};
98 hs_service_intro_point_t *ip = NULL;
100 MOCK(ed25519_sign_prefixed, mock_ed25519_sign_prefixed);
102 crypto_rand(circ_nonce, sizeof(circ_nonce));
104 setup_full_capture_of_logs(LOG_WARN);
105 /* Easiest way to make that function fail is to mock the
106 ed25519_sign_prefixed() function and make it fail. */
107 cell = trn_cell_establish_intro_new();
108 tt_assert(cell);
109 ip = service_intro_point_new(NULL, 0, 0);
110 cell_len = hs_cell_build_establish_intro(circ_nonce, ip, NULL);
111 service_intro_point_free(ip);
112 expect_log_msg_containing("Unable to make signature for "
113 "ESTABLISH_INTRO cell.");
114 teardown_capture_of_logs();
115 tt_i64_op(cell_len, OP_EQ, -1);
117 done:
118 trn_cell_establish_intro_free(cell);
119 UNMOCK(ed25519_sign_prefixed);
122 struct testcase_t hs_cell_tests[] = {
123 { "gen_establish_intro_cell", test_gen_establish_intro_cell, TT_FORK,
124 NULL, NULL },
125 { "gen_establish_intro_cell_bad", test_gen_establish_intro_cell_bad, TT_FORK,
126 NULL, NULL },
128 END_OF_TESTCASES