async def complete_rekey(self, peer,
                             action: DecryptedMessageActionCommitKey):
        peer = self.get_secret_chat(peer)
        if peer.rekeying[0] != 2 or self.temp_rekeyed_secret_chats.get(
                action.exchange_id, None):
            return
        if self.temp_rekeyed_secret_chats.get(
                action.exchange_id) != action.key_fingerprint:
            message = DecryptedMessageService(
                action=DecryptedMessageActionAbortKey(
                    exchange_id=action.exchange_id, ))
            message = await self.encrypt_secret_message(peer, message)
            await self.client(
                SendEncryptedServiceRequest(
                    InputEncryptedChat(peer.id, peer.access_hash), message))
            raise SecurityError("Invalid Key fingerprint")

        self._log.debug(f'Completing rekeying secret chat {peer}')
        peer.rekeying = [0]
        peer.auth_key = self.temp_rekeyed_secret_chats[action.exchange_id]
        peer.ttr = 100
        peer.updated = time()
        del self.temp_rekeyed_secret_chats[action.exchange_id]
        message = DecryptedMessageService(action=DecryptedMessageActionNoop())
        message = await self.encrypt_secret_message(peer, message)
        await self.client(
            SendEncryptedServiceRequest(
                InputEncryptedChat(peer.id, peer.access_hash), message))
        self._log.debug(f'Secret chat {peer} rekeyed succrsfully')
Exemplo n.º 2
0
 async def commit_rekey(self, peer, action: DecryptedMessageActionAcceptKey):
     peer = self.get_secret_chat(peer)
     if peer.rekeying[0] != 1 or not self._temp_rekeyed_secret_chats.get(action.exchange_id, None):
         peer.rekeying = [0]
         return
     self._log.debug(f'Committing rekeying secret chat {peer}')
     dh_config = await self.get_dh_config()
     g_b = int.from_bytes(action.g_b, 'big', signed=False)
     self.check_g_a(g_b, dh_config.p)
     res = pow(g_b, self._temp_rekeyed_secret_chats[action.exchange_id], dh_config.p)
     auth_key = res.to_bytes(256, 'big', signed=False)
     key_fingerprint = struct.unpack('<q', sha1(auth_key).digest()[-8:])[0]
     if key_fingerprint != action.key_fingerprint:
         message = DecryptedMessageService(action=DecryptedMessageActionAbortKey(
             exchange_id=action.exchange_id,
         ))
         message = await self.encrypt_secret_message(peer, message)
         await self.client(SendEncryptedServiceRequest(InputEncryptedChat(peer.id, peer.access_hash), message))
         raise SecurityError("Invalid Key fingerprint")
     message = DecryptedMessageService(action=DecryptedMessageActionCommitKey(
         exchange_id=action.exchange_id,
         key_fingerprint=key_fingerprint
     ))
     message = await self.encrypt_secret_message(peer, message)
     await self.client(SendEncryptedServiceRequest(InputEncryptedChat(peer.id, peer.access_hash), message))
     del self._temp_rekeyed_secret_chats[action.exchange_id]
     peer.rekeying = [0]
     peer.auth_key = auth_key
     peer.ttl = 100
     peer.updated = time()
 async def accept_rekey(self, peer,
                        action: DecryptedMessageActionRequestKey):
     peer = self.get_secret_chat(peer)
     if peer.rekeying[0] != 0:
         my_exchange_id = peer.rekeying[1]
         other_exchange_id = action.exchange_id
         if my_exchange_id > other_exchange_id:
             return
         if my_exchange_id == other_exchange_id:
             peer.rekeying = [0]
             return
     self._log.debug(f'Accepting rekeying secret chat {peer}')
     dh_config = await self.get_dh_config()
     random_bytes = os.urandom(256)
     b = int.from_bytes(random_bytes, byteorder="big", signed=False)
     g_a = int.from_bytes(action.g_a, 'big', signed=False)
     self.check_g_a(g_a, dh_config.p)
     res = pow(g_a, b, dh_config.p)
     auth_key = res.to_bytes(256, 'big', signed=False)
     key_fingerprint = struct.unpack('<q', sha1(auth_key).digest()[-8:])[0]
     self.temp_rekeyed_secret_chats[action.exchange_id] = auth_key
     peer.rekeying = [2, action.exchange_id]
     g_b = pow(dh_config.g, b, dh_config.p)
     self.check_g_a(g_b, dh_config.p)
     message = DecryptedMessageService(
         action=DecryptedMessageActionAcceptKey(
             g_b=g_b.to_bytes(256, 'big', signed=False),
             exchange_id=action.exchange_id,
             key_fingerprint=key_fingerprint))
     message = await self.encrypt_secret_message(peer, message)
     await self.client(
         SendEncryptedServiceRequest(
             InputEncryptedChat(peer.id, peer.access_hash), message))
Exemplo n.º 4
0
 async def notify_layer(self, peer: [int, SecretChat, InputEncryptedChat, EncryptedChat]):
     peer = self.get_secret_chat(peer)
     if peer.layer == 8:
         return
     message = DecryptedMessageService8(action=DecryptedMessageActionNotifyLayer(
         layer=min(DEFAULT_LAYER, peer.layer)), random_bytes=os.urandom(15 + 4 * random.randint(0, 2)))
     data = await self.encrypt_secret_message(peer.id, message)
     return await self.client(
         SendEncryptedServiceRequest(peer=InputEncryptedChat(peer.id, peer.access_hash),
                                     data=data))
Exemplo n.º 5
0
    async def rekey(self, peer):
        peer = self.get_secret_chat(peer)
        self._log.debug(f'Rekeying secret chat {peer}')
        dh_config = await self.get_dh_config()
        a = int.from_bytes(os.urandom(256), 'big', signed=False)
        g_a = pow(dh_config.g, a, dh_config.p)
        self.check_g_a(g_a, dh_config.p)
        e = random.randint(10000000, 99999999)
        self._temp_rekeyed_secret_chats[e] = a
        peer.rekeying = [1, e]
        message = DecryptedMessageService(action=DecryptedMessageActionRequestKey(
            g_a=g_a.to_bytes(256, 'big', signed=False),
            exchange_id=e,
        ))
        message = await self.encrypt_secret_message(peer, message)
        await self.client(SendEncryptedServiceRequest(InputEncryptedChat(peer.id, peer.access_hash), message))

        return e