Finally fixed authorization
This commit is contained in:
parent
2bc5dc62b7
commit
f99f432056
@ -13,8 +13,6 @@ Here all of the things that still have to be done in this library.
|
|||||||
You can (and you are also encouraged to) contribute by completing any of the following points.
|
You can (and you are also encouraged to) contribute by completing any of the following points.
|
||||||
The importance of each item will range from 1 to 5. It's better to start from the most important items.
|
The importance of each item will range from 1 to 5. It's better to start from the most important items.
|
||||||
|
|
||||||
* In Session.php, complete the function that creates the authorization key (5).
|
|
||||||
* In Crypto.php or aes256.php, choose which of the ige implementation to use and complete it (4).
|
|
||||||
* In Session.php and TL, manage rpc errors, notifications, error codes and basically everything that isn't a normal response (4).
|
* In Session.php and TL, manage rpc errors, notifications, error codes and basically everything that isn't a normal response (4).
|
||||||
* In Connection.php and Session.php, add support for http, https and (maybe) udp connections and fix tcp intermediate connections (3).
|
* In Connection.php and Session.php, add support for http, https and (maybe) udp connections and fix tcp intermediate connections (3).
|
||||||
* In API.php, complete a decent authorization flow that supports both bots and normal users (2).
|
* In API.php, complete a decent authorization flow that supports both bots and normal users (2).
|
||||||
|
@ -21,8 +21,8 @@ class API extends Exception
|
|||||||
set_error_handler([$this, 'ExceptionErrorHandler']);
|
set_error_handler([$this, 'ExceptionErrorHandler']);
|
||||||
$this->session = new Session($params);
|
$this->session = new Session($params);
|
||||||
$this->session->create_auth_key();
|
$this->session->create_auth_key();
|
||||||
$future_salts = $this->session->method_call('get_future_salts', 3);
|
$future_salts = $this->get_future_salts(3);
|
||||||
Logging::log($future_salts, 3);
|
$this->session->log->log($future_salts);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __destruct()
|
public function __destruct()
|
||||||
@ -33,6 +33,6 @@ class API extends Exception
|
|||||||
|
|
||||||
public function __call($name, $arguments)
|
public function __call($name, $arguments)
|
||||||
{
|
{
|
||||||
return $session->method_call($name, $arguments);
|
return $this->session->method_call($name, $arguments);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@ class Crypt
|
|||||||
}
|
}
|
||||||
$cipher = new \phpseclib\Crypt\AES(\phpseclib\Crypt\AES::MODE_ECB);
|
$cipher = new \phpseclib\Crypt\AES(\phpseclib\Crypt\AES::MODE_ECB);
|
||||||
$cipher->setKey($key);
|
$cipher->setKey($key);
|
||||||
|
$cipher->paddable = false;
|
||||||
$blocksize = $cipher->block_size;
|
$blocksize = $cipher->block_size;
|
||||||
if ((strlen($message) % $blocksize) != 0) {
|
if ((strlen($message) % $blocksize) != 0) {
|
||||||
throw new Exception('message must be a multiple of 16 bytes (try adding '.(16 - (strlen($message) % 16)).' bytes of padding)');
|
throw new Exception('message must be a multiple of 16 bytes (try adding '.(16 - (strlen($message) % 16)).' bytes of padding)');
|
||||||
|
@ -61,6 +61,9 @@ class Logging
|
|||||||
$mode = $this->mode;
|
$mode = $this->mode;
|
||||||
}
|
}
|
||||||
foreach ($params as $param) {
|
foreach ($params as $param) {
|
||||||
|
if (!is_string($param)) {
|
||||||
|
$param = var_export($param, true);
|
||||||
|
}
|
||||||
switch ($mode) {
|
switch ($mode) {
|
||||||
case '1':
|
case '1':
|
||||||
error_log($param);
|
error_log($param);
|
||||||
|
@ -108,7 +108,7 @@ Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB
|
|||||||
$encrypted_data =
|
$encrypted_data =
|
||||||
$this->server_salt.$this->session_id.$message_id.$this->struct->pack('<II', $this->number, strlen($message_data)).$message_data;
|
$this->server_salt.$this->session_id.$message_id.$this->struct->pack('<II', $this->number, strlen($message_data)).$message_data;
|
||||||
$message_key = substr(sha1($encrypted_data, true), -16);
|
$message_key = substr(sha1($encrypted_data, true), -16);
|
||||||
$padding = \phpseclib\Crypt\Random::string(posmod(-strlen($encrypted_data), 16));
|
$padding = \phpseclib\Crypt\Random::string(Tools::posmod(-strlen($encrypted_data), 16));
|
||||||
$this->log->log(strlen($encrypted_data.$padding));
|
$this->log->log(strlen($encrypted_data.$padding));
|
||||||
list($aes_key, $aes_iv) = $this->aes_calculate($message_key);
|
list($aes_key, $aes_iv) = $this->aes_calculate($message_key);
|
||||||
$message = $this->auth_key_id.$message_key.Crypt::ige_encrypt($encrypted_data.$padding, $aes_key, $aes_iv);
|
$message = $this->auth_key_id.$message_key.Crypt::ige_encrypt($encrypted_data.$padding, $aes_key, $aes_iv);
|
||||||
@ -306,7 +306,6 @@ Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB
|
|||||||
$tmp_aes_key = sha1($new_nonce.$server_nonce, true).substr(sha1($server_nonce.$new_nonce, true), 0, 12);
|
$tmp_aes_key = sha1($new_nonce.$server_nonce, true).substr(sha1($server_nonce.$new_nonce, true), 0, 12);
|
||||||
$tmp_aes_iv = substr(sha1($server_nonce.$new_nonce, true), 12, 8).sha1($new_nonce.$new_nonce, true).substr($new_nonce, 0, 4);
|
$tmp_aes_iv = substr(sha1($server_nonce.$new_nonce, true), 12, 8).sha1($new_nonce.$new_nonce, true).substr($new_nonce, 0, 4);
|
||||||
$answer_with_hash = Crypt::ige_decrypt($encrypted_answer, $tmp_aes_key, $tmp_aes_iv);
|
$answer_with_hash = Crypt::ige_decrypt($encrypted_answer, $tmp_aes_key, $tmp_aes_iv);
|
||||||
var_dump($answer_with_hash);
|
|
||||||
$answer_hash = substr($answer_with_hash, 0, 20);
|
$answer_hash = substr($answer_with_hash, 0, 20);
|
||||||
$answer = substr($answer_with_hash, 20);
|
$answer = substr($answer_with_hash, 20);
|
||||||
$server_DH_inner_data = $this->tl->deserialize(Tools::fopen_and_write('php://memory', 'rw+b', $answer));
|
$server_DH_inner_data = $this->tl->deserialize(Tools::fopen_and_write('php://memory', 'rw+b', $answer));
|
||||||
@ -317,29 +316,29 @@ Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB
|
|||||||
throw new Exception('Handshake: wrong server nonce');
|
throw new Exception('Handshake: wrong server nonce');
|
||||||
}
|
}
|
||||||
$dh_prime_str = $server_DH_inner_data['dh_prime'];
|
$dh_prime_str = $server_DH_inner_data['dh_prime'];
|
||||||
$g = $server_DH_inner_data['g'];
|
$g = new \phpseclib\Math\BigInteger($server_DH_inner_data['g']);
|
||||||
$g_a_str = $server_DH_inner_data['g_a'];
|
$g_a_str = $server_DH_inner_data['g_a'];
|
||||||
$server_time = $server_DH_inner_data['server_time'];
|
$server_time = $server_DH_inner_data['server_time'];
|
||||||
$this->timedelta = ($server_time - time());
|
$this->timedelta = ($server_time - time());
|
||||||
$this->log->log(sprintf('Server-client time delta = %.1f s', $this->timedelta));
|
$this->log->log(sprintf('Server-client time delta = %.1f s', $this->timedelta));
|
||||||
$dh_prime = $this->struct->unpack('>Q', $dh_prime_str);
|
$dh_prime = new \phpseclib\Math\BigInteger($dh_prime_str, 256);
|
||||||
$g_a = $this->struct->unpack('>Q', $g_a_str);
|
$g_a = new \phpseclib\Math\BigInteger($g_a_str, 256);
|
||||||
if (!$this->PrimeModule->isprime($dh_prime)) {
|
if (!$dh_prime->isPrime()) {
|
||||||
throw new Exception("Handshake: dh_prime isn't a prime.");
|
throw new Exception("Handshake: dh_prime isn't a prime.");
|
||||||
}
|
}
|
||||||
$retry_id = 0;
|
$retry_id = 0;
|
||||||
$b_str = \phpseclib\Crypt\Random::string(256);
|
$b_str = \phpseclib\Crypt\Random::string(256);
|
||||||
$b = $this->struct->unpack('>Q', $b_str);
|
$b = new \phpseclib\Math\BigInteger($b_str, 256);
|
||||||
$g_b = pow($g, $b, $dh_prime);
|
$g_b = $g->powMod($b, $dh_prime);
|
||||||
$g_b_str = $this->struct->pack('>Q', $g_b);
|
$g_b_str = $g_b->toBytes();
|
||||||
$data = serialize_obj(['client_DH_inner_data'], ['nonce' => $nonce, 'server_nonce' => $server_nonce, 'retry_id' => $retry_id, 'g_b' => $g_b_str]);
|
$data = $this->tl->serialize_obj('client_DH_inner_data', ['nonce' => $nonce, 'server_nonce' => $server_nonce, 'retry_id' => $retry_id, 'g_b' => $g_b_str]);
|
||||||
$data_with_sha = sha1($data, true).$data;
|
$data_with_sha = sha1($data, true).$data;
|
||||||
$data_with_sha_padded = $data_with_sha.\phpseclib\Crypt\Random::string(posmod(-strlen($data_with_sha), 16));
|
$data_with_sha_padded = $data_with_sha.\phpseclib\Crypt\Random::string(Tools::posmod(-strlen($data_with_sha), 16));
|
||||||
$encrypted_data = Crypt::ige_encrypt($data_with_sha_padded, $tmp_aes_key, $tmp_aes_iv);
|
$encrypted_data = Crypt::ige_encrypt($data_with_sha_padded, $tmp_aes_key, $tmp_aes_iv);
|
||||||
foreach (pyjslib_range(1, $this->AUTH_MAX_RETRY) as $i) {
|
foreach (Tools::range(1, $this->AUTH_MAX_RETRY) as $i) {
|
||||||
$Set_client_DH_params_answer = $this->method_call('set_client_DH_params', ['nonce' => $nonce, 'server_nonce' => $server_nonce, 'encrypted_data' => $encrypted_data]);
|
$Set_client_DH_params_answer = $this->method_call('set_client_DH_params', ['nonce' => $nonce, 'server_nonce' => $server_nonce, 'encrypted_data' => $encrypted_data]);
|
||||||
$auth_key = pow($g_a, $b, $dh_prime);
|
$auth_key = $g_a->powMod($b, $dh_prime);
|
||||||
$auth_key_str = $this->struct->pack('>Q', $auth_key);
|
$auth_key_str = $auth_key->toBytes();
|
||||||
$auth_key_sha = sha1($auth_key_str, true);
|
$auth_key_sha = sha1($auth_key_str, true);
|
||||||
$auth_key_aux_hash = substr($auth_key_sha, 0, 8);
|
$auth_key_aux_hash = substr($auth_key_sha, 0, 8);
|
||||||
$new_nonce_hash1 = substr(sha1($new_nonce.''.$auth_key_aux_hash, true), -16);
|
$new_nonce_hash1 = substr(sha1($new_nonce.''.$auth_key_aux_hash, true), -16);
|
||||||
@ -356,7 +355,7 @@ Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB
|
|||||||
throw new Exception('Handshake: wrong new_nonce_hash1');
|
throw new Exception('Handshake: wrong new_nonce_hash1');
|
||||||
}
|
}
|
||||||
$this->log->log('Diffie Hellman key exchange processed successfully');
|
$this->log->log('Diffie Hellman key exchange processed successfully');
|
||||||
$this->server_salt = new strxor(substr($new_nonce, 0, 8 - 0), substr($server_nonce, 0, 8 - 0));
|
$this->server_salt = substr($new_nonce, 0, 8 - 0) ^ substr($server_nonce, 0, 8 - 0);
|
||||||
$this->auth_key = $auth_key_str;
|
$this->auth_key = $auth_key_str;
|
||||||
$this->auth_key_id = substr($auth_key_sha, -8);
|
$this->auth_key_id = substr($auth_key_sha, -8);
|
||||||
$this->log->log('Auth key generated');
|
$this->log->log('Auth key generated');
|
||||||
|
Loading…
Reference in New Issue
Block a user