commit ff1641d5d27deaa735ffd78727922bcfa6f3e1a0 Author: Damian Johnson atagar@torproject.org Date: Sun Mar 26 16:29:42 2017 +0200
Change extension flags to an enum list
Seems they're going for unix permission style flag encoding in the int so we should include a proper splitting of the attributes. We can't know yet what future flags will be so gotta keep the int around too. --- stem/descriptor/certificate.py | 28 +++++++++++++++++++++++++--- test/unit/descriptor/certificate.py | 10 +++++----- 2 files changed, 30 insertions(+), 8 deletions(-)
diff --git a/stem/descriptor/certificate.py b/stem/descriptor/certificate.py index 52bb33b..e1d75bb 100644 --- a/stem/descriptor/certificate.py +++ b/stem/descriptor/certificate.py @@ -26,6 +26,17 @@ to sign server descriptors. **LINK_CERT** TLS link certificate signed with ed25519 signing key **AUTH** authentication key signed with ed25519 signing key ============== =========== + +.. data::ExtensionFlag (enum) + + Flags that can be assigned to Ed25519 certificate extensions. + + ==================== =========== + ExtensionFlag Description + ==================== =========== + AFFECTS_VALIDATION extension affects whether the certificate is valid + UNKNOWN extension includes flags not yet recognized by stem + ==================== =========== """
import base64 @@ -38,6 +49,7 @@ ED25519_HEADER_LENGTH = 40 ED25519_SIGNATURE_LENGTH = 64
CertType = enum.UppercaseEnum('SIGNING', 'LINK_CERT', 'AUTH') +ExtensionFlag = enum.UppercaseEnum('AFFECTS_VALIDATION', 'UNKNOWN')
class Ed25519Certificate(object): @@ -138,19 +150,29 @@ class Ed25519CertificateV1(Ed25519Certificate): if extension_length != len(extension_data): raise ValueError("Ed25519 extension is truncated. It should have %i bytes of data but there's only %i." % (extension_length, len(extension_data)))
- self.extensions.append(Ed25519Extension(extension_type, extension_flags, extension_data)) + flags, remaining_flags = [], extension_flags + + if remaining_flags % 2 == 1: + flags.append(ExtensionFlag.AFFECTS_VALIDATION) + remaining_flags -= 1 + + if remaining_flags: + flags.append(ExtensionFlag.UNKNOWN) + + self.extensions.append(Ed25519Extension(extension_type, flags, extension_flags, extension_data)) remaining_data = remaining_data[4 + extension_length:]
if remaining_data: raise ValueError('Ed25519 certificate had %i bytes of unused extension data' % len(remaining_data))
-class Ed25519Extension(collections.namedtuple('Ed25519Extension', ['extension_type', 'flags', 'data'])): +class Ed25519Extension(collections.namedtuple('Ed25519Extension', ['extension_type', 'flags', 'flag_int', 'data'])): """ Extension within an Ed25519 certificate.
:var int extension_type: extension type - :var int flags: extension attributes + :var list flags: extension attribute flags + :var int flag_int: integer encoding of the extension attribute flags :var bytes data: data the extension concerns """
diff --git a/test/unit/descriptor/certificate.py b/test/unit/descriptor/certificate.py index fde7fa3..5728711 100644 --- a/test/unit/descriptor/certificate.py +++ b/test/unit/descriptor/certificate.py @@ -11,7 +11,7 @@ import stem.descriptor.certificate import stem.prereq import test.runner
-from stem.descriptor.certificate import ED25519_SIGNATURE_LENGTH, CertType, Ed25519Certificate, Ed25519CertificateV1, Ed25519Extension +from stem.descriptor.certificate import ED25519_SIGNATURE_LENGTH, CertType, ExtensionFlag, Ed25519Certificate, Ed25519CertificateV1, Ed25519Extension
ED25519_CERT = """ AQQABhtZAaW2GoBED1IjY3A6f6GNqBEl5A83fD2Za9upGke51JGqAQAgBABnprVR @@ -41,7 +41,7 @@ class TestEd25519Certificate(unittest.TestCase): self.assertRaisesRegexp(ValueError, re.escape(exc_msg), Ed25519Certificate.parse, parse_arg)
def test_basic_parsing(self): - cert_bytes = certificate(extension_data = [b'\x00\x02\x04\x07\x15\x12', b'\x00\x00\x05\x03']) + cert_bytes = certificate(extension_data = [b'\x00\x02\x04\x07\x15\x12', b'\x00\x00\x05\x04']) cert = Ed25519Certificate.parse(cert_bytes)
self.assertEqual(Ed25519CertificateV1, type(cert)) @@ -54,8 +54,8 @@ class TestEd25519Certificate(unittest.TestCase): self.assertEqual(b'\x01' * ED25519_SIGNATURE_LENGTH, cert.signature)
self.assertEqual([ - Ed25519Extension(extension_type = 4, flags = 7, data = b'\x15\x12'), - Ed25519Extension(extension_type = 5, flags = 3, data = b''), + Ed25519Extension(extension_type = 4, flags = [ExtensionFlag.AFFECTS_VALIDATION, ExtensionFlag.UNKNOWN], flag_int = 7, data = b'\x15\x12'), + Ed25519Extension(extension_type = 5, flags = [ExtensionFlag.UNKNOWN], flag_int = 4, data = b''), ], cert.extensions)
def test_with_real_cert(self): @@ -68,7 +68,7 @@ class TestEd25519Certificate(unittest.TestCase): self.assertEqual(datetime.datetime(2015, 8, 28, 19, 0), cert.expiration) self.assertEqual(1, cert.key_type) self.assertEqual(EXPECTED_CERT_KEY, cert.key) - self.assertEqual([Ed25519Extension(extension_type = 4, flags = 0, data = EXPECTED_EXTENSION_DATA)], cert.extensions) + self.assertEqual([Ed25519Extension(extension_type = 4, flags = [], flag_int = 0, data = EXPECTED_EXTENSION_DATA)], cert.extensions) self.assertEqual(EXPECTED_SIGNATURE, cert.signature)
def test_non_base64(self):
tor-commits@lists.torproject.org