[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [stem/master] Adjust extended v3 HS address validation
commit 63a476056017dda5ede35efc4e4f7acfcc1d7d1a
Author: Damian Johnson <atagar@xxxxxxxxxxxxxx>
Date: Tue Feb 9 16:12:36 2021 -0800
Adjust extended v3 HS address validation
Mostly minor stylistic adjustments. The only functional bit is correcting a
unit test failure...
======================================================================
FAIL: test_identity_key_from_address
----------------------------------------------------------------------
ValueError: '55555555555555555555555555555555555555555555555555555555.onion' isn't a valid hidden service v3 address
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/atagar/Desktop/stem/test/unit/descriptor/hidden_service_v3.py", line 220, in test_identity_key_from_address
self.assertRaisesWith(ValueError, 'Bad checksum (expected def7 but was 842e)', HiddenServiceDescriptorV3.identity_key_from_address, '5' * 56)
File "/home/atagar/Desktop/stem/stem/util/test_tools.py", line 249, in assertRaisesWith
return self.assertRaisesRegexp(exc_type, '^%s$' % re.escape(exc_msg), *args, **kwargs)
AssertionError: "^Bad\ checksum\ \(expected\ def7\ but\ was\ 842e\)$" does not match "'55555555555555555555555555555555555555555555555555555555.onion' isn't a valid hidden service v3 address"
----------------------------------------------------------------------
---
stem/descriptor/hidden_service.py | 2 +-
stem/util/tor_tools.py | 35 +++++++++++++----------------
test/unit/util/tor_tools.py | 46 ++++++++++++++++++---------------------
3 files changed, 37 insertions(+), 46 deletions(-)
diff --git a/stem/descriptor/hidden_service.py b/stem/descriptor/hidden_service.py
index 63f107e7..249c2153 100644
--- a/stem/descriptor/hidden_service.py
+++ b/stem/descriptor/hidden_service.py
@@ -1129,7 +1129,7 @@ class HiddenServiceDescriptorV3(HiddenServiceDescriptor):
if onion_address.endswith('.onion'):
onion_address = onion_address[:-6]
- if not stem.util.tor_tools.is_valid_hidden_service_address(onion_address, version = 3):
+ if not stem.util.tor_tools.HS_V3_ADDRESS_PATTERN.match(onion_address):
raise ValueError("'%s.onion' isn't a valid hidden service v3 address" % onion_address)
# onion_address = base32(PUBKEY | CHECKSUM | VERSION) + '.onion'
diff --git a/stem/util/tor_tools.py b/stem/util/tor_tools.py
index c9a04e33..e758b897 100644
--- a/stem/util/tor_tools.py
+++ b/stem/util/tor_tools.py
@@ -19,9 +19,9 @@ Miscellaneous utility functions for working with tor.
is_hex_digits - checks if a string is only made up of hex digits
"""
+import base64
+import hashlib
import re
-from base64 import b32decode
-from hashlib import sha3_256
import stem.util.str_tools
@@ -47,7 +47,6 @@ CIRC_ID_PATTERN = re.compile('^[a-zA-Z0-9]{1,16}$')
HS_V2_ADDRESS_PATTERN = re.compile('^[a-z2-7]{16}$')
HS_V3_ADDRESS_PATTERN = re.compile('^[a-z2-7]{56}$')
-HS_V3_CHECKSUM_CONSTANT = ".onion checksum"
def is_valid_fingerprint(entry: str, check_prefix: bool = False) -> bool:
@@ -156,14 +155,6 @@ def is_valid_hidden_service_address(entry: str, version: Optional[Union[int, Seq
otherwise
"""
- def _extract_v3_parts(address):
- decoded = b32decode(address.upper())
- return (decoded[:32], decoded[32:34])
-
- v3_pubkey = None
- v3_checksum = None
- v3_version = int(3).to_bytes(1, 'little')
-
if isinstance(entry, bytes):
entry = stem.util.str_tools._to_unicode(entry)
@@ -179,15 +170,19 @@ def is_valid_hidden_service_address(entry: str, version: Optional[Union[int, Seq
return True
if 3 in version and bool(HS_V3_ADDRESS_PATTERN.match(entry)):
- # v3+ onions have a consistent version at end of address
- if not entry.endswith('d'):
- return False
- # Test that the checksum (part of every v3 address) is valid
- v3_pubkey, v3_checksum = _extract_v3_parts(entry)
- expected_checksum = sha3_256(HS_V3_CHECKSUM_CONSTANT.encode('utf-8') + v3_pubkey + v3_version).digest()[:2]
- if expected_checksum != v3_checksum:
- return False
- return True
+ # onion_address = base32(PUBKEY | CHECKSUM | VERSION) + ".onion"
+
+ decoded = base64.b32decode(entry.upper())
+ pubkey, checksum, addr_version = decoded[:32], decoded[32:34], decoded[34:]
+
+ if addr_version != b'\x03':
+ return False # VERSION component must be three
+
+ # CHECKSUM = H(".onion checksum" | PUBKEY | VERSION)[:2]
+
+ expected_checksum = hashlib.sha3_256(b'.onion checksum' + pubkey + addr_version).digest()[:2]
+
+ return checksum == expected_checksum
return False
except TypeError:
diff --git a/test/unit/util/tor_tools.py b/test/unit/util/tor_tools.py
index 285b4dde..06707390 100644
--- a/test/unit/util/tor_tools.py
+++ b/test/unit/util/tor_tools.py
@@ -3,66 +3,62 @@ Unit tests for the stem.util.tor_tools functions.
"""
import unittest
-import os
import stem.util.str_tools
import stem.util.tor_tools
class TestTorTools(unittest.TestCase):
-
- def test_is_valid_hidden_service_address(self):
+ def test_is_valid_hidden_service_address_v2(self):
"""
- Check hidden service addresses are valid (no .onion)
+ Checks the is_valid_hidden_service_address for v2 addresses.
"""
+
valid_v2_addresses = [
'facebookcorewwwi',
'aaaaaaaaaaaaaaaa',
]
+
invalid_v2_addresses = [
'facebookcorewww',
'facebookcorewwyi'
'facebookc0rewwwi',
'facebookcorew wi',
- None,
- 0,
- 1,
- -1,
- os.urandom(8)
]
for address in valid_v2_addresses:
self.assertTrue(stem.util.tor_tools.is_valid_hidden_service_address(address))
- self.assertTrue(stem.util.tor_tools.is_valid_hidden_service_address(address, version=2))
+ self.assertTrue(stem.util.tor_tools.is_valid_hidden_service_address(address, version = 2))
for address in invalid_v2_addresses:
self.assertFalse(stem.util.tor_tools.is_valid_hidden_service_address(address))
- self.assertFalse(stem.util.tor_tools.is_valid_hidden_service_address(address, version=2))
+ self.assertFalse(stem.util.tor_tools.is_valid_hidden_service_address(address, version = 2))
+
+ def test_is_valid_hidden_service_address_v3(self):
+ """
+ Checks the is_valid_hidden_service_address for v3 addresses.
+ """
- # Test version 3 addresses
valid_v3_addresses = [
'pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd',
'sp3k262uwy4r2k3ycr5awluarykdpag6a7y33jxop4cs2lu5uz5sseqd',
- 'xa4r2iadxm55fbnqgwwi5mymqdcofiu3w6rpbtqn7b2dyn7mgwj64jyd'
- ]
+ 'xa4r2iadxm55fbnqgwwi5mymqdcofiu3w6rpbtqn7b2dyn7mgwj64jyd',
+ ]
+
invalid_v3_addresses = [
- 'pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryc', # bad version
- 'xa4r2iadxm55fbnqgwwi5mymqdcofiu3w6rpbtqn7b2dyn7mgwj64jy', # too short
- 'sp3k262uwy4r2k4ycr5awluarykdpag6a7y33jxop4cs2lu5uz5sseqd', # checksum mismatch
- 'pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscrybd', # too long
- None,
- 0,
- 1,
- -1,
- os.urandom(56)
+ 'pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryc', # bad version
+ 'xa4r2iadxm55fbnqgwwi5mymqdcofiu3w6rpbtqn7b2dyn7mgwj64jy', # too short
+ 'sp3k262uwy4r2k4ycr5awluarykdpag6a7y33jxop4cs2lu5uz5sseqd', # checksum mismatch
+ 'pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscrybd', # too long
]
for address in valid_v3_addresses:
self.assertTrue(stem.util.tor_tools.is_valid_hidden_service_address(address))
- self.assertTrue(stem.util.tor_tools.is_valid_hidden_service_address(address, version=3))
+ self.assertTrue(stem.util.tor_tools.is_valid_hidden_service_address(address, version = 3))
+
for address in invalid_v3_addresses:
self.assertFalse(stem.util.tor_tools.is_valid_hidden_service_address(address))
- self.assertFalse(stem.util.tor_tools.is_valid_hidden_service_address(address, version=3))
+ self.assertFalse(stem.util.tor_tools.is_valid_hidden_service_address(address, version = 3))
def test_is_valid_fingerprint(self):
"""
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits