[tor-commits] [stem/master] Drop undocumented 'encoded' attribute from certificates
atagar at torproject.org
atagar at torproject.org
Tue Feb 18 07:57:23 UTC 2020
commit 657b8acf95c83ec3836039bf1844d9e55c607956
Author: Damian Johnson <atagar at torproject.org>
Date: Mon Feb 17 16:42:27 2020 -0800
Drop undocumented 'encoded' attribute from certificates
When an Ed25519Certificate was created through from_base64() we appended an
undocumented 'encoded' attribute with the base64 content we were created from.
Our to_base64() method computes the exact same thing.
This attribute was only used in a single place for server descriptor
validation.
If 'encoded' and to_base64() mismatches that is a bug. Fiddling with these I
cound't come up with a scenario where that is a case, so dropping the redundant
attribute.
Also merging _validate_server_desc_signing_key() into its sole caller.
---
stem/descriptor/certificate.py | 44 +++++++++++++------------------
test/unit/descriptor/certificate.py | 7 +++--
test/unit/descriptor/server_descriptor.py | 2 +-
3 files changed, 23 insertions(+), 30 deletions(-)
diff --git a/stem/descriptor/certificate.py b/stem/descriptor/certificate.py
index d7c0743d..ae2d6636 100644
--- a/stem/descriptor/certificate.py
+++ b/stem/descriptor/certificate.py
@@ -6,8 +6,8 @@ Parsing for `Tor Ed25519 certificates
<https://gitweb.torproject.org/torspec.git/tree/cert-spec.txt>`_, which are
used to for a variety of purposes...
- * validating the key used to sign server descriptors
- * validating the key used to sign hidden service v3 descriptors
+ * validate the signing key of server descriptors
+ * validate the signing key of hidden service v3 descriptors
* signing and encrypting hidden service v3 indroductory points
.. versionadded:: 1.6.0
@@ -185,9 +185,7 @@ class Ed25519Certificate(object):
if not decoded:
raise TypeError('empty')
- instance = Ed25519Certificate.unpack(decoded)
- instance.encoded = content
- return instance
+ return Ed25519Certificate.unpack(decoded)
except (TypeError, binascii.Error) as exc:
raise ValueError("Ed25519 certificate wasn't propoerly base64 encoded (%s):\n%s" % (exc, content))
@@ -236,7 +234,7 @@ class Ed25519Certificate(object):
class Ed25519CertificateV1(Ed25519Certificate):
"""
- Version 1 Ed25519 certificate, which are used for signing tor server
+ Version 1 Ed25519 certificate, which sign tor server and hidden service v3
descriptors.
:var stem.client.datatype.CertType type: certificate purpose
@@ -381,7 +379,21 @@ class Ed25519CertificateV1(Ed25519Certificate):
signed_content = hashlib.sha256(Ed25519CertificateV1._signed_content(descriptor)).digest()
signature = stem.util.str_tools._decode_b64(descriptor.ed25519_signature)
- self._validate_server_desc_signing_key(descriptor)
+ # verify that we're created from this descriptor's signing key
+
+ if descriptor.ed25519_master_key:
+ signing_key = base64.b64decode(stem.util.str_tools._to_bytes(descriptor.ed25519_master_key) + b'=')
+ else:
+ signing_key = self.signing_key()
+
+ if not signing_key:
+ raise ValueError('Server descriptor missing an ed25519 signing key')
+
+ try:
+ key = Ed25519PublicKey.from_public_bytes(signing_key)
+ key.verify(self.signature, base64.b64decode(stem.util.str_tools._to_bytes(self.to_base64()))[:-ED25519_SIGNATURE_LENGTH])
+ except InvalidSignature:
+ raise ValueError('Ed25519KeyCertificate signing key is invalid (signature forged or corrupt)')
elif isinstance(descriptor, stem.descriptor.hidden_service.HiddenServiceDescriptorV3):
signed_content = Ed25519CertificateV1._signed_content(descriptor)
signature = stem.util.str_tools._decode_b64(descriptor.signature)
@@ -418,21 +430,3 @@ class Ed25519CertificateV1(Ed25519Certificate):
raise ValueError('Malformed descriptor missing signature line')
return prefix + match.group(1)
-
- def _validate_server_desc_signing_key(self, descriptor):
- from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
- from cryptography.exceptions import InvalidSignature
-
- if descriptor.ed25519_master_key:
- signing_key = base64.b64decode(stem.util.str_tools._to_bytes(descriptor.ed25519_master_key) + b'=')
- else:
- signing_key = self.signing_key()
-
- if not signing_key:
- raise ValueError('Server descriptor missing an ed25519 signing key')
-
- try:
- key = Ed25519PublicKey.from_public_bytes(signing_key)
- key.verify(self.signature, base64.b64decode(stem.util.str_tools._to_bytes(self.encoded))[:-ED25519_SIGNATURE_LENGTH])
- except InvalidSignature:
- raise ValueError('Ed25519KeyCertificate signing key is invalid (signature forged or corrupt)')
diff --git a/test/unit/descriptor/certificate.py b/test/unit/descriptor/certificate.py
index 9e29556a..000de2de 100644
--- a/test/unit/descriptor/certificate.py
+++ b/test/unit/descriptor/certificate.py
@@ -58,7 +58,7 @@ class TestEd25519Certificate(unittest.TestCase):
self.assertEqual(Ed25519CertificateV1, type(cert))
self.assertEqual(1, cert.version)
- self.assertEqual(stem.util.str_tools._to_unicode(cert_bytes), cert.encoded)
+ self.assertEqual(stem.util.str_tools._to_unicode(cert_bytes), cert.to_base64().replace('\n', ''))
self.assertEqual(CertType.ED25519_SIGNING, cert.type)
self.assertEqual(datetime.datetime(1970, 1, 1, 0, 0), cert.expiration)
self.assertEqual(1, cert.key_type)
@@ -82,7 +82,7 @@ class TestEd25519Certificate(unittest.TestCase):
self.assertEqual(Ed25519CertificateV1, type(cert))
self.assertEqual(1, cert.version)
- self.assertEqual(ED25519_CERT, cert.encoded)
+ self.assertEqual(ED25519_CERT, cert.to_base64())
self.assertEqual(CertType.ED25519_SIGNING, cert.type)
self.assertEqual(datetime.datetime(2015, 8, 28, 17, 0), cert.expiration)
self.assertEqual(1, cert.key_type)
@@ -109,8 +109,7 @@ class TestEd25519Certificate(unittest.TestCase):
"""
cert = Ed25519Certificate.from_base64(ED25519_CERT)
- self.assertEqual(ED25519_CERT, cert.encoded) # read base64 encoding (getting removed in stem 2.x)
- self.assertEqual(ED25519_CERT, cert.to_base64()) # computed base64 encoding
+ self.assertEqual(ED25519_CERT, cert.to_base64())
def test_non_base64(self):
"""
diff --git a/test/unit/descriptor/server_descriptor.py b/test/unit/descriptor/server_descriptor.py
index e1036ada..07f50013 100644
--- a/test/unit/descriptor/server_descriptor.py
+++ b/test/unit/descriptor/server_descriptor.py
@@ -355,7 +355,7 @@ Qlx9HNCqCY877ztFRC624ja2ql6A2hBcuoYMbkHjcQ4=
self.assertTrue(desc.certificate.key.startswith(b'\xa5\xb6\x1a\x80D\x0f'))
self.assertTrue(desc.certificate.signature.startswith(b'\xc6\x8e\xd3\xae\x0b'))
self.assertEqual(1, len(desc.certificate.extensions))
- self.assertTrue('bWPo2fIzo3uOywfoM' in desc.certificate.encoded)
+ self.assertTrue('bWPo2fIzo3uOywfoM' in desc.certificate.to_base64())
extension = desc.certificate.extensions[0]
self.assertEqual(ExtensionType.HAS_SIGNING_KEY, extension.type)
More information about the tor-commits
mailing list