[stem/master] Certificate signing_key() helper
commit 287a27dc99bb6f5caa91964d0e307c123d1662d5 Author: Damian Johnson <atagar@torproject.org> Date: Wed Oct 2 15:03:14 2019 -0700 Certificate signing_key() helper Ok, I've kept going back and forth on this but definitely cleaner for callers. --- stem/descriptor/certificate.py | 30 +++++++++++++++++++++--------- stem/descriptor/hidden_service.py | 10 ++-------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/stem/descriptor/certificate.py b/stem/descriptor/certificate.py index 01238182..4a78fa3f 100644 --- a/stem/descriptor/certificate.py +++ b/stem/descriptor/certificate.py @@ -247,6 +247,22 @@ class Ed25519CertificateV1(Ed25519Certificate): return datetime.datetime.now() > self.expiration + def signing_key(self): + """ + Provides this certificate's signing key. + + .. versionadded:: 1.8.0 + + :returns: **bytes** with the first signing key on the certificate, None if + not present + """ + + for extension in self.extensions: + if extension.type == ExtensionType.HAS_SIGNING_KEY: + return extension.data + + return None + def validate(self, descriptor): """ Validates our signing key and that the given descriptor content matches its @@ -271,27 +287,23 @@ class Ed25519CertificateV1(Ed25519Certificate): if not isinstance(descriptor, stem.descriptor.server_descriptor.RelayDescriptor): raise ValueError('Certificate validation only supported for server descriptors, not %s' % type(descriptor).__name__) - descriptor_content = descriptor.get_bytes() - signing_key = None - if descriptor.ed25519_master_key: - signing_key = Ed25519PublicKey.from_public_bytes(base64.b64decode(stem.util.str_tools._to_bytes(descriptor.ed25519_master_key) + b'=')) + signing_key = base64.b64decode(stem.util.str_tools._to_bytes(descriptor.ed25519_master_key) + b'=') else: - for extension in self.extensions: - if extension.type == ExtensionType.HAS_SIGNING_KEY: - signing_key = Ed25519PublicKey.from_public_bytes(extension.data) - break + signing_key = self.signing_key() if not signing_key: raise ValueError('Server descriptor missing an ed25519 signing key') try: - signing_key.verify(self.signature, base64.b64decode(stem.util.str_tools._to_bytes(self.encoded))[:-ED25519_SIGNATURE_LENGTH]) + Ed25519PublicKey.from_public_bytes(signing_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 was forged or corrupt)') # ed25519 signature validates descriptor content up until the signature itself + descriptor_content = descriptor.get_bytes() + if b'router-sig-ed25519 ' not in descriptor_content: raise ValueError("Descriptor doesn't have a router-sig-ed25519 entry.") diff --git a/stem/descriptor/hidden_service.py b/stem/descriptor/hidden_service.py index dc282202..2ca9f4bf 100644 --- a/stem/descriptor/hidden_service.py +++ b/stem/descriptor/hidden_service.py @@ -54,8 +54,6 @@ from stem.descriptor import ( _random_crypto_blob, ) -from stem.descriptor.certificate import ExtensionType - if stem.prereq._is_lru_cache_available(): from functools import lru_cache else: @@ -562,12 +560,8 @@ 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/)') - desc_signing_cert = stem.descriptor.certificate.Ed25519Certificate.parse(self.signing_cert) - - for extension in desc_signing_cert.extensions: - if extension.type == ExtensionType.HAS_SIGNING_KEY: - blinded_key = extension.data - break + cert = stem.descriptor.certificate.Ed25519Certificate.parse(self.signing_cert) + blinded_key = cert.signing_key() if not blinded_key: raise ValueError('No signing key extension present')
participants (1)
-
atagar@torproject.org