List of commits:
Subject Hash Author Date (UTC)
Initial 5492ec94c8cab618b3e617e0ac2f8d5b27335f83 GDR! 2017-11-09 17:41:55
Commit 5492ec94c8cab618b3e617e0ac2f8d5b27335f83 - Initial
Author: GDR!
Author date (UTC): 2017-11-09 17:41
Committer name: GDR!
Committer date (UTC): 2017-11-09 17:41
Parent(s):
Signing key:
Tree: 905462612e649f4739bd7464c1e593924af36403
File Lines added Lines deleted
crap.py 26 0
exceptions.py 4 0
identity.py 25 0
session.py 27 0
tcp.py 96 0
File crap.py added (mode: 100755) (index 0000000..9292361)
1 #!/usr/bin/python3
2
3 import socket
4
5 from identity import Identity
6 from session import Session
7 from tcp import TcpPacket, TcpRelay
8
9 if __name__ == "__main__":
10 identity = Identity()
11 sess = Session()
12 print("PK", sess.get_printable_public_key())
13 print("toxid", identity.get_printable_public_key())
14
15 relay = TcpRelay("biribiri.org", 3389, "F404ABAA1C99A9D37D61AB54898F56793E1DEF8BD46B1038B9D822E8460FAB67")
16 packet = relay.get_client_hello_packet(sess, identity)
17
18 s = socket.socket()
19 s.connect(("biribiri.org", 3389))
20 print("connected")
21
22 packet.send(s)
23
24 print ("RECEIVED:")
25 print(s.recv(4096))
26 s.close()
File exceptions.py added (mode: 100644) (index 0000000..2b8db81)
1 #!/usr/bin/python3
2
3 class ToxException(RuntimeError):
4 pass
File identity.py added (mode: 100644) (index 0000000..fe0c50c)
1 #!/usr/bin/python
2
3 import binascii
4 import nacl.utils
5
6 from nacl.public import PrivateKey, Box
7
8 class Identity:
9 """
10 The main profile keypair (ToxID and its private counterpart)
11 """
12 def __init__(self):
13 # TODO load from save file
14 self.tox_key = PrivateKey.generate()
15
16 def get_private_key(self):
17 return self.tox_key
18
19 def get_public_key(self):
20 return self.tox_key.public_key
21
22 def get_printable_public_key(self):
23 return binascii.hexlify(bytes(self.get_public_key()))
24
25
File session.py added (mode: 100644) (index 0000000..ef63045)
1 #!/usr/bin/python
2
3 import binascii
4 import nacl.utils
5
6 from nacl.public import PrivateKey, Box
7
8 class Session:
9 """
10 The temporary DHT keypair and some wrappers
11 """
12 def __init__(self):
13 self.tcp_nonce = None
14 self.session_key = PrivateKey.generate()
15
16 def get_private_key(self):
17 return self.session_key
18
19 def get_public_key(self):
20 return self.session_key.public_key
21
22 def get_printable_public_key(self):
23 return binascii.hexlify(bytes(self.get_public_key()))
24
25 def get_nonce(self):
26 return nacl.utils.random(Box.NONCE_SIZE)
27
File tcp.py added (mode: 100644) (index 0000000..f7847f7)
1 #!/usr/bin/python3
2
3 import binascii
4 import struct
5 import nacl.bindings
6 import nacl.utils
7
8 from nacl.public import PrivateKey, PublicKey, Box
9
10 from exceptions import *
11
12 class SerializationError(ToxException):
13 pass
14
15 class TcpPacket:
16 """
17 Holds generic packet to be sent via TCP
18 """
19 def __init__(self):
20 self.bytes = b""
21
22 def send(self, socket):
23 """
24 Serialize and send packet via socket
25 """
26 serialized_b = self.serialize()
27 print(binascii.hexlify(serialized_b))
28 socket.send(serialized_b)
29
30 def serialize(self):
31 """
32 Return wire-ready serialized packet
33 """
34 serialized_b = self.bytes
35 if len(serialized_b) >= 2**16:
36 raise SerializationError('TCP packet too long: %d' % len(serialized_b))
37
38 length_b = struct.pack(">H", len(serialized_b))
39 return length_b + serialized_b
40
41 class TestTcpPacket(TcpPacket):
42 def __init__(self):
43 self.bytes = "Hi!".encode("utf-8")
44
45 class TcpClientHelloPacket(TcpPacket):
46 def __init__(self, relay, session, identity):
47 # The nonce used in hello packet only
48 self.nonce = bytes(session.get_nonce())
49
50 self.bytes = b""
51 self.bytes += bytes(session.get_public_key())
52 self.bytes += self.nonce
53 self.bytes += self.get_payload(relay, session, identity)
54
55 def get_payload(self, relay, session, identity):
56 payload = bytes(identity.get_public_key())
57 payload += bytes(relay.get_tcp_nonce())
58 print (payload)
59
60 combined = nacl.bindings.crypto_box_beforenm(bytes(relay.get_public_key()), bytes(session.get_private_key()))
61 encrypted = nacl.bindings.crypto_box_afternm(payload, relay.get_tcp_nonce(), combined)
62 print(encrypted)
63
64 #box = Box(session.get_private_key(), relay.get_public_key())
65 #encrypted = box.encrypt(payload, relay.get_tcp_nonce())
66 return bytes(encrypted)
67
68 def serialize(self):
69 """
70 The hello packet doesn't add length header
71 """
72 return self.bytes
73
74 class TcpRelay:
75 """
76 Represents a connection to TCP relay
77 """
78 def __init__(self, hostname, port, public_key):
79 """
80 public_key is a hex-encoded string containing relay's public key
81 """
82 self.hostname = hostname
83 self.port = int(port)
84 self.public_key = PublicKey(binascii.unhexlify(public_key))
85 # "Base Nonce" from documentation
86 # The base nonce is the one the TCP server wants the TCP client to use to encrypt the packets sent to the TCP server.
87 self.tcp_nonce = nacl.utils.random(Box.NONCE_SIZE)
88
89 def get_client_hello_packet(self, session, identity):
90 return TcpClientHelloPacket(self, session, identity)
91
92 def get_tcp_nonce(self):
93 return self.tcp_nonce
94
95 def get_public_key(self):
96 return self.public_key
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/gdr/PurePyTox

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/gdr/PurePyTox

Clone this repository using git:
git clone git://git.rocketgit.com/user/gdr/PurePyTox

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main