Browse Source

work-in-progress for telescoping implementation

Chelsea H. Komlo 4 years ago
parent
commit
b4f2219648
2 changed files with 123 additions and 3 deletions
  1. 45 1
      client.py
  2. 78 2
      relay.py

+ 45 - 1
client.py

@@ -63,6 +63,31 @@ class VanillaCreatedExtendedHandler:
         # Send the cell
         circhandler.send_cell(circextendmsg)
 
+class TelescopingCreatedHandler:
+    """A handler for TelescopingCreatedCircuitCell cells."""
+
+    def __init__(self, channelmgr, ntor, guarddesc):
+        self.channelmgr = channelmgr
+        self.ntor = ntor
+        self.guarddesc = guarddesc
+        self.onionkey = guarddesc.snipdict['onionkey']
+        self.idkey = guarddesc.snipdict['idkey']
+
+    def received_cell(self, circhandler, cell):
+        print("LOG: Received cell in TelescopingCreatedHandler")
+
+        secret = self.ntor.verify(cell.ntor_reply, self.onionkey, self.idkey)
+        enckey = nacl.hash.sha256(secret + b'upstream')
+        deckey = nacl.hash.sha256(secret + b'downstream')
+        circhandler.add_crypt_layer(enckey, deckey)
+
+        # Are we done building the circuit?
+        if len(circhandler.circuit_descs) == 3:
+            # Yes!
+            return
+
+        sys.exit("Err: Unimplemented! Need to implement circuit extension for telescoping.")
+
 
 class ClientChannelManager(relay.ChannelManager):
     """The subclass of ChannelManager for clients."""
@@ -170,7 +195,26 @@ class ClientChannelManager(relay.ChannelManager):
         """Create a new circuit from this client. (Telescoping Walking Onions
         version)"""
 
-        print("WARNING: Unimplemented! Need to implement building circuits via telescoping.")
+        # Get our channel to the guard
+        guardchannel = self.get_channel_to(self.guardaddr)
+
+        # Allocate a new circuit id on it
+        circid, circhandler = guardchannel.new_circuit()
+
+        # Construct the VanillaCreateCircuitMsg
+        ntor = relay.NTor(self.perfstats)
+        ntor_request = ntor.request()
+        circcreatemsg = relay.TelescopingCreateCircuitMsg(circid, ntor_request)
+
+        # Set up the reply handler
+        circhandler.replace_celltype_handler(
+                relay.TelescopingCreatedCircuitCell,
+                TelescopingCreatedHandler(self, ntor, self.guard))
+
+        # Send the message
+        guardchannel.send_msg(circcreatemsg)
+
+        return circhandler
 
     def new_circuit(self):
         """Create a new circuit from this client."""

+ 78 - 2
relay.py

@@ -121,7 +121,7 @@ class VanillaCreatedCircuitCell(RelayCell):
 
 
 class VanillaExtendCircuitCell(RelayCell):
-    """The message for requesting circuit creation in Vanilla Onion
+    """The message for requesting circuit extension in Vanilla Onion
     Routing."""
 
     def __init__(self, hopaddr, ntor_request):
@@ -130,12 +130,45 @@ class VanillaExtendCircuitCell(RelayCell):
 
 
 class VanillaExtendedCircuitCell(RelayCell):
-    """The message for responding to circuit creation in Vanilla Onion
+    """The message for responding to circuit extension in Vanilla Onion
     Routing."""
 
     def __init__(self, ntor_reply):
         self.ntor_reply = ntor_reply
 
+# It is intentional that TelescopingCreateCircuitMsg is a RelayNetMsg and
+# not a RelayCell.  This is the message that _creates_ the circuit, so
+# it can't be sent as a cell _within_ the circuit.
+class TelescopingCreateCircuitMsg(RelayNetMsg):
+    """The message for requesting circuit creation in Telescoping Onion
+    Routing."""
+
+    def __init__(self, circid, ntor_request):
+        self.circid = circid
+        self.ntor_request = ntor_request
+
+class TelescopingCreatedCircuitCell(RelayCell):
+    """The message for responding to circuit creation in Telescoping Walking
+    Onions."""
+
+    def __init__(self, ntor_reply):
+        self.ntor_reply = ntor_reply
+
+class TelescopingExtendCircuitCell(RelayCell):
+    """The message for requesting circuit extension in Telescoping Walking
+    Onionss."""
+
+    def __init__(self, idx, ntor_request):
+        self.idx = idx
+        self.ntor_request = ntor_request
+
+class TelescopingExtendedCircuitCell(RelayCell):
+    """The message for responding to circuit extension in Telescoping Walking
+    Onions."""
+
+    def __init__(self, ntor_reply):
+        self.ntor_reply = ntor_reply
+
 
 class EncryptedCell(RelayCell):
     """Send a message encrypted with a symmetric key.  In this
@@ -248,6 +281,30 @@ class VanillaExtendCircuitHandler:
         nexthopchannel.send_msg(
                 VanillaCreateCircuitMsg(newcircid, cell.ntor_request))
 
+class TelescopingExtendCircuitHandler:
+    """A handler for TelescopingExtendCircuitCell cells.  It allocates a new
+    circuit id on the Channel to the requested next hop, connects the
+    existing and new circuits together, and forwards a
+    TelescopingCreateCircuitMsg to the next hop."""
+
+    def received_cell(self, circhandler, cell):
+        # Remove ourselves from handling a second
+        # TelescopingExtendCircuitCell on this circuit
+        circhandler.replace_celltype_handler(TelescopingExtendCircuitCell, None)
+
+        # Allocate a new circuit id to the requested next hop
+        channelmgr = circhandler.channel.channelmgr
+        nexthopchannel = channelmgr.get_channel_to(cell.hopaddr)
+        print("WARNING: Unimplemented! " +  cell.hopaddr)
+
+        #newcircid, newcirchandler = nexthopchannel.new_circuit()
+
+        print("WARNING: Unimplemented! TelescopingExtendCircuitHandler")
+
+
+
+
+
 
 class VanillaCreatedRelayHandler:
     """Handle a VanillaCreatedCircuitCell received by a _relay_ that
@@ -608,6 +665,25 @@ class RelayChannelManager(ChannelManager):
             # Send the ntor reply
             self.send_msg(CircuitCellMsg(msg.circid,
                     VanillaCreatedCircuitCell(reply)), peeraddr)
+        elif isinstance(msg, TelescopingCreateCircuitMsg):
+            print("LOG: Received TelescopingCreateCircuitMsg circuit message, handling.")
+            # A new circuit has arrived
+            circhandler = channel.new_circuit_with_circid(msg.circid)
+            # Create the ntor reply
+            reply, secret = NTor.reply(self.onionkey, self.idpubkey,
+                    msg.ntor_request, self.perfstats)
+            # Set up the circuit to use the shared secret
+            enckey = nacl.hash.sha256(secret + b'downstream')
+            deckey = nacl.hash.sha256(secret + b'upstream')
+            circhandler.add_crypt_layer(enckey, deckey)
+            # Add a handler for if an Extend Cell arrives (there should
+            # be at most one on this circuit).
+            circhandler.replace_celltype_handler(
+                    TelescopingExtendCircuitCell, TelescopingExtendCircuitHandler())
+            print("LOG: Sending TelescopingCreatedCircuitMsg circuit message")
+            # Send the ntor reply
+            self.send_msg(CircuitCellMsg(msg.circid,
+                    TelescopingCreatedCircuitCell(reply)), peeraddr)
         else:
             return super().received_msg(msg, peeraddr, channel)