[tor-commits] [stem/master] Server descriptor digest validation failed for python 3

atagar at torproject.org atagar at torproject.org
Thu Apr 25 03:16:32 UTC 2013


commit 92af5b8d50e3dac52e2380cd44ff706c88d9332e
Author: Damian Johnson <atagar at torproject.org>
Date:   Wed Apr 24 09:35:52 2013 -0700

    Server descriptor digest validation failed for python 3
    
    When validating the digest for server descriptors via python 3 we forgot to
    explicitly use byte values (rather than unicode). This is an adaptation of a
    patch from aj00200...
    
    https://trac.torproject.org/8755
---
 docs/change_log.rst                  |    1 +
 stem/descriptor/server_descriptor.py |   21 ++++++++-------------
 2 files changed, 9 insertions(+), 13 deletions(-)

diff --git a/docs/change_log.rst b/docs/change_log.rst
index d9fe02e..5ddfcda 100644
--- a/docs/change_log.rst
+++ b/docs/change_log.rst
@@ -42,6 +42,7 @@ The following are only available within stem's `git repository
 
   * :class:`~stem.response.events.AddrMapEvent` support for the new CACHED argument (:trac:`8596`, :spec:`25b0d43`)
   * :func:`~stem.control.Controller.attach_stream` could encounter an undocumented 555 response (:trac:`8701`, :spec:`7286576`)
+  * :class:`~stem.descriptor.server_descriptor.RelayDescriptor` digest validation was broken with python 3 (:trac:`8755`)
 
  * **Website**
 
diff --git a/stem/descriptor/server_descriptor.py b/stem/descriptor/server_descriptor.py
index 000b864..dc21813 100644
--- a/stem/descriptor/server_descriptor.py
+++ b/stem/descriptor/server_descriptor.py
@@ -17,7 +17,6 @@ etc). This information is provided from a few sources...
 
   ServerDescriptor - Tor server descriptor.
     |- RelayDescriptor - Server descriptor for a relay.
-    |  +- is_valid - checks the signature against the descriptor content
     |
     |- BridgeDescriptor - Scrubbed server descriptor for a bridge.
     |  |- is_scrubbed - checks if our content has been properly scrubbed
@@ -30,6 +29,7 @@ etc). This information is provided from a few sources...
 """
 
 import base64
+import codecs
 import datetime
 import hashlib
 import re
@@ -649,9 +649,9 @@ class RelayDescriptor(ServerDescriptor):
     """
     Provides the digest of our descriptor's content.
 
-    :raises: ValueError if the digest canot be calculated
-
     :returns: the digest string encoded in uppercase hex
+
+    :raises: ValueError if the digest canot be calculated
     """
 
     if self._digest is None:
@@ -743,7 +743,7 @@ class RelayDescriptor(ServerDescriptor):
     ############################################################################
 
     try:
-      if decrypted_bytes.index('\x00\x01') != 0:
+      if decrypted_bytes.index(b'\x00\x01') != 0:
         raise ValueError("Verification failed, identifier missing")
     except ValueError:
       raise ValueError("Verification failed, malformed data")
@@ -752,20 +752,15 @@ class RelayDescriptor(ServerDescriptor):
       identifier_offset = 2
 
       # find the separator
-      seperator_index = decrypted_bytes.index('\x00', identifier_offset)
+      seperator_index = decrypted_bytes.index(b'\x00', identifier_offset)
     except ValueError:
       raise ValueError("Verification failed, seperator not found")
 
-    digest = decrypted_bytes[seperator_index + 1:]
-
-    # The local digest is stored in uppercase hex;
-    #  - so decode it from hex
-    #  - and convert it to lower case
-
-    local_digest = self.digest().lower().decode('hex')
+    digest = codecs.encode(decrypted_bytes[seperator_index + 1:], 'hex_codec').upper()
+    local_digest = self.digest()
 
     if digest != local_digest:
-      raise ValueError("Decrypted digest does not match local digest")
+      raise ValueError("Decrypted digest does not match local digest (calculated: %s, local: %s)" % (digest, local_digest))
 
   def _parse(self, entries, validate):
     entries = dict(entries)  # shallow copy since we're destructive



More information about the tor-commits mailing list