[tor-commits] [stem/master] Revised behavior for document signature methods

atagar at torproject.org atagar at torproject.org
Sun Dec 2 07:56:48 UTC 2012


commit e1772bb9ad9ad2f6f085e2c0f489214d2f7fd6ee
Author: Damian Johnson <atagar at torproject.org>
Date:   Fri Nov 23 12:14:12 2012 -0800

    Revised behavior for document signature methods
    
    The spec has been revised to explain how signature methods worked. I had
    assumed that they were included in microdescritor consensuses and excluded from
    standard consensuses. Turns out however that they can be included with both
    and, if excluded, have a default value of 'sha1'. This is much nicer from a
    parsing and behavior standpoint.
    
    bug report: https://trac.torproject.org/7072
    fix: https://gitweb.torproject.org/torspec.git/commitdiff/96427e8
---
 stem/descriptor/networkstatus.py                  |   22 +++---------
 test/integ/descriptor/networkstatus.py            |    4 +-
 test/mocking.py                                   |    5 ---
 test/unit/descriptor/networkstatus/document_v3.py |   37 +++++++--------------
 4 files changed, 19 insertions(+), 49 deletions(-)

diff --git a/stem/descriptor/networkstatus.py b/stem/descriptor/networkstatus.py
index 0c08611..ca6aca2 100644
--- a/stem/descriptor/networkstatus.py
+++ b/stem/descriptor/networkstatus.py
@@ -768,19 +768,12 @@ class _DocumentFooter(object):
             raise ValueError("A network status document's 'bandwidth-weights' entries should be '%s', got '%s'" % (expected_label, actual_label))
       elif keyword == "directory-signature":
         for sig_value, block_contents in values:
-          if not header.is_microdescriptor:
-            expected_spaces = 1
-            format_label = 'directory-signature FINGERPRINT KEY_DIGEST'
-          else:
-            expected_spaces = 2
-            format_label = 'directory-signature METHOD FINGERPRINT KEY_DIGEST'
-          
-          if sig_value.count(" ") != expected_spaces or not block_contents:
+          if not sig_value.count(" ") in (1, 2) or not block_contents:
             if not validate: continue
-            raise ValueError("Authority signatures in a network status document are expected to be of the form '%s\\nSIGNATURE', got:\n%s\n%s" % (format_label, sig_value, block_contents))
+            raise ValueError("Authority signatures in a network status document are expected to be of the form 'directory-signature [METHOD] FINGERPRINT KEY_DIGEST\\nSIGNATURE', got:\n%s\n%s" % (sig_value, block_contents))
           
-          if not header.is_microdescriptor:
-            method = None
+          if sig_value.count(" ") == 1:
+            method = 'sha1' # default if none was provided
             fingerprint, key_digest = sig_value.split(" ", 1)
           else:
             method, fingerprint, key_digest = sig_value.split(" ", 2)
