mirror of
https://github.com/danog/MadelineProto.git
synced 2024-11-30 07:18:57 +01:00
Finish refactoring
This commit is contained in:
parent
a01fa820c6
commit
b0ab083367
@ -554,7 +554,7 @@ final class MTProto implements TLCallback, LoggerGetter
|
||||
private ?string $tmpDbPrefix = null;
|
||||
|
||||
/** @internal */
|
||||
protected function getDbPrefix(): string
|
||||
public function getDbPrefix(): string
|
||||
{
|
||||
$prefix = $this->getSelf()['id'] ?? null;
|
||||
if (!$prefix) {
|
||||
@ -636,9 +636,8 @@ final class MTProto implements TLCallback, LoggerGetter
|
||||
'TL',
|
||||
|
||||
// Secret chats
|
||||
'secret_chats',
|
||||
'secretChats',
|
||||
'temp_requested_secret_chats',
|
||||
'temp_rekeyed_secret_chats',
|
||||
|
||||
// Report URI
|
||||
'reportDest',
|
||||
@ -803,7 +802,7 @@ final class MTProto implements TLCallback, LoggerGetter
|
||||
$db []= async($this->minDatabase->init(...));
|
||||
$db []= async($this->peerDatabase->init(...));
|
||||
$db []= async($this->initDb(...), $this);
|
||||
foreach ($this->secret_chats as $chat) {
|
||||
foreach ($this->secretChats as $chat) {
|
||||
$db []= async($chat->init(...));
|
||||
}
|
||||
await($db);
|
||||
@ -857,12 +856,9 @@ final class MTProto implements TLCallback, LoggerGetter
|
||||
$this->config = ['expires' => -1];
|
||||
$this->dh_config = ['version' => 0];
|
||||
$this->initialize($this->settings);
|
||||
foreach ($this->secret_chats as $chat => &$data) {
|
||||
$data['chat_id'] = $chat;
|
||||
foreach ($this->secretChats as $chat) {
|
||||
try {
|
||||
if (isset($this->secret_chats[$chat]) && $this->secret_chats[$chat]['InputEncryptedChat'] !== null) {
|
||||
$this->notifyLayer($chat);
|
||||
}
|
||||
$chat->notifyLayer();
|
||||
} catch (RPCErrorException $e) {
|
||||
}
|
||||
}
|
||||
|
@ -1035,12 +1035,11 @@ trait UpdateHandler
|
||||
$this->logger->logger('Applying qts: '.$update['qts'].' over current qts '.$cur_state->qts().', chat id: '.$update['message']['chat_id'], Logger::VERBOSE);
|
||||
$this->methodCallAsyncRead('messages.receivedQueue', ['max_qts' => $cur_state->qts($update['qts'])]);
|
||||
}
|
||||
if (!isset($this->secret_chats[$update['message']['chat_id']])) {
|
||||
if (!isset($this->secretChats[$update['message']['chat_id']])) {
|
||||
$this->logger->logger(\sprintf(Lang::$current_lang['secret_chat_skipping'], $update['message']['chat_id']));
|
||||
return;
|
||||
}
|
||||
$this->secretFeeders[$update['message']['chat_id']]->feed($update);
|
||||
$this->secretFeeders[$update['message']['chat_id']]->resume();
|
||||
$this->secretChats[$update['message']['chat_id']]->feed($update);
|
||||
return;
|
||||
}
|
||||
if ($update['_'] === 'updateEncryption') {
|
||||
@ -1058,15 +1057,7 @@ trait UpdateHandler
|
||||
break;
|
||||
case 'encryptedChatDiscarded':
|
||||
$this->logger->logger('Deleting secret chat '.$update['chat']['id'].' because it was revoked by the other user (it was probably accepted by another client)', Logger::NOTICE);
|
||||
if (isset($this->secret_chats[$update['chat']['id']])) {
|
||||
unset($this->secret_chats[$update['chat']['id']]);
|
||||
}
|
||||
if (isset($this->temp_requested_secret_chats[$update['chat']['id']])) {
|
||||
unset($this->temp_requested_secret_chats[$update['chat']['id']]);
|
||||
}
|
||||
if (isset($this->temp_rekeyed_secret_chats[$update['chat']['id']])) {
|
||||
unset($this->temp_rekeyed_secret_chats[$update['chat']['id']]);
|
||||
}
|
||||
$this->discardSecretChat($update['chat']['id']);
|
||||
break;
|
||||
case 'encryptedChat':
|
||||
$this->logger->logger('Completing creation of secret chat '.$update['chat']['id'], Logger::NOTICE);
|
||||
|
@ -51,7 +51,7 @@ trait AuthKeyHandler
|
||||
*
|
||||
* @var array<int, SecretChatController>
|
||||
*/
|
||||
public array $secret_chats = [];
|
||||
public array $secretChats = [];
|
||||
/**
|
||||
* Request secret chat.
|
||||
*
|
||||
@ -84,7 +84,7 @@ trait AuthKeyHandler
|
||||
*/
|
||||
public function acceptSecretChat(array $params): void
|
||||
{
|
||||
if ($this->secretChatStatus($params['id']) !== 0) {
|
||||
if (isset($this->secretChats[$params['id']])) {
|
||||
$this->logger->logger("I've already accepted secret chat ".$params['id']);
|
||||
return;
|
||||
}
|
||||
@ -98,7 +98,7 @@ trait AuthKeyHandler
|
||||
$key['fingerprint'] = \substr(\sha1($key['auth_key'], true), -8);
|
||||
$key['visualization_orig'] = \substr(\sha1($key['auth_key'], true), 16);
|
||||
$key['visualization_46'] = \substr(\hash('sha256', $key['auth_key'], true), 20);
|
||||
$this->secret_chats[$params['id']] = new SecretChatController(
|
||||
$this->secretChats[$params['id']] = $chat = new SecretChatController(
|
||||
$this,
|
||||
$key,
|
||||
$params['id'],
|
||||
@ -109,7 +109,7 @@ trait AuthKeyHandler
|
||||
$g_b = $dh_config['g']->powMod($b, $dh_config['p']);
|
||||
Crypt::checkG($g_b, $dh_config['p']);
|
||||
$this->methodCallAsyncRead('messages.acceptEncryption', ['peer' => $params['id'], 'g_b' => $g_b->toBytes(), 'key_fingerprint' => $key['fingerprint']]);
|
||||
$this->notifyLayer($params['id']);
|
||||
$chat->notifyLayer();
|
||||
$this->logger->logger('Secret chat '.$params['id'].' accepted successfully!', Logger::NOTICE);
|
||||
}
|
||||
/**
|
||||
@ -119,7 +119,7 @@ trait AuthKeyHandler
|
||||
*/
|
||||
private function completeSecretChat(array $params)
|
||||
{
|
||||
if ($this->secretChatStatus($params['id']) !== 1) {
|
||||
if (!isset($this->temp_requested_secret_chats[$params['id']])) {
|
||||
//$this->logger->logger($this->secretChatStatus($params['id']));
|
||||
$this->logger->logger('Could not find and complete secret chat '.$params['id']);
|
||||
return false;
|
||||
@ -137,14 +137,13 @@ trait AuthKeyHandler
|
||||
}
|
||||
$key['visualization_orig'] = \substr(\sha1($key['auth_key'], true), 16);
|
||||
$key['visualization_46'] = \substr(\hash('sha256', $key['auth_key'], true), 20);
|
||||
$this->secret_chats[$params['id']] = $chat = new SecretChatController(
|
||||
$this->secretChats[$params['id']] = $chat = new SecretChatController(
|
||||
$this,
|
||||
$key,
|
||||
$params['id'],
|
||||
$params['access_hash'],
|
||||
true,
|
||||
$params['participant_id'],
|
||||
\time(),
|
||||
);
|
||||
$chat->notifyLayer();
|
||||
$this->logger->logger('Secret chat '.$params['id'].' completed successfully!', Logger::NOTICE);
|
||||
@ -186,7 +185,7 @@ trait AuthKeyHandler
|
||||
} elseif (DialogId::isSecretChat($chat)) {
|
||||
$chat = DialogId::toSecretChatId($chat);
|
||||
}
|
||||
return $this->secret_chats[$chat];
|
||||
return $this->secretChats[$chat];
|
||||
}
|
||||
/**
|
||||
* Check whether secret chat exists.
|
||||
@ -195,7 +194,7 @@ trait AuthKeyHandler
|
||||
*/
|
||||
public function hasSecretChat(array|int $chat): bool
|
||||
{
|
||||
return isset($this->secret_chats[\is_array($chat) ? $chat['chat_id'] : $chat]);
|
||||
return isset($this->secretChats[\is_array($chat) ? $chat['chat_id'] : $chat]);
|
||||
}
|
||||
/**
|
||||
* Discard secret chat.
|
||||
@ -205,8 +204,8 @@ trait AuthKeyHandler
|
||||
public function discardSecretChat(int $chat): void
|
||||
{
|
||||
$this->logger->logger('Discarding secret chat '.$chat.'...', Logger::VERBOSE);
|
||||
if (isset($this->secret_chats[$chat])) {
|
||||
unset($this->secret_chats[$chat]);
|
||||
if (isset($this->secretChats[$chat])) {
|
||||
unset($this->secretChats[$chat]);
|
||||
}
|
||||
if (isset($this->temp_requested_secret_chats[$chat])) {
|
||||
unset($this->temp_requested_secret_chats[$chat]);
|
||||
|
@ -130,6 +130,11 @@ final class SecretChatController implements Stringable
|
||||
$this->init();
|
||||
}
|
||||
|
||||
public function feed(array $update): void
|
||||
{
|
||||
$this->feedLoop->feed($update);
|
||||
$this->feedLoop->resume();
|
||||
}
|
||||
public function init(): void
|
||||
{
|
||||
$this->initDb($this->API);
|
||||
@ -187,7 +192,7 @@ final class SecretChatController implements Stringable
|
||||
$this->rekeyState = RekeyState::REQUESTED;
|
||||
$this->rekeyExchangeId = Tools::randomInt();
|
||||
$this->rekeyParam = $a;
|
||||
$this->API->methodCallAsyncRead('messages.sendEncryptedService', ['peer' => $this->id, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionRequestKey', 'g_a' => $g_a->toBytes(), 'exchange_id' => $e]]]);
|
||||
$this->API->methodCallAsyncRead('messages.sendEncryptedService', ['peer' => $this->id, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionRequestKey', 'g_a' => $g_a->toBytes(), 'exchange_id' => $this->rekeyExchangeId]]]);
|
||||
$this->API->updaters[UpdateLoop::GENERIC]->resume();
|
||||
} finally {
|
||||
EventLoop::queue($lock->release(...));
|
||||
@ -251,6 +256,7 @@ final class SecretChatController implements Stringable
|
||||
$dh_config = ($this->API->getDhConfig());
|
||||
$params['g_b'] = new BigInteger((string) $params['g_b'], 256);
|
||||
Crypt::checkG($params['g_b'], $dh_config['p']);
|
||||
assert($this->rekeyParam !== null);
|
||||
$key = ['auth_key' => \str_pad($params['g_b']->powMod($this->rekeyParam, $dh_config['p'])->toBytes(), 256, \chr(0), STR_PAD_LEFT)];
|
||||
$key['fingerprint'] = \substr(\sha1($key['auth_key'], true), -8);
|
||||
$key['visualization_orig'] = $this->key['visualization_orig'];
|
||||
@ -282,6 +288,7 @@ final class SecretChatController implements Stringable
|
||||
if ($this->rekeyState !== RekeyState::ACCEPTED || $this->rekeyExchangeId !== $params['exchange_id']) {
|
||||
return;
|
||||
}
|
||||
assert($this->rekeyKey !== null);
|
||||
if ($this->rekeyKey['fingerprint'] !== $params['key_fingerprint']) {
|
||||
$this->API->methodCallAsyncRead('messages.sendEncryptedService', ['peer' => $this->id, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionAbortKey', 'exchange_id' => $params['exchange_id']]]]);
|
||||
throw new SecurityException('Invalid key fingerprint!');
|
||||
@ -488,7 +495,9 @@ final class SecretChatController implements Stringable
|
||||
|
||||
private function tryMTProtoV1Decrypt(string $message_key, bool $old, string $encrypted_data): string
|
||||
{
|
||||
[$aes_key, $aes_iv] = Crypt::oldKdf($message_key, ($old ? $this->oldKey : $this->key)['auth_key'], true);
|
||||
$key = $old ? $this->oldKey : $this->key;
|
||||
assert($key !== null);
|
||||
[$aes_key, $aes_iv] = Crypt::oldKdf($message_key, $key['auth_key'], true);
|
||||
$decrypted_data = Crypt::igeDecrypt($encrypted_data, $aes_key, $aes_iv);
|
||||
$message_data_length = \unpack('V', \substr($decrypted_data, 0, 4))[1];
|
||||
$message_data = \substr($decrypted_data, 4, $message_data_length);
|
||||
@ -509,7 +518,9 @@ final class SecretChatController implements Stringable
|
||||
|
||||
private function tryMTProtoV2Decrypt(string $message_key, bool $old, string $encrypted_data): string
|
||||
{
|
||||
$key = ($old ? $this->oldKey : $this->key)['auth_key'];
|
||||
$key = $old ? $this->oldKey : $this->key;
|
||||
assert($key !== null);
|
||||
$key = $key['auth_key'];
|
||||
[$aes_key, $aes_iv] = Crypt::kdf($message_key, $key, !$this->public->creator);
|
||||
$decrypted_data = Crypt::igeDecrypt($encrypted_data, $aes_key, $aes_iv);
|
||||
if ($message_key != \substr(\hash('sha256', \substr($key, 88 + ($this->public->creator ? 8 : 0), 32).$decrypted_data, true), 8, 16)) {
|
||||
|
Loading…
Reference in New Issue
Block a user