19
#include "adnl-channel.hpp"
21
#include "adnl-peer-table.h"
23
#include "td/utils/crypto.h"
24
#include "crypto/Ed25519.h"
30
td::Result<td::actor::ActorOwn<AdnlChannel>> AdnlChannel::create(privkeys::Ed25519 pk_data, pubkeys::Ed25519 pub_data,
31
AdnlNodeIdShort local_id, AdnlNodeIdShort peer_id,
32
AdnlChannelIdShort &out_id, AdnlChannelIdShort &in_id,
33
td::actor::ActorId<AdnlPeerPair> peer_pair) {
34
td::Ed25519::PublicKey pub_k = pub_data.export_key();
35
td::Ed25519::PrivateKey priv_k = pk_data.export_key();
37
TRY_RESULT_PREFIX(shared_secret, td::Ed25519::compute_shared_secret(pub_k, priv_k),
38
"failed to compute channel shared secret: ");
39
CHECK(shared_secret.length() == 32);
41
td::SecureString rev_secret{32};
42
for (td::uint32 i = 0; i < 32; i++) {
43
rev_secret.as_mutable_slice()[i] = shared_secret[31 - i];
46
auto R = [&]() -> std::pair<PrivateKey, PublicKey> {
47
if (local_id < peer_id) {
48
return {privkeys::AES{std::move(shared_secret)}, pubkeys::AES{std::move(rev_secret)}};
49
} else if (peer_id < local_id) {
50
return {privkeys::AES{std::move(rev_secret)}, pubkeys::AES{std::move(shared_secret)}};
52
auto c = shared_secret.copy();
53
return {privkeys::AES{std::move(c)}, pubkeys::AES{std::move(shared_secret)}};
57
in_id = AdnlChannelIdShort{R.first.compute_short_id()};
58
out_id = AdnlChannelIdShort{R.second.compute_short_id()};
60
TRY_RESULT_PREFIX(encryptor, R.second.create_encryptor(), "failed to init channel encryptor: ");
61
TRY_RESULT_PREFIX(decryptor, R.first.create_decryptor(), "failed to init channel decryptor: ");
63
return td::actor::create_actor<AdnlChannelImpl>("channel", local_id, peer_id, peer_pair, in_id, out_id,
64
std::move(encryptor), std::move(decryptor));
67
AdnlChannelImpl::AdnlChannelImpl(AdnlNodeIdShort local_id, AdnlNodeIdShort peer_id,
68
td::actor::ActorId<AdnlPeerPair> peer_pair, AdnlChannelIdShort in_id,
69
AdnlChannelIdShort out_id, std::unique_ptr<Encryptor> encryptor,
70
std::unique_ptr<Decryptor> decryptor) {
74
encryptor_ = std::move(encryptor);
75
decryptor_ = std::move(decryptor);
77
channel_in_id_ = in_id;
78
channel_out_id_ = out_id;
80
peer_pair_ = peer_pair;
82
VLOG(ADNL_INFO) << this << ": created";
85
void AdnlChannelImpl::decrypt(td::BufferSlice raw_data, td::Promise<AdnlPacket> promise) {
86
TRY_RESULT_PROMISE_PREFIX(promise, data, decryptor_->decrypt(raw_data.as_slice()),
87
"failed to decrypt channel message: ");
88
TRY_RESULT_PROMISE_PREFIX(promise, tl_packet, fetch_tl_object<ton_api::adnl_packetContents>(std::move(data), true),
89
"decrypted channel packet contains invalid TL scheme: ");
90
TRY_RESULT_PROMISE_PREFIX(promise, packet, AdnlPacket::create(std::move(tl_packet)), "received bad packet: ");
91
if (packet.inited_from_short() && packet.from_short() != peer_id_) {
92
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "bad channel packet destination"));
95
promise.set_value(std::move(packet));
98
void AdnlChannelImpl::send_message(td::uint32 priority, td::actor::ActorId<AdnlNetworkConnection> conn,
99
td::BufferSlice data) {
100
auto E = encryptor_->encrypt(data.as_slice());
102
VLOG(ADNL_ERROR) << this << ": dropping OUT message: can not encrypt: " << E.move_as_error();
105
auto enc = E.move_as_ok();
106
auto B = td::BufferSlice(enc.size() + 32);
107
td::MutableSlice S = B.as_slice();
108
S.copy_from(channel_out_id_.as_slice());
110
S.copy_from(enc.as_slice());
111
td::actor::send_closure(conn, &AdnlNetworkConnection::send, local_id_, peer_id_, priority, std::move(B));
114
void AdnlChannelImpl::receive(td::IPAddress addr, td::BufferSlice data) {
115
auto P = td::PromiseCreator::lambda(
116
[peer = peer_pair_, channel_id = channel_in_id_, addr, id = print_id()](td::Result<AdnlPacket> R) {
118
VLOG(ADNL_WARNING) << id << ": dropping IN message: can not decrypt: " << R.move_as_error();
120
auto packet = R.move_as_ok();
121
packet.set_remote_addr(addr);
122
td::actor::send_closure(peer, &AdnlPeerPair::receive_packet_from_channel, channel_id, std::move(packet));
126
decrypt(std::move(data), std::move(P));