diff options
Diffstat (limited to 'src/or/routerlist.c')
-rw-r--r-- | src/or/routerlist.c | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/src/or/routerlist.c b/src/or/routerlist.c index d40d704a1d..045d50c3db 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -2898,6 +2898,7 @@ routerinfo_free(routerinfo_t *router) if (router->identity_pkey) crypto_pk_free(router->identity_pkey); tor_cert_free(router->signing_key_cert); + tor_cert_free(router->cache_info.signing_key_cert); if (router->declared_family) { SMARTLIST_FOREACH(router->declared_family, char *, s, tor_free(s)); smartlist_free(router->declared_family); @@ -2917,6 +2918,7 @@ extrainfo_free(extrainfo_t *extrainfo) if (!extrainfo) return; tor_cert_free(extrainfo->signing_key_cert); + tor_cert_free(extrainfo->cache_info.signing_key_cert); tor_free(extrainfo->cache_info.signed_descriptor_body); tor_free(extrainfo->pending_sig); @@ -3126,7 +3128,7 @@ extrainfo_insert,(routerlist_t *rl, extrainfo_t *ei, int warn_if_incompatible)) "Mismatch in digest in extrainfo map."); goto done; } - if (routerinfo_incompatible_with_extrainfo(ri, ei, sd, + if (routerinfo_incompatible_with_extrainfo(ri->identity_pkey, ei, sd, &compatibility_error_msg)) { char d1[HEX_DIGEST_LEN+1], d2[HEX_DIGEST_LEN+1]; r = (ri->cache_info.extrainfo_is_bogus) ? @@ -5165,25 +5167,32 @@ router_differences_are_cosmetic(const routerinfo_t *r1, const routerinfo_t *r2) return 1; } -/** Check whether <b>ri</b> (a.k.a. sd) is a router compatible with the - * extrainfo document - * <b>ei</b>. If no router is compatible with <b>ei</b>, <b>ei</b> should be +/** Check whether <b>sd</b> describes a router descriptor compatible with the + * extrainfo document <b>ei</b>. + * + * <b>identity_pkey</b> (which must also be provided) is RSA1024 identity key + * for the router. We use it to check the signature of the extrainfo document, + * if it has not already been checked. + * + * If no router is compatible with <b>ei</b>, <b>ei</b> should be * dropped. Return 0 for "compatible", return 1 for "reject, and inform * whoever uploaded <b>ei</b>, and return -1 for "reject silently.". If * <b>msg</b> is present, set *<b>msg</b> to a description of the * incompatibility (if any). + * + * Set the extrainfo_is_bogus field in <b>sd</b> if the digests matched + * but the extrainfo was nonetheless incompatible. **/ int -routerinfo_incompatible_with_extrainfo(const routerinfo_t *ri, +routerinfo_incompatible_with_extrainfo(const crypto_pk_t *identity_pkey, extrainfo_t *ei, signed_descriptor_t *sd, const char **msg) { int digest_matches, digest256_matches, r=1; - tor_assert(ri); + tor_assert(identity_pkey); + tor_assert(sd); tor_assert(ei); - if (!sd) - sd = (signed_descriptor_t*)&ri->cache_info; if (ei->bad_sig) { if (msg) *msg = "Extrainfo signature was bad, or signed with wrong key."; @@ -5195,27 +5204,27 @@ routerinfo_incompatible_with_extrainfo(const routerinfo_t *ri, /* Set digest256_matches to 1 if the digest is correct, or if no * digest256 was in the ri. */ digest256_matches = tor_memeq(ei->digest256, - ri->extra_info_digest256, DIGEST256_LEN); + sd->extra_info_digest256, DIGEST256_LEN); digest256_matches |= - tor_mem_is_zero(ri->extra_info_digest256, DIGEST256_LEN); + tor_mem_is_zero(sd->extra_info_digest256, DIGEST256_LEN); /* The identity must match exactly to have been generated at the same time * by the same router. */ - if (tor_memneq(ri->cache_info.identity_digest, + if (tor_memneq(sd->identity_digest, ei->cache_info.identity_digest, DIGEST_LEN)) { if (msg) *msg = "Extrainfo nickname or identity did not match routerinfo"; goto err; /* different servers */ } - if (! tor_cert_opt_eq(ri->signing_key_cert, ei->signing_key_cert)) { + if (! tor_cert_opt_eq(sd->signing_key_cert, ei->signing_key_cert)) { if (msg) *msg = "Extrainfo signing key cert didn't match routerinfo"; goto err; /* different servers */ } if (ei->pending_sig) { char signed_digest[128]; - if (crypto_pk_public_checksig(ri->identity_pkey, + if (crypto_pk_public_checksig(identity_pkey, signed_digest, sizeof(signed_digest), ei->pending_sig, ei->pending_sig_len) != DIGEST_LEN || tor_memneq(signed_digest, ei->cache_info.signed_descriptor_digest, @@ -5226,7 +5235,7 @@ routerinfo_incompatible_with_extrainfo(const routerinfo_t *ri, goto err; /* Bad signature, or no match. */ } - ei->cache_info.send_unencrypted = ri->cache_info.send_unencrypted; + ei->cache_info.send_unencrypted = sd->send_unencrypted; tor_free(ei->pending_sig); } |