diff options
author | Nick Mathewson <nickm@torproject.org> | 2007-06-04 22:29:00 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2007-06-04 22:29:00 +0000 |
commit | 8b0e6a446697ad3d15a1fe23a8c5c3ed53a60c70 (patch) | |
tree | d2dcdf0c97e3db1bf4852bcb0b96102c6a120bae /src/or | |
parent | 8d1224eb51bf0f9fd0c829aa7fb22e359513b71b (diff) | |
download | tor-8b0e6a446697ad3d15a1fe23a8c5c3ed53a60c70.tar.gz tor-8b0e6a446697ad3d15a1fe23a8c5c3ed53a60c70.zip |
r13250@catbus: nickm | 2007-06-04 18:28:55 -0400
Adapt code to parse v3 networkstatus votes so it can also parse a consensus. Make networkstatus_vote_t the catch-all type for votes and conensuses. Correct/clarify the second argument to directory-signature.
svn:r10491
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/dirserv.c | 16 | ||||
-rw-r--r-- | src/or/dirvote.c | 68 | ||||
-rw-r--r-- | src/or/or.h | 45 | ||||
-rw-r--r-- | src/or/routerparse.c | 279 |
4 files changed, 270 insertions, 138 deletions
diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 616c8e4d41..6852984c43 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -1897,19 +1897,19 @@ generate_networkstatus_opinion(int v2) } outp += strlen(outp); } else { - char hex_digest[HEX_DIGEST_LEN+1]; - if (tor_snprintf(outp, endp-outp, "directory-signature %s ", - fingerprint)<0) { + char signing_key_fingerprint[FINGERPRINT_LEN+1]; + if (tor_snprintf(outp, endp-outp, "directory-signature ")<0) { log_warn(LD_BUG, "Unable to start signature line."); goto done; } - if (router_get_networkstatus_v3_hash(status, digest)<0) { - log_warn(LD_BUG, "Unable to hash network status vote"); + outp += strlen(outp); + + if (crypto_pk_get_fingerprint(private_key, signing_key_fingerprint, 0)<0) { + log_warn(LD_BUG, "Unable to get fingerprint for signing key"); goto done; } - base16_encode(hex_digest, sizeof(hex_digest), digest, DIGEST_LEN); - outp += strlen(outp); - if (tor_snprintf(outp, endp-outp, "%s\n", hex_digest)<0) { + if (tor_snprintf(outp, endp-outp, "%s %s\n", fingerprint, + signing_key_fingerprint)<0) { log_warn(LD_BUG, "Unable to end signature line."); goto done; } diff --git a/src/or/dirvote.c b/src/or/dirvote.c index f45ca1fce2..ea6e8b1f04 100644 --- a/src/or/dirvote.c +++ b/src/or/dirvote.c @@ -26,9 +26,15 @@ networkstatus_vote_free(networkstatus_vote_t *ns) tor_free(ns->known_flags[i]); tor_free(ns->known_flags); } - tor_free(ns->nickname); - tor_free(ns->address); - tor_free(ns->contact); + if (ns->voters) { + SMARTLIST_FOREACH(ns->voters, networkstatus_voter_info_t *, voter, + { + tor_free(voter->nickname); + tor_free(voter->address); + tor_free(voter->contact); + }); + smartlist_free(ns->voters); + } if (ns->cert) authority_cert_free(ns->cert); @@ -47,6 +53,19 @@ networkstatus_vote_free(networkstatus_vote_t *ns) } /** DOCDOC */ +networkstatus_voter_info_t * +networkstatus_get_voter_by_id(networkstatus_vote_t *vote, + const char *identity) +{ + if (!vote || !vote->voters) + return NULL; + SMARTLIST_FOREACH(vote->voters, networkstatus_voter_info_t *, voter, + if (!memcmp(voter->identity_digest, identity, DIGEST_LEN)) + return voter); + return NULL; +} + +/** DOCDOC */ static int _compare_times(const void **_a, const void **_b) { @@ -92,12 +111,23 @@ median_int(smartlist_t *ints) return *(time_t*)smartlist_get(ints, idx); } +static networkstatus_voter_info_t * +get_voter(const networkstatus_vote_t *vote) +{ + tor_assert(vote); + tor_assert(vote->is_vote); + tor_assert(vote->voters); + tor_assert(smartlist_len(vote->voters) == 1); + return smartlist_get(vote->voters, 0); +} + /** DOCDOC */ static int _compare_votes_by_authority_id(const void **_a, const void **_b) { const networkstatus_vote_t *a = *_a, *b = *_b; - return memcmp(a->identity_digest, b->identity_digest, DIGEST_LEN); + return memcmp(get_voter(a)->identity_digest, + get_voter(b)->identity_digest, DIGEST_LEN); } /** DOCDOC */ @@ -193,7 +223,8 @@ compute_routerstatus_consensus(smartlist_t *votes) ++cur_n; } else { if (cur_n > most_n || - (cur && cur_n == most_n && cur->status.published_on > most_published)) { + (cur && cur_n == most_n && + cur->status.published_on > most_published)) { most = cur; most_n = cur_n; most_published = cur->status.published_on; @@ -246,7 +277,6 @@ networkstatus_compute_consensus(smartlist_t *votes, } /* XXXX020 somebody needs to check vote authority. It could be this * function, it could be somebody else. */ - flags = smartlist_create(); /* Compute medians of time-related things, and figure out how many @@ -363,20 +393,23 @@ networkstatus_compute_consensus(smartlist_t *votes, char ip[INET_NTOA_BUF_LEN]; char fingerprint[HEX_DIGEST_LEN+1]; char votedigest[HEX_DIGEST_LEN+1]; + networkstatus_voter_info_t *voter = get_voter(v); - in.s_addr = htonl(v->addr); + in.s_addr = htonl(voter->addr); tor_inet_ntoa(&in, ip, sizeof(ip)); - base16_encode(fingerprint, sizeof(fingerprint), v->identity_digest, + base16_encode(fingerprint, sizeof(fingerprint), voter->identity_digest, + DIGEST_LEN); + base16_encode(votedigest, sizeof(votedigest), voter->vote_digest, DIGEST_LEN); - base16_encode(votedigest, sizeof(votedigest), v->vote_digest, DIGEST_LEN); tor_snprintf(buf, sizeof(buf), "dir-source %s %s %s %s %d %d\n" "contact %s\n" "vote-digest %s\n", - v->nickname, fingerprint, v->address, ip, v->dir_port, - v->or_port, - v->contact, + voter->nickname, fingerprint, voter->address, ip, + voter->dir_port, + voter->or_port, + voter->contact, votedigest); smartlist_add(chunks, tor_strdup(buf)); }); @@ -564,19 +597,21 @@ networkstatus_compute_consensus(smartlist_t *votes, { char digest[DIGEST_LEN]; char fingerprint[HEX_DIGEST_LEN+1]; - char hex_digest[HEX_DIGEST_LEN+1]; + char signing_key_fingerprint[HEX_DIGEST_LEN+1]; + char buf[4096]; smartlist_add(chunks, tor_strdup("directory-signature ")); /* Compute the hash of the chunks. */ hash_list_members(digest, chunks); - /* Get hex stuff as needed. */ - base16_encode(hex_digest, sizeof(hex_digest), digest, DIGEST_LEN); + /* Get the fingerprints */ crypto_pk_get_fingerprint(identity_key, fingerprint, 0); + crypto_pk_get_fingerprint(signing_key, signing_key_fingerprint, 0); /* add the junk that will go at the end of the line. */ - tor_snprintf(buf, sizeof(buf), "%s %s\n", hex_digest, fingerprint); + tor_snprintf(buf, sizeof(buf), "%s %s\n", fingerprint, + signing_key_fingerprint); /* And the signature. */ /* XXXX020 check return */ router_append_dirobj_signature(buf, sizeof(buf), digest, signing_key); @@ -593,3 +628,4 @@ networkstatus_compute_consensus(smartlist_t *votes, return result; } + diff --git a/src/or/or.h b/src/or/or.h index 71c829c177..cfb6fb7d21 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1300,9 +1300,28 @@ typedef struct vote_routerstatus_t { char *version; } vote_routerstatus_t; -/** DOCDOC */ +/* DOCDOC */ +typedef struct networkstatus_voter_info_t { + char *nickname; + char identity_digest[DIGEST_LEN]; + char *address; + uint32_t addr; + uint16_t dir_port; + uint16_t or_port; + char *contact; + char vote_digest[DIGEST_LEN]; /* consensus only. */ + char signing_key_digest[DIGEST_LEN]; /* This part is _not_ signed. */ + + char *pending_signature; + int pending_signature_len; + int bad_signature; +} networkstatus_voter_info_t; + +/*XXXX020 rename to networkstatus_t once it works. */ +/** DOCDOC is vote or consensus. */ typedef struct networkstatus_vote_t { - time_t published; + int is_vote; + time_t published; /* vote only. */ time_t valid_after; time_t fresh_until; time_t valid_until; @@ -1313,20 +1332,12 @@ typedef struct networkstatus_vote_t { char *server_versions; char **known_flags; /* NULL-terminated */ - char *nickname; - char identity_digest[DIGEST_LEN]; - char *address; - uint32_t addr; - uint16_t dir_port; - uint16_t or_port; - - struct authority_cert_t *cert; - - char *contact; + smartlist_t *voters; /* list of networkstatus_voter_info_t */ - char vote_digest[DIGEST_LEN]; + struct authority_cert_t *cert; /* vote only. */ - smartlist_t *routerstatus_list; + smartlist_t *routerstatus_list; /* holds vote_routerstatus_t if is_vote, + * otherwise just routerstatus_t. */ } networkstatus_vote_t; /** Contents of a directory of onion routers. */ @@ -2718,6 +2729,9 @@ void networkstatus_vote_free(networkstatus_vote_t *ns); char *networkstatus_compute_consensus(smartlist_t *votes, crypto_pk_env_t *identity_key, crypto_pk_env_t *signing_key); +networkstatus_voter_info_t *networkstatus_get_voter_by_id( + networkstatus_vote_t *vote, + const char *identity); /********************************* dns.c ***************************/ @@ -3383,7 +3397,8 @@ void assert_addr_policy_ok(addr_policy_t *t); void dump_distinct_digest_count(int severity); networkstatus_t *networkstatus_parse_from_string(const char *s); -networkstatus_vote_t *networkstatus_parse_vote_from_string(const char *s); +networkstatus_vote_t *networkstatus_parse_vote_from_string(const char *s, + int is_vote); void authority_cert_free(authority_cert_t *cert); authority_cert_t *authority_cert_parse_from_string(const char *s, diff --git a/src/or/routerparse.c b/src/or/routerparse.c index 93f2366faf..2eee814d2e 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -311,12 +311,7 @@ static token_rule_t networkstatus_vote_token_table[] = { END_OF_TABLE }; - -#if 0 -/* XXXX This stuff is commented out for now so we can avoid warnings about - * unused variables. */ - -static token_rule_t status_consensus_table[] = { +static token_rule_t networkstatus_consensus_token_table[] = { T1("network-status-version", K_NETWORK_STATUS_VERSION, GE(1), NO_OBJ ), T1("vote-status", K_VOTE_STATUS, GE(1), NO_OBJ ), @@ -325,26 +320,19 @@ static token_rule_t status_consensus_table[] = { T1("valid-until", K_VALID_UNTIL, CONCAT_ARGS, NO_OBJ ), T1("voting-delay", K_VOTING_DELAY, GE(2), NO_OBJ ), - CERTIFICATE_MEMBERS - T0N("opt", K_OPT, CONCAT_ARGS, OBJ_OK ), T1N("dir-source", K_DIR_SOURCE, GE(3), NO_OBJ ), - T1N("fingerprint", K_FINGERPRINT, CONCAT_ARGS, NO_OBJ ), T1N("contact", K_CONTACT, CONCAT_ARGS, NO_OBJ ), T1N("vote-digest", K_VOTE_DIGEST, GE(1), NO_OBJ ), -#if 0 - T1( "dir-options", K_DIR_OPTIONS, ARGS, NO_OBJ ), T1( "known-flags", K_KNOWN_FLAGS, CONCAT_ARGS, NO_OBJ ), -#endif T01("client-versions", K_CLIENT_VERSIONS, CONCAT_ARGS, NO_OBJ ), T01("server-versions", K_SERVER_VERSIONS, CONCAT_ARGS, NO_OBJ ), END_OF_TABLE }; -#endif static token_rule_t networkstatus_vote_footer_token_table[] = { T( "directory-signature", K_DIRECTORY_SIGNATURE, GE(2), NEED_OBJ ), @@ -1786,14 +1774,14 @@ networkstatus_parse_from_string(const char *s) /** DOCDOC */ networkstatus_vote_t * -networkstatus_parse_vote_from_string(const char *s) +networkstatus_parse_vote_from_string(const char *s, int is_vote) { smartlist_t *tokens = smartlist_create(); smartlist_t *rs_tokens = NULL, *footer_tokens = NULL; + networkstatus_voter_info_t *voter = NULL; networkstatus_vote_t *ns = NULL; - char ns_digest[DIGEST_LEN], declared_identity[DIGEST_LEN], - declared_digest[DIGEST_LEN]; - const char *cert, *end_of_cert = NULL, *end_of_header, *end_of_footer; + char ns_digest[DIGEST_LEN]; + const char *cert, *end_of_header, *end_of_footer; directory_token_t *tok; int ok; struct in_addr in; @@ -1806,31 +1794,46 @@ networkstatus_parse_vote_from_string(const char *s) end_of_header = find_start_of_next_routerstatus(s); if (tokenize_string(s, end_of_header, tokens, - networkstatus_vote_token_table)) { + is_vote ? networkstatus_vote_token_table : + networkstatus_consensus_token_table)) { log_warn(LD_DIR, "Error tokenizing network-status vote header."); goto err; } ns = tor_malloc_zero(sizeof(networkstatus_vote_t)); - if (!(cert = strstr(s, "\ndir-key-certificate-version"))) - goto err; - ++cert; - ns->cert = authority_cert_parse_from_string(cert, &end_of_cert); - if (!ns->cert || !end_of_cert || end_of_cert > end_of_header) - goto err; + + if (is_vote) { + const char *end_of_cert = NULL; + if (!(cert = strstr(s, "\ndir-key-certificate-version"))) + goto err; + ++cert; + ns->cert = authority_cert_parse_from_string(cert, &end_of_cert); + if (!ns->cert || !end_of_cert || end_of_cert > end_of_header) + goto err; + } tok = find_first_by_keyword(tokens, K_VOTE_STATUS); tor_assert(tok); tor_assert(tok->n_args); - if (strcmp(tok->args[0], "vote")) { - log_warn(LD_DIR, "Unrecognized vote status %s in network-status vote.", + if (!strcmp(tok->args[0], "vote")) { + ns->is_vote = 1; + } else if (!strcmp(tok->args[0], "consensus")) { + ns->is_vote = 0; + } else { + log_warn(LD_DIR, "Unrecognized vote status %s in network-status", escaped(tok->args[0])); goto err; } - - tok = find_first_by_keyword(tokens, K_PUBLISHED); - if (parse_iso_time(tok->args[0], &ns->published)) + if (!bool_eq(ns->is_vote, is_vote)) { + log_warn(LD_DIR, "Got the wrong kind of v3 networkstatus."); goto err; + } + + if (ns->is_vote) { + tok = find_first_by_keyword(tokens, K_PUBLISHED); + if (parse_iso_time(tok->args[0], &ns->published)) + goto err; + } tok = find_first_by_keyword(tokens, K_VALID_AFTER); if (parse_iso_time(tok->args[0], &ns->valid_after)) @@ -1870,55 +1873,105 @@ networkstatus_parse_vote_from_string(const char *s) ns->known_flags[tok->n_args] = NULL; tok->n_args = 0; /* suppress free of args members, but not of args itself. */ - tok = find_first_by_keyword(tokens, K_DIR_SOURCE); - tor_assert(tok); - tor_assert(tok->n_args >= 6); - ns->nickname = tor_strdup(tok->args[0]); - if (strlen(tok->args[1]) != HEX_DIGEST_LEN || - base16_decode(ns->identity_digest, sizeof(ns->identity_digest), - tok->args[1], HEX_DIGEST_LEN) < 0) { - log_warn(LD_DIR, "Error decoding identity digest %s in " - "network-status vote.", escaped(tok->args[1])); - goto err; + ns->voters = smartlist_create(); + + SMARTLIST_FOREACH(tokens, directory_token_t *, _tok, + { + tok = _tok; + if (tok->tp == K_DIR_SOURCE) { + tor_assert(tok->n_args >= 6); + + if (voter) + smartlist_add(ns->voters, voter); + voter = tor_malloc_zero(sizeof(networkstatus_voter_info_t)); + + voter->nickname = tor_strdup(tok->args[0]); + if (strlen(tok->args[1]) != HEX_DIGEST_LEN || + base16_decode(voter->identity_digest, sizeof(voter->identity_digest), + tok->args[1], HEX_DIGEST_LEN) < 0) { + log_warn(LD_DIR, "Error decoding identity digest %s in " + "network-status vote.", escaped(tok->args[1])); + goto err; + } + voter->address = tor_strdup(tok->args[2]); + if (!tor_inet_aton(tok->args[3], &in)) { + log_warn(LD_DIR, "Error decoding IP address %s in network-status.", + escaped(tok->args[3])); + goto err; + } + voter->dir_port = (uint64_t) + (int) tor_parse_long(tok->args[4], 10, 0, 65535, &ok, NULL); + if (!ok) + goto err; + voter->or_port = (uint64_t) + (int) tor_parse_long(tok->args[5], 10, 0, 65535, &ok, NULL); + if (!ok) + goto err; + } else if (tok->tp == K_CONTACT) { + if (!voter || voter->contact) { + log_warn(LD_DIR, "contact element is out of place."); + goto err; + } + voter->contact = tor_strdup(tok->args[0]); + } else if (tok->tp == K_VOTE_DIGEST) { + tor_assert(!is_vote); + tor_assert(tok->n_args >= 1); + if (!voter || ! tor_digest_is_zero(voter->vote_digest)) { + log_warn(LD_DIR, "vote-digest element is out of place."); + goto err; + } + if (strlen(tok->args[0]) != HEX_DIGEST_LEN || + base16_decode(voter->vote_digest, sizeof(voter->vote_digest), + tok->args[0], HEX_DIGEST_LEN) < 0) { + log_warn(LD_DIR, "Error decoding vote digest %s in " + "network-status consensus.", escaped(tok->args[1])); + goto err; + } + } + }); + if (voter) { + smartlist_add(ns->voters, voter); + voter = NULL; } - ns->address = tor_strdup(tok->args[2]); - if (!tor_inet_aton(tok->args[3], &in)) { - log_warn(LD_DIR, "Error decoding IP address %s in network-status vote.", - escaped(tok->args[3])); + if (smartlist_len(ns->voters) == 0) { + log_warn(LD_DIR, "Missing dir-source elements in a vote networkstatus."); goto err; - } - ns->dir_port = (uint64_t) - (int) tor_parse_long(tok->args[4], 10, 0, 65535, &ok, NULL); - if (!ok) + } else if (is_vote && smartlist_len(ns->voters) != 1) { + log_warn(LD_DIR, "Too many dir-source elements in a vote networkstatus."); goto err; - ns->or_port = (uint64_t) - (int) tor_parse_long(tok->args[5], 10, 0, 65535, &ok, NULL); - if (!ok) - goto err; - - tok = find_first_by_keyword(tokens, K_CONTACT); - if (tok) { - ns->contact = tor_strdup(tok->args[0]); } /* Parse routerstatus lines. */ rs_tokens = smartlist_create(); s = end_of_header; ns->routerstatus_list = smartlist_create(); + while (!strcmpstart(s, "r ")) { - vote_routerstatus_t *rs = tor_malloc_zero(sizeof(vote_routerstatus_t)); - if (routerstatus_parse_entry_from_string(&s, tokens, ns, rs)) - smartlist_add(ns->routerstatus_list, rs); - else { - tor_free(rs->version); - tor_free(rs); + if (is_vote) { + vote_routerstatus_t *rs = tor_malloc_zero(sizeof(vote_routerstatus_t)); + if (routerstatus_parse_entry_from_string(&s, tokens, ns, rs)) + smartlist_add(ns->routerstatus_list, rs); + else { + tor_free(rs->version); + tor_free(rs); + } + } else { + routerstatus_t *rs; + if ((rs =routerstatus_parse_entry_from_string(&s, tokens, NULL, NULL))) + smartlist_add(ns->routerstatus_list, rs); } } for (i = 1; i < smartlist_len(ns->routerstatus_list); ++i) { - vote_routerstatus_t *a = smartlist_get(ns->routerstatus_list, i-1); - vote_routerstatus_t *b = smartlist_get(ns->routerstatus_list, i); - if (memcmp(a->status.identity_digest, b->status.identity_digest, - DIGEST_LEN) >= 0) { + routerstatus_t *rs1, *rs2; + if (is_vote) { + vote_routerstatus_t *a = smartlist_get(ns->routerstatus_list, i-1); + vote_routerstatus_t *b = smartlist_get(ns->routerstatus_list, i); + rs1 = &a->status; rs2 = &b->status; + } else { + rs1 = smartlist_get(ns->routerstatus_list, i-1); + rs2 = smartlist_get(ns->routerstatus_list, i); + } + if (memcmp(rs1->identity_digest, rs2->identity_digest, DIGEST_LEN) >= 0) { log_warn(LD_DIR, "Vote networkstatus entries not sorted by identity " "digest"); goto err; @@ -1933,40 +1986,62 @@ networkstatus_parse_vote_from_string(const char *s) log_warn(LD_DIR, "Error tokenizing network-status vote footer."); goto err; } - if (!(tok = find_first_by_keyword(footer_tokens, K_DIRECTORY_SIGNATURE))) { - log_warn(LD_DIR, "No signature on network-status vote."); - goto err; - } - tor_assert(tok->n_args >= 2); - if (strlen(tok->args[0]) != HEX_DIGEST_LEN || - base16_decode(declared_identity, sizeof(ns->identity_digest), - tok->args[0], HEX_DIGEST_LEN) < 0) { - log_warn(LD_DIR, "Error decoding declared identity %s in " - "network-status vote.", escaped(tok->args[1])); - goto err; - } - if (strlen(tok->args[1]) != HEX_DIGEST_LEN || - base16_decode(declared_digest, sizeof(ns->identity_digest), - tok->args[1], HEX_DIGEST_LEN) < 0) { - log_warn(LD_DIR, "Error decoding declared digest %s in " - "network-status vote.", escaped(tok->args[1])); - goto err; - } - memcpy(ns->vote_digest, declared_digest, DIGEST_LEN); - if (memcmp(declared_identity, ns->cert->cache_info.identity_digest, - DIGEST_LEN)) { - log_warn(LD_DIR, "Digest mismatch between declared and actual on " - "network-status vote."); - goto err; - } - if (memcmp(declared_digest, ns_digest, DIGEST_LEN)) { - log_warn(LD_DIR, "Digest mismatch between declared and actual on " - "network-status vote."); - goto err; - } - if (check_signature_token(ns_digest, tok, ns->cert->signing_key, 0, - "network-status vote")) - goto err; + + SMARTLIST_FOREACH(footer_tokens, directory_token_t *, _tok, + { + char declared_identity[DIGEST_LEN]; + networkstatus_voter_info_t *v; + tok = _tok; + if (tok->tp != K_DIRECTORY_SIGNATURE) + continue; + tor_assert(tok->n_args >= 2); + + if (!tok->object_type || + strcmp(tok->object_type, "SIGNATURE") || + tok->object_size < 128 || tok->object_size > 512) { + log_warn(LD_DIR, "Bad object type or length on directory-signature"); + goto err; + } + + if (strlen(tok->args[0]) != HEX_DIGEST_LEN || + base16_decode(declared_identity, sizeof(declared_identity), + tok->args[0], HEX_DIGEST_LEN) < 0) { + log_warn(LD_DIR, "Error decoding declared identity %s in " + "network-status vote.", escaped(tok->args[0])); + goto err; + } + if (!(v = networkstatus_get_voter_by_id(ns, declared_identity))) { + log_warn(LD_DIR, "ID on signature on network-status vote does not match" + "any declared directory source."); + goto err; + } + if (strlen(tok->args[1]) != HEX_DIGEST_LEN || + base16_decode(v->signing_key_digest, sizeof(v->signing_key_digest), + tok->args[1], HEX_DIGEST_LEN) < 0) { + log_warn(LD_DIR, "Error decoding declared digest %s in " + "network-status vote.", escaped(tok->args[1])); + goto err; + } + + if (is_vote && + memcmp(declared_identity, ns->cert->cache_info.identity_digest, + DIGEST_LEN)) { + log_warn(LD_DIR, "Digest mismatch between declared and actual on " + "network-status vote."); + goto err; + /* XXXX020 also check cert against dir-source line. */ + } + + if (is_vote) { + if (check_signature_token(ns_digest, tok, ns->cert->signing_key, 0, + "network-status vote")) + goto err; + } else { + v->pending_signature = tor_memdup(tok->object_body, + tok->object_size); + v->pending_signature_len = tok->object_size; + } + }); /* XXXX020 check dates for plausibility. ??? */ @@ -1980,6 +2055,12 @@ networkstatus_parse_vote_from_string(const char *s) SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_free(t)); smartlist_free(tokens); } + if (voter) { + tor_free(voter->nickname); + tor_free(voter->address); + tor_free(voter->contact); + tor_free(voter); + } if (rs_tokens) { SMARTLIST_FOREACH(rs_tokens, directory_token_t *, t, token_free(t)); smartlist_free(rs_tokens); |