123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425 |
- /* Copyright (c) 2001-2004, Roger Dingledine.
- * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2018, The Tor Project, Inc. */
- /* See LICENSE for licensing information */
- #include "orconfig.h"
- #define DIRVOTE_PRIVATE
- #include "test/test.h"
- #include "core/or/or.h"
- #include "feature/dirauth/dirvote.h"
- #include "feature/nodelist/nodelist.h"
- #include "feature/nodelist/routerlist.h"
- #include "test/test_dir_common.h"
- #include "feature/dircommon/voting_schedule.h"
- #include "feature/nodelist/authority_cert_st.h"
- #include "feature/nodelist/networkstatus_st.h"
- #include "feature/nodelist/networkstatus_voter_info_st.h"
- #include "feature/nodelist/routerinfo_st.h"
- #include "feature/dirauth/vote_microdesc_hash_st.h"
- #include "feature/nodelist/vote_routerstatus_st.h"
- void dir_common_setup_vote(networkstatus_t **vote, time_t now);
- networkstatus_t * dir_common_add_rs_and_parse(networkstatus_t *vote,
- networkstatus_t **vote_out,
- vote_routerstatus_t * (*vrs_gen)(int idx, time_t now),
- crypto_pk_t *sign_skey, int *n_vrs,
- time_t now, int clear_rl);
- /** Initialize and set auth certs and keys
- * Returns 0 on success, -1 on failure. Clean up handled by caller.
- */
- int
- dir_common_authority_pk_init(authority_cert_t **cert1,
- authority_cert_t **cert2,
- authority_cert_t **cert3,
- crypto_pk_t **sign_skey_1,
- crypto_pk_t **sign_skey_2,
- crypto_pk_t **sign_skey_3)
- {
- /* Parse certificates and keys. */
- authority_cert_t *cert;
- cert = authority_cert_parse_from_string(AUTHORITY_CERT_1, NULL);
- tt_assert(cert);
- tt_assert(cert->identity_key);
- *cert1 = cert;
- tt_assert(*cert1);
- *cert2 = authority_cert_parse_from_string(AUTHORITY_CERT_2, NULL);
- tt_assert(*cert2);
- *cert3 = authority_cert_parse_from_string(AUTHORITY_CERT_3, NULL);
- tt_assert(*cert3);
- *sign_skey_1 = crypto_pk_new();
- *sign_skey_2 = crypto_pk_new();
- *sign_skey_3 = crypto_pk_new();
- tt_assert(!crypto_pk_read_private_key_from_string(*sign_skey_1,
- AUTHORITY_SIGNKEY_1, -1));
- tt_assert(!crypto_pk_read_private_key_from_string(*sign_skey_2,
- AUTHORITY_SIGNKEY_2, -1));
- tt_assert(!crypto_pk_read_private_key_from_string(*sign_skey_3,
- AUTHORITY_SIGNKEY_3, -1));
- tt_assert(!crypto_pk_cmp_keys(*sign_skey_1, (*cert1)->signing_key));
- tt_assert(!crypto_pk_cmp_keys(*sign_skey_2, (*cert2)->signing_key));
- return 0;
- done:
- return -1;
- }
- /**
- * Generate a routerstatus for v3_networkstatus test.
- */
- vote_routerstatus_t *
- dir_common_gen_routerstatus_for_v3ns(int idx, time_t now)
- {
- vote_routerstatus_t *vrs=NULL;
- routerstatus_t *rs = NULL;
- tor_addr_t addr_ipv6;
- char *method_list = NULL;
- switch (idx) {
- case 0:
- /* Generate the first routerstatus. */
- vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
- rs = &vrs->status;
- vrs->version = tor_strdup("0.1.2.14");
- rs->published_on = now-1500;
- strlcpy(rs->nickname, "router2", sizeof(rs->nickname));
- memset(rs->identity_digest, TEST_DIR_ROUTER_ID_1, DIGEST_LEN);
- memset(rs->descriptor_digest, TEST_DIR_ROUTER_DD_1, DIGEST_LEN);
- rs->addr = 0x99008801;
- rs->or_port = 443;
- rs->dir_port = 8000;
- /* all flags but running and v2dir cleared */
- rs->is_flagged_running = 1;
- rs->is_v2_dir = 1;
- rs->is_valid = 1; /* xxxxx */
- break;
- case 1:
- /* Generate the second routerstatus. */
- vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
- rs = &vrs->status;
- vrs->version = tor_strdup("0.2.0.5");
- rs->published_on = now-1000;
- strlcpy(rs->nickname, "router1", sizeof(rs->nickname));
- memset(rs->identity_digest, TEST_DIR_ROUTER_ID_2, DIGEST_LEN);
- memset(rs->descriptor_digest, TEST_DIR_ROUTER_DD_2, DIGEST_LEN);
- rs->addr = 0x99009901;
- rs->or_port = 443;
- rs->dir_port = 0;
- tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
- tor_addr_copy(&rs->ipv6_addr, &addr_ipv6);
- rs->ipv6_orport = 4711;
- rs->is_exit = rs->is_stable = rs->is_fast = rs->is_flagged_running =
- rs->is_valid = rs->is_possible_guard = rs->is_v2_dir = 1;
- break;
- case 2:
- /* Generate the third routerstatus. */
- vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
- rs = &vrs->status;
- vrs->version = tor_strdup("0.1.0.3");
- rs->published_on = now-1000;
- strlcpy(rs->nickname, "router3", sizeof(rs->nickname));
- memset(rs->identity_digest, TEST_DIR_ROUTER_ID_3, DIGEST_LEN);
- memset(rs->descriptor_digest, TEST_DIR_ROUTER_DD_3, DIGEST_LEN);
- rs->addr = 0xAA009901;
- rs->or_port = 400;
- rs->dir_port = 9999;
- rs->is_authority = rs->is_exit = rs->is_stable = rs->is_fast =
- rs->is_flagged_running = rs->is_valid = rs->is_v2_dir =
- rs->is_possible_guard = 1;
- break;
- case 3:
- /* Generate a fourth routerstatus that is not running. */
- vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
- rs = &vrs->status;
- vrs->version = tor_strdup("0.1.6.3");
- rs->published_on = now-1000;
- strlcpy(rs->nickname, "router4", sizeof(rs->nickname));
- memset(rs->identity_digest, TEST_DIR_ROUTER_ID_4, DIGEST_LEN);
- memset(rs->descriptor_digest, TEST_DIR_ROUTER_DD_4, DIGEST_LEN);
- rs->addr = 0xC0000203;
- rs->or_port = 500;
- rs->dir_port = 1999;
- rs->is_v2_dir = 1;
- /* Running flag (and others) cleared */
- break;
- case 4:
- /* No more for this test; return NULL */
- vrs = NULL;
- break;
- default:
- /* Shouldn't happen */
- tt_abort();
- }
- if (vrs) {
- vrs->microdesc = tor_malloc_zero(sizeof(vote_microdesc_hash_t));
- method_list = make_consensus_method_list(MIN_SUPPORTED_CONSENSUS_METHOD,
- MAX_SUPPORTED_CONSENSUS_METHOD,
- ",");
- tor_asprintf(&vrs->microdesc->microdesc_hash_line,
- "m %s "
- "sha256=xyzajkldsdsajdadlsdjaslsdksdjlsdjsdaskdaaa%d\n",
- method_list, idx);
- }
- done:
- tor_free(method_list);
- return vrs;
- }
- /** Initialize networkstatus vote object attributes. */
- void
- dir_common_setup_vote(networkstatus_t **vote, time_t now)
- {
- *vote = tor_malloc_zero(sizeof(networkstatus_t));
- (*vote)->type = NS_TYPE_VOTE;
- (*vote)->published = now;
- (*vote)->supported_methods = smartlist_new();
- (*vote)->known_flags = smartlist_new();
- (*vote)->net_params = smartlist_new();
- (*vote)->routerstatus_list = smartlist_new();
- (*vote)->voters = smartlist_new();
- }
- /** Helper: Make a new routerinfo containing the right information for a
- * given vote_routerstatus_t. */
- routerinfo_t *
- dir_common_generate_ri_from_rs(const vote_routerstatus_t *vrs)
- {
- routerinfo_t *r;
- const routerstatus_t *rs = &vrs->status;
- static time_t published = 0;
- r = tor_malloc_zero(sizeof(routerinfo_t));
- r->cert_expiration_time = TIME_MAX;
- memcpy(r->cache_info.identity_digest, rs->identity_digest, DIGEST_LEN);
- memcpy(r->cache_info.signed_descriptor_digest, rs->descriptor_digest,
- DIGEST_LEN);
- r->cache_info.do_not_cache = 1;
- r->cache_info.routerlist_index = -1;
- r->cache_info.signed_descriptor_body =
- tor_strdup("123456789012345678901234567890123");
- r->cache_info.signed_descriptor_len =
- strlen(r->cache_info.signed_descriptor_body);
- r->exit_policy = smartlist_new();
- r->cache_info.published_on = ++published + time(NULL);
- if (rs->has_bandwidth) {
- /*
- * Multiply by 1000 because the routerinfo_t and the routerstatus_t
- * seem to use different units (*sigh*) and because we seem stuck on
- * icky and perverse decimal kilobytes (*double sigh*) - see
- * router_get_advertised_bandwidth_capped() of routerlist.c and
- * routerstatus_format_entry() of dirserv.c.
- */
- r->bandwidthrate = rs->bandwidth_kb * 1000;
- r->bandwidthcapacity = rs->bandwidth_kb * 1000;
- }
- return r;
- }
- /** Create routerstatuses and signed vote.
- * Create routerstatuses using *vrs_gen* and add them to global routerlist.
- * Next, create signed vote using *sign_skey* and *vote*, which should have
- * predefined header fields.
- * Setting *clear_rl* clears the global routerlist before adding the new
- * routers.
- * Return the signed vote, same as *vote_out*. Save the number of routers added
- * in *n_vrs*.
- */
- networkstatus_t *
- dir_common_add_rs_and_parse(networkstatus_t *vote, networkstatus_t **vote_out,
- vote_routerstatus_t * (*vrs_gen)(int idx, time_t now),
- crypto_pk_t *sign_skey, int *n_vrs, time_t now,
- int clear_rl)
- {
- vote_routerstatus_t *vrs;
- char *v_text=NULL;
- const char *msg=NULL;
- int idx;
- was_router_added_t router_added = -1;
- *vote_out = NULL;
- if (clear_rl) {
- nodelist_free_all();
- routerlist_free_all();
- }
- idx = 0;
- do {
- vrs = vrs_gen(idx, now);
- if (vrs) {
- smartlist_add(vote->routerstatus_list, vrs);
- router_added =
- router_add_to_routerlist(dir_common_generate_ri_from_rs(vrs),
- &msg,0,0);
- tt_assert(router_added >= 0);
- ++idx;
- }
- } while (vrs);
- *n_vrs = idx;
- /* dump the vote and try to parse it. */
- v_text = format_networkstatus_vote(sign_skey, vote);
- tt_assert(v_text);
- *vote_out = networkstatus_parse_vote_from_string(v_text, NULL, NS_TYPE_VOTE);
- done:
- if (v_text)
- tor_free(v_text);
- return *vote_out;
- }
- /** Create a fake *vote* where *cert* describes the signer, *sign_skey*
- * is the signing key, and *vrs_gen* is the function we'll use to create the
- * routers on which we're voting.
- * We pass *vote_out*, *n_vrs*, and *clear_rl* directly to vrs_gen().
- * Return 0 on success, return -1 on failure.
- */
- int
- dir_common_construct_vote_1(networkstatus_t **vote, authority_cert_t *cert,
- crypto_pk_t *sign_skey,
- vote_routerstatus_t * (*vrs_gen)(int idx, time_t now),
- networkstatus_t **vote_out, int *n_vrs,
- time_t now, int clear_rl)
- {
- networkstatus_voter_info_t *voter;
- dir_common_setup_vote(vote, now);
- (*vote)->valid_after = now+1000;
- (*vote)->fresh_until = now+2000;
- (*vote)->valid_until = now+3000;
- (*vote)->vote_seconds = 100;
- (*vote)->dist_seconds = 200;
- smartlist_split_string((*vote)->supported_methods, "1 2 3", NULL, 0, -1);
- (*vote)->client_versions = tor_strdup("0.1.2.14,0.1.2.15");
- (*vote)->server_versions = tor_strdup("0.1.2.14,0.1.2.15,0.1.2.16");
- smartlist_split_string((*vote)->known_flags,
- "Authority Exit Fast Guard Running Stable V2Dir Valid",
- 0, SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
- voter = tor_malloc_zero(sizeof(networkstatus_voter_info_t));
- voter->nickname = tor_strdup("Voter1");
- voter->address = tor_strdup("1.2.3.4");
- voter->addr = 0x01020304;
- voter->dir_port = 80;
- voter->or_port = 9000;
- voter->contact = tor_strdup("voter@example.com");
- crypto_pk_get_digest(cert->identity_key, voter->identity_digest);
- /*
- * Set up a vote; generate it; try to parse it.
- */
- smartlist_add((*vote)->voters, voter);
- (*vote)->cert = authority_cert_dup(cert);
- smartlist_split_string((*vote)->net_params, "circuitwindow=101 foo=990",
- NULL, 0, 0);
- *n_vrs = 0;
- /* add routerstatuses */
- if (!dir_common_add_rs_and_parse(*vote, vote_out, vrs_gen, sign_skey,
- n_vrs, now, clear_rl))
- return -1;
- return 0;
- }
- /** See dir_common_construct_vote_1.
- * Produces a vote with slightly different values.
- */
- int
- dir_common_construct_vote_2(networkstatus_t **vote, authority_cert_t *cert,
- crypto_pk_t *sign_skey,
- vote_routerstatus_t * (*vrs_gen)(int idx, time_t now),
- networkstatus_t **vote_out, int *n_vrs,
- time_t now, int clear_rl)
- {
- networkstatus_voter_info_t *voter;
- dir_common_setup_vote(vote, now);
- (*vote)->type = NS_TYPE_VOTE;
- (*vote)->published += 1;
- (*vote)->valid_after = now+1000;
- (*vote)->fresh_until = now+3005;
- (*vote)->valid_until = now+3000;
- (*vote)->vote_seconds = 100;
- (*vote)->dist_seconds = 300;
- smartlist_split_string((*vote)->supported_methods, "1 2 3", NULL, 0, -1);
- smartlist_split_string((*vote)->known_flags,
- "Authority Exit Fast Guard MadeOfCheese MadeOfTin "
- "Running Stable V2Dir Valid", 0,
- SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
- voter = tor_malloc_zero(sizeof(networkstatus_voter_info_t));
- voter->nickname = tor_strdup("Voter2");
- voter->address = tor_strdup("2.3.4.5");
- voter->addr = 0x02030405;
- voter->dir_port = 80;
- voter->or_port = 9000;
- voter->contact = tor_strdup("voter@example.com");
- crypto_pk_get_digest(cert->identity_key, voter->identity_digest);
- /*
- * Set up a vote; generate it; try to parse it.
- */
- smartlist_add((*vote)->voters, voter);
- (*vote)->cert = authority_cert_dup(cert);
- if (! (*vote)->net_params)
- (*vote)->net_params = smartlist_new();
- smartlist_split_string((*vote)->net_params,
- "bar=2000000000 circuitwindow=20",
- NULL, 0, 0);
- /* add routerstatuses */
- /* dump the vote and try to parse it. */
- dir_common_add_rs_and_parse(*vote, vote_out, vrs_gen, sign_skey,
- n_vrs, now, clear_rl);
- return 0;
- }
- /** See dir_common_construct_vote_1.
- * Produces a vote with slightly different values. Adds a legacy key.
- */
- int
- dir_common_construct_vote_3(networkstatus_t **vote, authority_cert_t *cert,
- crypto_pk_t *sign_skey,
- vote_routerstatus_t * (*vrs_gen)(int idx, time_t now),
- networkstatus_t **vote_out, int *n_vrs,
- time_t now, int clear_rl)
- {
- networkstatus_voter_info_t *voter;
- dir_common_setup_vote(vote, now);
- (*vote)->valid_after = now+1000;
- (*vote)->fresh_until = now+2003;
- (*vote)->valid_until = now+3000;
- (*vote)->vote_seconds = 100;
- (*vote)->dist_seconds = 250;
- smartlist_split_string((*vote)->supported_methods, "1 2 3 4", NULL, 0, -1);
- (*vote)->client_versions = tor_strdup("0.1.2.14,0.1.2.17");
- (*vote)->server_versions = tor_strdup("0.1.2.10,0.1.2.15,0.1.2.16");
- smartlist_split_string((*vote)->known_flags,
- "Authority Exit Fast Guard Running Stable V2Dir Valid",
- 0, SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
- voter = tor_malloc_zero(sizeof(networkstatus_voter_info_t));
- voter->nickname = tor_strdup("Voter2");
- voter->address = tor_strdup("3.4.5.6");
- voter->addr = 0x03040506;
- voter->dir_port = 80;
- voter->or_port = 9000;
- voter->contact = tor_strdup("voter@example.com");
- crypto_pk_get_digest(cert->identity_key, voter->identity_digest);
- memset(voter->legacy_id_digest, (int)'A', DIGEST_LEN);
- /*
- * Set up a vote; generate it; try to parse it.
- */
- smartlist_add((*vote)->voters, voter);
- (*vote)->cert = authority_cert_dup(cert);
- smartlist_split_string((*vote)->net_params, "circuitwindow=80 foo=660",
- NULL, 0, 0);
- /* add routerstatuses */
- /* dump the vote and try to parse it. */
- dir_common_add_rs_and_parse(*vote, vote_out, vrs_gen, sign_skey,
- n_vrs, now, clear_rl);
- return 0;
- }
|