@@ -1232,8 +1225,7 @@ class DocumentSignature(object):
   """
   Directory signature of a v3 network status document.
   
-  :var str method: method used to make the signature, this only appears in
-    microdescriptor consensuses
+  :var str method: algorithm used to make the signature
   :var str identity: fingerprint of the authority that made the signature
   :var str key_digest: digest of the signing key
   :var str signature: document signature
@@ -1253,10 +1245,6 @@ class DocumentSignature(object):
       if not stem.util.tor_tools.is_valid_fingerprint(key_digest):
         raise ValueError("Malformed key digest (%s) in the document signature" % (key_digest))
     
-    # TODO: The method field is undocumented so I'm just guessing how we should
-    # handle it. Ticket for clarification...
-    # https://trac.torproject.org/7072
-    
     self.method = method
     self.identity = identity
     self.key_digest = key_digest
diff --git a/test/integ/descriptor/networkstatus.py b/test/integ/descriptor/networkstatus.py
index 1b70898..84a1901 100644
--- a/test/integ/descriptor/networkstatus.py
+++ b/test/integ/descriptor/networkstatus.py
@@ -189,7 +189,7 @@ I/TJmV928na7RLZe2mGHCAW3VQOvV+QkCfj05VZ8CsY=
       
       signature = document.signatures[0]
       self.assertEquals(8, len(document.signatures))
-      self.assertEquals(None, signature.method)
+      self.assertEquals("sha1", signature.method)
       self.assertEquals("14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4", signature.identity)
       self.assertEquals("BF112F1C6D5543CFD0A32215ACABD4197B5279AD", signature.key_digest)
       self.assertEquals(expected_signature, signature.signature)
@@ -400,7 +400,7 @@ DnN5aFtYKiTc19qIC7Nmo+afPdDEf0MlJvEOP5EWl3w=
       
       signature = document.signatures[0]
       self.assertEquals(1, len(document.signatures))
-      self.assertEquals(None, signature.method)
+      self.assertEquals("sha1", signature.method)
       self.assertEquals("27B6B5996C426270A5C95488AA5BCEB6BCC86956", signature.identity)
       self.assertEquals("D5C30C15BB3F1DA27669C2D88439939E8F418FCF", signature.key_digest)
       self.assertEquals(expected_signature, signature.signature)
diff --git a/test/mocking.py b/test/mocking.py
index d1b92db..e48ce64 100644
--- a/test/mocking.py
+++ b/test/mocking.py
@@ -759,11 +759,6 @@ def get_network_status_document_v3(attr = None, exclude = (), authorities = None
       "consensus-method": "9",
     }
   
-  if "microdesc" in attr.get("network-status-version", ""):
-    extra_defaults.update({
-      "directory-signature": "sha256 " + NETWORK_STATUS_DOCUMENT_FOOTER[2][1],
-    })
-  
   for k, v in extra_defaults.items():
     if not (k in attr or (exclude and k in exclude)):
       attr[k] = v
diff --git a/test/unit/descriptor/networkstatus/document_v3.py b/test/unit/descriptor/networkstatus/document_v3.py
index 11c9a9f..0396754 100644
--- a/test/unit/descriptor/networkstatus/document_v3.py
+++ b/test/unit/descriptor/networkstatus/document_v3.py
@@ -635,39 +635,26 @@ class TestNetworkStatusDocument(unittest.TestCase):
   
   def test_microdescriptor_signature(self):
     """
-    The 'directory-signature' lines for normal and microdescriptor conensuses
-    differ slightly in their format.
+    The 'directory-signature' lines both with and without a defined method for
+    the signature format.
     """
     
-    # including a microdescriptor flavored 'directory-signature' line should work
+    # including the signature method field should work
     
-    document = get_network_status_document_v3({"network-status-version": "3 microdesc"})
-    self.assertEqual('sha256', document.signatures[0].method)
-    
-    # include a standard 'directory-signature' line in a microdescriptor
-    # consensus
-    
-    content = get_network_status_document_v3({
+    document = get_network_status_document_v3({
       "network-status-version": "3 microdesc",
-      "directory-signature": NETWORK_STATUS_DOCUMENT_FOOTER[2][1],
-    }, content = True)
-    
-    self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
-    
-    document = NetworkStatusDocumentV3(content, validate = False)
-    self.assertEqual([], document.signatures)
+      "directory-signature": "sha256 " + NETWORK_STATUS_DOCUMENT_FOOTER[2][1],
+    })
     
-    # includes a microdescriptor flavored 'directory-signature' line in a
-    # normal consensus
+    self.assertEqual('sha256', document.signatures[0].method)
     
-    content = get_network_status_document_v3({
-      "directory-signature": "sha256 " + NETWORK_STATUS_DOCUMENT_FOOTER[2][1],
-    }, content = True)
+    # excluding the method should default to sha1
     
-    self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
+    document = get_network_status_document_v3({
+      "network-status-version": "3 microdesc",
+    })
     
-    document = NetworkStatusDocumentV3(content, validate = False)
-    self.assertEqual([], document.signatures)
+    self.assertEqual('sha1', document.signatures[0].method)
   
   def test_malformed_signature(self):
     """



More information about the tor-commits mailing list