commit ba120539ed9d333c85a765156bb80c1336a19f21 Author: Damian Johnson atagar@torproject.org Date: Mon Feb 27 12:11:09 2017 -0800
Only import nacl module if it's available
Having a top level import like this puts a strict dependency on nacl. Nobody can use any part of stem without it.
Narrowing this dependency to just the new additions. Also fixing our OrderedDict import so we continue to work with python 2.6. Support for python 2.6 won't be dropped until stem 2.x. --- stem/descriptor/__init__.py | 1 + stem/descriptor/certificate.py | 34 ++++++++++++++++++++++++---------- test/unit/descriptor/certificate.py | 13 +++++++++---- 3 files changed, 34 insertions(+), 14 deletions(-)
diff --git a/stem/descriptor/__init__.py b/stem/descriptor/__init__.py index 4e90889..97e7699 100644 --- a/stem/descriptor/__init__.py +++ b/stem/descriptor/__init__.py @@ -646,6 +646,7 @@ class Descriptor(object):
:returns: the digest string encoded in uppercase hex """ + digest_hash = hashlib.sha1(bytes_to_sign) return stem.util.str_tools._to_unicode(digest_hash.hexdigest().upper())
diff --git a/stem/descriptor/certificate.py b/stem/descriptor/certificate.py index 0c3b2b6..03b3781 100644 --- a/stem/descriptor/certificate.py +++ b/stem/descriptor/certificate.py @@ -5,32 +5,34 @@ Parsing for the Tor server descriptor Ed25519 Certificates, which is used to validate the Ed25519 key used to sign the relay descriptor.
-Certificates can optionally contain CertificateExtension objects depending on their type and purpose. Currently Ed25519KeyCertificate certificates will contain one SignedWithEd25519KeyCertificateExtension - +Certificates can optionally contain CertificateExtension objects depending on +their type and purpose. Currently Ed25519KeyCertificate certificates will +contain one SignedWithEd25519KeyCertificateExtension.
**Module Overview:**
::
Certificate - Tor Certificate - |- Ed25519KeyCertificate - Certificate for Ed25519 signing key - +- +- verify_descriptor_signature - verify a relay descriptor against a signature - + +- Ed25519KeyCertificate - Certificate for Ed25519 signing key + +- verify_descriptor_signature - verify a relay descriptor against a signature
CertificateExtension - Certificate extension - +- - SignedWithEd25519KeyCertificateExtension - Ed25519 signing key extension + +- SignedWithEd25519KeyCertificateExtension - Ed25519 signing key extension """
import base64 import hashlib import time -from collections import OrderedDict
+import stem.prereq import stem.util.str_tools
-import nacl.signing -from nacl.exceptions import BadSignatureError - +try: + # added in python 2.7 + from collections import OrderedDict +except ImportError: + from stem.util.ordereddict import OrderedDict
SIGNATURE_LENGTH = 64 STANDARD_ATTRIBUTES_LENGTH = 40 @@ -155,6 +157,12 @@ class Ed25519KeyCertificate(Certificate): raise ValueError('Expired Ed25519KeyCertificate')
def verify_descriptor_signature(self, descriptor, signature): + if not stem.prereq.is_nacl_available(): + raise ValueError('Certificate validation requires the nacl module') + + import nacl.signing + from nacl.exceptions import BadSignatureError + missing_padding = len(signature) % 4 signature_bytes = base64.b64decode(stem.util.str_tools._to_bytes(signature) + b'=' * missing_padding) verify_key = nacl.signing.VerifyKey(self.certified_key) @@ -169,6 +177,12 @@ class Ed25519KeyCertificate(Certificate): raise ValueError('Descriptor Ed25519 certificate signature invalid')
def _verify_signature(self): + if not stem.prereq.is_nacl_available(): + raise ValueError('Certificate validation requires the nacl module') + + import nacl.signing + from nacl.exceptions import BadSignatureError + if self.identity_key: verify_key = nacl.signing.VerifyKey(base64.b64decode(self.identity_key + '=')) else: diff --git a/test/unit/descriptor/certificate.py b/test/unit/descriptor/certificate.py index 450685f..24a5a7e 100644 --- a/test/unit/descriptor/certificate.py +++ b/test/unit/descriptor/certificate.py @@ -5,13 +5,11 @@ Unit tests for stem.descriptor.certificate. import unittest
import stem.descriptor.certificate - -import nacl.signing -import nacl.encoding +import stem.prereq +import test.runner
class TestCertificate(unittest.TestCase): - def test_with_invalid_version(self): cert_bytes = '\x02\x04' self.assertRaisesRegexp( @@ -89,6 +87,13 @@ class TestCertificate(unittest.TestCase): )
def test_certificate_with_invalid_signature(self): + if not stem.prereq.is_nacl_available(): + test.runner.skip(self, '(require nacl module)') + return + + import nacl.signing + import nacl.encoding + master_key = nacl.signing.SigningKey.generate() master_key_base64 = master_key.encode(nacl.encoding.Base64Encoder)