Line data Source code
1 : /* Copyright (c) 2001-2004, Roger Dingledine.
2 : * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 : * Copyright (c) 2007-2021, The Tor Project, Inc. */
4 : /* See LICENSE for licensing information */
5 :
6 : #include "orconfig.h"
7 : #define DIRVOTE_PRIVATE
8 : #include "test/test.h"
9 : #include "core/or/or.h"
10 : #include "feature/dirauth/dirvote.h"
11 : #include "feature/nodelist/nodelist.h"
12 : #include "feature/nodelist/routerlist.h"
13 : #include "feature/dirparse/authcert_parse.h"
14 : #include "feature/dirparse/ns_parse.h"
15 : #include "test/test_dir_common.h"
16 : #include "feature/dirauth/voting_schedule.h"
17 :
18 : #include "feature/nodelist/authority_cert_st.h"
19 : #include "feature/nodelist/networkstatus_st.h"
20 : #include "feature/nodelist/networkstatus_voter_info_st.h"
21 : #include "feature/nodelist/routerinfo_st.h"
22 : #include "feature/dirauth/vote_microdesc_hash_st.h"
23 : #include "feature/nodelist/vote_routerstatus_st.h"
24 :
25 : void dir_common_setup_vote(networkstatus_t **vote, time_t now);
26 : networkstatus_t * dir_common_add_rs_and_parse(networkstatus_t *vote,
27 : networkstatus_t **vote_out,
28 : vote_routerstatus_t * (*vrs_gen)(int idx, time_t now),
29 : crypto_pk_t *sign_skey, int *n_vrs,
30 : time_t now, int clear_rl);
31 :
32 : /** Initialize and set auth certs and keys
33 : * Returns 0 on success, -1 on failure. Clean up handled by caller.
34 : */
35 : int
36 6 : dir_common_authority_pk_init(authority_cert_t **cert1,
37 : authority_cert_t **cert2,
38 : authority_cert_t **cert3,
39 : crypto_pk_t **sign_skey_1,
40 : crypto_pk_t **sign_skey_2,
41 : crypto_pk_t **sign_skey_3)
42 : {
43 : /* Parse certificates and keys. */
44 6 : authority_cert_t *cert;
45 6 : cert = authority_cert_parse_from_string(AUTHORITY_CERT_1,
46 : strlen(AUTHORITY_CERT_1),
47 : NULL);
48 6 : tt_assert(cert);
49 6 : tt_assert(cert->identity_key);
50 6 : *cert1 = cert;
51 6 : tt_assert(*cert1);
52 6 : *cert2 = authority_cert_parse_from_string(AUTHORITY_CERT_2,
53 : strlen(AUTHORITY_CERT_2),
54 : NULL);
55 6 : tt_assert(*cert2);
56 6 : *cert3 = authority_cert_parse_from_string(AUTHORITY_CERT_3,
57 : strlen(AUTHORITY_CERT_3),
58 : NULL);
59 6 : tt_assert(*cert3);
60 6 : *sign_skey_1 = crypto_pk_new();
61 6 : *sign_skey_2 = crypto_pk_new();
62 6 : *sign_skey_3 = crypto_pk_new();
63 :
64 6 : tt_assert(!crypto_pk_read_private_key_from_string(*sign_skey_1,
65 : AUTHORITY_SIGNKEY_1, -1));
66 6 : tt_assert(!crypto_pk_read_private_key_from_string(*sign_skey_2,
67 : AUTHORITY_SIGNKEY_2, -1));
68 6 : tt_assert(!crypto_pk_read_private_key_from_string(*sign_skey_3,
69 : AUTHORITY_SIGNKEY_3, -1));
70 :
71 6 : tt_assert(!crypto_pk_cmp_keys(*sign_skey_1, (*cert1)->signing_key));
72 6 : tt_assert(!crypto_pk_cmp_keys(*sign_skey_2, (*cert2)->signing_key));
73 :
74 : return 0;
75 : done:
76 : return -1;
77 : }
78 :
79 : /**
80 : * Generate a routerstatus for v3_networkstatus test.
81 : */
82 : vote_routerstatus_t *
83 105 : dir_common_gen_routerstatus_for_v3ns(int idx, time_t now)
84 : {
85 105 : vote_routerstatus_t *vrs=NULL;
86 105 : routerstatus_t *rs = NULL;
87 105 : tor_addr_t addr_ipv6;
88 105 : char *method_list = NULL;
89 :
90 105 : switch (idx) {
91 21 : case 0:
92 : /* Generate the first routerstatus. */
93 21 : vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
94 21 : rs = &vrs->status;
95 21 : vrs->version = tor_strdup("0.1.2.14");
96 21 : rs->published_on = now-1500;
97 21 : strlcpy(rs->nickname, "router2", sizeof(rs->nickname));
98 21 : memset(rs->identity_digest, TEST_DIR_ROUTER_ID_1, DIGEST_LEN);
99 21 : memset(rs->descriptor_digest, TEST_DIR_ROUTER_DD_1, DIGEST_LEN);
100 21 : tor_addr_from_ipv4h(&rs->ipv4_addr, 0x99008801);
101 21 : rs->ipv4_orport = 443;
102 21 : rs->ipv4_dirport = 8000;
103 : /* all flags but running and v2dir cleared */
104 21 : rs->is_flagged_running = 1;
105 21 : rs->is_v2_dir = 1;
106 21 : rs->is_valid = 1; /* xxxxx */
107 21 : vrs->protocols = tor_strdup("Link=7 HSDir=3");
108 21 : break;
109 21 : case 1:
110 : /* Generate the second routerstatus. */
111 21 : vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
112 21 : rs = &vrs->status;
113 21 : vrs->version = tor_strdup("0.2.0.5");
114 21 : rs->published_on = now-1000;
115 21 : strlcpy(rs->nickname, "router1", sizeof(rs->nickname));
116 21 : memset(rs->identity_digest, TEST_DIR_ROUTER_ID_2, DIGEST_LEN);
117 21 : memset(rs->descriptor_digest, TEST_DIR_ROUTER_DD_2, DIGEST_LEN);
118 21 : tor_addr_from_ipv4h(&rs->ipv4_addr, 0x99009901);
119 21 : rs->ipv4_orport = 443;
120 21 : rs->ipv4_dirport = 0;
121 21 : tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
122 21 : tor_addr_copy(&rs->ipv6_addr, &addr_ipv6);
123 21 : rs->ipv6_orport = 4711;
124 21 : rs->is_exit = rs->is_stable = rs->is_fast = rs->is_flagged_running =
125 21 : rs->is_valid = rs->is_possible_guard = rs->is_v2_dir = 1;
126 21 : vrs->protocols = tor_strdup("Link=3,4 HSDir=2,3");
127 21 : break;
128 21 : case 2:
129 : /* Generate the third routerstatus. */
130 21 : vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
131 21 : rs = &vrs->status;
132 21 : vrs->version = tor_strdup("0.1.0.3");
133 21 : rs->published_on = now-1000;
134 21 : strlcpy(rs->nickname, "router3", sizeof(rs->nickname));
135 21 : memset(rs->identity_digest, TEST_DIR_ROUTER_ID_3, DIGEST_LEN);
136 21 : memset(rs->descriptor_digest, TEST_DIR_ROUTER_DD_3, DIGEST_LEN);
137 21 : tor_addr_from_ipv4h(&rs->ipv4_addr, 0xAA009901);
138 21 : rs->ipv4_orport = 400;
139 21 : rs->ipv4_dirport = 9999;
140 21 : rs->is_authority = rs->is_exit = rs->is_stable = rs->is_fast =
141 21 : rs->is_flagged_running = rs->is_valid = rs->is_v2_dir =
142 21 : rs->is_possible_guard = 1;
143 21 : vrs->protocols = tor_strdup("Link=3,4 HSDir=2,3");
144 21 : break;
145 21 : case 3:
146 : /* Generate a fourth routerstatus that is not running. */
147 21 : vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
148 21 : rs = &vrs->status;
149 21 : vrs->version = tor_strdup("0.1.6.3");
150 21 : rs->published_on = now-1000;
151 21 : strlcpy(rs->nickname, "router4", sizeof(rs->nickname));
152 21 : memset(rs->identity_digest, TEST_DIR_ROUTER_ID_4, DIGEST_LEN);
153 21 : memset(rs->descriptor_digest, TEST_DIR_ROUTER_DD_4, DIGEST_LEN);
154 21 : tor_addr_from_ipv4h(&rs->ipv4_addr, 0xC0000203);
155 21 : rs->ipv4_orport = 500;
156 21 : rs->ipv4_dirport = 1999;
157 21 : rs->is_v2_dir = 1;
158 21 : vrs->protocols = tor_strdup("Link=3,4 HSDir=3");
159 : /* Running flag (and others) cleared */
160 21 : break;
161 : case 4:
162 : /* No more for this test; return NULL */
163 : vrs = NULL;
164 : break;
165 0 : default:
166 : /* Shouldn't happen */
167 0 : tt_abort();
168 : }
169 84 : if (vrs) {
170 84 : vrs->microdesc = tor_malloc_zero(sizeof(vote_microdesc_hash_t));
171 84 : method_list = make_consensus_method_list(MIN_SUPPORTED_CONSENSUS_METHOD,
172 : MAX_SUPPORTED_CONSENSUS_METHOD,
173 : ",");
174 84 : tor_asprintf(&vrs->microdesc->microdesc_hash_line,
175 : "m %s "
176 : "sha256=xyzajkldsdsajdadlsdjaslsdksdjlsdjsdaskdaaa%d\n",
177 : method_list, idx);
178 : }
179 :
180 105 : done:
181 105 : tor_free(method_list);
182 105 : return vrs;
183 : }
184 :
185 : /** Initialize networkstatus vote object attributes. */
186 : void
187 27 : dir_common_setup_vote(networkstatus_t **vote, time_t now)
188 : {
189 27 : *vote = tor_malloc_zero(sizeof(networkstatus_t));
190 27 : (*vote)->type = NS_TYPE_VOTE;
191 27 : (*vote)->published = now;
192 27 : (*vote)->supported_methods = smartlist_new();
193 27 : (*vote)->known_flags = smartlist_new();
194 27 : (*vote)->net_params = smartlist_new();
195 27 : (*vote)->routerstatus_list = smartlist_new();
196 27 : (*vote)->voters = smartlist_new();
197 27 : }
198 :
199 : /** Helper: Make a new routerinfo containing the right information for a
200 : * given vote_routerstatus_t. */
201 : routerinfo_t *
202 109 : dir_common_generate_ri_from_rs(const vote_routerstatus_t *vrs)
203 : {
204 109 : routerinfo_t *r;
205 109 : const routerstatus_t *rs = &vrs->status;
206 109 : static time_t published = 0;
207 :
208 109 : r = tor_malloc_zero(sizeof(routerinfo_t));
209 109 : r->cert_expiration_time = TIME_MAX;
210 109 : memcpy(r->cache_info.identity_digest, rs->identity_digest, DIGEST_LEN);
211 109 : memcpy(r->cache_info.signed_descriptor_digest, rs->descriptor_digest,
212 : DIGEST_LEN);
213 109 : r->cache_info.do_not_cache = 1;
214 109 : r->cache_info.routerlist_index = -1;
215 218 : r->cache_info.signed_descriptor_body =
216 109 : tor_strdup("123456789012345678901234567890123");
217 109 : r->cache_info.signed_descriptor_len =
218 109 : strlen(r->cache_info.signed_descriptor_body);
219 109 : r->exit_policy = smartlist_new();
220 109 : r->cache_info.published_on = ++published + time(NULL);
221 109 : if (rs->has_bandwidth) {
222 : /*
223 : * Multiply by 1000 because the routerinfo_t and the routerstatus_t
224 : * seem to use different units (*sigh*) and because we seem stuck on
225 : * icky and perverse decimal kilobytes (*double sigh*) - see
226 : * router_get_advertised_bandwidth_capped() of routerlist.c and
227 : * routerstatus_format_entry() of dirserv.c.
228 : */
229 25 : r->bandwidthrate = rs->bandwidth_kb * 1000;
230 25 : r->bandwidthcapacity = rs->bandwidth_kb * 1000;
231 : }
232 109 : return r;
233 : }
234 :
235 : /** Create routerstatuses and signed vote.
236 : * Create routerstatuses using *vrs_gen* and add them to global routerlist.
237 : * Next, create signed vote using *sign_skey* and *vote*, which should have
238 : * predefined header fields.
239 : * Setting *clear_rl* clears the global routerlist before adding the new
240 : * routers.
241 : * Return the signed vote, same as *vote_out*. Save the number of routers added
242 : * in *n_vrs*.
243 : */
244 : networkstatus_t *
245 27 : dir_common_add_rs_and_parse(networkstatus_t *vote, networkstatus_t **vote_out,
246 : vote_routerstatus_t * (*vrs_gen)(int idx, time_t now),
247 : crypto_pk_t *sign_skey, int *n_vrs, time_t now,
248 : int clear_rl)
249 : {
250 27 : vote_routerstatus_t *vrs;
251 27 : char *v_text=NULL;
252 27 : const char *msg=NULL;
253 27 : int idx;
254 27 : was_router_added_t router_added = -1;
255 27 : *vote_out = NULL;
256 :
257 27 : if (clear_rl) {
258 27 : nodelist_free_all();
259 27 : routerlist_free_all();
260 : }
261 :
262 : idx = 0;
263 135 : do {
264 135 : vrs = vrs_gen(idx, now);
265 135 : if (vrs) {
266 108 : smartlist_add(vote->routerstatus_list, vrs);
267 108 : router_added =
268 108 : router_add_to_routerlist(dir_common_generate_ri_from_rs(vrs),
269 : &msg,0,0);
270 108 : tt_assert(router_added >= 0);
271 108 : ++idx;
272 : }
273 135 : } while (vrs);
274 27 : *n_vrs = idx;
275 :
276 : /* dump the vote and try to parse it. */
277 27 : v_text = format_networkstatus_vote(sign_skey, vote);
278 27 : tt_assert(v_text);
279 27 : *vote_out = networkstatus_parse_vote_from_string(v_text,
280 : strlen(v_text),
281 : NULL, NS_TYPE_VOTE);
282 :
283 27 : done:
284 27 : if (v_text)
285 27 : tor_free(v_text);
286 :
287 27 : return *vote_out;
288 : }
289 :
290 : /** Create a fake *vote* where *cert* describes the signer, *sign_skey*
291 : * is the signing key, and *vrs_gen* is the function we'll use to create the
292 : * routers on which we're voting.
293 : * We pass *vote_out*, *n_vrs*, and *clear_rl* directly to vrs_gen().
294 : * Return 0 on success, return -1 on failure.
295 : */
296 : int
297 9 : dir_common_construct_vote_1(networkstatus_t **vote, authority_cert_t *cert,
298 : crypto_pk_t *sign_skey,
299 : vote_routerstatus_t * (*vrs_gen)(int idx, time_t now),
300 : networkstatus_t **vote_out, int *n_vrs,
301 : time_t now, int clear_rl)
302 : {
303 9 : networkstatus_voter_info_t *voter;
304 :
305 9 : dir_common_setup_vote(vote, now);
306 9 : (*vote)->valid_after = now+1000;
307 9 : (*vote)->fresh_until = now+2000;
308 9 : (*vote)->valid_until = now+3000;
309 9 : (*vote)->vote_seconds = 100;
310 9 : (*vote)->dist_seconds = 200;
311 9 : smartlist_split_string((*vote)->supported_methods, "1 2 3", NULL, 0, -1);
312 9 : (*vote)->client_versions = tor_strdup("0.1.2.14,0.1.2.15");
313 9 : (*vote)->server_versions = tor_strdup("0.1.2.14,0.1.2.15,0.1.2.16");
314 9 : smartlist_split_string((*vote)->known_flags,
315 : "Authority Exit Fast Guard Running Stable V2Dir Valid",
316 : 0, SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
317 9 : voter = tor_malloc_zero(sizeof(networkstatus_voter_info_t));
318 9 : voter->nickname = tor_strdup("Voter1");
319 9 : voter->address = tor_strdup("1.2.3.4");
320 9 : tor_addr_from_ipv4h(&voter->ipv4_addr, 0x01020304);
321 9 : voter->ipv4_dirport = 80;
322 9 : voter->ipv4_orport = 9000;
323 9 : voter->contact = tor_strdup("voter@example.com");
324 9 : crypto_pk_get_digest(cert->identity_key, voter->identity_digest);
325 : /*
326 : * Set up a vote; generate it; try to parse it.
327 : */
328 9 : smartlist_add((*vote)->voters, voter);
329 9 : (*vote)->cert = authority_cert_dup(cert);
330 9 : smartlist_split_string((*vote)->net_params, "circuitwindow=101 foo=990",
331 : NULL, 0, 0);
332 9 : *n_vrs = 0;
333 : /* add routerstatuses */
334 9 : if (!dir_common_add_rs_and_parse(*vote, vote_out, vrs_gen, sign_skey,
335 : n_vrs, now, clear_rl))
336 0 : return -1;
337 :
338 : return 0;
339 : }
340 :
341 : /** See dir_common_construct_vote_1.
342 : * Produces a vote with slightly different values.
343 : */
344 : int
345 9 : dir_common_construct_vote_2(networkstatus_t **vote, authority_cert_t *cert,
346 : crypto_pk_t *sign_skey,
347 : vote_routerstatus_t * (*vrs_gen)(int idx, time_t now),
348 : networkstatus_t **vote_out, int *n_vrs,
349 : time_t now, int clear_rl)
350 : {
351 9 : networkstatus_voter_info_t *voter;
352 :
353 9 : dir_common_setup_vote(vote, now);
354 9 : (*vote)->type = NS_TYPE_VOTE;
355 9 : (*vote)->published += 1;
356 9 : (*vote)->valid_after = now+1000;
357 9 : (*vote)->fresh_until = now+3005;
358 9 : (*vote)->valid_until = now+3000;
359 9 : (*vote)->vote_seconds = 100;
360 9 : (*vote)->dist_seconds = 300;
361 9 : smartlist_split_string((*vote)->supported_methods, "1 2 3", NULL, 0, -1);
362 9 : smartlist_split_string((*vote)->known_flags,
363 : "Authority Exit Fast Guard MadeOfCheese MadeOfTin "
364 : "Running Stable V2Dir Valid", 0,
365 : SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
366 9 : voter = tor_malloc_zero(sizeof(networkstatus_voter_info_t));
367 9 : voter->nickname = tor_strdup("Voter2");
368 9 : voter->address = tor_strdup("2.3.4.5");
369 9 : tor_addr_from_ipv4h(&voter->ipv4_addr, 0x02030405);
370 9 : voter->ipv4_dirport = 80;
371 9 : voter->ipv4_orport = 9000;
372 9 : voter->contact = tor_strdup("voter@example.com");
373 9 : crypto_pk_get_digest(cert->identity_key, voter->identity_digest);
374 : /*
375 : * Set up a vote; generate it; try to parse it.
376 : */
377 9 : smartlist_add((*vote)->voters, voter);
378 9 : (*vote)->cert = authority_cert_dup(cert);
379 9 : if (! (*vote)->net_params)
380 0 : (*vote)->net_params = smartlist_new();
381 9 : smartlist_split_string((*vote)->net_params,
382 : "bar=2000000000 circuitwindow=20",
383 : NULL, 0, 0);
384 : /* add routerstatuses */
385 : /* dump the vote and try to parse it. */
386 9 : dir_common_add_rs_and_parse(*vote, vote_out, vrs_gen, sign_skey,
387 : n_vrs, now, clear_rl);
388 :
389 9 : return 0;
390 : }
391 :
392 : /** See dir_common_construct_vote_1.
393 : * Produces a vote with slightly different values. Adds a legacy key.
394 : */
395 : int
396 9 : dir_common_construct_vote_3(networkstatus_t **vote, authority_cert_t *cert,
397 : crypto_pk_t *sign_skey,
398 : vote_routerstatus_t * (*vrs_gen)(int idx, time_t now),
399 : networkstatus_t **vote_out, int *n_vrs,
400 : time_t now, int clear_rl)
401 : {
402 9 : networkstatus_voter_info_t *voter;
403 :
404 9 : dir_common_setup_vote(vote, now);
405 9 : (*vote)->valid_after = now+1000;
406 9 : (*vote)->fresh_until = now+2003;
407 9 : (*vote)->valid_until = now+3000;
408 9 : (*vote)->vote_seconds = 100;
409 9 : (*vote)->dist_seconds = 250;
410 9 : smartlist_split_string((*vote)->supported_methods, "1 2 3 4", NULL, 0, -1);
411 9 : (*vote)->client_versions = tor_strdup("0.1.2.14,0.1.2.17");
412 9 : (*vote)->server_versions = tor_strdup("0.1.2.10,0.1.2.15,0.1.2.16");
413 9 : smartlist_split_string((*vote)->known_flags,
414 : "Authority Exit Fast Guard Running Stable V2Dir Valid",
415 : 0, SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
416 9 : voter = tor_malloc_zero(sizeof(networkstatus_voter_info_t));
417 9 : voter->nickname = tor_strdup("Voter2");
418 9 : voter->address = tor_strdup("3.4.5.6");
419 9 : tor_addr_from_ipv4h(&voter->ipv4_addr, 0x03040506);
420 9 : voter->ipv4_dirport = 80;
421 9 : voter->ipv4_orport = 9000;
422 9 : voter->contact = tor_strdup("voter@example.com");
423 9 : crypto_pk_get_digest(cert->identity_key, voter->identity_digest);
424 9 : memset(voter->legacy_id_digest, (int)'A', DIGEST_LEN);
425 : /*
426 : * Set up a vote; generate it; try to parse it.
427 : */
428 9 : smartlist_add((*vote)->voters, voter);
429 9 : (*vote)->cert = authority_cert_dup(cert);
430 9 : smartlist_split_string((*vote)->net_params, "circuitwindow=80 foo=660",
431 : NULL, 0, 0);
432 : /* add routerstatuses */
433 : /* dump the vote and try to parse it. */
434 9 : dir_common_add_rs_and_parse(*vote, vote_out, vrs_gen, sign_skey,
435 : n_vrs, now, clear_rl);
436 :
437 9 : return 0;
438 : }
|