Skip to content

Commit

Permalink
Update to 8.7.1
Browse files Browse the repository at this point in the history
  • Loading branch information
xaxtix committed Apr 21, 2022
1 parent 1e50785 commit 8309ac8
Show file tree
Hide file tree
Showing 70 changed files with 2,480 additions and 1,043 deletions.
4 changes: 2 additions & 2 deletions TMessagesProj/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ android {
}
}

defaultConfig.versionCode = 2622
defaultConfig.versionCode = 2629

applicationVariants.all { variant ->
variant.outputs.all { output ->
Expand All @@ -319,7 +319,7 @@ android {
defaultConfig {
minSdkVersion 16
targetSdkVersion 30
versionName "8.7.0"
versionName "8.7.1"

vectorDrawables.generatedDensities = ['mdpi', 'hdpi', 'xhdpi', 'xxhdpi']

Expand Down
180 changes: 179 additions & 1 deletion TMessagesProj/jni/voip/tgcalls/EncryptedConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ constexpr auto kServiceCauseResend = 2;

static constexpr uint8_t kAckId = uint8_t(-1);
static constexpr uint8_t kEmptyId = uint8_t(-2);
static constexpr uint8_t kCustomId = uint8_t(127);

void AppendSeq(rtc::CopyOnWriteBuffer &buffer, uint32_t seq) {
const auto bytes = rtc::HostToNetwork32(seq);
Expand Down Expand Up @@ -68,6 +69,22 @@ bool ConstTimeIsDifferent(const void *a, const void *b, size_t size) {
return different;
}

rtc::CopyOnWriteBuffer SerializeRawMessageWithSeq(
const rtc::CopyOnWriteBuffer &message,
uint32_t seq,
bool singleMessagePacket) {
rtc::ByteBufferWriter writer;
writer.WriteUInt32(seq);
writer.WriteUInt8(kCustomId);
writer.WriteUInt32((uint32_t)message.size());
writer.WriteBytes((const char *)message.data(), message.size());

auto result = rtc::CopyOnWriteBuffer();
result.AppendData(writer.Data(), writer.Length());

return result;
}

} // namespace

EncryptedConnection::EncryptedConnection(
Expand Down Expand Up @@ -142,7 +159,7 @@ auto EncryptedConnection::prepareForSending(const Message &message)
const auto messageRequiresAck = absl::visit([](const auto &data) {
return std::decay_t<decltype(data)>::kRequiresAck;
}, message.data);

// If message requires ack, then we can't serialize it as a single
// message packet, because later it may be sent as a part of big packet.
const auto singleMessagePacket = !haveAdditionalMessages() && !messageRequiresAck;
Expand All @@ -152,6 +169,25 @@ auto EncryptedConnection::prepareForSending(const Message &message)
}
const auto seq = *maybeSeq;
auto serialized = SerializeMessageWithSeq(message, seq, singleMessagePacket);

return prepareForSendingMessageInternal(serialized, seq, messageRequiresAck);
}

absl::optional<EncryptedConnection::EncryptedPacket> EncryptedConnection::prepareForSendingRawMessage(rtc::CopyOnWriteBuffer &message, bool messageRequiresAck) {
// If message requires ack, then we can't serialize it as a single
// message packet, because later it may be sent as a part of big packet.
const auto singleMessagePacket = !haveAdditionalMessages() && !messageRequiresAck;
const auto maybeSeq = computeNextSeq(messageRequiresAck, singleMessagePacket);
if (!maybeSeq) {
return absl::nullopt;
}
const auto seq = *maybeSeq;
auto serialized = SerializeRawMessageWithSeq(message, seq, singleMessagePacket);

return prepareForSendingMessageInternal(serialized, seq, messageRequiresAck);
}

absl::optional<EncryptedConnection::EncryptedPacket> EncryptedConnection::prepareForSendingMessageInternal(rtc::CopyOnWriteBuffer &serialized, uint32_t seq, bool messageRequiresAck) {
if (!enoughSpaceInPacket(serialized, 0)) {
return LogError("Too large packet: ", std::to_string(serialized.size()));
}
Expand Down Expand Up @@ -404,6 +440,41 @@ auto EncryptedConnection::handleIncomingPacket(const char *bytes, size_t size)
return processPacket(decryptionBuffer, incomingSeq);
}

absl::optional<EncryptedConnection::DecryptedRawPacket> EncryptedConnection::handleIncomingRawPacket(const char *bytes, size_t size) {
if (size < 21 || size > kMaxIncomingPacketSize) {
return LogError("Bad incoming packet size: ", std::to_string(size));
}

const auto x = (_key.isOutgoing ? 8 : 0) + (_type == Type::Signaling ? 128 : 0);
const auto key = _key.value->data();
const auto msgKey = reinterpret_cast<const uint8_t*>(bytes);
const auto encryptedData = msgKey + 16;
const auto dataSize = size - 16;

auto aesKeyIv = PrepareAesKeyIv(key, msgKey, x);

auto decryptionBuffer = rtc::Buffer(dataSize);
AesProcessCtr(
MemorySpan{ encryptedData, dataSize },
decryptionBuffer.data(),
std::move(aesKeyIv));

const auto msgKeyLarge = ConcatSHA256(
MemorySpan{ key + 88 + x, 32 },
MemorySpan{ decryptionBuffer.data(), decryptionBuffer.size() });
if (ConstTimeIsDifferent(msgKeyLarge.data() + 8, msgKey, 16)) {
return LogError("Bad incoming data hash.");
}

const auto incomingSeq = ReadSeq(decryptionBuffer.data());
const auto incomingCounter = CounterFromSeq(incomingSeq);
if (!registerIncomingCounter(incomingCounter)) {
// We've received that packet already.
return LogError("Already handled packet received.", std::to_string(incomingCounter));
}
return processRawPacket(decryptionBuffer, incomingSeq);
}

auto EncryptedConnection::processPacket(
const rtc::Buffer &fullBuffer,
uint32_t packetSeq)
Expand Down Expand Up @@ -490,6 +561,98 @@ auto EncryptedConnection::processPacket(
return result;
}

auto EncryptedConnection::processRawPacket(
const rtc::Buffer &fullBuffer,
uint32_t packetSeq)
-> absl::optional<DecryptedRawPacket> {
assert(fullBuffer.size() >= 5);

auto additionalMessage = false;
auto firstMessageRequiringAck = true;
auto newRequiringAckReceived = false;

auto currentSeq = packetSeq;
auto currentCounter = CounterFromSeq(currentSeq);
rtc::ByteBufferReader reader(
reinterpret_cast<const char*>(fullBuffer.data() + 4), // Skip seq.
fullBuffer.size() - 4);

auto result = absl::optional<DecryptedRawPacket>();
while (true) {
const auto type = uint8_t(*reader.Data());
const auto singleMessagePacket = ((currentSeq & kSingleMessagePacketSeqBit) != 0);
if (singleMessagePacket && additionalMessage) {
return LogError("Single message packet bit in not first message.");
}

if (type == kEmptyId) {
if (additionalMessage) {
return LogError("Empty message should be only the first one in the packet.");
}
RTC_LOG(LS_INFO) << logHeader()
<< "Got RECV:empty" << "#" << currentCounter;
reader.Consume(1);
} else if (type == kAckId) {
if (!additionalMessage) {
return LogError("Ack message must not be the first one in the packet.");
}
ackMyMessage(currentSeq);
reader.Consume(1);
} else if (type == kCustomId) {
reader.Consume(1);

if (auto message = DeserializeRawMessage(reader, singleMessagePacket)) {
const auto messageRequiresAck = ((currentSeq & kMessageRequiresAckSeqBit) != 0);
const auto skipMessage = messageRequiresAck
? !registerSentAck(currentCounter, firstMessageRequiringAck)
: (additionalMessage && !registerIncomingCounter(currentCounter));
if (messageRequiresAck) {
firstMessageRequiringAck = false;
if (!skipMessage) {
newRequiringAckReceived = true;
}
sendAckPostponed(currentSeq);
RTC_LOG(LS_INFO) << logHeader()
<< (skipMessage ? "Repeated RECV:type" : "Got RECV:type") << type << "#" << currentCounter;
}
if (!skipMessage) {
appendReceivedRawMessage(result, std::move(*message), currentSeq);
}
} else {
return LogError("Could not parse message from packet, type: ", std::to_string(type));
}
} else {
return LogError("Could not parse message from packet, type: ", std::to_string(type));
}
if (!reader.Length()) {
break;
} else if (singleMessagePacket) {
return LogError("Single message didn't fill the entire packet.");
} else if (reader.Length() < 5) {
return LogError("Bad remaining data size: ", std::to_string(reader.Length()));
}
const auto success = reader.ReadUInt32(&currentSeq);
assert(success);
(void)success;
currentCounter = CounterFromSeq(currentSeq);

additionalMessage = true;
}

if (!_acksToSendSeqs.empty()) {
if (newRequiringAckReceived) {
_requestSendService(0, 0);
} else if (!_sendAcksTimerActive) {
_sendAcksTimerActive = true;
_requestSendService(
_delayIntervals.maxDelayBeforeAckResend,
kServiceCauseAcks);
}
}

return result;
}

void EncryptedConnection::appendReceivedMessage(
absl::optional<DecryptedPacket> &to,
Message &&message,
Expand All @@ -505,6 +668,21 @@ void EncryptedConnection::appendReceivedMessage(
}
}

void EncryptedConnection::appendReceivedRawMessage(
absl::optional<DecryptedRawPacket> &to,
rtc::CopyOnWriteBuffer &&message,
uint32_t incomingSeq) {
auto decrypted = DecryptedRawMessage{
std::move(message),
CounterFromSeq(incomingSeq)
};
if (to) {
to->additional.push_back(std::move(decrypted));
} else {
to = DecryptedRawPacket{ std::move(decrypted) };
}
}

const char *EncryptedConnection::logHeader() const {
return (_type == Type::Signaling) ? "(signaling) " : "(transport) ";
}
Expand Down
12 changes: 12 additions & 0 deletions TMessagesProj/jni/voip/tgcalls/EncryptedConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,19 @@ class EncryptedConnection final {
uint32_t counter = 0;
};
absl::optional<EncryptedPacket> prepareForSending(const Message &message);
absl::optional<EncryptedPacket> prepareForSendingRawMessage(rtc::CopyOnWriteBuffer &serialized, bool messageRequiresAck);
absl::optional<EncryptedPacket> prepareForSendingService(int cause);

struct DecryptedPacket {
DecryptedMessage main;
std::vector<DecryptedMessage> additional;
};
struct DecryptedRawPacket {
DecryptedRawMessage main;
std::vector<DecryptedRawMessage> additional;
};
absl::optional<DecryptedPacket> handleIncomingPacket(const char *bytes, size_t size);
absl::optional<DecryptedRawPacket> handleIncomingRawPacket(const char *bytes, size_t size);

absl::optional<rtc::CopyOnWriteBuffer> encryptRawPacket(rtc::CopyOnWriteBuffer const &buffer);
absl::optional<rtc::CopyOnWriteBuffer> decryptRawPacket(rtc::CopyOnWriteBuffer const &buffer);
Expand All @@ -57,6 +63,7 @@ class EncryptedConnection final {
EncryptedPacket encryptPrepared(const rtc::CopyOnWriteBuffer &buffer);
bool registerIncomingCounter(uint32_t incomingCounter);
absl::optional<DecryptedPacket> processPacket(const rtc::Buffer &fullBuffer, uint32_t packetSeq);
absl::optional<DecryptedRawPacket> processRawPacket(const rtc::Buffer &fullBuffer, uint32_t packetSeq);
bool registerSentAck(uint32_t counter, bool firstInPacket);
void ackMyMessage(uint32_t counter);
void sendAckPostponed(uint32_t incomingSeq);
Expand All @@ -66,6 +73,11 @@ class EncryptedConnection final {
absl::optional<DecryptedPacket> &to,
Message &&message,
uint32_t incomingSeq);
void appendReceivedRawMessage(
absl::optional<DecryptedRawPacket> &to,
rtc::CopyOnWriteBuffer &&message,
uint32_t incomingSeq);
absl::optional<EncryptedPacket> prepareForSendingMessageInternal(rtc::CopyOnWriteBuffer &serialized, uint32_t seq, bool messageRequiresAck);

const char *logHeader() const;

Expand Down
1 change: 1 addition & 0 deletions TMessagesProj/jni/voip/tgcalls/Instance.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ template <typename Implementation>
bool Register();

struct Descriptor {
std::string version;
Config config;
PersistentState persistentState;
std::vector<Endpoint> endpoints;
Expand Down
25 changes: 25 additions & 0 deletions TMessagesProj/jni/voip/tgcalls/Message.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -378,4 +378,29 @@ absl::optional<Message> DeserializeMessage(
: absl::nullopt;
}

absl::optional<rtc::CopyOnWriteBuffer> DeserializeRawMessage(
rtc::ByteBufferReader &reader,
bool singleMessagePacket) {
if (!reader.Length()) {
return absl::nullopt;
}

uint32_t length = 0;
if (!reader.ReadUInt32(&length)) {
return absl::nullopt;
}

if (length < 0 || length > 1024 * 1024) {
return absl::nullopt;
}

rtc::CopyOnWriteBuffer result;
result.SetSize(length);
if (!reader.ReadBytes((char *)result.MutableData(), result.size())) {
return absl::nullopt;
}

return result;
}

} // namespace tgcalls
16 changes: 13 additions & 3 deletions TMessagesProj/jni/voip/tgcalls/Message.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@ enum class AudioState;
struct PeerIceParameters {
std::string ufrag;
std::string pwd;
bool supportsRenomination = false;

PeerIceParameters() = default;
PeerIceParameters(const PeerIceParameters &other) = default;

PeerIceParameters(std::string ufrag_, std::string pwd_) :
PeerIceParameters(std::string ufrag_, std::string pwd_, bool supportsRenomination_) :
ufrag(ufrag_),
pwd(pwd_) {
pwd(pwd_),
supportsRenomination(supportsRenomination_) {
}

};
Expand Down Expand Up @@ -127,12 +128,21 @@ rtc::CopyOnWriteBuffer SerializeMessageWithSeq(
absl::optional<Message> DeserializeMessage(
rtc::ByteBufferReader &reader,
bool singleMessagePacket);
absl::optional<rtc::CopyOnWriteBuffer> DeserializeRawMessage(
rtc::ByteBufferReader &reader,
bool singleMessagePacket);

struct DecryptedMessage {
Message message;
uint32_t counter = 0;
};

struct DecryptedRawMessage {
rtc::CopyOnWriteBuffer message;
uint32_t counter = 0;
};


} // namespace tgcalls

#endif
4 changes: 2 additions & 2 deletions TMessagesProj/jni/voip/tgcalls/NetworkManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ _isOutgoing(encryptionKey.isOutgoing),
_stateUpdated(std::move(stateUpdated)),
_transportMessageReceived(std::move(transportMessageReceived)),
_sendSignalingMessage(std::move(sendSignalingMessage)),
_localIceParameters(rtc::CreateRandomString(cricket::ICE_UFRAG_LENGTH), rtc::CreateRandomString(cricket::ICE_PWD_LENGTH)) {
_localIceParameters(rtc::CreateRandomString(cricket::ICE_UFRAG_LENGTH), rtc::CreateRandomString(cricket::ICE_PWD_LENGTH), false) {
assert(_thread->IsCurrent());

_networkMonitorFactory = PlatformInterface::SharedInstance()->createNetworkMonitorFactory();
Expand Down Expand Up @@ -207,7 +207,7 @@ void NetworkManager::receiveSignalingMessage(DecryptedMessage &&message) {
assert(list != nullptr);

if (!_remoteIceParameters.has_value()) {
PeerIceParameters parameters(list->iceParameters.ufrag, list->iceParameters.pwd);
PeerIceParameters parameters(list->iceParameters.ufrag, list->iceParameters.pwd, false);
_remoteIceParameters = parameters;

cricket::IceParameters remoteIceParameters(
Expand Down
Loading

0 comments on commit 8309ac8

Please sign in to comment.