Moved data sending/recieving functions to Connection calss, implemented other security checks
This commit is contained in:
parent
69b80a0d96
commit
4bf443cd64
@ -32,6 +32,8 @@ class Connection
|
|||||||
- udp
|
- udp
|
||||||
*/
|
*/
|
||||||
$this->protocol = $protocol;
|
$this->protocol = $protocol;
|
||||||
|
// Istantiate struct class
|
||||||
|
$this->struct = new \danog\PHP\StructTools();
|
||||||
switch ($this->protocol) {
|
switch ($this->protocol) {
|
||||||
case 'tcp_abridged':
|
case 'tcp_abridged':
|
||||||
$this->sock = fsockopen('tcp://'.$ip.':'.$port);
|
$this->sock = fsockopen('tcp://'.$ip.':'.$port);
|
||||||
@ -55,6 +57,8 @@ class Connection
|
|||||||
if (!(get_resource_type($this->sock) == 'file' || get_resource_type($this->sock) == 'stream')) {
|
if (!(get_resource_type($this->sock) == 'file' || get_resource_type($this->sock) == 'stream')) {
|
||||||
throw new Exception("Connection: couldn't connect to socket.");
|
throw new Exception("Connection: couldn't connect to socket.");
|
||||||
}
|
}
|
||||||
|
$this->out_seq_no = -1;
|
||||||
|
$this->in_seq_no = -1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Exception('Connection: invalid protocol specified.');
|
throw new Exception('Connection: invalid protocol specified.');
|
||||||
@ -76,6 +80,16 @@ class Connection
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to get hex crc32.
|
||||||
|
*
|
||||||
|
* @param $data Data to encode.
|
||||||
|
*/
|
||||||
|
public function newcrc32($data)
|
||||||
|
{
|
||||||
|
return hexdec(hash('crc32b', $data));
|
||||||
|
}
|
||||||
|
|
||||||
public function write($what, $length = null)
|
public function write($what, $length = null)
|
||||||
{
|
{
|
||||||
if ($length != null) {
|
if ($length != null) {
|
||||||
@ -114,4 +128,75 @@ class Connection
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public function read_message() {
|
||||||
|
switch ($this->protocol) {
|
||||||
|
case 'tcp_full':
|
||||||
|
$packet_length_data = $this->read(4);
|
||||||
|
if (strlen($packet_length_data) < 4) {
|
||||||
|
throw new Exception('Nothing in the socket!');
|
||||||
|
}
|
||||||
|
$packet_length = $this->struct->unpack('<I', $packet_length_data)[0];
|
||||||
|
$packet = $this->read($packet_length - 4);
|
||||||
|
if (!($this->newcrc32($packet_length_data.substr($packet, 0, -4)) == $this->struct->unpack('<I', substr($packet, -4))[0])) {
|
||||||
|
throw new Exception('CRC32 was not correct!');
|
||||||
|
}
|
||||||
|
$this->in_seq_no++;
|
||||||
|
$in_seq_no = $this->struct->unpack('<I', substr($packet, 0, 4))[0];
|
||||||
|
if ($in_seq_no != $this->in_seq_no) {
|
||||||
|
throw new Exception('Incoming seq_no mismatch');
|
||||||
|
}
|
||||||
|
$payload = Tools::fopen_and_write('php://memory', 'rw+b', substr($packet, 4, $packet_length - 12));
|
||||||
|
break;
|
||||||
|
case 'tcp_intermediate':
|
||||||
|
$packet_length_data = $this->sock->read(4);
|
||||||
|
if (strlen($packet_length_data) < 4) {
|
||||||
|
throw new Exception('Nothing in the socket!');
|
||||||
|
}
|
||||||
|
$packet_length = $this->struct->unpack('<I', $packet_length_data)[0];
|
||||||
|
$packet = $this->sock->read($packet_length);
|
||||||
|
$payload = Tools::fopen_and_write('php://memory', 'rw+b', $packet);
|
||||||
|
break;
|
||||||
|
case 'tcp_abridged':
|
||||||
|
$packet_length_data = $this->sock->read(1);
|
||||||
|
if (strlen($packet_length_data) < 1) {
|
||||||
|
throw new Exception('Nothing in the socket!');
|
||||||
|
}
|
||||||
|
$packet_length = ord($packet_length_data);
|
||||||
|
if ($packet_length < 127) {
|
||||||
|
$packet_length <<= 2;
|
||||||
|
} else {
|
||||||
|
$packet_length_data = $this->sock->read(3);
|
||||||
|
$packet_length = $this->struct->unpack('<I', $packet_length_data.pack('x'))[0] << 2;
|
||||||
|
}
|
||||||
|
$packet = $this->sock->read($packet_length);
|
||||||
|
$payload = Tools::fopen_and_write('php://memory', 'rw+b', $packet);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return $payload;
|
||||||
|
}
|
||||||
|
public function send_message($message) {
|
||||||
|
switch ($this->protocol) {
|
||||||
|
case 'tcp_full':
|
||||||
|
$this->out_seq_no++;
|
||||||
|
$step1 = $this->struct->pack('<II', (strlen($message) + 12), $this->out_seq_no).$message;
|
||||||
|
$step2 = $step1.$this->struct->pack('<I', $this->newcrc32($step1));
|
||||||
|
$this->write($step2);
|
||||||
|
break;
|
||||||
|
case 'tcp_intermediate':
|
||||||
|
$step1 = $this->struct->pack('<I', strlen($message)).$message;
|
||||||
|
$this->write($step1);
|
||||||
|
break;
|
||||||
|
case 'tcp_abridged':
|
||||||
|
$len = strlen($message) / 4;
|
||||||
|
if ($len < 127) {
|
||||||
|
$step1 = chr($len).$message;
|
||||||
|
} else {
|
||||||
|
$step1 = chr(127).substr($this->struct->pack('<I', $len), 0, 3).$message;
|
||||||
|
}
|
||||||
|
$this->write($step1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,6 @@ class Crypt
|
|||||||
}
|
}
|
||||||
$ciphered .= $outdata;
|
$ciphered .= $outdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $ciphered;
|
return $ciphered;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB
|
|||||||
// Load rsa key
|
// Load rsa key
|
||||||
$this->key = new RSA($settings['authorization']['rsa_key']);
|
$this->key = new RSA($settings['authorization']['rsa_key']);
|
||||||
// Istantiate struct class
|
// Istantiate struct class
|
||||||
$this->struct = new \danog\PHP\Struct();
|
$this->struct = new \danog\PHP\StructTools();
|
||||||
// Istantiate prime class
|
// Istantiate prime class
|
||||||
$this->PrimeModule = new PrimeModule();
|
$this->PrimeModule = new PrimeModule();
|
||||||
// Istantiate TL class
|
// Istantiate TL class
|
||||||
@ -90,8 +90,7 @@ Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB
|
|||||||
// Istantiate logging class
|
// Istantiate logging class
|
||||||
$this->log = new Logging($this->settings['logging']['logging'], $this->settings['logging']['logging_param']);
|
$this->log = new Logging($this->settings['logging']['logging'], $this->settings['logging']['logging_param']);
|
||||||
|
|
||||||
$this->connection_seq_no = -1;
|
$this->seq_no = 0;
|
||||||
$this->seq_no = -1;
|
|
||||||
$this->timedelta = 0; // time delta
|
$this->timedelta = 0; // time delta
|
||||||
$this->message_ids = [];
|
$this->message_ids = [];
|
||||||
|
|
||||||
@ -108,34 +107,36 @@ Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB
|
|||||||
unset($this->sock);
|
unset($this->sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function add_check_message_ids($new_message_id)
|
public function check_message_id($new_message_id, $from_client)
|
||||||
{
|
{
|
||||||
|
$new_message_id = $this->struct->unpack('<Q', $new_message_id)[0];
|
||||||
if (((int) ((time() + $this->timedelta - 300) * pow(2, 30)) * 4) > $new_message_id) {
|
if (((int) ((time() + $this->timedelta - 300) * pow(2, 30)) * 4) > $new_message_id) {
|
||||||
throw new Exception('Given message id is too old.');
|
throw new Exception('Given message id is too old.');
|
||||||
}
|
}
|
||||||
if (((int) ((time() + $this->timedelta + 30) * pow(2, 30)) * 4) < $new_message_id) {
|
if (((int) ((time() + $this->timedelta + 30) * pow(2, 30)) * 4) < $new_message_id) {
|
||||||
throw new Exception('Given message id is too new.');
|
throw new Exception('Given message id is too new.');
|
||||||
}
|
}
|
||||||
foreach ($this->message_ids as $message_id) {
|
if ($from_client) {
|
||||||
if ($new_message_id <= $message_id) {
|
if ($new_message_id % 4 != 0) {
|
||||||
throw new Exception('Given message id is lower than or equal than the current limit ('.$message_id.').');
|
throw new Exception('Given message id is not divisible by 4.');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ($new_message_id % 4 != 1 && $new_message_id % 4 != 3) {
|
||||||
|
throw new Exception('message id mod 4 != 1 or 3');
|
||||||
|
}
|
||||||
|
foreach ($this->message_ids as $message_id) {
|
||||||
|
if ($new_message_id <= $message_id) {
|
||||||
|
throw new Exception('Given message id is lower than or equal than the current limit ('.$message_id.').');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->message_ids[] = $new_message_id;
|
||||||
|
if (count($this->message_ids) > $this->settings['authorization']['message_ids_limit']) {
|
||||||
|
array_shift($this->message_ids);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->message_ids[] = $new_message_id;
|
|
||||||
if (count($this->message_ids) > $this->settings['authorization']['message_ids_limit']) {
|
|
||||||
array_shift($this->message_ids);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to get hex crc32.
|
|
||||||
*
|
|
||||||
* @param $data Data to encode.
|
|
||||||
*/
|
|
||||||
public function newcrc32($data)
|
|
||||||
{
|
|
||||||
return hexdec(hash('crc32b', $data));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Forming the message frame and sending message to server
|
* Forming the message frame and sending message to server
|
||||||
@ -144,6 +145,7 @@ Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB
|
|||||||
public function send_message($message_data)
|
public function send_message($message_data)
|
||||||
{
|
{
|
||||||
$message_id = $this->struct->pack('<Q', (int) ((time() + $this->timedelta) * pow(2, 30)) * 4);
|
$message_id = $this->struct->pack('<Q', (int) ((time() + $this->timedelta) * pow(2, 30)) * 4);
|
||||||
|
$this->check_message_id($message_id, true);
|
||||||
if (($this->settings['authorization']['temp_auth_key']['auth_key'] == null) || ($this->settings['authorization']['temp_auth_key']['server_salt'] == null)) {
|
if (($this->settings['authorization']['temp_auth_key']['auth_key'] == null) || ($this->settings['authorization']['temp_auth_key']['server_salt'] == null)) {
|
||||||
$message = Tools::string2bin('\x00\x00\x00\x00\x00\x00\x00\x00').$message_id.$this->struct->pack('<I', strlen($message_data)).$message_data;
|
$message = Tools::string2bin('\x00\x00\x00\x00\x00\x00\x00\x00').$message_id.$this->struct->pack('<I', strlen($message_data)).$message_data;
|
||||||
} else {
|
} else {
|
||||||
@ -154,29 +156,7 @@ Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB
|
|||||||
list($aes_key, $aes_iv) = $this->aes_calculate($message_key);
|
list($aes_key, $aes_iv) = $this->aes_calculate($message_key);
|
||||||
$message = $this->settings['authorization']['temp_auth_key']['id'].$message_key.Crypt::ige_encrypt($encrypted_data.$padding, $aes_key, $aes_iv);
|
$message = $this->settings['authorization']['temp_auth_key']['id'].$message_key.Crypt::ige_encrypt($encrypted_data.$padding, $aes_key, $aes_iv);
|
||||||
}
|
}
|
||||||
switch ($this->settings['connection']['protocol']) {
|
$this->sock->send_message($message);
|
||||||
case 'tcp_full':
|
|
||||||
$this->connection_seq_no++;
|
|
||||||
$step1 = $this->struct->pack('<II', (strlen($message) + 12), $this->connection_seq_no).$message;
|
|
||||||
$step2 = $step1.$this->struct->pack('<I', $this->newcrc32($step1));
|
|
||||||
$this->sock->write($step2);
|
|
||||||
break;
|
|
||||||
case 'tcp_intermediate':
|
|
||||||
$step1 = $this->struct->pack('<I', strlen($message)).$message;
|
|
||||||
$this->sock->write($step1);
|
|
||||||
break;
|
|
||||||
case 'tcp_abridged':
|
|
||||||
$len = strlen($message) / 4;
|
|
||||||
if ($len < 127) {
|
|
||||||
$step1 = chr($len).$message;
|
|
||||||
} else {
|
|
||||||
$step1 = chr(127).substr($this->struct->pack('<I', $len), 0, 3).$message;
|
|
||||||
}
|
|
||||||
$this->sock->write($step1);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -184,87 +164,68 @@ Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB
|
|||||||
*/
|
*/
|
||||||
public function recv_message()
|
public function recv_message()
|
||||||
{
|
{
|
||||||
switch ($this->settings['connection']['protocol']) {
|
$payload = $this->sock->read_message();
|
||||||
case 'tcp_full':
|
|
||||||
$packet_length_data = $this->sock->read(4);
|
|
||||||
if (strlen($packet_length_data) < 4) {
|
|
||||||
throw new Exception('Nothing in the socket!');
|
|
||||||
}
|
|
||||||
$packet_length = $this->struct->unpack('<I', $packet_length_data)[0];
|
|
||||||
$packet = $this->sock->read($packet_length - 4);
|
|
||||||
if (!($this->newcrc32($packet_length_data.substr($packet, 0, -4)) == $this->struct->unpack('<I', substr($packet, -4))[0])) {
|
|
||||||
throw new Exception('CRC32 was not correct!');
|
|
||||||
}
|
|
||||||
$connection_seq_no = $this->struct->unpack('<I', substr($packet, 0, 4))[0];
|
|
||||||
if ($connection_seq_no != $this->connection_seq_no) {
|
|
||||||
throw new Exception('Connection seq_no mismatch');
|
|
||||||
}
|
|
||||||
$payload = Tools::fopen_and_write('php://memory', 'rw+b', substr($packet, 4, $packet_length - 12));
|
|
||||||
break;
|
|
||||||
case 'tcp_intermediate':
|
|
||||||
$packet_length_data = $this->sock->read(4);
|
|
||||||
if (strlen($packet_length_data) < 4) {
|
|
||||||
throw new Exception('Nothing in the socket!');
|
|
||||||
}
|
|
||||||
$packet_length = $this->struct->unpack('<I', $packet_length_data)[0];
|
|
||||||
$packet = $this->sock->read($packet_length);
|
|
||||||
$payload = Tools::fopen_and_write('php://memory', 'rw+b', $packet);
|
|
||||||
break;
|
|
||||||
case 'tcp_abridged':
|
|
||||||
$packet_length_data = $this->sock->read(1);
|
|
||||||
if (strlen($packet_length_data) < 1) {
|
|
||||||
throw new Exception('Nothing in the socket!');
|
|
||||||
}
|
|
||||||
$packet_length = ord($packet_length_data);
|
|
||||||
if ($packet_length < 127) {
|
|
||||||
$packet_length <<= 2;
|
|
||||||
} else {
|
|
||||||
$packet_length_data = $this->sock->read(3);
|
|
||||||
$packet_length = $this->struct->unpack('<I', $packet_length_data.pack('x'))[0] << 2;
|
|
||||||
}
|
|
||||||
$packet = $this->sock->read($packet_length);
|
|
||||||
$payload = Tools::fopen_and_write('php://memory', 'rw+b', $packet);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fstat($payload)['size'] == 4) {
|
if (fstat($payload)['size'] == 4) {
|
||||||
throw new Exception('Server response error: '.abs($this->struct->unpack('<i', fread($payload, 4))[0]));
|
throw new Exception('Server response error: '.abs($this->struct->unpack('<i', fread($payload, 4))[0]));
|
||||||
}
|
}
|
||||||
$auth_key_id = fread($payload, 8);
|
$auth_key_id = fread($payload, 8);
|
||||||
if ($auth_key_id == Tools::string2bin('\x00\x00\x00\x00\x00\x00\x00\x00')) {
|
if ($auth_key_id == Tools::string2bin('\x00\x00\x00\x00\x00\x00\x00\x00')) {
|
||||||
list($message_id, $message_length) = $this->struct->unpack('<QI', fread($payload, 12));
|
list($message_id, $message_length) = $this->struct->unpack('<8sI', fread($payload, 12));
|
||||||
$this->add_check_message_ids($message_id);
|
$this->check_message_id($message_id, false);
|
||||||
$data = fread($payload, $message_length);
|
$message_data = fread($payload, $message_length);
|
||||||
} elseif ($auth_key_id == $this->settings['authorization']['temp_auth_key']['id']) {
|
} elseif ($auth_key_id == $this->settings['authorization']['temp_auth_key']['id']) {
|
||||||
$message_key = fread($payload, 16);
|
$message_key = fread($payload, 16);
|
||||||
$encrypted_data = stream_get_contents($payload);
|
$encrypted_data = stream_get_contents($payload);
|
||||||
list($aes_key, $aes_iv) = $this->aes_calculate($message_key, 'from server');
|
list($aes_key, $aes_iv) = $this->aes_calculate($message_key, 'from server');
|
||||||
$decrypted_data = Tools::fopen_and_write('php://memory', 'rw+b', Crypt::ige_decrypt($encrypted_data, $aes_key, $aes_iv));
|
$decrypted_data = Tools::fopen_and_write('php://memory', 'rw+b', Crypt::ige_decrypt($encrypted_data, $aes_key, $aes_iv));
|
||||||
|
|
||||||
$server_salt = fread($decrypted_data, 8);
|
$server_salt = fread($decrypted_data, 8);
|
||||||
$session_id = fread($decrypted_data, 8);
|
|
||||||
if ($server_salt != $this->settings['authorization']['temp_auth_key']['server_salt']) {
|
if ($server_salt != $this->settings['authorization']['temp_auth_key']['server_salt']) {
|
||||||
throw new Exception('Server salt mismatch.');
|
throw new Exception('Server salt mismatch.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$session_id = fread($decrypted_data, 8);
|
||||||
if ($session_id != $this->settings['authorization']['session_id']) {
|
if ($session_id != $this->settings['authorization']['session_id']) {
|
||||||
throw new Exception('Session id mismatch.');
|
throw new Exception('Session id mismatch.');
|
||||||
}
|
}
|
||||||
$message_id = $this->struct->unpack('<Q', fread($decrypted_data, 8))[0];
|
|
||||||
$this->add_check_message_ids($message_id);
|
$message_id = fread($decrypted_data, 8);
|
||||||
|
$this->check_message_id($message_id, false);
|
||||||
|
|
||||||
$seq_no = $this->struct->unpack('<I', fread($decrypted_data, 4)) [0];
|
$seq_no = $this->struct->unpack('<I', fread($decrypted_data, 4)) [0];
|
||||||
var_dump($seq_no, $this->seq_no);
|
var_dump($seq_no, $this->seq_no *2);
|
||||||
if ($seq_no != $this->seq_no) {
|
if ($seq_no != $this->seq_no * 2) {
|
||||||
throw new Exception('Seq_no mismatch');
|
throw new Exception('Seq_no mismatch');
|
||||||
}
|
}
|
||||||
|
|
||||||
$message_data_length = $this->struct->unpack('<I', fread($decrypted_data, 4)) [0];
|
$message_data_length = $this->struct->unpack('<I', fread($decrypted_data, 4)) [0];
|
||||||
$data = fread($decrypted_data, $message_data_length);
|
|
||||||
if ($message_key != substr(sha1(stream_get_contents($decrypted_data, 0, ftell($decrypted_data)), true), -16)) {
|
if ($message_data_length > fstat($decrypted_data)["size"]) {
|
||||||
|
throw new Exception('message_data_length is too big');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((fstat($decrypted_data)["size"] - 32) - $message_data_length > 15) {
|
||||||
|
throw new Exception('difference between message_data_length and the length of the remaining decrypted buffer is too big');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($message_data_length < 0) {
|
||||||
|
throw new Exception('message_data_length not positive');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($message_data_length % 4 != 0) {
|
||||||
|
throw new Exception('message_data_length not divisible by 4');
|
||||||
|
}
|
||||||
|
|
||||||
|
$message_data = fread($decrypted_data, $message_data_length);
|
||||||
|
DebugTools::hex_dump(substr(sha1(stream_get_contents($decrypted_data, 32 + $message_data_length), true), -16), $message_key);
|
||||||
|
if ($message_key != sha1($message_data, true)) {
|
||||||
throw new Exception('msg_key mismatch');
|
throw new Exception('msg_key mismatch');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Exception('Got unknown auth_key id');
|
throw new Exception('Got unknown auth_key id');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $data;
|
return $message_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function method_call($method, $kwargs)
|
public function method_call($method, $kwargs)
|
||||||
@ -274,21 +235,22 @@ Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB
|
|||||||
$this->send_message($this->tl->serialize_method($method, $kwargs));
|
$this->send_message($this->tl->serialize_method($method, $kwargs));
|
||||||
$server_answer = $this->recv_message();
|
$server_answer = $this->recv_message();
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$this->log->log(PHP_EOL.'An error occurred while calling method '.$method.': '.$e->getMessage().' on line '.$e->getLine().' of file '.$e->getFile().PHP_EOL.'Retrying to call method...'.PHP_EOL);
|
$this->log->log('An error occurred while calling method '.$method.': '.$e->getMessage().' in '.$e->getFile().':'.$e->getLine().'. Recreating connection and retrying to call method...');
|
||||||
|
unset($this->sock);
|
||||||
|
$this->sock = new Connection($this->settings['connection']['ip_address'], $this->settings['connection']['port'], $this->settings['connection']['protocol']);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ($server_answer == null) {
|
if ($server_answer == null) {
|
||||||
throw new Exception('An error occurred while calling method '.$method.'.');
|
throw new Exception('An error occurred while calling method '.$method.'.');
|
||||||
}
|
}
|
||||||
|
$deserialized = $this->tl->deserialize(Tools::fopen_and_write('php://memory', 'rw+b', $server_answer));
|
||||||
return $this->tl->deserialize(Tools::fopen_and_write('php://memory', 'rw+b', $server_answer));
|
return $deserialized;
|
||||||
}
|
}
|
||||||
throw new Exception('An error occurred while calling method '.$method.'.');
|
throw new Exception('An error occurred while calling method '.$method.'.');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function create_auth_key($expires_in = -1)
|
public function create_auth_key($expires_in = -1)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Make pq request
|
// Make pq request
|
||||||
$nonce = \phpseclib\Crypt\Random::string(16);
|
$nonce = \phpseclib\Crypt\Random::string(16);
|
||||||
$this->log->log('Handshake: Requesting pq');
|
$this->log->log('Handshake: Requesting pq');
|
||||||
@ -375,12 +337,7 @@ Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB
|
|||||||
|
|
||||||
// Deserialize
|
// Deserialize
|
||||||
$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));
|
||||||
|
|
||||||
// Time delta
|
|
||||||
$server_time = $server_DH_inner_data['server_time'];
|
|
||||||
$this->timedelta = ($server_time - time());
|
|
||||||
$this->log->log(sprintf('Server-client time delta = %.1f s', $this->timedelta));
|
|
||||||
|
|
||||||
// Do some checks
|
// Do some checks
|
||||||
$server_DH_inner_data_length = $this->tl->get_length(Tools::fopen_and_write('php://memory', 'rw+b', $answer));
|
$server_DH_inner_data_length = $this->tl->get_length(Tools::fopen_and_write('php://memory', 'rw+b', $answer));
|
||||||
if (sha1(substr($answer, 0, $server_DH_inner_data_length), true) != $answer_hash) {
|
if (sha1(substr($answer, 0, $server_DH_inner_data_length), true) != $answer_hash) {
|
||||||
@ -396,6 +353,12 @@ Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB
|
|||||||
$g_a = new \phpseclib\Math\BigInteger($server_DH_inner_data['g_a'], 256);
|
$g_a = new \phpseclib\Math\BigInteger($server_DH_inner_data['g_a'], 256);
|
||||||
$dh_prime = new \phpseclib\Math\BigInteger($server_DH_inner_data['dh_prime'], 256);
|
$dh_prime = new \phpseclib\Math\BigInteger($server_DH_inner_data['dh_prime'], 256);
|
||||||
|
|
||||||
|
// Time delta
|
||||||
|
$server_time = $server_DH_inner_data['server_time'];
|
||||||
|
$this->timedelta = ($server_time - time());
|
||||||
|
$this->log->log(sprintf('Server-client time delta = %.1f s', $this->timedelta));
|
||||||
|
|
||||||
|
|
||||||
// Define some needed numbers for BigInteger
|
// Define some needed numbers for BigInteger
|
||||||
$one = new \phpseclib\Math\BigInteger(1);
|
$one = new \phpseclib\Math\BigInteger(1);
|
||||||
$two = new \phpseclib\Math\BigInteger(2);
|
$two = new \phpseclib\Math\BigInteger(2);
|
||||||
|
Loading…
Reference in New Issue
Block a user