[tor-commits] [stem/master] Bridge extrainfo support for ed25519

atagar at torproject.org atagar at torproject.org
Mon Aug 24 17:02:05 UTC 2015


commit 4a504c8922ff66cf414538f4e5cbd84c504ebcce
Author: Damian Johnson <atagar at torproject.org>
Date:   Mon Aug 24 09:43:05 2015 -0700

    Bridge extrainfo support for ed25519
    
    Accounting for bridge extrainfo descriptor parsing of ed25519. It replaces the
    two new fields with a couple different ones. Need clarification on the second
    though.
---
 stem/descriptor/extrainfo_descriptor.py            |   32 +++++++++++++-------
 .../data/bridge_extrainfo_descriptor_with_ed25519  |   25 +++++++++++++++
 test/unit/descriptor/extrainfo_descriptor.py       |   17 ++++++++++-
 3 files changed, 62 insertions(+), 12 deletions(-)

diff --git a/stem/descriptor/extrainfo_descriptor.py b/stem/descriptor/extrainfo_descriptor.py
index 7373620..5b986b4 100644
--- a/stem/descriptor/extrainfo_descriptor.py
+++ b/stem/descriptor/extrainfo_descriptor.py
@@ -535,6 +535,7 @@ def _parse_hs_stats(keyword, stat_attribute, extra_attribute, descriptor, entrie
 
 
 _parse_identity_ed25519_line = _parse_key_block('identity-ed25519', 'ed25519_certificate', 'ED25519 CERT')
+_parse_master_key_ed25519_line = _parse_simple_line('master-key-ed25519', 'ed25519_certificate_hash')
 _parse_geoip_db_digest_line = _parse_forty_character_hex('geoip-db-digest', 'geoip_db_digest')
 _parse_geoip6_db_digest_line = _parse_forty_character_hex('geoip6-db-digest', 'geoip6_db_digest')
 _parse_dirreq_v2_resp_line = functools.partial(_parse_dirreq_line, 'dirreq-v2-resp', 'dir_v2_responses', 'dir_v2_responses_unknown')
@@ -573,6 +574,7 @@ _parse_geoip_client_origins_line = functools.partial(_parse_geoip_to_count_line,
 _parse_entry_ips_line = functools.partial(_parse_geoip_to_count_line, 'entry-ips', 'entry_ips')
 _parse_bridge_ips_line = functools.partial(_parse_geoip_to_count_line, 'bridge-ips', 'bridge_ips')
 _parse_router_sig_ed25519_line = _parse_simple_line('router-sig-ed25519', 'ed25519_signature')
+_parse_router_digest_sha256_line = _parse_simple_line('router-digest-sha256', 'router_digest_sha256')
 _parse_router_digest_line = _parse_forty_character_hex('router-digest', '_digest')
 _parse_router_signature_line = _parse_key_block('router-signature', 'signature', 'SIGNATURE')
 
@@ -590,9 +592,6 @@ class ExtraInfoDescriptor(Descriptor):
     port, args) tuple, these usually appear on bridges in which case all of
     those are **None**
 
-  :var ed25519_certificate str: base64 encoded ed25519 certificate
-  :var ed25519_signature str: signature of this document using ed25519
-
   **Bi-directional connection usage:**
 
   :var datetime conn_bi_direct_end: end of the sampling interval
@@ -695,9 +694,6 @@ class ExtraInfoDescriptor(Descriptor):
   .. versionchanged:: 1.4.0
      Added the hs_stats_end, hs_rend_cells, hs_rend_cells_attr,
      hs_dir_onions_seen, and hs_dir_onions_seen_attr attributes.
-
-  .. versionchanged:: 1.5.0
-     Added the ed25519_certificate and ed25519_signature attributes.
   """
 
   ATTRIBUTES = {
@@ -708,9 +704,6 @@ class ExtraInfoDescriptor(Descriptor):
     'geoip6_db_digest': (None, _parse_geoip6_db_digest_line),
     'transport': ({}, _parse_transport_line),
 
-    'ed25519_certificate': (None, _parse_identity_ed25519_line),
-    'ed25519_signature': (None, _parse_router_sig_ed25519_line),
-
     'conn_bi_direct_end': (None, _parse_conn_bi_direct_line),
     'conn_bi_direct_interval': (None, _parse_conn_bi_direct_line),
     'conn_bi_direct_below': (None, _parse_conn_bi_direct_line),
@@ -790,8 +783,6 @@ class ExtraInfoDescriptor(Descriptor):
 
   PARSER_FOR_LINE = {
     'extra-info': _parse_extra_info_line,
-    'identity-ed25519': _parse_identity_ed25519_line,
-    'router-sig-ed25519': _parse_router_sig_ed25519_line,
     'geoip-db-digest': _parse_geoip_db_digest_line,
     'geoip6-db-digest': _parse_geoip6_db_digest_line,
     'transport': _parse_transport_line,
@@ -900,16 +891,25 @@ class RelayExtraInfoDescriptor(ExtraInfoDescriptor):
   'GETINFO extra-info/digest/\*', cached descriptors, and metrics
   (`specification <https://gitweb.torproject.org/torspec.git/tree/dir-spec.txt>`_).
 
+  :var ed25519_certificate str: base64 encoded ed25519 certificate
+  :var ed25519_signature str: signature of this document using ed25519
   :var str signature: **\*** signature for this extrainfo descriptor
 
   **\*** attribute is required when we're parsed with validation
+
+  .. versionchanged:: 1.5.0
+     Added the ed25519_certificate and ed25519_signature attributes.
   """
 
   ATTRIBUTES = dict(ExtraInfoDescriptor.ATTRIBUTES, **{
+    'ed25519_certificate': (None, _parse_identity_ed25519_line),
+    'ed25519_signature': (None, _parse_router_sig_ed25519_line),
     'signature': (None, _parse_router_signature_line),
   })
 
   PARSER_FOR_LINE = dict(ExtraInfoDescriptor.PARSER_FOR_LINE, **{
+    'identity-ed25519': _parse_identity_ed25519_line,
+    'router-sig-ed25519': _parse_router_sig_ed25519_line,
     'router-signature': _parse_router_signature_line,
   })
 
@@ -925,13 +925,23 @@ class BridgeExtraInfoDescriptor(ExtraInfoDescriptor):
   """
   Bridge extra-info descriptor (`bridge descriptor specification
   <https://collector.torproject.org/formats.html#bridge-descriptors>`_)
+
+  :var str ed25519_certificate_hash: sha256 hash of the original identity-ed25519
+  :var str router_digest_sha256: **todo**, needs clarification
+
+  .. versionchanged:: 1.5.0
+     Added the ed25519_certificate_hash and router_digest_sha256 attributes.
   """
 
   ATTRIBUTES = dict(ExtraInfoDescriptor.ATTRIBUTES, **{
+    'ed25519_certificate_hash': (None, _parse_master_key_ed25519_line),
+    'router_digest_sha256': (None, _parse_router_digest_sha256_line),
     '_digest': (None, _parse_router_digest_line),
   })
 
   PARSER_FOR_LINE = dict(ExtraInfoDescriptor.PARSER_FOR_LINE, **{
+    'master-key-ed25519': _parse_master_key_ed25519_line,
+    'router-digest-sha256': _parse_router_digest_sha256_line,
     'router-digest': _parse_router_digest_line,
   })
 
diff --git a/test/unit/descriptor/data/bridge_extrainfo_descriptor_with_ed25519 b/test/unit/descriptor/data/bridge_extrainfo_descriptor_with_ed25519
new file mode 100644
index 0000000..0030c45
--- /dev/null
+++ b/test/unit/descriptor/data/bridge_extrainfo_descriptor_with_ed25519
@@ -0,0 +1,25 @@
+ at type bridge-extra-info 1.3
+extra-info Unnamed B8AB331047F1C1637EFE07FB1B94CCC0FE0ABFFA
+master-key-ed25519 VigmhxML9uw8CT1XeGqZ8KLMhKk6AOKnChQt24usBbI
+published 2015-08-21 16:08:15
+write-history 2015-08-21 12:51:16 (14400 s) 2371584,40206336,45142016,8745984,6049792,1072128
+read-history 2015-08-21 12:51:16 (14400 s) 5175296,43838464,50509824,13580288,8732672,4001792
+dirreq-write-history 2015-08-21 12:51:16 (14400 s) 1630208,565248,29696,28672,1993728,581632
+dirreq-read-history 2015-08-21 12:51:16 (14400 s) 1024,3072,5120,4096,285696,11264
+geoip-db-digest 6882B8663F74C23E26E3C2274C24CAB2E82D67A2
+geoip6-db-digest F063BD5247EB9829E6B9E586393D7036656DAF44
+dirreq-stats-end 2015-08-21 12:51:16 (86400 s)
+dirreq-v3-ips ie=8,in=8,kz=8,nl=8,qa=8
+dirreq-v3-reqs ie=8,in=8,kz=8,nl=8,qa=8
+dirreq-v3-resp ok=8,not-enough-sigs=0,unavailable=0,not-found=0,not-modified=0,busy=0
+dirreq-v3-direct-dl complete=0,timeout=0,running=0
+dirreq-v3-tunneled-dl complete=4,timeout=4,running=0
+transport scramblesuit
+transport obfs3
+transport obfs4
+bridge-stats-end 2015-08-21 12:51:21 (86400 s)
+bridge-ips ie=8,in=8,kz=8,nl=8,qa=8
+bridge-ip-versions v4=8,v6=0
+bridge-ip-transports <OR>=8,obfs3=8,obfs4=8
+router-digest-sha256 7DSOQz9eGgjDX6GT7qcrVViK8yqJD4aoEnuhdAgYtgA
+router-digest 3DBE6840376F3EC277002396832788DB2FB38393
diff --git a/test/unit/descriptor/extrainfo_descriptor.py b/test/unit/descriptor/extrainfo_descriptor.py
index b4bc34f..fa68e62 100644
--- a/test/unit/descriptor/extrainfo_descriptor.py
+++ b/test/unit/descriptor/extrainfo_descriptor.py
@@ -143,7 +143,7 @@ k0d2aofcVbHr4fPQOSST0LXDrhFl5Fqo5um296zpJGvRUeO6S44U/EfJAGShtqWw
     """
 
     with open(get_resource('extrainfo_descriptor_with_ed25519'), 'rb') as descriptor_file:
-      desc = next(stem.descriptor.parse_file(descriptor_file, 'extra-info 1.0', validate = True))
+      desc = next(stem.descriptor.parse_file(descriptor_file, validate = True))
 
     self.assertEqual('silverfoxden', desc.nickname)
     self.assertEqual('4970B1DC3DBC8D82D7F1E43FF44B28DBF4765A4E', desc.fingerprint)
@@ -151,6 +151,21 @@ k0d2aofcVbHr4fPQOSST0LXDrhFl5Fqo5um296zpJGvRUeO6S44U/EfJAGShtqWw
     self.assertEqual('g6Zg7Er8K7C1etmt7p20INE1ExIvMRPvhwt6sjbLqEK+EtQq8hT+86hQ1xu7cnz6bHee+Zhhmcc4JamV4eiMAw', desc.ed25519_signature)
     self.assertEqual([], desc.get_unrecognized_lines())
 
+  def test_bridge_with_ed25519(self):
+    """
+    Parses a bridge descriptor with a ed25519 identity key.
+    """
+
+    with open(get_resource('bridge_extrainfo_descriptor_with_ed25519'), 'rb') as descriptor_file:
+      desc = next(stem.descriptor.parse_file(descriptor_file, validate = True))
+
+    self.assertEqual('Unnamed', desc.nickname)
+    self.assertEqual('B8AB331047F1C1637EFE07FB1B94CCC0FE0ABFFA', desc.fingerprint)
+    self.assertFalse(hasattr(desc, 'ed25519_certificate'))
+    self.assertEqual('VigmhxML9uw8CT1XeGqZ8KLMhKk6AOKnChQt24usBbI', desc.ed25519_certificate_hash)
+    self.assertEqual('7DSOQz9eGgjDX6GT7qcrVViK8yqJD4aoEnuhdAgYtgA', desc.router_digest_sha256)
+    self.assertEqual([], desc.get_unrecognized_lines())
+
   def test_minimal_extrainfo_descriptor(self):
     """
     Basic sanity check that we can parse an extrainfo descriptor with minimal





More information about the tor-commits mailing list