commit f487454259537fe37adea2ba90d7990475e789fd Author: Damian Johnson atagar@torproject.org Date: Mon Apr 10 17:25:45 2017 -0700
Support sha256 extrainfo digests
Server descriptors now include both a hex digest along with the base64 encoded sha256. Including this new attribute in our parser. --- docs/change_log.rst | 3 ++- stem/descriptor/server_descriptor.py | 13 ++++++++----- test/unit/descriptor/server_descriptor.py | 14 ++++++++++++++ 3 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/docs/change_log.rst b/docs/change_log.rst index d5c9755..e9b6323 100644 --- a/docs/change_log.rst +++ b/docs/change_log.rst @@ -56,7 +56,8 @@ The following are only available within Stem's `git repository * Support and validation for `ed25519 certificates <api/descriptor/certificate.html>`_ (`spec https://gitweb.torproject.org/torspec.git/tree/cert-spec.txt`_, :trac:`21558`) * Moved from the deprecated `pycrypto https://www.dlitz.net/software/pycrypto/`_ module to `cryptography https://pypi.python.org/pypi/cryptography`_ for validating signatures (:trac:`21086`) * Sped descriptor reading by ~25% by deferring defaulting when validating - * Support for protocol descriptor fields (:spec:`eb4fb3c`) + * Added server descriptor's new extra_info_sha256_digest attribute (:spec:`0f03581`) + * Added server descriptor's new protocol attribute (:spec:`eb4fb3c`) * Shared randomness properties weren't being read in votes (:trac:`21102`)
* **Utilities** diff --git a/stem/descriptor/server_descriptor.py b/stem/descriptor/server_descriptor.py index 1cedbe5..ddc1149 100644 --- a/stem/descriptor/server_descriptor.py +++ b/stem/descriptor/server_descriptor.py @@ -279,12 +279,13 @@ def _parse_fingerprint_line(descriptor, entries):
def _parse_extrainfo_digest_line(descriptor, entries): value = _value('extra-info-digest', entries) - value = value.split(' ')[0] # lines have additional content from propsal 228, waiting for it to be documented: #16227 + digest_comp = value.split(' ')
- if not stem.util.tor_tools.is_hex_digits(value, 40): - raise ValueError('extra-info-digest should be 40 hex characters: %s' % value) + if not stem.util.tor_tools.is_hex_digits(digest_comp[0], 40): + raise ValueError('extra-info-digest should be 40 hex characters: %s' % digest_comp[0])
- descriptor.extra_info_digest = value + descriptor.extra_info_digest = digest_comp[0] + descriptor.extra_info_sha256_digest = digest_comp[1] if len(digest_comp) >= 2 else None
def _parse_hibernating_line(descriptor, entries): @@ -457,6 +458,7 @@ class ServerDescriptor(Descriptor): requests are accepted :var bool extra_info_cache: ***** flag if a mirror for extra-info documents :var str extra_info_digest: upper-case hex encoded digest of our extra-info document + :var str extra_info_sha256_digest: base64 encoded sha256 digest of our extra-info document :var bool eventdns: flag for evdns backend (**deprecated**, always unset) :var str ntor_onion_key: base64 key used to encrypt EXTEND in the ntor protocol :var list or_addresses: ***** alternative for our address/or_port @@ -481,7 +483,7 @@ class ServerDescriptor(Descriptor): Added the allow_tunneled_dir_requests attribute.
.. versionchanged:: 1.6.0 - Added the protocols attribute. + Added the extra_info_sha256_digest and protocols attributes. """
ATTRIBUTES = { @@ -515,6 +517,7 @@ class ServerDescriptor(Descriptor): 'protocols': ({}, _parse_proto_line), 'extra_info_cache': (False, _parse_caches_extra_info_line), 'extra_info_digest': (None, _parse_extrainfo_digest_line), + 'extra_info_sha256_digest': (None, _parse_extrainfo_digest_line), 'hidden_service_dir': (None, _parse_hidden_service_dir_line), 'eventdns': (None, _parse_eventdns_line), 'ntor_onion_key': (None, _parse_ntor_onion_key_line), diff --git a/test/unit/descriptor/server_descriptor.py b/test/unit/descriptor/server_descriptor.py index 42fa392..747600c 100644 --- a/test/unit/descriptor/server_descriptor.py +++ b/test/unit/descriptor/server_descriptor.py @@ -129,6 +129,7 @@ Qlx9HNCqCY877ztFRC624ja2ql6A2hBcuoYMbkHjcQ4= self.assertEqual(False, desc.allow_tunneled_dir_requests) self.assertEqual(False, desc.extra_info_cache) self.assertEqual('D225B728768D7EA4B5587C13A7A9D22EBBEE6E66', desc.extra_info_digest) + self.assertEqual(None, desc.extra_info_sha256_digest) self.assertEqual(['2'], desc.hidden_service_dir) self.assertEqual(expected_family, desc.family) self.assertEqual(153600, desc.average_bandwidth) @@ -187,6 +188,7 @@ Qlx9HNCqCY877ztFRC624ja2ql6A2hBcuoYMbkHjcQ4= self.assertEqual(False, desc.allow_tunneled_dir_requests) self.assertEqual(False, desc.extra_info_cache) self.assertEqual(None, desc.extra_info_digest) + self.assertEqual(None, desc.extra_info_sha256_digest) self.assertEqual(None, desc.hidden_service_dir) self.assertEqual(set(), desc.family) self.assertEqual(102400, desc.average_bandwidth) @@ -234,6 +236,7 @@ Qlx9HNCqCY877ztFRC624ja2ql6A2hBcuoYMbkHjcQ4= self.assertEqual(False, desc.allow_tunneled_dir_requests) self.assertEqual(False, desc.extra_info_cache) self.assertEqual('56403D838DE152421CD401B8E57DAD4483A3D56B', desc.extra_info_digest) + self.assertEqual(None, desc.extra_info_sha256_digest) self.assertEqual(['2'], desc.hidden_service_dir) self.assertEqual(set(), desc.family) self.assertEqual(102400, desc.average_bandwidth) @@ -303,6 +306,7 @@ Qlx9HNCqCY877ztFRC624ja2ql6A2hBcuoYMbkHjcQ4= self.assertEqual(False, desc.allow_tunneled_dir_requests) self.assertEqual(False, desc.extra_info_cache) self.assertEqual('44E9B679AF0B4EB09296985BAF4066AE9CA5BB93', desc.extra_info_digest) + self.assertEqual('r+roMxhsjd1GPpn5knQoBvtE9Rhsv8zQHCqiYL6u2CA', desc.extra_info_sha256_digest) self.assertEqual(['2'], desc.hidden_service_dir) self.assertEqual(family, desc.family) self.assertEqual(149715200, desc.average_bandwidth) @@ -413,6 +417,7 @@ Qlx9HNCqCY877ztFRC624ja2ql6A2hBcuoYMbkHjcQ4= self.assertEqual(False, desc.allow_tunneled_dir_requests) self.assertEqual(True, desc.extra_info_cache) self.assertEqual('BB1F13AA431421BEA29B840A2E33BB1C31C2990B', desc.extra_info_digest) + self.assertEqual(None, desc.extra_info_sha256_digest) self.assertEqual(None, desc.hidden_service_dir) self.assertEqual(set(), desc.family) self.assertEqual(3220480, desc.average_bandwidth) @@ -687,6 +692,15 @@ Qlx9HNCqCY877ztFRC624ja2ql6A2hBcuoYMbkHjcQ4= desc = get_relay_server_descriptor({'ipv6-policy': 'accept 22-23,53,80,110'}) self.assertEqual(expected, desc.exit_policy_v6)
+ def test_extrainfo_sha256_digest(self): + """ + Extrainfo descriptor line with both a hex and base64 encoded sha256 digest. + """ + + desc = get_relay_server_descriptor({'extra-info-digest': '03272BF7C68484AFBDA508DAE3734D809E4A5BC4 DWMz1AEdqPlcroubwx3lPEoGbT+oX7S2BH653sPIqfI'}) + self.assertEqual('03272BF7C68484AFBDA508DAE3734D809E4A5BC4', desc.extra_info_digest) + self.assertEqual('DWMz1AEdqPlcroubwx3lPEoGbT+oX7S2BH653sPIqfI', desc.extra_info_sha256_digest) + def test_protocols(self): """ Checks a 'proto' line.
tor-commits@lists.torproject.org