commit 80f4934183a0037926f11e18b54eda09bacb012c
Author: Damian Johnson <[email protected]>
Date: Wed Oct 2 15:59:10 2019 -0700
Parse signing_cert as an ed25519 certificate
I was mistaken to parse signing_cert as a key blob. Server descriptors are
deprecating their key blob copy (the 'ed25519_certificate' attribute) in
favor
of a Ed25519Certificate instance, and hidden service descriptors should do
the
same.
Hidden service v3 parsing isn't yet in a release so we can simply fix this
in
place without concern for backward compatibility.
---
stem/descriptor/certificate.py | 15 +++++++++++++++
stem/descriptor/hidden_service.py | 14 +++++++-------
stem/descriptor/server_descriptor.py | 2 ++
test/unit/descriptor/hidden_service_v3.py | 2 +-
4 files changed, 25 insertions(+), 8 deletions(-)
diff --git a/stem/descriptor/certificate.py b/stem/descriptor/certificate.py
index 4a78fa3f..e336bbda 100644
--- a/stem/descriptor/certificate.py
+++ b/stem/descriptor/certificate.py
@@ -152,6 +152,21 @@ class Ed25519Certificate(object):
else:
raise ValueError('Ed25519 certificate is version %i. Parser presently
only supports version 1.' % version)
+ @staticmethod
+ def _from_descriptor(keyword, attribute):
+ def _parse(descriptor, entries):
+ value, block_type, block_contents = entries[keyword][0]
+
+ if not block_contents or block_type != 'ED25519 CERT':
+ raise ValueError("'%s' should be followed by a ED25519 CERT block, but
was a %s" % (keyword, block_type))
+
+ setattr(descriptor, attribute, Ed25519Certificate.parse(block_contents))
+
+ return _parse
+
+ def __str__(self):
+ return '-----BEGIN ED25519 CERT-----\n%s\n-----END ED25519 CERT-----' %
self.encoded
+
class Ed25519CertificateV1(Ed25519Certificate):
"""
diff --git a/stem/descriptor/hidden_service.py
b/stem/descriptor/hidden_service.py
index 2ca9f4bf..bf11c685 100644
--- a/stem/descriptor/hidden_service.py
+++ b/stem/descriptor/hidden_service.py
@@ -31,13 +31,14 @@ import collections
import hashlib
import io
-import stem.descriptor.certificate
import stem.descriptor.hsv3_crypto
import stem.prereq
import stem.util.connection
import stem.util.str_tools
import stem.util.tor_tools
+from stem.descriptor.certificate import Ed25519Certificate
+
from stem.descriptor import (
PGP_BLOCK_END,
Descriptor,
@@ -199,7 +200,7 @@ _parse_v2_signature_line = _parse_key_block('signature',
'signature', 'SIGNATURE
_parse_v3_version_line = _parse_int_line('hs-descriptor', 'version',
allow_negative = False)
_parse_lifetime_line = _parse_int_line('descriptor-lifetime', 'lifetime',
allow_negative = False)
-_parse_signing_key_line = _parse_key_block('descriptor-signing-key-cert',
'signing_cert', 'ED25519 CERT')
+_parse_signing_cert =
Ed25519Certificate._from_descriptor('descriptor-signing-key-cert',
'signing_cert')
_parse_revision_counter_line = _parse_int_line('revision-counter',
'revision_counter', allow_negative = False)
_parse_superencrypted_line = _parse_key_block('superencrypted',
'superencrypted', 'MESSAGE')
_parse_v3_signature_line = _parse_simple_line('signature', 'signature')
@@ -481,7 +482,7 @@ class
HiddenServiceDescriptorV3(BaseHiddenServiceDescriptor):
:var int version: **\\*** hidden service descriptor version
:var int lifetime: **\\*** minutes after publication this descriptor is valid
- :var str signing_cert: **\\*** cross-certifier for the short-term descriptor
signing key
+ :var stem.certificate.Ed25519Certificate signing_cert: **\\***
cross-certifier for the short-term descriptor signing key
:var int revision_counter: **\\*** descriptor revision number
:var str superencrypted: **\\*** encrypted HS-DESC-ENC payload
:var str signature: **\\*** signature of this descriptor
@@ -497,7 +498,7 @@ class
HiddenServiceDescriptorV3(BaseHiddenServiceDescriptor):
ATTRIBUTES = {
'version': (None, _parse_v3_version_line),
'lifetime': (None, _parse_lifetime_line),
- 'signing_cert': (None, _parse_signing_key_line),
+ 'signing_cert': (None, _parse_signing_cert),
'revision_counter': (None, _parse_revision_counter_line),
'superencrypted': (None, _parse_superencrypted_line),
'signature': (None, _parse_v3_signature_line),
@@ -506,7 +507,7 @@ class
HiddenServiceDescriptorV3(BaseHiddenServiceDescriptor):
PARSER_FOR_LINE = {
'hs-descriptor': _parse_v3_version_line,
'descriptor-lifetime': _parse_lifetime_line,
- 'descriptor-signing-key-cert': _parse_signing_key_line,
+ 'descriptor-signing-key-cert': _parse_signing_cert,
'revision-counter': _parse_revision_counter_line,
'superencrypted': _parse_superencrypted_line,
'signature': _parse_v3_signature_line,
@@ -560,8 +561,7 @@ 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/)')
- cert =
stem.descriptor.certificate.Ed25519Certificate.parse(self.signing_cert)
- blinded_key = cert.signing_key()
+ blinded_key = self.signing_cert.signing_key()
if not blinded_key:
raise ValueError('No signing key extension present')
diff --git a/stem/descriptor/server_descriptor.py
b/stem/descriptor/server_descriptor.py
index 71f3a803..ebadcde2 100644
--- a/stem/descriptor/server_descriptor.py
+++ b/stem/descriptor/server_descriptor.py
@@ -401,6 +401,8 @@ def _parse_exit_policy(descriptor, entries):
def _parse_identity_ed25519_line(descriptor, entries):
+ # TODO: replace this with Ed25519Certificate._from_descriptor() in stem 2.x
+
_parse_key_block('identity-ed25519', 'ed25519_certificate', 'ED25519
CERT')(descriptor, entries)
if descriptor.ed25519_certificate:
diff --git a/test/unit/descriptor/hidden_service_v3.py
b/test/unit/descriptor/hidden_service_v3.py
index 2242d617..3824c8a6 100644
--- a/test/unit/descriptor/hidden_service_v3.py
+++ b/test/unit/descriptor/hidden_service_v3.py
@@ -46,7 +46,7 @@ class TestHiddenServiceDescriptorV3(unittest.TestCase):
self.assertEqual(3, desc.version)
self.assertEqual(180, desc.lifetime)
- self.assertEqual(EXPECTED_SIGNING_CERT, desc.signing_cert)
+ self.assertEqual(EXPECTED_SIGNING_CERT, str(desc.signing_cert))
self.assertEqual(42, desc.revision_counter)
self.assertTrue('eaH8VdaTKS' in desc.superencrypted)
self.assertEqual('aglChCQF+lbzKgyxJJTpYGVShV/GMDRJ4+cRGCp+a2y/yX/tLSh7hzqI7rVZrUoGj74Xr1CLMYO3fXYCS+DPDQ',
desc.signature)
_______________________________________________
tor-commits mailing list
[email protected]
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits