File crap.py changed (mode: 100755) (index 99a0c93..4f6aae1) |
... |
... |
import time |
5 |
5 |
|
|
6 |
6 |
from identity import Identity |
from identity import Identity |
7 |
7 |
from session import Session |
from session import Session |
8 |
|
from tcp import TcpPacket, TcpRelay, TcpServerHelloPacket, TcpPingPacket, TcpPongPacket, IncomingStreamHandler, h |
|
|
8 |
|
from tcp import TcpPacket, TcpRelay, TcpServerHelloPacket, TcpPingPacket, TcpPongPacket, IncomingStreamHandler, TcpRoutingRequestPacket, h |
9 |
9 |
|
|
10 |
10 |
if __name__ == "__main__": |
if __name__ == "__main__": |
11 |
11 |
identity = Identity() |
identity = Identity() |
|
... |
... |
if __name__ == "__main__": |
22 |
22 |
|
|
23 |
23 |
relay.negotiate_forward_secret_keys(session, identity) |
relay.negotiate_forward_secret_keys(session, identity) |
24 |
24 |
|
|
|
25 |
|
print("=== PFS established ===") |
|
26 |
|
|
25 |
27 |
def on_ping_recvd(packet): |
def on_ping_recvd(packet): |
26 |
28 |
print ("<<< PING", packet) |
print ("<<< PING", packet) |
27 |
29 |
def on_pong_recvd(packet): |
def on_pong_recvd(packet): |
|
... |
... |
if __name__ == "__main__": |
42 |
44 |
time.sleep(0.1) |
time.sleep(0.1) |
43 |
45 |
tick += 1 |
tick += 1 |
44 |
46 |
|
|
45 |
|
if tick % 30 == 0: |
|
|
47 |
|
if tick == 10: |
|
48 |
|
packet = TcpRoutingRequestPacket( |
|
49 |
|
relay=relay, |
|
50 |
|
public_key=bytearray.fromhex("E702791968D0DFB5C1B0AF5F7EAD1A457F29CC01FD9A07F754E6A621B041F001"), |
|
51 |
|
) |
|
52 |
|
packet.send() |
|
53 |
|
|
|
54 |
|
if tick % 50 == 1: |
46 |
55 |
print (">>> PING") |
print (">>> PING") |
47 |
|
ping = TcpPingPacket(relay=relay) |
|
48 |
|
ping.send() |
|
|
56 |
|
payload = "%dpytox!!" % tick |
|
57 |
|
relay.ping(payload[:8].encode()) |
49 |
58 |
|
|
50 |
59 |
s.close() |
s.close() |
File tcp.py changed (mode: 100644) (index 0b4efe4..f97354f) |
... |
... |
class TcpPacket: |
49 |
49 |
""" |
""" |
50 |
50 |
return data |
return data |
51 |
51 |
|
|
|
52 |
|
def prepare_bytes(self): |
|
53 |
|
""" |
|
54 |
|
Fill self.bytes pre-encryption if necessary |
|
55 |
|
To be overridden |
|
56 |
|
""" |
|
57 |
|
pass |
|
58 |
|
|
52 |
59 |
def serialize(self): |
def serialize(self): |
53 |
60 |
""" |
""" |
54 |
61 |
Return wire-ready serialized packet |
Return wire-ready serialized packet |
55 |
62 |
""" |
""" |
|
63 |
|
self.prepare_bytes() |
56 |
64 |
serialized_b = self.encrypt(self.bytes) |
serialized_b = self.encrypt(self.bytes) |
57 |
65 |
if len(serialized_b) >= 2**16: |
if len(serialized_b) >= 2**16: |
58 |
66 |
raise SerializationError('TCP packet too long: %d' % len(serialized_b)) |
raise SerializationError('TCP packet too long: %d' % len(serialized_b)) |
|
... |
... |
class TcpPingPacket(EncryptedPacket): |
97 |
105 |
Ping packet (0x04) |
Ping packet (0x04) |
98 |
106 |
""" |
""" |
99 |
107 |
packet_id = 0x04 |
packet_id = 0x04 |
100 |
|
def __init__(self, relay=None): |
|
|
108 |
|
def __init__(self, relay=None, payload=None): |
101 |
109 |
super().__init__(relay) |
super().__init__(relay) |
102 |
|
self.bytes = b"\x04puretoxc" |
|
|
110 |
|
if payload: |
|
111 |
|
self.bytes = b"\x04" + payload |
|
112 |
|
print ("PING BYTES SEND", self.bytes) |
|
113 |
|
else: |
|
114 |
|
self.bytes = b"\x04puretoxc" |
|
115 |
|
|
|
116 |
|
if len(self.bytes) != 9: |
|
117 |
|
raise ValueError("Ping payload is %d bytes long - must be 8" % (len(self.bytes)-1)) |
103 |
118 |
|
|
104 |
119 |
@classmethod |
@classmethod |
105 |
120 |
def from_bytes(cls, packet_bytes): |
def from_bytes(cls, packet_bytes): |
|
... |
... |
class TcpRoutingRequestPacket(EncryptedPacket): |
136 |
151 |
Routing request (0x00) |
Routing request (0x00) |
137 |
152 |
""" |
""" |
138 |
153 |
packet_id = 0x00 |
packet_id = 0x00 |
|
154 |
|
def __init__(self, relay=None, public_key=None): |
|
155 |
|
""" |
|
156 |
|
public_key: 32-byte bytes object public key |
|
157 |
|
""" |
|
158 |
|
super().__init__(relay) |
|
159 |
|
if public_key: |
|
160 |
|
self.public_key = public_key |
|
161 |
|
if len(public_key) != 32: |
|
162 |
|
raise ValueError("Public key %s is not a 32-byte array" % str(public_key)) |
|
163 |
|
|
|
164 |
|
def prepare_bytes(self): |
|
165 |
|
self.bytes = b"\x00" + self.public_key |
|
166 |
|
|
|
167 |
|
class TcpRoutingResponsePacket(EncryptedPacket): |
|
168 |
|
packet_id = 0x01 |
139 |
169 |
def __init__(self, relay=None): |
def __init__(self, relay=None): |
140 |
170 |
super().__init__(relay) |
super().__init__(relay) |
141 |
|
|
|
|
171 |
|
|
|
172 |
|
@classmethod |
|
173 |
|
def from_bytes(cls, packet_bytes): |
|
174 |
|
self = TcpRoutingResponsePacket() |
|
175 |
|
assert (len(packet_bytes) == 34), "Packet length is not 34 bytes" |
|
176 |
|
assert (packet_bytes[0] == self.packet_id), "First byte does not equal to packet id" |
|
177 |
|
self.connection_id = int(packet_bytes[1]) |
|
178 |
|
self.public_key = packet_bytes[2:] |
|
179 |
|
|
|
180 |
|
self.bytes = packet_bytes |
|
181 |
|
|
|
182 |
|
return self |
|
183 |
|
|
|
184 |
|
def __repr__(self): |
|
185 |
|
return "<TcpRoutingResponse for %s, connection #%d>" % (h(self.public_key), self.connection_id) |
142 |
186 |
|
|
143 |
187 |
class TcpClientHelloPacket(TcpPacket): |
class TcpClientHelloPacket(TcpPacket): |
144 |
188 |
""" |
""" |
|
... |
... |
class TcpRelay: |
308 |
352 |
self.set_outgoing_public_key(packet.relay_public_key) |
self.set_outgoing_public_key(packet.relay_public_key) |
309 |
353 |
self._socket.setblocking(0) |
self._socket.setblocking(0) |
310 |
354 |
|
|
|
355 |
|
def ping(self, payload=None): |
|
356 |
|
""" |
|
357 |
|
Construct and send a ping packet to relay |
|
358 |
|
""" |
|
359 |
|
packet = TcpPingPacket(relay=self, payload=payload) |
|
360 |
|
packet.send() |
|
361 |
|
|
311 |
362 |
class IncomingStreamHandler: |
class IncomingStreamHandler: |
312 |
363 |
""" |
""" |
313 |
364 |
Split incoming TCP stream into packets |
Split incoming TCP stream into packets |
|
... |
... |
class IncomingStreamHandler: |
349 |
400 |
def decrypt(self, ciphertext): |
def decrypt(self, ciphertext): |
350 |
401 |
combined = nacl.bindings.crypto_box_beforenm(bytes(self.relay.get_outgoing_public_key()), bytes(self.relay.get_private_key())) |
combined = nacl.bindings.crypto_box_beforenm(bytes(self.relay.get_outgoing_public_key()), bytes(self.relay.get_private_key())) |
351 |
402 |
nonce = self.relay.get_incoming_nonce() |
nonce = self.relay.get_incoming_nonce() |
352 |
|
print ("IncomingStreamHandler.decrypt:") |
|
353 |
|
print ("combined key", binascii.hexlify(combined)) |
|
354 |
|
print ("incoming nonce", h(nonce)) |
|
|
403 |
|
# print ("IncomingStreamHandler.decrypt:") |
|
404 |
|
# print ("combined key", binascii.hexlify(combined)) |
|
405 |
|
# print ("incoming nonce", h(nonce)) |
355 |
406 |
plaintext = nacl.bindings.crypto_box_open_afternm(ciphertext, nonce, combined) |
plaintext = nacl.bindings.crypto_box_open_afternm(ciphertext, nonce, combined) |
356 |
407 |
|
|
357 |
408 |
return plaintext |
return plaintext |
|
... |
... |
class IncomingStreamHandler: |
381 |
432 |
return packet |
return packet |
382 |
433 |
else: |
else: |
383 |
434 |
print("Unknown packet type %d" % packet_id) |
print("Unknown packet type %d" % packet_id) |
|
435 |
|
print(packet_bytes) |