def save_contact(self): global contacts if self.username_line.text() and self.name_line.text(): username = self.username_line.text() readable_name = self.name_line.text() picture = Image.open(self.picture_path) if not list(filter(lambda x: x.username == username, contacts)): if len(username) == username_len: filename = "img/" + username + ".png" picture.save(filename) contact = Contact(username, readable_name, filename) session.add(contact) session.commit() contacts.append(Contact(readable_name, username, picture)) self.parent.update_contacts_list() self.parent.on_list_label.hide() self.close() else: QtWidgets.QMessageBox().critical( self, " ", f"Username should contain of {username_len} characters" ) else: QtWidgets.QMessageBox().critical( self, " ", "Contact with this username already exists") else: QtWidgets.QMessageBox().critical(self, " ", "Fill all the lines")
def cache_messages(self, messages): session = db_session.create_session() for m in messages: m.chat_id = self.current_chat.chat_id cached_message = session.query(Message).filter( Message.unix_time == m.unix_time and Message.chat_id == m.chat_id).first() if not cached_message: session.add(m) session.commit()
def decrypt_data(self, data, key, signature, username): from constants import credentials, session, config from data.users import User unpadder = padding.PKCS7(128).unpadder() my_private = serialization.load_pem_private_key(open(hashlib.sha512(bytes(self.credentials["login"], "utf-8")).hexdigest() + ".pem", "rb").read(), password=bytes(self.credentials["password"], "utf-8"), backend=default_backend()) if username == self.credentials["username"]: public_key = my_private.public_key() else: cached_user = session.query(User).filter(User.username == username).first() if cached_user: pub_response = {"status": "OK", "public_key": cached_user.public_key} else: pub_response = self.get_public_key(username) user = User() user.username = username user.public_key = pub_response["public_key"] session.add(user) session.commit() if pub_response["status"] == "OK": public_key = serialization.load_pem_public_key(bytes(pub_response["public_key"], "utf-8"), backend=default_backend()) else: return {"status": "error", "error": "Error getting users public key"} key_iv = my_private.decrypt( bytes.fromhex(key), asymmetric_padding.OAEP( mgf=asymmetric_padding.MGF1(algorithm=hashes.SHA512()), algorithm=hashes.SHA512(), label=None ) ) key = key_iv[:32] iv = key_iv[32:] cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()) decryptor = cipher.decryptor() decrypted_data = decryptor.update(bytes.fromhex(data)) + decryptor.finalize() decrypted_data = unpadder.update(decrypted_data) + unpadder.finalize() public_key.verify( bytes.fromhex(signature), hashlib.sha512(decrypted_data).digest(), asymmetric_padding.PSS( mgf=asymmetric_padding.MGF1(hashes.SHA512()), salt_length=asymmetric_padding.PSS.MAX_LENGTH ), hashes.SHA512() ) payload = { "status": "OK", "data": decrypted_data, "sent_by": username, "key": key_iv.hex(), "signature": signature } return payload
def cache_chats(self, chats): session = db_session.create_session() for chat in chats: cached_chat = session.query(Chat).filter(Chat == chat).first() if not cached_chat: chat.last_message = json.dumps(chat.last_message) session.add(chat) elif cached_chat.unix_time != chat.unix_time: cached_chat.unix_time = chat.unix_time cached_chat.last_message = json.dumps(chat.last_message) session.merge(cached_chat) session.commit()
def complete_sending_message(self, response): row = response[1] if response[0]["status"] == "OK": self.messages_list.itemWidget( self.messages_list.item(row)).message_status_label.setPixmap( QtGui.QPixmap("img/message_sent_server.png").scaled( 20, 20, transformMode=QtCore.Qt.SmoothTransformation)) message = response[2] message.unix_time = response[0]["send_time"] session.merge(message) session.commit() else: logging.error("error sending the message: " + response[0]["error"])
def update_statuses(self, messages): try: session = db_session.create_session() for n, message in enumerate(messages): cached_message = session.query(Message).filter( Message.unix_time == message.unix_time and Message.chat_id == message.chat_id).first() if cached_message is not None: if cached_message.viewed != message.viewed: self.messages_list.itemWidget( self.messages_list.item(n) ).message_status_label.setPixmap( QtGui.QPixmap("img/message_delivered.png").scaled( 20, 20, transformMode=QtCore.Qt.SmoothTransformation)) cached_message.viewed = message.viewed if cached_message.type == MessageTypes.Document: cached_message.data = message.data session.commit() except Exception as e: logging.warning(e)
def encrypt_data(self, data, username): from constants import session, config from data.users import User cached_user = session.query(User).filter(User.username == username).first() if cached_user: response = {"status": "OK", "public_key": cached_user.public_key} else: response = self.get_public_key(username) if response["status"] == "OK": user = User() user.username = username user.public_key = response["public_key"] session.add(user) session.commit() else: print(response["error"]) return {"status": "error", "error": response["error"]} if response["status"] == "OK": # Pad data padder = padding.PKCS7(128).padder() padded_data = padder.update(data) + padder.finalize() # Define backend and key + iv backend = default_backend() key = os.urandom(32) iv = os.urandom(16) key_iv = key + iv # Encrypt all data cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend) encryptor = cipher.encryptor() encrypted_data = encryptor.update(padded_data) + encryptor.finalize() # Get public key of user users_pub = serialization.load_pem_public_key(bytes(response["public_key"], "utf-8"), backend=default_backend()) # Get your private and public keys my_private = serialization.load_pem_private_key(open(hashlib.sha512(bytes(self.credentials["login"], "utf-8")).hexdigest() + ".pem", "rb").read(), password=bytes(self.credentials["password"], "utf-8"), backend=default_backend()) my_pub = my_private.public_key() # Encrypt keys user_encrypted_key = users_pub.encrypt( key_iv, asymmetric_padding.OAEP( mgf=asymmetric_padding.MGF1(algorithm=hashes.SHA512()), algorithm=hashes.SHA512(), label=None ) ) my_encrypted_key = my_pub.encrypt( key_iv, asymmetric_padding.OAEP( mgf=asymmetric_padding.MGF1(algorithm=hashes.SHA512()), algorithm=hashes.SHA512(), label=None ) ) # Sign hash of data signature = my_private.sign( hashlib.sha512(data).digest(), asymmetric_padding.PSS( mgf=asymmetric_padding.MGF1(hashes.SHA512()), salt_length=asymmetric_padding.PSS.MAX_LENGTH ), hashes.SHA512() ) users_keys = {username: user_encrypted_key.hex(), self.credentials["username"]: my_encrypted_key.hex()} payload = { "status": "OK", "data": encrypted_data.hex(), "signature": signature.hex(), "keys": users_keys } return payload else: return {"status": "error", "error": response["error"]}