[tor-commits] [stem/master] Simplify encryption/decryption implementation in Circuit

atagar at torproject.org atagar at torproject.org
Sun Aug 26 20:49:21 UTC 2018


commit d355d01a7a4709ffc6941722248c9861e2acd306
Author: Dave Rolek <dmr-x at riseup.net>
Date:   Wed Aug 8 03:06:38 2018 +0000

    Simplify encryption/decryption implementation in Circuit
    
    This is a proof-of-concept change to show the benefits of migrating
    finer details into the Cell abstraction.
    
    It still arguably violates the Cell abstraction by using
    RelayCell._unpack(), but that can be addressed in a later change.
---
 stem/client/__init__.py | 40 ++++++++++++++--------------------------
 1 file changed, 14 insertions(+), 26 deletions(-)

diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index 24b6de38..71f6d390 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -34,7 +34,7 @@ import stem.client.cell
 import stem.socket
 import stem.util.connection
 
-from stem.client.datatype import ZERO, LinkProtocol, Address, Size, KDF, split
+from stem.client.datatype import ZERO, LinkProtocol, Address, KDF
 
 __all__ = [
   'cell',
@@ -237,45 +237,33 @@ class Circuit(object):
       orig_digest = self.forward_digest.copy()
       orig_key = copy.copy(self.forward_key)
 
-      # Digests and such are computed using the RELAY cell payload. This
-      # doesn't include the initial circuit id and cell type fields.
-      # Circuit ids vary in length depending on the protocol version.
-
-      header_size = self.relay.link_protocol.circ_id_size.size + 1
-
       try:
+        # Digests and such are computed using the RELAY cell payload.
         cell = stem.client.cell.RelayCell(self.id, command, data, 0, stream_id)
-        payload_without_digest = cell.pack(self.relay.link_protocol)[header_size:]
+        payload_without_digest = cell.pack(self.relay.link_protocol)[-stem.client.cell.FIXED_PAYLOAD_LEN:]
         self.forward_digest.update(payload_without_digest)
 
         cell = stem.client.cell.RelayCell(self.id, command, data, self.forward_digest, stream_id)
-        header, payload = split(cell.pack(self.relay.link_protocol), header_size)
-        encrypted_payload = header + self.forward_key.update(payload)
+        payload_with_digest = cell.pack(self.relay.link_protocol)[-stem.client.cell.FIXED_PAYLOAD_LEN:]
+        encrypted_payload = self.forward_key.update(payload_with_digest)
+        encrypted_cell = stem.client.cell.RawRelayCell(self.id, encrypted_payload)
 
         reply_cells = []
-        self.relay._orport.send(encrypted_payload)
+        self.relay._orport.send(encrypted_cell.pack(self.relay.link_protocol))
         reply = self.relay._orport.recv()
 
-        # Check that we got the correct number of bytes for a series of RELAY cells
-
-        relay_cell_size = header_size + stem.client.cell.FIXED_PAYLOAD_LEN
         relay_cell_cmd = stem.client.cell.RelayCell.VALUE
 
-        if len(reply) % relay_cell_size != 0:
-          raise stem.ProtocolError('Circuit response should be a series of RELAY cells, but received an unexpected size for a response: %i' % len(reply))
-
         while reply:
-          circ_id, reply = self.relay.link_protocol.circ_id_size.pop(reply)
-          command, reply = Size.CHAR.pop(reply)
-          payload, reply = split(reply, stem.client.cell.FIXED_PAYLOAD_LEN)
+          raw_cell, reply = stem.client.cell.Cell.pop(reply, self.relay.link_protocol)
 
-          if command != relay_cell_cmd:
-            raise stem.ProtocolError('RELAY cell responses should be %i but was %i' % (relay_cell_cmd, command))
-          elif circ_id != self.id:
-            raise stem.ProtocolError('Response should be for circuit id %i, not %i' % (self.id, circ_id))
+          if raw_cell.VALUE != relay_cell_cmd:
+            raise stem.ProtocolError('RELAY cell responses should be %i but was %i' % (relay_cell_cmd, raw_cell.VALUE))
+          elif raw_cell.circ_id != self.id:
+            raise stem.ProtocolError('Response should be for circuit id %i, not %i' % (self.id, raw_cell.circ_id))
 
-          decrypted = self.backward_key.update(payload)
-          reply_cells.append(stem.client.cell.RelayCell._unpack(decrypted, self.id, self.relay.link_protocol))
+          decrypted_payload = self.backward_key.update(raw_cell.payload)
+          reply_cells.append(stem.client.cell.RelayCell._unpack(decrypted_payload, self.id, self.relay.link_protocol))
 
         return reply_cells
       except:





More information about the tor-commits mailing list