[tor-commits] [stem/master] Parse signing_cert as an ed25519 certificate

atagar at torproject.org atagar at torproject.org
Sun Oct 6 02:07:34 UTC 2019


commit 80f4934183a0037926f11e18b54eda09bacb012c
Author: Damian Johnson <atagar at torproject.org>
Date:   Wed Oct 2 15:59:10 2019 -0700

    Parse signing_cert as an ed25519 certificate
    
    I was mistaken to parse signing_cert as a key blob. Server descriptors are
    deprecating their key blob copy (the 'ed25519_certificate' attribute) in favor
    of a Ed25519Certificate instance, and hidden service descriptors should do the
    same.
    
    Hidden service v3 parsing isn't yet in a release so we can simply fix this in
    place without concern for backward compatibility.
---
 stem/descriptor/certificate.py            | 15 +++++++++++++++
 stem/descriptor/hidden_service.py         | 14 +++++++-------
 stem/descriptor/server_descriptor.py      |  2 ++
 test/unit/descriptor/hidden_service_v3.py |  2 +-
 4 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/stem/descriptor/certificate.py b/stem/descriptor/certificate.py
index 4a78fa3f..e336bbda 100644
--- a/stem/descriptor/certificate.py
+++ b/stem/descriptor/certificate.py
@@ -152,6 +152,21 @@ class Ed25519Certificate(object):
     else:
       raise ValueError('Ed25519 certificate is version %i. Parser presently only supports version 1.' % version)
 
