pybutt/discovery.py

83 lines
2.6 KiB
Python

from nacl.public import PrivateKey, PublicKey
import identity
import socket
import sys
from shs import SHSClientCrypto, SHSServerCrypto
import hmac
from hashlib import sha256
class Peer(object):
def __init__(
self,
identity:
identity.Identity,
port=8008,
network_id=b'42'
) -> None:
super().__init__()
self.identity = identity
hostname = socket.gethostname()
self.ip_address = socket.gethostbyname(hostname)
self.port = port
self.ephemeral_keys = None
self.network_id = network_id
def broadcast(self):
print(f'#TODO: Broadcast net:{self.ip_address}:{self.port}~shs:{self.identity}')
# try:
# s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# except socket.error:
# print('Failed to create socket')
# sys.exit()
# host = '255.255.255.255'
# port = 55558
# while True:
# msg = f'net:{self.ip_address}:{self.port}~shs:{self.identity[1:]}'
def generate_ephemeral_keys(self):
sk = PrivateKey.generate()
pk = sk.public_key
self.ephemeral_keys = {'sk': sk, 'pk': pk}
def do_handshake(self, role='client'):
self.generate_ephemeral_keys()
if role=='client':
self.client_handshake()
def client_handshake(self):
# Client knows
# own private/public keys
# ephemeral handshake keys
# server public key from discovery
# network ID
self.send_client_hello()
def server_handshake(self):
# Server already knows
# own private/public keys
# ephemeral handshake keys
# network ID
self.verify_client_hello()
self.send_server_hello()
def send_client_hello(self):
nacl_auth = bytearray(
hmac.HMAC(msg=self.ephemeral_keys.get('pk')._public_key, key=self.network_id, digestmod=sha256).digest()
)
client_ephemeral_pk = bytearray(self.ephemeral_keys.get('pk')._public_key)
return nacl_auth + client_ephemeral_pk
def verify_client_hello(self, hello_msg: bytearray):
assert(len(hello_msg) == 64)
client_hmac = hello_msg[0:31]
client_ephemeral_pk = hello_msg[32:]
hmac.compare_digest(client_hmac, hmac.new(key=self.network_id, msg=client_ephemeral_pk))
def send_server_hello(self):
pass
if __name__ == '__main__':
client = Peer(identity=identity.Identity())
server = Peer(identity=identity.Identity())
client.generate_ephemeral_keys()
print(server.verify_client_hello(client.send_client_hello()))