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 */
7 #define DIRVOTE_PRIVATE
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"
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"
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
);
32 /** Initialize and set auth certs and keys
33 * Returns 0 on success, -1 on failure. Clean up handled by caller.
36 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
)
43 /* Parse certificates and keys. */
44 authority_cert_t
*cert
;
45 cert
= authority_cert_parse_from_string(AUTHORITY_CERT_1
,
46 strlen(AUTHORITY_CERT_1
),
49 tt_assert(cert
->identity_key
);
52 *cert2
= authority_cert_parse_from_string(AUTHORITY_CERT_2
,
53 strlen(AUTHORITY_CERT_2
),
56 *cert3
= authority_cert_parse_from_string(AUTHORITY_CERT_3
,
57 strlen(AUTHORITY_CERT_3
),
60 *sign_skey_1
= crypto_pk_new();
61 *sign_skey_2
= crypto_pk_new();
62 *sign_skey_3
= crypto_pk_new();
64 tt_assert(!crypto_pk_read_private_key_from_string(*sign_skey_1
,
65 AUTHORITY_SIGNKEY_1
, -1));
66 tt_assert(!crypto_pk_read_private_key_from_string(*sign_skey_2
,
67 AUTHORITY_SIGNKEY_2
, -1));
68 tt_assert(!crypto_pk_read_private_key_from_string(*sign_skey_3
,
69 AUTHORITY_SIGNKEY_3
, -1));
71 tt_assert(!crypto_pk_cmp_keys(*sign_skey_1
, (*cert1
)->signing_key
));
72 tt_assert(!crypto_pk_cmp_keys(*sign_skey_2
, (*cert2
)->signing_key
));
80 * Generate a routerstatus for v3_networkstatus test.
83 dir_common_gen_routerstatus_for_v3ns(int idx
, time_t now
)
85 vote_routerstatus_t
*vrs
=NULL
;
86 routerstatus_t
*rs
= NULL
;
88 char *method_list
= NULL
;
92 /* Generate the first routerstatus. */
93 vrs
= tor_malloc_zero(sizeof(vote_routerstatus_t
));
95 vrs
->version
= tor_strdup("0.1.2.14");
96 vrs
->published_on
= now
-1500;
97 strlcpy(rs
->nickname
, "router2", sizeof(rs
->nickname
));
98 memset(rs
->identity_digest
, TEST_DIR_ROUTER_ID_1
, DIGEST_LEN
);
99 memset(rs
->descriptor_digest
, TEST_DIR_ROUTER_DD_1
, DIGEST_LEN
);
100 tor_addr_from_ipv4h(&rs
->ipv4_addr
, 0x99008801);
101 rs
->ipv4_orport
= 443;
102 rs
->ipv4_dirport
= 8000;
103 /* all flags but running and v2dir cleared */
104 rs
->is_flagged_running
= 1;
106 rs
->is_valid
= 1; /* xxxxx */
107 vrs
->protocols
= tor_strdup("Link=7 HSDir=3");
110 /* Generate the second routerstatus. */
111 vrs
= tor_malloc_zero(sizeof(vote_routerstatus_t
));
113 vrs
->version
= tor_strdup("0.2.0.5");
114 vrs
->published_on
= now
-1000;
115 strlcpy(rs
->nickname
, "router1", sizeof(rs
->nickname
));
116 memset(rs
->identity_digest
, TEST_DIR_ROUTER_ID_2
, DIGEST_LEN
);
117 memset(rs
->descriptor_digest
, TEST_DIR_ROUTER_DD_2
, DIGEST_LEN
);
118 tor_addr_from_ipv4h(&rs
->ipv4_addr
, 0x99009901);
119 rs
->ipv4_orport
= 443;
120 rs
->ipv4_dirport
= 0;
121 tor_addr_parse(&addr_ipv6
, "[1:2:3::4]");
122 tor_addr_copy(&rs
->ipv6_addr
, &addr_ipv6
);
123 rs
->ipv6_orport
= 4711;
124 rs
->is_exit
= rs
->is_stable
= rs
->is_fast
= rs
->is_flagged_running
=
125 rs
->is_valid
= rs
->is_possible_guard
= rs
->is_v2_dir
= 1;
126 vrs
->protocols
= tor_strdup("Link=3,4 HSDir=2,3");
129 /* Generate the third routerstatus. */
130 vrs
= tor_malloc_zero(sizeof(vote_routerstatus_t
));
132 vrs
->version
= tor_strdup("0.1.0.3");
133 vrs
->published_on
= now
-1000;
134 strlcpy(rs
->nickname
, "router3", sizeof(rs
->nickname
));
135 memset(rs
->identity_digest
, TEST_DIR_ROUTER_ID_3
, DIGEST_LEN
);
136 memset(rs
->descriptor_digest
, TEST_DIR_ROUTER_DD_3
, DIGEST_LEN
);
137 tor_addr_from_ipv4h(&rs
->ipv4_addr
, 0xAA009901);
138 rs
->ipv4_orport
= 400;
139 rs
->ipv4_dirport
= 9999;
140 rs
->is_authority
= rs
->is_exit
= rs
->is_stable
= rs
->is_fast
=
141 rs
->is_flagged_running
= rs
->is_valid
= rs
->is_v2_dir
=
142 rs
->is_possible_guard
= 1;
143 vrs
->protocols
= tor_strdup("Link=3,4 HSDir=2,3");
146 /* Generate a fourth routerstatus that is not running. */
147 vrs
= tor_malloc_zero(sizeof(vote_routerstatus_t
));
149 vrs
->version
= tor_strdup("0.1.6.3");
150 vrs
->published_on
= now
-1000;
151 strlcpy(rs
->nickname
, "router4", sizeof(rs
->nickname
));
152 memset(rs
->identity_digest
, TEST_DIR_ROUTER_ID_4
, DIGEST_LEN
);
153 memset(rs
->descriptor_digest
, TEST_DIR_ROUTER_DD_4
, DIGEST_LEN
);
154 tor_addr_from_ipv4h(&rs
->ipv4_addr
, 0xC0000203);
155 rs
->ipv4_orport
= 500;
156 rs
->ipv4_dirport
= 1999;
158 vrs
->protocols
= tor_strdup("Link=3,4 HSDir=3");
159 /* Running flag (and others) cleared */
162 /* No more for this test; return NULL */
166 /* Shouldn't happen */
170 vrs
->microdesc
= tor_malloc_zero(sizeof(vote_microdesc_hash_t
));
171 method_list
= make_consensus_method_list(MIN_SUPPORTED_CONSENSUS_METHOD
,
172 MAX_SUPPORTED_CONSENSUS_METHOD
,
174 tor_asprintf(&vrs
->microdesc
->microdesc_hash_line
,
176 "sha256=xyzajkldsdsajdadlsdjaslsdksdjlsdjsdaskdaaa%d\n",
181 tor_free(method_list
);
185 /** Initialize networkstatus vote object attributes. */
187 dir_common_setup_vote(networkstatus_t
**vote
, time_t now
)
189 *vote
= tor_malloc_zero(sizeof(networkstatus_t
));
190 (*vote
)->type
= NS_TYPE_VOTE
;
191 (*vote
)->published
= now
;
192 (*vote
)->supported_methods
= smartlist_new();
193 (*vote
)->known_flags
= smartlist_new();
194 (*vote
)->net_params
= smartlist_new();
195 (*vote
)->routerstatus_list
= smartlist_new();
196 (*vote
)->voters
= smartlist_new();
199 /** Helper: Make a new routerinfo containing the right information for a
200 * given vote_routerstatus_t. */
202 dir_common_generate_ri_from_rs(const vote_routerstatus_t
*vrs
)
205 const routerstatus_t
*rs
= &vrs
->status
;
206 static time_t published
= 0;
208 r
= tor_malloc_zero(sizeof(routerinfo_t
));
209 r
->cert_expiration_time
= TIME_MAX
;
210 memcpy(r
->cache_info
.identity_digest
, rs
->identity_digest
, DIGEST_LEN
);
211 memcpy(r
->cache_info
.signed_descriptor_digest
, rs
->descriptor_digest
,
213 r
->cache_info
.do_not_cache
= 1;
214 r
->cache_info
.routerlist_index
= -1;
215 r
->cache_info
.signed_descriptor_body
=
216 tor_strdup("123456789012345678901234567890123");
217 r
->cache_info
.signed_descriptor_len
=
218 strlen(r
->cache_info
.signed_descriptor_body
);
219 r
->exit_policy
= smartlist_new();
220 r
->cache_info
.published_on
= ++published
+ time(NULL
);
221 if (rs
->has_bandwidth
) {
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.
229 r
->bandwidthrate
= rs
->bandwidth_kb
* 1000;
230 r
->bandwidthcapacity
= rs
->bandwidth_kb
* 1000;
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
241 * Return the signed vote, same as *vote_out*. Save the number of routers added
245 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
,
250 vote_routerstatus_t
*vrs
;
252 const char *msg
=NULL
;
254 was_router_added_t router_added
= -1;
259 routerlist_free_all();
264 vrs
= vrs_gen(idx
, now
);
266 smartlist_add(vote
->routerstatus_list
, vrs
);
268 router_add_to_routerlist(dir_common_generate_ri_from_rs(vrs
),
270 tt_assert(router_added
>= 0);
276 /* dump the vote and try to parse it. */
277 v_text
= format_networkstatus_vote(sign_skey
, vote
);
279 *vote_out
= networkstatus_parse_vote_from_string(v_text
,
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.
297 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
)
303 networkstatus_voter_info_t
*voter
;
305 dir_common_setup_vote(vote
, now
);
306 (*vote
)->valid_after
= now
+1000;
307 (*vote
)->fresh_until
= now
+2000;
308 (*vote
)->valid_until
= now
+3000;
309 (*vote
)->vote_seconds
= 100;
310 (*vote
)->dist_seconds
= 200;
311 smartlist_split_string((*vote
)->supported_methods
, "1 2 3", NULL
, 0, -1);
312 (*vote
)->client_versions
= tor_strdup("0.1.2.14,0.1.2.15");
313 (*vote
)->server_versions
= tor_strdup("0.1.2.14,0.1.2.15,0.1.2.16");
314 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 voter
= tor_malloc_zero(sizeof(networkstatus_voter_info_t
));
318 voter
->nickname
= tor_strdup("Voter1");
319 voter
->address
= tor_strdup("1.2.3.4");
320 tor_addr_from_ipv4h(&voter
->ipv4_addr
, 0x01020304);
321 voter
->ipv4_dirport
= 80;
322 voter
->ipv4_orport
= 9000;
323 voter
->contact
= tor_strdup("voter@example.com");
324 crypto_pk_get_digest(cert
->identity_key
, voter
->identity_digest
);
326 * Set up a vote; generate it; try to parse it.
328 smartlist_add((*vote
)->voters
, voter
);
329 (*vote
)->cert
= authority_cert_dup(cert
);
330 smartlist_split_string((*vote
)->net_params
, "circuitwindow=101 foo=990",
333 /* add routerstatuses */
334 if (!dir_common_add_rs_and_parse(*vote
, vote_out
, vrs_gen
, sign_skey
,
335 n_vrs
, now
, clear_rl
))
341 /** See dir_common_construct_vote_1.
342 * Produces a vote with slightly different values.
345 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
)
351 networkstatus_voter_info_t
*voter
;
353 dir_common_setup_vote(vote
, now
);
354 (*vote
)->type
= NS_TYPE_VOTE
;
355 (*vote
)->published
+= 1;
356 (*vote
)->valid_after
= now
+1000;
357 (*vote
)->fresh_until
= now
+3005;
358 (*vote
)->valid_until
= now
+3000;
359 (*vote
)->vote_seconds
= 100;
360 (*vote
)->dist_seconds
= 300;
361 smartlist_split_string((*vote
)->supported_methods
, "1 2 3", NULL
, 0, -1);
362 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 voter
= tor_malloc_zero(sizeof(networkstatus_voter_info_t
));
367 voter
->nickname
= tor_strdup("Voter2");
368 voter
->address
= tor_strdup("2.3.4.5");
369 tor_addr_from_ipv4h(&voter
->ipv4_addr
, 0x02030405);
370 voter
->ipv4_dirport
= 80;
371 voter
->ipv4_orport
= 9000;
372 voter
->contact
= tor_strdup("voter@example.com");
373 crypto_pk_get_digest(cert
->identity_key
, voter
->identity_digest
);
375 * Set up a vote; generate it; try to parse it.
377 smartlist_add((*vote
)->voters
, voter
);
378 (*vote
)->cert
= authority_cert_dup(cert
);
379 if (! (*vote
)->net_params
)
380 (*vote
)->net_params
= smartlist_new();
381 smartlist_split_string((*vote
)->net_params
,
382 "bar=2000000000 circuitwindow=20",
384 /* add routerstatuses */
385 /* dump the vote and try to parse it. */
386 dir_common_add_rs_and_parse(*vote
, vote_out
, vrs_gen
, sign_skey
,
387 n_vrs
, now
, clear_rl
);
392 /** See dir_common_construct_vote_1.
393 * Produces a vote with slightly different values. Adds a legacy key.
396 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
)
402 networkstatus_voter_info_t
*voter
;
404 dir_common_setup_vote(vote
, now
);
405 (*vote
)->valid_after
= now
+1000;
406 (*vote
)->fresh_until
= now
+2003;
407 (*vote
)->valid_until
= now
+3000;
408 (*vote
)->vote_seconds
= 100;
409 (*vote
)->dist_seconds
= 250;
410 smartlist_split_string((*vote
)->supported_methods
, "1 2 3 4", NULL
, 0, -1);
411 (*vote
)->client_versions
= tor_strdup("0.1.2.14,0.1.2.17");
412 (*vote
)->server_versions
= tor_strdup("0.1.2.10,0.1.2.15,0.1.2.16");
413 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 voter
= tor_malloc_zero(sizeof(networkstatus_voter_info_t
));
417 voter
->nickname
= tor_strdup("Voter2");
418 voter
->address
= tor_strdup("3.4.5.6");
419 tor_addr_from_ipv4h(&voter
->ipv4_addr
, 0x03040506);
420 voter
->ipv4_dirport
= 80;
421 voter
->ipv4_orport
= 9000;
422 voter
->contact
= tor_strdup("voter@example.com");
423 crypto_pk_get_digest(cert
->identity_key
, voter
->identity_digest
);
424 memset(voter
->legacy_id_digest
, (int)'A', DIGEST_LEN
);
426 * Set up a vote; generate it; try to parse it.
428 smartlist_add((*vote
)->voters
, voter
);
429 (*vote
)->cert
= authority_cert_dup(cert
);
430 smartlist_split_string((*vote
)->net_params
, "circuitwindow=80 foo=660",
432 /* add routerstatuses */
433 /* dump the vote and try to parse it. */
434 dir_common_add_rs_and_parse(*vote
, vote_out
, vrs_gen
, sign_skey
,
435 n_vrs
, now
, clear_rl
);