mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-27 22:03:31 +01:00
r13921@catbus: nickm | 2007-07-26 16:26:48 -0400
Code to add signatures to a pending consensus directory. svn:r10936
This commit is contained in:
parent
189bc7cf9f
commit
fb2f3c035b
113
src/or/dirvote.c
113
src/or/dirvote.c
@ -698,15 +698,17 @@ networkstatus_check_voter_signature(networkstatus_vote_t *consensus,
|
||||
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 ||
|
||||
voter->signature,
|
||||
voter->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);
|
||||
/* XXXX020 did anything rely on this?
|
||||
* also, rename so it's no longer called "pending". */
|
||||
// tor_free(voter->signature);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -730,7 +732,7 @@ networkstatus_check_consensus_signature(networkstatus_vote_t *consensus)
|
||||
++n_unknown;
|
||||
continue;
|
||||
}
|
||||
if (voter->pending_signature) {
|
||||
if (voter->signature) {
|
||||
tor_assert(!voter->good_signature && !voter->bad_signature);
|
||||
if (!ds->v3_cert ||
|
||||
networkstatus_check_voter_signature(consensus, voter,
|
||||
@ -752,6 +754,93 @@ networkstatus_check_consensus_signature(networkstatus_vote_t *consensus)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** DOCDOC */
|
||||
int
|
||||
networkstatus_add_consensus_signatures(networkstatus_vote_t *target,
|
||||
networkstatus_vote_t *src,
|
||||
char **new_signatures_out)
|
||||
{
|
||||
smartlist_t *added_signatures, *sigs;
|
||||
int r;
|
||||
tor_assert(target);
|
||||
tor_assert(src);
|
||||
tor_assert(! target->is_vote);
|
||||
tor_assert(! src->is_vote);
|
||||
tor_assert(new_signatures_out);
|
||||
|
||||
*new_signatures_out = NULL;
|
||||
|
||||
/* Are they the same consensus? */
|
||||
if (memcmp(target->networkstatus_digest, src->networkstatus_digest,
|
||||
DIGEST_LEN))
|
||||
return -1;
|
||||
if (target == src)
|
||||
return 0;
|
||||
|
||||
added_signatures = smartlist_create();
|
||||
|
||||
/* For each voter in src... */
|
||||
SMARTLIST_FOREACH(src->voters, networkstatus_voter_info_t *, src_voter,
|
||||
{
|
||||
networkstatus_voter_info_t *target_voter =
|
||||
networkstatus_get_voter_by_id(target, src_voter->identity_digest);
|
||||
authority_cert_t *cert;
|
||||
/* If the target a doesn't know about this voter, then forget it. */
|
||||
if (!target_voter)
|
||||
continue;
|
||||
|
||||
/* If the target already has a good signature from this voter, then skip
|
||||
* this one. */
|
||||
if (target_voter->good_signature)
|
||||
continue;
|
||||
|
||||
/* If this signature is no good, then skip. */
|
||||
cert = authority_cert_get_by_digests(src_voter->identity_digest,
|
||||
src_voter->signing_key_digest);
|
||||
if (cert) {
|
||||
networkstatus_check_voter_signature(target, src_voter, cert);
|
||||
}
|
||||
/* If this signature is good, then replace and add. */
|
||||
if (src_voter->good_signature || !target_voter->signature) {
|
||||
tor_free(target_voter->signature);
|
||||
target_voter->signature =
|
||||
tor_memdup(src_voter->signature, src_voter->signature_len);
|
||||
memcpy(target_voter->signing_key_digest, src_voter->signing_key_digest,
|
||||
DIGEST_LEN);
|
||||
target_voter->signature_len = src_voter->signature_len;
|
||||
target_voter->good_signature = 1;
|
||||
target_voter->bad_signature = 0;
|
||||
smartlist_add(added_signatures, target_voter);
|
||||
}
|
||||
});
|
||||
|
||||
sigs = smartlist_create();
|
||||
SMARTLIST_FOREACH(added_signatures, networkstatus_voter_info_t *, v,
|
||||
{
|
||||
char buf[4096];
|
||||
char sk[HEX_DIGEST_LEN+1];
|
||||
char ik[HEX_DIGEST_LEN+1];
|
||||
tor_assert(v->signature);
|
||||
|
||||
base16_encode(sk, sizeof(sk), v->signing_key_digest, DIGEST_LEN);
|
||||
base16_encode(ik, sizeof(ik), v->identity_digest, DIGEST_LEN);
|
||||
tor_snprintf(buf, sizeof(buf), "directory-signature %s %s\n"
|
||||
"-----BEGIN SIGNATURE-----", ik, sk);
|
||||
smartlist_add(sigs, tor_strdup(buf));
|
||||
base64_encode(buf, sizeof(buf), v->signature, v->signature_len);
|
||||
strlcat(buf, "-----END SIGNATURE-----", sizeof(buf));
|
||||
smartlist_add(sigs, tor_strdup(buf));
|
||||
});
|
||||
|
||||
*new_signatures_out = smartlist_join_strings(sigs, "", 0, NULL);
|
||||
SMARTLIST_FOREACH(sigs, char *, cp, tor_free(cp));
|
||||
smartlist_free(sigs);
|
||||
r = smartlist_len(added_signatures);
|
||||
smartlist_free(added_signatures);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/* =====
|
||||
* Certificate functions
|
||||
* ===== */
|
||||
@ -876,6 +965,8 @@ typedef struct pending_vote_t {
|
||||
static smartlist_t *pending_vote_list = NULL;
|
||||
/** DOCDOC */
|
||||
static char *pending_consensus_body = NULL;
|
||||
/** DOCDOC */
|
||||
static networkstatus_vote_t *pending_consensus = NULL;
|
||||
|
||||
/** DOCDOC */
|
||||
void
|
||||
@ -988,6 +1079,7 @@ dirvote_compute_consensus(void)
|
||||
int n_votes, n_voters;
|
||||
smartlist_t *votes = NULL;
|
||||
char *consensus_body = NULL;
|
||||
networkstatus_vote_t *consensus = NULL;
|
||||
authority_cert_t *my_cert;
|
||||
|
||||
if (!pending_vote_list)
|
||||
@ -1011,13 +1103,26 @@ dirvote_compute_consensus(void)
|
||||
my_cert->identity_key,
|
||||
get_my_v3_authority_signing_key());
|
||||
|
||||
consensus = networkstatus_parse_vote_from_string(consensus_body, 0);
|
||||
if (!consensus) {
|
||||
log_warn(LD_DIR, "Couldn't parse consensus we generated!");
|
||||
goto err;
|
||||
}
|
||||
|
||||
tor_free(pending_consensus_body);
|
||||
pending_consensus_body = consensus_body;
|
||||
|
||||
if (pending_consensus)
|
||||
networkstatus_vote_free(pending_consensus);
|
||||
pending_consensus = consensus;
|
||||
|
||||
return 0;
|
||||
err:
|
||||
if (votes)
|
||||
smartlist_free(votes);
|
||||
tor_free(consensus_body);
|
||||
networkstatus_vote_free(consensus);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
10
src/or/or.h
10
src/or/or.h
@ -1330,8 +1330,8 @@ typedef struct networkstatus_voter_info_t {
|
||||
char vote_digest[DIGEST_LEN];
|
||||
char signing_key_digest[DIGEST_LEN]; /* This part is _not_ signed. */
|
||||
|
||||
char *pending_signature;
|
||||
int pending_signature_len;
|
||||
char *signature;
|
||||
int signature_len;
|
||||
unsigned int bad_signature : 1;
|
||||
unsigned int good_signature : 1;
|
||||
} networkstatus_voter_info_t;
|
||||
@ -2792,6 +2792,9 @@ networkstatus_voter_info_t *networkstatus_get_voter_by_id(
|
||||
networkstatus_vote_t *vote,
|
||||
const char *identity);
|
||||
int networkstatus_check_consensus_signature(networkstatus_vote_t *consensus);
|
||||
int networkstatus_add_consensus_signatures(networkstatus_vote_t *target,
|
||||
networkstatus_vote_t *src,
|
||||
char **new_signatures_out);
|
||||
|
||||
/* cert manipulation */
|
||||
void authority_cert_free(authority_cert_t *cert);
|
||||
@ -3272,6 +3275,7 @@ typedef struct trusted_dir_server_t {
|
||||
/** What kind of authority is this? (Bitfield.) */
|
||||
authority_type_t type;
|
||||
|
||||
/* XXXX020 this should be a list. */
|
||||
authority_cert_t *v3_cert; /**< V3 key certificate for this authority */
|
||||
|
||||
int n_networkstatus_failures; /**< How many times have we asked for this
|
||||
@ -3299,6 +3303,8 @@ trusted_dir_server_t *router_get_trusteddirserver_by_digest(
|
||||
const char *digest);
|
||||
trusted_dir_server_t *trusteddirserver_get_by_v3_auth_digest(
|
||||
const char *digest);
|
||||
authority_cert_t *authority_cert_get_by_digests(const char *id_digest,
|
||||
const char *sk_digest);
|
||||
void routerlist_add_family(smartlist_t *sl, routerinfo_t *router);
|
||||
void add_nickname_list_to_smartlist(smartlist_t *sl, const char *list,
|
||||
int must_be_running);
|
||||
|
@ -266,6 +266,23 @@ trusted_dirs_flush_certs_to_disk(void)
|
||||
trusted_dir_servers_certs_changed = 0;
|
||||
}
|
||||
|
||||
/** DOCDOC */
|
||||
authority_cert_t *
|
||||
authority_cert_get_by_digests(const char *id_digest,
|
||||
const char *sk_digest)
|
||||
{
|
||||
char d[DIGEST_LEN];
|
||||
trusted_dir_server_t *ds = trusteddirserver_get_by_v3_auth_digest(id_digest);
|
||||
|
||||
if (!ds || !ds->v3_cert)
|
||||
return NULL;
|
||||
crypto_pk_get_digest(ds->v3_cert->signing_key, d);
|
||||
if (memcmp(d, sk_digest, DIGEST_LEN))
|
||||
return NULL;
|
||||
|
||||
return ds->v3_cert;
|
||||
}
|
||||
|
||||
/* Router descriptor storage.
|
||||
*
|
||||
* Routerdescs are stored in a big file, named "cached-routers". As new
|
||||
|
@ -2046,9 +2046,9 @@ networkstatus_parse_vote_from_string(const char *s, int is_vote)
|
||||
goto err;
|
||||
v->good_signature = 1;
|
||||
} else {
|
||||
v->pending_signature = tor_memdup(tok->object_body,
|
||||
v->signature = tor_memdup(tok->object_body,
|
||||
tok->object_size);
|
||||
v->pending_signature_len = tok->object_size;
|
||||
v->signature_len = tok->object_size;
|
||||
}
|
||||
});
|
||||
/* XXXX020 enforce: vote must have at least one signature. */
|
||||
|
@ -2672,18 +2672,18 @@ test_v3_networkstatus(void)
|
||||
/* 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->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->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->signature);
|
||||
test_assert(voter->good_signature);
|
||||
test_assert(!voter->bad_signature);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user