From 525383c46d1430abf680133e486fc532050d7123 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 29 Oct 2014 13:36:21 -0400 Subject: [PATCH] Checkpoint some work on voting on ed25519 identities * Include ed25519 identities in votes * Include "no ed25519 identity" in votes * Include some commented-out code about identity voting. (This will disappear.) * Include some functions for identity voting (These will disappear.) * Enforce uniqueness in ed25519 keys within a vote --- src/or/dirserv.c | 15 +++++++++++++++ src/or/dirvote.c | 32 ++++++++++++++++++++++++++++++++ src/or/dirvote.h | 3 +++ src/or/or.h | 3 +++ src/or/routerparse.c | 27 +++++++++++++++++++++++++++ 5 files changed, 80 insertions(+) diff --git a/src/or/dirserv.c b/src/or/dirserv.c index f26a6bb216..5b103bcf52 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -1993,6 +1993,16 @@ routerstatus_format_entry(const routerstatus_t *rs, const char *version, smartlist_add_asprintf(chunks, "p %s\n", summary); tor_free(summary); } + + if (format == NS_V3_VOTE && vrs) { + if (tor_mem_is_zero((char*)vrs->ed25519_id, ED25519_PUBKEY_LEN)) { + smartlist_add(chunks, tor_strdup("id ed25519 none\n")); + } else { + char ed_b64[BASE64_DIGEST256_LEN+1]; + digest256_to_base64(ed_b64, (const char*)vrs->ed25519_id); + smartlist_add_asprintf(chunks, "id ed25519 %s\n", ed_b64); + } + } } done: @@ -2815,6 +2825,11 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key, listbadexits, vote_on_hsdirs); + if (ri->signing_key_cert) { + memcpy(vrs->ed25519_id, ri->signing_key_cert->signing_key.pubkey, + ED25519_PUBKEY_LEN); + } + if (digestmap_get(omit_as_sybil, ri->cache_info.identity_digest)) clear_status_flags_on_sybil(rs); diff --git a/src/or/dirvote.c b/src/or/dirvote.c index 94b4e5136a..6c53b3c642 100644 --- a/src/or/dirvote.c +++ b/src/or/dirvote.c @@ -782,6 +782,28 @@ networkstatus_check_weights(int64_t Wgg, int64_t Wgd, int64_t Wmg, return berr; } +#if 0 +/** DOCDOC */ +static vote_identity_map_t * +networkstatus_compute_identity_mapping(const smartlist_t *votes) +{ + vote_identity_map_t *map = vote_identity_map_new(); + + SMARTLIST_FOREACH_BEGIN(votes, networkstatus_t *, vote) { + SMARTLIST_FOREACH_BEGIN(vote->routerstatus_list, + vote_routerstatus_t *, vrs) { + vote_identity_map_add(map, vrs->status.identity_digest, + vrs->has_ed25519_listing ? vrs->ed25519_id : NULL, + vote_sl_idx); + } SMARTLIST_FOREACH_END(vrs); + } SMARTLIST_FOREACH_END(vote); + + vote_identity_map_resolve(map); + + return map; +} +#endif + /** * This function computes the bandwidth weights for consensus method 10. * @@ -1139,6 +1161,9 @@ networkstatus_compute_consensus(smartlist_t *votes, char *params = NULL; char *packages = NULL; int added_weights = 0; +#if 0 + vote_identity_map_t *id_map = NULL; +#endif tor_assert(flavor == FLAV_NS || flavor == FLAV_MICRODESC); tor_assert(total_authorities >= smartlist_len(votes)); @@ -1494,6 +1519,10 @@ networkstatus_compute_consensus(smartlist_t *votes, } ); +#if 0 + id_map = networkstatus_compute_identity_mapping(votes); +#endif + /* Now go through all the votes */ flag_counts = tor_calloc(smartlist_len(flags), sizeof(int)); while (1) { @@ -1981,6 +2010,9 @@ networkstatus_compute_consensus(smartlist_t *votes, done: +#if 0 + vote_identity_map_free(id_map); +#endif tor_free(client_versions); tor_free(server_versions); tor_free(packages); diff --git a/src/or/dirvote.h b/src/or/dirvote.h index edd5751090..0fb2b2599b 100644 --- a/src/or/dirvote.h +++ b/src/or/dirvote.h @@ -89,6 +89,9 @@ /** Lowest consensus method where authorities may include an "id" line for * ed25519 identities in microdescriptors. */ #define MIN_METHOD_FOR_ED25519_ID_IN_MD 21 +/** Lowest consensus method where authorities vote on ed25519 ids and ensure + * ed25519 id consistency. */ +#define MIN_METHOD_FOR_ED25519_ID_VOTING MIN_METHOD_FOR_ED25519_ID_IN_MD /** Default bandwidth to clip unmeasured bandwidths to using method >= * MIN_METHOD_TO_CLIP_UNMEASURED_BW. (This is not a consensus method; do not diff --git a/src/or/or.h b/src/or/or.h index 714b1c6ce6..a41a14e17f 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2356,9 +2356,12 @@ typedef struct vote_routerstatus_t { char *version; /**< The version that the authority says this router is * running. */ unsigned int has_measured_bw:1; /**< The vote had a measured bw */ + unsigned int has_ed25519_listing:1; /** DOCDOC */ uint32_t measured_bw_kb; /**< Measured bandwidth (capacity) of the router */ /** The hash or hashes that the authority claims this microdesc has. */ vote_microdesc_hash_t *microdesc; + /** Ed25519 identity for this router, or zero if it has none. */ + uint8_t ed25519_id[ED25519_PUBKEY_LEN]; } vote_routerstatus_t; /** A signature of some document by an authority. */ diff --git a/src/or/routerparse.c b/src/or/routerparse.c index 03a5eafd88..71a0baa0bd 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -369,6 +369,7 @@ static token_rule_t rtrstatus_token_table[] = { T01("v", K_V, CONCAT_ARGS, NO_OBJ ), T01("w", K_W, ARGS, NO_OBJ ), T0N("m", K_M, CONCAT_ARGS, NO_OBJ ), + T0N("id", K_ID, GE(2), NO_OBJ ), T0N("opt", K_OPT, CONCAT_ARGS, OBJ_OK ), END_OF_TABLE }; @@ -2348,6 +2349,17 @@ routerstatus_parse_entry_from_string(memarea_t *area, line->microdesc_hash_line = tor_strdup(t->args[0]); vote_rs->microdesc = line; } + if (t->tp == K_ID) { + tor_assert(t->n_args >= 2); + if (!strcmp(t->args[0], "ed25519")) { + vote_rs->has_ed25519_listing = 1; + if (strcmp(t->args[1], "none") && + digest256_from_base64((char*)vote_rs->ed25519_id, t->args[1])<0) { + log_warn(LD_DIR, "Bogus ed25519 key in networkstatus vote"); + goto err; + } + } + } } SMARTLIST_FOREACH_END(t); } else if (flav == FLAV_MICRODESC) { tok = find_opt_by_keyword(tokens, K_M); @@ -3172,6 +3184,21 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out, goto err; } } + if (ns_type != NS_TYPE_CONSENSUS) { + digest256map_t *ed_id_map = digest256map_new(); + SMARTLIST_FOREACH_BEGIN(ns->routerstatus_list, vote_routerstatus_t *, vrs) { + if (! vrs->has_ed25519_listing || + tor_mem_is_zero((const char *)vrs->ed25519_id, DIGEST256_LEN)) + continue; + if (digest256map_get(ed_id_map, vrs->ed25519_id) != NULL) { + log_warn(LD_DIR, "Vote networkstatus ed25519 identities were not " + "unique"); + goto err; + } + digest256map_set(ed_id_map, vrs->ed25519_id, (void*)1); + } SMARTLIST_FOREACH_END(vrs); + digest256map_free(ed_id_map, NULL); + } /* Parse footer; check signature. */ footer_tokens = smartlist_new();