Browse Source

Enforce more correspondence between ri and ei

In particular, they have to list the same ed25519 certificate, and
the SHA256 digest of the ei needs to match.
Nick Mathewson 9 years ago
parent
commit
0b819a2a7c
3 changed files with 39 additions and 1 deletions
  1. 16 1
      src/or/routerlist.c
  2. 21 0
      src/or/torcert.c
  3. 2 0
      src/or/torcert.h

+ 16 - 1
src/or/routerlist.c

@@ -4906,7 +4906,7 @@ routerinfo_incompatible_with_extrainfo(const routerinfo_t *ri,
                                        signed_descriptor_t *sd,
                                        const char **msg)
 {
-  int digest_matches, r=1;
+  int digest_matches, digest256_matches, r=1;
   tor_assert(ri);
   tor_assert(ei);
   if (!sd)
@@ -4919,6 +4919,11 @@ routerinfo_incompatible_with_extrainfo(const routerinfo_t *ri,
 
   digest_matches = tor_memeq(ei->cache_info.signed_descriptor_digest,
                            sd->extra_info_digest, DIGEST_LEN);
+  /* 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);
+  digest256_matches |= tor_mem_is_zero(ri->extra_info_digest256, DIGEST256_LEN);
 
   /* The identity must match exactly to have been generated at the same time
    * by the same router. */
@@ -4929,6 +4934,11 @@ routerinfo_incompatible_with_extrainfo(const routerinfo_t *ri,
     goto err; /* different servers */
   }
 
+  if (! tor_cert_opt_eq(ri->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,
@@ -4955,6 +4965,11 @@ routerinfo_incompatible_with_extrainfo(const routerinfo_t *ri,
     goto err;
   }
 
+  if (!digest256_matches) {
+    if (msg) *msg = "Extrainfo digest did not match digest256 from routerdesc";
+    goto err; /* Digest doesn't match declared value. */
+  }
+
   if (!digest_matches) {
     if (msg) *msg = "Extrainfo digest did not match value from routerdesc";
     goto err; /* Digest doesn't match declared value. */

+ 21 - 0
src/or/torcert.c

@@ -216,3 +216,24 @@ tor_cert_dup(const tor_cert_t *cert)
   return newcert;
 }
 
+/** Return true iff cert1 and cert2 are the same cert. */
+int
+tor_cert_eq(const tor_cert_t *cert1, const tor_cert_t *cert2)
+{
+  tor_assert(cert1);
+  tor_assert(cert2);
+  return cert1->encoded_len == cert2->encoded_len &&
+    tor_memeq(cert1->encoded, cert2->encoded, cert1->encoded_len);
+}
+
+/** Return true iff cert1 and cert2 are the same cert, or if they are both
+ * NULL. */
+int
+tor_cert_opt_eq(const tor_cert_t *cert1, const tor_cert_t *cert2)
+{
+  if (cert1 == NULL && cert2 == NULL)
+    return 1;
+  if (!cert1 || !cert2)
+    return 0;
+  return tor_cert_eq(cert1, cert2);
+}

+ 2 - 0
src/or/torcert.h

@@ -64,6 +64,8 @@ int tor_cert_checksig(tor_cert_t *cert,
                       const ed25519_public_key_t *pubkey, time_t now);
 
 tor_cert_t *tor_cert_dup(const tor_cert_t *cert);
+int tor_cert_eq(const tor_cert_t *cert1, const tor_cert_t *cert2);
+int tor_cert_opt_eq(const tor_cert_t *cert1, const tor_cert_t *cert2);
 
 #endif