2018-12-31 20:04:05 +01:00
|
|
|
//
|
2020-01-01 02:23:48 +01:00
|
|
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2020
|
2018-12-31 20:04:05 +01:00
|
|
|
//
|
|
|
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
|
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
//
|
|
|
|
#pragma once
|
2018-06-26 21:51:00 +02:00
|
|
|
|
2019-01-31 03:23:40 +01:00
|
|
|
#include "td/mtproto/PacketInfo.h"
|
2018-12-31 20:04:05 +01:00
|
|
|
|
|
|
|
#include "td/utils/common.h"
|
|
|
|
#include "td/utils/Slice.h"
|
|
|
|
#include "td/utils/Status.h"
|
2019-02-12 17:48:52 +01:00
|
|
|
#include "td/utils/StorerBase.h"
|
2018-12-19 22:18:53 +01:00
|
|
|
#include "td/utils/UInt.h"
|
2018-12-31 20:04:05 +01:00
|
|
|
|
2019-01-31 03:27:21 +01:00
|
|
|
#include <utility>
|
2018-12-31 20:04:05 +01:00
|
|
|
|
|
|
|
namespace td {
|
2020-10-05 17:07:23 +02:00
|
|
|
|
|
|
|
extern int VERBOSITY_NAME(raw_mtproto);
|
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
namespace mtproto {
|
2019-01-31 03:05:40 +01:00
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
class AuthKey;
|
|
|
|
|
|
|
|
class Transport {
|
|
|
|
public:
|
2018-06-17 19:52:40 +02:00
|
|
|
class ReadResult {
|
|
|
|
public:
|
|
|
|
enum Type { Packet, Nop, Error, Quickack };
|
|
|
|
|
|
|
|
static ReadResult make_nop() {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
static ReadResult make_error(int32 error_code) {
|
|
|
|
ReadResult res;
|
|
|
|
res.type_ = Error;
|
|
|
|
res.error_code_ = error_code;
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
static ReadResult make_packet(MutableSlice packet) {
|
|
|
|
CHECK(!packet.empty());
|
|
|
|
ReadResult res;
|
|
|
|
res.type_ = Packet;
|
|
|
|
res.packet_ = packet;
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
static ReadResult make_quick_ack(uint32 quick_ack) {
|
|
|
|
ReadResult res;
|
|
|
|
res.type_ = Quickack;
|
|
|
|
res.quick_ack_ = quick_ack;
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
Type type() const {
|
|
|
|
return type_;
|
|
|
|
}
|
|
|
|
|
|
|
|
MutableSlice packet() const {
|
|
|
|
CHECK(type_ == Packet);
|
|
|
|
return packet_;
|
|
|
|
}
|
|
|
|
uint32 quick_ack() const {
|
|
|
|
CHECK(type_ == Quickack);
|
|
|
|
return quick_ack_;
|
|
|
|
}
|
|
|
|
int32 error() const {
|
|
|
|
CHECK(type_ == Error);
|
|
|
|
return error_code_;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
Type type_ = Nop;
|
|
|
|
MutableSlice packet_;
|
2018-10-26 16:11:20 +02:00
|
|
|
int32 error_code_ = 0;
|
|
|
|
uint32 quick_ack_ = 0;
|
2018-06-17 19:52:40 +02:00
|
|
|
};
|
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
static Result<uint64> read_auth_key_id(Slice message);
|
|
|
|
|
|
|
|
// Reads mtproto packet from [message] and saves into [data].
|
|
|
|
// If message is encrypted, [auth_key] is used.
|
|
|
|
// Decryption and unpacking is made inplace, so [data] will be subslice of [message].
|
|
|
|
// Returns size of mtproto packet.
|
|
|
|
// If dest.size() >= size, the packet is also written into [dest].
|
|
|
|
// If auth_key is nonempty, encryption will be used.
|
2018-06-17 19:52:40 +02:00
|
|
|
static Result<ReadResult> read(MutableSlice message, const AuthKey &auth_key, PacketInfo *info) TD_WARN_UNUSED_RESULT;
|
2018-12-31 20:04:05 +01:00
|
|
|
|
|
|
|
static size_t write(const Storer &storer, const AuthKey &auth_key, PacketInfo *info,
|
|
|
|
MutableSlice dest = MutableSlice());
|
|
|
|
|
|
|
|
private:
|
|
|
|
template <class HeaderT>
|
2019-01-31 03:27:21 +01:00
|
|
|
static std::pair<uint32, UInt128> calc_message_ack_and_key(const HeaderT &head, size_t data_size);
|
2018-12-31 20:04:05 +01:00
|
|
|
|
2019-01-31 03:27:21 +01:00
|
|
|
static std::pair<uint32, UInt128> calc_message_key2(const AuthKey &auth_key, int X, Slice to_encrypt);
|
2018-12-31 20:04:05 +01:00
|
|
|
|
|
|
|
template <class HeaderT>
|
|
|
|
static size_t calc_crypto_size(size_t data_size);
|
|
|
|
|
|
|
|
template <class HeaderT>
|
2019-07-04 12:56:10 +02:00
|
|
|
static size_t calc_crypto_size2(size_t data_size, PacketInfo *info);
|
2018-12-31 20:04:05 +01:00
|
|
|
|
|
|
|
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_crypto(MutableSlice message, const AuthKey &auth_key, PacketInfo *info,
|
|
|
|
MutableSlice *data) TD_WARN_UNUSED_RESULT;
|
|
|
|
static Status read_e2e_crypto(MutableSlice message, const AuthKey &auth_key, PacketInfo *info,
|
|
|
|
MutableSlice *data) TD_WARN_UNUSED_RESULT;
|
|
|
|
template <class HeaderT, class PrefixT>
|
|
|
|
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;
|
|
|
|
|
|
|
|
static size_t write_no_crypto(const Storer &storer, PacketInfo *info, MutableSlice dest);
|
|
|
|
|
|
|
|
static size_t write_crypto(const Storer &storer, const AuthKey &auth_key, PacketInfo *info, MutableSlice dest);
|
|
|
|
static size_t write_e2e_crypto(const Storer &storer, const AuthKey &auth_key, PacketInfo *info, MutableSlice dest);
|
|
|
|
template <class HeaderT>
|
|
|
|
static void write_crypto_impl(int X, const Storer &storer, const AuthKey &auth_key, PacketInfo *info, HeaderT *header,
|
|
|
|
size_t data_size);
|
|
|
|
};
|
2018-06-26 21:51:00 +02:00
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
} // namespace mtproto
|
|
|
|
} // namespace td
|