83 lines
2.6 KiB
Python
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())) |