ソースを参照

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 年 前
コミット
0b819a2a7c
3 ファイル変更39 行追加1 行削除
  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