+  @staticmethod
+  def _from_descriptor(keyword, attribute):
+    def _parse(descriptor, entries):
+      value, block_type, block_contents = entries[keyword][0]
+
+      if not block_contents or block_type != 'ED25519 CERT':
+        raise ValueError("'%s' should be followed by a ED25519 CERT block, but was a %s" % (keyword, block_type))
+
+      setattr(descriptor, attribute, Ed25519Certificate.parse(block_contents))
+
+    return _parse
+
+  def __str__(self):
+    return '-----BEGIN ED25519 CERT-----\n%s\n-----END ED25519 CERT-----' % self.encoded
+
 
 class Ed25519CertificateV1(Ed25519Certificate):
   """
diff --git a/stem/descriptor/hidden_service.py b/stem/descriptor/hidden_service.py
index 2ca9f4bf..bf11c685 100644
--- a/stem/descriptor/hidden_service.py
+++ b/stem/descriptor/hidden_service.py
@@ -31,13 +31,14 @@ import collections
 import hashlib
 import io
 
-import stem.descriptor.certificate
 import stem.descriptor.hsv3_crypto
 import stem.prereq
 import stem.util.connection
 import stem.util.str_tools
 import stem.util.tor_tools
 
+from stem.descriptor.certificate import Ed25519Certificate
+
 from stem.descriptor import (
   PGP_BLOCK_END,
   Descriptor,
@@ -199,7 +200,7 @@ _parse_v2_signature_line = _parse_key_block('signature', 'signature', 'SIGNATURE
 
 _parse_v3_version_line = _parse_int_line('hs-descriptor', 'version', allow_negative = False)
 _parse_lifetime_line = _parse_int_line('descriptor-lifetime', 'lifetime', allow_negative = False)
-_parse_signing_key_line = _parse_key_block('descriptor-signing-key-cert', 'signing_cert', 'ED25519 CERT')
+_parse_signing_cert = Ed25519Certificate._from_descriptor('descriptor-signing-key-cert', 'signing_cert')
 _parse_revision_counter_line = _parse_int_line('revision-counter', 'revision_counter', allow_negative = False)
 _parse_superencrypted_line = _parse_key_block('superencrypted', 'superencrypted', 'MESSAGE')
 _parse_v3_signature_line = _parse_simple_line('signature', 'signature')
@@ -481,7 +482,7 @@ class HiddenServiceDescriptorV3(BaseHiddenServiceDescriptor):
 
   :var int version: **\\*** hidden service descriptor version
   :var int lifetime: **\\*** minutes after publication this descriptor is valid
-  :var str signing_cert: **\\*** cross-certifier for the short-term descriptor signing key
+  :var stem.certificate.Ed25519Certificate signing_cert: **\\*** cross-certifier for the short-term descriptor signing key
   :var int revision_counter: **\\*** descriptor revision number
   :var str superencrypted: **\\*** encrypted HS-DESC-ENC payload
   :var str signature: **\\*** signature of this descriptor
@@ -497,7 +498,7 @@ class HiddenServiceDescriptorV3(BaseHiddenServiceDescriptor):
   ATTRIBUTES = {
     'version': (None, _parse_v3_version_line),
     'lifetime': (None, _parse_lifetime_line),
-    'signing_cert': (None, _parse_signing_key_line),
+    'signing_cert': (None, _parse_signing_cert),
     'revision_counter': (None, _parse_revision_counter_line),
     'superencrypted': (None, _parse_superencrypted_line),
     'signature': (None, _parse_v3_signature_line),
@@ -506,7 +507,7 @@ class HiddenServiceDescriptorV3(BaseHiddenServiceDescriptor):
   PARSER_FOR_LINE = {
     'hs-descriptor': _parse_v3_version_line,
     'descriptor-lifetime': _parse_lifetime_line,
-    'descriptor-signing-key-cert': _parse_signing_key_line,
+    'descriptor-signing-key-cert': _parse_signing_cert,
     'revision-counter': _parse_revision_counter_line,
     'superencrypted': _parse_superencrypted_line,
     'signature': _parse_v3_signature_line,
@@ -560,8 +561,7 @@ class HiddenServiceDescriptorV3(BaseHiddenServiceDescriptor):
     elif not stem.prereq._is_sha3_available():
       raise ImportError('Hidden service descriptor decryption requires python 3.6+ or the pysha3 module (https://pypi.org/project/pysha3/)')
 
-    cert = stem.descriptor.certificate.Ed25519Certificate.parse(self.signing_cert)
-    blinded_key = cert.signing_key()
+    blinded_key = self.signing_cert.signing_key()
 
     if not blinded_key:
       raise ValueError('No signing key extension present')
diff --git a/stem/descriptor/server_descriptor.py b/stem/descriptor/server_descriptor.py
index 71f3a803..ebadcde2 100644
--- a/stem/descriptor/server_descriptor.py
+++ b/stem/descriptor/server_descriptor.py
@@ -401,6 +401,8 @@ def _parse_exit_policy(descriptor, entries):
 
 
 def _parse_identity_ed25519_line(descriptor, entries):
+  # TODO: replace this with Ed25519Certificate._from_descriptor() in stem 2.x
+
   _parse_key_block('identity-ed25519', 'ed25519_certificate', 'ED25519 CERT')(descriptor, entries)
 
   if descriptor.ed25519_certificate:
diff --git a/test/unit/descriptor/hidden_service_v3.py b/test/unit/descriptor/hidden_service_v3.py
index 2242d617..3824c8a6 100644
--- a/test/unit/descriptor/hidden_service_v3.py
+++ b/test/unit/descriptor/hidden_service_v3.py
@@ -46,7 +46,7 @@ class TestHiddenServiceDescriptorV3(unittest.TestCase):
 
     self.assertEqual(3, desc.version)
     self.assertEqual(180, desc.lifetime)
-    self.assertEqual(EXPECTED_SIGNING_CERT, desc.signing_cert)
+    self.assertEqual(EXPECTED_SIGNING_CERT, str(desc.signing_cert))
     self.assertEqual(42, desc.revision_counter)
     self.assertTrue('eaH8VdaTKS' in desc.superencrypted)
     self.assertEqual('aglChCQF+lbzKgyxJJTpYGVShV/GMDRJ4+cRGCp+a2y/yX/tLSh7hzqI7rVZrUoGj74Xr1CLMYO3fXYCS+DPDQ', desc.signature)





More information about the tor-commits mailing list