diff options
| author | Damian Johnson <atagar@torproject.org> | 2019-11-22 14:03:14 -0800 |
|---|---|---|
| committer | Damian Johnson <atagar@torproject.org> | 2019-11-22 14:03:14 -0800 |
| commit | f5c8c96cdd2cdc967d44ff017b68ea58ce77ca36 (patch) | |
| tree | bf38d6812405c1f4081529b0d6d364e630d6172b | |
| parent | 2526db23a86022796d7d635e1081f2bcd976376b (diff) | |
Include sixteen auth-client lines by default
auth-client are a required field...
https://trac.torproject.org/projects/tor/ticket/32563
https://trac.torproject.org/projects/tor/ticket/31823#comment:16
Tor creates sixteen by default, so doing the same unless our caller specifies
otherwise.
% cat demo.py
from stem.descriptor.hidden_service import OuterLayer
print(OuterLayer.create())
% python demo.py
desc-auth-type x25519
desc-auth-ephemeral-key fhUEgYTR3j4/8MC8aH75WTIKWFOzvKiXURvPHdIXTH4=
auth-client 1J4LPB+umNA iOGHkI+vpsWJaugbv6akgg EtisFxHd3buXMcl30uxJ8A
auth-client wbmXMy71u+Q aiFlaQQV3hBPrmOaQ8kXDg HP+ZFqEt0z47F5AVBnyzxA
auth-client ahHWCcU8INM kQrwT8jZOXAdxiyeVZ/EWw tIBpoOqhvoGhFCOceSLZXA
auth-client UrnUpDYoCTs 6VC/C7xcIWd4Dtmrj1nKig 1k2hfoPhGPwX4BORgHeDPw
auth-client 5I03RmlXJps rgdrWYmq02EmMF+v7PMoLw lkxQtmEz3+CVniXM0E16vQ
auth-client ub0ap7cdghQ gGjmEJTYcw6RGwri2DlPaQ Wz+vnYEc2PmeFxM85lNCcg
auth-client TLgL1NsDjIU bKuIgs/blO3mL80mC13JDw 8sjbuwv3o9sQTt0yQbhIxw
auth-client aytYGQGGAkE lqg3uBRYIX9DHjWl8aLmxQ Nsb6dvhnykFJtSyeGekUhw
auth-client htPYuHAyOsA Wim8CZKo3o2toq+dqeGgMg m6vIoCpQWT0JRR+JgcHIqw
auth-client oJJr9IpqKpc gwd5SFc0CWtRMAaZaqWQrQ iA8qoyKVXWs2N6DA9WzqiQ
auth-client EEIi97LqhGA K+Vn6P2dfRgFZXHhgBvX9A 9bXjd6UBUXuBY3/aeNCR5w
auth-client 1JCG9WKhPKY CgMjZquv+KPLzpqn72uMKQ kC6e5GM/1+2TIvq8kb47Lw
auth-client 6MuN+1vob4w Wi1ktyiaiOaG6PaLbneydQ OEigSskYEZb8hGqWZMDKlg
auth-client uOoXx8epem4 /VjgpZzC71Gj6WAXuVXzVw Q4dOW6GYc/JoQrKNLUQmbQ
auth-client aC9d6RbIr1M FCY56VPOLEktEsQiCDrORQ 0fAhfjriUxnFvbjiTfGDrw
auth-client 60vj3crxSwg XSytZMniMFUCDYbhyrdhDg 3P5Q5QaI70AvX/d8Wh7Etw
encrypted
-----BEGIN MESSAGE-----
EqEXDglNZxN+TmE6I7U7fd9DM0ue9ys770n6AnH4ga+fLSJ8AOb0lX4XANG9TuFh
6hyOfGa0joPezoQSeAFf+yk=
-----END MESSAGE-----
| -rw-r--r-- | stem/descriptor/hidden_service.py | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/stem/descriptor/hidden_service.py b/stem/descriptor/hidden_service.py index e75c7a6e..983fb94b 100644 --- a/stem/descriptor/hidden_service.py +++ b/stem/descriptor/hidden_service.py @@ -1183,9 +1183,13 @@ class OuterLayer(Descriptor): return _encrypt_layer(content, b'hsdir-superencrypted-data', revision_counter, subcredential, blinded_key) @classmethod - def content(cls, attr = None, exclude = (), validate = True, sign = False, inner_layer = None, revision_counter = None, subcredential = None, blinded_key = None): + def content(cls, attr = None, exclude = (), validate = True, sign = False, inner_layer = None, revision_counter = None, authorized_clients = None, subcredential = None, blinded_key = None): if not stem.prereq.is_crypto_available(ed25519 = True): raise ImportError('Hidden service layer creation requires cryptography version 2.6') + elif not stem.prereq._is_sha3_available(): + raise ImportError('Hidden service layer creation requires python 3.6+ or the pysha3 module (https://pypi.org/project/pysha3/)') + elif authorized_clients and 'auth-client' in attr: + raise ValueError('Authorized clients cannot be specified through both attr and authorized_clients') from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey @@ -1195,16 +1199,31 @@ class OuterLayer(Descriptor): blinded_key = blinded_key if blinded_key else stem.util._pubkey_bytes(Ed25519PrivateKey.generate()) subcredential = subcredential if subcredential else HiddenServiceDescriptorV3._subcredential(Ed25519PrivateKey.generate(), blinded_key) - return _descriptor_content(attr, exclude, ( + if not authorized_clients: + authorized_clients = [] + + if attr and 'auth-client' in attr: + pass # caller is providing raw auth-client lines through the attr + else: + for i in range(16): + client_id = base64.b64encode(os.urandom(8)).rstrip(b'=') + iv = base64.b64encode(os.urandom(16)).rstrip(b'=') + cookie = base64.b64encode(os.urandom(16)).rstrip(b'=') + + authorized_clients.append(AuthorizedClient(client_id, iv, cookie)) + + return _descriptor_content(attr, exclude, [ ('desc-auth-type', 'x25519'), ('desc-auth-ephemeral-key', base64.b64encode(stem.util._pubkey_bytes(X25519PrivateKey.generate()))), - ), ( + ] + [ + ('auth-client', '%s %s %s' % (c.id, c.iv, c.cookie)) for c in authorized_clients + ], ( ('encrypted', b'\n' + inner_layer._encrypt(revision_counter, subcredential, blinded_key)), )) @classmethod - def create(cls, attr = None, exclude = (), validate = True, sign = False, inner_layer = None, revision_counter = None, subcredential = None, blinded_key = None): - return cls(cls.content(attr, exclude, validate, sign, inner_layer, revision_counter, subcredential, blinded_key), validate = validate) + def create(cls, attr = None, exclude = (), validate = True, sign = False, inner_layer = None, revision_counter = None, authorized_clients = None, subcredential = None, blinded_key = None): + return cls(cls.content(attr, exclude, validate, sign, inner_layer, revision_counter, authorized_clients, subcredential, blinded_key), validate = validate) def __init__(self, content, validate = False): content = stem.util.str_tools._to_bytes(content).rstrip(b'\x00') # strip null byte padding |
