Line data Source code
1 : /* Copyright (c) 2016-2021, The Tor Project, Inc. */
2 : /* See LICENSE for licensing information */
3 :
4 : #define SHARED_RANDOM_PRIVATE
5 : #define SHARED_RANDOM_STATE_PRIVATE
6 : #define CONFIG_PRIVATE
7 : #define DIRVOTE_PRIVATE
8 :
9 : #include "core/or/or.h"
10 : #include "test/test.h"
11 : #include "app/config/config.h"
12 : #include "lib/crypt_ops/crypto_rand.h"
13 : #include "feature/dirauth/dirvote.h"
14 : #include "feature/dirauth/shared_random.h"
15 : #include "feature/dirauth/shared_random_state.h"
16 : #include "test/log_test_helpers.h"
17 : #include "feature/nodelist/networkstatus.h"
18 : #include "feature/relay/router.h"
19 : #include "feature/relay/routerkeys.h"
20 : #include "feature/nodelist/authcert.h"
21 : #include "feature/nodelist/dirlist.h"
22 : #include "feature/dirparse/authcert_parse.h"
23 : #include "feature/hs_common/shared_random_client.h"
24 : #include "feature/dirauth/voting_schedule.h"
25 :
26 : #include "feature/dirclient/dir_server_st.h"
27 : #include "feature/nodelist/networkstatus_st.h"
28 : #include "app/config/or_state_st.h"
29 :
30 : #ifdef HAVE_SYS_STAT_H
31 : #include <sys/stat.h>
32 : #endif
33 :
34 : #ifdef _WIN32
35 : /* For mkdir */
36 : #include <direct.h>
37 : #endif
38 :
39 : static authority_cert_t *mock_cert;
40 :
41 : static authority_cert_t *
42 11 : get_my_v3_authority_cert_m(void)
43 : {
44 11 : tor_assert(mock_cert);
45 11 : return mock_cert;
46 : }
47 :
48 : static dir_server_t ds;
49 :
50 : static dir_server_t *
51 12 : trusteddirserver_get_by_v3_auth_digest_m(const char *digest)
52 : {
53 12 : (void) digest;
54 : /* The shared random code only need to know if a valid pointer to a dir
55 : * server object has been found so this is safe because it won't use the
56 : * pointer at all never. */
57 12 : return &ds;
58 : }
59 :
60 : /* Setup a minimal dirauth environment by initializing the SR state and
61 : * making sure the options are set to be an authority directory.
62 : * You must only call this function once per process. */
63 : static void
64 8 : init_authority_state(void)
65 : {
66 8 : MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m);
67 :
68 8 : or_options_t *options = get_options_mutable();
69 8 : mock_cert = authority_cert_parse_from_string(AUTHORITY_CERT_1,
70 : strlen(AUTHORITY_CERT_1),
71 : NULL);
72 8 : tt_assert(mock_cert);
73 8 : options->AuthoritativeDir = 1;
74 8 : tt_int_op(load_ed_keys(options, time(NULL)), OP_GE, 0);
75 8 : sr_state_init(0, 0);
76 : /* It's possible a commit has been generated in our state depending on
77 : * the phase we are currently in which uses "now" as the starting
78 : * timestamp. Delete it before we do any testing below. */
79 8 : sr_state_delete_commits();
80 : /* It's also possible that a current SRV has been generated, if we are at
81 : * state transition time. But let's just forget about that SRV. */
82 8 : sr_state_clean_srvs();
83 :
84 8 : done:
85 8 : UNMOCK(get_my_v3_authority_cert);
86 8 : }
87 :
88 : static void
89 1 : test_get_sr_protocol_phase(void *arg)
90 : {
91 1 : time_t the_time;
92 1 : sr_phase_t phase;
93 1 : int retval;
94 :
95 1 : (void) arg;
96 :
97 : /* Initialize SR state */
98 1 : init_authority_state();
99 :
100 : {
101 1 : retval = parse_rfc1123_time("Wed, 20 Apr 2015 23:59:00 UTC", &the_time);
102 1 : tt_int_op(retval, OP_EQ, 0);
103 :
104 1 : phase = get_sr_protocol_phase(the_time);
105 1 : tt_int_op(phase, OP_EQ, SR_PHASE_REVEAL);
106 : }
107 :
108 : {
109 1 : retval = parse_rfc1123_time("Wed, 20 Apr 2015 00:00:00 UTC", &the_time);
110 1 : tt_int_op(retval, OP_EQ, 0);
111 :
112 1 : phase = get_sr_protocol_phase(the_time);
113 1 : tt_int_op(phase, OP_EQ, SR_PHASE_COMMIT);
114 : }
115 :
116 : {
117 1 : retval = parse_rfc1123_time("Wed, 20 Apr 2015 00:00:01 UTC", &the_time);
118 1 : tt_int_op(retval, OP_EQ, 0);
119 :
120 1 : phase = get_sr_protocol_phase(the_time);
121 1 : tt_int_op(phase, OP_EQ, SR_PHASE_COMMIT);
122 : }
123 :
124 : {
125 1 : retval = parse_rfc1123_time("Wed, 20 Apr 2015 11:59:00 UTC", &the_time);
126 1 : tt_int_op(retval, OP_EQ, 0);
127 :
128 1 : phase = get_sr_protocol_phase(the_time);
129 1 : tt_int_op(phase, OP_EQ, SR_PHASE_COMMIT);
130 : }
131 :
132 : {
133 1 : retval = parse_rfc1123_time("Wed, 20 Apr 2015 12:00:00 UTC", &the_time);
134 1 : tt_int_op(retval, OP_EQ, 0);
135 :
136 1 : phase = get_sr_protocol_phase(the_time);
137 1 : tt_int_op(phase, OP_EQ, SR_PHASE_REVEAL);
138 : }
139 :
140 : {
141 1 : retval = parse_rfc1123_time("Wed, 20 Apr 2015 12:00:01 UTC", &the_time);
142 1 : tt_int_op(retval, OP_EQ, 0);
143 :
144 1 : phase = get_sr_protocol_phase(the_time);
145 1 : tt_int_op(phase, OP_EQ, SR_PHASE_REVEAL);
146 : }
147 :
148 : {
149 1 : retval = parse_rfc1123_time("Wed, 20 Apr 2015 13:00:00 UTC", &the_time);
150 1 : tt_int_op(retval, OP_EQ, 0);
151 :
152 1 : phase = get_sr_protocol_phase(the_time);
153 1 : tt_int_op(phase, OP_EQ, SR_PHASE_REVEAL);
154 : }
155 :
156 1 : done:
157 1 : ;
158 1 : }
159 :
160 : static networkstatus_t mock_consensus;
161 :
162 : /* Mock function to immediately return our local 'mock_consensus'. */
163 : static networkstatus_t *
164 13 : mock_networkstatus_get_live_consensus(time_t now)
165 : {
166 13 : (void) now;
167 13 : return &mock_consensus;
168 : }
169 :
170 : /* Mock function to immediately return our local 'mock_consensus'. */
171 : static networkstatus_t *
172 14 : mock_networkstatus_get_reasonably_live_consensus(time_t now, int flavor)
173 : {
174 14 : (void) now;
175 14 : (void) flavor;
176 14 : return &mock_consensus;
177 : }
178 :
179 : static void
180 1 : test_get_state_valid_until_time(void *arg)
181 : {
182 1 : time_t current_time;
183 1 : time_t valid_until_time;
184 1 : char tbuf[ISO_TIME_LEN + 1];
185 1 : int retval;
186 :
187 1 : (void) arg;
188 :
189 1 : MOCK(networkstatus_get_live_consensus,
190 : mock_networkstatus_get_live_consensus);
191 1 : MOCK(networkstatus_get_reasonably_live_consensus,
192 : mock_networkstatus_get_reasonably_live_consensus);
193 :
194 1 : retval = parse_rfc1123_time("Mon, 20 Apr 2015 01:00:00 UTC",
195 : &mock_consensus.fresh_until);
196 1 : tt_int_op(retval, OP_EQ, 0);
197 :
198 1 : retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:00:00 UTC",
199 : &mock_consensus.valid_after);
200 1 : tt_int_op(retval, OP_EQ, 0);
201 :
202 : {
203 : /* Get the valid until time if called at 00:00:01 */
204 1 : retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:00:01 UTC",
205 : ¤t_time);
206 1 : tt_int_op(retval, OP_EQ, 0);
207 1 : dirauth_sched_recalculate_timing(get_options(), current_time);
208 1 : valid_until_time = get_state_valid_until_time(current_time);
209 :
210 : /* Compare it with the correct result */
211 1 : format_iso_time(tbuf, valid_until_time);
212 1 : tt_str_op("2015-04-21 00:00:00", OP_EQ, tbuf);
213 : }
214 :
215 : {
216 1 : retval = parse_rfc1123_time("Mon, 20 Apr 2015 19:22:00 UTC",
217 : ¤t_time);
218 1 : tt_int_op(retval, OP_EQ, 0);
219 1 : dirauth_sched_recalculate_timing(get_options(), current_time);
220 1 : valid_until_time = get_state_valid_until_time(current_time);
221 :
222 1 : format_iso_time(tbuf, valid_until_time);
223 1 : tt_str_op("2015-04-21 00:00:00", OP_EQ, tbuf);
224 : }
225 :
226 : {
227 1 : retval = parse_rfc1123_time("Mon, 20 Apr 2015 23:59:00 UTC",
228 : ¤t_time);
229 1 : tt_int_op(retval, OP_EQ, 0);
230 1 : dirauth_sched_recalculate_timing(get_options(), current_time);
231 1 : valid_until_time = get_state_valid_until_time(current_time);
232 :
233 1 : format_iso_time(tbuf, valid_until_time);
234 1 : tt_str_op("2015-04-21 00:00:00", OP_EQ, tbuf);
235 : }
236 :
237 : {
238 1 : retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:00:00 UTC",
239 : ¤t_time);
240 1 : tt_int_op(retval, OP_EQ, 0);
241 1 : dirauth_sched_recalculate_timing(get_options(), current_time);
242 1 : valid_until_time = get_state_valid_until_time(current_time);
243 :
244 1 : format_iso_time(tbuf, valid_until_time);
245 1 : tt_str_op("2015-04-21 00:00:00", OP_EQ, tbuf);
246 : }
247 :
248 1 : done:
249 1 : UNMOCK(networkstatus_get_reasonably_live_consensus);
250 1 : }
251 :
252 : /** Test the function that calculates the start time of the current SRV
253 : * protocol run. */
254 : static void
255 1 : test_get_start_time_of_current_run(void *arg)
256 : {
257 1 : int retval;
258 1 : char tbuf[ISO_TIME_LEN + 1];
259 1 : time_t current_time, run_start_time;
260 :
261 1 : (void) arg;
262 :
263 1 : MOCK(networkstatus_get_live_consensus,
264 : mock_networkstatus_get_live_consensus);
265 1 : MOCK(networkstatus_get_reasonably_live_consensus,
266 : mock_networkstatus_get_reasonably_live_consensus);
267 :
268 1 : retval = parse_rfc1123_time("Mon, 20 Apr 2015 01:00:00 UTC",
269 : &mock_consensus.fresh_until);
270 1 : tt_int_op(retval, OP_EQ, 0);
271 :
272 1 : retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:00:00 UTC",
273 : &mock_consensus.valid_after);
274 1 : tt_int_op(retval, OP_EQ, 0);
275 :
276 : {
277 : /* Get start time if called at 00:00:01 */
278 1 : retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:00:01 UTC",
279 : ¤t_time);
280 1 : tt_int_op(retval, OP_EQ, 0);
281 1 : dirauth_sched_recalculate_timing(get_options(), current_time);
282 1 : run_start_time = sr_state_get_start_time_of_current_protocol_run();
283 :
284 : /* Compare it with the correct result */
285 1 : format_iso_time(tbuf, run_start_time);
286 1 : tt_str_op("2015-04-20 00:00:00", OP_EQ, tbuf);
287 : }
288 :
289 : {
290 1 : retval = parse_rfc1123_time("Mon, 20 Apr 2015 23:59:59 UTC",
291 : ¤t_time);
292 1 : tt_int_op(retval, OP_EQ, 0);
293 1 : dirauth_sched_recalculate_timing(get_options(), current_time);
294 1 : run_start_time = sr_state_get_start_time_of_current_protocol_run();
295 :
296 : /* Compare it with the correct result */
297 1 : format_iso_time(tbuf, run_start_time);
298 1 : tt_str_op("2015-04-20 00:00:00", OP_EQ, tbuf);
299 : }
300 :
301 : {
302 1 : retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:00:00 UTC",
303 : ¤t_time);
304 1 : tt_int_op(retval, OP_EQ, 0);
305 1 : dirauth_sched_recalculate_timing(get_options(), current_time);
306 1 : run_start_time = sr_state_get_start_time_of_current_protocol_run();
307 :
308 : /* Compare it with the correct result */
309 1 : format_iso_time(tbuf, run_start_time);
310 1 : tt_str_op("2015-04-20 00:00:00", OP_EQ, tbuf);
311 : }
312 :
313 : {
314 : /* We want the local time to be past midnight, but the current consensus to
315 : * have valid-after 23:00 (e.g. this can happen if we fetch a new consensus
316 : * at 00:08 before dircaches have a chance to get the midnight consensus).
317 : *
318 : * Basically, we want to cause a desynch between ns->valid_after (23:00)
319 : * and the voting_schedule.interval_starts (01:00), to make sure that
320 : * sr_state_get_start_time_of_current_protocol_run() handles it gracefully:
321 : * It should actually follow the local consensus time and not the voting
322 : * schedule (which is designed for authority voting purposes). */
323 1 : retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:00:00 UTC",
324 : &mock_consensus.fresh_until);
325 1 : tt_int_op(retval, OP_EQ, 0);
326 :
327 1 : retval = parse_rfc1123_time("Mon, 19 Apr 2015 23:00:00 UTC",
328 : &mock_consensus.valid_after);
329 1 : tt_int_op(retval, OP_EQ, 0);
330 :
331 1 : retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:08:00 UTC",
332 : ¤t_time);
333 1 : tt_int_op(retval, OP_EQ, 0);
334 1 : update_approx_time(current_time);
335 1 : dirauth_sched_recalculate_timing(get_options(), current_time);
336 :
337 1 : run_start_time = sr_state_get_start_time_of_current_protocol_run();
338 :
339 : /* Compare it with the correct result */
340 1 : format_iso_time(tbuf, run_start_time);
341 1 : tt_str_op("2015-04-19 00:00:00", OP_EQ, tbuf);
342 : /* Check that voting_schedule.interval_starts is at 01:00 (see above) */
343 1 : time_t interval_starts = dirauth_sched_get_next_valid_after_time();
344 1 : format_iso_time(tbuf, interval_starts);
345 1 : tt_str_op("2015-04-20 01:00:00", OP_EQ, tbuf);
346 : }
347 :
348 : /* Next test is testing it without a consensus to use the testing voting
349 : * interval . */
350 1 : UNMOCK(networkstatus_get_live_consensus);
351 1 : UNMOCK(networkstatus_get_reasonably_live_consensus);
352 :
353 : /* Now let's alter the voting schedule and check the correctness of the
354 : * function. Voting interval of 10 seconds, means that an SRV protocol run
355 : * takes 10 seconds * 24 rounds = 4 mins */
356 : {
357 1 : or_options_t *options = get_options_mutable();
358 1 : options->V3AuthVotingInterval = 10;
359 1 : options->TestingV3AuthInitialVotingInterval = 10;
360 1 : retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:15:32 UTC",
361 : ¤t_time);
362 1 : tt_int_op(retval, OP_EQ, 0);
363 1 : dirauth_sched_recalculate_timing(get_options(), current_time);
364 1 : run_start_time = sr_state_get_start_time_of_current_protocol_run();
365 :
366 : /* Compare it with the correct result */
367 1 : format_iso_time(tbuf, run_start_time);
368 1 : tt_str_op("2015-04-20 00:12:00", OP_EQ, tbuf);
369 : }
370 :
371 1 : done:
372 1 : ;
373 1 : }
374 :
375 : /** Do some rudimentary consistency checks between the functions that
376 : * understand the shared random protocol schedule */
377 : static void
378 1 : test_get_start_time_functions(void *arg)
379 : {
380 1 : (void) arg;
381 1 : int retval;
382 :
383 1 : MOCK(networkstatus_get_reasonably_live_consensus,
384 : mock_networkstatus_get_reasonably_live_consensus);
385 :
386 1 : retval = parse_rfc1123_time("Mon, 20 Apr 2015 01:00:00 UTC",
387 : &mock_consensus.fresh_until);
388 1 : tt_int_op(retval, OP_EQ, 0);
389 :
390 1 : retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:00:00 UTC",
391 : &mock_consensus.valid_after);
392 1 : tt_int_op(retval, OP_EQ, 0);
393 1 : time_t now = mock_consensus.valid_after;
394 :
395 1 : dirauth_sched_recalculate_timing(get_options(), now);
396 1 : time_t start_time_of_protocol_run =
397 1 : sr_state_get_start_time_of_current_protocol_run();
398 1 : tt_assert(start_time_of_protocol_run);
399 :
400 : /* Check that the round start time of the beginning of the run, is itself */
401 1 : tt_int_op(dirauth_sched_get_cur_valid_after_time(), OP_EQ,
402 : start_time_of_protocol_run);
403 :
404 1 : done:
405 1 : UNMOCK(networkstatus_get_reasonably_live_consensus);
406 1 : }
407 :
408 : static void
409 1 : test_get_sr_protocol_duration(void *arg)
410 : {
411 1 : (void) arg;
412 :
413 : /* Check that by default an SR phase is 12 hours */
414 1 : tt_int_op(sr_state_get_phase_duration(), OP_EQ, 12*60*60);
415 1 : tt_int_op(sr_state_get_protocol_run_duration(), OP_EQ, 24*60*60);
416 :
417 : /* Now alter the voting interval and check that the SR phase is 2 mins long
418 : * if voting happens every 10 seconds (10*12 seconds = 2 mins) */
419 1 : or_options_t *options = get_options_mutable();
420 1 : options->V3AuthVotingInterval = 10;
421 1 : tt_int_op(sr_state_get_phase_duration(), OP_EQ, 2*60);
422 1 : tt_int_op(sr_state_get_protocol_run_duration(), OP_EQ, 4*60);
423 :
424 1 : done: ;
425 1 : }
426 :
427 : /* In this test we are going to generate a sr_commit_t object and validate
428 : * it. We first generate our values, and then we parse them as if they were
429 : * received from the network. After we parse both the commit and the reveal,
430 : * we verify that they indeed match. */
431 : static void
432 1 : test_sr_commit(void *arg)
433 : {
434 1 : authority_cert_t *auth_cert = NULL;
435 1 : time_t now = time(NULL);
436 1 : sr_commit_t *our_commit = NULL;
437 1 : smartlist_t *args = smartlist_new();
438 1 : sr_commit_t *parsed_commit = NULL;
439 :
440 1 : (void) arg;
441 :
442 : { /* Setup a minimal dirauth environment for this test */
443 1 : or_options_t *options = get_options_mutable();
444 :
445 1 : auth_cert = authority_cert_parse_from_string(AUTHORITY_CERT_1,
446 : strlen(AUTHORITY_CERT_1),
447 : NULL);
448 1 : tt_assert(auth_cert);
449 :
450 1 : options->AuthoritativeDir = 1;
451 1 : tt_int_op(load_ed_keys(options, time(NULL)), OP_GE, 0);
452 : }
453 :
454 : /* Generate our commit object and validate it has the appropriate field
455 : * that we can then use to build a representation that we'll find in a
456 : * vote coming from the network. */
457 : {
458 1 : sr_commit_t test_commit;
459 1 : our_commit = sr_generate_our_commit(now, auth_cert);
460 1 : tt_assert(our_commit);
461 : /* Default and only supported algorithm for now. */
462 1 : tt_assert(our_commit->alg == DIGEST_SHA3_256);
463 : /* We should have a reveal value. */
464 1 : tt_assert(commit_has_reveal_value(our_commit));
465 : /* We should have a random value. */
466 1 : tt_assert(!fast_mem_is_zero((char *) our_commit->random_number,
467 : sizeof(our_commit->random_number)));
468 : /* Commit and reveal timestamp should be the same. */
469 1 : tt_u64_op(our_commit->commit_ts, OP_EQ, our_commit->reveal_ts);
470 : /* We should have a hashed reveal. */
471 1 : tt_assert(!fast_mem_is_zero(our_commit->hashed_reveal,
472 : sizeof(our_commit->hashed_reveal)));
473 : /* Do we have a valid encoded commit and reveal. Note the following only
474 : * tests if the generated values are correct. Their could be a bug in
475 : * the decode function but we test them separately. */
476 1 : tt_int_op(0, OP_EQ, reveal_decode(our_commit->encoded_reveal,
477 : &test_commit));
478 1 : tt_int_op(0, OP_EQ, commit_decode(our_commit->encoded_commit,
479 : &test_commit));
480 1 : tt_int_op(0, OP_EQ, verify_commit_and_reveal(our_commit));
481 : }
482 :
483 : /* Let's make sure our verify commit and reveal function works. We'll
484 : * make it fail a bit with known failure case. */
485 : {
486 : /* Copy our commit so we don't alter it for the rest of testing. */
487 1 : sr_commit_t test_commit;
488 1 : memcpy(&test_commit, our_commit, sizeof(test_commit));
489 :
490 : /* Timestamp MUST match. */
491 1 : test_commit.commit_ts = test_commit.reveal_ts - 42;
492 1 : setup_full_capture_of_logs(LOG_WARN);
493 1 : tt_int_op(-1, OP_EQ, verify_commit_and_reveal(&test_commit));
494 1 : expect_log_msg_containing("doesn't match reveal timestamp");
495 1 : teardown_capture_of_logs();
496 1 : memcpy(&test_commit, our_commit, sizeof(test_commit));
497 1 : tt_int_op(0, OP_EQ, verify_commit_and_reveal(&test_commit));
498 :
499 : /* Hashed reveal must match the H(encoded_reveal). */
500 1 : memset(test_commit.hashed_reveal, 'X',
501 : sizeof(test_commit.hashed_reveal));
502 1 : setup_full_capture_of_logs(LOG_WARN);
503 1 : tt_int_op(-1, OP_EQ, verify_commit_and_reveal(&test_commit));
504 1 : expect_single_log_msg_containing("doesn't match the commit value");
505 1 : teardown_capture_of_logs();
506 1 : memcpy(&test_commit, our_commit, sizeof(test_commit));
507 1 : tt_int_op(0, OP_EQ, verify_commit_and_reveal(&test_commit));
508 : }
509 :
510 : /* We'll build a list of values from our commit that our parsing function
511 : * takes from a vote line and see if we can parse it correctly. */
512 : {
513 1 : smartlist_add_strdup(args, "1");
514 1 : smartlist_add_strdup(args,
515 : crypto_digest_algorithm_get_name(our_commit->alg));
516 1 : smartlist_add_strdup(args, sr_commit_get_rsa_fpr(our_commit));
517 1 : smartlist_add_strdup(args, our_commit->encoded_commit);
518 1 : smartlist_add_strdup(args, our_commit->encoded_reveal);
519 1 : parsed_commit = sr_parse_commit(args);
520 1 : tt_assert(parsed_commit);
521 : /* That parsed commit should be _EXACTLY_ like our original commit (we
522 : * have to explicitly set the valid flag though). */
523 1 : parsed_commit->valid = 1;
524 1 : tt_mem_op(parsed_commit, OP_EQ, our_commit, sizeof(*parsed_commit));
525 : /* Cleanup */
526 : }
527 :
528 1 : done:
529 1 : teardown_capture_of_logs();
530 6 : SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
531 1 : smartlist_free(args);
532 1 : sr_commit_free(our_commit);
533 1 : sr_commit_free(parsed_commit);
534 1 : authority_cert_free(auth_cert);
535 1 : }
536 :
537 : /* Test the encoding and decoding function for commit and reveal values. */
538 : static void
539 1 : test_encoding(void *arg)
540 : {
541 1 : (void) arg;
542 1 : int ret;
543 : /* Random number is 32 bytes. */
544 1 : char raw_rand[32];
545 1 : time_t ts = 1454333590;
546 1 : char hashed_rand[DIGEST256_LEN], hashed_reveal[DIGEST256_LEN];
547 1 : sr_commit_t parsed_commit;
548 :
549 : /* Those values were generated by sr_commit_calc_ref.py where the random
550 : * value is 32 'A' and timestamp is the one in ts. */
551 1 : static const char *encoded_reveal =
552 : "AAAAAFavXpZJxbwTupvaJCTeIUCQmOPxAMblc7ChL5H2nZKuGchdaA==";
553 1 : static const char *encoded_commit =
554 : "AAAAAFavXpbkBMzMQG7aNoaGLFNpm2Wkk1ozXhuWWqL//GynltxVAg==";
555 :
556 : /* Set up our raw random bytes array. */
557 1 : memset(raw_rand, 'A', sizeof(raw_rand));
558 : /* Hash random number because we don't expose bytes of the RNG. */
559 1 : ret = crypto_digest256(hashed_rand, raw_rand,
560 : sizeof(raw_rand), SR_DIGEST_ALG);
561 1 : tt_int_op(0, OP_EQ, ret);
562 : /* Hash reveal value. */
563 1 : tt_int_op(SR_REVEAL_BASE64_LEN, OP_EQ, strlen(encoded_reveal));
564 1 : ret = crypto_digest256(hashed_reveal, encoded_reveal,
565 : strlen(encoded_reveal), SR_DIGEST_ALG);
566 1 : tt_int_op(0, OP_EQ, ret);
567 1 : tt_int_op(SR_COMMIT_BASE64_LEN, OP_EQ, strlen(encoded_commit));
568 :
569 : /* Test our commit/reveal decode functions. */
570 : {
571 : /* Test the reveal encoded value. */
572 1 : tt_int_op(0, OP_EQ, reveal_decode(encoded_reveal, &parsed_commit));
573 1 : tt_u64_op(ts, OP_EQ, parsed_commit.reveal_ts);
574 1 : tt_mem_op(hashed_rand, OP_EQ, parsed_commit.random_number,
575 1 : sizeof(hashed_rand));
576 :
577 : /* Test the commit encoded value. */
578 1 : memset(&parsed_commit, 0, sizeof(parsed_commit));
579 1 : tt_int_op(0, OP_EQ, commit_decode(encoded_commit, &parsed_commit));
580 1 : tt_u64_op(ts, OP_EQ, parsed_commit.commit_ts);
581 1 : tt_mem_op(encoded_commit, OP_EQ, parsed_commit.encoded_commit,
582 1 : sizeof(parsed_commit.encoded_commit));
583 1 : tt_mem_op(hashed_reveal, OP_EQ, parsed_commit.hashed_reveal,
584 1 : sizeof(hashed_reveal));
585 : }
586 :
587 : /* Test our commit/reveal encode functions. */
588 : {
589 : /* Test the reveal encode. */
590 1 : char encoded[SR_REVEAL_BASE64_LEN + 1];
591 1 : parsed_commit.reveal_ts = ts;
592 1 : memcpy(parsed_commit.random_number, hashed_rand,
593 : sizeof(parsed_commit.random_number));
594 1 : ret = reveal_encode(&parsed_commit, encoded, sizeof(encoded));
595 1 : tt_int_op(SR_REVEAL_BASE64_LEN, OP_EQ, ret);
596 1 : tt_mem_op(encoded_reveal, OP_EQ, encoded, strlen(encoded_reveal));
597 : }
598 :
599 : {
600 : /* Test the commit encode. */
601 1 : char encoded[SR_COMMIT_BASE64_LEN + 1];
602 1 : parsed_commit.commit_ts = ts;
603 1 : memcpy(parsed_commit.hashed_reveal, hashed_reveal,
604 : sizeof(parsed_commit.hashed_reveal));
605 1 : ret = commit_encode(&parsed_commit, encoded, sizeof(encoded));
606 1 : tt_int_op(SR_COMMIT_BASE64_LEN, OP_EQ, ret);
607 1 : tt_mem_op(encoded_commit, OP_EQ, encoded, strlen(encoded_commit));
608 : }
609 :
610 1 : done:
611 1 : ;
612 1 : }
613 :
614 : /** Setup some SRVs in our SR state.
615 : * If <b>also_current</b> is set, then set both current and previous SRVs.
616 : * Otherwise, just set the previous SRV. (And clear the current SRV.)
617 : *
618 : * You must call sr_state_free_all() to free the state at the end of each test
619 : * function (on pass or fail). */
620 : static void
621 15 : test_sr_setup_srv(int also_current)
622 : {
623 : /* Clear both SRVs before starting.
624 : * In 0.3.5 and earlier, sr_state_set_previous_srv() and
625 : * sr_state_set_current_srv() do not free() the old srvs. */
626 15 : sr_state_clean_srvs();
627 :
628 15 : sr_srv_t *srv = tor_malloc_zero(sizeof(sr_srv_t));
629 15 : srv->num_reveals = 42;
630 15 : memcpy(srv->value,
631 : "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ",
632 : sizeof(srv->value));
633 :
634 15 : sr_state_set_previous_srv(srv);
635 :
636 15 : if (also_current) {
637 13 : srv = tor_malloc_zero(sizeof(sr_srv_t));
638 13 : srv->num_reveals = 128;
639 13 : memcpy(srv->value,
640 : "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN",
641 : sizeof(srv->value));
642 :
643 13 : sr_state_set_current_srv(srv);
644 : }
645 15 : }
646 :
647 : /* Test anything that has to do with SR protocol and vote. */
648 : static void
649 1 : test_vote(void *arg)
650 : {
651 1 : int ret;
652 1 : time_t now = time(NULL);
653 1 : sr_commit_t *our_commit = NULL;
654 :
655 1 : (void) arg;
656 :
657 1 : MOCK(trusteddirserver_get_by_v3_auth_digest,
658 : trusteddirserver_get_by_v3_auth_digest_m);
659 :
660 : { /* Setup a minimal dirauth environment for this test */
661 1 : init_authority_state();
662 : /* Set ourself in reveal phase so we can parse the reveal value in the
663 : * vote as well. */
664 1 : set_sr_phase(SR_PHASE_REVEAL);
665 : }
666 :
667 : /* Generate our commit object and validate it has the appropriate field
668 : * that we can then use to build a representation that we'll find in a
669 : * vote coming from the network. */
670 : {
671 1 : sr_commit_t *saved_commit;
672 1 : our_commit = sr_generate_our_commit(now, mock_cert);
673 1 : tt_assert(our_commit);
674 1 : sr_state_add_commit(our_commit);
675 : /* Make sure it's there. */
676 1 : saved_commit = sr_state_get_commit(our_commit->rsa_identity);
677 1 : tt_assert(saved_commit);
678 : }
679 :
680 : /* Also setup the SRVs */
681 1 : test_sr_setup_srv(1);
682 :
683 : { /* Now test the vote generation */
684 1 : smartlist_t *chunks = smartlist_new();
685 1 : smartlist_t *tokens = smartlist_new();
686 : /* Get our vote line and validate it. */
687 1 : char *lines = sr_get_string_for_vote();
688 1 : tt_assert(lines);
689 : /* Split the lines. We expect 2 here. */
690 1 : ret = smartlist_split_string(chunks, lines, "\n", SPLIT_IGNORE_BLANK, 0);
691 1 : tt_int_op(ret, OP_EQ, 4);
692 1 : tt_str_op(smartlist_get(chunks, 0), OP_EQ, "shared-rand-participate");
693 : /* Get our commitment line and will validate it against our commit. The
694 : * format is as follow:
695 : * "shared-rand-commitment" SP version SP algname SP identity
696 : * SP COMMIT [SP REVEAL] NL
697 : */
698 1 : char *commit_line = smartlist_get(chunks, 1);
699 1 : tt_assert(commit_line);
700 1 : ret = smartlist_split_string(tokens, commit_line, " ", 0, 0);
701 1 : tt_int_op(ret, OP_EQ, 6);
702 1 : tt_str_op(smartlist_get(tokens, 0), OP_EQ, "shared-rand-commit");
703 1 : tt_str_op(smartlist_get(tokens, 1), OP_EQ, "1");
704 1 : tt_str_op(smartlist_get(tokens, 2), OP_EQ,
705 : crypto_digest_algorithm_get_name(DIGEST_SHA3_256));
706 1 : char digest[DIGEST_LEN];
707 1 : base16_decode(digest, sizeof(digest), smartlist_get(tokens, 3),
708 : HEX_DIGEST_LEN);
709 1 : tt_mem_op(digest, OP_EQ, our_commit->rsa_identity, sizeof(digest));
710 1 : tt_str_op(smartlist_get(tokens, 4), OP_EQ, our_commit->encoded_commit);
711 1 : tt_str_op(smartlist_get(tokens, 5), OP_EQ, our_commit->encoded_reveal)
712 : ;
713 : /* Finally, does this vote line creates a valid commit object? */
714 1 : smartlist_t *args = smartlist_new();
715 1 : smartlist_add(args, smartlist_get(tokens, 1));
716 1 : smartlist_add(args, smartlist_get(tokens, 2));
717 1 : smartlist_add(args, smartlist_get(tokens, 3));
718 1 : smartlist_add(args, smartlist_get(tokens, 4));
719 1 : smartlist_add(args, smartlist_get(tokens, 5));
720 1 : sr_commit_t *parsed_commit = sr_parse_commit(args);
721 1 : tt_assert(parsed_commit);
722 : /* Set valid flag explicitly here to compare since it's not set by
723 : * simply parsing the commit. */
724 1 : parsed_commit->valid = 1;
725 1 : tt_mem_op(parsed_commit, OP_EQ, our_commit, sizeof(*our_commit));
726 :
727 : /* minor cleanup */
728 7 : SMARTLIST_FOREACH(tokens, char *, s, tor_free(s));
729 1 : smartlist_clear(tokens);
730 :
731 : /* Now test the previous SRV */
732 1 : char *prev_srv_line = smartlist_get(chunks, 2);
733 1 : tt_assert(prev_srv_line);
734 1 : ret = smartlist_split_string(tokens, prev_srv_line, " ", 0, 0);
735 1 : tt_int_op(ret, OP_EQ, 3);
736 1 : tt_str_op(smartlist_get(tokens, 0), OP_EQ, "shared-rand-previous-value");
737 1 : tt_str_op(smartlist_get(tokens, 1), OP_EQ, "42");
738 1 : tt_str_op(smartlist_get(tokens, 2), OP_EQ,
739 : "WlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlo=");
740 :
741 : /* minor cleanup */
742 4 : SMARTLIST_FOREACH(tokens, char *, s, tor_free(s));
743 1 : smartlist_clear(tokens);
744 :
745 : /* Now test the current SRV */
746 1 : char *current_srv_line = smartlist_get(chunks, 3);
747 1 : tt_assert(current_srv_line);
748 1 : ret = smartlist_split_string(tokens, current_srv_line, " ", 0, 0);
749 1 : tt_int_op(ret, OP_EQ, 3);
750 1 : tt_str_op(smartlist_get(tokens, 0), OP_EQ, "shared-rand-current-value");
751 1 : tt_str_op(smartlist_get(tokens, 1), OP_EQ, "128");
752 1 : tt_str_op(smartlist_get(tokens, 2), OP_EQ,
753 : "Tk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk4=");
754 :
755 : /* Clean up */
756 1 : sr_commit_free(parsed_commit);
757 5 : SMARTLIST_FOREACH(chunks, char *, s, tor_free(s));
758 1 : smartlist_free(chunks);
759 4 : SMARTLIST_FOREACH(tokens, char *, s, tor_free(s));
760 1 : smartlist_free(tokens);
761 1 : smartlist_clear(args);
762 1 : smartlist_free(args);
763 1 : tor_free(lines);
764 : }
765 :
766 1 : done:
767 1 : UNMOCK(trusteddirserver_get_by_v3_auth_digest);
768 1 : sr_state_free_all();
769 1 : }
770 :
771 : static const char *sr_state_str = "Version 1\n"
772 : "TorVersion 0.2.9.0-alpha-dev\n"
773 : "ValidAfter 2037-04-19 07:16:00\n"
774 : "ValidUntil 2037-04-20 07:16:00\n"
775 : "Commit 1 sha3-256 FA3CEC2C99DC68D3166B9B6E4FA21A4026C2AB1C "
776 : "7M8GdubCAAdh7WUG0DiwRyxTYRKji7HATa7LLJEZ/UAAAAAAVmfUSg== "
777 : "AAAAAFZn1EojfIheIw42bjK3VqkpYyjsQFSbv/dxNna3Q8hUEPKpOw==\n"
778 : "Commit 1 sha3-256 41E89EDFBFBA44983E21F18F2230A4ECB5BFB543 "
779 : "17aUsYuMeRjd2N1r8yNyg7aHqRa6gf4z7QPoxxAZbp0AAAAAVmfUSg==\n"
780 : "Commit 1 sha3-256 36637026573A04110CF3E6B1D201FB9A98B88734 "
781 : "DDDYtripvdOU+XPEUm5xpU64d9IURSds1xSwQsgeB8oAAAAAVmfUSg==\n"
782 : "SharedRandPreviousValue 4 qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqo=\n"
783 : "SharedRandCurrentValue 3 8dWeW12KEzTGEiLGgO1UVJ7Z91CekoRcxt6Q9KhnOFI=\n";
784 :
785 : /** Create an SR disk state, parse it and validate that the parsing went
786 : * well. Yes! */
787 : static void
788 1 : test_state_load_from_disk(void *arg)
789 : {
790 1 : int ret;
791 1 : char *dir = tor_strdup(get_fname("test_sr_state"));
792 1 : char *sr_state_path = tor_strdup(get_fname("test_sr_state/sr_state"));
793 1 : sr_state_t *the_sr_state = NULL;
794 :
795 1 : (void) arg;
796 :
797 1 : MOCK(trusteddirserver_get_by_v3_auth_digest,
798 : trusteddirserver_get_by_v3_auth_digest_m);
799 :
800 : /* First try with a nonexistent path. */
801 1 : ret = disk_state_load_from_disk_impl("NONEXISTENTNONEXISTENT");
802 1 : tt_int_op(ret, OP_EQ, -ENOENT);
803 :
804 : /* Now create a mock state directory and state file */
805 : #ifdef _WIN32
806 : ret = mkdir(dir);
807 : #else
808 1 : ret = mkdir(dir, 0700);
809 : #endif
810 1 : tt_int_op(ret, OP_EQ, 0);
811 1 : ret = write_str_to_file(sr_state_path, sr_state_str, 0);
812 1 : tt_int_op(ret, OP_EQ, 0);
813 :
814 : /* Try to load the directory itself. Should fail. */
815 1 : ret = disk_state_load_from_disk_impl(dir);
816 1 : tt_int_op(ret, OP_LT, 0);
817 :
818 : /* State should be non-existent at this point. */
819 1 : the_sr_state = get_sr_state();
820 1 : tt_ptr_op(the_sr_state, OP_EQ, NULL);
821 :
822 : /* Now try to load the correct file! */
823 1 : ret = disk_state_load_from_disk_impl(sr_state_path);
824 1 : tt_int_op(ret, OP_EQ, 0);
825 :
826 : /* Check the content of the state */
827 : /* XXX check more deeply!!! */
828 1 : the_sr_state = get_sr_state();
829 1 : tt_assert(the_sr_state);
830 1 : tt_assert(the_sr_state->version == 1);
831 1 : tt_assert(digestmap_size(the_sr_state->commits) == 3);
832 1 : tt_assert(the_sr_state->current_srv);
833 1 : tt_assert(the_sr_state->current_srv->num_reveals == 3);
834 1 : tt_assert(the_sr_state->previous_srv);
835 :
836 : /* XXX Now also try loading corrupted state files and make sure parsing
837 : fails */
838 :
839 1 : done:
840 1 : tor_free(dir);
841 1 : tor_free(sr_state_path);
842 1 : UNMOCK(trusteddirserver_get_by_v3_auth_digest);
843 1 : }
844 :
845 : /** Generate three specially crafted commits (based on the test
846 : * vector at sr_srv_calc_ref.py). Helper of test_sr_compute_srv(). */
847 : static void
848 1 : test_sr_setup_commits(void)
849 : {
850 1 : time_t now = time(NULL);
851 1 : sr_commit_t *commit_a, *commit_b, *commit_c, *commit_d;
852 1 : sr_commit_t *place_holder = tor_malloc_zero(sizeof(*place_holder));
853 1 : authority_cert_t *auth_cert = NULL;
854 :
855 : { /* Setup a minimal dirauth environment for this test */
856 1 : or_options_t *options = get_options_mutable();
857 :
858 1 : auth_cert = authority_cert_parse_from_string(AUTHORITY_CERT_1,
859 : strlen(AUTHORITY_CERT_1),
860 : NULL);
861 1 : tt_assert(auth_cert);
862 :
863 1 : options->AuthoritativeDir = 1;
864 1 : tt_int_op(0, OP_EQ, load_ed_keys(options, now));
865 : }
866 :
867 : /* Generate three dummy commits according to sr_srv_calc_ref.py . Then
868 : register them to the SR state. Also register a fourth commit 'd' with no
869 : reveal info, to make sure that it will get ignored during SRV
870 : calculation. */
871 :
872 : { /* Commit from auth 'a' */
873 1 : commit_a = sr_generate_our_commit(now, auth_cert);
874 1 : tt_assert(commit_a);
875 :
876 : /* Do some surgery on the commit */
877 1 : memset(commit_a->rsa_identity, 'A', sizeof(commit_a->rsa_identity));
878 1 : base16_encode(commit_a->rsa_identity_hex,
879 : sizeof(commit_a->rsa_identity_hex), commit_a->rsa_identity,
880 : sizeof(commit_a->rsa_identity));
881 1 : strlcpy(commit_a->encoded_reveal,
882 : "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
883 : sizeof(commit_a->encoded_reveal));
884 1 : memcpy(commit_a->hashed_reveal,
885 : "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
886 : sizeof(commit_a->hashed_reveal));
887 : }
888 :
889 : { /* Commit from auth 'b' */
890 1 : commit_b = sr_generate_our_commit(now, auth_cert);
891 1 : tt_assert(commit_b);
892 :
893 : /* Do some surgery on the commit */
894 1 : memset(commit_b->rsa_identity, 'B', sizeof(commit_b->rsa_identity));
895 1 : base16_encode(commit_b->rsa_identity_hex,
896 : sizeof(commit_b->rsa_identity_hex), commit_b->rsa_identity,
897 : sizeof(commit_b->rsa_identity));
898 1 : strlcpy(commit_b->encoded_reveal,
899 : "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
900 : sizeof(commit_b->encoded_reveal));
901 1 : memcpy(commit_b->hashed_reveal,
902 : "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
903 : sizeof(commit_b->hashed_reveal));
904 : }
905 :
906 : { /* Commit from auth 'c' */
907 1 : commit_c = sr_generate_our_commit(now, auth_cert);
908 1 : tt_assert(commit_c);
909 :
910 : /* Do some surgery on the commit */
911 1 : memset(commit_c->rsa_identity, 'C', sizeof(commit_c->rsa_identity));
912 1 : base16_encode(commit_c->rsa_identity_hex,
913 : sizeof(commit_c->rsa_identity_hex), commit_c->rsa_identity,
914 : sizeof(commit_c->rsa_identity));
915 1 : strlcpy(commit_c->encoded_reveal,
916 : "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC",
917 : sizeof(commit_c->encoded_reveal));
918 1 : memcpy(commit_c->hashed_reveal,
919 : "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC",
920 : sizeof(commit_c->hashed_reveal));
921 : }
922 :
923 : { /* Commit from auth 'd' */
924 1 : commit_d = sr_generate_our_commit(now, auth_cert);
925 1 : tt_assert(commit_d);
926 :
927 : /* Do some surgery on the commit */
928 1 : memset(commit_d->rsa_identity, 'D', sizeof(commit_d->rsa_identity));
929 1 : base16_encode(commit_d->rsa_identity_hex,
930 : sizeof(commit_d->rsa_identity_hex), commit_d->rsa_identity,
931 : sizeof(commit_d->rsa_identity));
932 1 : strlcpy(commit_d->encoded_reveal,
933 : "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD",
934 : sizeof(commit_d->encoded_reveal));
935 1 : memcpy(commit_d->hashed_reveal,
936 : "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD",
937 : sizeof(commit_d->hashed_reveal));
938 : /* Clean up its reveal info */
939 1 : memcpy(place_holder, commit_d, sizeof(*place_holder));
940 1 : memset(commit_d->encoded_reveal, 0, sizeof(commit_d->encoded_reveal));
941 1 : tt_assert(!commit_has_reveal_value(commit_d));
942 : }
943 :
944 : /* Register commits to state (during commit phase) */
945 1 : set_sr_phase(SR_PHASE_COMMIT);
946 1 : save_commit_to_state(commit_a);
947 1 : save_commit_to_state(commit_b);
948 1 : save_commit_to_state(commit_c);
949 1 : save_commit_to_state(commit_d);
950 1 : tt_int_op(digestmap_size(get_sr_state()->commits), OP_EQ, 4);
951 :
952 : /* Now during REVEAL phase save commit D by restoring its reveal. */
953 1 : set_sr_phase(SR_PHASE_REVEAL);
954 1 : save_commit_to_state(place_holder);
955 1 : place_holder = NULL;
956 1 : tt_str_op(commit_d->encoded_reveal, OP_EQ,
957 : "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD");
958 : /* Go back to an empty encoded reveal value. */
959 1 : memset(commit_d->encoded_reveal, 0, sizeof(commit_d->encoded_reveal));
960 1 : memset(commit_d->random_number, 0, sizeof(commit_d->random_number));
961 1 : tt_assert(!commit_has_reveal_value(commit_d));
962 :
963 1 : done:
964 1 : tor_free(place_holder);
965 1 : authority_cert_free(auth_cert);
966 1 : }
967 :
968 : /** Verify that the SRV generation procedure is proper by testing it against
969 : * the test vector from ./sr_srv_calc_ref.py. */
970 : static void
971 1 : test_sr_compute_srv(void *arg)
972 : {
973 1 : (void) arg;
974 1 : const sr_srv_t *current_srv = NULL;
975 :
976 : #define SRV_TEST_VECTOR \
977 : "2A9B1D6237DAB312A40F575DA85C147663E7ED3F80E9555395F15B515C74253D"
978 :
979 1 : MOCK(trusteddirserver_get_by_v3_auth_digest,
980 : trusteddirserver_get_by_v3_auth_digest_m);
981 :
982 1 : init_authority_state();
983 :
984 : /* Setup the commits for this unittest */
985 1 : test_sr_setup_commits();
986 1 : test_sr_setup_srv(0);
987 :
988 : /* Now switch to reveal phase */
989 1 : set_sr_phase(SR_PHASE_REVEAL);
990 :
991 : /* Compute the SRV */
992 1 : sr_compute_srv();
993 :
994 : /* Check the result against the test vector */
995 1 : current_srv = sr_state_get_current_srv();
996 1 : tt_assert(current_srv);
997 1 : tt_u64_op(current_srv->num_reveals, OP_EQ, 3);
998 1 : tt_str_op(hex_str((char*)current_srv->value, 32),
999 : OP_EQ,
1000 : SRV_TEST_VECTOR);
1001 :
1002 1 : done:
1003 1 : UNMOCK(trusteddirserver_get_by_v3_auth_digest);
1004 1 : sr_state_free_all();
1005 1 : }
1006 :
1007 : /** Return a minimal vote document with a current SRV value set to
1008 : * <b>srv</b>. */
1009 : static networkstatus_t *
1010 9 : get_test_vote_with_curr_srv(const char *srv)
1011 : {
1012 9 : networkstatus_t *vote = tor_malloc_zero(sizeof(networkstatus_t));
1013 :
1014 9 : vote->type = NS_TYPE_VOTE;
1015 9 : vote->sr_info.participate = 1;
1016 9 : vote->sr_info.current_srv = tor_malloc_zero(sizeof(sr_srv_t));
1017 9 : vote->sr_info.current_srv->num_reveals = 42;
1018 9 : memcpy(vote->sr_info.current_srv->value,
1019 : srv,
1020 : sizeof(vote->sr_info.current_srv->value));
1021 :
1022 9 : return vote;
1023 : }
1024 :
1025 : /* Test the function that picks the right SRV given a bunch of votes. Make sure
1026 : * that the function returns an SRV iff the majority/agreement requirements are
1027 : * met. */
1028 : static void
1029 1 : test_sr_get_majority_srv_from_votes(void *arg)
1030 : {
1031 1 : sr_srv_t *chosen_srv;
1032 1 : smartlist_t *votes = smartlist_new();
1033 :
1034 : #define SRV_1 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
1035 : #define SRV_2 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
1036 :
1037 1 : (void) arg;
1038 :
1039 1 : init_authority_state();
1040 : /* Make sure our SRV is fresh so we can consider the super majority with
1041 : * the consensus params of number of agreements needed. */
1042 1 : sr_state_set_fresh_srv();
1043 :
1044 : /* The test relies on the dirauth list being initialized. */
1045 1 : clear_dir_servers();
1046 1 : add_default_trusted_dir_authorities(V3_DIRINFO);
1047 :
1048 : { /* Prepare voting environment with just a single vote. */
1049 1 : networkstatus_t *vote = get_test_vote_with_curr_srv(SRV_1);
1050 1 : smartlist_add(votes, vote);
1051 : }
1052 :
1053 : /* Since it's only one vote with an SRV, it should not achieve majority and
1054 : hence no SRV will be returned. */
1055 1 : chosen_srv = get_majority_srv_from_votes(votes, 1);
1056 1 : tt_ptr_op(chosen_srv, OP_EQ, NULL);
1057 :
1058 : { /* Now put in 8 more votes. Let SRV_1 have majority. */
1059 : int i;
1060 : /* Now 7 votes believe in SRV_1 */
1061 4 : for (i = 0; i < 3; i++) {
1062 3 : networkstatus_t *vote = get_test_vote_with_curr_srv(SRV_1);
1063 3 : smartlist_add(votes, vote);
1064 : }
1065 : /* and 2 votes believe in SRV_2 */
1066 3 : for (i = 0; i < 2; i++) {
1067 2 : networkstatus_t *vote = get_test_vote_with_curr_srv(SRV_2);
1068 2 : smartlist_add(votes, vote);
1069 : }
1070 4 : for (i = 0; i < 3; i++) {
1071 3 : networkstatus_t *vote = get_test_vote_with_curr_srv(SRV_1);
1072 3 : smartlist_add(votes, vote);
1073 : }
1074 :
1075 1 : tt_int_op(smartlist_len(votes), OP_EQ, 9);
1076 : }
1077 :
1078 : /* Now we achieve majority for SRV_1, but not the AuthDirNumSRVAgreements
1079 : requirement. So still not picking an SRV. */
1080 1 : set_num_srv_agreements(8);
1081 1 : chosen_srv = get_majority_srv_from_votes(votes, 1);
1082 1 : tt_ptr_op(chosen_srv, OP_EQ, NULL);
1083 :
1084 : /* We will now lower the AuthDirNumSRVAgreements requirement by tweaking the
1085 : * consensus parameter and we will try again. This time it should work. */
1086 1 : set_num_srv_agreements(7);
1087 1 : chosen_srv = get_majority_srv_from_votes(votes, 1);
1088 1 : tt_assert(chosen_srv);
1089 1 : tt_u64_op(chosen_srv->num_reveals, OP_EQ, 42);
1090 1 : tt_mem_op(chosen_srv->value, OP_EQ, SRV_1, sizeof(chosen_srv->value));
1091 :
1092 1 : done:
1093 10 : SMARTLIST_FOREACH(votes, networkstatus_t *, vote,
1094 : networkstatus_vote_free(vote));
1095 1 : smartlist_free(votes);
1096 1 : }
1097 :
1098 : /* Testing sr_srv_dup(). */
1099 : static void
1100 1 : test_sr_svr_dup(void *arg)
1101 : {
1102 1 : (void)arg;
1103 :
1104 1 : sr_srv_t *srv = NULL, *dup_srv = NULL;
1105 1 : const char *srv_value =
1106 : "1BDB7C3E973936E4D13A49F37C859B3DC69C429334CF9412E3FEF6399C52D47A";
1107 1 : srv = tor_malloc_zero(sizeof(*srv));
1108 1 : srv->num_reveals = 42;
1109 1 : memcpy(srv->value, srv_value, sizeof(srv->value));
1110 1 : dup_srv = sr_srv_dup(srv);
1111 1 : tt_assert(dup_srv);
1112 1 : tt_u64_op(dup_srv->num_reveals, OP_EQ, srv->num_reveals);
1113 1 : tt_mem_op(dup_srv->value, OP_EQ, srv->value, sizeof(srv->value));
1114 :
1115 1 : done:
1116 1 : tor_free(srv);
1117 1 : tor_free(dup_srv);
1118 1 : }
1119 :
1120 : /* Testing commitments_are_the_same(). Currently, the check is to test the
1121 : * value of the encoded commit so let's make sure that actually works. */
1122 : static void
1123 1 : test_commitments_are_the_same(void *arg)
1124 : {
1125 1 : (void)arg;
1126 :
1127 : /* Payload of 57 bytes that is the length of sr_commit_t->encoded_commit.
1128 : * 56 bytes of payload and a NUL terminated byte at the end ('\x00')
1129 : * which comes down to SR_COMMIT_BASE64_LEN + 1. */
1130 1 : const char *payload =
1131 : "\x5d\xb9\x60\xb6\xcc\x51\x68\x52\x31\xd9\x88\x88\x71\x71\xe0\x30"
1132 : "\x59\x55\x7f\xcd\x61\xc0\x4b\x05\xb8\xcd\xc1\x48\xe9\xcd\x16\x1f"
1133 : "\x70\x15\x0c\xfc\xd3\x1a\x75\xd0\x93\x6c\xc4\xe0\x5c\xbe\xe2\x18"
1134 : "\xc7\xaf\x72\xb6\x7c\x9b\x52\x00";
1135 1 : sr_commit_t commit1, commit2;
1136 1 : memcpy(commit1.encoded_commit, payload, sizeof(commit1.encoded_commit));
1137 1 : memcpy(commit2.encoded_commit, payload, sizeof(commit2.encoded_commit));
1138 1 : tt_int_op(commitments_are_the_same(&commit1, &commit2), OP_EQ, 1);
1139 : /* Let's corrupt one of them. */
1140 1 : memset(commit1.encoded_commit, 'A', sizeof(commit1.encoded_commit));
1141 1 : tt_int_op(commitments_are_the_same(&commit1, &commit2), OP_EQ, 0);
1142 :
1143 1 : done:
1144 1 : return;
1145 : }
1146 :
1147 : /* Testing commit_is_authoritative(). */
1148 : static void
1149 1 : test_commit_is_authoritative(void *arg)
1150 : {
1151 1 : (void)arg;
1152 :
1153 1 : crypto_pk_t *k = crypto_pk_new();
1154 1 : char digest[DIGEST_LEN];
1155 1 : sr_commit_t commit;
1156 :
1157 1 : tt_assert(!crypto_pk_generate_key(k));
1158 :
1159 1 : tt_int_op(0, OP_EQ, crypto_pk_get_digest(k, digest));
1160 1 : memcpy(commit.rsa_identity, digest, sizeof(commit.rsa_identity));
1161 1 : tt_int_op(commit_is_authoritative(&commit, digest), OP_EQ, 1);
1162 : /* Change the pubkey. */
1163 1 : memset(commit.rsa_identity, 0, sizeof(commit.rsa_identity));
1164 1 : tt_int_op(commit_is_authoritative(&commit, digest), OP_EQ, 0);
1165 :
1166 1 : done:
1167 1 : crypto_pk_free(k);
1168 1 : }
1169 :
1170 : static void
1171 1 : test_get_phase_str(void *arg)
1172 : {
1173 1 : (void)arg;
1174 :
1175 1 : tt_str_op(get_phase_str(SR_PHASE_REVEAL), OP_EQ, "reveal");
1176 1 : tt_str_op(get_phase_str(SR_PHASE_COMMIT), OP_EQ, "commit");
1177 :
1178 1 : done:
1179 1 : return;
1180 : }
1181 :
1182 : /* Test utils that depend on authority state */
1183 : static void
1184 1 : test_utils_auth(void *arg)
1185 : {
1186 1 : (void)arg;
1187 1 : init_authority_state();
1188 :
1189 : /* Testing phase transition */
1190 : {
1191 1 : set_sr_phase(SR_PHASE_COMMIT);
1192 1 : tt_int_op(is_phase_transition(SR_PHASE_REVEAL), OP_EQ, 1);
1193 1 : tt_int_op(is_phase_transition(SR_PHASE_COMMIT), OP_EQ, 0);
1194 1 : set_sr_phase(SR_PHASE_REVEAL);
1195 1 : tt_int_op(is_phase_transition(SR_PHASE_REVEAL), OP_EQ, 0);
1196 1 : tt_int_op(is_phase_transition(SR_PHASE_COMMIT), OP_EQ, 1);
1197 : /* Junk. */
1198 1 : tt_int_op(is_phase_transition(42), OP_EQ, 1);
1199 : }
1200 :
1201 : /* Testing get, set, delete, clean SRVs */
1202 :
1203 : {
1204 : /* Just set the previous SRV */
1205 1 : test_sr_setup_srv(0);
1206 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
1207 1 : tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
1208 1 : state_del_previous_srv();
1209 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
1210 1 : tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
1211 : }
1212 :
1213 : {
1214 : /* Delete the SRVs one at a time */
1215 1 : test_sr_setup_srv(1);
1216 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
1217 1 : tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
1218 1 : state_del_current_srv();
1219 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
1220 1 : tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
1221 1 : state_del_previous_srv();
1222 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
1223 1 : tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
1224 :
1225 : /* And in the opposite order */
1226 1 : test_sr_setup_srv(1);
1227 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
1228 1 : tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
1229 1 : state_del_previous_srv();
1230 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
1231 1 : tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
1232 1 : state_del_current_srv();
1233 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
1234 1 : tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
1235 :
1236 : /* And both at once */
1237 1 : test_sr_setup_srv(1);
1238 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
1239 1 : tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
1240 1 : sr_state_clean_srvs();
1241 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
1242 1 : tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
1243 :
1244 : /* And do the gets and sets multiple times */
1245 1 : test_sr_setup_srv(1);
1246 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
1247 1 : tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
1248 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
1249 1 : tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
1250 1 : state_del_previous_srv();
1251 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
1252 1 : tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
1253 1 : state_del_previous_srv();
1254 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
1255 1 : tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
1256 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
1257 1 : tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
1258 1 : sr_state_clean_srvs();
1259 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
1260 1 : tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
1261 1 : state_del_current_srv();
1262 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
1263 1 : tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
1264 1 : sr_state_clean_srvs();
1265 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
1266 1 : tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
1267 1 : state_del_current_srv();
1268 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
1269 1 : tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
1270 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
1271 1 : tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
1272 : }
1273 :
1274 : {
1275 : /* Now set the SRVs to NULL instead */
1276 1 : test_sr_setup_srv(1);
1277 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
1278 1 : tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
1279 1 : sr_state_set_current_srv(NULL);
1280 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
1281 1 : tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
1282 1 : sr_state_set_previous_srv(NULL);
1283 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
1284 1 : tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
1285 :
1286 : /* And in the opposite order */
1287 1 : test_sr_setup_srv(1);
1288 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
1289 1 : tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
1290 1 : sr_state_set_previous_srv(NULL);
1291 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
1292 1 : tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
1293 1 : sr_state_set_current_srv(NULL);
1294 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
1295 1 : tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
1296 :
1297 : /* And both at once */
1298 1 : test_sr_setup_srv(1);
1299 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
1300 1 : tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
1301 1 : sr_state_clean_srvs();
1302 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
1303 1 : tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
1304 :
1305 : /* And do the gets and sets multiple times */
1306 1 : test_sr_setup_srv(1);
1307 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
1308 1 : tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
1309 1 : sr_state_set_previous_srv(NULL);
1310 1 : sr_state_set_previous_srv(NULL);
1311 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
1312 1 : tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
1313 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
1314 1 : tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
1315 1 : sr_state_set_current_srv(NULL);
1316 1 : sr_state_set_previous_srv(NULL);
1317 1 : sr_state_set_current_srv(NULL);
1318 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
1319 1 : tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
1320 : }
1321 :
1322 : {
1323 : /* Now copy the values across */
1324 1 : test_sr_setup_srv(1);
1325 : /* Check that the pointers are non-NULL, and different from each other */
1326 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
1327 1 : tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
1328 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_NE,
1329 : sr_state_get_current_srv());
1330 : /* Check that the content is different */
1331 1 : tt_mem_op(sr_state_get_previous_srv(), OP_NE,
1332 1 : sr_state_get_current_srv(), sizeof(sr_srv_t));
1333 : /* Set the current to the previous: the protocol goes the other way */
1334 1 : sr_state_set_current_srv(sr_srv_dup(sr_state_get_previous_srv()));
1335 : /* Check that the pointers are non-NULL, and different from each other */
1336 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
1337 1 : tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
1338 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_NE,
1339 : sr_state_get_current_srv());
1340 : /* Check that the content is the same */
1341 1 : tt_mem_op(sr_state_get_previous_srv(), OP_EQ,
1342 1 : sr_state_get_current_srv(), sizeof(sr_srv_t));
1343 : }
1344 :
1345 : {
1346 : /* Now copy a value onto itself */
1347 1 : test_sr_setup_srv(1);
1348 : /* Check that the pointers are non-NULL, and different from each other */
1349 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
1350 1 : tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
1351 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_NE,
1352 : sr_state_get_current_srv());
1353 : /* Take a copy of the old value */
1354 1 : sr_srv_t old_current_srv;
1355 1 : memcpy(&old_current_srv, sr_state_get_current_srv(), sizeof(sr_srv_t));
1356 : /* Check that the content is different */
1357 1 : tt_mem_op(sr_state_get_previous_srv(), OP_NE,
1358 1 : sr_state_get_current_srv(), sizeof(sr_srv_t));
1359 : /* Set the current to the current: the protocol never replaces an SRV with
1360 : * the same value */
1361 1 : sr_state_set_current_srv(sr_srv_dup(sr_state_get_current_srv()));
1362 : /* Check that the pointers are non-NULL, and different from each other */
1363 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
1364 1 : tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
1365 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_NE,
1366 : sr_state_get_current_srv());
1367 : /* Check that the content is different between current and previous */
1368 1 : tt_mem_op(sr_state_get_previous_srv(), OP_NE,
1369 1 : sr_state_get_current_srv(), sizeof(sr_srv_t));
1370 : /* Check that the content is the same as the old content */
1371 1 : tt_mem_op(&old_current_srv, OP_EQ,
1372 1 : sr_state_get_current_srv(), sizeof(sr_srv_t));
1373 : }
1374 :
1375 : /* I don't think we can say "expect a BUG()" in our tests. */
1376 : #if 0
1377 : {
1378 : /* Now copy a value onto itself without sr_srv_dup().
1379 : * This should fail with a BUG() warning. */
1380 : test_sr_setup_srv(1);
1381 : sr_state_set_current_srv(sr_state_get_current_srv());
1382 : sr_state_set_previous_srv(sr_state_get_previous_srv());
1383 : }
1384 : #endif /* 0 */
1385 :
1386 1 : done:
1387 1 : sr_state_free_all();
1388 1 : }
1389 :
1390 : static void
1391 1 : test_state_transition(void *arg)
1392 : {
1393 1 : sr_state_t *state = NULL;
1394 1 : time_t now = time(NULL);
1395 1 : sr_srv_t *cur = NULL;
1396 :
1397 1 : (void) arg;
1398 :
1399 : { /* Setup a minimal dirauth environment for this test */
1400 1 : init_authority_state();
1401 1 : state = get_sr_state();
1402 1 : tt_assert(state);
1403 : }
1404 :
1405 : /* Test our state reset for a new protocol run. */
1406 : {
1407 : /* Add a commit to the state so we can test if the reset cleans the
1408 : * commits. Also, change all params that we expect to be updated. */
1409 1 : sr_commit_t *commit = sr_generate_our_commit(now, mock_cert);
1410 1 : tt_assert(commit);
1411 1 : sr_state_add_commit(commit);
1412 1 : tt_int_op(digestmap_size(state->commits), OP_EQ, 1);
1413 : /* Let's test our delete feature. */
1414 1 : sr_state_delete_commits();
1415 1 : tt_int_op(digestmap_size(state->commits), OP_EQ, 0);
1416 : /* Add it back so we can continue the rest of the test because after
1417 : * deleting our commit will be freed so generate a new one. */
1418 1 : commit = sr_generate_our_commit(now, mock_cert);
1419 1 : tt_assert(commit);
1420 1 : sr_state_add_commit(commit);
1421 1 : tt_int_op(digestmap_size(state->commits), OP_EQ, 1);
1422 1 : state->n_reveal_rounds = 42;
1423 1 : state->n_commit_rounds = 43;
1424 1 : state->n_protocol_runs = 44;
1425 1 : reset_state_for_new_protocol_run(now);
1426 1 : tt_int_op(state->n_reveal_rounds, OP_EQ, 0);
1427 1 : tt_int_op(state->n_commit_rounds, OP_EQ, 0);
1428 1 : tt_u64_op(state->n_protocol_runs, OP_EQ, 45);
1429 1 : tt_int_op(digestmap_size(state->commits), OP_EQ, 0);
1430 : }
1431 :
1432 : /* Test SRV rotation in our state. */
1433 : {
1434 1 : test_sr_setup_srv(1);
1435 1 : tt_assert(sr_state_get_current_srv());
1436 : /* Take a copy of the data, because the state owns the pointer */
1437 1 : cur = sr_srv_dup(sr_state_get_current_srv());
1438 1 : tt_assert(cur);
1439 : /* After, the previous SRV should be the same as the old current SRV, and
1440 : * the current SRV should be set to NULL */
1441 1 : state_rotate_srv();
1442 1 : tt_mem_op(sr_state_get_previous_srv(), OP_EQ, cur, sizeof(sr_srv_t));
1443 1 : tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
1444 1 : sr_state_clean_srvs();
1445 1 : tor_free(cur);
1446 : }
1447 :
1448 : /* New protocol run. */
1449 : {
1450 : /* Setup some new SRVs so we can confirm that a new protocol run
1451 : * actually makes them rotate and compute new ones. */
1452 1 : test_sr_setup_srv(1);
1453 1 : tt_assert(sr_state_get_current_srv());
1454 : /* Take a copy of the data, because the state owns the pointer */
1455 1 : cur = sr_srv_dup(sr_state_get_current_srv());
1456 1 : set_sr_phase(SR_PHASE_REVEAL);
1457 1 : MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m);
1458 1 : new_protocol_run(now);
1459 1 : UNMOCK(get_my_v3_authority_cert);
1460 : /* Rotation happened. */
1461 1 : tt_mem_op(sr_state_get_previous_srv(), OP_EQ, cur, sizeof(sr_srv_t));
1462 : /* We are going into COMMIT phase so we had to rotate our SRVs. Usually
1463 : * our current SRV would be NULL but a new protocol run should make us
1464 : * compute a new SRV. */
1465 1 : tt_assert(sr_state_get_current_srv());
1466 : /* Also, make sure we did change the current. */
1467 1 : tt_mem_op(sr_state_get_current_srv(), OP_NE, cur, sizeof(sr_srv_t));
1468 : /* We should have our commitment alone. */
1469 1 : tt_int_op(digestmap_size(state->commits), OP_EQ, 1);
1470 1 : tt_int_op(state->n_reveal_rounds, OP_EQ, 0);
1471 1 : tt_int_op(state->n_commit_rounds, OP_EQ, 0);
1472 : /* 46 here since we were at 45 just before. */
1473 1 : tt_u64_op(state->n_protocol_runs, OP_EQ, 46);
1474 1 : tor_free(cur);
1475 : }
1476 :
1477 : /* Cleanup of SRVs. */
1478 : {
1479 1 : sr_state_clean_srvs();
1480 1 : tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
1481 1 : tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
1482 : }
1483 :
1484 1 : done:
1485 1 : tor_free(cur);
1486 1 : sr_state_free_all();
1487 1 : }
1488 :
1489 : static void
1490 1 : test_keep_commit(void *arg)
1491 : {
1492 1 : char fp[FINGERPRINT_LEN + 1];
1493 1 : sr_commit_t *commit = NULL, *dup_commit = NULL;
1494 1 : sr_state_t *state;
1495 1 : time_t now = time(NULL);
1496 1 : crypto_pk_t *k = NULL;
1497 :
1498 1 : (void) arg;
1499 :
1500 1 : MOCK(trusteddirserver_get_by_v3_auth_digest,
1501 : trusteddirserver_get_by_v3_auth_digest_m);
1502 :
1503 : {
1504 1 : k = pk_generate(1);
1505 : /* Setup a minimal dirauth environment for this test */
1506 : /* Have a key that is not the one from our commit. */
1507 1 : init_authority_state();
1508 1 : state = get_sr_state();
1509 : }
1510 :
1511 1 : crypto_rand((char*)fp, sizeof(fp));
1512 :
1513 : /* Test this very important function that tells us if we should keep a
1514 : * commit or not in our state. Most of it depends on the phase and what's
1515 : * in the commit so we'll change the commit as we go. */
1516 1 : commit = sr_generate_our_commit(now, mock_cert);
1517 1 : tt_assert(commit);
1518 : /* Set us in COMMIT phase for starter. */
1519 1 : set_sr_phase(SR_PHASE_COMMIT);
1520 : /* We should never keep a commit from a non authoritative authority. */
1521 1 : tt_int_op(should_keep_commit(commit, fp, SR_PHASE_COMMIT), OP_EQ, 0);
1522 : /* This should NOT be kept because it has a reveal value in it. */
1523 1 : tt_assert(commit_has_reveal_value(commit));
1524 1 : tt_int_op(should_keep_commit(commit, commit->rsa_identity,
1525 : SR_PHASE_COMMIT), OP_EQ, 0);
1526 : /* Add it to the state which should return to not keep it. */
1527 1 : sr_state_add_commit(commit);
1528 1 : tt_int_op(should_keep_commit(commit, commit->rsa_identity,
1529 : SR_PHASE_COMMIT), OP_EQ, 0);
1530 : /* Remove it from state so we can continue our testing. */
1531 1 : digestmap_remove(state->commits, commit->rsa_identity);
1532 : /* Let's remove our reveal value which should make it OK to keep it. */
1533 1 : memset(commit->encoded_reveal, 0, sizeof(commit->encoded_reveal));
1534 1 : tt_int_op(should_keep_commit(commit, commit->rsa_identity,
1535 : SR_PHASE_COMMIT), OP_EQ, 1);
1536 :
1537 : /* Let's reset our commit and go into REVEAL phase. */
1538 1 : sr_commit_free(commit);
1539 1 : commit = sr_generate_our_commit(now, mock_cert);
1540 1 : tt_assert(commit);
1541 : /* Dup the commit so we have one with and one without a reveal value. */
1542 1 : dup_commit = tor_malloc_zero(sizeof(*dup_commit));
1543 1 : memcpy(dup_commit, commit, sizeof(*dup_commit));
1544 1 : memset(dup_commit->encoded_reveal, 0, sizeof(dup_commit->encoded_reveal));
1545 1 : set_sr_phase(SR_PHASE_REVEAL);
1546 : /* We should never keep a commit from a non authoritative authority. */
1547 1 : tt_int_op(should_keep_commit(commit, fp, SR_PHASE_REVEAL), OP_EQ, 0);
1548 : /* We shouldn't accept a commit that is not in our state. */
1549 1 : tt_int_op(should_keep_commit(commit, commit->rsa_identity,
1550 : SR_PHASE_REVEAL), OP_EQ, 0);
1551 : /* Important to add the commit _without_ the reveal here. */
1552 1 : sr_state_add_commit(dup_commit);
1553 1 : tt_int_op(digestmap_size(state->commits), OP_EQ, 1);
1554 : /* Our commit should be valid that is authoritative, contains a reveal, be
1555 : * in the state and commitment and reveal values match. */
1556 1 : tt_int_op(should_keep_commit(commit, commit->rsa_identity,
1557 : SR_PHASE_REVEAL), OP_EQ, 1);
1558 : /* The commit shouldn't be kept if it's not verified that is no matching
1559 : * hashed reveal. */
1560 : {
1561 : /* Let's save the hash reveal so we can restore it. */
1562 1 : sr_commit_t place_holder;
1563 1 : memcpy(place_holder.hashed_reveal, commit->hashed_reveal,
1564 : sizeof(place_holder.hashed_reveal));
1565 1 : memset(commit->hashed_reveal, 0, sizeof(commit->hashed_reveal));
1566 1 : setup_full_capture_of_logs(LOG_WARN);
1567 1 : tt_int_op(should_keep_commit(commit, commit->rsa_identity,
1568 : SR_PHASE_REVEAL), OP_EQ, 0);
1569 1 : expect_log_msg_containing("doesn't match the commit value.");
1570 1 : expect_log_msg_containing("has an invalid reveal value.");
1571 1 : assert_log_predicate(mock_saved_log_n_entries() == 2,
1572 : ("expected 2 log entries"));
1573 1 : teardown_capture_of_logs();
1574 1 : memcpy(commit->hashed_reveal, place_holder.hashed_reveal,
1575 : sizeof(commit->hashed_reveal));
1576 : }
1577 : /* We shouldn't keep a commit that has no reveal. */
1578 1 : tt_int_op(should_keep_commit(dup_commit, dup_commit->rsa_identity,
1579 : SR_PHASE_REVEAL), OP_EQ, 0);
1580 : /* We must not keep a commit that is not the same from the commit phase. */
1581 1 : memset(commit->encoded_commit, 0, sizeof(commit->encoded_commit));
1582 1 : tt_int_op(should_keep_commit(commit, commit->rsa_identity,
1583 : SR_PHASE_REVEAL), OP_EQ, 0);
1584 :
1585 1 : done:
1586 1 : teardown_capture_of_logs();
1587 1 : sr_commit_free(commit);
1588 1 : sr_commit_free(dup_commit);
1589 1 : crypto_pk_free(k);
1590 1 : UNMOCK(trusteddirserver_get_by_v3_auth_digest);
1591 1 : }
1592 :
1593 : static void
1594 1 : test_state_update(void *arg)
1595 : {
1596 1 : time_t commit_phase_time = 1452076000;
1597 1 : time_t reveal_phase_time = 1452086800;
1598 1 : sr_state_t *state;
1599 :
1600 1 : (void) arg;
1601 :
1602 : {
1603 1 : init_authority_state();
1604 1 : state = get_sr_state();
1605 1 : set_sr_phase(SR_PHASE_COMMIT);
1606 : /* We'll cheat a bit here and reset the creation time of the state which
1607 : * will avoid us to compute a valid_after time that fits the commit
1608 : * phase. */
1609 1 : state->valid_after = 0;
1610 1 : state->n_reveal_rounds = 0;
1611 1 : state->n_commit_rounds = 0;
1612 1 : state->n_protocol_runs = 0;
1613 : }
1614 :
1615 : /* We need to mock for the state update function call. */
1616 1 : MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m);
1617 :
1618 : /* We are in COMMIT phase here and we'll trigger a state update but no
1619 : * transition. */
1620 1 : sr_state_update(commit_phase_time);
1621 1 : tt_int_op(state->valid_after, OP_EQ, commit_phase_time);
1622 1 : tt_int_op(state->n_commit_rounds, OP_EQ, 1);
1623 1 : tt_int_op(state->phase, OP_EQ, SR_PHASE_COMMIT);
1624 1 : tt_int_op(digestmap_size(state->commits), OP_EQ, 1);
1625 :
1626 : /* We are still in the COMMIT phase here but we'll trigger a state
1627 : * transition to the REVEAL phase. */
1628 1 : sr_state_update(reveal_phase_time);
1629 1 : tt_int_op(state->phase, OP_EQ, SR_PHASE_REVEAL);
1630 1 : tt_int_op(state->valid_after, OP_EQ, reveal_phase_time);
1631 : /* Only our commit should be in there. */
1632 1 : tt_int_op(digestmap_size(state->commits), OP_EQ, 1);
1633 1 : tt_int_op(state->n_reveal_rounds, OP_EQ, 1);
1634 :
1635 : /* We can't update a state with a valid after _lower_ than the creation
1636 : * time so here it is. */
1637 1 : sr_state_update(commit_phase_time);
1638 1 : tt_int_op(state->valid_after, OP_EQ, reveal_phase_time);
1639 :
1640 : /* Finally, let's go back in COMMIT phase so we can test the state update
1641 : * of a new protocol run. */
1642 1 : state->valid_after = 0;
1643 1 : sr_state_update(commit_phase_time);
1644 1 : tt_int_op(state->valid_after, OP_EQ, commit_phase_time);
1645 1 : tt_int_op(state->n_commit_rounds, OP_EQ, 1);
1646 1 : tt_int_op(state->n_reveal_rounds, OP_EQ, 0);
1647 1 : tt_u64_op(state->n_protocol_runs, OP_EQ, 1);
1648 1 : tt_int_op(state->phase, OP_EQ, SR_PHASE_COMMIT);
1649 1 : tt_int_op(digestmap_size(state->commits), OP_EQ, 1);
1650 1 : tt_assert(state->current_srv);
1651 :
1652 1 : done:
1653 1 : sr_state_free_all();
1654 1 : UNMOCK(get_my_v3_authority_cert);
1655 1 : }
1656 :
1657 : struct testcase_t sr_tests[] = {
1658 : { "get_sr_protocol_phase", test_get_sr_protocol_phase, TT_FORK,
1659 : NULL, NULL },
1660 : { "sr_commit", test_sr_commit, TT_FORK,
1661 : NULL, NULL },
1662 : { "keep_commit", test_keep_commit, TT_FORK,
1663 : NULL, NULL },
1664 : { "encoding", test_encoding, TT_FORK,
1665 : NULL, NULL },
1666 : { "get_start_time_of_current_run", test_get_start_time_of_current_run,
1667 : TT_FORK, NULL, NULL },
1668 : { "get_start_time_functions", test_get_start_time_functions,
1669 : TT_FORK, NULL, NULL },
1670 : { "get_sr_protocol_duration", test_get_sr_protocol_duration, TT_FORK,
1671 : NULL, NULL },
1672 : { "get_state_valid_until_time", test_get_state_valid_until_time, TT_FORK,
1673 : NULL, NULL },
1674 : { "vote", test_vote, TT_FORK,
1675 : NULL, NULL },
1676 : { "state_load_from_disk", test_state_load_from_disk, TT_FORK,
1677 : NULL, NULL },
1678 : { "sr_compute_srv", test_sr_compute_srv, TT_FORK, NULL, NULL },
1679 : { "sr_get_majority_srv_from_votes", test_sr_get_majority_srv_from_votes,
1680 : TT_FORK, NULL, NULL },
1681 : { "sr_svr_dup", test_sr_svr_dup, TT_FORK, NULL, NULL },
1682 : { "commitments_are_the_same", test_commitments_are_the_same, TT_FORK, NULL,
1683 : NULL },
1684 : { "commit_is_authoritative", test_commit_is_authoritative, TT_FORK, NULL,
1685 : NULL },
1686 : { "get_phase_str", test_get_phase_str, TT_FORK, NULL, NULL },
1687 : { "utils_auth", test_utils_auth, TT_FORK, NULL, NULL },
1688 : { "state_transition", test_state_transition, TT_FORK, NULL, NULL },
1689 : { "state_update", test_state_update, TT_FORK,
1690 : NULL, NULL },
1691 : END_OF_TESTCASES
1692 : };
|