Fixed example bot, updated TL scheme.

Also implemented MTProto 2.0 but don't you dare copy my code without credit lonami <3
This commit is contained in:
Daniil Gentili 2017-12-09 11:39:45 +00:00
parent a5232b5ea7
commit 29a19c173c
6 changed files with 1115 additions and 1085 deletions

View File

@ -46,7 +46,7 @@ class MTProto
/*
const V = 71;
*/
const V = 79;
const V = 80;
const NOT_LOGGED_IN = 0;
const WAITING_CODE = 1;

View File

@ -544,7 +544,10 @@ trait AuthKeyHandler
$encrypted_data = $this->random(16).$message_id.pack('VV', $seq_no, strlen($message_data)).$message_data;
$message_key = substr(sha1($encrypted_data, true), -16);
$padding = $this->random($this->posmod(-strlen($encrypted_data), 16));
list($aes_key, $aes_iv) = $this->aes_calculate($message_key, $this->datacenter->sockets[$datacenter]->auth_key['auth_key']);
//$message_key = substr(hash('sha256', substr($this->datacenter->sockets[$datacenter]->auth_key['auth_key'], 88, 32).$encrypted_data.$padding, true), 8, 16);
list($aes_key, $aes_iv) = $this->old_aes_calculate($message_key, $this->datacenter->sockets[$datacenter]->auth_key['auth_key']);
$encrypted_message = $this->datacenter->sockets[$datacenter]->auth_key['id'].$message_key.$this->ige_encrypt($encrypted_data.$padding, $aes_key, $aes_iv);
$res = $this->method_call('auth.bindTempAuthKey', ['perm_auth_key_id' => $perm_auth_key_id, 'nonce' => $nonce, 'expires_at' => $expires_at, 'encrypted_message' => $encrypted_message], ['message_id' => $message_id, 'datacenter' => $datacenter]);
if ($res === true) {

View File

@ -17,12 +17,24 @@ trait Crypt
public function aes_calculate($msg_key, $auth_key, $direction = 'to server')
{
$x = ($direction === 'to server') ? 0 : 8;
$sha1_a = sha1($msg_key.substr($auth_key, $x, ($x + 32) - $x), true);
$sha1_b = sha1(substr($auth_key, ($x + 32), ($x + 48) - ($x + 32)).$msg_key.substr($auth_key, (48 + $x), (64 + $x) - (48 + $x)), true);
$sha1_c = sha1(substr($auth_key, ($x + 64), ($x + 96) - ($x + 64)).$msg_key, true);
$sha1_d = sha1($msg_key.substr($auth_key, ($x + 96), ($x + 128) - ($x + 96)), true);
$aes_key = substr($sha1_a, 0, 8 - 0).substr($sha1_b, 8, 20 - 8).substr($sha1_c, 4, 16 - 4);
$aes_iv = substr($sha1_a, 8, 20 - 8).substr($sha1_b, 0, 8 - 0).substr($sha1_c, 16, 20 - 16).substr($sha1_d, 0, 8 - 0);
$sha256_a = hash('sha256', $msg_key.substr($auth_key, $x, 36), true);
$sha256_b = hash('sha256', substr($auth_key, 40+$x, 36).$msg_key, true);
$aes_key = substr($sha256_a, 0, 8).substr($sha256_b, 8, 16).substr($sha256_a, 24, 8);
$aes_iv = substr($sha256_b, 0, 8).substr($sha256_a, 8, 16).substr($sha256_b, 24, 8);
return [$aes_key, $aes_iv];
}
public function old_aes_calculate($msg_key, $auth_key, $direction = 'to server')
{
$x = ($direction === 'to server') ? 0 : 8;
$sha1_a = sha1($msg_key.substr($auth_key, $x, 32), true);
$sha1_b = sha1(substr($auth_key, 32 + $x, 16).$msg_key.substr($auth_key, 48 + $x, 16), true);
$sha1_c = sha1(substr($auth_key, 64 + $x, 32).$msg_key, true);
$sha1_d = sha1($msg_key.substr($auth_key, 96 + $x, 32), true);
$aes_key = substr($sha1_a, 0, 8).substr($sha1_b, 8, 12).substr($sha1_c, 4, 12);
$aes_iv = substr($sha1_a, 8, 12).substr($sha1_b, 0, 8).substr($sha1_c, 16, 4).substr($sha1_d, 0, 8);
return [$aes_key, $aes_iv];
}

View File

@ -37,11 +37,14 @@ trait MessageHandler
$message = "\0\0\0\0\0\0\0\0".$message_id.$this->pack_unsigned_int(strlen($message_data)).$message_data;
} else {
$seq_no = $this->generate_out_seq_no($aargs['datacenter'], $content_related);
$data2enc = $this->datacenter->sockets[$aargs['datacenter']]->temp_auth_key['server_salt'].$this->datacenter->sockets[$aargs['datacenter']]->session_id.$message_id.pack('VV', $seq_no, strlen($message_data)).$message_data;
$padding = $this->random($this->posmod(-strlen($data2enc), 16));
$message_key = substr(sha1($data2enc, true), -16);
$plaintext = $this->datacenter->sockets[$aargs['datacenter']]->temp_auth_key['server_salt'].$this->datacenter->sockets[$aargs['datacenter']]->session_id.$message_id.pack('VV', $seq_no, strlen($message_data)).$message_data;
$padding = $this->posmod(-strlen($plaintext), 16);
if ($padding < 12) $padding += 16;
$padding = $this->random($padding);
$message_key = substr(hash('sha256', substr($this->datacenter->sockets[$aargs['datacenter']]->temp_auth_key['auth_key'], 88, 32).$plaintext.$padding, true), 8, 16);
list($aes_key, $aes_iv) = $this->aes_calculate($message_key, $this->datacenter->sockets[$aargs['datacenter']]->temp_auth_key['auth_key']);
$message = $this->datacenter->sockets[$aargs['datacenter']]->temp_auth_key['id'].$message_key.$this->ige_encrypt($data2enc.$padding, $aes_key, $aes_iv);
$message = $this->datacenter->sockets[$aargs['datacenter']]->temp_auth_key['id'].$message_key.$this->ige_encrypt($plaintext.$padding, $aes_key, $aes_iv);
$this->datacenter->sockets[$aargs['datacenter']]->outgoing_messages[$message_id]['seq_no'] = $seq_no;
}
$this->datacenter->sockets[$aargs['datacenter']]->outgoing_messages[$message_id]['response'] = -1;
@ -94,8 +97,12 @@ trait MessageHandler
throw new \danog\MadelineProto\SecurityException('message_data_length is too big');
}
if ((strlen($decrypted_data) - 32) - $message_data_length > 15) {
throw new \danog\MadelineProto\SecurityException('difference between message_data_length and the length of the remaining decrypted buffer is too big');
if ((strlen($decrypted_data) - 32) - $message_data_length < 12) {
throw new \danog\MadelineProto\SecurityException('padding is too small');
}
if ((strlen($decrypted_data) - 32) - $message_data_length > 1024) {
throw new \danog\MadelineProto\SecurityException('padding is too big');
}
if ($message_data_length < 0) {
@ -107,7 +114,7 @@ trait MessageHandler
}
$message_data = substr($decrypted_data, 32, $message_data_length);
if ($message_key != substr(sha1(substr($decrypted_data, 0, 32 + $message_data_length), true), -16)) {
if ($message_key != substr(hash('sha256', substr($this->datacenter->sockets[$datacenter]->temp_auth_key['auth_key'], 96, 32).$decrypted_data, true), 8, 16)) {
throw new \danog\MadelineProto\SecurityException('msg_key mismatch');
}
$this->datacenter->sockets[$datacenter]->incoming_messages[$message_id] = ['seq_no' => $seq_no];

File diff suppressed because it is too large Load Diff

View File

@ -19,6 +19,9 @@ $MadelineProto = false;
try {
$MadelineProto = new \danog\MadelineProto\API('MadelineProto_bot.madeline');
} catch (\danog\MadelineProto\Exception $e) {
$MadelineProto = new \danog\MadelineProto\API($settings);
$authorization = $MadelineProto->bot_login(readline('Enter a bot token: '));
\danog\MadelineProto\Logger::log([$authorization], \danog\MadelineProto\Logger::NOTICE);
}
if (file_exists('token.php') && $MadelineProto === false) {
@ -58,6 +61,8 @@ Row 3 c1 | Row 3 c2 | Row 3 c3
This will create a keyboard exactly like the one used in this message (click the buttons ;D) with the phrase "Text to show in message" instead of this help message.
Created by [Daniil Gentili](mention:@danogentili) (@daniilgentili) using the [MadelineProto PHP MTProto client](daniil.it/MadelineProto).';
echo 'Bot started.'.PHP_EOL;
while (true) {
$updates = $MadelineProto->API->get_updates(['offset' => $offset, 'limit' => 50, 'timeout' => 0]); // Just like in the bot API, you can specify an offset, a limit and a timeout
foreach ($updates as $update) {
@ -106,10 +111,10 @@ while (true) {
array_walk($rows, function (&$value, $key) {
$value = explode('|', $value);
array_walk($value, function (&$value, $key) {
$value = ['text' => trim($value)];
$value = ['text' => trim($value), 'url' => 'https://yayponies.eu'];
});
});
$toset['results'] = [['_' => 'inputBotInlineResult', 'id' => rand(0, pow(2, 31) - 1), 'type' => 'article', 'title' => $text, 'description' => 'Your keyboard', 'send_message' => ['_' => 'inputBotInlineMessageText', 'message' => $text, 'reply_markup' => ['inline_keyboard' => $rows]]]];
$toset['results'] = [['_' => 'inputBotInlineResult', 'id' => (string) random_int(0, pow(2, 31) - 1), 'type' => 'article', 'title' => $text, 'description' => 'Your keyboard', 'send_message' => ['_' => 'inputBotInlineMessageText', 'message' => $text, 'reply_markup' => ['inline_keyboard' => $rows]]]];
$MadelineProto->messages->setInlineBotResults($toset);
}
}