Unify names of PacketInfo variables.
This commit is contained in:
parent
4da0f76d2a
commit
efba70c2ef
@ -61,23 +61,23 @@ class RawConnectionDefault final : public RawConnection {
|
|||||||
|
|
||||||
size_t send_crypto(const Storer &storer, uint64 session_id, int64 salt, const AuthKey &auth_key,
|
size_t send_crypto(const Storer &storer, uint64 session_id, int64 salt, const AuthKey &auth_key,
|
||||||
uint64 quick_ack_token) final {
|
uint64 quick_ack_token) final {
|
||||||
PacketInfo info;
|
PacketInfo packet_info;
|
||||||
info.version = 2;
|
packet_info.version = 2;
|
||||||
info.no_crypto_flag = false;
|
packet_info.no_crypto_flag = false;
|
||||||
info.salt = salt;
|
packet_info.salt = salt;
|
||||||
info.session_id = session_id;
|
packet_info.session_id = session_id;
|
||||||
info.use_random_padding = transport_->use_random_padding();
|
packet_info.use_random_padding = transport_->use_random_padding();
|
||||||
auto packet =
|
auto packet =
|
||||||
Transport::write(storer, auth_key, &info, transport_->max_prepend_size(), transport_->max_append_size());
|
Transport::write(storer, auth_key, &packet_info, transport_->max_prepend_size(), transport_->max_append_size());
|
||||||
|
|
||||||
bool use_quick_ack = false;
|
bool use_quick_ack = false;
|
||||||
if (quick_ack_token != 0 && transport_->support_quick_ack()) {
|
if (quick_ack_token != 0 && transport_->support_quick_ack()) {
|
||||||
CHECK(info.message_ack & (1u << 31));
|
CHECK(packet_info.message_ack & (1u << 31));
|
||||||
auto tmp = quick_ack_to_token_.emplace(info.message_ack, quick_ack_token);
|
auto tmp = quick_ack_to_token_.emplace(packet_info.message_ack, quick_ack_token);
|
||||||
if (tmp.second) {
|
if (tmp.second) {
|
||||||
use_quick_ack = true;
|
use_quick_ack = true;
|
||||||
} else {
|
} else {
|
||||||
LOG(ERROR) << "Quick ack " << info.message_ack << " collision";
|
LOG(ERROR) << "Quick ack " << packet_info.message_ack << " collision";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,14 +87,14 @@ class RawConnectionDefault final : public RawConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint64 send_no_crypto(const Storer &storer) final {
|
uint64 send_no_crypto(const Storer &storer) final {
|
||||||
PacketInfo info;
|
PacketInfo packet_info;
|
||||||
info.no_crypto_flag = true;
|
packet_info.no_crypto_flag = true;
|
||||||
auto packet =
|
auto packet = Transport::write(storer, AuthKey(), &packet_info, transport_->max_prepend_size(),
|
||||||
Transport::write(storer, AuthKey(), &info, transport_->max_prepend_size(), transport_->max_append_size());
|
transport_->max_append_size());
|
||||||
|
|
||||||
LOG(INFO) << "Send handshake packet: " << format::as_hex_dump<4>(packet.as_slice());
|
LOG(INFO) << "Send handshake packet: " << format::as_hex_dump<4>(packet.as_slice());
|
||||||
transport_->write(std::move(packet), false);
|
transport_->write(std::move(packet), false);
|
||||||
return info.message_id;
|
return packet_info.message_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
PollableFdInfo &get_poll_info() final {
|
PollableFdInfo &get_poll_info() final {
|
||||||
@ -187,10 +187,10 @@ class RawConnectionDefault final : public RawConnection {
|
|||||||
<< old_pointer << ' ' << packet.as_slice().ubegin() << ' ' << BufferSlice(0).as_slice().ubegin() << ' '
|
<< old_pointer << ' ' << packet.as_slice().ubegin() << ' ' << BufferSlice(0).as_slice().ubegin() << ' '
|
||||||
<< packet.size() << ' ' << wait_size << ' ' << quick_ack;
|
<< packet.size() << ' ' << wait_size << ' ' << quick_ack;
|
||||||
|
|
||||||
PacketInfo info;
|
PacketInfo packet_info;
|
||||||
info.version = 2;
|
packet_info.version = 2;
|
||||||
|
|
||||||
TRY_RESULT(read_result, Transport::read(packet.as_mutable_slice(), auth_key, &info));
|
TRY_RESULT(read_result, Transport::read(packet.as_mutable_slice(), auth_key, &packet_info));
|
||||||
switch (read_result.type()) {
|
switch (read_result.type()) {
|
||||||
case Transport::ReadResult::Quickack:
|
case Transport::ReadResult::Quickack:
|
||||||
TRY_STATUS(on_quick_ack(read_result.quick_ack(), callback));
|
TRY_STATUS(on_quick_ack(read_result.quick_ack(), callback));
|
||||||
@ -206,7 +206,7 @@ class RawConnectionDefault final : public RawConnection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TRY_STATUS(callback.on_raw_packet(info, packet.from_slice(read_result.packet())));
|
TRY_STATUS(callback.on_raw_packet(packet_info, packet.from_slice(read_result.packet())));
|
||||||
break;
|
break;
|
||||||
case Transport::ReadResult::Nop:
|
case Transport::ReadResult::Nop:
|
||||||
break;
|
break;
|
||||||
@ -302,13 +302,13 @@ class RawConnectionHttp final : public RawConnection {
|
|||||||
|
|
||||||
size_t send_crypto(const Storer &storer, uint64 session_id, int64 salt, const AuthKey &auth_key,
|
size_t send_crypto(const Storer &storer, uint64 session_id, int64 salt, const AuthKey &auth_key,
|
||||||
uint64 quick_ack_token) final {
|
uint64 quick_ack_token) final {
|
||||||
PacketInfo info;
|
PacketInfo packet_info;
|
||||||
info.version = 2;
|
packet_info.version = 2;
|
||||||
info.no_crypto_flag = false;
|
packet_info.no_crypto_flag = false;
|
||||||
info.salt = salt;
|
packet_info.salt = salt;
|
||||||
info.session_id = session_id;
|
packet_info.session_id = session_id;
|
||||||
info.use_random_padding = false;
|
packet_info.use_random_padding = false;
|
||||||
auto packet = Transport::write(storer, auth_key, &info);
|
auto packet = Transport::write(storer, auth_key, &packet_info);
|
||||||
|
|
||||||
auto packet_size = packet.size();
|
auto packet_size = packet.size();
|
||||||
send_packet(packet.as_buffer_slice());
|
send_packet(packet.as_buffer_slice());
|
||||||
@ -316,13 +316,13 @@ class RawConnectionHttp final : public RawConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint64 send_no_crypto(const Storer &storer) final {
|
uint64 send_no_crypto(const Storer &storer) final {
|
||||||
PacketInfo info;
|
PacketInfo packet_info;
|
||||||
info.no_crypto_flag = true;
|
packet_info.no_crypto_flag = true;
|
||||||
auto packet = Transport::write(storer, AuthKey(), &info);
|
auto packet = Transport::write(storer, AuthKey(), &packet_info);
|
||||||
|
|
||||||
LOG(INFO) << "Send handshake packet: " << format::as_hex_dump<4>(packet.as_slice());
|
LOG(INFO) << "Send handshake packet: " << format::as_hex_dump<4>(packet.as_slice());
|
||||||
send_packet(packet.as_buffer_slice());
|
send_packet(packet.as_buffer_slice());
|
||||||
return info.message_id;
|
return packet_info.message_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
PollableFdInfo &get_poll_info() final {
|
PollableFdInfo &get_poll_info() final {
|
||||||
@ -403,10 +403,10 @@ class RawConnectionHttp final : public RawConnection {
|
|||||||
CHECK(mode_ == Receive);
|
CHECK(mode_ == Receive);
|
||||||
mode_ = Send;
|
mode_ = Send;
|
||||||
|
|
||||||
PacketInfo info;
|
PacketInfo packet_info;
|
||||||
info.version = 2;
|
packet_info.version = 2;
|
||||||
|
|
||||||
TRY_RESULT(read_result, Transport::read(packet.as_mutable_slice(), auth_key, &info));
|
TRY_RESULT(read_result, Transport::read(packet.as_mutable_slice(), auth_key, &packet_info));
|
||||||
switch (read_result.type()) {
|
switch (read_result.type()) {
|
||||||
case Transport::ReadResult::Quickack: {
|
case Transport::ReadResult::Quickack: {
|
||||||
break;
|
break;
|
||||||
@ -423,7 +423,7 @@ class RawConnectionHttp final : public RawConnection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TRY_STATUS(callback.on_raw_packet(info, packet.from_slice(read_result.packet())));
|
TRY_STATUS(callback.on_raw_packet(packet_info, packet.from_slice(read_result.packet())));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Transport::ReadResult::Nop:
|
case Transport::ReadResult::Nop:
|
||||||
|
@ -61,7 +61,7 @@ class RawConnection {
|
|||||||
Callback(const Callback &) = delete;
|
Callback(const Callback &) = delete;
|
||||||
Callback &operator=(const Callback &) = delete;
|
Callback &operator=(const Callback &) = delete;
|
||||||
virtual ~Callback() = default;
|
virtual ~Callback() = default;
|
||||||
virtual Status on_raw_packet(const PacketInfo &info, BufferSlice packet) = 0;
|
virtual Status on_raw_packet(const PacketInfo &packet_info, BufferSlice packet) = 0;
|
||||||
virtual Status on_quick_ack(uint64 quick_ack_token) {
|
virtual Status on_quick_ack(uint64 quick_ack_token) {
|
||||||
return Status::Error("Quick acknowledgements are unsupported by the callback");
|
return Status::Error("Quick acknowledgements are unsupported by the callback");
|
||||||
}
|
}
|
||||||
|
@ -544,7 +544,7 @@ Status SessionConnection::parse_packet(TlParser &parser) {
|
|||||||
return on_slice_packet(info, packet);
|
return on_slice_packet(info, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
Status SessionConnection::on_main_packet(const PacketInfo &info, Slice packet) {
|
Status SessionConnection::on_main_packet(const PacketInfo &packet_info, Slice packet) {
|
||||||
// Update pong here too. Real pong can be delayed by many big packets
|
// Update pong here too. Real pong can be delayed by many big packets
|
||||||
last_pong_at_ = Time::now_cached();
|
last_pong_at_ = Time::now_cached();
|
||||||
real_last_pong_at_ = last_pong_at_;
|
real_last_pong_at_ = last_pong_at_;
|
||||||
@ -555,10 +555,10 @@ Status SessionConnection::on_main_packet(const PacketInfo &info, Slice packet) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
VLOG(raw_mtproto) << "Receive packet of size " << packet.size() << ':' << format::as_hex_dump<4>(packet);
|
VLOG(raw_mtproto) << "Receive packet of size " << packet.size() << ':' << format::as_hex_dump<4>(packet);
|
||||||
VLOG(mtproto) << "Receive packet with seq_no " << info.seq_no << " and msg_id " << format::as_hex(info.message_id)
|
VLOG(mtproto) << "Receive packet with seq_no " << packet_info.seq_no << " and msg_id "
|
||||||
<< " of size " << packet.size();
|
<< format::as_hex(packet_info.message_id) << " of size " << packet.size();
|
||||||
|
|
||||||
if (info.no_crypto_flag) {
|
if (packet_info.no_crypto_flag) {
|
||||||
return Status::Error("Unencrypted packet");
|
return Status::Error("Unencrypted packet");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -684,27 +684,27 @@ Status SessionConnection::before_write() {
|
|||||||
return Status::OK();
|
return Status::OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
Status SessionConnection::on_raw_packet(const PacketInfo &info, BufferSlice packet) {
|
Status SessionConnection::on_raw_packet(const PacketInfo &packet_info, BufferSlice packet) {
|
||||||
auto old_main_message_id = main_message_id_;
|
auto old_main_message_id = main_message_id_;
|
||||||
main_message_id_ = info.message_id;
|
main_message_id_ = packet_info.message_id;
|
||||||
SCOPE_EXIT {
|
SCOPE_EXIT {
|
||||||
main_message_id_ = old_main_message_id;
|
main_message_id_ = old_main_message_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (info.no_crypto_flag) {
|
if (packet_info.no_crypto_flag) {
|
||||||
return Status::Error("Unexpected unencrypted packet");
|
return Status::Error("Unexpected unencrypted packet");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool time_difference_was_updated = false;
|
bool time_difference_was_updated = false;
|
||||||
auto status =
|
auto status = auth_data_->check_packet(packet_info.session_id, packet_info.message_id, Time::now_cached(),
|
||||||
auth_data_->check_packet(info.session_id, info.message_id, Time::now_cached(), time_difference_was_updated);
|
time_difference_was_updated);
|
||||||
if (time_difference_was_updated) {
|
if (time_difference_was_updated) {
|
||||||
callback_->on_server_time_difference_updated(false);
|
callback_->on_server_time_difference_updated(false);
|
||||||
}
|
}
|
||||||
if (status.is_error()) {
|
if (status.is_error()) {
|
||||||
if (status.code() == 1) {
|
if (status.code() == 1) {
|
||||||
LOG(INFO) << "Packet is ignored: " << status;
|
LOG(INFO) << "Packet is ignored: " << status;
|
||||||
send_ack(info.message_id);
|
send_ack(packet_info.message_id);
|
||||||
return Status::OK();
|
return Status::OK();
|
||||||
} else if (status.code() == 2) {
|
} else if (status.code() == 2) {
|
||||||
LOG(WARNING) << "Receive too old packet: " << status;
|
LOG(WARNING) << "Receive too old packet: " << status;
|
||||||
@ -716,7 +716,7 @@ Status SessionConnection::on_raw_packet(const PacketInfo &info, BufferSlice pack
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto guard = set_buffer_slice(&packet);
|
auto guard = set_buffer_slice(&packet);
|
||||||
TRY_STATUS(on_main_packet(info, packet.as_slice()));
|
TRY_STATUS(on_main_packet(packet_info, packet.as_slice()));
|
||||||
return Status::OK();
|
return Status::OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -844,12 +844,12 @@ std::pair<uint64, BufferSlice> SessionConnection::encrypted_bind(int64 perm_key,
|
|||||||
PacketStorer<QueryImpl> query_storer(query, Slice());
|
PacketStorer<QueryImpl> query_storer(query, Slice());
|
||||||
|
|
||||||
const AuthKey &main_auth_key = auth_data_->get_main_auth_key();
|
const AuthKey &main_auth_key = auth_data_->get_main_auth_key();
|
||||||
PacketInfo info;
|
PacketInfo packet_info;
|
||||||
info.version = 1;
|
packet_info.version = 1;
|
||||||
info.no_crypto_flag = false;
|
packet_info.no_crypto_flag = false;
|
||||||
info.salt = Random::secure_int64();
|
packet_info.salt = Random::secure_int64();
|
||||||
info.session_id = Random::secure_int64();
|
packet_info.session_id = Random::secure_int64();
|
||||||
auto packet = Transport::write(query_storer, main_auth_key, &info);
|
auto packet = Transport::write(query_storer, main_auth_key, &packet_info);
|
||||||
return std::make_pair(query.message_id, packet.as_buffer_slice());
|
return std::make_pair(query.message_id, packet.as_buffer_slice());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,7 +256,7 @@ class SessionConnection final
|
|||||||
Status on_destroy_auth_key(const mtproto_api::DestroyAuthKeyRes &destroy_auth_key);
|
Status on_destroy_auth_key(const mtproto_api::DestroyAuthKeyRes &destroy_auth_key);
|
||||||
|
|
||||||
Status on_slice_packet(const MsgInfo &info, Slice packet) TD_WARN_UNUSED_RESULT;
|
Status on_slice_packet(const MsgInfo &info, Slice packet) TD_WARN_UNUSED_RESULT;
|
||||||
Status on_main_packet(const PacketInfo &info, Slice packet) TD_WARN_UNUSED_RESULT;
|
Status on_main_packet(const PacketInfo &packet_info, Slice packet) TD_WARN_UNUSED_RESULT;
|
||||||
void on_message_failed(uint64 id, Status status);
|
void on_message_failed(uint64 id, Status status);
|
||||||
void on_message_failed_inner(uint64 id);
|
void on_message_failed_inner(uint64 id);
|
||||||
|
|
||||||
@ -274,7 +274,7 @@ class SessionConnection final
|
|||||||
Status do_flush() TD_WARN_UNUSED_RESULT;
|
Status do_flush() TD_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
Status before_write() final TD_WARN_UNUSED_RESULT;
|
Status before_write() final TD_WARN_UNUSED_RESULT;
|
||||||
Status on_raw_packet(const PacketInfo &info, BufferSlice packet) final;
|
Status on_raw_packet(const PacketInfo &packet_info, BufferSlice packet) final;
|
||||||
Status on_quick_ack(uint64 quick_ack_token) final;
|
Status on_quick_ack(uint64 quick_ack_token) final;
|
||||||
void on_read(size_t size) final;
|
void on_read(size_t size) final;
|
||||||
};
|
};
|
||||||
|
@ -186,10 +186,10 @@ size_t do_calc_crypto_size2_rand(size_t data_size, size_t enc_size, size_t raw_s
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
template <class HeaderT>
|
template <class HeaderT>
|
||||||
size_t Transport::calc_crypto_size2(size_t data_size, PacketInfo *info) {
|
size_t Transport::calc_crypto_size2(size_t data_size, PacketInfo *packet_info) {
|
||||||
size_t enc_size = HeaderT::encrypted_header_size();
|
size_t enc_size = HeaderT::encrypted_header_size();
|
||||||
size_t raw_size = sizeof(HeaderT) - enc_size;
|
size_t raw_size = sizeof(HeaderT) - enc_size;
|
||||||
if (info->use_random_padding) {
|
if (packet_info->use_random_padding) {
|
||||||
return do_calc_crypto_size2_rand(data_size, enc_size, raw_size);
|
return do_calc_crypto_size2_rand(data_size, enc_size, raw_size);
|
||||||
} else {
|
} else {
|
||||||
return do_calc_crypto_size2_basic(data_size, enc_size, raw_size);
|
return do_calc_crypto_size2_basic(data_size, enc_size, raw_size);
|
||||||
@ -200,7 +200,7 @@ size_t Transport::calc_no_crypto_size(size_t data_size) {
|
|||||||
return sizeof(NoCryptoHeader) + data_size;
|
return sizeof(NoCryptoHeader) + data_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status Transport::read_no_crypto(MutableSlice message, PacketInfo *info, MutableSlice *data) {
|
Status Transport::read_no_crypto(MutableSlice message, PacketInfo *packet_info, MutableSlice *data) {
|
||||||
if (message.size() < sizeof(NoCryptoHeader)) {
|
if (message.size() < sizeof(NoCryptoHeader)) {
|
||||||
return Status::Error(PSLICE() << "Invalid MTProto message: too small [message.size() = " << message.size()
|
return Status::Error(PSLICE() << "Invalid MTProto message: too small [message.size() = " << message.size()
|
||||||
<< "] < [sizeof(NoCryptoHeader) = " << sizeof(NoCryptoHeader) << "]");
|
<< "] < [sizeof(NoCryptoHeader) = " << sizeof(NoCryptoHeader) << "]");
|
||||||
@ -213,7 +213,7 @@ Status Transport::read_no_crypto(MutableSlice message, PacketInfo *info, Mutable
|
|||||||
|
|
||||||
template <class HeaderT, class PrefixT>
|
template <class HeaderT, class PrefixT>
|
||||||
Status Transport::read_crypto_impl(int X, MutableSlice message, const AuthKey &auth_key, HeaderT **header_ptr,
|
Status Transport::read_crypto_impl(int X, MutableSlice message, const AuthKey &auth_key, HeaderT **header_ptr,
|
||||||
PrefixT **prefix_ptr, MutableSlice *data, PacketInfo *info) {
|
PrefixT **prefix_ptr, MutableSlice *data, PacketInfo *packet_info) {
|
||||||
if (message.size() < sizeof(HeaderT)) {
|
if (message.size() < sizeof(HeaderT)) {
|
||||||
return Status::Error(PSLICE() << "Invalid MTProto message: too small [message.size() = " << message.size()
|
return Status::Error(PSLICE() << "Invalid MTProto message: too small [message.size() = " << message.size()
|
||||||
<< "] < [sizeof(HeaderT) = " << sizeof(HeaderT) << "]");
|
<< "] < [sizeof(HeaderT) = " << sizeof(HeaderT) << "]");
|
||||||
@ -232,7 +232,7 @@ Status Transport::read_crypto_impl(int X, MutableSlice message, const AuthKey &a
|
|||||||
|
|
||||||
UInt256 aes_key;
|
UInt256 aes_key;
|
||||||
UInt256 aes_iv;
|
UInt256 aes_iv;
|
||||||
if (info->version == 1) {
|
if (packet_info->version == 1) {
|
||||||
KDF(auth_key.key(), header->message_key, X, &aes_key, &aes_iv);
|
KDF(auth_key.key(), header->message_key, X, &aes_key, &aes_iv);
|
||||||
} else {
|
} else {
|
||||||
KDF2(auth_key.key(), header->message_key, X, &aes_key, &aes_iv);
|
KDF2(auth_key.key(), header->message_key, X, &aes_key, &aes_iv);
|
||||||
@ -251,14 +251,14 @@ Status Transport::read_crypto_impl(int X, MutableSlice message, const AuthKey &a
|
|||||||
bool is_length_bad = false;
|
bool is_length_bad = false;
|
||||||
UInt128 real_message_key;
|
UInt128 real_message_key;
|
||||||
|
|
||||||
if (info->version == 1) {
|
if (packet_info->version == 1) {
|
||||||
is_length_bad |= info->check_mod4 && prefix->message_data_length % 4 != 0;
|
is_length_bad |= packet_info->check_mod4 && prefix->message_data_length % 4 != 0;
|
||||||
auto expected_size = calc_crypto_size<HeaderT>(data_size);
|
auto expected_size = calc_crypto_size<HeaderT>(data_size);
|
||||||
is_length_bad |= expected_size != message.size();
|
is_length_bad |= expected_size != message.size();
|
||||||
auto check_size = data_size * (1 - is_length_bad) + tail_size * is_length_bad;
|
auto check_size = data_size * (1 - is_length_bad) + tail_size * is_length_bad;
|
||||||
std::tie(info->message_ack, real_message_key) = calc_message_ack_and_key(*header, check_size);
|
std::tie(packet_info->message_ack, real_message_key) = calc_message_ack_and_key(*header, check_size);
|
||||||
} else {
|
} else {
|
||||||
std::tie(info->message_ack, real_message_key) = calc_message_key2(auth_key, X, to_decrypt);
|
std::tie(packet_info->message_ack, real_message_key) = calc_message_key2(auth_key, X, to_decrypt);
|
||||||
}
|
}
|
||||||
|
|
||||||
int is_key_bad = false;
|
int is_key_bad = false;
|
||||||
@ -271,8 +271,8 @@ Status Transport::read_crypto_impl(int X, MutableSlice message, const AuthKey &a
|
|||||||
<< "] [expected = " << format::as_hex_dump(real_message_key) << "]");
|
<< "] [expected = " << format::as_hex_dump(real_message_key) << "]");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info->version == 2) {
|
if (packet_info->version == 2) {
|
||||||
if (info->check_mod4 && prefix->message_data_length % 4 != 0) {
|
if (packet_info->check_mod4 && prefix->message_data_length % 4 != 0) {
|
||||||
return Status::Error(PSLICE() << "Invalid MTProto message: invalid length (not divisible by four)"
|
return Status::Error(PSLICE() << "Invalid MTProto message: invalid length (not divisible by four)"
|
||||||
<< tag("total_size", message.size())
|
<< tag("total_size", message.size())
|
||||||
<< tag("message_data_length", prefix->message_data_length));
|
<< tag("message_data_length", prefix->message_data_length));
|
||||||
@ -299,33 +299,35 @@ Status Transport::read_crypto_impl(int X, MutableSlice message, const AuthKey &a
|
|||||||
return Status::OK();
|
return Status::OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
Status Transport::read_crypto(MutableSlice message, const AuthKey &auth_key, PacketInfo *info, MutableSlice *data) {
|
Status Transport::read_crypto(MutableSlice message, const AuthKey &auth_key, PacketInfo *packet_info,
|
||||||
|
MutableSlice *data) {
|
||||||
CryptoHeader *header = nullptr;
|
CryptoHeader *header = nullptr;
|
||||||
CryptoPrefix *prefix = nullptr;
|
CryptoPrefix *prefix = nullptr;
|
||||||
TRY_STATUS(read_crypto_impl(8, message, auth_key, &header, &prefix, data, info));
|
TRY_STATUS(read_crypto_impl(8, message, auth_key, &header, &prefix, data, packet_info));
|
||||||
CHECK(header != nullptr);
|
CHECK(header != nullptr);
|
||||||
CHECK(prefix != nullptr);
|
CHECK(prefix != nullptr);
|
||||||
CHECK(info != nullptr);
|
CHECK(packet_info != nullptr);
|
||||||
info->type = PacketInfo::Common;
|
packet_info->type = PacketInfo::Common;
|
||||||
info->salt = header->salt;
|
packet_info->salt = header->salt;
|
||||||
info->session_id = header->session_id;
|
packet_info->session_id = header->session_id;
|
||||||
info->message_id = prefix->message_id;
|
packet_info->message_id = prefix->message_id;
|
||||||
info->seq_no = prefix->seq_no;
|
packet_info->seq_no = prefix->seq_no;
|
||||||
return Status::OK();
|
return Status::OK();
|
||||||
}
|
}
|
||||||
Status Transport::read_e2e_crypto(MutableSlice message, const AuthKey &auth_key, PacketInfo *info, MutableSlice *data) {
|
Status Transport::read_e2e_crypto(MutableSlice message, const AuthKey &auth_key, PacketInfo *packet_info,
|
||||||
|
MutableSlice *data) {
|
||||||
EndToEndHeader *header = nullptr;
|
EndToEndHeader *header = nullptr;
|
||||||
EndToEndPrefix *prefix = nullptr;
|
EndToEndPrefix *prefix = nullptr;
|
||||||
TRY_STATUS(read_crypto_impl(info->is_creator && info->version != 1 ? 8 : 0, message, auth_key, &header, &prefix, data,
|
TRY_STATUS(read_crypto_impl(packet_info->is_creator && packet_info->version != 1 ? 8 : 0, message, auth_key, &header,
|
||||||
info));
|
&prefix, data, packet_info));
|
||||||
CHECK(header != nullptr);
|
CHECK(header != nullptr);
|
||||||
CHECK(prefix != nullptr);
|
CHECK(prefix != nullptr);
|
||||||
CHECK(info != nullptr);
|
CHECK(packet_info != nullptr);
|
||||||
info->type = PacketInfo::EndToEnd;
|
packet_info->type = PacketInfo::EndToEnd;
|
||||||
return Status::OK();
|
return Status::OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferWriter Transport::write_no_crypto(const Storer &storer, PacketInfo *info, size_t prepend_size,
|
BufferWriter Transport::write_no_crypto(const Storer &storer, PacketInfo *packet_info, size_t prepend_size,
|
||||||
size_t append_size) {
|
size_t append_size) {
|
||||||
size_t size = calc_no_crypto_size(storer.size());
|
size_t size = calc_no_crypto_size(storer.size());
|
||||||
auto packet = BufferWriter{size, prepend_size, append_size};
|
auto packet = BufferWriter{size, prepend_size, append_size};
|
||||||
@ -339,7 +341,7 @@ BufferWriter Transport::write_no_crypto(const Storer &storer, PacketInfo *info,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class HeaderT>
|
template <class HeaderT>
|
||||||
void Transport::write_crypto_impl(int X, const Storer &storer, const AuthKey &auth_key, PacketInfo *info,
|
void Transport::write_crypto_impl(int X, const Storer &storer, const AuthKey &auth_key, PacketInfo *packet_info,
|
||||||
HeaderT *header, size_t data_size, size_t padded_size) {
|
HeaderT *header, size_t data_size, size_t padded_size) {
|
||||||
auto real_data_size = storer.store(header->data);
|
auto real_data_size = storer.store(header->data);
|
||||||
CHECK(real_data_size == data_size);
|
CHECK(real_data_size == data_size);
|
||||||
@ -352,47 +354,47 @@ void Transport::write_crypto_impl(int X, const Storer &storer, const AuthKey &au
|
|||||||
|
|
||||||
UInt256 aes_key;
|
UInt256 aes_key;
|
||||||
UInt256 aes_iv;
|
UInt256 aes_iv;
|
||||||
if (info->version == 1) {
|
if (packet_info->version == 1) {
|
||||||
std::tie(info->message_ack, header->message_key) = calc_message_ack_and_key(*header, data_size);
|
std::tie(packet_info->message_ack, header->message_key) = calc_message_ack_and_key(*header, data_size);
|
||||||
KDF(auth_key.key(), header->message_key, X, &aes_key, &aes_iv);
|
KDF(auth_key.key(), header->message_key, X, &aes_key, &aes_iv);
|
||||||
} else {
|
} else {
|
||||||
std::tie(info->message_ack, header->message_key) = calc_message_key2(auth_key, X, to_encrypt);
|
std::tie(packet_info->message_ack, header->message_key) = calc_message_key2(auth_key, X, to_encrypt);
|
||||||
KDF2(auth_key.key(), header->message_key, X, &aes_key, &aes_iv);
|
KDF2(auth_key.key(), header->message_key, X, &aes_key, &aes_iv);
|
||||||
}
|
}
|
||||||
|
|
||||||
aes_ige_encrypt(as_slice(aes_key), as_mutable_slice(aes_iv), to_encrypt, to_encrypt);
|
aes_ige_encrypt(as_slice(aes_key), as_mutable_slice(aes_iv), to_encrypt, to_encrypt);
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferWriter Transport::write_crypto(const Storer &storer, const AuthKey &auth_key, PacketInfo *info,
|
BufferWriter Transport::write_crypto(const Storer &storer, const AuthKey &auth_key, PacketInfo *packet_info,
|
||||||
size_t prepend_size, size_t append_size) {
|
size_t prepend_size, size_t append_size) {
|
||||||
size_t data_size = storer.size();
|
size_t data_size = storer.size();
|
||||||
size_t padded_size;
|
size_t padded_size;
|
||||||
if (info->version == 1) {
|
if (packet_info->version == 1) {
|
||||||
padded_size = calc_crypto_size<CryptoHeader>(data_size);
|
padded_size = calc_crypto_size<CryptoHeader>(data_size);
|
||||||
} else {
|
} else {
|
||||||
padded_size = calc_crypto_size2<CryptoHeader>(data_size, info);
|
padded_size = calc_crypto_size2<CryptoHeader>(data_size, packet_info);
|
||||||
}
|
}
|
||||||
auto packet = BufferWriter{padded_size, prepend_size, append_size};
|
auto packet = BufferWriter{padded_size, prepend_size, append_size};
|
||||||
|
|
||||||
//FIXME: rewrite without reinterpret cast
|
//FIXME: rewrite without reinterpret cast
|
||||||
auto &header = *reinterpret_cast<CryptoHeader *>(packet.as_mutable_slice().begin());
|
auto &header = *reinterpret_cast<CryptoHeader *>(packet.as_mutable_slice().begin());
|
||||||
header.auth_key_id = auth_key.id();
|
header.auth_key_id = auth_key.id();
|
||||||
header.salt = info->salt;
|
header.salt = packet_info->salt;
|
||||||
header.session_id = info->session_id;
|
header.session_id = packet_info->session_id;
|
||||||
|
|
||||||
write_crypto_impl(0, storer, auth_key, info, &header, data_size, padded_size);
|
write_crypto_impl(0, storer, auth_key, packet_info, &header, data_size, padded_size);
|
||||||
|
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferWriter Transport::write_e2e_crypto(const Storer &storer, const AuthKey &auth_key, PacketInfo *info,
|
BufferWriter Transport::write_e2e_crypto(const Storer &storer, const AuthKey &auth_key, PacketInfo *packet_info,
|
||||||
size_t prepend_size, size_t append_size) {
|
size_t prepend_size, size_t append_size) {
|
||||||
size_t data_size = storer.size();
|
size_t data_size = storer.size();
|
||||||
size_t padded_size;
|
size_t padded_size;
|
||||||
if (info->version == 1) {
|
if (packet_info->version == 1) {
|
||||||
padded_size = calc_crypto_size<EndToEndHeader>(data_size);
|
padded_size = calc_crypto_size<EndToEndHeader>(data_size);
|
||||||
} else {
|
} else {
|
||||||
padded_size = calc_crypto_size2<EndToEndHeader>(data_size, info);
|
padded_size = calc_crypto_size2<EndToEndHeader>(data_size, packet_info);
|
||||||
}
|
}
|
||||||
auto packet = BufferWriter{padded_size, prepend_size, append_size};
|
auto packet = BufferWriter{padded_size, prepend_size, append_size};
|
||||||
|
|
||||||
@ -400,8 +402,8 @@ BufferWriter Transport::write_e2e_crypto(const Storer &storer, const AuthKey &au
|
|||||||
auto &header = *reinterpret_cast<EndToEndHeader *>(packet.as_mutable_slice().begin());
|
auto &header = *reinterpret_cast<EndToEndHeader *>(packet.as_mutable_slice().begin());
|
||||||
header.auth_key_id = auth_key.id();
|
header.auth_key_id = auth_key.id();
|
||||||
|
|
||||||
write_crypto_impl(info->is_creator || info->version == 1 ? 0 : 8, storer, auth_key, info, &header, data_size,
|
write_crypto_impl(packet_info->is_creator || packet_info->version == 1 ? 0 : 8, storer, auth_key, packet_info,
|
||||||
padded_size);
|
&header, data_size, padded_size);
|
||||||
|
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
@ -413,7 +415,7 @@ Result<uint64> Transport::read_auth_key_id(Slice message) {
|
|||||||
return as<uint64>(message.begin());
|
return as<uint64>(message.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<Transport::ReadResult> Transport::read(MutableSlice message, const AuthKey &auth_key, PacketInfo *info) {
|
Result<Transport::ReadResult> Transport::read(MutableSlice message, const AuthKey &auth_key, PacketInfo *packet_info) {
|
||||||
if (message.size() < 12) {
|
if (message.size() < 12) {
|
||||||
if (message.size() < 4) {
|
if (message.size() < 4) {
|
||||||
return Status::Error(PSLICE() << "Invalid MTProto message: smaller than 4 bytes [size = " << message.size()
|
return Status::Error(PSLICE() << "Invalid MTProto message: smaller than 4 bytes [size = " << message.size()
|
||||||
@ -430,31 +432,31 @@ Result<Transport::ReadResult> Transport::read(MutableSlice message, const AuthKe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
info->no_crypto_flag = as<int64>(message.begin()) == 0;
|
packet_info->no_crypto_flag = as<int64>(message.begin()) == 0;
|
||||||
MutableSlice data;
|
MutableSlice data;
|
||||||
if (info->type == PacketInfo::EndToEnd) {
|
if (packet_info->type == PacketInfo::EndToEnd) {
|
||||||
TRY_STATUS(read_e2e_crypto(message, auth_key, info, &data));
|
TRY_STATUS(read_e2e_crypto(message, auth_key, packet_info, &data));
|
||||||
} else if (info->no_crypto_flag) {
|
} else if (packet_info->no_crypto_flag) {
|
||||||
TRY_STATUS(read_no_crypto(message, info, &data));
|
TRY_STATUS(read_no_crypto(message, packet_info, &data));
|
||||||
} else {
|
} else {
|
||||||
if (auth_key.empty()) {
|
if (auth_key.empty()) {
|
||||||
return Status::Error("Failed to decrypt MTProto message: auth key is empty");
|
return Status::Error("Failed to decrypt MTProto message: auth key is empty");
|
||||||
}
|
}
|
||||||
TRY_STATUS(read_crypto(message, auth_key, info, &data));
|
TRY_STATUS(read_crypto(message, auth_key, packet_info, &data));
|
||||||
}
|
}
|
||||||
return ReadResult::make_packet(data);
|
return ReadResult::make_packet(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferWriter Transport::write(const Storer &storer, const AuthKey &auth_key, PacketInfo *info, size_t prepend_size,
|
BufferWriter Transport::write(const Storer &storer, const AuthKey &auth_key, PacketInfo *packet_info,
|
||||||
size_t append_size) {
|
size_t prepend_size, size_t append_size) {
|
||||||
if (info->type == PacketInfo::EndToEnd) {
|
if (packet_info->type == PacketInfo::EndToEnd) {
|
||||||
return write_e2e_crypto(storer, auth_key, info, prepend_size, append_size);
|
return write_e2e_crypto(storer, auth_key, packet_info, prepend_size, append_size);
|
||||||
}
|
}
|
||||||
if (info->no_crypto_flag) {
|
if (packet_info->no_crypto_flag) {
|
||||||
return write_no_crypto(storer, info, prepend_size, append_size);
|
return write_no_crypto(storer, packet_info, prepend_size, append_size);
|
||||||
} else {
|
} else {
|
||||||
CHECK(!auth_key.empty());
|
CHECK(!auth_key.empty());
|
||||||
return write_crypto(storer, auth_key, info, prepend_size, append_size);
|
return write_crypto(storer, auth_key, packet_info, prepend_size, append_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,10 +87,11 @@ class Transport {
|
|||||||
// Returns size of MTProto packet.
|
// Returns size of MTProto packet.
|
||||||
// If dest.size() >= size, the packet is also written into [dest].
|
// If dest.size() >= size, the packet is also written into [dest].
|
||||||
// If auth_key is nonempty, encryption will be used.
|
// If auth_key is nonempty, encryption will be used.
|
||||||
static Result<ReadResult> read(MutableSlice message, const AuthKey &auth_key, PacketInfo *info) TD_WARN_UNUSED_RESULT;
|
static Result<ReadResult> read(MutableSlice message, const AuthKey &auth_key,
|
||||||
|
PacketInfo *packet_info) TD_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
static BufferWriter write(const Storer &storer, const AuthKey &auth_key, PacketInfo *info, size_t prepend_size = 0,
|
static BufferWriter write(const Storer &storer, const AuthKey &auth_key, PacketInfo *packet_info,
|
||||||
size_t append_size = 0);
|
size_t prepend_size = 0, size_t append_size = 0);
|
||||||
|
|
||||||
// public for testing purposes
|
// public for testing purposes
|
||||||
static std::pair<uint32, UInt128> calc_message_key2(const AuthKey &auth_key, int X, Slice to_encrypt);
|
static std::pair<uint32, UInt128> calc_message_key2(const AuthKey &auth_key, int X, Slice to_encrypt);
|
||||||
@ -103,33 +104,35 @@ class Transport {
|
|||||||
static size_t calc_crypto_size(size_t data_size);
|
static size_t calc_crypto_size(size_t data_size);
|
||||||
|
|
||||||
template <class HeaderT>
|
template <class HeaderT>
|
||||||
static size_t calc_crypto_size2(size_t data_size, PacketInfo *info);
|
static size_t calc_crypto_size2(size_t data_size, PacketInfo *packet_info);
|
||||||
|
|
||||||
static size_t calc_no_crypto_size(size_t data_size);
|
static size_t calc_no_crypto_size(size_t data_size);
|
||||||
|
|
||||||
static Status read_no_crypto(MutableSlice message, PacketInfo *info, MutableSlice *data) TD_WARN_UNUSED_RESULT;
|
static Status read_no_crypto(MutableSlice message, PacketInfo *packet_info, MutableSlice *data) TD_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
static Status read_crypto(MutableSlice message, const AuthKey &auth_key, PacketInfo *info,
|
static Status read_crypto(MutableSlice message, const AuthKey &auth_key, PacketInfo *packet_info,
|
||||||
MutableSlice *data) TD_WARN_UNUSED_RESULT;
|
MutableSlice *data) TD_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
static Status read_e2e_crypto(MutableSlice message, const AuthKey &auth_key, PacketInfo *info,
|
static Status read_e2e_crypto(MutableSlice message, const AuthKey &auth_key, PacketInfo *packet_info,
|
||||||
MutableSlice *data) TD_WARN_UNUSED_RESULT;
|
MutableSlice *data) TD_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
template <class HeaderT, class PrefixT>
|
template <class HeaderT, class PrefixT>
|
||||||
static Status read_crypto_impl(int X, MutableSlice message, const AuthKey &auth_key, HeaderT **header_ptr,
|
static Status read_crypto_impl(int X, MutableSlice message, const AuthKey &auth_key, HeaderT **header_ptr,
|
||||||
PrefixT **prefix_ptr, MutableSlice *data, PacketInfo *info) TD_WARN_UNUSED_RESULT;
|
PrefixT **prefix_ptr, MutableSlice *data,
|
||||||
|
PacketInfo *packet_info) TD_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
static BufferWriter write_no_crypto(const Storer &storer, PacketInfo *info, size_t prepend_size, size_t append_size);
|
static BufferWriter write_no_crypto(const Storer &storer, PacketInfo *packet_info, size_t prepend_size,
|
||||||
|
size_t append_size);
|
||||||
|
|
||||||
static BufferWriter write_crypto(const Storer &storer, const AuthKey &auth_key, PacketInfo *info, size_t prepend_size,
|
static BufferWriter write_crypto(const Storer &storer, const AuthKey &auth_key, PacketInfo *packet_info,
|
||||||
size_t append_size);
|
size_t prepend_size, size_t append_size);
|
||||||
|
|
||||||
static BufferWriter write_e2e_crypto(const Storer &storer, const AuthKey &auth_key, PacketInfo *info,
|
static BufferWriter write_e2e_crypto(const Storer &storer, const AuthKey &auth_key, PacketInfo *packet_info,
|
||||||
size_t prepend_size, size_t append_size);
|
size_t prepend_size, size_t append_size);
|
||||||
|
|
||||||
template <class HeaderT>
|
template <class HeaderT>
|
||||||
static void write_crypto_impl(int X, const Storer &storer, const AuthKey &auth_key, PacketInfo *info, HeaderT *header,
|
static void write_crypto_impl(int X, const Storer &storer, const AuthKey &auth_key, PacketInfo *packet_info,
|
||||||
size_t data_size, size_t padded_size);
|
HeaderT *header, size_t data_size, size_t padded_size);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mtproto
|
} // namespace mtproto
|
||||||
|
@ -223,11 +223,11 @@ Result<BufferSlice> SecretChatActor::create_encrypted_message(int32 my_in_seq_no
|
|||||||
LOG(INFO) << "Create message " << to_string(message_with_layer);
|
LOG(INFO) << "Create message " << to_string(message_with_layer);
|
||||||
auto storer = create_storer(*message_with_layer);
|
auto storer = create_storer(*message_with_layer);
|
||||||
auto new_storer = mtproto::PacketStorer<SecretImpl>(storer);
|
auto new_storer = mtproto::PacketStorer<SecretImpl>(storer);
|
||||||
mtproto::PacketInfo info;
|
mtproto::PacketInfo packet_info;
|
||||||
info.type = mtproto::PacketInfo::EndToEnd;
|
packet_info.type = mtproto::PacketInfo::EndToEnd;
|
||||||
info.version = 2;
|
packet_info.version = 2;
|
||||||
info.is_creator = auth_state_.x == 0;
|
packet_info.is_creator = auth_state_.x == 0;
|
||||||
auto packet_writer = mtproto::Transport::write(new_storer, *auth_key, &info);
|
auto packet_writer = mtproto::Transport::write(new_storer, *auth_key, &packet_info);
|
||||||
message = std::move(message_with_layer->message_);
|
message = std::move(message_with_layer->message_);
|
||||||
return packet_writer.as_buffer_slice();
|
return packet_writer.as_buffer_slice();
|
||||||
}
|
}
|
||||||
@ -792,12 +792,12 @@ Result<std::tuple<uint64, BufferSlice, int32>> SecretChatActor::decrypt(BufferSl
|
|||||||
data = encrypted_message_copy.as_mutable_slice();
|
data = encrypted_message_copy.as_mutable_slice();
|
||||||
CHECK(is_aligned_pointer<4>(data.data()));
|
CHECK(is_aligned_pointer<4>(data.data()));
|
||||||
|
|
||||||
mtproto::PacketInfo info;
|
mtproto::PacketInfo packet_info;
|
||||||
info.type = mtproto::PacketInfo::EndToEnd;
|
packet_info.type = mtproto::PacketInfo::EndToEnd;
|
||||||
mtproto_version = versions[i];
|
mtproto_version = versions[i];
|
||||||
info.version = mtproto_version;
|
packet_info.version = mtproto_version;
|
||||||
info.is_creator = auth_state_.x == 0;
|
packet_info.is_creator = auth_state_.x == 0;
|
||||||
r_read_result = mtproto::Transport::read(data, *auth_key, &info);
|
r_read_result = mtproto::Transport::read(data, *auth_key, &packet_info);
|
||||||
if (i + 1 != versions.size() && r_read_result.is_error()) {
|
if (i + 1 != versions.size() && r_read_result.is_error()) {
|
||||||
if (config_state_.his_layer >= static_cast<int32>(SecretChatLayer::Mtproto2)) {
|
if (config_state_.his_layer >= static_cast<int32>(SecretChatLayer::Mtproto2)) {
|
||||||
LOG(WARNING) << tag("mtproto", mtproto_version) << " decryption failed " << r_read_result.error();
|
LOG(WARNING) << tag("mtproto", mtproto_version) << " decryption failed " << r_read_result.error();
|
||||||
|
Loading…
Reference in New Issue
Block a user