|
@@ -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);
|
|
|
}
|
|
|
|