[tor-commits] [stem/master] Fix python 3.x support
atagar at torproject.org
atagar at torproject.org
Sun Nov 17 23:40:39 UTC 2019
commit 8530ad6f5386c8dd1112a9e071f60aa002d14566
Author: Damian Johnson <atagar at torproject.org>
Date: Thu Nov 14 14:19:40 2019 -0800
Fix python 3.x support
This might *not* fully fix python3 support, but closer. I don't quite grok why
but my openssl bindings have ed25519 support with python 2.7 but not 3.5. Oh
well, fixing what I can for now.
% python
Python 2.7.12 (default, Oct 8 2019, 14:14:10)
>>> import cryptography
>>> cryptography.__version__
'2.7'
>>> from cryptography.hazmat.backends.openssl.backend import backend
>>> backend.ed25519_supported()
True
------------------------------------------------------------
% python3
Python 3.5.2 (default, Oct 8 2019, 13:06:37)
>>> import cryptography
>>> cryptography.__version__
'2.8'
>>> from cryptography.hazmat.backends.openssl.backend import backend
>>> backend.ed25519_supported()
False
---
stem/descriptor/certificate.py | 10 ++++------
stem/descriptor/hidden_service.py | 7 ++++---
stem/util/__init__.py | 7 ++++---
test/unit/descriptor/hidden_service_v3.py | 9 +++++++--
4 files changed, 19 insertions(+), 14 deletions(-)
diff --git a/stem/descriptor/certificate.py b/stem/descriptor/certificate.py
index 10518364..74a4e08c 100644
--- a/stem/descriptor/certificate.py
+++ b/stem/descriptor/certificate.py
@@ -307,7 +307,7 @@ class Ed25519CertificateV1(Ed25519Certificate):
self.type, self.type_int = ClientCertType.get(cert_type)
self.expiration = expiration if expiration else datetime.datetime.utcnow() + datetime.timedelta(hours = DEFAULT_EXPIRATION_HOURS)
self.key_type = key_type if key_type else 1
- self.key = key if isinstance(key, str) else stem.util._pubkey_bytes(key)
+ self.key = stem.util._pubkey_bytes(key)
self.extensions = extensions if extensions else []
self.signature = signature
@@ -371,9 +371,7 @@ class Ed25519CertificateV1(Ed25519Certificate):
if extension_data:
raise ValueError('Ed25519 certificate had %i bytes of unused extension data' % len(extension_data))
- instance = Ed25519CertificateV1(cert_type, datetime.datetime.utcfromtimestamp(expiration_hours * 3600), key_type, key, extensions, signature)
-
- return instance
+ return Ed25519CertificateV1(cert_type, datetime.datetime.utcfromtimestamp(expiration_hours * 3600), key_type, key, extensions, signature)
def is_expired(self):
"""
@@ -448,10 +446,10 @@ class Ed25519CertificateV1(Ed25519Certificate):
if isinstance(descriptor, stem.descriptor.server_descriptor.RelayDescriptor):
prefix = SIG_PREFIX_SERVER_DESC
- regex = '(.+router-sig-ed25519 )'
+ regex = b'(.+router-sig-ed25519 )'
elif isinstance(descriptor, stem.descriptor.hidden_service.HiddenServiceDescriptorV3):
prefix = SIG_PREFIX_HS_V3
- regex = '(.+)signature '
+ regex = b'(.+)signature '
else:
raise ValueError('BUG: %s type unexpected' % type(descriptor).__name__)
diff --git a/stem/descriptor/hidden_service.py b/stem/descriptor/hidden_service.py
index 604c3849..dd4ab934 100644
--- a/stem/descriptor/hidden_service.py
+++ b/stem/descriptor/hidden_service.py
@@ -563,7 +563,7 @@ def _parse_v3_introduction_points(descriptor, entries):
remaining = descriptor._unparsed_introduction_points
while remaining:
- div = remaining.find('\nintroduction-point ', 10)
+ div = remaining.find(b'\nintroduction-point ', 10)
content, remaining = (remaining[:div], remaining[div + 1:]) if div != -1 else (remaining, '')
introduction_points.append(IntroductionPointV3.parse(content))
@@ -1257,7 +1257,7 @@ class InnerLayer(Descriptor):
return _descriptor_content(attr, exclude, (
('create2-formats', '2'),
- )) + suffix
+ )) + stem.util.str_tools._to_bytes(suffix)
@classmethod
def create(cls, attr = None, exclude = (), validate = True, sign = False, introduction_points = None):
@@ -1270,7 +1270,8 @@ class InnerLayer(Descriptor):
# inner layer begins with a few header fields, followed by any
# number of introduction-points
- div = content.find('\nintroduction-point ')
+ content = stem.util.str_tools._to_bytes(content)
+ div = content.find(b'\nintroduction-point ')
if div != -1:
self._unparsed_introduction_points = content[div + 1:]
diff --git a/stem/util/__init__.py b/stem/util/__init__.py
index a8870499..eb4e0618 100644
--- a/stem/util/__init__.py
+++ b/stem/util/__init__.py
@@ -132,6 +132,9 @@ def _pubkey_bytes(key):
Normalizes X25509 and ED25519 keys into their public key bytes.
"""
+ if _is_str(key):
+ return key
+
if not stem.prereq.is_crypto_available():
raise ImportError('Key normalization requires the cryptography module')
elif not stem.prereq.is_crypto_available(ed25519 = True):
@@ -141,9 +144,7 @@ def _pubkey_bytes(key):
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey, Ed25519PublicKey
from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey, X25519PublicKey
- if isinstance(key, str):
- return key
- elif isinstance(key, (X25519PrivateKey, Ed25519PrivateKey)):
+ if isinstance(key, (X25519PrivateKey, Ed25519PrivateKey)):
return key.public_key().public_bytes(
encoding = serialization.Encoding.Raw,
format = serialization.PublicFormat.Raw,
diff --git a/test/unit/descriptor/hidden_service_v3.py b/test/unit/descriptor/hidden_service_v3.py
index 81e04a0f..893ef29e 100644
--- a/test/unit/descriptor/hidden_service_v3.py
+++ b/test/unit/descriptor/hidden_service_v3.py
@@ -162,6 +162,7 @@ class TestHiddenServiceDescriptorV3(unittest.TestCase):
self.assertEqual(None, intro_point.legacy_key_raw)
self.assertEqual(None, intro_point.legacy_key_cert)
+ @test.require.ed25519_support
def test_required_fields(self):
"""
Check that we require the mandatory fields.
@@ -180,6 +181,7 @@ class TestHiddenServiceDescriptorV3(unittest.TestCase):
desc_text = HiddenServiceDescriptorV3.content(exclude = (line,))
expect_invalid_attr_for_text(self, desc_text, line_to_attr[line], None)
+ @test.require.ed25519_support
def test_invalid_version(self):
"""
Checks that our version field expects a numeric value.
@@ -194,6 +196,7 @@ class TestHiddenServiceDescriptorV3(unittest.TestCase):
for test_value in test_values:
expect_invalid_attr(self, {'hs-descriptor': test_value}, 'version')
+ @test.require.ed25519_support
def test_invalid_lifetime(self):
"""
Checks that our lifetime field expects a numeric value.
@@ -208,6 +211,7 @@ class TestHiddenServiceDescriptorV3(unittest.TestCase):
for test_value in test_values:
expect_invalid_attr(self, {'descriptor-lifetime': test_value}, 'lifetime')
+ @test.require.ed25519_support
def test_invalid_revision_counter(self):
"""
Checks that our revision counter field expects a numeric value.
@@ -302,6 +306,7 @@ class TestHiddenServiceDescriptorV3(unittest.TestCase):
reparsed = IntroductionPointV3.parse(intro_point.encode())
self.assertEqual(intro_point, reparsed)
+ @test.require.ed25519_support
def test_inner_layer_creation(self):
"""
Internal layer creation.
@@ -309,12 +314,12 @@ class TestHiddenServiceDescriptorV3(unittest.TestCase):
# minimal layer
- self.assertEqual('create2-formats 2', InnerLayer.content())
+ self.assertEqual(b'create2-formats 2', InnerLayer.content())
self.assertEqual([2], InnerLayer.create().formats)
# specify their only mandatory parameter (formats)
- self.assertEqual('create2-formats 1 2 3', InnerLayer.content({'create2-formats': '1 2 3'}))
+ self.assertEqual(b'create2-formats 1 2 3', InnerLayer.content({'create2-formats': '1 2 3'}))
self.assertEqual([1, 2, 3], InnerLayer.create({'create2-formats': '1 2 3'}).formats)
# include optional parameters
More information about the tor-commits
mailing list