Make dir servers include a "Date:" http header more often
[tor.git] / src / test / test_shared_random.c
blob4c303cbb35b26013e973244b48e1df6a7ccb40d6
1 #define SHARED_RANDOM_PRIVATE
2 #define SHARED_RANDOM_STATE_PRIVATE
3 #define CONFIG_PRIVATE
4 #define DIRVOTE_PRIVATE
6 #include "or.h"
7 #include "test.h"
8 #include "config.h"
9 #include "dirvote.h"
10 #include "shared_random.h"
11 #include "shared_random_state.h"
12 #include "routerkeys.h"
13 #include "routerlist.h"
14 #include "router.h"
15 #include "routerparse.h"
16 #include "networkstatus.h"
17 #include "log_test_helpers.h"
19 static authority_cert_t *mock_cert;
21 static authority_cert_t *
22 get_my_v3_authority_cert_m(void)
24 tor_assert(mock_cert);
25 return mock_cert;
28 static dir_server_t ds;
30 static dir_server_t *
31 trusteddirserver_get_by_v3_auth_digest_m(const char *digest)
33 (void) digest;
34 /* The shared random code only need to know if a valid pointer to a dir
35 * server object has been found so this is safe because it won't use the
36 * pointer at all never. */
37 return &ds;
40 /* Setup a minimal dirauth environment by initializing the SR state and
41 * making sure the options are set to be an authority directory. */
42 static void
43 init_authority_state(void)
45 MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m);
47 or_options_t *options = get_options_mutable();
48 mock_cert = authority_cert_parse_from_string(AUTHORITY_CERT_1, NULL);
49 tt_assert(mock_cert);
50 options->AuthoritativeDir = 1;
51 tt_int_op(load_ed_keys(options, time(NULL)), OP_GE, 0);
52 sr_state_init(0, 0);
53 /* It's possible a commit has been generated in our state depending on
54 * the phase we are currently in which uses "now" as the starting
55 * timestamp. Delete it before we do any testing below. */
56 sr_state_delete_commits();
58 done:
59 UNMOCK(get_my_v3_authority_cert);
62 static void
63 test_get_sr_protocol_phase(void *arg)
65 time_t the_time;
66 sr_phase_t phase;
67 int retval;
69 (void) arg;
71 /* Initialize SR state */
72 init_authority_state();
75 retval = parse_rfc1123_time("Wed, 20 Apr 2015 23:59:00 UTC", &the_time);
76 tt_int_op(retval, OP_EQ, 0);
78 phase = get_sr_protocol_phase(the_time);
79 tt_int_op(phase, OP_EQ, SR_PHASE_REVEAL);
83 retval = parse_rfc1123_time("Wed, 20 Apr 2015 00:00:00 UTC", &the_time);
84 tt_int_op(retval, OP_EQ, 0);
86 phase = get_sr_protocol_phase(the_time);
87 tt_int_op(phase, OP_EQ, SR_PHASE_COMMIT);
91 retval = parse_rfc1123_time("Wed, 20 Apr 2015 00:00:01 UTC", &the_time);
92 tt_int_op(retval, OP_EQ, 0);
94 phase = get_sr_protocol_phase(the_time);
95 tt_int_op(phase, OP_EQ, SR_PHASE_COMMIT);
99 retval = parse_rfc1123_time("Wed, 20 Apr 2015 11:59:00 UTC", &the_time);
100 tt_int_op(retval, OP_EQ, 0);
102 phase = get_sr_protocol_phase(the_time);
103 tt_int_op(phase, OP_EQ, SR_PHASE_COMMIT);
107 retval = parse_rfc1123_time("Wed, 20 Apr 2015 12:00:00 UTC", &the_time);
108 tt_int_op(retval, OP_EQ, 0);
110 phase = get_sr_protocol_phase(the_time);
111 tt_int_op(phase, OP_EQ, SR_PHASE_REVEAL);
115 retval = parse_rfc1123_time("Wed, 20 Apr 2015 12:00:01 UTC", &the_time);
116 tt_int_op(retval, OP_EQ, 0);
118 phase = get_sr_protocol_phase(the_time);
119 tt_int_op(phase, OP_EQ, SR_PHASE_REVEAL);
123 retval = parse_rfc1123_time("Wed, 20 Apr 2015 13:00:00 UTC", &the_time);
124 tt_int_op(retval, OP_EQ, 0);
126 phase = get_sr_protocol_phase(the_time);
127 tt_int_op(phase, OP_EQ, SR_PHASE_REVEAL);
130 done:
134 static networkstatus_t *mock_consensus = NULL;
136 static void
137 test_get_state_valid_until_time(void *arg)
139 time_t current_time;
140 time_t valid_until_time;
141 char tbuf[ISO_TIME_LEN + 1];
142 int retval;
144 (void) arg;
147 /* Get the valid until time if called at 00:00:01 */
148 retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:00:01 UTC",
149 &current_time);
150 tt_int_op(retval, OP_EQ, 0);
151 valid_until_time = get_state_valid_until_time(current_time);
153 /* Compare it with the correct result */
154 format_iso_time(tbuf, valid_until_time);
155 tt_str_op("2015-04-21 00:00:00", OP_EQ, tbuf);
159 retval = parse_rfc1123_time("Mon, 20 Apr 2015 19:22:00 UTC",
160 &current_time);
161 tt_int_op(retval, OP_EQ, 0);
162 valid_until_time = get_state_valid_until_time(current_time);
164 format_iso_time(tbuf, valid_until_time);
165 tt_str_op("2015-04-21 00:00:00", OP_EQ, tbuf);
169 retval = parse_rfc1123_time("Mon, 20 Apr 2015 23:59:00 UTC",
170 &current_time);
171 tt_int_op(retval, OP_EQ, 0);
172 valid_until_time = get_state_valid_until_time(current_time);
174 format_iso_time(tbuf, valid_until_time);
175 tt_str_op("2015-04-21 00:00:00", OP_EQ, tbuf);
179 retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:00:00 UTC",
180 &current_time);
181 tt_int_op(retval, OP_EQ, 0);
182 valid_until_time = get_state_valid_until_time(current_time);
184 format_iso_time(tbuf, valid_until_time);
185 tt_str_op("2015-04-21 00:00:00", OP_EQ, tbuf);
188 done:
192 /** Test the function that calculates the start time of the current SRV
193 * protocol run. */
194 static void
195 test_get_start_time_of_current_run(void *arg)
197 int retval;
198 char tbuf[ISO_TIME_LEN + 1];
199 time_t current_time, run_start_time;
201 (void) arg;
204 /* Get start time if called at 00:00:01 */
205 retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:00:01 UTC",
206 &current_time);
207 tt_int_op(retval, OP_EQ, 0);
208 run_start_time =
209 sr_state_get_start_time_of_current_protocol_run(current_time);
211 /* Compare it with the correct result */
212 format_iso_time(tbuf, run_start_time);
213 tt_str_op("2015-04-20 00:00:00", OP_EQ, tbuf);
217 retval = parse_rfc1123_time("Mon, 20 Apr 2015 23:59:59 UTC",
218 &current_time);
219 tt_int_op(retval, OP_EQ, 0);
220 run_start_time =
221 sr_state_get_start_time_of_current_protocol_run(current_time);
223 /* Compare it with the correct result */
224 format_iso_time(tbuf, run_start_time);
225 tt_str_op("2015-04-20 00:00:00", OP_EQ, tbuf);
229 retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:00:00 UTC",
230 &current_time);
231 tt_int_op(retval, OP_EQ, 0);
232 run_start_time =
233 sr_state_get_start_time_of_current_protocol_run(current_time);
235 /* Compare it with the correct result */
236 format_iso_time(tbuf, run_start_time);
237 tt_str_op("2015-04-20 00:00:00", OP_EQ, tbuf);
240 /* Now let's alter the voting schedule and check the correctness of the
241 * function. Voting interval of 10 seconds, means that an SRV protocol run
242 * takes 10 seconds * 24 rounds = 4 mins */
244 or_options_t *options = get_options_mutable();
245 options->V3AuthVotingInterval = 10;
246 options->TestingV3AuthInitialVotingInterval = 10;
247 retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:15:32 UTC",
248 &current_time);
250 tt_int_op(retval, OP_EQ, 0);
251 run_start_time =
252 sr_state_get_start_time_of_current_protocol_run(current_time);
254 /* Compare it with the correct result */
255 format_iso_time(tbuf, run_start_time);
256 tt_str_op("2015-04-20 00:12:00", OP_EQ, tbuf);
259 done:
263 /** Do some rudimentary consistency checks between the functions that
264 * understand the shared random protocol schedule */
265 static void
266 test_get_start_time_functions(void *arg)
268 (void) arg;
269 time_t now = approx_time();
271 time_t start_time_of_protocol_run =
272 sr_state_get_start_time_of_current_protocol_run(now);
273 tt_assert(start_time_of_protocol_run);
275 /* Check that the round start time of the beginning of the run, is itself */
276 tt_int_op(get_start_time_of_current_round(start_time_of_protocol_run), OP_EQ,
277 start_time_of_protocol_run);
279 /* Check that even if we increment the start time, we still get the start
280 time of the run as the beginning of the round. */
281 tt_int_op(get_start_time_of_current_round(start_time_of_protocol_run+1),
282 OP_EQ, start_time_of_protocol_run);
284 done: ;
287 static void
288 test_get_sr_protocol_duration(void *arg)
290 (void) arg;
292 /* Check that by default an SR phase is 12 hours */
293 tt_int_op(sr_state_get_phase_duration(), OP_EQ, 12*60*60);
294 tt_int_op(sr_state_get_protocol_run_duration(), OP_EQ, 24*60*60);
296 /* Now alter the voting interval and check that the SR phase is 2 mins long
297 * if voting happens every 10 seconds (10*12 seconds = 2 mins) */
298 or_options_t *options = get_options_mutable();
299 options->V3AuthVotingInterval = 10;
300 tt_int_op(sr_state_get_phase_duration(), OP_EQ, 2*60);
301 tt_int_op(sr_state_get_protocol_run_duration(), OP_EQ, 4*60);
303 done: ;
306 /* Mock function to immediately return our local 'mock_consensus'. */
307 static networkstatus_t *
308 mock_networkstatus_get_live_consensus(time_t now)
310 (void) now;
311 return mock_consensus;
314 /** Test the get_next_valid_after_time() function. */
315 static void
316 test_get_next_valid_after_time(void *arg)
318 time_t current_time;
319 time_t valid_after_time;
320 char tbuf[ISO_TIME_LEN + 1];
321 int retval;
323 (void) arg;
326 /* Setup a fake consensus just to get the times out of it, since
327 get_next_valid_after_time() needs them. */
328 mock_consensus = tor_malloc_zero(sizeof(networkstatus_t));
330 retval = parse_rfc1123_time("Mon, 13 Jan 2016 16:00:00 UTC",
331 &mock_consensus->fresh_until);
332 tt_int_op(retval, OP_EQ, 0);
334 retval = parse_rfc1123_time("Mon, 13 Jan 2016 15:00:00 UTC",
335 &mock_consensus->valid_after);
336 tt_int_op(retval, OP_EQ, 0);
338 MOCK(networkstatus_get_live_consensus,
339 mock_networkstatus_get_live_consensus);
343 /* Get the valid after time if called at 00:00:00 */
344 retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:00:00 UTC",
345 &current_time);
346 tt_int_op(retval, OP_EQ, 0);
347 valid_after_time = get_next_valid_after_time(current_time);
349 /* Compare it with the correct result */
350 format_iso_time(tbuf, valid_after_time);
351 tt_str_op("2015-04-20 01:00:00", OP_EQ, tbuf);
355 /* Get the valid until time if called at 00:00:01 */
356 retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:00:01 UTC",
357 &current_time);
358 tt_int_op(retval, OP_EQ, 0);
359 valid_after_time = get_next_valid_after_time(current_time);
361 /* Compare it with the correct result */
362 format_iso_time(tbuf, valid_after_time);
363 tt_str_op("2015-04-20 01:00:00", OP_EQ, tbuf);
367 retval = parse_rfc1123_time("Mon, 20 Apr 2015 23:30:01 UTC",
368 &current_time);
369 tt_int_op(retval, OP_EQ, 0);
370 valid_after_time = get_next_valid_after_time(current_time);
372 /* Compare it with the correct result */
373 format_iso_time(tbuf, valid_after_time);
374 tt_str_op("2015-04-21 00:00:00", OP_EQ, tbuf);
377 done:
378 networkstatus_vote_free(mock_consensus);
381 /* In this test we are going to generate a sr_commit_t object and validate
382 * it. We first generate our values, and then we parse them as if they were
383 * received from the network. After we parse both the commit and the reveal,
384 * we verify that they indeed match. */
385 static void
386 test_sr_commit(void *arg)
388 authority_cert_t *auth_cert = NULL;
389 time_t now = time(NULL);
390 sr_commit_t *our_commit = NULL;
391 smartlist_t *args = smartlist_new();
392 sr_commit_t *parsed_commit = NULL;
394 (void) arg;
396 { /* Setup a minimal dirauth environment for this test */
397 or_options_t *options = get_options_mutable();
399 auth_cert = authority_cert_parse_from_string(AUTHORITY_CERT_1, NULL);
400 tt_assert(auth_cert);
402 options->AuthoritativeDir = 1;
403 tt_int_op(load_ed_keys(options, time(NULL)), OP_GE, 0);
406 /* Generate our commit object and validate it has the appropriate field
407 * that we can then use to build a representation that we'll find in a
408 * vote coming from the network. */
410 sr_commit_t test_commit;
411 our_commit = sr_generate_our_commit(now, auth_cert);
412 tt_assert(our_commit);
413 /* Default and only supported algorithm for now. */
414 tt_assert(our_commit->alg == DIGEST_SHA3_256);
415 /* We should have a reveal value. */
416 tt_assert(commit_has_reveal_value(our_commit));
417 /* We should have a random value. */
418 tt_assert(!tor_mem_is_zero((char *) our_commit->random_number,
419 sizeof(our_commit->random_number)));
420 /* Commit and reveal timestamp should be the same. */
421 tt_u64_op(our_commit->commit_ts, OP_EQ, our_commit->reveal_ts);
422 /* We should have a hashed reveal. */
423 tt_assert(!tor_mem_is_zero(our_commit->hashed_reveal,
424 sizeof(our_commit->hashed_reveal)));
425 /* Do we have a valid encoded commit and reveal. Note the following only
426 * tests if the generated values are correct. Their could be a bug in
427 * the decode function but we test them seperately. */
428 tt_int_op(0, OP_EQ, reveal_decode(our_commit->encoded_reveal,
429 &test_commit));
430 tt_int_op(0, OP_EQ, commit_decode(our_commit->encoded_commit,
431 &test_commit));
432 tt_int_op(0, OP_EQ, verify_commit_and_reveal(our_commit));
435 /* Let's make sure our verify commit and reveal function works. We'll
436 * make it fail a bit with known failure case. */
438 /* Copy our commit so we don't alter it for the rest of testing. */
439 sr_commit_t test_commit;
440 memcpy(&test_commit, our_commit, sizeof(test_commit));
442 /* Timestamp MUST match. */
443 test_commit.commit_ts = test_commit.reveal_ts - 42;
444 setup_full_capture_of_logs(LOG_WARN);
445 tt_int_op(-1, OP_EQ, verify_commit_and_reveal(&test_commit));
446 expect_log_msg_containing("doesn't match reveal timestamp");
447 teardown_capture_of_logs();
448 memcpy(&test_commit, our_commit, sizeof(test_commit));
449 tt_int_op(0, OP_EQ, verify_commit_and_reveal(&test_commit));
451 /* Hashed reveal must match the H(encoded_reveal). */
452 memset(test_commit.hashed_reveal, 'X',
453 sizeof(test_commit.hashed_reveal));
454 setup_full_capture_of_logs(LOG_WARN);
455 tt_int_op(-1, OP_EQ, verify_commit_and_reveal(&test_commit));
456 expect_single_log_msg_containing("doesn't match the commit value");
457 teardown_capture_of_logs();
458 memcpy(&test_commit, our_commit, sizeof(test_commit));
459 tt_int_op(0, OP_EQ, verify_commit_and_reveal(&test_commit));
462 /* We'll build a list of values from our commit that our parsing function
463 * takes from a vote line and see if we can parse it correctly. */
465 smartlist_add_strdup(args, "1");
466 smartlist_add_strdup(args,
467 crypto_digest_algorithm_get_name(our_commit->alg));
468 smartlist_add_strdup(args, sr_commit_get_rsa_fpr(our_commit));
469 smartlist_add_strdup(args, our_commit->encoded_commit);
470 smartlist_add_strdup(args, our_commit->encoded_reveal);
471 parsed_commit = sr_parse_commit(args);
472 tt_assert(parsed_commit);
473 /* That parsed commit should be _EXACTLY_ like our original commit (we
474 * have to explicitly set the valid flag though). */
475 parsed_commit->valid = 1;
476 tt_mem_op(parsed_commit, OP_EQ, our_commit, sizeof(*parsed_commit));
477 /* Cleanup */
480 done:
481 teardown_capture_of_logs();
482 SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
483 smartlist_free(args);
484 sr_commit_free(our_commit);
485 sr_commit_free(parsed_commit);
486 authority_cert_free(auth_cert);
489 /* Test the encoding and decoding function for commit and reveal values. */
490 static void
491 test_encoding(void *arg)
493 (void) arg;
494 int ret;
495 /* Random number is 32 bytes. */
496 char raw_rand[32];
497 time_t ts = 1454333590;
498 char hashed_rand[DIGEST256_LEN], hashed_reveal[DIGEST256_LEN];
499 sr_commit_t parsed_commit;
501 /* Those values were generated by sr_commit_calc_ref.py where the random
502 * value is 32 'A' and timestamp is the one in ts. */
503 static const char *encoded_reveal =
504 "AAAAAFavXpZJxbwTupvaJCTeIUCQmOPxAMblc7ChL5H2nZKuGchdaA==";
505 static const char *encoded_commit =
506 "AAAAAFavXpbkBMzMQG7aNoaGLFNpm2Wkk1ozXhuWWqL//GynltxVAg==";
508 /* Set up our raw random bytes array. */
509 memset(raw_rand, 'A', sizeof(raw_rand));
510 /* Hash random number because we don't expose bytes of the RNG. */
511 ret = crypto_digest256(hashed_rand, raw_rand,
512 sizeof(raw_rand), SR_DIGEST_ALG);
513 tt_int_op(0, OP_EQ, ret);
514 /* Hash reveal value. */
515 tt_int_op(SR_REVEAL_BASE64_LEN, OP_EQ, strlen(encoded_reveal));
516 ret = crypto_digest256(hashed_reveal, encoded_reveal,
517 strlen(encoded_reveal), SR_DIGEST_ALG);
518 tt_int_op(0, OP_EQ, ret);
519 tt_int_op(SR_COMMIT_BASE64_LEN, OP_EQ, strlen(encoded_commit));
521 /* Test our commit/reveal decode functions. */
523 /* Test the reveal encoded value. */
524 tt_int_op(0, OP_EQ, reveal_decode(encoded_reveal, &parsed_commit));
525 tt_u64_op(ts, OP_EQ, parsed_commit.reveal_ts);
526 tt_mem_op(hashed_rand, OP_EQ, parsed_commit.random_number,
527 sizeof(hashed_rand));
529 /* Test the commit encoded value. */
530 memset(&parsed_commit, 0, sizeof(parsed_commit));
531 tt_int_op(0, OP_EQ, commit_decode(encoded_commit, &parsed_commit));
532 tt_u64_op(ts, OP_EQ, parsed_commit.commit_ts);
533 tt_mem_op(encoded_commit, OP_EQ, parsed_commit.encoded_commit,
534 sizeof(parsed_commit.encoded_commit));
535 tt_mem_op(hashed_reveal, OP_EQ, parsed_commit.hashed_reveal,
536 sizeof(hashed_reveal));
539 /* Test our commit/reveal encode functions. */
541 /* Test the reveal encode. */
542 char encoded[SR_REVEAL_BASE64_LEN + 1];
543 parsed_commit.reveal_ts = ts;
544 memcpy(parsed_commit.random_number, hashed_rand,
545 sizeof(parsed_commit.random_number));
546 ret = reveal_encode(&parsed_commit, encoded, sizeof(encoded));
547 tt_int_op(SR_REVEAL_BASE64_LEN, OP_EQ, ret);
548 tt_mem_op(encoded_reveal, OP_EQ, encoded, strlen(encoded_reveal));
552 /* Test the commit encode. */
553 char encoded[SR_COMMIT_BASE64_LEN + 1];
554 parsed_commit.commit_ts = ts;
555 memcpy(parsed_commit.hashed_reveal, hashed_reveal,
556 sizeof(parsed_commit.hashed_reveal));
557 ret = commit_encode(&parsed_commit, encoded, sizeof(encoded));
558 tt_int_op(SR_COMMIT_BASE64_LEN, OP_EQ, ret);
559 tt_mem_op(encoded_commit, OP_EQ, encoded, strlen(encoded_commit));
562 done:
566 /** Setup some SRVs in our SR state. If <b>also_current</b> is set, then set
567 * both current and previous SRVs.
568 * Helper of test_vote() and test_sr_compute_srv(). */
569 static void
570 test_sr_setup_srv(int also_current)
572 sr_srv_t *srv = tor_malloc_zero(sizeof(sr_srv_t));
573 srv->num_reveals = 42;
574 memcpy(srv->value,
575 "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ",
576 sizeof(srv->value));
578 sr_state_set_previous_srv(srv);
580 if (also_current) {
581 srv = tor_malloc_zero(sizeof(sr_srv_t));
582 srv->num_reveals = 128;
583 memcpy(srv->value,
584 "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN",
585 sizeof(srv->value));
587 sr_state_set_current_srv(srv);
591 /* Test anything that has to do with SR protocol and vote. */
592 static void
593 test_vote(void *arg)
595 int ret;
596 time_t now = time(NULL);
597 sr_commit_t *our_commit = NULL;
599 (void) arg;
601 MOCK(trusteddirserver_get_by_v3_auth_digest,
602 trusteddirserver_get_by_v3_auth_digest_m);
604 { /* Setup a minimal dirauth environment for this test */
605 init_authority_state();
606 /* Set ourself in reveal phase so we can parse the reveal value in the
607 * vote as well. */
608 set_sr_phase(SR_PHASE_REVEAL);
611 /* Generate our commit object and validate it has the appropriate field
612 * that we can then use to build a representation that we'll find in a
613 * vote coming from the network. */
615 sr_commit_t *saved_commit;
616 our_commit = sr_generate_our_commit(now, mock_cert);
617 tt_assert(our_commit);
618 sr_state_add_commit(our_commit);
619 /* Make sure it's there. */
620 saved_commit = sr_state_get_commit(our_commit->rsa_identity);
621 tt_assert(saved_commit);
624 /* Also setup the SRVs */
625 test_sr_setup_srv(1);
627 { /* Now test the vote generation */
628 smartlist_t *chunks = smartlist_new();
629 smartlist_t *tokens = smartlist_new();
630 /* Get our vote line and validate it. */
631 char *lines = sr_get_string_for_vote();
632 tt_assert(lines);
633 /* Split the lines. We expect 2 here. */
634 ret = smartlist_split_string(chunks, lines, "\n", SPLIT_IGNORE_BLANK, 0);
635 tt_int_op(ret, OP_EQ, 4);
636 tt_str_op(smartlist_get(chunks, 0), OP_EQ, "shared-rand-participate");
637 /* Get our commitment line and will validate it agains our commit. The
638 * format is as follow:
639 * "shared-rand-commitment" SP version SP algname SP identity
640 * SP COMMIT [SP REVEAL] NL
642 char *commit_line = smartlist_get(chunks, 1);
643 tt_assert(commit_line);
644 ret = smartlist_split_string(tokens, commit_line, " ", 0, 0);
645 tt_int_op(ret, OP_EQ, 6);
646 tt_str_op(smartlist_get(tokens, 0), OP_EQ, "shared-rand-commit");
647 tt_str_op(smartlist_get(tokens, 1), OP_EQ, "1");
648 tt_str_op(smartlist_get(tokens, 2), OP_EQ,
649 crypto_digest_algorithm_get_name(DIGEST_SHA3_256));
650 char digest[DIGEST_LEN];
651 base16_decode(digest, sizeof(digest), smartlist_get(tokens, 3),
652 HEX_DIGEST_LEN);
653 tt_mem_op(digest, OP_EQ, our_commit->rsa_identity, sizeof(digest));
654 tt_str_op(smartlist_get(tokens, 4), OP_EQ, our_commit->encoded_commit);
655 tt_str_op(smartlist_get(tokens, 5), OP_EQ, our_commit->encoded_reveal)
657 /* Finally, does this vote line creates a valid commit object? */
658 smartlist_t *args = smartlist_new();
659 smartlist_add(args, smartlist_get(tokens, 1));
660 smartlist_add(args, smartlist_get(tokens, 2));
661 smartlist_add(args, smartlist_get(tokens, 3));
662 smartlist_add(args, smartlist_get(tokens, 4));
663 smartlist_add(args, smartlist_get(tokens, 5));
664 sr_commit_t *parsed_commit = sr_parse_commit(args);
665 tt_assert(parsed_commit);
666 /* Set valid flag explicitly here to compare since it's not set by
667 * simply parsing the commit. */
668 parsed_commit->valid = 1;
669 tt_mem_op(parsed_commit, OP_EQ, our_commit, sizeof(*our_commit));
671 /* minor cleanup */
672 SMARTLIST_FOREACH(tokens, char *, s, tor_free(s));
673 smartlist_clear(tokens);
675 /* Now test the previous SRV */
676 char *prev_srv_line = smartlist_get(chunks, 2);
677 tt_assert(prev_srv_line);
678 ret = smartlist_split_string(tokens, prev_srv_line, " ", 0, 0);
679 tt_int_op(ret, OP_EQ, 3);
680 tt_str_op(smartlist_get(tokens, 0), OP_EQ, "shared-rand-previous-value");
681 tt_str_op(smartlist_get(tokens, 1), OP_EQ, "42");
682 tt_str_op(smartlist_get(tokens, 2), OP_EQ,
683 "WlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlo=");
685 /* minor cleanup */
686 SMARTLIST_FOREACH(tokens, char *, s, tor_free(s));
687 smartlist_clear(tokens);
689 /* Now test the current SRV */
690 char *current_srv_line = smartlist_get(chunks, 3);
691 tt_assert(current_srv_line);
692 ret = smartlist_split_string(tokens, current_srv_line, " ", 0, 0);
693 tt_int_op(ret, OP_EQ, 3);
694 tt_str_op(smartlist_get(tokens, 0), OP_EQ, "shared-rand-current-value");
695 tt_str_op(smartlist_get(tokens, 1), OP_EQ, "128");
696 tt_str_op(smartlist_get(tokens, 2), OP_EQ,
697 "Tk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk4=");
699 /* Clean up */
700 sr_commit_free(parsed_commit);
701 SMARTLIST_FOREACH(chunks, char *, s, tor_free(s));
702 smartlist_free(chunks);
703 SMARTLIST_FOREACH(tokens, char *, s, tor_free(s));
704 smartlist_free(tokens);
705 smartlist_clear(args);
706 smartlist_free(args);
707 tor_free(lines);
710 done:
711 sr_commit_free(our_commit);
712 UNMOCK(trusteddirserver_get_by_v3_auth_digest);
715 static const char *sr_state_str = "Version 1\n"
716 "TorVersion 0.2.9.0-alpha-dev\n"
717 "ValidAfter 2037-04-19 07:16:00\n"
718 "ValidUntil 2037-04-20 07:16:00\n"
719 "Commit 1 sha3-256 FA3CEC2C99DC68D3166B9B6E4FA21A4026C2AB1C "
720 "7M8GdubCAAdh7WUG0DiwRyxTYRKji7HATa7LLJEZ/UAAAAAAVmfUSg== "
721 "AAAAAFZn1EojfIheIw42bjK3VqkpYyjsQFSbv/dxNna3Q8hUEPKpOw==\n"
722 "Commit 1 sha3-256 41E89EDFBFBA44983E21F18F2230A4ECB5BFB543 "
723 "17aUsYuMeRjd2N1r8yNyg7aHqRa6gf4z7QPoxxAZbp0AAAAAVmfUSg==\n"
724 "Commit 1 sha3-256 36637026573A04110CF3E6B1D201FB9A98B88734 "
725 "DDDYtripvdOU+XPEUm5xpU64d9IURSds1xSwQsgeB8oAAAAAVmfUSg==\n"
726 "SharedRandPreviousValue 4 qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqo=\n"
727 "SharedRandCurrentValue 3 8dWeW12KEzTGEiLGgO1UVJ7Z91CekoRcxt6Q9KhnOFI=\n";
729 /** Create an SR disk state, parse it and validate that the parsing went
730 * well. Yes! */
731 static void
732 test_state_load_from_disk(void *arg)
734 int ret;
735 char *dir = tor_strdup(get_fname("test_sr_state"));
736 char *sr_state_path = tor_strdup(get_fname("test_sr_state/sr_state"));
737 sr_state_t *the_sr_state = NULL;
739 (void) arg;
741 MOCK(trusteddirserver_get_by_v3_auth_digest,
742 trusteddirserver_get_by_v3_auth_digest_m);
744 /* First try with a nonexistent path. */
745 ret = disk_state_load_from_disk_impl("NONEXISTENTNONEXISTENT");
746 tt_int_op(ret, OP_EQ, -ENOENT);
748 /* Now create a mock state directory and state file */
749 #ifdef _WIN32
750 ret = mkdir(dir);
751 #else
752 ret = mkdir(dir, 0700);
753 #endif
754 tt_int_op(ret, OP_EQ, 0);
755 ret = write_str_to_file(sr_state_path, sr_state_str, 0);
756 tt_int_op(ret, OP_EQ, 0);
758 /* Try to load the directory itself. Should fail. */
759 ret = disk_state_load_from_disk_impl(dir);
760 tt_int_op(ret, OP_LT, 0);
762 /* State should be non-existent at this point. */
763 the_sr_state = get_sr_state();
764 tt_ptr_op(the_sr_state, OP_EQ, NULL);
766 /* Now try to load the correct file! */
767 ret = disk_state_load_from_disk_impl(sr_state_path);
768 tt_int_op(ret, OP_EQ, 0);
770 /* Check the content of the state */
771 /* XXX check more deeply!!! */
772 the_sr_state = get_sr_state();
773 tt_assert(the_sr_state);
774 tt_assert(the_sr_state->version == 1);
775 tt_assert(digestmap_size(the_sr_state->commits) == 3);
776 tt_assert(the_sr_state->current_srv);
777 tt_assert(the_sr_state->current_srv->num_reveals == 3);
778 tt_assert(the_sr_state->previous_srv);
780 /* XXX Now also try loading corrupted state files and make sure parsing
781 fails */
783 done:
784 tor_free(dir);
785 tor_free(sr_state_path);
786 UNMOCK(trusteddirserver_get_by_v3_auth_digest);
789 /** Generate three specially crafted commits (based on the test
790 * vector at sr_srv_calc_ref.py). Helper of test_sr_compute_srv(). */
791 static void
792 test_sr_setup_commits(void)
794 time_t now = time(NULL);
795 sr_commit_t *commit_a, *commit_b, *commit_c, *commit_d;
796 sr_commit_t *place_holder = tor_malloc_zero(sizeof(*place_holder));
797 authority_cert_t *auth_cert = NULL;
799 { /* Setup a minimal dirauth environment for this test */
800 or_options_t *options = get_options_mutable();
802 auth_cert = authority_cert_parse_from_string(AUTHORITY_CERT_1, NULL);
803 tt_assert(auth_cert);
805 options->AuthoritativeDir = 1;
806 tt_int_op(0, OP_EQ, load_ed_keys(options, now));
809 /* Generate three dummy commits according to sr_srv_calc_ref.py . Then
810 register them to the SR state. Also register a fourth commit 'd' with no
811 reveal info, to make sure that it will get ignored during SRV
812 calculation. */
814 { /* Commit from auth 'a' */
815 commit_a = sr_generate_our_commit(now, auth_cert);
816 tt_assert(commit_a);
818 /* Do some surgery on the commit */
819 memset(commit_a->rsa_identity, 'A', sizeof(commit_a->rsa_identity));
820 base16_encode(commit_a->rsa_identity_hex,
821 sizeof(commit_a->rsa_identity_hex), commit_a->rsa_identity,
822 sizeof(commit_a->rsa_identity));
823 strlcpy(commit_a->encoded_reveal,
824 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
825 sizeof(commit_a->encoded_reveal));
826 memcpy(commit_a->hashed_reveal,
827 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
828 sizeof(commit_a->hashed_reveal));
831 { /* Commit from auth 'b' */
832 commit_b = sr_generate_our_commit(now, auth_cert);
833 tt_assert(commit_b);
835 /* Do some surgery on the commit */
836 memset(commit_b->rsa_identity, 'B', sizeof(commit_b->rsa_identity));
837 base16_encode(commit_b->rsa_identity_hex,
838 sizeof(commit_b->rsa_identity_hex), commit_b->rsa_identity,
839 sizeof(commit_b->rsa_identity));
840 strlcpy(commit_b->encoded_reveal,
841 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
842 sizeof(commit_b->encoded_reveal));
843 memcpy(commit_b->hashed_reveal,
844 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
845 sizeof(commit_b->hashed_reveal));
848 { /* Commit from auth 'c' */
849 commit_c = sr_generate_our_commit(now, auth_cert);
850 tt_assert(commit_c);
852 /* Do some surgery on the commit */
853 memset(commit_c->rsa_identity, 'C', sizeof(commit_c->rsa_identity));
854 base16_encode(commit_c->rsa_identity_hex,
855 sizeof(commit_c->rsa_identity_hex), commit_c->rsa_identity,
856 sizeof(commit_c->rsa_identity));
857 strlcpy(commit_c->encoded_reveal,
858 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC",
859 sizeof(commit_c->encoded_reveal));
860 memcpy(commit_c->hashed_reveal,
861 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC",
862 sizeof(commit_c->hashed_reveal));
865 { /* Commit from auth 'd' */
866 commit_d = sr_generate_our_commit(now, auth_cert);
867 tt_assert(commit_d);
869 /* Do some surgery on the commit */
870 memset(commit_d->rsa_identity, 'D', sizeof(commit_d->rsa_identity));
871 base16_encode(commit_d->rsa_identity_hex,
872 sizeof(commit_d->rsa_identity_hex), commit_d->rsa_identity,
873 sizeof(commit_d->rsa_identity));
874 strlcpy(commit_d->encoded_reveal,
875 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD",
876 sizeof(commit_d->encoded_reveal));
877 memcpy(commit_d->hashed_reveal,
878 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD",
879 sizeof(commit_d->hashed_reveal));
880 /* Clean up its reveal info */
881 memcpy(place_holder, commit_d, sizeof(*place_holder));
882 memset(commit_d->encoded_reveal, 0, sizeof(commit_d->encoded_reveal));
883 tt_assert(!commit_has_reveal_value(commit_d));
886 /* Register commits to state (during commit phase) */
887 set_sr_phase(SR_PHASE_COMMIT);
888 save_commit_to_state(commit_a);
889 save_commit_to_state(commit_b);
890 save_commit_to_state(commit_c);
891 save_commit_to_state(commit_d);
892 tt_int_op(digestmap_size(get_sr_state()->commits), OP_EQ, 4);
894 /* Now during REVEAL phase save commit D by restoring its reveal. */
895 set_sr_phase(SR_PHASE_REVEAL);
896 save_commit_to_state(place_holder);
897 tt_str_op(commit_d->encoded_reveal, OP_EQ,
898 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD");
899 /* Go back to an empty encoded reveal value. */
900 memset(commit_d->encoded_reveal, 0, sizeof(commit_d->encoded_reveal));
901 memset(commit_d->random_number, 0, sizeof(commit_d->random_number));
902 tt_assert(!commit_has_reveal_value(commit_d));
904 done:
905 authority_cert_free(auth_cert);
908 /** Verify that the SRV generation procedure is proper by testing it against
909 * the test vector from ./sr_srv_calc_ref.py. */
910 static void
911 test_sr_compute_srv(void *arg)
913 (void) arg;
914 const sr_srv_t *current_srv = NULL;
916 #define SRV_TEST_VECTOR \
917 "2A9B1D6237DAB312A40F575DA85C147663E7ED3F80E9555395F15B515C74253D"
919 MOCK(trusteddirserver_get_by_v3_auth_digest,
920 trusteddirserver_get_by_v3_auth_digest_m);
922 init_authority_state();
924 /* Setup the commits for this unittest */
925 test_sr_setup_commits();
926 test_sr_setup_srv(0);
928 /* Now switch to reveal phase */
929 set_sr_phase(SR_PHASE_REVEAL);
931 /* Compute the SRV */
932 sr_compute_srv();
934 /* Check the result against the test vector */
935 current_srv = sr_state_get_current_srv();
936 tt_assert(current_srv);
937 tt_u64_op(current_srv->num_reveals, OP_EQ, 3);
938 tt_str_op(hex_str((char*)current_srv->value, 32),
939 OP_EQ,
940 SRV_TEST_VECTOR);
942 done:
943 UNMOCK(trusteddirserver_get_by_v3_auth_digest);
946 /** Return a minimal vote document with a current SRV value set to
947 * <b>srv</b>. */
948 static networkstatus_t *
949 get_test_vote_with_curr_srv(const char *srv)
951 networkstatus_t *vote = tor_malloc_zero(sizeof(networkstatus_t));
953 vote->type = NS_TYPE_VOTE;
954 vote->sr_info.participate = 1;
955 vote->sr_info.current_srv = tor_malloc_zero(sizeof(sr_srv_t));
956 vote->sr_info.current_srv->num_reveals = 42;
957 memcpy(vote->sr_info.current_srv->value,
958 srv,
959 sizeof(vote->sr_info.current_srv->value));
961 return vote;
964 /* Test the function that picks the right SRV given a bunch of votes. Make sure
965 * that the function returns an SRV iff the majority/agreement requirements are
966 * met. */
967 static void
968 test_sr_get_majority_srv_from_votes(void *arg)
970 sr_srv_t *chosen_srv;
971 smartlist_t *votes = smartlist_new();
973 #define SRV_1 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
974 #define SRV_2 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
976 (void) arg;
978 init_authority_state();
979 /* Make sure our SRV is fresh so we can consider the super majority with
980 * the consensus params of number of agreements needed. */
981 sr_state_set_fresh_srv();
983 /* The test relies on the dirauth list being initialized. */
984 clear_dir_servers();
985 add_default_trusted_dir_authorities(V3_DIRINFO);
987 { /* Prepare voting environment with just a single vote. */
988 networkstatus_t *vote = get_test_vote_with_curr_srv(SRV_1);
989 smartlist_add(votes, vote);
992 /* Since it's only one vote with an SRV, it should not achieve majority and
993 hence no SRV will be returned. */
994 chosen_srv = get_majority_srv_from_votes(votes, 1);
995 tt_ptr_op(chosen_srv, OP_EQ, NULL);
997 { /* Now put in 8 more votes. Let SRV_1 have majority. */
998 int i;
999 /* Now 7 votes believe in SRV_1 */
1000 for (i = 0; i < 3; i++) {
1001 networkstatus_t *vote = get_test_vote_with_curr_srv(SRV_1);
1002 smartlist_add(votes, vote);
1004 /* and 2 votes believe in SRV_2 */
1005 for (i = 0; i < 2; i++) {
1006 networkstatus_t *vote = get_test_vote_with_curr_srv(SRV_2);
1007 smartlist_add(votes, vote);
1009 for (i = 0; i < 3; i++) {
1010 networkstatus_t *vote = get_test_vote_with_curr_srv(SRV_1);
1011 smartlist_add(votes, vote);
1014 tt_int_op(smartlist_len(votes), OP_EQ, 9);
1017 /* Now we achieve majority for SRV_1, but not the AuthDirNumSRVAgreements
1018 requirement. So still not picking an SRV. */
1019 set_num_srv_agreements(8);
1020 chosen_srv = get_majority_srv_from_votes(votes, 1);
1021 tt_ptr_op(chosen_srv, OP_EQ, NULL);
1023 /* We will now lower the AuthDirNumSRVAgreements requirement by tweaking the
1024 * consensus parameter and we will try again. This time it should work. */
1025 set_num_srv_agreements(7);
1026 chosen_srv = get_majority_srv_from_votes(votes, 1);
1027 tt_assert(chosen_srv);
1028 tt_u64_op(chosen_srv->num_reveals, OP_EQ, 42);
1029 tt_mem_op(chosen_srv->value, OP_EQ, SRV_1, sizeof(chosen_srv->value));
1031 done:
1032 SMARTLIST_FOREACH(votes, networkstatus_t *, vote,
1033 networkstatus_vote_free(vote));
1034 smartlist_free(votes);
1037 static void
1038 test_utils(void *arg)
1040 (void) arg;
1042 /* Testing srv_dup(). */
1044 sr_srv_t *srv = NULL, *dup_srv = NULL;
1045 const char *srv_value =
1046 "1BDB7C3E973936E4D13A49F37C859B3DC69C429334CF9412E3FEF6399C52D47A";
1047 srv = tor_malloc_zero(sizeof(*srv));
1048 srv->num_reveals = 42;
1049 memcpy(srv->value, srv_value, sizeof(srv->value));
1050 dup_srv = srv_dup(srv);
1051 tt_assert(dup_srv);
1052 tt_u64_op(dup_srv->num_reveals, OP_EQ, srv->num_reveals);
1053 tt_mem_op(dup_srv->value, OP_EQ, srv->value, sizeof(srv->value));
1054 tor_free(srv);
1055 tor_free(dup_srv);
1058 /* Testing commitments_are_the_same(). Currently, the check is to test the
1059 * value of the encoded commit so let's make sure that actually works. */
1061 /* Payload of 57 bytes that is the length of sr_commit_t->encoded_commit.
1062 * 56 bytes of payload and a NUL terminated byte at the end ('\x00')
1063 * which comes down to SR_COMMIT_BASE64_LEN + 1. */
1064 const char *payload =
1065 "\x5d\xb9\x60\xb6\xcc\x51\x68\x52\x31\xd9\x88\x88\x71\x71\xe0\x30"
1066 "\x59\x55\x7f\xcd\x61\xc0\x4b\x05\xb8\xcd\xc1\x48\xe9\xcd\x16\x1f"
1067 "\x70\x15\x0c\xfc\xd3\x1a\x75\xd0\x93\x6c\xc4\xe0\x5c\xbe\xe2\x18"
1068 "\xc7\xaf\x72\xb6\x7c\x9b\x52\x00";
1069 sr_commit_t commit1, commit2;
1070 memcpy(commit1.encoded_commit, payload, sizeof(commit1.encoded_commit));
1071 memcpy(commit2.encoded_commit, payload, sizeof(commit2.encoded_commit));
1072 tt_int_op(commitments_are_the_same(&commit1, &commit2), OP_EQ, 1);
1073 /* Let's corrupt one of them. */
1074 memset(commit1.encoded_commit, 'A', sizeof(commit1.encoded_commit));
1075 tt_int_op(commitments_are_the_same(&commit1, &commit2), OP_EQ, 0);
1078 /* Testing commit_is_authoritative(). */
1080 crypto_pk_t *k = crypto_pk_new();
1081 char digest[DIGEST_LEN];
1082 sr_commit_t commit;
1084 tt_assert(!crypto_pk_generate_key(k));
1086 tt_int_op(0, OP_EQ, crypto_pk_get_digest(k, digest));
1087 memcpy(commit.rsa_identity, digest, sizeof(commit.rsa_identity));
1088 tt_int_op(commit_is_authoritative(&commit, digest), OP_EQ, 1);
1089 /* Change the pubkey. */
1090 memset(commit.rsa_identity, 0, sizeof(commit.rsa_identity));
1091 tt_int_op(commit_is_authoritative(&commit, digest), OP_EQ, 0);
1092 crypto_pk_free(k);
1095 /* Testing get_phase_str(). */
1097 tt_str_op(get_phase_str(SR_PHASE_REVEAL), OP_EQ, "reveal");
1098 tt_str_op(get_phase_str(SR_PHASE_COMMIT), OP_EQ, "commit");
1101 /* Testing phase transition */
1103 init_authority_state();
1104 set_sr_phase(SR_PHASE_COMMIT);
1105 tt_int_op(is_phase_transition(SR_PHASE_REVEAL), OP_EQ, 1);
1106 tt_int_op(is_phase_transition(SR_PHASE_COMMIT), OP_EQ, 0);
1107 set_sr_phase(SR_PHASE_REVEAL);
1108 tt_int_op(is_phase_transition(SR_PHASE_REVEAL), OP_EQ, 0);
1109 tt_int_op(is_phase_transition(SR_PHASE_COMMIT), OP_EQ, 1);
1110 /* Junk. */
1111 tt_int_op(is_phase_transition(42), OP_EQ, 1);
1114 done:
1115 return;
1118 static void
1119 test_state_transition(void *arg)
1121 sr_state_t *state = NULL;
1122 time_t now = time(NULL);
1124 (void) arg;
1126 { /* Setup a minimal dirauth environment for this test */
1127 init_authority_state();
1128 state = get_sr_state();
1129 tt_assert(state);
1132 /* Test our state reset for a new protocol run. */
1134 /* Add a commit to the state so we can test if the reset cleans the
1135 * commits. Also, change all params that we expect to be updated. */
1136 sr_commit_t *commit = sr_generate_our_commit(now, mock_cert);
1137 tt_assert(commit);
1138 sr_state_add_commit(commit);
1139 tt_int_op(digestmap_size(state->commits), OP_EQ, 1);
1140 /* Let's test our delete feature. */
1141 sr_state_delete_commits();
1142 tt_int_op(digestmap_size(state->commits), OP_EQ, 0);
1143 /* Add it back so we can continue the rest of the test because after
1144 * deletiong our commit will be freed so generate a new one. */
1145 commit = sr_generate_our_commit(now, mock_cert);
1146 tt_assert(commit);
1147 sr_state_add_commit(commit);
1148 tt_int_op(digestmap_size(state->commits), OP_EQ, 1);
1149 state->n_reveal_rounds = 42;
1150 state->n_commit_rounds = 43;
1151 state->n_protocol_runs = 44;
1152 reset_state_for_new_protocol_run(now);
1153 tt_int_op(state->n_reveal_rounds, OP_EQ, 0);
1154 tt_int_op(state->n_commit_rounds, OP_EQ, 0);
1155 tt_u64_op(state->n_protocol_runs, OP_EQ, 45);
1156 tt_int_op(digestmap_size(state->commits), OP_EQ, 0);
1159 /* Test SRV rotation in our state. */
1161 const sr_srv_t *cur, *prev;
1162 test_sr_setup_srv(1);
1163 cur = sr_state_get_current_srv();
1164 tt_assert(cur);
1165 /* After, current srv should be the previous and then set to NULL. */
1166 state_rotate_srv();
1167 prev = sr_state_get_previous_srv();
1168 tt_assert(prev == cur);
1169 tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
1170 sr_state_clean_srvs();
1173 /* New protocol run. */
1175 const sr_srv_t *cur;
1176 /* Setup some new SRVs so we can confirm that a new protocol run
1177 * actually makes them rotate and compute new ones. */
1178 test_sr_setup_srv(1);
1179 cur = sr_state_get_current_srv();
1180 tt_assert(cur);
1181 set_sr_phase(SR_PHASE_REVEAL);
1182 MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m);
1183 new_protocol_run(now);
1184 UNMOCK(get_my_v3_authority_cert);
1185 /* Rotation happened. */
1186 tt_assert(sr_state_get_previous_srv() == cur);
1187 /* We are going into COMMIT phase so we had to rotate our SRVs. Usually
1188 * our current SRV would be NULL but a new protocol run should make us
1189 * compute a new SRV. */
1190 tt_assert(sr_state_get_current_srv());
1191 /* Also, make sure we did change the current. */
1192 tt_assert(sr_state_get_current_srv() != cur);
1193 /* We should have our commitment alone. */
1194 tt_int_op(digestmap_size(state->commits), OP_EQ, 1);
1195 tt_int_op(state->n_reveal_rounds, OP_EQ, 0);
1196 tt_int_op(state->n_commit_rounds, OP_EQ, 0);
1197 /* 46 here since we were at 45 just before. */
1198 tt_u64_op(state->n_protocol_runs, OP_EQ, 46);
1201 /* Cleanup of SRVs. */
1203 sr_state_clean_srvs();
1204 tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
1205 tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
1208 done:
1209 return;
1212 static void
1213 test_keep_commit(void *arg)
1215 char fp[FINGERPRINT_LEN + 1];
1216 sr_commit_t *commit = NULL, *dup_commit = NULL;
1217 sr_state_t *state;
1218 time_t now = time(NULL);
1219 crypto_pk_t *k = NULL;
1221 (void) arg;
1223 MOCK(trusteddirserver_get_by_v3_auth_digest,
1224 trusteddirserver_get_by_v3_auth_digest_m);
1227 k = pk_generate(1);
1228 /* Setup a minimal dirauth environment for this test */
1229 /* Have a key that is not the one from our commit. */
1230 init_authority_state();
1231 state = get_sr_state();
1234 /* Test this very important function that tells us if we should keep a
1235 * commit or not in our state. Most of it depends on the phase and what's
1236 * in the commit so we'll change the commit as we go. */
1237 commit = sr_generate_our_commit(now, mock_cert);
1238 tt_assert(commit);
1239 /* Set us in COMMIT phase for starter. */
1240 set_sr_phase(SR_PHASE_COMMIT);
1241 /* We should never keep a commit from a non authoritative authority. */
1242 tt_int_op(should_keep_commit(commit, fp, SR_PHASE_COMMIT), OP_EQ, 0);
1243 /* This should NOT be kept because it has a reveal value in it. */
1244 tt_assert(commit_has_reveal_value(commit));
1245 tt_int_op(should_keep_commit(commit, commit->rsa_identity,
1246 SR_PHASE_COMMIT), OP_EQ, 0);
1247 /* Add it to the state which should return to not keep it. */
1248 sr_state_add_commit(commit);
1249 tt_int_op(should_keep_commit(commit, commit->rsa_identity,
1250 SR_PHASE_COMMIT), OP_EQ, 0);
1251 /* Remove it from state so we can continue our testing. */
1252 digestmap_remove(state->commits, commit->rsa_identity);
1253 /* Let's remove our reveal value which should make it OK to keep it. */
1254 memset(commit->encoded_reveal, 0, sizeof(commit->encoded_reveal));
1255 tt_int_op(should_keep_commit(commit, commit->rsa_identity,
1256 SR_PHASE_COMMIT), OP_EQ, 1);
1258 /* Let's reset our commit and go into REVEAL phase. */
1259 sr_commit_free(commit);
1260 commit = sr_generate_our_commit(now, mock_cert);
1261 tt_assert(commit);
1262 /* Dup the commit so we have one with and one without a reveal value. */
1263 dup_commit = tor_malloc_zero(sizeof(*dup_commit));
1264 memcpy(dup_commit, commit, sizeof(*dup_commit));
1265 memset(dup_commit->encoded_reveal, 0, sizeof(dup_commit->encoded_reveal));
1266 set_sr_phase(SR_PHASE_REVEAL);
1267 /* We should never keep a commit from a non authoritative authority. */
1268 tt_int_op(should_keep_commit(commit, fp, SR_PHASE_REVEAL), OP_EQ, 0);
1269 /* We shouldn't accept a commit that is not in our state. */
1270 tt_int_op(should_keep_commit(commit, commit->rsa_identity,
1271 SR_PHASE_REVEAL), OP_EQ, 0);
1272 /* Important to add the commit _without_ the reveal here. */
1273 sr_state_add_commit(dup_commit);
1274 tt_int_op(digestmap_size(state->commits), OP_EQ, 1);
1275 /* Our commit should be valid that is authoritative, contains a reveal, be
1276 * in the state and commitment and reveal values match. */
1277 tt_int_op(should_keep_commit(commit, commit->rsa_identity,
1278 SR_PHASE_REVEAL), OP_EQ, 1);
1279 /* The commit shouldn't be kept if it's not verified that is no matchin
1280 * hashed reveal. */
1282 /* Let's save the hash reveal so we can restore it. */
1283 sr_commit_t place_holder;
1284 memcpy(place_holder.hashed_reveal, commit->hashed_reveal,
1285 sizeof(place_holder.hashed_reveal));
1286 memset(commit->hashed_reveal, 0, sizeof(commit->hashed_reveal));
1287 setup_full_capture_of_logs(LOG_WARN);
1288 tt_int_op(should_keep_commit(commit, commit->rsa_identity,
1289 SR_PHASE_REVEAL), OP_EQ, 0);
1290 expect_log_msg_containing("doesn't match the commit value.");
1291 expect_log_msg_containing("has an invalid reveal value.");
1292 assert_log_predicate(mock_saved_log_n_entries() == 2,
1293 "expected 2 log entries");
1294 teardown_capture_of_logs();
1295 memcpy(commit->hashed_reveal, place_holder.hashed_reveal,
1296 sizeof(commit->hashed_reveal));
1298 /* We shouldn't keep a commit that has no reveal. */
1299 tt_int_op(should_keep_commit(dup_commit, dup_commit->rsa_identity,
1300 SR_PHASE_REVEAL), OP_EQ, 0);
1301 /* We must not keep a commit that is not the same from the commit phase. */
1302 memset(commit->encoded_commit, 0, sizeof(commit->encoded_commit));
1303 tt_int_op(should_keep_commit(commit, commit->rsa_identity,
1304 SR_PHASE_REVEAL), OP_EQ, 0);
1306 done:
1307 teardown_capture_of_logs();
1308 sr_commit_free(commit);
1309 sr_commit_free(dup_commit);
1310 crypto_pk_free(k);
1311 UNMOCK(trusteddirserver_get_by_v3_auth_digest);
1314 static void
1315 test_state_update(void *arg)
1317 time_t commit_phase_time = 1452076000;
1318 time_t reveal_phase_time = 1452086800;
1319 sr_state_t *state;
1321 (void) arg;
1324 init_authority_state();
1325 state = get_sr_state();
1326 set_sr_phase(SR_PHASE_COMMIT);
1327 /* We'll cheat a bit here and reset the creation time of the state which
1328 * will avoid us to compute a valid_after time that fits the commit
1329 * phase. */
1330 state->valid_after = 0;
1331 state->n_reveal_rounds = 0;
1332 state->n_commit_rounds = 0;
1333 state->n_protocol_runs = 0;
1336 /* We need to mock for the state update function call. */
1337 MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m);
1339 /* We are in COMMIT phase here and we'll trigger a state update but no
1340 * transition. */
1341 sr_state_update(commit_phase_time);
1342 tt_int_op(state->valid_after, OP_EQ, commit_phase_time);
1343 tt_int_op(state->n_commit_rounds, OP_EQ, 1);
1344 tt_int_op(state->phase, OP_EQ, SR_PHASE_COMMIT);
1345 tt_int_op(digestmap_size(state->commits), OP_EQ, 1);
1347 /* We are still in the COMMIT phase here but we'll trigger a state
1348 * transition to the REVEAL phase. */
1349 sr_state_update(reveal_phase_time);
1350 tt_int_op(state->phase, OP_EQ, SR_PHASE_REVEAL);
1351 tt_int_op(state->valid_after, OP_EQ, reveal_phase_time);
1352 /* Only our commit should be in there. */
1353 tt_int_op(digestmap_size(state->commits), OP_EQ, 1);
1354 tt_int_op(state->n_reveal_rounds, OP_EQ, 1);
1356 /* We can't update a state with a valid after _lower_ than the creation
1357 * time so here it is. */
1358 sr_state_update(commit_phase_time);
1359 tt_int_op(state->valid_after, OP_EQ, reveal_phase_time);
1361 /* Finally, let's go back in COMMIT phase so we can test the state update
1362 * of a new protocol run. */
1363 state->valid_after = 0;
1364 sr_state_update(commit_phase_time);
1365 tt_int_op(state->valid_after, OP_EQ, commit_phase_time);
1366 tt_int_op(state->n_commit_rounds, OP_EQ, 1);
1367 tt_int_op(state->n_reveal_rounds, OP_EQ, 0);
1368 tt_u64_op(state->n_protocol_runs, OP_EQ, 1);
1369 tt_int_op(state->phase, OP_EQ, SR_PHASE_COMMIT);
1370 tt_int_op(digestmap_size(state->commits), OP_EQ, 1);
1371 tt_assert(state->current_srv);
1373 done:
1374 sr_state_free();
1375 UNMOCK(get_my_v3_authority_cert);
1378 struct testcase_t sr_tests[] = {
1379 { "get_sr_protocol_phase", test_get_sr_protocol_phase, TT_FORK,
1380 NULL, NULL },
1381 { "sr_commit", test_sr_commit, TT_FORK,
1382 NULL, NULL },
1383 { "keep_commit", test_keep_commit, TT_FORK,
1384 NULL, NULL },
1385 { "encoding", test_encoding, TT_FORK,
1386 NULL, NULL },
1387 { "get_next_valid_after_time", test_get_next_valid_after_time, TT_FORK,
1388 NULL, NULL },
1389 { "get_start_time_of_current_run", test_get_start_time_of_current_run,
1390 TT_FORK, NULL, NULL },
1391 { "get_start_time_functions", test_get_start_time_functions,
1392 TT_FORK, NULL, NULL },
1393 { "get_sr_protocol_duration", test_get_sr_protocol_duration, TT_FORK,
1394 NULL, NULL },
1395 { "get_state_valid_until_time", test_get_state_valid_until_time, TT_FORK,
1396 NULL, NULL },
1397 { "vote", test_vote, TT_FORK,
1398 NULL, NULL },
1399 { "state_load_from_disk", test_state_load_from_disk, TT_FORK,
1400 NULL, NULL },
1401 { "sr_compute_srv", test_sr_compute_srv, TT_FORK, NULL, NULL },
1402 { "sr_get_majority_srv_from_votes", test_sr_get_majority_srv_from_votes,
1403 TT_FORK, NULL, NULL },
1404 { "utils", test_utils, TT_FORK, NULL, NULL },
1405 { "state_transition", test_state_transition, TT_FORK, NULL, NULL },
1406 { "state_update", test_state_update, TT_FORK,
1407 NULL, NULL },
1408 END_OF_TESTCASES