Example #1
0
 def generate(self, payload):
     return {
             "result" :
                 {
                 "payload" : payload,
                 "cert" : sendBytes(self.cert.dump_certificate()),
                 "signed" :sendBytes(self.sign(json.dumps(payload, sort_keys = True)))
                 }
             }
Example #2
0
    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")
Example #3
0
    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)
Example #4
0
    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')))
Example #5
0
    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))
Example #6
0
    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")
Example #7
0
    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
Example #8
0
    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)
Example #9
0
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