Loading src/or/dirvote.c +38 −27 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ const char dirvote_c_id[] = "$Id$"; #define DIRVOTE_PRIVATE #include "or.h" /** Loading Loading @@ -347,9 +348,6 @@ networkstatus_compute_consensus(smartlist_t *votes, smartlist_free(lst); } /* XXXX020 we list any flag that _any_ dirserver lists. possible * problem. */ smartlist_sort_strings(flags); smartlist_uniq_strings(flags); Loading Loading @@ -537,6 +535,7 @@ networkstatus_compute_consensus(smartlist_t *votes, memcpy(rs_out.identity_digest, lowest_id, DIGEST_LEN); memcpy(rs_out.descriptor_digest, rs->status.descriptor_digest, DIGEST_LEN); rs_out.addr = rs->status.addr; rs_out.published_on = rs->status.published_on; rs_out.dir_port = rs->status.dir_port; rs_out.or_port = rs->status.or_port; Loading Loading @@ -647,6 +646,37 @@ networkstatus_compute_consensus(smartlist_t *votes, return result; } /** DOCDOC */ /* private */ int networkstatus_check_voter_signature(networkstatus_vote_t *consensus, networkstatus_voter_info_t *voter, authority_cert_t *cert) { char d[DIGEST_LEN]; char *signed_digest; size_t signed_digest_len; /*XXXX020 check return*/ crypto_pk_get_digest(cert->signing_key, d); if (memcmp(voter->signing_key_digest, d, DIGEST_LEN)) { return -1; } signed_digest_len = crypto_pk_keysize(cert->signing_key); signed_digest = tor_malloc(signed_digest_len); if (crypto_pk_public_checksig(cert->signing_key, signed_digest, voter->pending_signature, voter->pending_signature_len) != DIGEST_LEN || memcmp(signed_digest, consensus->networkstatus_digest, DIGEST_LEN)) { log_warn(LD_DIR, "Got a bad signature."); /*XXXX020 say more*/ voter->bad_signature = 1; } else { voter->good_signature = 1; } tor_free(voter->pending_signature); return 0; } /** DOCDOC */ int networkstatus_check_consensus_signature(networkstatus_vote_t *consensus) Loading @@ -655,6 +685,7 @@ networkstatus_check_consensus_signature(networkstatus_vote_t *consensus) int n_missing_key = 0; int n_bad = 0; int n_unknown = 0; int n_no_signature = 0; tor_assert(! consensus->is_vote); Loading @@ -667,40 +698,20 @@ networkstatus_check_consensus_signature(networkstatus_vote_t *consensus) continue; } if (voter->pending_signature) { char d[DIGEST_LEN]; char *signed_digest; size_t signed_digest_len; tor_assert(!voter->good_signature && !voter->bad_signature); if (!ds->v3_cert) { ++n_missing_key; continue; } /*XXXX020 check return*/ crypto_pk_get_digest(ds->v3_cert->signing_key, d); if (memcmp(voter->signing_key_digest, d, DIGEST_LEN)) { if (!ds->v3_cert || networkstatus_check_voter_signature(consensus, voter, ds->v3_cert) < 0) { ++n_missing_key; continue; } signed_digest_len = crypto_pk_keysize(ds->v3_cert->signing_key); signed_digest = tor_malloc(signed_digest_len); if (crypto_pk_public_checksig(ds->v3_cert->signing_key, signed_digest, voter->pending_signature, voter->pending_signature_len) != DIGEST_LEN || memcmp(signed_digest, consensus->networkstatus_digest, DIGEST_LEN)) { log_warn(LD_DIR, "Got a bad signature."); /*XXXX020 say more*/ voter->bad_signature = 1; } else { voter->good_signature = 1; } tor_free(voter->pending_signature); } if (voter->good_signature) ++n_good; else if (voter->bad_signature) ++n_bad; else tor_assert(0); ++n_no_signature; }); /* XXXX020 actually use the result. */ Loading src/or/or.h +6 −0 Original line number Diff line number Diff line Loading @@ -2768,6 +2768,12 @@ int networkstatus_check_consensus_signature(networkstatus_vote_t *consensus); void authority_cert_free(authority_cert_t *cert); authority_cert_t *authority_cert_dup(authority_cert_t *cert); #ifdef DIRVOTE_PRIVATE int networkstatus_check_voter_signature(networkstatus_vote_t *consensus, networkstatus_voter_info_t *voter, authority_cert_t *cert); #endif /********************************* dns.c ***************************/ int dns_init(void); Loading src/or/test.c +68 −8 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ const char tor_svn_revision[] = ""; #define CONTROL_PRIVATE #define CRYPTO_PRIVATE #define DIRSERV_PRIVATE #define DIRVOTE_PRIVATE #define MEMPOOL_PRIVATE #define ROUTER_PRIVATE Loading Loading @@ -2296,7 +2297,7 @@ test_v3_networkstatus(void) "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3", DIGEST_LEN); test_memeq(rs->descriptor_digest, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN); test_eq(rs->addr, 0x099008801); test_eq(rs->addr, 0x99008801); test_eq(rs->or_port, 443); test_eq(rs->dir_port, 8000); test_eq(vrs->flags, U64_LITERAL(0)); Loading @@ -2310,7 +2311,7 @@ test_v3_networkstatus(void) "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5", DIGEST_LEN); test_memeq(rs->descriptor_digest, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN); test_eq(rs->addr, 0x099009901); test_eq(rs->addr, 0x99009901); test_eq(rs->or_port, 443); test_eq(rs->dir_port, 0); test_eq(vrs->flags, U64_LITERAL(254)); // all flags except "authority." Loading Loading @@ -2338,7 +2339,8 @@ test_v3_networkstatus(void) smartlist_del_keeporder(vote->routerstatus_list, 2); tor_free(vrs->version); tor_free(vrs); /* XXXX020 set some flags in router0 */ vrs = smartlist_get(vote->routerstatus_list, 0); vrs->status.is_fast = 1; /* generate and parse. */ v2_text = format_networkstatus_vote(sign_skey_2, vote); test_assert(v2_text); Loading Loading @@ -2372,7 +2374,9 @@ test_v3_networkstatus(void) smartlist_del_keeporder(vote->routerstatus_list, 0); tor_free(vrs->version); tor_free(vrs); /* XXXX020 clear some flags in the remaining entry. */ vrs = smartlist_get(vote->routerstatus_list, 0); memset(vrs->status.descriptor_digest, (int)'Z', DIGEST_LEN); v3_text = format_networkstatus_vote(sign_skey_3, vote); test_assert(v3_text); v3 = networkstatus_parse_vote_from_string(v3_text, 1); Loading @@ -2388,7 +2392,8 @@ test_v3_networkstatus(void) test_assert(consensus_text); con = networkstatus_parse_vote_from_string(consensus_text, 0); test_assert(con); // log_notice(LD_GENERAL, "<<%s>>", consensus_text); log_notice(LD_GENERAL, "<<%s>>\n<<%s>>\n<<%s>>\n", v1_text, v2_text, v3_text); /* Check consensus contents. */ test_assert(!con->is_vote); Loading Loading @@ -2419,9 +2424,64 @@ test_v3_networkstatus(void) test_assert(!con->cert); test_eq(2, smartlist_len(con->routerstatus_list)); /* XXXX020 test routerstatus_list contents */ /* XXXX020 Check signatures */ /* There should be two listed routers: one with identity 3, one with * identity 5. */ /* This one showed up in 2 digests. */ rs = smartlist_get(con->routerstatus_list, 0); test_memeq(rs->identity_digest, "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3", DIGEST_LEN); test_memeq(rs->descriptor_digest, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN); test_assert(!rs->is_authority); test_assert(!rs->is_exit); test_assert(!rs->is_fast); test_assert(!rs->is_possible_guard); test_assert(!rs->is_stable); test_assert(!rs->is_running); test_assert(!rs->is_v2_dir); test_assert(!rs->is_valid); test_assert(!rs->is_named); /* XXXX020 check version */ rs = smartlist_get(con->routerstatus_list, 1); /* This one showed up in 3 digests. Twice with ID 'M', once with 'Z'. */ test_memeq(rs->identity_digest, "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5", DIGEST_LEN); test_streq(rs->nickname, "router1"); test_memeq(rs->descriptor_digest, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN); test_eq(rs->published_on, now-1000); test_eq(rs->addr, 0x99009901); test_eq(rs->or_port, 443); test_eq(rs->dir_port, 0); test_assert(!rs->is_authority); test_assert(rs->is_exit); test_assert(rs->is_fast); test_assert(rs->is_possible_guard); test_assert(rs->is_stable); test_assert(rs->is_running); test_assert(rs->is_v2_dir); test_assert(rs->is_valid); test_assert(!rs->is_named); /* XXXX020 check version */ /* Check signatures. the first voter hasn't got one. The second one * does: validate it. */ voter = smartlist_get(con->voters, 0); test_assert(!voter->pending_signature); test_assert(!voter->good_signature); test_assert(!voter->bad_signature); voter = smartlist_get(con->voters, 1); test_assert(voter->pending_signature); test_assert(!voter->good_signature); test_assert(!voter->bad_signature); test_assert(!networkstatus_check_voter_signature(con, smartlist_get(con->voters, 1), cert3)); test_assert(!voter->pending_signature); test_assert(voter->good_signature); test_assert(!voter->bad_signature); /* XXXX020 frob with detached signatures */ Loading Loading
src/or/dirvote.c +38 −27 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ const char dirvote_c_id[] = "$Id$"; #define DIRVOTE_PRIVATE #include "or.h" /** Loading Loading @@ -347,9 +348,6 @@ networkstatus_compute_consensus(smartlist_t *votes, smartlist_free(lst); } /* XXXX020 we list any flag that _any_ dirserver lists. possible * problem. */ smartlist_sort_strings(flags); smartlist_uniq_strings(flags); Loading Loading @@ -537,6 +535,7 @@ networkstatus_compute_consensus(smartlist_t *votes, memcpy(rs_out.identity_digest, lowest_id, DIGEST_LEN); memcpy(rs_out.descriptor_digest, rs->status.descriptor_digest, DIGEST_LEN); rs_out.addr = rs->status.addr; rs_out.published_on = rs->status.published_on; rs_out.dir_port = rs->status.dir_port; rs_out.or_port = rs->status.or_port; Loading Loading @@ -647,6 +646,37 @@ networkstatus_compute_consensus(smartlist_t *votes, return result; } /** DOCDOC */ /* private */ int networkstatus_check_voter_signature(networkstatus_vote_t *consensus, networkstatus_voter_info_t *voter, authority_cert_t *cert) { char d[DIGEST_LEN]; char *signed_digest; size_t signed_digest_len; /*XXXX020 check return*/ crypto_pk_get_digest(cert->signing_key, d); if (memcmp(voter->signing_key_digest, d, DIGEST_LEN)) { return -1; } signed_digest_len = crypto_pk_keysize(cert->signing_key); signed_digest = tor_malloc(signed_digest_len); if (crypto_pk_public_checksig(cert->signing_key, signed_digest, voter->pending_signature, voter->pending_signature_len) != DIGEST_LEN || memcmp(signed_digest, consensus->networkstatus_digest, DIGEST_LEN)) { log_warn(LD_DIR, "Got a bad signature."); /*XXXX020 say more*/ voter->bad_signature = 1; } else { voter->good_signature = 1; } tor_free(voter->pending_signature); return 0; } /** DOCDOC */ int networkstatus_check_consensus_signature(networkstatus_vote_t *consensus) Loading @@ -655,6 +685,7 @@ networkstatus_check_consensus_signature(networkstatus_vote_t *consensus) int n_missing_key = 0; int n_bad = 0; int n_unknown = 0; int n_no_signature = 0; tor_assert(! consensus->is_vote); Loading @@ -667,40 +698,20 @@ networkstatus_check_consensus_signature(networkstatus_vote_t *consensus) continue; } if (voter->pending_signature) { char d[DIGEST_LEN]; char *signed_digest; size_t signed_digest_len; tor_assert(!voter->good_signature && !voter->bad_signature); if (!ds->v3_cert) { ++n_missing_key; continue; } /*XXXX020 check return*/ crypto_pk_get_digest(ds->v3_cert->signing_key, d); if (memcmp(voter->signing_key_digest, d, DIGEST_LEN)) { if (!ds->v3_cert || networkstatus_check_voter_signature(consensus, voter, ds->v3_cert) < 0) { ++n_missing_key; continue; } signed_digest_len = crypto_pk_keysize(ds->v3_cert->signing_key); signed_digest = tor_malloc(signed_digest_len); if (crypto_pk_public_checksig(ds->v3_cert->signing_key, signed_digest, voter->pending_signature, voter->pending_signature_len) != DIGEST_LEN || memcmp(signed_digest, consensus->networkstatus_digest, DIGEST_LEN)) { log_warn(LD_DIR, "Got a bad signature."); /*XXXX020 say more*/ voter->bad_signature = 1; } else { voter->good_signature = 1; } tor_free(voter->pending_signature); } if (voter->good_signature) ++n_good; else if (voter->bad_signature) ++n_bad; else tor_assert(0); ++n_no_signature; }); /* XXXX020 actually use the result. */ Loading
src/or/or.h +6 −0 Original line number Diff line number Diff line Loading @@ -2768,6 +2768,12 @@ int networkstatus_check_consensus_signature(networkstatus_vote_t *consensus); void authority_cert_free(authority_cert_t *cert); authority_cert_t *authority_cert_dup(authority_cert_t *cert); #ifdef DIRVOTE_PRIVATE int networkstatus_check_voter_signature(networkstatus_vote_t *consensus, networkstatus_voter_info_t *voter, authority_cert_t *cert); #endif /********************************* dns.c ***************************/ int dns_init(void); Loading
src/or/test.c +68 −8 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ const char tor_svn_revision[] = ""; #define CONTROL_PRIVATE #define CRYPTO_PRIVATE #define DIRSERV_PRIVATE #define DIRVOTE_PRIVATE #define MEMPOOL_PRIVATE #define ROUTER_PRIVATE Loading Loading @@ -2296,7 +2297,7 @@ test_v3_networkstatus(void) "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3", DIGEST_LEN); test_memeq(rs->descriptor_digest, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN); test_eq(rs->addr, 0x099008801); test_eq(rs->addr, 0x99008801); test_eq(rs->or_port, 443); test_eq(rs->dir_port, 8000); test_eq(vrs->flags, U64_LITERAL(0)); Loading @@ -2310,7 +2311,7 @@ test_v3_networkstatus(void) "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5", DIGEST_LEN); test_memeq(rs->descriptor_digest, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN); test_eq(rs->addr, 0x099009901); test_eq(rs->addr, 0x99009901); test_eq(rs->or_port, 443); test_eq(rs->dir_port, 0); test_eq(vrs->flags, U64_LITERAL(254)); // all flags except "authority." Loading Loading @@ -2338,7 +2339,8 @@ test_v3_networkstatus(void) smartlist_del_keeporder(vote->routerstatus_list, 2); tor_free(vrs->version); tor_free(vrs); /* XXXX020 set some flags in router0 */ vrs = smartlist_get(vote->routerstatus_list, 0); vrs->status.is_fast = 1; /* generate and parse. */ v2_text = format_networkstatus_vote(sign_skey_2, vote); test_assert(v2_text); Loading Loading @@ -2372,7 +2374,9 @@ test_v3_networkstatus(void) smartlist_del_keeporder(vote->routerstatus_list, 0); tor_free(vrs->version); tor_free(vrs); /* XXXX020 clear some flags in the remaining entry. */ vrs = smartlist_get(vote->routerstatus_list, 0); memset(vrs->status.descriptor_digest, (int)'Z', DIGEST_LEN); v3_text = format_networkstatus_vote(sign_skey_3, vote); test_assert(v3_text); v3 = networkstatus_parse_vote_from_string(v3_text, 1); Loading @@ -2388,7 +2392,8 @@ test_v3_networkstatus(void) test_assert(consensus_text); con = networkstatus_parse_vote_from_string(consensus_text, 0); test_assert(con); // log_notice(LD_GENERAL, "<<%s>>", consensus_text); log_notice(LD_GENERAL, "<<%s>>\n<<%s>>\n<<%s>>\n", v1_text, v2_text, v3_text); /* Check consensus contents. */ test_assert(!con->is_vote); Loading Loading @@ -2419,9 +2424,64 @@ test_v3_networkstatus(void) test_assert(!con->cert); test_eq(2, smartlist_len(con->routerstatus_list)); /* XXXX020 test routerstatus_list contents */ /* XXXX020 Check signatures */ /* There should be two listed routers: one with identity 3, one with * identity 5. */ /* This one showed up in 2 digests. */ rs = smartlist_get(con->routerstatus_list, 0); test_memeq(rs->identity_digest, "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3", DIGEST_LEN); test_memeq(rs->descriptor_digest, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN); test_assert(!rs->is_authority); test_assert(!rs->is_exit); test_assert(!rs->is_fast); test_assert(!rs->is_possible_guard); test_assert(!rs->is_stable); test_assert(!rs->is_running); test_assert(!rs->is_v2_dir); test_assert(!rs->is_valid); test_assert(!rs->is_named); /* XXXX020 check version */ rs = smartlist_get(con->routerstatus_list, 1); /* This one showed up in 3 digests. Twice with ID 'M', once with 'Z'. */ test_memeq(rs->identity_digest, "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5", DIGEST_LEN); test_streq(rs->nickname, "router1"); test_memeq(rs->descriptor_digest, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN); test_eq(rs->published_on, now-1000); test_eq(rs->addr, 0x99009901); test_eq(rs->or_port, 443); test_eq(rs->dir_port, 0); test_assert(!rs->is_authority); test_assert(rs->is_exit); test_assert(rs->is_fast); test_assert(rs->is_possible_guard); test_assert(rs->is_stable); test_assert(rs->is_running); test_assert(rs->is_v2_dir); test_assert(rs->is_valid); test_assert(!rs->is_named); /* XXXX020 check version */ /* Check signatures. the first voter hasn't got one. The second one * does: validate it. */ voter = smartlist_get(con->voters, 0); test_assert(!voter->pending_signature); test_assert(!voter->good_signature); test_assert(!voter->bad_signature); voter = smartlist_get(con->voters, 1); test_assert(voter->pending_signature); test_assert(!voter->good_signature); test_assert(!voter->bad_signature); test_assert(!networkstatus_check_voter_signature(con, smartlist_get(con->voters, 1), cert3)); test_assert(!voter->pending_signature); test_assert(voter->good_signature); test_assert(!voter->bad_signature); /* XXXX020 frob with detached signatures */ Loading