[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [stem/master] Stub minimal cell decryption function
commit 52edd22ca10d559270ee240409447351bd8639f8
Author: Damian Johnson <atagar@xxxxxxxxxxxxxx>
Date: Sat Aug 25 13:32:07 2018 -0700
Stub minimal cell decryption function
Ok, now into the meat of this sucker. Dave's branch introduces nice additions
such as validating our backward digest and a flag to indicate if we've fully
decrypted the cell or not.
For the moment moving to a minimal decryption function that only supports what
we did previously. Next gonna try to integrate his new features to make a
hybrid approach that hopefully takes the best of both.
---
stem/client/__init__.py | 22 +++++++---------------
stem/client/cell.py | 30 ++++++++++++++++++++++++++++++
2 files changed, 37 insertions(+), 15 deletions(-)
diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index a216696a..19528d67 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -33,7 +33,7 @@ import stem.client.cell
import stem.socket
import stem.util.connection
-from stem.client.datatype import ZERO, LinkProtocol, Address, KDF
+from stem.client.datatype import ZERO, LinkProtocol, Address, KDF, split
__all__ = [
'cell',
@@ -253,22 +253,14 @@ class Circuit(object):
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:
- raw_cell, reply = stem.client.cell.Cell.pop(reply, self.relay.link_protocol)
+ encrypted_cell, reply = split(reply, self.relay.link_protocol.fixed_cell_length)
+ decrypted_cell, backward_key, backward_digest = stem.client.cell.RelayCell.decrypt(encrypted_cell, self.backward_key, self.backward_digest)
- if raw_cell.VALUE != stem.client.cell.RelayCell.VALUE:
- raise stem.ProtocolError('RELAY cell responses should be %i but was %i' % (stem.client.cell.RelayCell.VALUE, 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))
+ if self.id != decrypted_cell.circ_id:
+ raise stem.ProtocolError('Response should be for circuit id %i, not %i' % (self.id, decrypted_cell.circ_id))
- decrypted_cell, fully_decrypted, new_backward_digest, new_backward_key = raw_cell.decrypt(self.backward_digest, self.backward_key, interpret = True)
-
- if not fully_decrypted:
- raise stem.ProtocolError('Response for circuit id %i was not fully decrypted, when expected to be' % self.id)
-
- # Again, if the above raises the digest/key should remain unchanged.
-
- self.backward_digest = new_backward_digest
- self.backward_key = new_backward_key
+ self.backward_digest = backward_digest
+ self.backward_key = backward_key
reply_cells.append(decrypted_cell)
diff --git a/stem/client/cell.py b/stem/client/cell.py
index 6587ebb5..3de1c731 100644
--- a/stem/client/cell.py
+++ b/stem/client/cell.py
@@ -551,6 +551,36 @@ class RelayCell(CircuitCell):
elif stream_id and self.command in STREAM_ID_DISALLOWED:
raise ValueError('%s relay cells concern the circuit itself and cannot have a stream id' % self.command)
+ @classmethod
+ def decrypt(link_protocol, content, digest, key):
+ """
+ Parse the given content as an encrypted RELAY cell.
+ """
+
+ # TODO: Fill in the above pydocs, deduplicate with the other decrypt
+ # method, yadda yadda. Starting with a minimal stub to see if this makes
+ # the Circuit class better. I'll circle back to clean up this module if it
+ # works.
+
+ if len(content) != link_protocol.fixed_cell_length:
+ raise stem.ProtocolError('RELAY cells should be %i bytes, but received %i' % (link_protocol.fixed_cell_length, len(content)))
+
+ circ_id, content = link_protocol.circ_id_size.pop(content)
+ command, payload = Size.CHAR.pop(content)
+
+ if command != RelayCell.VALUE:
+ raise stem.ProtocolError('Cannot decrypt as a RELAY cell. This had command %i instead.' % command)
+
+ key = copy.copy(key)
+ decrypted = key.update(payload)
+
+ # TODO: Integrate with check_digest() and flag for integrating if we're
+ # fully decrypted. For the moment we only handle direct responses (ie. all
+ # the cells we receive can be fully decrypted) but if we attempt to support
+ # relaying we'll need to pass along cells we can only partially decrypt.
+
+ return RelayCell._unpack(decrypted, circ_id, link_protocol), key, digest
+
@staticmethod
def _coerce_digest(digest):
"""
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits