1 /* Copyright (c) 2017, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
6 * \brief Test hidden service cell functionality.
9 #define HS_INTROPOINT_PRIVATE
10 #define HS_SERVICE_PRIVATE
13 #include "test_helpers.h"
14 #include "log_test_helpers.h"
16 #include "crypto_ed25519.h"
18 #include "hs_intropoint.h"
19 #include "hs_service.h"
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. */
27 test_gen_establish_intro_cell(void *arg
)
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
,
69 tt_u64_op(ret
, OP_EQ
, 0);
73 trn_cell_establish_intro_free(cell_in
);
76 /* Mocked ed25519_sign_prefixed() function that always fails :) */
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
) {
90 /** We simulate a failure to create an ESTABLISH_INTRO cell */
92 test_gen_establish_intro_cell_bad(void *arg
)
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();
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);
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
,
125 { "gen_establish_intro_cell_bad", test_gen_establish_intro_cell_bad
, TT_FORK
,