def generate(self, payload): return { "result" : { "payload" : payload, "cert" : sendBytes(self.cert.dump_certificate()), "signed" :sendBytes(self.sign(json.dumps(payload, sort_keys = True))) } }
def handleRequest(self, s, request, client): """Handle a request from a client socket. """ try: logging.info("HANDLING message from %s: %r" % (client, repr(request))) try: req = json.loads(request) except: logging.exception("Invalid message from client") return if not isinstance(req, dict): log(logging.ERROR, "Invalid message format from client") return if 'type' not in req: ok, client.blockChain, req = ourCrypto.verify_integrity( req, client.sessionKeys, client.blockChain) if ok is not True: payload = { "error": "No integrity in package or package malformed", "last_hash": sendBytes(client.blockChain.currentHash) } payload, client.blockChain = ourCrypto.generate_integrity( payload, client.sessionKeys, client.blockChain) client.sendResult(payload) return req = req["payload"] if 'type' not in req: log(logging.ERROR, "Message has no TYPE field") return if req['type'] in self.messageTypes: self.messageTypes[req['type']](req, client) else: log( logging.ERROR, "Invalid message type: " + str(req['type']) + " Should be one of: " + str(self.messageTypes.keys())) client.sendResult({"error": "unknown request"}) except Exception as e: logging.exception("Could not handle request")
def Receipt(self, box, msg): if self.id == None: log_error("No user id, pls create a user\n") return log_info("Sending receipt for message number %s " % str(box)) date = str(int(time.mktime(datetime.utcnow().timetuple()))) msg = msg + "\n" + sendBytes(date) signature = self.cc.sign(msg) payload = { 'type': 'receipt', 'id': self.id, 'msg': str(box), 'receipt': signature, 'date': date, } payload = load_payload(payload) payload, self.blockChain = ourCrypto.generate_integrity( payload, self.sessionKeys, self.blockChain) self.send_to_server(payload) self.socket.settimeout(2) try: response = json.loads(self.socket.recv(BUFSIZE).decode('utf-8')) ok, self.blockChain, response = ourCrypto.verify_integrity( response, self.sessionKeys, self.blockChain) if not ok: print("No integrity of message. Exiting...") sys.exit(-1) response = response["payload"] response = get_bytes(unload_payload(response)) log_error(response.get('error')) except Exception as e: log_success("Receipt was sent\n") self.socket.settimeout(None)
def Create(self): payload = { 'uuid': self.uuid, 'publicKey': self.AsyCypher.getPub(), 'cert': self.cc.cert.dump_certificate(), 'subject_name': self.cc.cert.get_subject(), #'randomId': msgID } payload = load_payload(payload) signature = self.cc.sign(json.dumps(payload, sort_keys=True)) payload["signature"] = sendBytes(signature) payload["type"] = "create" payload, self.blockChain = ourCrypto.generate_integrity( payload, self.sessionKeys, self.blockChain) self.send_to_server(payload) response = json.loads(self.socket.recv(BUFSIZE).decode('utf-8')) ok, self.blockChain, response = ourCrypto.verify_integrity( response, self.sessionKeys, self.blockChain) if not ok: print("No integrity of message. Exiting...") sys.exit(-1) #verificar o msgID se esta na lista de enviados? e verificar assinatura response = response["payload"] response = unload_payload(response) if response.get('error'): log_error(response.get('error').decode(ENCODING)) elif response.get('login'): self.id = response.get('result') log_info(response.get('login').decode(ENCODING)) else: self.id = response.get('result') log_success("Message box with created successfully (ID: %s)" % str(response.get('result')))
def Recv(self, box): if self.id == None: log_error("No user id, pls create/login a user\n") return payload = { 'type': 'recv', 'id': self.id, 'msg': str(box), } payload = load_payload(payload) payload, self.blockChain = ourCrypto.generate_integrity( payload, self.sessionKeys, self.blockChain) self.send_to_server(payload) response = json.loads(self.socket.recv(BUFSIZE).decode('utf-8')) ok, self.blockChain, response = ourCrypto.verify_integrity( response, self.sessionKeys, self.blockChain) if not ok: print("No integrity of message. Exiting...") sys.exit(-1) response = response["payload"] response = unload_payload(response) if response.get('error'): log_error(response.get('error').decode(ENCODING)) else: intermidiate_data = response["payload"][1].split( bytes("\n", "utf-8")) plaintext, padd = self.AsyCypher.decyph(intermidiate_data[0]) log_success("\nMessage: %s \n" % str(plaintext.decode(ENCODING))) self.Receipt(box, plaintext.decode(ENCODING) + "\n" + sendBytes(padd))
def Status(self, box): if self.id == None: log_error("No user id, pls create a user\n") return message = { 'type': 'status', 'id': self.id, 'msg': box, } self.send_to_server(message) response = json.loads(self.socket.recv(BUFSIZE).decode('utf-8')) ok, self.blockChain, response = ourCrypto.verify_integrity( response, self.sessionKeys, self.blockChain) if not ok: print("No integrity of message. Exiting...") sys.exit(-1) response = response["payload"] response = unload_payload(response) valido = False if response.get('error'): log_error(response.get('error').decode(ENCODING)) else: response = response["payload"] msg = response["msg"] receipt = response["receipts"] receiptID = "" valido = False validoCert = False for x in receipt: if receiptID != x["id"]: receiptID = x["id"] list_result = (self.List(receiptID, get_response=True)[0]) signature = recvBytes( list_result["signature"].decode(ENCODING)) del list_result["signature"] try: self.certCertificate = Certificate( recvBytes(list_result["cert"].decode(ENCODING))) list_result["cert"] = list_result["cert"].decode( ENCODING) list_result["publicKey"] = list_result[ "publicKey"].decode(ENCODING) list_result["subject_name"] = list_result[ "subject_name"].decode(ENCODING) log_info("Validating certificate\n") validoCert = self.certCertificate.validate_signature( json.dumps(list_result, sort_keys=True), signature) except Exception as e: pass if validoCert: intermidiate_data = msg.split(bytes("\n", "utf-8")) plaintext, padd = self.AsyCypher.decyph( intermidiate_data[0]) try: receipt_splited = x["receipt"].split( bytes("\n", "utf-8")) time_to_validate = time.gmtime( float( recvBytes( receipt_splited[1].decode(ENCODING)))) time_to_validate = datetime.fromtimestamp( time.mktime(time_to_validate)) signature = recvBytes( receipt_splited[0].decode(ENCODING)) plaintext = plaintext.decode( ENCODING) + "\n" + sendBytes( padd) + "\n" + receipt_splited[1].decode( ENCODING) valido = self.certCertificate.validate_signature( plaintext, signature, time_to_validate=time_to_validate) except Exception as e: raise e if valido: valido = False log_success( "Authenticated receipt. ID-%s\nClient_Date-%s\nServer_Date-%s \n" % (str(x["id"].decode(ENCODING)), str( datetime.fromtimestamp( int( recvBytes(receipt_splited[1].decode( ENCODING))))), str( datetime.fromtimestamp( int( int(x["date"].decode(ENCODING)) / 1000))))) else: log_error( "Unauthenticated receipt. ID-%s\nClient_Date-%s\nServer_Date-%s \n" % (str(x["id"].decode(ENCODING)), str( datetime.fromtimestamp( int( recvBytes(receipt_splited[1].decode( ENCODING))))), str( datetime.fromtimestamp( int( int(x["date"].decode(ENCODING)) / 1000))))) else: log_error( "Information in the description is not reliable \n")
def processSession(self, data, client): log(logging.DEBUG, "%s" % json.dumps(data)) if not set({'type', 'payload', 'signed', 'cert'}).issubset( set(data.keys())): log(logging.ERROR, "Badly formated \"status\" message: " + json.dumps(data)) client.sendResult({"error": "wrong session message format"}) #verificar payload e assinatura if data["payload"]["status"] == 1: try: client.clientCertificate = Certificate( ourCrypto.recvBytes(data["cert"])) valido = client.clientCertificate.validate_signature( json.dumps(data["payload"], sort_keys=True), ourCrypto.recvBytes(data["signed"])) except Exception as e: print(e) payload = { "error": "Client invalid certificate", "randomID": data["payload"]["randomID"] } client.sendResult(client.certServe.generate(payload)) return payload = { "pubKey": ourCrypto.sendPubKey(client.sessionKeys.pubKey), "status": 2, "randomID": data["payload"]["randomID"] } client.sendResult(client.certServe.generate(payload)) return #se tiver valida if data["payload"]["status"] == 2: try: client.clientCertificate = Certificate( ourCrypto.recvBytes(data["cert"])) valido = client.clientCertificate.validate_signature( json.dumps(data["payload"], sort_keys=True), ourCrypto.recvBytes(data["signed"])) except Exception as e: payload = {"error": "Invalida certificate"} client.sendResult(client.certServe.generate(payload)) return peer_pub_key = data["payload"]["pubKey"] client.sessionKeys.getSecret(ourCrypto.recvPubKey(peer_pub_key)) salt = ourCrypto.recvBytes(data["payload"]["salt"]) key, salt = client.sessionKeys.deriveShared(salt) hashS = ourCrypto.recvBytes(data["payload"]["hash"]) del data["payload"]["hash"] serverHash = ourCrypto.generate_hash( 0, '0', json.dumps(data["payload"], sort_keys=True), key) if serverHash == hashS: client.blockChain = Block(0, '0', data["payload"], hashS) payload = {"ack": "yes"} key, salt = client.sessionKeys.deriveShared() payload["salt"] = ourCrypto.sendBytes(salt) client.blockChain.generateNextBlock( json.dumps(payload, sort_keys=True), key) payload["hash"] = ourCrypto.sendBytes( client.blockChain.currentHash) client.sendResult({"result": payload}) return else: log(logging.ERROR, "Badly hash " + json.dumps(data)) payload = {"error": "wrong hash payload"} client.sendResult(client.certServe.generate(payload)) return
def processCreate(self, data, client): log(logging.DEBUG, "%s" % json.dumps(data)) signature = recvBytes(data["signature"]) del data["signature"] del data["type"] try: client.clientCertificate = Certificate(recvBytes(data["cert"])) valido = client.clientCertificate.validate_signature( json.dumps(data, sort_keys=True), signature) print(valido) except Exception as e: raise e data["signature"] = sendBytes(signature) data_error = "" if 'uuid' not in data.keys(): print("no data.keys") log(logging.ERROR, "No \"uuid\" field in \"create\" message: " + json.dumps(data)) data_error = {"error": "wrong message format"} uuid = data['uuid'] if not isinstance(uuid, int): # is it an error ? log( logging.ERROR, "No valid \"uuid\" field in \"create\" message: " + json.dumps(data)) data_error = {"error": "wrong message format"} #esta a usar a userExists para verificar o uuid e o id if self.registry.userExistsUuid(uuid): #do lado do servidor agora os clientes tem uuid e id associados client.id, client.uuid = self.registry.userExistsUuid(uuid) # Comparing certificates just to be sure :) cert_stored = recvBytes( self.registry.listUsers(client.id)[0]['cert']) cert_recived = recvBytes(data["cert"]) if cert_stored == cert_recived: data_error = {"login": "******", "result": client.id} else: data_error = { "error": "You are not who you say you are :) Get Rekt m8" } if data_error: data_error = load_payload(data_error) payload, client.blockChain = ourCrypto.generate_integrity( data_error, client.sessionKeys, client.blockChain) client.sendResult(payload) return me = self.registry.addUser(data) client.id = me.id client.uuid = uuid payload = {"result": me.id} payload = load_payload(payload) payload, client.blockChain = ourCrypto.generate_integrity( payload, client.sessionKeys, client.blockChain) client.sendResult(payload)
def sessionConnect(client): randomID = ourCrypto.randomMsgId() payload = {"status": 1, "randomID": randomID} signature = client.cc.sign(json.dumps(payload, sort_keys=True)) message = { 'type': 'session', 'payload': payload, 'signed': ourCrypto.sendBytes(signature), 'cert': ourCrypto.sendBytes(client.cc.cert.dump_certificate()), } client.send_to_server(message) response = json.loads(client.socket.recv(BUFSIZE).decode('utf-8')) #verificar assinatura e se os randomMsgId sao iguais valido = False try: client.certCertificate = Certificate( ourCrypto.recvBytes(response["result"]["cert"])) log_info("Validation of the server signature.") valido = client.certCertificate.validate_signature( json.dumps(response["result"]["payload"], sort_keys=True), ourCrypto.recvBytes(response["result"]["signed"]), False) except Exception as e: log_error("Session was not established, try again") return False if valido: try: log_error(response["result"]["payload"]["error"]) return False except Exception as e: pass if randomID == response["result"]["payload"]["randomID"]: client.sessionKeys.getSecret( ourCrypto.recvPubKey(response["result"]["payload"]["pubKey"])) else: log_error("Session was not established") return False payload = { "status": 2, "pubKey": ourCrypto.sendPubKey(client.sessionKeys.pubKey) } key, salt = client.sessionKeys.deriveShared() payload["salt"] = ourCrypto.sendBytes(salt) hashS = ourCrypto.generate_hash(0, '0', json.dumps(payload, sort_keys=True), key) client.blockChain = Block(0, '0', payload, hashS) payload["hash"] = ourCrypto.sendBytes(hashS) signature = client.cc.sign(json.dumps(payload, sort_keys=True)) message = { 'type': 'session', 'payload': payload, 'signed': ourCrypto.sendBytes(signature), 'cert': ourCrypto.sendBytes(client.cc.cert.dump_certificate()), } client.send_to_server(message) response = json.loads(client.socket.recv(BUFSIZE).decode('utf-8')) try: log_error(response["result"]["payload"]["error"]) except Exception as e: pass hashS = ourCrypto.recvBytes(response["result"]["hash"]) del response["result"]["hash"] salt = ourCrypto.recvBytes(response["result"]["salt"]) key, salt = client.sessionKeys.deriveShared(salt) if hashS == client.blockChain.isNextBlock( json.dumps(response["result"], sort_keys=True), key): client.blockChain.createNext(hashS) log_success("Session successfully established.") return True else: log_error("Session was not established.") return False