commit ce8d1ff8f922ccda30a9edeef91adf61eded7024 Author: Damian Johnson atagar@torproject.org Date: Wed Jan 31 12:34:28 2018 -0800
Initial attempt at a Circuit class
Haven't a clue if this is close to what we want, but lets just get something down to get this ball rolling. --- stem/client/__init__.py | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-)
diff --git a/stem/client/__init__.py b/stem/client/__init__.py index f3e842c6..0accaa59 100644 --- a/stem/client/__init__.py +++ b/stem/client/__init__.py @@ -13,9 +13,6 @@ a wrapper for :class:`~stem.socket.RelaySocket`, much the same way as
split - splits bytes into substrings
- KDF - KDF-TOR derivatived attributes - +- from_value - parses key material - Field - Packable and unpackable datatype. |- Size - Field of a static size. |- Address - Relay address. @@ -25,6 +22,9 @@ a wrapper for :class:`~stem.socket.RelaySocket`, much the same way as |- unpack - decodes content +- pop - decodes content with remainder
+ KDF - KDF-TOR derivatived attributes + +- from_value - parses key material + .. data:: AddrType (enum)
Form an address takes. @@ -114,6 +114,7 @@ import hashlib import io import struct
+import stem.prereq import stem.util.connection import stem.util.enum
@@ -498,6 +499,37 @@ class KDF(collections.namedtuple('KDF', ['key_hash', 'forward_digest', 'backward return KDF(key_hash, forward_digest, backward_digest, forward_key, backward_key)
+class Circuit(collections.namedtuple('Circuit', ['id', 'forward_digest', 'backward_digest', 'forward_key', 'backward_key'])): + """ + Circuit through which requests can be made of a `Tor relay's ORPort + https://gitweb.torproject.org/torspec.git/tree/tor-spec.txt`_. + + :var int id: circuit id + :var hashlib.sha1 forward_digest: digest for forward integrity check + :var hashlib.sha1 backward_digest: digest for backward integrity check + :var bytes forward_key: forward encryption key + :var bytes backward_key: backward encryption key + """ + + @staticmethod + def from_kdf(circ_id, kdf): + if not stem.prereq.is_crypto_available(): + raise ImportError('Circuit construction requires the cryptography module') + + from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes + from cryptography.hazmat.backends import default_backend + + ctr = modes.CTR(ZERO * (algorithms.AES.block_size / 8)) + + return Circuit( + circ_id, + hashlib.sha1(kdf.forward_digest), + hashlib.sha1(kdf.backward_digest), + Cipher(algorithms.AES(kdf.forward_key), ctr, default_backend()).encryptor(), + Cipher(algorithms.AES(kdf.backward_key), ctr, default_backend()).decryptor(), + ) + + setattr(Size, 'CHAR', Size('CHAR', 1, '!B')) setattr(Size, 'SHORT', Size('SHORT', 2, '!H')) setattr(Size, 'LONG', Size('LONG', 4, '!L'))