From d55f387c8c89d972c7b18a418df21734b9582442 Mon Sep 17 00:00:00 2001 From: Tom Wang Date: Sun, 29 Mar 2020 23:28:41 -0700 Subject: [PATCH] Update Flowchart.vsd, app_secure_client.py, and 2 more files...Work in Progress --- Flowchart.vsd | Bin 52224 -> 110080 bytes app_secure_client.py | 71 +++++++++++++++++++++++++++++++++++---- app_secure_server.py | 77 +++++++++++++++++++++++-------------------- lib_secure_server.py | 69 +++++++++++++++++++++++++++++++------- 4 files changed, 163 insertions(+), 54 deletions(-) diff --git a/Flowchart.vsd b/Flowchart.vsd index 8100d8edbe70e074518aa9803ed8d354a7165f5b..7dd02b861eb1bda20b6f617607dea892edecccb8 100644 GIT binary patch delta 75000 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%0AX+#P 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 p+VsGuV8Cf%>v$Hd^Gqcb0FsV)C)I-Fq@d%Rb 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 diff --git a/app_secure_client.py b/app_secure_client.py index b7f5e1c..9c04e53 100644 --- a/app_secure_client.py +++ b/app_secure_client.py @@ -13,7 +13,9 @@ import socket import json import io import struct - +import hashlib +from Crypto import Random +from Crypto.PublicKey import RSA def create_request(action, value): if action == "search": @@ -105,6 +107,55 @@ def process_response(sock, addr, jsonheader, _recv_buffer): print(f"got response: {repr(content)}") +def send_client_key(sock, data): + response = { + "content_bytes": data, + "content_type": "binary/custom-server-binary-type", + "content_encoding": "binary", + } + message = _create_message(**response) + print(f'Sending client public key and hash...') + sock.sendall(message) + +def recv_server_secrets(sock, _recv_buffer, key): + HDRLEN = 2 + # read and process protoheader (fixed length of 2 byte in network order) + read_to_buffer(sock, HDRLEN, _recv_buffer) + _jsonheader_len = struct.unpack(">H", _recv_buffer[:HDRLEN])[0] + _recv_buffer = _recv_buffer[HDRLEN:] + + # read and process jsonheader + read_to_buffer(sock, _jsonheader_len, _recv_buffer) + jsonheader = _json_decode(_recv_buffer[:_jsonheader_len], "utf-8") + _recv_buffer = _recv_buffer[_jsonheader_len:] + for reqhdr in ("byteorder", "content-length", "content-type", + "content-encoding",): + if reqhdr not in jsonheader: + raise ValueError(f'Missing required header "{reqhdr}".') + + content_len = jsonheader["content-length"] + read_to_buffer(sock, content_len, _recv_buffer) + data = _recv_buffer[:content_len] + _recv_buffer = _recv_buffer[content_len:] + sesskeyhash = data[-128:] + data = data[:-128] + encryptedsess = data[-256:] + # halfsesskey = key.decrypt(encryptedsess) + data = data[:-256] + pubkeyhash = data[-128:] + pubkey = data[:-128] + if hashlib.sha3_512(pubkey).hexdigest().encode() != pubkeyhash: + sock.shutdown(socket.SHUT_RDWR) + sock.close() + raise Exception('Server public key does not match hash') + if hashlib.sha3_512(halfsesskey).hexdigest().encode() != sesskeyhash: + sock.shutdown(socket.SHUT_RDWR) + sock.close() + raise Exception('Server public key does not match hash') + print(f"Received server secrets correctly.") + return pubkey, halfsesskey + + def main(): HDRLEN = 2 _recv_buffer = bytearray(b"") @@ -114,15 +165,23 @@ def main(): sys.exit(1) host, port = sys.argv[1], int(sys.argv[2]) - action, value = sys.argv[3], sys.argv[4] - request = create_request(action, value) - message = create_message(request) - addr = (host, port) print("starting connection to", addr) sock = socket.create_connection(addr) - sock.settimeout(5) + sock.settimeout(10) + # security handshake + key = RSA.generate(2048, Random.new().read) + publickey = key.publickey().exportKey('PEM') + keyhash = hashlib.sha3_512(publickey).hexdigest().encode() + data = publickey + keyhash + send_client_key(sock, data) + # receiving server secrets - public key and session key + serverkey, sessionkey = recv_server_secrets(sock, _recv_buffer, key) + + action, value = sys.argv[3], sys.argv[4] + request = create_request(action, value) + message = create_message(request) print(f"sending request {repr(message)} to {addr}") sock.sendall(message) diff --git a/app_secure_server.py b/app_secure_server.py index c59f268..0a744da 100644 --- a/app_secure_server.py +++ b/app_secure_server.py @@ -15,46 +15,51 @@ import lib_secure_server as libserver sel = selectors.DefaultSelector() -def accept_wrapper(sock): +def accept_wrapper(sock, passhash): conn, addr = sock.accept() # Should be ready to read print("accepted connection from", addr) conn.setblocking(False) - message = libserver.Message(sel, conn, addr) + message = libserver.Message(sel, conn, addr, passhash) sel.register(conn, selectors.EVENT_READ, data=message) +def main(): + if len(sys.argv) != 3: + print("usage:", sys.argv[0], " ") + sys.exit(1) + with open('password.txt', 'r') as f: + passhash = f.read() + passhash = passhash.encode() # into byte string + host, port = sys.argv[1], int(sys.argv[2]) + lsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + # Avoid bind() exception: OSError: [Errno 48] Address already in use + lsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + lsock.bind((host, port)) + lsock.listen() + print("listening on", (host, port)) + lsock.setblocking(False) + sel.register(lsock, selectors.EVENT_READ, data=None) -if len(sys.argv) != 3: - print("usage:", sys.argv[0], " ") - sys.exit(1) + try: + while True: + events = sel.select(timeout=None) + for key, mask in events: + if key.data is None: + accept_wrapper(key.fileobj, passhash) + else: + message = key.data + try: + message.process_events(mask) + except Exception: + print( + "main: error: exception for", + f"{message.addr}:\n{traceback.format_exc()}", + ) + message.close() + except KeyboardInterrupt: + print("caught keyboard interrupt, exiting") + finally: + sel.close() + lsock.close() -host, port = sys.argv[1], int(sys.argv[2]) -lsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) -# Avoid bind() exception: OSError: [Errno 48] Address already in use -lsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) -lsock.bind((host, port)) -lsock.listen() -print("listening on", (host, port)) -lsock.setblocking(False) -sel.register(lsock, selectors.EVENT_READ, data=None) - -try: - while True: - events = sel.select(timeout=None) - for key, mask in events: - if key.data is None: - accept_wrapper(key.fileobj) - else: - message = key.data - try: - message.process_events(mask) - except Exception: - print( - "main: error: exception for", - f"{message.addr}:\n{traceback.format_exc()}", - ) - message.close() -except KeyboardInterrupt: - print("caught keyboard interrupt, exiting") -finally: - sel.close() - lsock.close() \ No newline at end of file +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/lib_secure_server.py b/lib_secure_server.py index b85391a..331b603 100644 --- a/lib_secure_server.py +++ b/lib_secure_server.py @@ -9,7 +9,12 @@ import sys import selectors import json import io +import os import struct +import hashlib +from Crypto import Random +from Crypto.PublicKey import RSA + request_search = { "morpheus": "Follow the white rabbit. \U0001f430", @@ -19,7 +24,7 @@ request_search = { class Message: - def __init__(self, selector, sock, addr): + def __init__(self, selector, sock, addr, passhash): self.selector = selector self.sock = sock self.addr = addr @@ -29,6 +34,16 @@ class Message: self.jsonheader = None self.request = None self.response_created = False + # added for security + self.key = RSA.generate(2048, Random.new().read) + self.sessionkey = os.urandom(8) + self.passhash = passhash # pass phrase hash + self.clientkey = None # client public key + self.handshake = False + print(f"initiating message associated with {addr}") + + def __del__(self): + print(f"destructing messange associlated with {self.addr}") def _set_selector_events_mask(self, mode): """Set selector to listen for events: mode is 'r', 'w', or 'rw'.""" @@ -120,6 +135,14 @@ class Message: } return response + def _create_handshake_content(self, data): + response = { + "content_bytes": data, + "content_type": "binary/custom-server-binary-type", + "content_encoding": "binary", + } + return response + def process_events(self, mask): if mask & selectors.EVENT_READ: self.read() @@ -148,7 +171,7 @@ class Message: self._write() def close(self): - print("closing connection to", self.addr) + print(f"closing connection to {self.addr}\n") try: self.selector.unregister(self.sock) except Exception as e: @@ -192,23 +215,45 @@ class Message: if reqhdr not in self.jsonheader: raise ValueError(f'Missing required header "{reqhdr}".') + def send_my_secrets(self): + halfsesskey = self.sessionkey + encryptedsess = self.clientkey.encrypt(halfsesskey, None)[0] + sesskeyhash = hashlib.sha3_512(halfsesskey).hexdigest().encode() + mypubkey = self.key.publickey().exportKey() + mypubkeyhash = hashlib.sha3_512(mypubkey).hexdigest().encode() + mysecret = mypubkey + mypubkeyhash + encryptedsess + sesskeyhash + response = self._create_handshake_content(mysecret) + message = self._create_message(**response) + self._send_buffer += message + print(f'Sending server public key, hash, session key, hash...') + def process_request(self): content_len = self.jsonheader["content-length"] if not len(self._recv_buffer) >= content_len: return data = self._recv_buffer[:content_len] self._recv_buffer = self._recv_buffer[content_len:] - if self.jsonheader["content-type"] == "text/json": - encoding = self.jsonheader["content-encoding"] - self.request = self._json_decode(data, encoding) - print("received request", repr(self.request), "from", self.addr) + if not self.handshake: # data is client public key plus hash + key = data[:-128] + keyhash = data[-128:] + if hashlib.sha3_512(key).hexdigest().encode() == keyhash: + self.clientkey = RSA.importKey(key) + else: + self.sock.close() + raise Exception('Client plublic key does not match key hash') + self.send_my_secrets() else: - # Binary or unknown content-type - self.request = data - print( - f'received {self.jsonheader["content-type"]} request from', - self.addr, - ) + if self.jsonheader["content-type"] == "text/json": + encoding = self.jsonheader["content-encoding"] + self.request = self._json_decode(data, encoding) + print("received request", repr(self.request), "from", self.addr) + else: + # Binary or unknown content-type + self.request = data + print( + f'received {self.jsonheader["content-type"]} request from', + self.addr, + ) # Set selector to listen for write events, we're done reading. self._set_selector_events_mask("w")