commit f214309e04a6e9924206c26ff4bb22637c826383 Author: Damian Johnson atagar@torproject.org Date: Tue Nov 13 17:32:27 2018 -0800
Compute extrainfo sha256 digests from the whole descriptor
Accounting for a tor bug that's prompting an upcoming spec change...
https://trac.torproject.org/projects/tor/ticket/28415 --- stem/descriptor/extrainfo_descriptor.py | 22 ++++++++++++++-------- test/unit/descriptor/extrainfo_descriptor.py | 3 ++- 2 files changed, 16 insertions(+), 9 deletions(-)
diff --git a/stem/descriptor/extrainfo_descriptor.py b/stem/descriptor/extrainfo_descriptor.py index 2df4bc71..f1e29cd2 100644 --- a/stem/descriptor/extrainfo_descriptor.py +++ b/stem/descriptor/extrainfo_descriptor.py @@ -954,17 +954,23 @@ class RelayExtraInfoDescriptor(ExtraInfoDescriptor):
@lru_cache() def digest(self, hash_type = DigestHashType.SHA1): - # our digest is calculated from everything except our signature - raw_content, ending = str(self), '\nrouter-signature\n' - raw_content = stem.util.str_tools._to_bytes(raw_content[:raw_content.find(ending) + len(ending)]) - if hash_type == DigestHashType.SHA1: + # our digest is calculated from everything except our signature + + raw_content, ending = str(self), '\nrouter-signature\n' + raw_content = stem.util.str_tools._to_bytes(raw_content[:raw_content.find(ending) + len(ending)]) return hashlib.sha1(raw_content).hexdigest().upper() elif hash_type == DigestHashType.SHA256: - # descriptors drop '=' hash padding from its fields (such as our server - # descriptor's extra-info-digest), so doing the same here so we match - - return base64.b64encode(hashlib.sha256(raw_content).digest()).rstrip('=') + # Due to a tor bug sha256 digests are calculated from the + # whole descriptor rather than ommiting the signature... + # + # https://trac.torproject.org/projects/tor/ticket/28415 + # + # Descriptors drop '=' hash padding from its fields (such + # as our server descriptor's extra-info-digest), so doing + # the same here so we match. + + return base64.b64encode(hashlib.sha256(str(self)).digest()).rstrip('=') else: raise NotImplementedError('Extrainfo descriptor digests are only available in sha1 and sha256, not %s' % hash_type)
diff --git a/test/unit/descriptor/extrainfo_descriptor.py b/test/unit/descriptor/extrainfo_descriptor.py index f3252d4e..7a85dd06 100644 --- a/test/unit/descriptor/extrainfo_descriptor.py +++ b/test/unit/descriptor/extrainfo_descriptor.py @@ -53,7 +53,8 @@ k0d2aofcVbHr4fPQOSST0LXDrhFl5Fqo5um296zpJGvRUeO6S44U/EfJAGShtqWw self.assertEqual(datetime.datetime(2012, 5, 5, 17, 2, 45), desc.dir_write_history_end) self.assertEqual(900, desc.dir_write_history_interval) self.assertEqual(expected_signature, desc.signature) - self.assertEqual('00A57A9AAB5EA113898E2DD02A755E31AFC27227', desc.digest()) + self.assertEqual('00A57A9AAB5EA113898E2DD02A755E31AFC27227', desc.digest(stem.descriptor.DigestHashType.SHA1)) + self.assertEqual('n2+wh6uM+lbKnhbkOog2jv9X5tPytlrFdO+I+auSmME', desc.digest(stem.descriptor.DigestHashType.SHA256)) self.assertEqual([], desc.get_unrecognized_lines())
# The read-history, write-history, dirreq-read-history, and
tor-commits@lists.torproject.org