Line data Source code
1 : /* Copyright (c) 2016-2021, The Tor Project, Inc. */
2 : /* See LICENSE for licensing information */
3 :
4 : /**
5 : * \file shared_random_state.c
6 : *
7 : * \brief Functions and data structures for the state of the random protocol
8 : * as defined in proposal #250.
9 : **/
10 :
11 : #define SHARED_RANDOM_STATE_PRIVATE
12 :
13 : #include "core/or/or.h"
14 : #include "app/config/config.h"
15 : #include "lib/confmgt/confmgt.h"
16 : #include "lib/crypt_ops/crypto_util.h"
17 : #include "feature/dirauth/dirvote.h"
18 : #include "feature/nodelist/networkstatus.h"
19 : #include "feature/relay/router.h"
20 : #include "feature/dirauth/shared_random.h"
21 : #include "feature/hs_common/shared_random_client.h"
22 : #include "feature/dirauth/shared_random_state.h"
23 : #include "feature/dirauth/voting_schedule.h"
24 : #include "lib/encoding/confline.h"
25 : #include "lib/version/torversion.h"
26 :
27 : #include "app/config/or_state_st.h"
28 :
29 : /** Default filename of the shared random state on disk. */
30 : static const char default_fname[] = "sr-state";
31 :
32 : /** String representation of a protocol phase. */
33 : static const char *phase_str[] = { "unknown", "commit", "reveal" };
34 :
35 : /** Our shared random protocol state. There is only one possible state per
36 : * protocol run so this is the global state which is reset at every run once
37 : * the shared random value has been computed. */
38 : static sr_state_t *sr_state = NULL;
39 :
40 : /** Representation of our persistent state on disk. The sr_state above
41 : * contains the data parsed from this state. When we save to disk, we
42 : * translate the sr_state to this sr_disk_state. */
43 : static sr_disk_state_t *sr_disk_state = NULL;
44 :
45 : /* Disk state file keys. */
46 : static const char dstate_commit_key[] = "Commit";
47 : static const char dstate_prev_srv_key[] = "SharedRandPreviousValue";
48 : static const char dstate_cur_srv_key[] = "SharedRandCurrentValue";
49 :
50 : /** dummy instance of sr_disk_state_t, used for type-checking its
51 : * members with CONF_CHECK_VAR_TYPE. */
52 : DUMMY_TYPECHECK_INSTANCE(sr_disk_state_t);
53 :
54 : #define VAR(varname,conftype,member,initvalue) \
55 : CONFIG_VAR_ETYPE(sr_disk_state_t, varname, conftype, member, 0, initvalue)
56 : #define V(member,conftype,initvalue) \
57 : VAR(#member, conftype, member, initvalue)
58 :
59 : /** Our persistent state magic number. */
60 : #define SR_DISK_STATE_MAGIC 0x98AB1254
61 :
62 : /** Array of variables that are saved to disk as a persistent state. */
63 : // clang-format off
64 : static const config_var_t state_vars[] = {
65 : V(Version, POSINT, "0"),
66 : V(TorVersion, STRING, NULL),
67 : V(ValidAfter, ISOTIME, NULL),
68 : V(ValidUntil, ISOTIME, NULL),
69 :
70 : V(Commit, LINELIST, NULL),
71 :
72 : V(SharedRandValues, LINELIST_V, NULL),
73 : VAR("SharedRandPreviousValue",LINELIST_S, SharedRandValues, NULL),
74 : VAR("SharedRandCurrentValue", LINELIST_S, SharedRandValues, NULL),
75 : END_OF_CONFIG_VARS
76 : };
77 : // clang-format on
78 :
79 : /** "Extra" variable in the state that receives lines we can't parse. This
80 : * lets us preserve options from versions of Tor newer than us. */
81 : static const struct_member_t state_extra_var = {
82 : .name = "__extra",
83 : .type = CONFIG_TYPE_LINELIST,
84 : .offset = offsetof(sr_disk_state_t, ExtraLines),
85 : };
86 :
87 : /** Configuration format of sr_disk_state_t. */
88 : static const config_format_t state_format = {
89 : .size = sizeof(sr_disk_state_t),
90 : .magic = {
91 : "sr_disk_state_t",
92 : SR_DISK_STATE_MAGIC,
93 : offsetof(sr_disk_state_t, magic_),
94 : },
95 : .vars = state_vars,
96 : .extra = &state_extra_var,
97 : };
98 :
99 : /** Global configuration manager for the shared-random state file */
100 : static config_mgr_t *shared_random_state_mgr = NULL;
101 :
102 : /** Return the configuration manager for the shared-random state file. */
103 : static const config_mgr_t *
104 217 : get_srs_mgr(void)
105 : {
106 217 : if (PREDICT_UNLIKELY(shared_random_state_mgr == NULL)) {
107 18 : shared_random_state_mgr = config_mgr_new(&state_format);
108 18 : config_mgr_freeze(shared_random_state_mgr);
109 : }
110 217 : return shared_random_state_mgr;
111 : }
112 :
113 : static void state_query_del_(sr_state_object_t obj_type, void *data);
114 :
115 : /** Return a string representation of a protocol phase. */
116 : STATIC const char *
117 17 : get_phase_str(sr_phase_t phase)
118 : {
119 17 : const char *the_string = NULL;
120 :
121 17 : switch (phase) {
122 17 : case SR_PHASE_COMMIT:
123 : case SR_PHASE_REVEAL:
124 17 : the_string = phase_str[phase];
125 17 : break;
126 : default:
127 : /* Unknown phase shouldn't be possible. */
128 0 : tor_assert(0);
129 : }
130 :
131 17 : return the_string;
132 : }
133 : /** Return the time we should expire the state file created at <b>now</b>.
134 : * We expire the state file in the beginning of the next protocol run. */
135 : STATIC time_t
136 43 : get_state_valid_until_time(time_t now)
137 : {
138 43 : int total_rounds = SHARED_RANDOM_N_ROUNDS * SHARED_RANDOM_N_PHASES;
139 43 : int current_round, voting_interval, rounds_left;
140 43 : time_t valid_until, beginning_of_current_round;
141 :
142 43 : voting_interval = get_voting_interval();
143 : /* Find the time the current round started. */
144 43 : beginning_of_current_round = dirauth_sched_get_cur_valid_after_time();
145 :
146 : /* Find how many rounds are left till the end of the protocol run */
147 43 : current_round = (now / voting_interval) % total_rounds;
148 43 : rounds_left = total_rounds - current_round;
149 :
150 : /* To find the valid-until time now, take the start time of the current
151 : * round and add to it the time it takes for the leftover rounds to
152 : * complete. */
153 43 : valid_until = beginning_of_current_round + (rounds_left * voting_interval);
154 :
155 : { /* Logging */
156 43 : char tbuf[ISO_TIME_LEN + 1];
157 43 : format_iso_time(tbuf, valid_until);
158 43 : log_debug(LD_DIR, "SR: Valid until time for state set to %s.", tbuf);
159 : }
160 :
161 43 : return valid_until;
162 : }
163 :
164 : /** Given the consensus 'valid-after' time, return the protocol phase we should
165 : * be in. */
166 : STATIC sr_phase_t
167 46 : get_sr_protocol_phase(time_t valid_after)
168 : {
169 : /* Shared random protocol has two phases, commit and reveal. */
170 46 : int total_periods = SHARED_RANDOM_N_ROUNDS * SHARED_RANDOM_N_PHASES;
171 46 : int current_slot;
172 :
173 : /* Split time into slots of size 'voting_interval'. See which slot we are
174 : * currently into, and find which phase it corresponds to. */
175 46 : current_slot = (valid_after / get_voting_interval()) % total_periods;
176 :
177 46 : if (current_slot < SHARED_RANDOM_N_ROUNDS) {
178 : return SR_PHASE_COMMIT;
179 : } else {
180 5 : return SR_PHASE_REVEAL;
181 : }
182 : }
183 :
184 : /** Add the given <b>commit</b> to <b>state</b>. It MUST be a valid commit
185 : * and there shouldn't be a commit from the same authority in the state
186 : * already else verification hasn't been done prior. This takes ownership of
187 : * the commit once in our state. */
188 : static void
189 32 : commit_add_to_state(sr_commit_t *commit, sr_state_t *state)
190 : {
191 32 : sr_commit_t *saved_commit;
192 :
193 32 : tor_assert(commit);
194 32 : tor_assert(state);
195 :
196 32 : saved_commit = digestmap_set(state->commits, commit->rsa_identity,
197 : commit);
198 32 : if (saved_commit != NULL) {
199 : /* This means we already have that commit in our state so adding twice
200 : * the same commit is either a code flow error, a corrupted disk state
201 : * or some new unknown issue. */
202 0 : log_warn(LD_DIR, "SR: Commit from %s exists in our state while "
203 : "adding it: '%s'", sr_commit_get_rsa_fpr(commit),
204 : commit->encoded_commit);
205 0 : sr_commit_free(saved_commit);
206 : }
207 32 : }
208 :
209 : /** Helper: deallocate a commit object. (Used with digestmap_free(), which
210 : * requires a function pointer whose argument is void *). */
211 : static void
212 7 : commit_free_(void *p)
213 : {
214 7 : sr_commit_free_(p);
215 7 : }
216 :
217 : #define state_free(val) \
218 : FREE_AND_NULL(sr_state_t, state_free_, (val))
219 :
220 : /** Free a state that was allocated with state_new(). */
221 : static void
222 5 : state_free_(sr_state_t *state)
223 : {
224 5 : if (state == NULL) {
225 : return;
226 : }
227 5 : tor_free(state->fname);
228 5 : digestmap_free(state->commits, commit_free_);
229 5 : tor_free(state->current_srv);
230 5 : tor_free(state->previous_srv);
231 5 : tor_free(state);
232 : }
233 :
234 : /** Allocate an sr_state_t object and returns it. If no <b>fname</b>, the
235 : * default file name is used. This function does NOT initialize the state
236 : * timestamp, phase or shared random value. NULL is never returned. */
237 : static sr_state_t *
238 18 : state_new(const char *fname, time_t now)
239 : {
240 18 : sr_state_t *new_state = tor_malloc_zero(sizeof(*new_state));
241 : /* If file name is not provided, use default. */
242 18 : if (fname == NULL) {
243 0 : fname = default_fname;
244 : }
245 18 : new_state->fname = tor_strdup(fname);
246 18 : new_state->version = SR_PROTO_VERSION;
247 18 : new_state->commits = digestmap_new();
248 18 : new_state->phase = get_sr_protocol_phase(now);
249 18 : new_state->valid_until = get_state_valid_until_time(now);
250 18 : return new_state;
251 : }
252 :
253 : /** Set our global state pointer with the one given. */
254 : static void
255 18 : state_set(sr_state_t *state)
256 : {
257 18 : tor_assert(state);
258 18 : if (sr_state != NULL) {
259 0 : state_free(sr_state);
260 : }
261 18 : sr_state = state;
262 18 : }
263 :
264 : #define disk_state_free(val) \
265 : FREE_AND_NULL(sr_disk_state_t, disk_state_free_, (val))
266 :
267 : /** Free an allocated disk state. */
268 : static void
269 8 : disk_state_free_(sr_disk_state_t *state)
270 : {
271 8 : if (state == NULL) {
272 : return;
273 : }
274 5 : config_free(get_srs_mgr(), state);
275 : }
276 :
277 : /** Allocate a new disk state, initialize it and return it. */
278 : static sr_disk_state_t *
279 18 : disk_state_new(time_t now)
280 : {
281 18 : sr_disk_state_t *new_state = config_new(get_srs_mgr());
282 :
283 18 : new_state->Version = SR_PROTO_VERSION;
284 18 : new_state->TorVersion = tor_strdup(get_version());
285 18 : new_state->ValidUntil = get_state_valid_until_time(now);
286 18 : new_state->ValidAfter = now;
287 :
288 : /* Init config format. */
289 18 : config_init(get_srs_mgr(), new_state);
290 18 : return new_state;
291 : }
292 :
293 : /** Set our global disk state with the given state. */
294 : static void
295 18 : disk_state_set(sr_disk_state_t *state)
296 : {
297 18 : tor_assert(state);
298 18 : if (sr_disk_state != NULL) {
299 0 : disk_state_free(sr_disk_state);
300 : }
301 18 : sr_disk_state = state;
302 18 : }
303 :
304 : /** Return -1 if the disk state is invalid (something in there that we can't or
305 : * shouldn't use). Return 0 if everything checks out. */
306 : static int
307 6 : disk_state_validate(const sr_disk_state_t *state)
308 : {
309 6 : time_t now;
310 :
311 6 : tor_assert(state);
312 :
313 : /* Do we support the protocol version in the state or is it 0 meaning
314 : * Version wasn't found in the state file or bad anyway ? */
315 6 : if (state->Version == 0 || state->Version > SR_PROTO_VERSION) {
316 0 : goto invalid;
317 : }
318 :
319 : /* If the valid until time is before now, we shouldn't use that state. */
320 6 : now = time(NULL);
321 6 : if (state->ValidUntil < now) {
322 0 : log_info(LD_DIR, "SR: Disk state has expired. Ignoring it.");
323 0 : goto invalid;
324 : }
325 :
326 : /* Make sure we don't have a valid after time that is earlier than a valid
327 : * until time which would make things not work well. */
328 6 : if (state->ValidAfter >= state->ValidUntil) {
329 0 : log_info(LD_DIR, "SR: Disk state valid after/until times are invalid.");
330 0 : goto invalid;
331 : }
332 :
333 : return 0;
334 :
335 : invalid:
336 : return -1;
337 : }
338 :
339 : /** Parse the Commit line(s) in the disk state and translate them to the
340 : * the memory state. Return 0 on success else -1 on error. */
341 : static int
342 6 : disk_state_parse_commits(sr_state_t *state,
343 : const sr_disk_state_t *disk_state)
344 : {
345 6 : config_line_t *line;
346 6 : smartlist_t *args = NULL;
347 :
348 6 : tor_assert(state);
349 6 : tor_assert(disk_state);
350 :
351 14 : for (line = disk_state->Commit; line; line = line->next) {
352 8 : sr_commit_t *commit = NULL;
353 :
354 : /* Extra safety. */
355 8 : if (strcasecmp(line->key, dstate_commit_key) ||
356 8 : line->value == NULL) {
357 : /* Ignore any lines that are not commits. */
358 0 : tor_fragile_assert();
359 0 : continue;
360 : }
361 8 : args = smartlist_new();
362 8 : smartlist_split_string(args, line->value, " ",
363 : SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
364 8 : if (smartlist_len(args) < 3) {
365 0 : log_warn(LD_BUG, "SR: Too few arguments in Commit Line: %s",
366 : escaped(line->value));
367 0 : goto error;
368 : }
369 8 : commit = sr_parse_commit(args);
370 8 : if (commit == NULL) {
371 : /* Ignore badly formed commit. It could also be a authority
372 : * fingerprint that we don't know about so it shouldn't be used. */
373 0 : smartlist_free(args);
374 0 : continue;
375 : }
376 : /* We consider parseable commit from our disk state to be valid because
377 : * they need to be in the first place to get in there. */
378 8 : commit->valid = 1;
379 : /* Add commit to our state pointer. */
380 8 : commit_add_to_state(commit, state);
381 :
382 46 : SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
383 8 : smartlist_free(args);
384 : }
385 :
386 : return 0;
387 :
388 0 : error:
389 0 : SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
390 0 : smartlist_free(args);
391 0 : return -1;
392 : }
393 :
394 : /** Parse a share random value line from the disk state and save it to dst
395 : * which is an allocated srv object. Return 0 on success else -1. */
396 : static int
397 2 : disk_state_parse_srv(const char *value, sr_srv_t *dst)
398 : {
399 2 : int ret = -1;
400 2 : smartlist_t *args;
401 2 : sr_srv_t *srv;
402 :
403 2 : tor_assert(value);
404 2 : tor_assert(dst);
405 :
406 2 : args = smartlist_new();
407 2 : smartlist_split_string(args, value, " ",
408 : SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
409 2 : if (smartlist_len(args) < 2) {
410 0 : log_warn(LD_BUG, "SR: Too few arguments in shared random value. "
411 : "Line: %s", escaped(value));
412 0 : goto error;
413 : }
414 2 : srv = sr_parse_srv(args);
415 2 : if (srv == NULL) {
416 0 : goto error;
417 : }
418 2 : dst->num_reveals = srv->num_reveals;
419 2 : memcpy(dst->value, srv->value, sizeof(dst->value));
420 2 : tor_free(srv);
421 2 : ret = 0;
422 :
423 2 : error:
424 6 : SMARTLIST_FOREACH(args, char *, s, tor_free(s));
425 2 : smartlist_free(args);
426 2 : return ret;
427 : }
428 :
429 : /** Parse both SharedRandCurrentValue and SharedRandPreviousValue line from
430 : * the state. Return 0 on success else -1. */
431 : static int
432 6 : disk_state_parse_sr_values(sr_state_t *state,
433 : const sr_disk_state_t *disk_state)
434 : {
435 : /* Only one value per type (current or previous) is allowed so we keep
436 : * track of it with these flag. */
437 6 : unsigned int seen_previous = 0, seen_current = 0;
438 6 : config_line_t *line;
439 6 : sr_srv_t *srv = NULL;
440 :
441 6 : tor_assert(state);
442 6 : tor_assert(disk_state);
443 :
444 8 : for (line = disk_state->SharedRandValues; line; line = line->next) {
445 2 : if (line->value == NULL) {
446 0 : continue;
447 : }
448 2 : srv = tor_malloc_zero(sizeof(*srv));
449 2 : if (disk_state_parse_srv(line->value, srv) < 0) {
450 0 : log_warn(LD_BUG, "SR: Broken current SRV line in state %s",
451 : escaped(line->value));
452 0 : goto bad;
453 : }
454 2 : if (!strcasecmp(line->key, dstate_prev_srv_key)) {
455 1 : if (seen_previous) {
456 0 : log_warn(LD_DIR, "SR: Second previous SRV value seen. Bad state");
457 0 : goto bad;
458 : }
459 1 : state->previous_srv = srv;
460 1 : seen_previous = 1;
461 1 : } else if (!strcasecmp(line->key, dstate_cur_srv_key)) {
462 1 : if (seen_current) {
463 0 : log_warn(LD_DIR, "SR: Second current SRV value seen. Bad state");
464 0 : goto bad;
465 : }
466 1 : state->current_srv = srv;
467 1 : seen_current = 1;
468 : } else {
469 : /* Unknown key. Ignoring. */
470 0 : tor_free(srv);
471 : }
472 : }
473 :
474 : return 0;
475 0 : bad:
476 0 : tor_free(srv);
477 0 : return -1;
478 : }
479 :
480 : /** Parse the given disk state and set a newly allocated state. On success,
481 : * return that state else NULL. */
482 : static sr_state_t *
483 6 : disk_state_parse(const sr_disk_state_t *new_disk_state)
484 : {
485 6 : sr_state_t *new_state = state_new(default_fname, time(NULL));
486 :
487 6 : tor_assert(new_disk_state);
488 :
489 6 : new_state->version = new_disk_state->Version;
490 6 : new_state->valid_until = new_disk_state->ValidUntil;
491 6 : new_state->valid_after = new_disk_state->ValidAfter;
492 :
493 : /* Set our current phase according to the valid-after time in our disk
494 : * state. The disk state we are parsing contains everything for the phase
495 : * starting at valid_after so make sure our phase reflects that. */
496 6 : new_state->phase = get_sr_protocol_phase(new_state->valid_after);
497 :
498 : /* Parse the shared random values. */
499 6 : if (disk_state_parse_sr_values(new_state, new_disk_state) < 0) {
500 0 : goto error;
501 : }
502 : /* Parse the commits. */
503 6 : if (disk_state_parse_commits(new_state, new_disk_state) < 0) {
504 0 : goto error;
505 : }
506 : /* Great! This new state contains everything we had on disk. */
507 : return new_state;
508 :
509 0 : error:
510 0 : state_free(new_state);
511 0 : return NULL;
512 : }
513 :
514 : /** From a valid commit object and an allocated config line, set the line's
515 : * value to the state string representation of a commit. */
516 : static void
517 75 : disk_state_put_commit_line(const sr_commit_t *commit, config_line_t *line)
518 : {
519 75 : char *reveal_str = NULL;
520 :
521 75 : tor_assert(commit);
522 75 : tor_assert(line);
523 :
524 75 : if (!fast_mem_is_zero(commit->encoded_reveal,
525 : sizeof(commit->encoded_reveal))) {
526 : /* Add extra whitespace so we can format the line correctly. */
527 69 : tor_asprintf(&reveal_str, " %s", commit->encoded_reveal);
528 : }
529 75 : tor_asprintf(&line->value, "%u %s %s %s%s",
530 : SR_PROTO_VERSION,
531 75 : crypto_digest_algorithm_get_name(commit->alg),
532 : sr_commit_get_rsa_fpr(commit),
533 75 : commit->encoded_commit,
534 75 : reveal_str != NULL ? reveal_str : "");
535 75 : if (reveal_str != NULL) {
536 69 : memwipe(reveal_str, 0, strlen(reveal_str));
537 69 : tor_free(reveal_str);
538 : }
539 75 : }
540 :
541 : /** From a valid srv object and an allocated config line, set the line's
542 : * value to the state string representation of a shared random value. */
543 : static void
544 78 : disk_state_put_srv_line(const sr_srv_t *srv, config_line_t *line)
545 : {
546 78 : char encoded[SR_SRV_VALUE_BASE64_LEN + 1];
547 :
548 78 : tor_assert(line);
549 :
550 : /* No SRV value thus don't add the line. This is possible since we might
551 : * not have a current or previous SRV value in our state. */
552 78 : if (srv == NULL) {
553 0 : return;
554 : }
555 78 : sr_srv_encode(encoded, sizeof(encoded), srv);
556 78 : tor_asprintf(&line->value, "%" PRIu64 " %s", srv->num_reveals, encoded);
557 : }
558 :
559 : /** Reset disk state that is free allocated memory and zeroed the object. */
560 : static void
561 170 : disk_state_reset(void)
562 : {
563 : /* Free allocated memory */
564 170 : config_free_lines(sr_disk_state->Commit);
565 170 : config_free_lines(sr_disk_state->SharedRandValues);
566 170 : config_free_lines(sr_disk_state->ExtraLines);
567 170 : tor_free(sr_disk_state->TorVersion);
568 :
569 : /* Clear other fields. */
570 170 : sr_disk_state->ValidAfter = 0;
571 170 : sr_disk_state->ValidUntil = 0;
572 170 : sr_disk_state->Version = 0;
573 :
574 : /* Reset it with useful data */
575 170 : sr_disk_state->TorVersion = tor_strdup(get_version());
576 170 : }
577 :
578 : /** Update our disk state based on our global SR state. */
579 : static void
580 170 : disk_state_update(void)
581 : {
582 170 : config_line_t **next, *line;
583 :
584 170 : if (BUG(!sr_disk_state))
585 0 : return;
586 170 : if (BUG(!sr_state))
587 0 : return;
588 :
589 : /* Reset current disk state. */
590 170 : disk_state_reset();
591 :
592 : /* First, update elements that we don't need to do a construction. */
593 170 : sr_disk_state->Version = sr_state->version;
594 170 : sr_disk_state->ValidUntil = sr_state->valid_until;
595 170 : sr_disk_state->ValidAfter = sr_state->valid_after;
596 :
597 : /* Shared random values. */
598 170 : next = &sr_disk_state->SharedRandValues;
599 170 : if (sr_state->previous_srv != NULL) {
600 40 : *next = line = tor_malloc_zero(sizeof(config_line_t));
601 40 : line->key = tor_strdup(dstate_prev_srv_key);
602 40 : disk_state_put_srv_line(sr_state->previous_srv, line);
603 : /* Go to the next shared random value. */
604 40 : next = &(line->next);
605 : }
606 170 : if (sr_state->current_srv != NULL) {
607 38 : *next = line = tor_malloc_zero(sizeof(*line));
608 38 : line->key = tor_strdup(dstate_cur_srv_key);
609 38 : disk_state_put_srv_line(sr_state->current_srv, line);
610 : }
611 :
612 : /* Parse the commits and construct config line(s). */
613 170 : next = &sr_disk_state->Commit;
614 245 : DIGESTMAP_FOREACH(sr_state->commits, key, sr_commit_t *, commit) {
615 75 : *next = line = tor_malloc_zero(sizeof(*line));
616 75 : line->key = tor_strdup(dstate_commit_key);
617 75 : disk_state_put_commit_line(commit, line);
618 75 : next = &(line->next);
619 170 : } DIGESTMAP_FOREACH_END;
620 : }
621 :
622 : /** Load state from disk and put it into our disk state. If the state passes
623 : * validation, our global state will be updated with it. Return 0 on
624 : * success. On error, -EINVAL is returned if the state on disk did contained
625 : * something malformed or is unreadable. -ENOENT is returned indicating that
626 : * the state file is either empty of non existing. */
627 : static int
628 6 : disk_state_load_from_disk(void)
629 : {
630 6 : int ret;
631 6 : char *fname;
632 :
633 6 : fname = get_datadir_fname(default_fname);
634 6 : ret = disk_state_load_from_disk_impl(fname);
635 6 : tor_free(fname);
636 :
637 6 : return ret;
638 : }
639 :
640 : /** Helper for disk_state_load_from_disk(). */
641 : STATIC int
642 9 : disk_state_load_from_disk_impl(const char *fname)
643 : {
644 9 : int ret;
645 9 : char *content = NULL;
646 9 : sr_state_t *parsed_state = NULL;
647 9 : sr_disk_state_t *disk_state = NULL;
648 :
649 : /* Read content of file so we can parse it. */
650 9 : if ((content = read_file_to_str(fname, 0, NULL)) == NULL) {
651 3 : log_warn(LD_FS, "SR: Unable to read SR state file %s",
652 : escaped(fname));
653 3 : ret = -errno;
654 3 : goto error;
655 : }
656 :
657 : {
658 6 : config_line_t *lines = NULL;
659 6 : char *errmsg = NULL;
660 :
661 : /* Every error in this code path will return EINVAL. */
662 6 : ret = -EINVAL;
663 6 : if (config_get_lines(content, &lines, 0) < 0) {
664 0 : config_free_lines(lines);
665 0 : goto error;
666 : }
667 :
668 6 : disk_state = disk_state_new(time(NULL));
669 6 : config_assign(get_srs_mgr(), disk_state, lines, 0, &errmsg);
670 6 : config_free_lines(lines);
671 6 : if (errmsg) {
672 0 : log_warn(LD_DIR, "SR: Reading state error: %s", errmsg);
673 0 : tor_free(errmsg);
674 0 : goto error;
675 : }
676 : }
677 :
678 : /* So far so good, we've loaded our state file into our disk state. Let's
679 : * validate it and then parse it. */
680 6 : if (disk_state_validate(disk_state) < 0) {
681 0 : ret = -EINVAL;
682 0 : goto error;
683 : }
684 :
685 6 : parsed_state = disk_state_parse(disk_state);
686 6 : if (parsed_state == NULL) {
687 0 : ret = -EINVAL;
688 0 : goto error;
689 : }
690 6 : state_set(parsed_state);
691 6 : disk_state_set(disk_state);
692 6 : tor_free(content);
693 6 : log_info(LD_DIR, "SR: State loaded successfully from file %s", fname);
694 6 : return 0;
695 :
696 3 : error:
697 3 : disk_state_free(disk_state);
698 3 : tor_free(content);
699 3 : return ret;
700 : }
701 :
702 : /** Save the disk state to disk but before that update it from the current
703 : * state so we always have the latest. Return 0 on success else -1. */
704 : static int
705 170 : disk_state_save_to_disk(void)
706 : {
707 170 : int ret;
708 170 : char *state, *content = NULL, *fname = NULL;
709 170 : char tbuf[ISO_TIME_LEN + 1];
710 170 : time_t now = time(NULL);
711 :
712 : /* If we didn't have the opportunity to setup an internal disk state,
713 : * don't bother saving something to disk. */
714 170 : if (sr_disk_state == NULL) {
715 0 : ret = 0;
716 0 : goto done;
717 : }
718 :
719 : /* Make sure that our disk state is up to date with our memory state
720 : * before saving it to disk. */
721 170 : disk_state_update();
722 170 : state = config_dump(get_srs_mgr(), NULL, sr_disk_state, 0, 0);
723 170 : format_local_iso_time(tbuf, now);
724 170 : tor_asprintf(&content,
725 : "# Tor shared random state file last generated on %s "
726 : "local time\n"
727 : "# Other times below are in UTC\n"
728 : "# Please *do not* edit this file.\n\n%s",
729 : tbuf, state);
730 170 : tor_free(state);
731 170 : fname = get_datadir_fname(default_fname);
732 170 : if (write_str_to_file(fname, content, 0) < 0) {
733 0 : log_warn(LD_FS, "SR: Unable to write SR state to file %s", fname);
734 0 : ret = -1;
735 0 : goto done;
736 : }
737 170 : ret = 0;
738 170 : log_debug(LD_DIR, "SR: Saved state to file %s", fname);
739 :
740 170 : done:
741 170 : tor_free(fname);
742 170 : tor_free(content);
743 170 : return ret;
744 : }
745 :
746 : /** Reset our state to prepare for a new protocol run. Once this returns, all
747 : * commits in the state will be removed and freed. */
748 : STATIC void
749 3 : reset_state_for_new_protocol_run(time_t valid_after)
750 : {
751 3 : if (BUG(!sr_state))
752 0 : return;
753 :
754 : /* Keep counters in track */
755 3 : sr_state->n_reveal_rounds = 0;
756 3 : sr_state->n_commit_rounds = 0;
757 3 : sr_state->n_protocol_runs++;
758 :
759 : /* Reset valid-until */
760 3 : sr_state->valid_until = get_state_valid_until_time(valid_after);
761 3 : sr_state->valid_after = valid_after;
762 :
763 : /* We are in a new protocol run so cleanup commits. */
764 3 : sr_state_delete_commits();
765 : }
766 :
767 : /** This is the first round of the new protocol run starting at
768 : * <b>valid_after</b>. Do the necessary housekeeping. */
769 : STATIC void
770 2 : new_protocol_run(time_t valid_after)
771 : {
772 2 : sr_commit_t *our_commitment = NULL;
773 :
774 : /* Only compute the srv at the end of the reveal phase. */
775 2 : if (sr_state->phase == SR_PHASE_REVEAL) {
776 : /* We are about to compute a new shared random value that will be set in
777 : * our state as the current value so rotate values. */
778 2 : state_rotate_srv();
779 : /* Compute the shared randomness value of the day. */
780 2 : sr_compute_srv();
781 : }
782 :
783 : /* Prepare for the new protocol run by resetting the state */
784 2 : reset_state_for_new_protocol_run(valid_after);
785 :
786 : /* Do some logging */
787 2 : log_info(LD_DIR, "SR: Protocol run #%" PRIu64 " starting!",
788 : sr_state->n_protocol_runs);
789 :
790 : /* Generate fresh commitments for this protocol run */
791 2 : our_commitment = sr_generate_our_commit(valid_after,
792 2 : get_my_v3_authority_cert());
793 2 : if (our_commitment) {
794 : /* Add our commitment to our state. In case we are unable to create one
795 : * (highly unlikely), we won't vote for this protocol run since our
796 : * commitment won't be in our state. */
797 2 : sr_state_add_commit(our_commitment);
798 : }
799 2 : }
800 :
801 : /** Return 1 iff the <b>next_phase</b> is a phase transition from the current
802 : * phase that is it's different. */
803 : STATIC int
804 20 : is_phase_transition(sr_phase_t next_phase)
805 : {
806 20 : return sr_state->phase != next_phase;
807 : }
808 :
809 : /** Helper function: return a commit using the RSA fingerprint of the
810 : * authority or NULL if no such commit is known. */
811 : static sr_commit_t *
812 10 : state_query_get_commit(const char *rsa_fpr)
813 : {
814 10 : tor_assert(rsa_fpr);
815 10 : return digestmap_get(sr_state->commits, rsa_fpr);
816 : }
817 :
818 : /** Helper function: This handles the GET state action using an
819 : * <b>obj_type</b> and <b>data</b> needed for the action. */
820 : static void *
821 243 : state_query_get_(sr_state_object_t obj_type, const void *data)
822 : {
823 243 : if (BUG(!sr_state))
824 0 : return NULL;
825 :
826 243 : void *obj = NULL;
827 :
828 243 : switch (obj_type) {
829 10 : case SR_STATE_OBJ_COMMIT:
830 : {
831 10 : obj = state_query_get_commit(data);
832 10 : break;
833 : }
834 31 : case SR_STATE_OBJ_COMMITS:
835 31 : obj = sr_state->commits;
836 31 : break;
837 87 : case SR_STATE_OBJ_CURSRV:
838 87 : obj = sr_state->current_srv;
839 87 : break;
840 79 : case SR_STATE_OBJ_PREVSRV:
841 79 : obj = sr_state->previous_srv;
842 79 : break;
843 36 : case SR_STATE_OBJ_PHASE:
844 36 : obj = &sr_state->phase;
845 36 : break;
846 : case SR_STATE_OBJ_VALID_AFTER:
847 : default:
848 0 : tor_assert(0);
849 : }
850 : return obj;
851 : }
852 :
853 : /** Helper function: This handles the PUT state action using an
854 : * <b>obj_type</b> and <b>data</b> needed for the action.
855 : * PUT frees the previous data before replacing it, if needed. */
856 : static void
857 87 : state_query_put_(sr_state_object_t obj_type, void *data)
858 : {
859 87 : if (BUG(!sr_state))
860 0 : return;
861 :
862 87 : switch (obj_type) {
863 24 : case SR_STATE_OBJ_COMMIT:
864 : {
865 24 : sr_commit_t *commit = data;
866 24 : tor_assert(commit);
867 : /* commit_add_to_state() frees the old commit, if there is one */
868 24 : commit_add_to_state(commit, sr_state);
869 24 : break;
870 : }
871 25 : case SR_STATE_OBJ_CURSRV:
872 : /* Check if the new pointer is the same as the old one: if it is, it's
873 : * probably a bug. The caller may have confused current and previous,
874 : * or they may have forgotten to sr_srv_dup().
875 : * Putting NULL multiple times is allowed. */
876 25 : if (!BUG(data && sr_state->current_srv == (sr_srv_t *) data)) {
877 : /* We own the old SRV, so we need to free it. */
878 25 : state_query_del_(SR_STATE_OBJ_CURSRV, NULL);
879 25 : sr_state->current_srv = (sr_srv_t *) data;
880 : }
881 : break;
882 23 : case SR_STATE_OBJ_PREVSRV:
883 : /* Check if the new pointer is the same as the old one: if it is, it's
884 : * probably a bug. The caller may have confused current and previous,
885 : * or they may have forgotten to sr_srv_dup().
886 : * Putting NULL multiple times is allowed. */
887 23 : if (!BUG(data && sr_state->previous_srv == (sr_srv_t *) data)) {
888 : /* We own the old SRV, so we need to free it. */
889 23 : state_query_del_(SR_STATE_OBJ_PREVSRV, NULL);
890 23 : sr_state->previous_srv = (sr_srv_t *) data;
891 : }
892 : break;
893 15 : case SR_STATE_OBJ_VALID_AFTER:
894 15 : sr_state->valid_after = *((time_t *) data);
895 15 : break;
896 : /* It's not allowed to change the phase nor the full commitments map from
897 : * the state. The phase is decided during a strict process post voting and
898 : * the commits should be put individually. */
899 : case SR_STATE_OBJ_PHASE:
900 : case SR_STATE_OBJ_COMMITS:
901 : default:
902 0 : tor_assert(0);
903 : }
904 : }
905 :
906 : /** Helper function: This handles the DEL_ALL state action using an
907 : * <b>obj_type</b> and <b>data</b> needed for the action. */
908 : static void
909 12 : state_query_del_all_(sr_state_object_t obj_type)
910 : {
911 12 : if (BUG(!sr_state))
912 0 : return;
913 :
914 12 : switch (obj_type) {
915 12 : case SR_STATE_OBJ_COMMIT:
916 : {
917 : /* We are in a new protocol run so cleanup commitments. */
918 23 : DIGESTMAP_FOREACH_MODIFY(sr_state->commits, key, sr_commit_t *, c) {
919 11 : sr_commit_free(c);
920 11 : MAP_DEL_CURRENT(key);
921 : } DIGESTMAP_FOREACH_END;
922 : break;
923 : }
924 : /* The following objects are _NOT_ supposed to be removed. */
925 : case SR_STATE_OBJ_CURSRV:
926 : case SR_STATE_OBJ_PREVSRV:
927 : case SR_STATE_OBJ_PHASE:
928 : case SR_STATE_OBJ_COMMITS:
929 : case SR_STATE_OBJ_VALID_AFTER:
930 : default:
931 0 : tor_assert(0);
932 : }
933 : }
934 :
935 : /** Helper function: This handles the DEL state action using an
936 : * <b>obj_type</b> and <b>data</b> needed for the action. */
937 : static void
938 118 : state_query_del_(sr_state_object_t obj_type, void *data)
939 : {
940 118 : (void) data;
941 :
942 118 : if (BUG(!sr_state))
943 0 : return;
944 :
945 118 : switch (obj_type) {
946 60 : case SR_STATE_OBJ_PREVSRV:
947 60 : tor_free(sr_state->previous_srv);
948 60 : break;
949 58 : case SR_STATE_OBJ_CURSRV:
950 58 : tor_free(sr_state->current_srv);
951 58 : break;
952 : case SR_STATE_OBJ_COMMIT:
953 : case SR_STATE_OBJ_COMMITS:
954 : case SR_STATE_OBJ_PHASE:
955 : case SR_STATE_OBJ_VALID_AFTER:
956 : default:
957 0 : tor_assert(0);
958 : }
959 : }
960 :
961 : /** Query state using an <b>action</b> for an object type <b>obj_type</b>.
962 : * The <b>data</b> pointer needs to point to an object that the action needs
963 : * to use and if anything is required to be returned, it is stored in
964 : * <b>out</b>.
965 : *
966 : * This mechanism exists so we have one single point where we synchronized
967 : * our memory state with our disk state for every actions that changes it.
968 : * We then trigger a write on disk immediately.
969 : *
970 : * This should be the only entry point to our memory state. It's used by all
971 : * our state accessors and should be in the future. */
972 : static void
973 413 : state_query(sr_state_action_t action, sr_state_object_t obj_type,
974 : void *data, void **out)
975 : {
976 413 : switch (action) {
977 243 : case SR_STATE_ACTION_GET:
978 243 : *out = state_query_get_(obj_type, data);
979 243 : break;
980 87 : case SR_STATE_ACTION_PUT:
981 87 : state_query_put_(obj_type, data);
982 87 : break;
983 70 : case SR_STATE_ACTION_DEL:
984 70 : state_query_del_(obj_type, data);
985 70 : break;
986 12 : case SR_STATE_ACTION_DEL_ALL:
987 12 : state_query_del_all_(obj_type);
988 12 : break;
989 : case SR_STATE_ACTION_SAVE:
990 : /* Only trigger a disk state save. */
991 : break;
992 : default:
993 0 : tor_assert(0);
994 : }
995 :
996 : /* If the action actually changes the state, immediately save it to disk.
997 : * The following will sync the state -> disk state and then save it. */
998 413 : if (action != SR_STATE_ACTION_GET) {
999 170 : disk_state_save_to_disk();
1000 : }
1001 413 : }
1002 :
1003 : /** Delete the current SRV value from the state freeing it and the value is set
1004 : * to NULL meaning empty. */
1005 : STATIC void
1006 33 : state_del_current_srv(void)
1007 : {
1008 33 : state_query(SR_STATE_ACTION_DEL, SR_STATE_OBJ_CURSRV, NULL, NULL);
1009 33 : }
1010 :
1011 : /** Delete the previous SRV value from the state freeing it and the value is
1012 : * set to NULL meaning empty. */
1013 : STATIC void
1014 37 : state_del_previous_srv(void)
1015 : {
1016 37 : state_query(SR_STATE_ACTION_DEL, SR_STATE_OBJ_PREVSRV, NULL, NULL);
1017 37 : }
1018 :
1019 : /** Rotate SRV value by setting the previous SRV to the current SRV, and
1020 : * clearing the current SRV. */
1021 : STATIC void
1022 3 : state_rotate_srv(void)
1023 : {
1024 : /* First delete previous SRV from the state. Object will be freed. */
1025 3 : state_del_previous_srv();
1026 : /* Set previous SRV to a copy of the current one. */
1027 3 : sr_state_set_previous_srv(sr_srv_dup(sr_state_get_current_srv()));
1028 : /* Free and NULL the current srv. */
1029 3 : sr_state_set_current_srv(NULL);
1030 3 : }
1031 :
1032 : /** Set valid after time in the our state. */
1033 : void
1034 15 : sr_state_set_valid_after(time_t valid_after)
1035 : {
1036 15 : state_query(SR_STATE_ACTION_PUT, SR_STATE_OBJ_VALID_AFTER,
1037 : (void *) &valid_after, NULL);
1038 15 : }
1039 :
1040 : /** Return the phase we are currently in according to our state. */
1041 : sr_phase_t
1042 36 : sr_state_get_phase(void)
1043 : {
1044 36 : void *ptr=NULL;
1045 36 : state_query(SR_STATE_ACTION_GET, SR_STATE_OBJ_PHASE, NULL, &ptr);
1046 36 : tor_assert(ptr);
1047 36 : return *(sr_phase_t *) ptr;
1048 : }
1049 :
1050 : /** Return the previous SRV value from our state. Value CAN be NULL.
1051 : * The state object owns the SRV, so the calling code should not free the SRV.
1052 : * Use sr_srv_dup() if you want to keep a copy of the SRV. */
1053 : const sr_srv_t *
1054 79 : sr_state_get_previous_srv(void)
1055 : {
1056 79 : const sr_srv_t *srv;
1057 79 : state_query(SR_STATE_ACTION_GET, SR_STATE_OBJ_PREVSRV, NULL,
1058 : (void *) &srv);
1059 79 : return srv;
1060 : }
1061 :
1062 : /** Set the current SRV value from our state. Value CAN be NULL. The srv
1063 : * object ownership is transferred to the state object. */
1064 : void
1065 23 : sr_state_set_previous_srv(const sr_srv_t *srv)
1066 : {
1067 23 : state_query(SR_STATE_ACTION_PUT, SR_STATE_OBJ_PREVSRV, (void *) srv,
1068 : NULL);
1069 23 : }
1070 :
1071 : /** Return the current SRV value from our state. Value CAN be NULL.
1072 : * The state object owns the SRV, so the calling code should not free the SRV.
1073 : * Use sr_srv_dup() if you want to keep a copy of the SRV. */
1074 : const sr_srv_t *
1075 87 : sr_state_get_current_srv(void)
1076 : {
1077 87 : const sr_srv_t *srv;
1078 87 : state_query(SR_STATE_ACTION_GET, SR_STATE_OBJ_CURSRV, NULL,
1079 : (void *) &srv);
1080 87 : return srv;
1081 : }
1082 :
1083 : /** Set the current SRV value from our state. Value CAN be NULL. The srv
1084 : * object ownership is transferred to the state object. */
1085 : void
1086 25 : sr_state_set_current_srv(const sr_srv_t *srv)
1087 : {
1088 25 : state_query(SR_STATE_ACTION_PUT, SR_STATE_OBJ_CURSRV, (void *) srv,
1089 : NULL);
1090 25 : }
1091 :
1092 : /** Clean all the SRVs in our state. */
1093 : void
1094 29 : sr_state_clean_srvs(void)
1095 : {
1096 : /* Remove SRVs from state. They will be set to NULL as "empty". */
1097 29 : state_del_previous_srv();
1098 29 : state_del_current_srv();
1099 29 : }
1100 :
1101 : /** Return a pointer to the commits map from our state. CANNOT be NULL. */
1102 : digestmap_t *
1103 31 : sr_state_get_commits(void)
1104 : {
1105 31 : digestmap_t *commits;
1106 31 : state_query(SR_STATE_ACTION_GET, SR_STATE_OBJ_COMMITS,
1107 : NULL, (void *) &commits);
1108 31 : tor_assert(commits);
1109 31 : return commits;
1110 : }
1111 :
1112 : /** Update the current SR state as needed for the upcoming voting round at
1113 : * <b>valid_after</b>. */
1114 : void
1115 21 : sr_state_update(time_t valid_after)
1116 : {
1117 21 : sr_phase_t next_phase;
1118 :
1119 21 : if (BUG(!sr_state))
1120 0 : return;
1121 :
1122 : /* Don't call this function twice in the same voting period. */
1123 21 : if (valid_after <= sr_state->valid_after) {
1124 6 : log_info(LD_DIR, "SR: Asked to update state twice. Ignoring.");
1125 6 : return;
1126 : }
1127 :
1128 : /* Get phase of upcoming round. */
1129 15 : next_phase = get_sr_protocol_phase(valid_after);
1130 :
1131 : /* If we are transitioning to a new protocol phase, prepare the stage. */
1132 15 : if (is_phase_transition(next_phase)) {
1133 2 : if (next_phase == SR_PHASE_COMMIT) {
1134 : /* Going into commit phase means we are starting a new protocol run. */
1135 1 : new_protocol_run(valid_after);
1136 : }
1137 : /* Set the new phase for this round */
1138 2 : sr_state->phase = next_phase;
1139 26 : } else if (sr_state->phase == SR_PHASE_COMMIT &&
1140 13 : digestmap_size(sr_state->commits) == 0) {
1141 : /* We are _NOT_ in a transition phase so if we are in the commit phase
1142 : * and have no commit, generate one. Chances are that we are booting up
1143 : * so let's have a commit in our state for the next voting period. */
1144 13 : sr_commit_t *our_commit =
1145 13 : sr_generate_our_commit(valid_after, get_my_v3_authority_cert());
1146 13 : if (our_commit) {
1147 : /* Add our commitment to our state. In case we are unable to create one
1148 : * (highly unlikely), we won't vote for this protocol run since our
1149 : * commitment won't be in our state. */
1150 13 : sr_state_add_commit(our_commit);
1151 : }
1152 : }
1153 :
1154 15 : sr_state_set_valid_after(valid_after);
1155 :
1156 : /* Count the current round */
1157 15 : if (sr_state->phase == SR_PHASE_COMMIT) {
1158 : /* invariant check: we've not entered reveal phase yet */
1159 14 : if (BUG(sr_state->n_reveal_rounds != 0))
1160 0 : return;
1161 14 : sr_state->n_commit_rounds++;
1162 : } else {
1163 1 : sr_state->n_reveal_rounds++;
1164 : }
1165 :
1166 : { /* Debugging. */
1167 15 : char tbuf[ISO_TIME_LEN + 1];
1168 15 : format_iso_time(tbuf, valid_after);
1169 15 : log_info(LD_DIR, "SR: State prepared for upcoming voting period (%s). "
1170 : "Upcoming phase is %s (counters: %d commit & %d reveal rounds).",
1171 : tbuf, get_phase_str(sr_state->phase),
1172 : sr_state->n_commit_rounds, sr_state->n_reveal_rounds);
1173 : }
1174 : }
1175 :
1176 : /** Return commit object from the given authority digest <b>rsa_identity</b>.
1177 : * Return NULL if not found. */
1178 : sr_commit_t *
1179 10 : sr_state_get_commit(const char *rsa_identity)
1180 : {
1181 10 : sr_commit_t *commit;
1182 :
1183 10 : tor_assert(rsa_identity);
1184 :
1185 10 : state_query(SR_STATE_ACTION_GET, SR_STATE_OBJ_COMMIT,
1186 : (void *) rsa_identity, (void *) &commit);
1187 10 : return commit;
1188 : }
1189 :
1190 : /** Add <b>commit</b> to the permanent state. The commit object ownership is
1191 : * transferred to the state so the caller MUST not free it. */
1192 : void
1193 24 : sr_state_add_commit(sr_commit_t *commit)
1194 : {
1195 24 : tor_assert(commit);
1196 :
1197 : /* Put the commit to the global state. */
1198 24 : state_query(SR_STATE_ACTION_PUT, SR_STATE_OBJ_COMMIT,
1199 : (void *) commit, NULL);
1200 :
1201 24 : log_debug(LD_DIR, "SR: Commit from %s has been added to our state.",
1202 : sr_commit_get_rsa_fpr(commit));
1203 24 : }
1204 :
1205 : /** Remove all commits from our state. */
1206 : void
1207 12 : sr_state_delete_commits(void)
1208 : {
1209 12 : state_query(SR_STATE_ACTION_DEL_ALL, SR_STATE_OBJ_COMMIT, NULL, NULL);
1210 12 : }
1211 :
1212 : /** Copy the reveal information from <b>commit</b> into <b>saved_commit</b>.
1213 : * This <b>saved_commit</b> MUST come from our current SR state. Once modified,
1214 : * the disk state is updated. */
1215 : void
1216 1 : sr_state_copy_reveal_info(sr_commit_t *saved_commit, const sr_commit_t *commit)
1217 : {
1218 1 : tor_assert(saved_commit);
1219 1 : tor_assert(commit);
1220 :
1221 1 : saved_commit->reveal_ts = commit->reveal_ts;
1222 1 : memcpy(saved_commit->random_number, commit->random_number,
1223 : sizeof(saved_commit->random_number));
1224 :
1225 1 : strlcpy(saved_commit->encoded_reveal, commit->encoded_reveal,
1226 : sizeof(saved_commit->encoded_reveal));
1227 1 : state_query(SR_STATE_ACTION_SAVE, 0, NULL, NULL);
1228 1 : log_debug(LD_DIR, "SR: Reveal value learned %s (for commit %s) from %s",
1229 : saved_commit->encoded_reveal, saved_commit->encoded_commit,
1230 : sr_commit_get_rsa_fpr(saved_commit));
1231 1 : }
1232 :
1233 : /** Set the fresh SRV flag from our state. This doesn't need to trigger a
1234 : * disk state synchronization so we directly change the state. */
1235 : void
1236 4 : sr_state_set_fresh_srv(void)
1237 : {
1238 4 : sr_state->is_srv_fresh = 1;
1239 4 : }
1240 :
1241 : /** Unset the fresh SRV flag from our state. This doesn't need to trigger a
1242 : * disk state synchronization so we directly change the state. */
1243 : void
1244 0 : sr_state_unset_fresh_srv(void)
1245 : {
1246 0 : sr_state->is_srv_fresh = 0;
1247 0 : }
1248 :
1249 : /** Return the value of the fresh SRV flag. */
1250 : unsigned int
1251 2 : sr_state_srv_is_fresh(void)
1252 : {
1253 2 : return sr_state->is_srv_fresh;
1254 : }
1255 :
1256 : /** Cleanup and free our disk and memory state. */
1257 : void
1258 5 : sr_state_free_all(void)
1259 : {
1260 5 : state_free(sr_state);
1261 5 : disk_state_free(sr_disk_state);
1262 : /* Nullify our global state. */
1263 5 : sr_state = NULL;
1264 5 : sr_disk_state = NULL;
1265 5 : config_mgr_free(shared_random_state_mgr);
1266 5 : }
1267 :
1268 : /** Save our current state in memory to disk. */
1269 : void
1270 0 : sr_state_save(void)
1271 : {
1272 : /* Query a SAVE action on our current state so it's synced and saved. */
1273 0 : state_query(SR_STATE_ACTION_SAVE, 0, NULL, NULL);
1274 0 : }
1275 :
1276 : /** Return 1 iff the state has been initialized that is it exists in memory.
1277 : * Return 0 otherwise. */
1278 : int
1279 17 : sr_state_is_initialized(void)
1280 : {
1281 17 : return sr_state == NULL ? 0 : 1;
1282 : }
1283 :
1284 : /** Initialize the disk and memory state.
1285 : *
1286 : * If save_to_disk is set to 1, the state is immediately saved to disk after
1287 : * creation else it's not thus only kept in memory.
1288 : * If read_from_disk is set to 1, we try to load the state from the disk and
1289 : * if not found, a new state is created.
1290 : *
1291 : * Return 0 on success else a negative value on error. */
1292 : int
1293 17 : sr_state_init(int save_to_disk, int read_from_disk)
1294 : {
1295 17 : int ret = -ENOENT;
1296 17 : time_t now = time(NULL);
1297 :
1298 : /* We shouldn't have those assigned. */
1299 17 : tor_assert(sr_disk_state == NULL);
1300 17 : tor_assert(sr_state == NULL);
1301 :
1302 : /* First, try to load the state from disk. */
1303 17 : if (read_from_disk) {
1304 6 : ret = disk_state_load_from_disk();
1305 : }
1306 :
1307 6 : if (ret < 0) {
1308 12 : switch (-ret) {
1309 12 : case EINVAL:
1310 : /* We have a state on disk but it contains something we couldn't parse
1311 : * or an invalid entry in the state file. Let's remove it since it's
1312 : * obviously unusable and replace it by an new fresh state below. */
1313 : case ENOENT:
1314 : {
1315 : /* No state on disk so allocate our states for the first time. */
1316 12 : sr_state_t *new_state = state_new(default_fname, now);
1317 12 : sr_disk_state_t *new_disk_state = disk_state_new(now);
1318 12 : state_set(new_state);
1319 : /* It's important to set our disk state pointer since the save call
1320 : * below uses it to synchronized it with our memory state. */
1321 12 : disk_state_set(new_disk_state);
1322 : /* No entry, let's save our new state to disk. */
1323 12 : if (save_to_disk && disk_state_save_to_disk() < 0) {
1324 0 : goto error;
1325 : }
1326 : break;
1327 : }
1328 : default:
1329 : /* Big problem. Not possible. */
1330 0 : tor_assert(0);
1331 : }
1332 : }
1333 : /* We have a state in memory, let's make sure it's updated for the current
1334 : * and next voting round. */
1335 : {
1336 17 : time_t valid_after = dirauth_sched_get_next_valid_after_time();
1337 17 : sr_state_update(valid_after);
1338 : }
1339 17 : return 0;
1340 :
1341 0 : error:
1342 0 : return -1;
1343 : }
1344 :
1345 : #ifdef TOR_UNIT_TESTS
1346 :
1347 : /** Set the current phase of the protocol. Used only by unit tests. */
1348 : void
1349 10 : set_sr_phase(sr_phase_t phase)
1350 : {
1351 10 : if (BUG(!sr_state))
1352 0 : return;
1353 10 : sr_state->phase = phase;
1354 : }
1355 :
1356 : /** Get the SR state. Used only by unit tests */
1357 : sr_state_t *
1358 6 : get_sr_state(void)
1359 : {
1360 6 : return sr_state;
1361 : }
1362 :
1363 : #endif /* defined(TOR_UNIT_TESTS) */
|