Fuzzing module for various string operations, currently focusing on
[tor.git] / src / test / test_shared_random.c
blob433661f128a80983c4f35af10596c7e2a7f52c32
1 /* Copyright (c) 2016-2018, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
4 #define SHARED_RANDOM_PRIVATE
5 #define SHARED_RANDOM_STATE_PRIVATE
6 #define CONFIG_PRIVATE
7 #define DIRVOTE_PRIVATE
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/dircommon/voting_schedule.h"
26 #include "feature/dirclient/dir_server_st.h"
27 #include "feature/nodelist/networkstatus_st.h"
28 #include "app/config/or_state_st.h"
30 #ifdef HAVE_SYS_STAT_H
31 #include <sys/stat.h>
32 #endif
34 #ifdef _WIN32
35 /* For mkdir */
36 #include <direct.h>
37 #endif
39 static authority_cert_t *mock_cert;
41 static authority_cert_t *
42 get_my_v3_authority_cert_m(void)
44 tor_assert(mock_cert);
45 return mock_cert;
48 static dir_server_t ds;
50 static dir_server_t *
51 trusteddirserver_get_by_v3_auth_digest_m(const char *digest)
53 (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 return &ds;
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 static void
63 init_authority_state(void)
65 MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m);
67 or_options_t *options = get_options_mutable();
68 mock_cert = authority_cert_parse_from_string(AUTHORITY_CERT_1,
69 strlen(AUTHORITY_CERT_1),
70 NULL);
71 tt_assert(mock_cert);
72 options->AuthoritativeDir = 1;
73 tt_int_op(load_ed_keys(options, time(NULL)), OP_GE, 0);
74 sr_state_init(0, 0);
75 /* It's possible a commit has been generated in our state depending on
76 * the phase we are currently in which uses "now" as the starting
77 * timestamp. Delete it before we do any testing below. */
78 sr_state_delete_commits();
80 done:
81 UNMOCK(get_my_v3_authority_cert);
84 static void
85 test_get_sr_protocol_phase(void *arg)
87 time_t the_time;
88 sr_phase_t phase;
89 int retval;
91 (void) arg;
93 /* Initialize SR state */
94 init_authority_state();
97 retval = parse_rfc1123_time("Wed, 20 Apr 2015 23:59:00 UTC", &the_time);
98 tt_int_op(retval, OP_EQ, 0);
100 phase = get_sr_protocol_phase(the_time);
101 tt_int_op(phase, OP_EQ, SR_PHASE_REVEAL);
105 retval = parse_rfc1123_time("Wed, 20 Apr 2015 00:00:00 UTC", &the_time);
106 tt_int_op(retval, OP_EQ, 0);
108 phase = get_sr_protocol_phase(the_time);
109 tt_int_op(phase, OP_EQ, SR_PHASE_COMMIT);
113 retval = parse_rfc1123_time("Wed, 20 Apr 2015 00:00:01 UTC", &the_time);
114 tt_int_op(retval, OP_EQ, 0);
116 phase = get_sr_protocol_phase(the_time);
117 tt_int_op(phase, OP_EQ, SR_PHASE_COMMIT);
121 retval = parse_rfc1123_time("Wed, 20 Apr 2015 11:59:00 UTC", &the_time);
122 tt_int_op(retval, OP_EQ, 0);
124 phase = get_sr_protocol_phase(the_time);
125 tt_int_op(phase, OP_EQ, SR_PHASE_COMMIT);
129 retval = parse_rfc1123_time("Wed, 20 Apr 2015 12:00:00 UTC", &the_time);
130 tt_int_op(retval, OP_EQ, 0);
132 phase = get_sr_protocol_phase(the_time);
133 tt_int_op(phase, OP_EQ, SR_PHASE_REVEAL);
137 retval = parse_rfc1123_time("Wed, 20 Apr 2015 12:00:01 UTC", &the_time);
138 tt_int_op(retval, OP_EQ, 0);
140 phase = get_sr_protocol_phase(the_time);
141 tt_int_op(phase, OP_EQ, SR_PHASE_REVEAL);
145 retval = parse_rfc1123_time("Wed, 20 Apr 2015 13:00:00 UTC", &the_time);
146 tt_int_op(retval, OP_EQ, 0);
148 phase = get_sr_protocol_phase(the_time);
149 tt_int_op(phase, OP_EQ, SR_PHASE_REVEAL);
152 done:
156 static networkstatus_t mock_consensus;
158 /* Mock function to immediately return our local 'mock_consensus'. */
159 static networkstatus_t *
160 mock_networkstatus_get_live_consensus(time_t now)
162 (void) now;
163 return &mock_consensus;
166 static void
167 test_get_state_valid_until_time(void *arg)
169 time_t current_time;
170 time_t valid_until_time;
171 char tbuf[ISO_TIME_LEN + 1];
172 int retval;
174 (void) arg;
176 MOCK(networkstatus_get_live_consensus,
177 mock_networkstatus_get_live_consensus);
179 retval = parse_rfc1123_time("Mon, 20 Apr 2015 01:00:00 UTC",
180 &mock_consensus.fresh_until);
181 tt_int_op(retval, OP_EQ, 0);
183 retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:00:00 UTC",
184 &mock_consensus.valid_after);
185 tt_int_op(retval, OP_EQ, 0);
188 /* Get the valid until time if called at 00:00:01 */
189 retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:00:01 UTC",
190 &current_time);
191 tt_int_op(retval, OP_EQ, 0);
192 voting_schedule_recalculate_timing(get_options(), current_time);
193 valid_until_time = get_state_valid_until_time(current_time);
195 /* Compare it with the correct result */
196 format_iso_time(tbuf, valid_until_time);
197 tt_str_op("2015-04-21 00:00:00", OP_EQ, tbuf);
201 retval = parse_rfc1123_time("Mon, 20 Apr 2015 19:22:00 UTC",
202 &current_time);
203 tt_int_op(retval, OP_EQ, 0);
204 voting_schedule_recalculate_timing(get_options(), current_time);
205 valid_until_time = get_state_valid_until_time(current_time);
207 format_iso_time(tbuf, valid_until_time);
208 tt_str_op("2015-04-21 00:00:00", OP_EQ, tbuf);
212 retval = parse_rfc1123_time("Mon, 20 Apr 2015 23:59:00 UTC",
213 &current_time);
214 tt_int_op(retval, OP_EQ, 0);
215 voting_schedule_recalculate_timing(get_options(), current_time);
216 valid_until_time = get_state_valid_until_time(current_time);
218 format_iso_time(tbuf, valid_until_time);
219 tt_str_op("2015-04-21 00:00:00", OP_EQ, tbuf);
223 retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:00:00 UTC",
224 &current_time);
225 tt_int_op(retval, OP_EQ, 0);
226 voting_schedule_recalculate_timing(get_options(), current_time);
227 valid_until_time = get_state_valid_until_time(current_time);
229 format_iso_time(tbuf, valid_until_time);
230 tt_str_op("2015-04-21 00:00:00", OP_EQ, tbuf);
233 done:
234 UNMOCK(networkstatus_get_live_consensus);
237 /** Test the function that calculates the start time of the current SRV
238 * protocol run. */
239 static void
240 test_get_start_time_of_current_run(void *arg)
242 int retval;
243 char tbuf[ISO_TIME_LEN + 1];
244 time_t current_time, run_start_time;
246 (void) arg;
248 MOCK(networkstatus_get_live_consensus,
249 mock_networkstatus_get_live_consensus);
251 retval = parse_rfc1123_time("Mon, 20 Apr 2015 01:00:00 UTC",
252 &mock_consensus.fresh_until);
253 tt_int_op(retval, OP_EQ, 0);
255 retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:00:00 UTC",
256 &mock_consensus.valid_after);
257 tt_int_op(retval, OP_EQ, 0);
260 /* Get start time if called at 00:00:01 */
261 retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:00:01 UTC",
262 &current_time);
263 tt_int_op(retval, OP_EQ, 0);
264 voting_schedule_recalculate_timing(get_options(), current_time);
265 run_start_time = sr_state_get_start_time_of_current_protocol_run();
267 /* Compare it with the correct result */
268 format_iso_time(tbuf, run_start_time);
269 tt_str_op("2015-04-20 00:00:00", OP_EQ, tbuf);
273 retval = parse_rfc1123_time("Mon, 20 Apr 2015 23:59:59 UTC",
274 &current_time);
275 tt_int_op(retval, OP_EQ, 0);
276 voting_schedule_recalculate_timing(get_options(), current_time);
277 run_start_time = sr_state_get_start_time_of_current_protocol_run();
279 /* Compare it with the correct result */
280 format_iso_time(tbuf, run_start_time);
281 tt_str_op("2015-04-20 00:00:00", OP_EQ, tbuf);
285 retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:00:00 UTC",
286 &current_time);
287 tt_int_op(retval, OP_EQ, 0);
288 voting_schedule_recalculate_timing(get_options(), current_time);
289 run_start_time = sr_state_get_start_time_of_current_protocol_run();
291 /* Compare it with the correct result */
292 format_iso_time(tbuf, run_start_time);
293 tt_str_op("2015-04-20 00:00:00", OP_EQ, tbuf);
297 /* We want the local time to be past midnight, but the current consensus to
298 * have valid-after 23:00 (e.g. this can happen if we fetch a new consensus
299 * at 00:08 before dircaches have a chance to get the midnight consensus).
301 * Basically, we want to cause a desynch between ns->valid_after (23:00)
302 * and the voting_schedule.interval_starts (01:00), to make sure that
303 * sr_state_get_start_time_of_current_protocol_run() handles it gracefully:
304 * It should actually follow the local consensus time and not the voting
305 * schedule (which is designed for authority voting purposes). */
306 retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:00:00 UTC",
307 &mock_consensus.fresh_until);
308 tt_int_op(retval, OP_EQ, 0);
310 retval = parse_rfc1123_time("Mon, 19 Apr 2015 23:00:00 UTC",
311 &mock_consensus.valid_after);
313 retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:08:00 UTC",
314 &current_time);
315 tt_int_op(retval, OP_EQ, 0);
316 update_approx_time(current_time);
317 voting_schedule_recalculate_timing(get_options(), current_time);
319 run_start_time = sr_state_get_start_time_of_current_protocol_run();
321 /* Compare it with the correct result */
322 format_iso_time(tbuf, run_start_time);
323 tt_str_op("2015-04-19 00:00:00", OP_EQ, tbuf);
324 /* Check that voting_schedule.interval_starts is at 01:00 (see above) */
325 time_t interval_starts = voting_schedule_get_next_valid_after_time();
326 format_iso_time(tbuf, interval_starts);
327 tt_str_op("2015-04-20 01:00:00", OP_EQ, tbuf);
330 /* Next test is testing it without a consensus to use the testing voting
331 * interval . */
332 UNMOCK(networkstatus_get_live_consensus);
334 /* Now let's alter the voting schedule and check the correctness of the
335 * function. Voting interval of 10 seconds, means that an SRV protocol run
336 * takes 10 seconds * 24 rounds = 4 mins */
338 or_options_t *options = get_options_mutable();
339 options->V3AuthVotingInterval = 10;
340 options->TestingV3AuthInitialVotingInterval = 10;
341 retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:15:32 UTC",
342 &current_time);
343 tt_int_op(retval, OP_EQ, 0);
344 voting_schedule_recalculate_timing(get_options(), current_time);
345 run_start_time = sr_state_get_start_time_of_current_protocol_run();
347 /* Compare it with the correct result */
348 format_iso_time(tbuf, run_start_time);
349 tt_str_op("2015-04-20 00:12:00", OP_EQ, tbuf);
352 done:
356 /** Do some rudimentary consistency checks between the functions that
357 * understand the shared random protocol schedule */
358 static void
359 test_get_start_time_functions(void *arg)
361 (void) arg;
362 int retval;
364 MOCK(networkstatus_get_live_consensus,
365 mock_networkstatus_get_live_consensus);
367 retval = parse_rfc1123_time("Mon, 20 Apr 2015 01:00:00 UTC",
368 &mock_consensus.fresh_until);
369 tt_int_op(retval, OP_EQ, 0);
371 retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:00:00 UTC",
372 &mock_consensus.valid_after);
373 tt_int_op(retval, OP_EQ, 0);
374 time_t now = mock_consensus.valid_after;
376 voting_schedule_recalculate_timing(get_options(), now);
377 time_t start_time_of_protocol_run =
378 sr_state_get_start_time_of_current_protocol_run();
379 tt_assert(start_time_of_protocol_run);
381 /* Check that the round start time of the beginning of the run, is itself */
382 tt_int_op(get_start_time_of_current_round(), OP_EQ,
383 start_time_of_protocol_run);
385 done:
386 UNMOCK(networkstatus_get_live_consensus);
389 static void
390 test_get_sr_protocol_duration(void *arg)
392 (void) arg;
394 /* Check that by default an SR phase is 12 hours */
395 tt_int_op(sr_state_get_phase_duration(), OP_EQ, 12*60*60);
396 tt_int_op(sr_state_get_protocol_run_duration(), OP_EQ, 24*60*60);
398 /* Now alter the voting interval and check that the SR phase is 2 mins long
399 * if voting happens every 10 seconds (10*12 seconds = 2 mins) */
400 or_options_t *options = get_options_mutable();
401 options->V3AuthVotingInterval = 10;
402 tt_int_op(sr_state_get_phase_duration(), OP_EQ, 2*60);
403 tt_int_op(sr_state_get_protocol_run_duration(), OP_EQ, 4*60);
405 done: ;
408 /* In this test we are going to generate a sr_commit_t object and validate
409 * it. We first generate our values, and then we parse them as if they were
410 * received from the network. After we parse both the commit and the reveal,
411 * we verify that they indeed match. */
412 static void
413 test_sr_commit(void *arg)
415 authority_cert_t *auth_cert = NULL;
416 time_t now = time(NULL);
417 sr_commit_t *our_commit = NULL;
418 smartlist_t *args = smartlist_new();
419 sr_commit_t *parsed_commit = NULL;
421 (void) arg;
423 { /* Setup a minimal dirauth environment for this test */
424 or_options_t *options = get_options_mutable();
426 auth_cert = authority_cert_parse_from_string(AUTHORITY_CERT_1,
427 strlen(AUTHORITY_CERT_1),
428 NULL);
429 tt_assert(auth_cert);
431 options->AuthoritativeDir = 1;
432 tt_int_op(load_ed_keys(options, time(NULL)), OP_GE, 0);
435 /* Generate our commit object and validate it has the appropriate field
436 * that we can then use to build a representation that we'll find in a
437 * vote coming from the network. */
439 sr_commit_t test_commit;
440 our_commit = sr_generate_our_commit(now, auth_cert);
441 tt_assert(our_commit);
442 /* Default and only supported algorithm for now. */
443 tt_assert(our_commit->alg == DIGEST_SHA3_256);
444 /* We should have a reveal value. */
445 tt_assert(commit_has_reveal_value(our_commit));
446 /* We should have a random value. */
447 tt_assert(!tor_mem_is_zero((char *) our_commit->random_number,
448 sizeof(our_commit->random_number)));
449 /* Commit and reveal timestamp should be the same. */
450 tt_u64_op(our_commit->commit_ts, OP_EQ, our_commit->reveal_ts);
451 /* We should have a hashed reveal. */
452 tt_assert(!tor_mem_is_zero(our_commit->hashed_reveal,
453 sizeof(our_commit->hashed_reveal)));
454 /* Do we have a valid encoded commit and reveal. Note the following only
455 * tests if the generated values are correct. Their could be a bug in
456 * the decode function but we test them separately. */
457 tt_int_op(0, OP_EQ, reveal_decode(our_commit->encoded_reveal,
458 &test_commit));
459 tt_int_op(0, OP_EQ, commit_decode(our_commit->encoded_commit,
460 &test_commit));
461 tt_int_op(0, OP_EQ, verify_commit_and_reveal(our_commit));
464 /* Let's make sure our verify commit and reveal function works. We'll
465 * make it fail a bit with known failure case. */
467 /* Copy our commit so we don't alter it for the rest of testing. */
468 sr_commit_t test_commit;
469 memcpy(&test_commit, our_commit, sizeof(test_commit));
471 /* Timestamp MUST match. */
472 test_commit.commit_ts = test_commit.reveal_ts - 42;
473 setup_full_capture_of_logs(LOG_WARN);
474 tt_int_op(-1, OP_EQ, verify_commit_and_reveal(&test_commit));
475 expect_log_msg_containing("doesn't match reveal timestamp");
476 teardown_capture_of_logs();
477 memcpy(&test_commit, our_commit, sizeof(test_commit));
478 tt_int_op(0, OP_EQ, verify_commit_and_reveal(&test_commit));
480 /* Hashed reveal must match the H(encoded_reveal). */
481 memset(test_commit.hashed_reveal, 'X',
482 sizeof(test_commit.hashed_reveal));
483 setup_full_capture_of_logs(LOG_WARN);
484 tt_int_op(-1, OP_EQ, verify_commit_and_reveal(&test_commit));
485 expect_single_log_msg_containing("doesn't match the commit value");
486 teardown_capture_of_logs();
487 memcpy(&test_commit, our_commit, sizeof(test_commit));
488 tt_int_op(0, OP_EQ, verify_commit_and_reveal(&test_commit));
491 /* We'll build a list of values from our commit that our parsing function
492 * takes from a vote line and see if we can parse it correctly. */
494 smartlist_add_strdup(args, "1");
495 smartlist_add_strdup(args,
496 crypto_digest_algorithm_get_name(our_commit->alg));
497 smartlist_add_strdup(args, sr_commit_get_rsa_fpr(our_commit));
498 smartlist_add_strdup(args, our_commit->encoded_commit);
499 smartlist_add_strdup(args, our_commit->encoded_reveal);
500 parsed_commit = sr_parse_commit(args);
501 tt_assert(parsed_commit);
502 /* That parsed commit should be _EXACTLY_ like our original commit (we
503 * have to explicitly set the valid flag though). */
504 parsed_commit->valid = 1;
505 tt_mem_op(parsed_commit, OP_EQ, our_commit, sizeof(*parsed_commit));
506 /* Cleanup */
509 done:
510 teardown_capture_of_logs();
511 SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
512 smartlist_free(args);
513 sr_commit_free(our_commit);
514 sr_commit_free(parsed_commit);
515 authority_cert_free(auth_cert);
518 /* Test the encoding and decoding function for commit and reveal values. */
519 static void
520 test_encoding(void *arg)
522 (void) arg;
523 int ret;
524 /* Random number is 32 bytes. */
525 char raw_rand[32];
526 time_t ts = 1454333590;
527 char hashed_rand[DIGEST256_LEN], hashed_reveal[DIGEST256_LEN];
528 sr_commit_t parsed_commit;
530 /* Those values were generated by sr_commit_calc_ref.py where the random
531 * value is 32 'A' and timestamp is the one in ts. */
532 static const char *encoded_reveal =
533 "AAAAAFavXpZJxbwTupvaJCTeIUCQmOPxAMblc7ChL5H2nZKuGchdaA==";
534 static const char *encoded_commit =
535 "AAAAAFavXpbkBMzMQG7aNoaGLFNpm2Wkk1ozXhuWWqL//GynltxVAg==";
537 /* Set up our raw random bytes array. */
538 memset(raw_rand, 'A', sizeof(raw_rand));
539 /* Hash random number because we don't expose bytes of the RNG. */
540 ret = crypto_digest256(hashed_rand, raw_rand,
541 sizeof(raw_rand), SR_DIGEST_ALG);
542 tt_int_op(0, OP_EQ, ret);
543 /* Hash reveal value. */
544 tt_int_op(SR_REVEAL_BASE64_LEN, OP_EQ, strlen(encoded_reveal));
545 ret = crypto_digest256(hashed_reveal, encoded_reveal,
546 strlen(encoded_reveal), SR_DIGEST_ALG);
547 tt_int_op(0, OP_EQ, ret);
548 tt_int_op(SR_COMMIT_BASE64_LEN, OP_EQ, strlen(encoded_commit));
550 /* Test our commit/reveal decode functions. */
552 /* Test the reveal encoded value. */
553 tt_int_op(0, OP_EQ, reveal_decode(encoded_reveal, &parsed_commit));
554 tt_u64_op(ts, OP_EQ, parsed_commit.reveal_ts);
555 tt_mem_op(hashed_rand, OP_EQ, parsed_commit.random_number,
556 sizeof(hashed_rand));
558 /* Test the commit encoded value. */
559 memset(&parsed_commit, 0, sizeof(parsed_commit));
560 tt_int_op(0, OP_EQ, commit_decode(encoded_commit, &parsed_commit));
561 tt_u64_op(ts, OP_EQ, parsed_commit.commit_ts);
562 tt_mem_op(encoded_commit, OP_EQ, parsed_commit.encoded_commit,
563 sizeof(parsed_commit.encoded_commit));
564 tt_mem_op(hashed_reveal, OP_EQ, parsed_commit.hashed_reveal,
565 sizeof(hashed_reveal));
568 /* Test our commit/reveal encode functions. */
570 /* Test the reveal encode. */
571 char encoded[SR_REVEAL_BASE64_LEN + 1];
572 parsed_commit.reveal_ts = ts;
573 memcpy(parsed_commit.random_number, hashed_rand,
574 sizeof(parsed_commit.random_number));
575 ret = reveal_encode(&parsed_commit, encoded, sizeof(encoded));
576 tt_int_op(SR_REVEAL_BASE64_LEN, OP_EQ, ret);
577 tt_mem_op(encoded_reveal, OP_EQ, encoded, strlen(encoded_reveal));
581 /* Test the commit encode. */
582 char encoded[SR_COMMIT_BASE64_LEN + 1];
583 parsed_commit.commit_ts = ts;
584 memcpy(parsed_commit.hashed_reveal, hashed_reveal,
585 sizeof(parsed_commit.hashed_reveal));
586 ret = commit_encode(&parsed_commit, encoded, sizeof(encoded));
587 tt_int_op(SR_COMMIT_BASE64_LEN, OP_EQ, ret);
588 tt_mem_op(encoded_commit, OP_EQ, encoded, strlen(encoded_commit));
591 done:
595 /** Setup some SRVs in our SR state. If <b>also_current</b> is set, then set
596 * both current and previous SRVs.
597 * Helper of test_vote() and test_sr_compute_srv(). */
598 static void
599 test_sr_setup_srv(int also_current)
601 sr_srv_t *srv = tor_malloc_zero(sizeof(sr_srv_t));
602 srv->num_reveals = 42;
603 memcpy(srv->value,
604 "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ",
605 sizeof(srv->value));
607 sr_state_set_previous_srv(srv);
609 if (also_current) {
610 srv = tor_malloc_zero(sizeof(sr_srv_t));
611 srv->num_reveals = 128;
612 memcpy(srv->value,
613 "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN",
614 sizeof(srv->value));
616 sr_state_set_current_srv(srv);
620 /* Test anything that has to do with SR protocol and vote. */
621 static void
622 test_vote(void *arg)
624 int ret;
625 time_t now = time(NULL);
626 sr_commit_t *our_commit = NULL;
628 (void) arg;
630 MOCK(trusteddirserver_get_by_v3_auth_digest,
631 trusteddirserver_get_by_v3_auth_digest_m);
633 { /* Setup a minimal dirauth environment for this test */
634 init_authority_state();
635 /* Set ourself in reveal phase so we can parse the reveal value in the
636 * vote as well. */
637 set_sr_phase(SR_PHASE_REVEAL);
640 /* Generate our commit object and validate it has the appropriate field
641 * that we can then use to build a representation that we'll find in a
642 * vote coming from the network. */
644 sr_commit_t *saved_commit;
645 our_commit = sr_generate_our_commit(now, mock_cert);
646 tt_assert(our_commit);
647 sr_state_add_commit(our_commit);
648 /* Make sure it's there. */
649 saved_commit = sr_state_get_commit(our_commit->rsa_identity);
650 tt_assert(saved_commit);
653 /* Also setup the SRVs */
654 test_sr_setup_srv(1);
656 { /* Now test the vote generation */
657 smartlist_t *chunks = smartlist_new();
658 smartlist_t *tokens = smartlist_new();
659 /* Get our vote line and validate it. */
660 char *lines = sr_get_string_for_vote();
661 tt_assert(lines);
662 /* Split the lines. We expect 2 here. */
663 ret = smartlist_split_string(chunks, lines, "\n", SPLIT_IGNORE_BLANK, 0);
664 tt_int_op(ret, OP_EQ, 4);
665 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "shared-rand-participate");
666 /* Get our commitment line and will validate it against our commit. The
667 * format is as follow:
668 * "shared-rand-commitment" SP version SP algname SP identity
669 * SP COMMIT [SP REVEAL] NL
671 char *commit_line = smartlist_get(chunks, 1);
672 tt_assert(commit_line);
673 ret = smartlist_split_string(tokens, commit_line, " ", 0, 0);
674 tt_int_op(ret, OP_EQ, 6);
675 tt_str_op(smartlist_get(tokens, 0), OP_EQ, "shared-rand-commit");
676 tt_str_op(smartlist_get(tokens, 1), OP_EQ, "1");
677 tt_str_op(smartlist_get(tokens, 2), OP_EQ,
678 crypto_digest_algorithm_get_name(DIGEST_SHA3_256));
679 char digest[DIGEST_LEN];
680 base16_decode(digest, sizeof(digest), smartlist_get(tokens, 3),
681 HEX_DIGEST_LEN);
682 tt_mem_op(digest, OP_EQ, our_commit->rsa_identity, sizeof(digest));
683 tt_str_op(smartlist_get(tokens, 4), OP_EQ, our_commit->encoded_commit);
684 tt_str_op(smartlist_get(tokens, 5), OP_EQ, our_commit->encoded_reveal)
686 /* Finally, does this vote line creates a valid commit object? */
687 smartlist_t *args = smartlist_new();
688 smartlist_add(args, smartlist_get(tokens, 1));
689 smartlist_add(args, smartlist_get(tokens, 2));
690 smartlist_add(args, smartlist_get(tokens, 3));
691 smartlist_add(args, smartlist_get(tokens, 4));
692 smartlist_add(args, smartlist_get(tokens, 5));
693 sr_commit_t *parsed_commit = sr_parse_commit(args);
694 tt_assert(parsed_commit);
695 /* Set valid flag explicitly here to compare since it's not set by
696 * simply parsing the commit. */
697 parsed_commit->valid = 1;
698 tt_mem_op(parsed_commit, OP_EQ, our_commit, sizeof(*our_commit));
700 /* minor cleanup */
701 SMARTLIST_FOREACH(tokens, char *, s, tor_free(s));
702 smartlist_clear(tokens);
704 /* Now test the previous SRV */
705 char *prev_srv_line = smartlist_get(chunks, 2);
706 tt_assert(prev_srv_line);
707 ret = smartlist_split_string(tokens, prev_srv_line, " ", 0, 0);
708 tt_int_op(ret, OP_EQ, 3);
709 tt_str_op(smartlist_get(tokens, 0), OP_EQ, "shared-rand-previous-value");
710 tt_str_op(smartlist_get(tokens, 1), OP_EQ, "42");
711 tt_str_op(smartlist_get(tokens, 2), OP_EQ,
712 "WlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlo=");
714 /* minor cleanup */
715 SMARTLIST_FOREACH(tokens, char *, s, tor_free(s));
716 smartlist_clear(tokens);
718 /* Now test the current SRV */
719 char *current_srv_line = smartlist_get(chunks, 3);
720 tt_assert(current_srv_line);
721 ret = smartlist_split_string(tokens, current_srv_line, " ", 0, 0);
722 tt_int_op(ret, OP_EQ, 3);
723 tt_str_op(smartlist_get(tokens, 0), OP_EQ, "shared-rand-current-value");
724 tt_str_op(smartlist_get(tokens, 1), OP_EQ, "128");
725 tt_str_op(smartlist_get(tokens, 2), OP_EQ,
726 "Tk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk4=");
728 /* Clean up */
729 sr_commit_free(parsed_commit);
730 SMARTLIST_FOREACH(chunks, char *, s, tor_free(s));
731 smartlist_free(chunks);
732 SMARTLIST_FOREACH(tokens, char *, s, tor_free(s));
733 smartlist_free(tokens);
734 smartlist_clear(args);
735 smartlist_free(args);
736 tor_free(lines);
739 done:
740 sr_commit_free(our_commit);
741 UNMOCK(trusteddirserver_get_by_v3_auth_digest);
744 static const char *sr_state_str = "Version 1\n"
745 "TorVersion 0.2.9.0-alpha-dev\n"
746 "ValidAfter 2037-04-19 07:16:00\n"
747 "ValidUntil 2037-04-20 07:16:00\n"
748 "Commit 1 sha3-256 FA3CEC2C99DC68D3166B9B6E4FA21A4026C2AB1C "
749 "7M8GdubCAAdh7WUG0DiwRyxTYRKji7HATa7LLJEZ/UAAAAAAVmfUSg== "
750 "AAAAAFZn1EojfIheIw42bjK3VqkpYyjsQFSbv/dxNna3Q8hUEPKpOw==\n"
751 "Commit 1 sha3-256 41E89EDFBFBA44983E21F18F2230A4ECB5BFB543 "
752 "17aUsYuMeRjd2N1r8yNyg7aHqRa6gf4z7QPoxxAZbp0AAAAAVmfUSg==\n"
753 "Commit 1 sha3-256 36637026573A04110CF3E6B1D201FB9A98B88734 "
754 "DDDYtripvdOU+XPEUm5xpU64d9IURSds1xSwQsgeB8oAAAAAVmfUSg==\n"
755 "SharedRandPreviousValue 4 qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqo=\n"
756 "SharedRandCurrentValue 3 8dWeW12KEzTGEiLGgO1UVJ7Z91CekoRcxt6Q9KhnOFI=\n";
758 /** Create an SR disk state, parse it and validate that the parsing went
759 * well. Yes! */
760 static void
761 test_state_load_from_disk(void *arg)
763 int ret;
764 char *dir = tor_strdup(get_fname("test_sr_state"));
765 char *sr_state_path = tor_strdup(get_fname("test_sr_state/sr_state"));
766 sr_state_t *the_sr_state = NULL;
768 (void) arg;
770 MOCK(trusteddirserver_get_by_v3_auth_digest,
771 trusteddirserver_get_by_v3_auth_digest_m);
773 /* First try with a nonexistent path. */
774 ret = disk_state_load_from_disk_impl("NONEXISTENTNONEXISTENT");
775 tt_int_op(ret, OP_EQ, -ENOENT);
777 /* Now create a mock state directory and state file */
778 #ifdef _WIN32
779 ret = mkdir(dir);
780 #else
781 ret = mkdir(dir, 0700);
782 #endif
783 tt_int_op(ret, OP_EQ, 0);
784 ret = write_str_to_file(sr_state_path, sr_state_str, 0);
785 tt_int_op(ret, OP_EQ, 0);
787 /* Try to load the directory itself. Should fail. */
788 ret = disk_state_load_from_disk_impl(dir);
789 tt_int_op(ret, OP_LT, 0);
791 /* State should be non-existent at this point. */
792 the_sr_state = get_sr_state();
793 tt_ptr_op(the_sr_state, OP_EQ, NULL);
795 /* Now try to load the correct file! */
796 ret = disk_state_load_from_disk_impl(sr_state_path);
797 tt_int_op(ret, OP_EQ, 0);
799 /* Check the content of the state */
800 /* XXX check more deeply!!! */
801 the_sr_state = get_sr_state();
802 tt_assert(the_sr_state);
803 tt_assert(the_sr_state->version == 1);
804 tt_assert(digestmap_size(the_sr_state->commits) == 3);
805 tt_assert(the_sr_state->current_srv);
806 tt_assert(the_sr_state->current_srv->num_reveals == 3);
807 tt_assert(the_sr_state->previous_srv);
809 /* XXX Now also try loading corrupted state files and make sure parsing
810 fails */
812 done:
813 tor_free(dir);
814 tor_free(sr_state_path);
815 UNMOCK(trusteddirserver_get_by_v3_auth_digest);
818 /** Generate three specially crafted commits (based on the test
819 * vector at sr_srv_calc_ref.py). Helper of test_sr_compute_srv(). */
820 static void
821 test_sr_setup_commits(void)
823 time_t now = time(NULL);
824 sr_commit_t *commit_a, *commit_b, *commit_c, *commit_d;
825 sr_commit_t *place_holder = tor_malloc_zero(sizeof(*place_holder));
826 authority_cert_t *auth_cert = NULL;
828 { /* Setup a minimal dirauth environment for this test */
829 or_options_t *options = get_options_mutable();
831 auth_cert = authority_cert_parse_from_string(AUTHORITY_CERT_1,
832 strlen(AUTHORITY_CERT_1),
833 NULL);
834 tt_assert(auth_cert);
836 options->AuthoritativeDir = 1;
837 tt_int_op(0, OP_EQ, load_ed_keys(options, now));
840 /* Generate three dummy commits according to sr_srv_calc_ref.py . Then
841 register them to the SR state. Also register a fourth commit 'd' with no
842 reveal info, to make sure that it will get ignored during SRV
843 calculation. */
845 { /* Commit from auth 'a' */
846 commit_a = sr_generate_our_commit(now, auth_cert);
847 tt_assert(commit_a);
849 /* Do some surgery on the commit */
850 memset(commit_a->rsa_identity, 'A', sizeof(commit_a->rsa_identity));
851 base16_encode(commit_a->rsa_identity_hex,
852 sizeof(commit_a->rsa_identity_hex), commit_a->rsa_identity,
853 sizeof(commit_a->rsa_identity));
854 strlcpy(commit_a->encoded_reveal,
855 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
856 sizeof(commit_a->encoded_reveal));
857 memcpy(commit_a->hashed_reveal,
858 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
859 sizeof(commit_a->hashed_reveal));
862 { /* Commit from auth 'b' */
863 commit_b = sr_generate_our_commit(now, auth_cert);
864 tt_assert(commit_b);
866 /* Do some surgery on the commit */
867 memset(commit_b->rsa_identity, 'B', sizeof(commit_b->rsa_identity));
868 base16_encode(commit_b->rsa_identity_hex,
869 sizeof(commit_b->rsa_identity_hex), commit_b->rsa_identity,
870 sizeof(commit_b->rsa_identity));
871 strlcpy(commit_b->encoded_reveal,
872 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
873 sizeof(commit_b->encoded_reveal));
874 memcpy(commit_b->hashed_reveal,
875 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
876 sizeof(commit_b->hashed_reveal));
879 { /* Commit from auth 'c' */
880 commit_c = sr_generate_our_commit(now, auth_cert);
881 tt_assert(commit_c);
883 /* Do some surgery on the commit */
884 memset(commit_c->rsa_identity, 'C', sizeof(commit_c->rsa_identity));
885 base16_encode(commit_c->rsa_identity_hex,
886 sizeof(commit_c->rsa_identity_hex), commit_c->rsa_identity,
887 sizeof(commit_c->rsa_identity));
888 strlcpy(commit_c->encoded_reveal,
889 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC",
890 sizeof(commit_c->encoded_reveal));
891 memcpy(commit_c->hashed_reveal,
892 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC",
893 sizeof(commit_c->hashed_reveal));
896 { /* Commit from auth 'd' */
897 commit_d = sr_generate_our_commit(now, auth_cert);
898 tt_assert(commit_d);
900 /* Do some surgery on the commit */
901 memset(commit_d->rsa_identity, 'D', sizeof(commit_d->rsa_identity));
902 base16_encode(commit_d->rsa_identity_hex,
903 sizeof(commit_d->rsa_identity_hex), commit_d->rsa_identity,
904 sizeof(commit_d->rsa_identity));
905 strlcpy(commit_d->encoded_reveal,
906 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD",
907 sizeof(commit_d->encoded_reveal));
908 memcpy(commit_d->hashed_reveal,
909 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD",
910 sizeof(commit_d->hashed_reveal));
911 /* Clean up its reveal info */
912 memcpy(place_holder, commit_d, sizeof(*place_holder));
913 memset(commit_d->encoded_reveal, 0, sizeof(commit_d->encoded_reveal));
914 tt_assert(!commit_has_reveal_value(commit_d));
917 /* Register commits to state (during commit phase) */
918 set_sr_phase(SR_PHASE_COMMIT);
919 save_commit_to_state(commit_a);
920 save_commit_to_state(commit_b);
921 save_commit_to_state(commit_c);
922 save_commit_to_state(commit_d);
923 tt_int_op(digestmap_size(get_sr_state()->commits), OP_EQ, 4);
925 /* Now during REVEAL phase save commit D by restoring its reveal. */
926 set_sr_phase(SR_PHASE_REVEAL);
927 save_commit_to_state(place_holder);
928 place_holder = NULL;
929 tt_str_op(commit_d->encoded_reveal, OP_EQ,
930 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD");
931 /* Go back to an empty encoded reveal value. */
932 memset(commit_d->encoded_reveal, 0, sizeof(commit_d->encoded_reveal));
933 memset(commit_d->random_number, 0, sizeof(commit_d->random_number));
934 tt_assert(!commit_has_reveal_value(commit_d));
936 done:
937 tor_free(place_holder);
938 authority_cert_free(auth_cert);
941 /** Verify that the SRV generation procedure is proper by testing it against
942 * the test vector from ./sr_srv_calc_ref.py. */
943 static void
944 test_sr_compute_srv(void *arg)
946 (void) arg;
947 const sr_srv_t *current_srv = NULL;
949 #define SRV_TEST_VECTOR \
950 "2A9B1D6237DAB312A40F575DA85C147663E7ED3F80E9555395F15B515C74253D"
952 MOCK(trusteddirserver_get_by_v3_auth_digest,
953 trusteddirserver_get_by_v3_auth_digest_m);
955 init_authority_state();
957 /* Setup the commits for this unittest */
958 test_sr_setup_commits();
959 test_sr_setup_srv(0);
961 /* Now switch to reveal phase */
962 set_sr_phase(SR_PHASE_REVEAL);
964 /* Compute the SRV */
965 sr_compute_srv();
967 /* Check the result against the test vector */
968 current_srv = sr_state_get_current_srv();
969 tt_assert(current_srv);
970 tt_u64_op(current_srv->num_reveals, OP_EQ, 3);
971 tt_str_op(hex_str((char*)current_srv->value, 32),
972 OP_EQ,
973 SRV_TEST_VECTOR);
975 done:
976 UNMOCK(trusteddirserver_get_by_v3_auth_digest);
979 /** Return a minimal vote document with a current SRV value set to
980 * <b>srv</b>. */
981 static networkstatus_t *
982 get_test_vote_with_curr_srv(const char *srv)
984 networkstatus_t *vote = tor_malloc_zero(sizeof(networkstatus_t));
986 vote->type = NS_TYPE_VOTE;
987 vote->sr_info.participate = 1;
988 vote->sr_info.current_srv = tor_malloc_zero(sizeof(sr_srv_t));
989 vote->sr_info.current_srv->num_reveals = 42;
990 memcpy(vote->sr_info.current_srv->value,
991 srv,
992 sizeof(vote->sr_info.current_srv->value));
994 return vote;
997 /* Test the function that picks the right SRV given a bunch of votes. Make sure
998 * that the function returns an SRV iff the majority/agreement requirements are
999 * met. */
1000 static void
1001 test_sr_get_majority_srv_from_votes(void *arg)
1003 sr_srv_t *chosen_srv;
1004 smartlist_t *votes = smartlist_new();
1006 #define SRV_1 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
1007 #define SRV_2 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
1009 (void) arg;
1011 init_authority_state();
1012 /* Make sure our SRV is fresh so we can consider the super majority with
1013 * the consensus params of number of agreements needed. */
1014 sr_state_set_fresh_srv();
1016 /* The test relies on the dirauth list being initialized. */
1017 clear_dir_servers();
1018 add_default_trusted_dir_authorities(V3_DIRINFO);
1020 { /* Prepare voting environment with just a single vote. */
1021 networkstatus_t *vote = get_test_vote_with_curr_srv(SRV_1);
1022 smartlist_add(votes, vote);
1025 /* Since it's only one vote with an SRV, it should not achieve majority and
1026 hence no SRV will be returned. */
1027 chosen_srv = get_majority_srv_from_votes(votes, 1);
1028 tt_ptr_op(chosen_srv, OP_EQ, NULL);
1030 { /* Now put in 8 more votes. Let SRV_1 have majority. */
1031 int i;
1032 /* Now 7 votes believe in SRV_1 */
1033 for (i = 0; i < 3; i++) {
1034 networkstatus_t *vote = get_test_vote_with_curr_srv(SRV_1);
1035 smartlist_add(votes, vote);
1037 /* and 2 votes believe in SRV_2 */
1038 for (i = 0; i < 2; i++) {
1039 networkstatus_t *vote = get_test_vote_with_curr_srv(SRV_2);
1040 smartlist_add(votes, vote);
1042 for (i = 0; i < 3; i++) {
1043 networkstatus_t *vote = get_test_vote_with_curr_srv(SRV_1);
1044 smartlist_add(votes, vote);
1047 tt_int_op(smartlist_len(votes), OP_EQ, 9);
1050 /* Now we achieve majority for SRV_1, but not the AuthDirNumSRVAgreements
1051 requirement. So still not picking an SRV. */
1052 set_num_srv_agreements(8);
1053 chosen_srv = get_majority_srv_from_votes(votes, 1);
1054 tt_ptr_op(chosen_srv, OP_EQ, NULL);
1056 /* We will now lower the AuthDirNumSRVAgreements requirement by tweaking the
1057 * consensus parameter and we will try again. This time it should work. */
1058 set_num_srv_agreements(7);
1059 chosen_srv = get_majority_srv_from_votes(votes, 1);
1060 tt_assert(chosen_srv);
1061 tt_u64_op(chosen_srv->num_reveals, OP_EQ, 42);
1062 tt_mem_op(chosen_srv->value, OP_EQ, SRV_1, sizeof(chosen_srv->value));
1064 done:
1065 SMARTLIST_FOREACH(votes, networkstatus_t *, vote,
1066 networkstatus_vote_free(vote));
1067 smartlist_free(votes);
1070 static void
1071 test_utils(void *arg)
1073 (void) arg;
1075 /* Testing srv_dup(). */
1077 sr_srv_t *srv = NULL, *dup_srv = NULL;
1078 const char *srv_value =
1079 "1BDB7C3E973936E4D13A49F37C859B3DC69C429334CF9412E3FEF6399C52D47A";
1080 srv = tor_malloc_zero(sizeof(*srv));
1081 srv->num_reveals = 42;
1082 memcpy(srv->value, srv_value, sizeof(srv->value));
1083 dup_srv = srv_dup(srv);
1084 tt_assert(dup_srv);
1085 tt_u64_op(dup_srv->num_reveals, OP_EQ, srv->num_reveals);
1086 tt_mem_op(dup_srv->value, OP_EQ, srv->value, sizeof(srv->value));
1087 tor_free(srv);
1088 tor_free(dup_srv);
1091 /* Testing commitments_are_the_same(). Currently, the check is to test the
1092 * value of the encoded commit so let's make sure that actually works. */
1094 /* Payload of 57 bytes that is the length of sr_commit_t->encoded_commit.
1095 * 56 bytes of payload and a NUL terminated byte at the end ('\x00')
1096 * which comes down to SR_COMMIT_BASE64_LEN + 1. */
1097 const char *payload =
1098 "\x5d\xb9\x60\xb6\xcc\x51\x68\x52\x31\xd9\x88\x88\x71\x71\xe0\x30"
1099 "\x59\x55\x7f\xcd\x61\xc0\x4b\x05\xb8\xcd\xc1\x48\xe9\xcd\x16\x1f"
1100 "\x70\x15\x0c\xfc\xd3\x1a\x75\xd0\x93\x6c\xc4\xe0\x5c\xbe\xe2\x18"
1101 "\xc7\xaf\x72\xb6\x7c\x9b\x52\x00";
1102 sr_commit_t commit1, commit2;
1103 memcpy(commit1.encoded_commit, payload, sizeof(commit1.encoded_commit));
1104 memcpy(commit2.encoded_commit, payload, sizeof(commit2.encoded_commit));
1105 tt_int_op(commitments_are_the_same(&commit1, &commit2), OP_EQ, 1);
1106 /* Let's corrupt one of them. */
1107 memset(commit1.encoded_commit, 'A', sizeof(commit1.encoded_commit));
1108 tt_int_op(commitments_are_the_same(&commit1, &commit2), OP_EQ, 0);
1111 /* Testing commit_is_authoritative(). */
1113 crypto_pk_t *k = crypto_pk_new();
1114 char digest[DIGEST_LEN];
1115 sr_commit_t commit;
1117 tt_assert(!crypto_pk_generate_key(k));
1119 tt_int_op(0, OP_EQ, crypto_pk_get_digest(k, digest));
1120 memcpy(commit.rsa_identity, digest, sizeof(commit.rsa_identity));
1121 tt_int_op(commit_is_authoritative(&commit, digest), OP_EQ, 1);
1122 /* Change the pubkey. */
1123 memset(commit.rsa_identity, 0, sizeof(commit.rsa_identity));
1124 tt_int_op(commit_is_authoritative(&commit, digest), OP_EQ, 0);
1125 crypto_pk_free(k);
1128 /* Testing get_phase_str(). */
1130 tt_str_op(get_phase_str(SR_PHASE_REVEAL), OP_EQ, "reveal");
1131 tt_str_op(get_phase_str(SR_PHASE_COMMIT), OP_EQ, "commit");
1134 /* Testing phase transition */
1136 init_authority_state();
1137 set_sr_phase(SR_PHASE_COMMIT);
1138 tt_int_op(is_phase_transition(SR_PHASE_REVEAL), OP_EQ, 1);
1139 tt_int_op(is_phase_transition(SR_PHASE_COMMIT), OP_EQ, 0);
1140 set_sr_phase(SR_PHASE_REVEAL);
1141 tt_int_op(is_phase_transition(SR_PHASE_REVEAL), OP_EQ, 0);
1142 tt_int_op(is_phase_transition(SR_PHASE_COMMIT), OP_EQ, 1);
1143 /* Junk. */
1144 tt_int_op(is_phase_transition(42), OP_EQ, 1);
1147 done:
1148 return;
1151 static void
1152 test_state_transition(void *arg)
1154 sr_state_t *state = NULL;
1155 time_t now = time(NULL);
1157 (void) arg;
1159 { /* Setup a minimal dirauth environment for this test */
1160 init_authority_state();
1161 state = get_sr_state();
1162 tt_assert(state);
1165 /* Test our state reset for a new protocol run. */
1167 /* Add a commit to the state so we can test if the reset cleans the
1168 * commits. Also, change all params that we expect to be updated. */
1169 sr_commit_t *commit = sr_generate_our_commit(now, mock_cert);
1170 tt_assert(commit);
1171 sr_state_add_commit(commit);
1172 tt_int_op(digestmap_size(state->commits), OP_EQ, 1);
1173 /* Let's test our delete feature. */
1174 sr_state_delete_commits();
1175 tt_int_op(digestmap_size(state->commits), OP_EQ, 0);
1176 /* Add it back so we can continue the rest of the test because after
1177 * deletiong our commit will be freed so generate a new one. */
1178 commit = sr_generate_our_commit(now, mock_cert);
1179 tt_assert(commit);
1180 sr_state_add_commit(commit);
1181 tt_int_op(digestmap_size(state->commits), OP_EQ, 1);
1182 state->n_reveal_rounds = 42;
1183 state->n_commit_rounds = 43;
1184 state->n_protocol_runs = 44;
1185 reset_state_for_new_protocol_run(now);
1186 tt_int_op(state->n_reveal_rounds, OP_EQ, 0);
1187 tt_int_op(state->n_commit_rounds, OP_EQ, 0);
1188 tt_u64_op(state->n_protocol_runs, OP_EQ, 45);
1189 tt_int_op(digestmap_size(state->commits), OP_EQ, 0);
1192 /* Test SRV rotation in our state. */
1194 const sr_srv_t *cur, *prev;
1195 test_sr_setup_srv(1);
1196 cur = sr_state_get_current_srv();
1197 tt_assert(cur);
1198 /* After, current srv should be the previous and then set to NULL. */
1199 state_rotate_srv();
1200 prev = sr_state_get_previous_srv();
1201 tt_assert(prev == cur);
1202 tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
1203 sr_state_clean_srvs();
1206 /* New protocol run. */
1208 const sr_srv_t *cur;
1209 /* Setup some new SRVs so we can confirm that a new protocol run
1210 * actually makes them rotate and compute new ones. */
1211 test_sr_setup_srv(1);
1212 cur = sr_state_get_current_srv();
1213 tt_assert(cur);
1214 set_sr_phase(SR_PHASE_REVEAL);
1215 MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m);
1216 new_protocol_run(now);
1217 UNMOCK(get_my_v3_authority_cert);
1218 /* Rotation happened. */
1219 tt_assert(sr_state_get_previous_srv() == cur);
1220 /* We are going into COMMIT phase so we had to rotate our SRVs. Usually
1221 * our current SRV would be NULL but a new protocol run should make us
1222 * compute a new SRV. */
1223 tt_assert(sr_state_get_current_srv());
1224 /* Also, make sure we did change the current. */
1225 tt_assert(sr_state_get_current_srv() != cur);
1226 /* We should have our commitment alone. */
1227 tt_int_op(digestmap_size(state->commits), OP_EQ, 1);
1228 tt_int_op(state->n_reveal_rounds, OP_EQ, 0);
1229 tt_int_op(state->n_commit_rounds, OP_EQ, 0);
1230 /* 46 here since we were at 45 just before. */
1231 tt_u64_op(state->n_protocol_runs, OP_EQ, 46);
1234 /* Cleanup of SRVs. */
1236 sr_state_clean_srvs();
1237 tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
1238 tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
1241 done:
1242 return;
1245 static void
1246 test_keep_commit(void *arg)
1248 char fp[FINGERPRINT_LEN + 1];
1249 sr_commit_t *commit = NULL, *dup_commit = NULL;
1250 sr_state_t *state;
1251 time_t now = time(NULL);
1252 crypto_pk_t *k = NULL;
1254 (void) arg;
1256 MOCK(trusteddirserver_get_by_v3_auth_digest,
1257 trusteddirserver_get_by_v3_auth_digest_m);
1260 k = pk_generate(1);
1261 /* Setup a minimal dirauth environment for this test */
1262 /* Have a key that is not the one from our commit. */
1263 init_authority_state();
1264 state = get_sr_state();
1267 crypto_rand((char*)fp, sizeof(fp));
1269 /* Test this very important function that tells us if we should keep a
1270 * commit or not in our state. Most of it depends on the phase and what's
1271 * in the commit so we'll change the commit as we go. */
1272 commit = sr_generate_our_commit(now, mock_cert);
1273 tt_assert(commit);
1274 /* Set us in COMMIT phase for starter. */
1275 set_sr_phase(SR_PHASE_COMMIT);
1276 /* We should never keep a commit from a non authoritative authority. */
1277 tt_int_op(should_keep_commit(commit, fp, SR_PHASE_COMMIT), OP_EQ, 0);
1278 /* This should NOT be kept because it has a reveal value in it. */
1279 tt_assert(commit_has_reveal_value(commit));
1280 tt_int_op(should_keep_commit(commit, commit->rsa_identity,
1281 SR_PHASE_COMMIT), OP_EQ, 0);
1282 /* Add it to the state which should return to not keep it. */
1283 sr_state_add_commit(commit);
1284 tt_int_op(should_keep_commit(commit, commit->rsa_identity,
1285 SR_PHASE_COMMIT), OP_EQ, 0);
1286 /* Remove it from state so we can continue our testing. */
1287 digestmap_remove(state->commits, commit->rsa_identity);
1288 /* Let's remove our reveal value which should make it OK to keep it. */
1289 memset(commit->encoded_reveal, 0, sizeof(commit->encoded_reveal));
1290 tt_int_op(should_keep_commit(commit, commit->rsa_identity,
1291 SR_PHASE_COMMIT), OP_EQ, 1);
1293 /* Let's reset our commit and go into REVEAL phase. */
1294 sr_commit_free(commit);
1295 commit = sr_generate_our_commit(now, mock_cert);
1296 tt_assert(commit);
1297 /* Dup the commit so we have one with and one without a reveal value. */
1298 dup_commit = tor_malloc_zero(sizeof(*dup_commit));
1299 memcpy(dup_commit, commit, sizeof(*dup_commit));
1300 memset(dup_commit->encoded_reveal, 0, sizeof(dup_commit->encoded_reveal));
1301 set_sr_phase(SR_PHASE_REVEAL);
1302 /* We should never keep a commit from a non authoritative authority. */
1303 tt_int_op(should_keep_commit(commit, fp, SR_PHASE_REVEAL), OP_EQ, 0);
1304 /* We shouldn't accept a commit that is not in our state. */
1305 tt_int_op(should_keep_commit(commit, commit->rsa_identity,
1306 SR_PHASE_REVEAL), OP_EQ, 0);
1307 /* Important to add the commit _without_ the reveal here. */
1308 sr_state_add_commit(dup_commit);
1309 tt_int_op(digestmap_size(state->commits), OP_EQ, 1);
1310 /* Our commit should be valid that is authoritative, contains a reveal, be
1311 * in the state and commitment and reveal values match. */
1312 tt_int_op(should_keep_commit(commit, commit->rsa_identity,
1313 SR_PHASE_REVEAL), OP_EQ, 1);
1314 /* The commit shouldn't be kept if it's not verified that is no matchin
1315 * hashed reveal. */
1317 /* Let's save the hash reveal so we can restore it. */
1318 sr_commit_t place_holder;
1319 memcpy(place_holder.hashed_reveal, commit->hashed_reveal,
1320 sizeof(place_holder.hashed_reveal));
1321 memset(commit->hashed_reveal, 0, sizeof(commit->hashed_reveal));
1322 setup_full_capture_of_logs(LOG_WARN);
1323 tt_int_op(should_keep_commit(commit, commit->rsa_identity,
1324 SR_PHASE_REVEAL), OP_EQ, 0);
1325 expect_log_msg_containing("doesn't match the commit value.");
1326 expect_log_msg_containing("has an invalid reveal value.");
1327 assert_log_predicate(mock_saved_log_n_entries() == 2,
1328 ("expected 2 log entries"));
1329 teardown_capture_of_logs();
1330 memcpy(commit->hashed_reveal, place_holder.hashed_reveal,
1331 sizeof(commit->hashed_reveal));
1333 /* We shouldn't keep a commit that has no reveal. */
1334 tt_int_op(should_keep_commit(dup_commit, dup_commit->rsa_identity,
1335 SR_PHASE_REVEAL), OP_EQ, 0);
1336 /* We must not keep a commit that is not the same from the commit phase. */
1337 memset(commit->encoded_commit, 0, sizeof(commit->encoded_commit));
1338 tt_int_op(should_keep_commit(commit, commit->rsa_identity,
1339 SR_PHASE_REVEAL), OP_EQ, 0);
1341 done:
1342 teardown_capture_of_logs();
1343 sr_commit_free(commit);
1344 sr_commit_free(dup_commit);
1345 crypto_pk_free(k);
1346 UNMOCK(trusteddirserver_get_by_v3_auth_digest);
1349 static void
1350 test_state_update(void *arg)
1352 time_t commit_phase_time = 1452076000;
1353 time_t reveal_phase_time = 1452086800;
1354 sr_state_t *state;
1356 (void) arg;
1359 init_authority_state();
1360 state = get_sr_state();
1361 set_sr_phase(SR_PHASE_COMMIT);
1362 /* We'll cheat a bit here and reset the creation time of the state which
1363 * will avoid us to compute a valid_after time that fits the commit
1364 * phase. */
1365 state->valid_after = 0;
1366 state->n_reveal_rounds = 0;
1367 state->n_commit_rounds = 0;
1368 state->n_protocol_runs = 0;
1371 /* We need to mock for the state update function call. */
1372 MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m);
1374 /* We are in COMMIT phase here and we'll trigger a state update but no
1375 * transition. */
1376 sr_state_update(commit_phase_time);
1377 tt_int_op(state->valid_after, OP_EQ, commit_phase_time);
1378 tt_int_op(state->n_commit_rounds, OP_EQ, 1);
1379 tt_int_op(state->phase, OP_EQ, SR_PHASE_COMMIT);
1380 tt_int_op(digestmap_size(state->commits), OP_EQ, 1);
1382 /* We are still in the COMMIT phase here but we'll trigger a state
1383 * transition to the REVEAL phase. */
1384 sr_state_update(reveal_phase_time);
1385 tt_int_op(state->phase, OP_EQ, SR_PHASE_REVEAL);
1386 tt_int_op(state->valid_after, OP_EQ, reveal_phase_time);
1387 /* Only our commit should be in there. */
1388 tt_int_op(digestmap_size(state->commits), OP_EQ, 1);
1389 tt_int_op(state->n_reveal_rounds, OP_EQ, 1);
1391 /* We can't update a state with a valid after _lower_ than the creation
1392 * time so here it is. */
1393 sr_state_update(commit_phase_time);
1394 tt_int_op(state->valid_after, OP_EQ, reveal_phase_time);
1396 /* Finally, let's go back in COMMIT phase so we can test the state update
1397 * of a new protocol run. */
1398 state->valid_after = 0;
1399 sr_state_update(commit_phase_time);
1400 tt_int_op(state->valid_after, OP_EQ, commit_phase_time);
1401 tt_int_op(state->n_commit_rounds, OP_EQ, 1);
1402 tt_int_op(state->n_reveal_rounds, OP_EQ, 0);
1403 tt_u64_op(state->n_protocol_runs, OP_EQ, 1);
1404 tt_int_op(state->phase, OP_EQ, SR_PHASE_COMMIT);
1405 tt_int_op(digestmap_size(state->commits), OP_EQ, 1);
1406 tt_assert(state->current_srv);
1408 done:
1409 sr_state_free_all();
1410 UNMOCK(get_my_v3_authority_cert);
1413 struct testcase_t sr_tests[] = {
1414 { "get_sr_protocol_phase", test_get_sr_protocol_phase, TT_FORK,
1415 NULL, NULL },
1416 { "sr_commit", test_sr_commit, TT_FORK,
1417 NULL, NULL },
1418 { "keep_commit", test_keep_commit, TT_FORK,
1419 NULL, NULL },
1420 { "encoding", test_encoding, TT_FORK,
1421 NULL, NULL },
1422 { "get_start_time_of_current_run", test_get_start_time_of_current_run,
1423 TT_FORK, NULL, NULL },
1424 { "get_start_time_functions", test_get_start_time_functions,
1425 TT_FORK, NULL, NULL },
1426 { "get_sr_protocol_duration", test_get_sr_protocol_duration, TT_FORK,
1427 NULL, NULL },
1428 { "get_state_valid_until_time", test_get_state_valid_until_time, TT_FORK,
1429 NULL, NULL },
1430 { "vote", test_vote, TT_FORK,
1431 NULL, NULL },
1432 { "state_load_from_disk", test_state_load_from_disk, TT_FORK,
1433 NULL, NULL },
1434 { "sr_compute_srv", test_sr_compute_srv, TT_FORK, NULL, NULL },
1435 { "sr_get_majority_srv_from_votes", test_sr_get_majority_srv_from_votes,
1436 TT_FORK, NULL, NULL },
1437 { "utils", test_utils, TT_FORK, NULL, NULL },
1438 { "state_transition", test_state_transition, TT_FORK, NULL, NULL },
1439 { "state_update", test_state_update, TT_FORK,
1440 NULL, NULL },
1441 END_OF_TESTCASES