Move all gsl::byte helpers to base/bytes module.

This commit is contained in:
John Preston 2018-03-27 16:16:00 +04:00
parent b2014f403e
commit 1392e05ab1
33 changed files with 360 additions and 390 deletions

View File

@ -10,6 +10,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <openssl/bn.h>
#include <openssl/sha.h>
#include <openssl/rand.h>
#include <openssl/aes.h>
#include <openssl/crypto.h>
#include "base/bytes.h"
namespace openssl {
@ -61,7 +63,7 @@ public:
explicit BigNum(unsigned int word) : BigNum() {
setWord(word);
}
explicit BigNum(base::const_byte_span bytes) : BigNum() {
explicit BigNum(bytes::const_span bytes) : BigNum() {
setBytes(bytes);
}
@ -70,7 +72,7 @@ public:
_failed = true;
}
}
void setBytes(base::const_byte_span bytes) {
void setBytes(bytes::const_span bytes) {
if (!BN_bin2bn(
reinterpret_cast<const unsigned char*>(bytes.data()),
bytes.size(),
@ -162,12 +164,12 @@ public:
return failed() ? 0 : BN_num_bytes(raw());
}
base::byte_vector getBytes() const {
bytes::vector getBytes() const {
if (failed()) {
return base::byte_vector();
return {};
}
auto length = BN_num_bytes(raw());
auto result = base::byte_vector(length, gsl::byte());
auto result = bytes::vector(length);
auto resultSize = BN_bn2bin(
raw(),
reinterpret_cast<unsigned char*>(result.data()));
@ -207,44 +209,35 @@ inline BigNum operator-(const BigNum &a, const BigNum &b) {
return result;
}
inline base::byte_array<SHA512_DIGEST_LENGTH> Sha512(
base::const_byte_span bytes) {
auto result = base::byte_array<SHA512_DIGEST_LENGTH>();
inline bytes::vector Sha512(bytes::const_span data) {
auto result = bytes::vector(SHA512_DIGEST_LENGTH);
SHA512(
reinterpret_cast<const unsigned char*>(bytes.data()),
bytes.size(),
reinterpret_cast<const unsigned char*>(data.data()),
data.size(),
reinterpret_cast<unsigned char*>(result.data()));
return result;
}
inline base::byte_array<SHA256_DIGEST_LENGTH> Sha256(
base::const_byte_span bytes) {
auto result = base::byte_array<SHA256_DIGEST_LENGTH>();
inline bytes::vector Sha256(bytes::const_span data) {
auto result = bytes::vector(SHA256_DIGEST_LENGTH);
SHA256(
reinterpret_cast<const unsigned char*>(bytes.data()),
bytes.size(),
reinterpret_cast<const unsigned char*>(data.data()),
data.size(),
reinterpret_cast<unsigned char*>(result.data()));
return result;
}
inline base::byte_array<SHA_DIGEST_LENGTH> Sha1(
base::const_byte_span bytes) {
auto result = base::byte_array<SHA_DIGEST_LENGTH>();
inline bytes::vector Sha1(bytes::const_span data) {
auto result = bytes::vector(SHA_DIGEST_LENGTH);
SHA1(
reinterpret_cast<const unsigned char*>(bytes.data()),
bytes.size(),
reinterpret_cast<const unsigned char*>(data.data()),
data.size(),
reinterpret_cast<unsigned char*>(result.data()));
return result;
}
inline int FillRandom(base::byte_span bytes) {
return RAND_bytes(
reinterpret_cast<unsigned char*>(bytes.data()),
bytes.size());
}
inline void AddRandomSeed(base::const_byte_span bytes) {
RAND_seed(bytes.data(), bytes.size());
inline void AddRandomSeed(bytes::const_span data) {
RAND_seed(data.data(), data.size());
}
} // namespace openssl

View File

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "boxes/passcode_box.h"
#include "base/bytes.h"
#include "lang/lang_keys.h"
#include "boxes/confirm_box.h"
#include "mainwindow.h"
@ -329,7 +330,7 @@ void PasscodeBox::save(bool force) {
if (_oldPasscode->isHidden() || _newPasscode->isHidden()) {
flags |= MTPDaccount_passwordInputSettings::Flag::f_email;
}
const auto newSecureSecret = base::byte_vector();
const auto newSecureSecret = bytes::vector();
_setRequest = MTP::send(
MTPaccount_UpdatePasswordSettings(
MTP_bytes(oldPasswordHash),

View File

@ -62,8 +62,9 @@ void ConvertEndpoint(
}
constexpr auto kFingerprintDataSize = 256;
uint64 ComputeFingerprint(
const std::array<gsl::byte, kFingerprintDataSize> &authKey) {
uint64 ComputeFingerprint(bytes::const_span authKey) {
Expects(authKey.size() == kFingerprintDataSize);
auto hash = openssl::Sha1(authKey);
return (gsl::to_integer<uint64>(hash[19]) << 56)
| (gsl::to_integer<uint64>(hash[18]) << 48)
@ -133,7 +134,7 @@ Call::Call(
}
}
void Call::generateModExpFirst(base::const_byte_span randomSeed) {
void Call::generateModExpFirst(bytes::const_span randomSeed) {
auto first = MTP::CreateModExp(_dhConfig.g, _dhConfig.p, randomSeed);
if (first.modexp.empty()) {
LOG(("Call Error: Could not compute mod-exp first."));
@ -141,7 +142,7 @@ void Call::generateModExpFirst(base::const_byte_span randomSeed) {
return;
}
_randomPower = first.randomPower;
_randomPower = std::move(first.randomPower);
if (_type == Type::Incoming) {
_gb = std::move(first.modexp);
} else {
@ -157,7 +158,7 @@ bool Call::isIncomingWaiting() const {
return (_state == State::Starting) || (_state == State::WaitingIncoming);
}
void Call::start(base::const_byte_span random) {
void Call::start(bytes::const_span random) {
// Save config here, because it is possible that it changes between
// different usages inside the same call.
_dhConfig = _delegate->getDhConfig();
@ -312,7 +313,7 @@ void Call::redial() {
QString Call::getDebugLog() const {
constexpr auto kDebugLimit = 4096;
auto bytes = base::byte_vector(kDebugLimit, gsl::byte {});
auto bytes = bytes::vector(kDebugLimit, gsl::byte {});
_controller->GetDebugString(reinterpret_cast<char*>(bytes.data()), bytes.size());
auto end = std::find(bytes.begin(), bytes.end(), gsl::byte {});
auto size = (end - bytes.begin());
@ -342,12 +343,13 @@ bool Call::isKeyShaForFingerprintReady() const {
return (_keyFingerprint != 0);
}
base::byte_array<Call::kSha256Size> Call::getKeyShaForFingerprint() const {
bytes::vector Call::getKeyShaForFingerprint() const {
Expects(isKeyShaForFingerprintReady());
Expects(!_ga.empty());
auto encryptedChatAuthKey = base::byte_vector(_authKey.size() + _ga.size(), gsl::byte {});
base::copy_bytes(gsl::make_span(encryptedChatAuthKey).subspan(0, _authKey.size()), _authKey);
base::copy_bytes(gsl::make_span(encryptedChatAuthKey).subspan(_authKey.size(), _ga.size()), _ga);
auto encryptedChatAuthKey = bytes::vector(_authKey.size() + _ga.size(), gsl::byte {});
bytes::copy(gsl::make_span(encryptedChatAuthKey).subspan(0, _authKey.size()), _authKey);
bytes::copy(gsl::make_span(encryptedChatAuthKey).subspan(_authKey.size(), _ga.size()), _ga);
return openssl::Sha256(encryptedChatAuthKey);
}
@ -367,13 +369,13 @@ bool Call::handleUpdate(const MTPPhoneCall &call) {
}
_id = data.vid.v;
_accessHash = data.vaccess_hash.v;
auto gaHashBytes = bytesFromMTP(data.vg_a_hash);
auto gaHashBytes = bytes::make_span(data.vg_a_hash.v);
if (gaHashBytes.size() != _gaHash.size()) {
LOG(("Call Error: Wrong g_a_hash size %1, expected %2.").arg(gaHashBytes.size()).arg(_gaHash.size()));
finish(FinishType::Failed);
return true;
}
base::copy_bytes(gsl::make_span(_gaHash), gaHashBytes);
bytes::copy(_gaHash, gaHashBytes);
} return true;
case mtpc_phoneCallEmpty: {
@ -453,7 +455,7 @@ bool Call::handleUpdate(const MTPPhoneCall &call) {
void Call::confirmAcceptedCall(const MTPDphoneCallAccepted &call) {
Expects(_type == Type::Outgoing);
auto firstBytes = bytesFromMTP(call.vg_b);
auto firstBytes = bytes::make_span(call.vg_b.v);
auto computedAuthKey = MTP::CreateAuthKey(firstBytes, _randomPower, _dhConfig.p);
if (computedAuthKey.empty()) {
LOG(("Call Error: Could not compute mod-exp final."));
@ -493,13 +495,13 @@ void Call::confirmAcceptedCall(const MTPDphoneCallAccepted &call) {
void Call::startConfirmedCall(const MTPDphoneCall &call) {
Expects(_type == Type::Incoming);
auto firstBytes = bytesFromMTP(call.vg_a_or_b);
auto firstBytes = bytes::make_span(call.vg_a_or_b.v);
if (_gaHash != openssl::Sha256(firstBytes)) {
LOG(("Call Error: Wrong g_a hash received."));
finish(FinishType::Failed);
return;
}
_ga = base::byte_vector(firstBytes.begin(), firstBytes.end());
_ga = bytes::vector(firstBytes.begin(), firstBytes.end());
auto computedAuthKey = MTP::CreateAuthKey(firstBytes, _randomPower, _dhConfig.p);
if (computedAuthKey.empty()) {
@ -535,12 +537,12 @@ void Call::createAndStartController(const MTPDphoneCall &call) {
auto callLogFolder = cWorkingDir() + qsl("DebugLogs");
auto callLogPath = callLogFolder + qsl("/last_call_log.txt");
auto callLogNative = QFile::encodeName(QDir::toNativeSeparators(callLogPath));
auto callLogBytesSrc = gsl::as_bytes(gsl::make_span(callLogNative));
auto callLogBytesDst = gsl::as_writeable_bytes(gsl::make_span(config.logFilePath));
auto callLogBytesSrc = bytes::make_span(callLogNative);
auto callLogBytesDst = bytes::make_span(config.logFilePath);
if (callLogBytesSrc.size() + 1 <= callLogBytesDst.size()) { // +1 - zero-terminator
QFile(callLogPath).remove();
QDir().mkpath(callLogFolder);
base::copy_bytes(callLogBytesDst, callLogBytesSrc);
bytes::copy(callLogBytesDst, callLogBytesSrc);
}
}

View File

@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/weak_ptr.h"
#include "base/timer.h"
#include "base/bytes.h"
#include "mtproto/sender.h"
#include "mtproto/auth_key.h"
@ -27,7 +28,7 @@ namespace Calls {
struct DhConfig {
int32 version = 0;
int32 g = 0;
std::vector<gsl::byte> p;
bytes::vector p;
};
class Call : public base::has_weak_ptr, private MTP::Sender {
@ -48,8 +49,6 @@ public:
};
static constexpr auto kRandomPowerSize = 256;
static constexpr auto kSha256Size = 32;
static constexpr auto kSoundSampleMs = 100;
enum class Type {
@ -66,7 +65,7 @@ public:
}
bool isIncomingWaiting() const;
void start(base::const_byte_span random);
void start(bytes::const_span random);
bool handleUpdate(const MTPPhoneCall &call);
enum State {
@ -116,7 +115,7 @@ public:
void redial();
bool isKeyShaForFingerprintReady() const;
std::array<gsl::byte, kSha256Size> getKeyShaForFingerprint() const;
bytes::vector getKeyShaForFingerprint() const;
QString getDebugLog() const;
@ -152,7 +151,7 @@ private:
void startIncoming();
void startWaitingTrack();
void generateModExpFirst(base::const_byte_span randomSeed);
void generateModExpFirst(bytes::const_span randomSeed);
void handleControllerStateChange(
tgvoip::VoIPController *controller,
int state);
@ -191,10 +190,10 @@ private:
base::Observable<bool> _muteChanged;
DhConfig _dhConfig;
std::vector<gsl::byte> _ga;
std::vector<gsl::byte> _gb;
std::array<gsl::byte, kSha256Size> _gaHash;
std::array<gsl::byte, kRandomPowerSize> _randomPower;
bytes::vector _ga;
bytes::vector _gb;
bytes::vector _gaHash;
bytes::vector _randomPower;
MTP::AuthKey::Data _authKey;
MTPPhoneCallProtocol _protocol;

View File

@ -99,7 +99,7 @@ const ushort Offsets[] = {
620, 622, 624, 626, 628, 630, 632, 634, 636, 638, 640, 641,
642, 643, 644, 646, 648, 650, 652, 654, 656, 658 };
uint64 ComputeEmojiIndex(base::const_byte_span bytes) {
uint64 ComputeEmojiIndex(bytes::const_span bytes) {
Expects(bytes.size() == 8);
return ((gsl::to_integer<uint64>(bytes[0]) & 0x7F) << 56)
| (gsl::to_integer<uint64>(bytes[1]) << 48)

View File

@ -126,26 +126,26 @@ void Instance::refreshDhConfig() {
Expects(_currentCall != nullptr);
request(MTPmessages_GetDhConfig(
MTP_int(_dhConfig.version),
MTP_int(Call::kRandomPowerSize)
MTP_int(MTP::ModExpFirst::kRandomPowerSize)
)).done([this, call = base::make_weak(_currentCall)](
const MTPmessages_DhConfig &result) {
auto random = base::const_byte_span();
auto random = bytes::const_span();
switch (result.type()) {
case mtpc_messages_dhConfig: {
auto &config = result.c_messages_dhConfig();
if (!MTP::IsPrimeAndGood(bytesFromMTP(config.vp), config.vg.v)) {
if (!MTP::IsPrimeAndGood(bytes::make_span(config.vp.v), config.vg.v)) {
LOG(("API Error: bad p/g received in dhConfig."));
callFailed(call.get());
return;
}
_dhConfig.g = config.vg.v;
_dhConfig.p = byteVectorFromMTP(config.vp);
random = bytesFromMTP(config.vrandom);
_dhConfig.p = bytes::make_vector(config.vp.v);
random = bytes::make_span(config.vrandom.v);
} break;
case mtpc_messages_dhConfigNotModified: {
auto &config = result.c_messages_dhConfigNotModified();
random = bytesFromMTP(config.vrandom);
random = bytes::make_span(config.vrandom.v);
if (!_dhConfig.g || _dhConfig.p.empty()) {
LOG(("API Error: dhConfigNotModified on zero version."));
callFailed(call.get());
@ -156,7 +156,7 @@ void Instance::refreshDhConfig() {
default: Unexpected("Type in messages.getDhConfig");
}
if (random.size() != Call::kRandomPowerSize) {
if (random.size() != MTP::ModExpFirst::kRandomPowerSize) {
LOG(("API Error: dhConfig random bytes wrong size: %1").arg(random.size()));
callFailed(call.get());
return;
@ -186,7 +186,7 @@ void Instance::refreshServerConfig() {
_lastServerConfigUpdateTime = getms(true);
auto configUpdate = std::map<std::string, std::string>();
auto bytes = bytesFromMTP(result.c_dataJSON().vdata);
auto bytes = bytes::make_span(result.c_dataJSON().vdata.v);
auto error = QJsonParseError { 0, QJsonParseError::NoError };
auto document = QJsonDocument::fromJson(QByteArray::fromRawData(reinterpret_cast<const char*>(bytes.data()), bytes.size()), &error);
if (error.error != QJsonParseError::NoError) {

View File

@ -92,31 +92,6 @@ using set_of_unique_ptr = std::set<std::unique_ptr<T>, base::pointer_comparator<
template <typename T>
using set_of_shared_ptr = std::set<std::shared_ptr<T>, base::pointer_comparator<T>>;
using byte_span = gsl::span<gsl::byte>;
using const_byte_span = gsl::span<const gsl::byte>;
using byte_vector = std::vector<gsl::byte>;
template <size_t N>
using byte_array = std::array<gsl::byte, N>;
inline void copy_bytes(byte_span destination, const_byte_span source) {
Expects(destination.size() >= source.size());
memcpy(destination.data(), source.data(), source.size());
}
inline void move_bytes(byte_span destination, const_byte_span source) {
Expects(destination.size() >= source.size());
memmove(destination.data(), source.data(), source.size());
}
inline void set_bytes(byte_span destination, gsl::byte value) {
memset(destination.data(), gsl::to_integer<unsigned char>(value), destination.size());
}
inline int compare_bytes(const_byte_span a, const_byte_span b) {
auto aSize = a.size(), bSize = b.size();
return (aSize > bSize) ? 1 : (aSize < bSize) ? -1 : memcmp(a.data(), b.data(), aSize);
}
// Thanks https://stackoverflow.com/a/28139075
template <typename Container>

View File

@ -1393,7 +1393,7 @@ void DetachFromDevice() {
class FFMpegAttributesReader : public AbstractFFMpegLoader {
public:
FFMpegAttributesReader(const FileLocation &file, const QByteArray &data)
: AbstractFFMpegLoader(file, data, base::byte_vector()) {
: AbstractFFMpegLoader(file, data, bytes::vector()) {
}
bool open(TimeMs positionMs) override {
@ -1519,7 +1519,7 @@ FileMediaInformation::Song PrepareForSending(const QString &fname, const QByteAr
class FFMpegWaveformCounter : public FFMpegLoader {
public:
FFMpegWaveformCounter(const FileLocation &file, const QByteArray &data) : FFMpegLoader(file, data, base::byte_vector()) {
FFMpegWaveformCounter(const FileLocation &file, const QByteArray &data) : FFMpegLoader(file, data, bytes::vector()) {
}
bool open(TimeMs positionMs) override {
@ -1562,7 +1562,7 @@ public:
continue;
}
auto sampleBytes = gsl::as_bytes(gsl::make_span(buffer));
auto sampleBytes = bytes::make_span(buffer);
if (fmt == AL_FORMAT_MONO8 || fmt == AL_FORMAT_STEREO8) {
Media::Audio::IterateSamples<uchar>(sampleBytes, callback);
} else if (fmt == AL_FORMAT_MONO16 || fmt == AL_FORMAT_STEREO16) {

View File

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once
#include "storage/localimageloader.h"
#include "base/bytes.h"
struct VideoSoundData;
struct VideoSoundPart;
@ -332,7 +333,7 @@ FORCE_INLINE uint16 ReadOneSample(int16 data) {
}
template <typename SampleType, typename Callback>
void IterateSamples(base::const_byte_span bytes, Callback &&callback) {
void IterateSamples(bytes::const_span bytes, Callback &&callback) {
auto samplesPointer = reinterpret_cast<const SampleType*>(bytes.data());
auto samplesCount = bytes.size() / sizeof(SampleType);
auto samplesData = gsl::make_span(samplesPointer, samplesCount);

View File

@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "media/media_audio_ffmpeg_loader.h"
#include "base/bytes.h"
uint64_t AbstractFFMpegLoader::ComputeChannelLayout(
uint64_t channel_layout,
int channels) {
@ -183,8 +185,8 @@ int64_t AbstractFFMpegLoader::_seek_file(void *opaque, int64_t offset, int whenc
AbstractAudioFFMpegLoader::AbstractAudioFFMpegLoader(
const FileLocation &file,
const QByteArray &data,
base::byte_vector &&bytes)
: AbstractFFMpegLoader(file, data, std::move(bytes)) {
bytes::vector &&buffer)
: AbstractFFMpegLoader(file, data, std::move(buffer)) {
_frame = av_frame_alloc();
}
@ -490,8 +492,8 @@ AbstractAudioFFMpegLoader::~AbstractAudioFFMpegLoader() {
FFMpegLoader::FFMpegLoader(
const FileLocation &file,
const QByteArray &data,
base::byte_vector &&bytes)
: AbstractAudioFFMpegLoader(file, data, std::move(bytes)) {
bytes::vector &&buffer)
: AbstractAudioFFMpegLoader(file, data, std::move(buffer)) {
}
bool FFMpegLoader::open(TimeMs positionMs) {

View File

@ -24,8 +24,8 @@ public:
AbstractFFMpegLoader(
const FileLocation &file,
const QByteArray &data,
base::byte_vector &&bytes)
: AudioPlayerLoader(file, data, std::move(bytes)) {
bytes::vector &&buffer)
: AudioPlayerLoader(file, data, std::move(buffer)) {
}
bool open(TimeMs positionMs) override;
@ -73,7 +73,7 @@ public:
AbstractAudioFFMpegLoader(
const FileLocation &file,
const QByteArray &data,
base::byte_vector &&bytes);
bytes::vector &&buffer);
int64 samplesCount() override {
return _outputSamplesCount;
@ -141,7 +141,7 @@ public:
FFMpegLoader(
const FileLocation &file,
const QByteArray &data,
base::byte_vector &&bytes);
bytes::vector &&buffer);
bool open(TimeMs positionMs) override;

View File

@ -7,10 +7,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "media/media_audio_loader.h"
AudioPlayerLoader::AudioPlayerLoader(const FileLocation &file, const QByteArray &data, base::byte_vector &&bytes)
AudioPlayerLoader::AudioPlayerLoader(const FileLocation &file, const QByteArray &data, bytes::vector &&buffer)
: _file(file)
, _data(data)
, _bytes(std::move(bytes)) {
, _bytes(std::move(buffer)) {
}
AudioPlayerLoader::~AudioPlayerLoader() {

View File

@ -7,13 +7,18 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "base/bytes.h"
namespace FFMpeg {
struct AVPacketDataWrap;
} // namespace FFMpeg
class AudioPlayerLoader {
public:
AudioPlayerLoader(const FileLocation &file, const QByteArray &data, base::byte_vector &&bytes);
AudioPlayerLoader(
const FileLocation &file,
const QByteArray &data,
bytes::vector &&buffer);
virtual ~AudioPlayerLoader();
virtual bool check(const FileLocation &file, const QByteArray &data);
@ -43,7 +48,7 @@ protected:
FileLocation _file;
bool _access = false;
QByteArray _data;
base::byte_vector _bytes;
bytes::vector _bytes;
QFile _f;
int _dataPos = 0;

View File

@ -326,7 +326,7 @@ AudioPlayerLoader *Loaders::setupLoader(
}
*loader = std::make_unique<ChildFFMpegLoader>(std::move(track->videoData));
} else {
*loader = std::make_unique<FFMpegLoader>(track->file, track->data, base::byte_vector());
*loader = std::make_unique<FFMpegLoader>(track->file, track->data, bytes::vector());
}
l = loader->get();

View File

@ -49,7 +49,7 @@ void Track::samplePeakEach(TimeMs peakDuration) {
_peakDurationMs = peakDuration;
}
void Track::fillFromData(base::byte_vector &&data) {
void Track::fillFromData(bytes::vector &&data) {
FFMpegLoader loader(FileLocation(), QByteArray(), std::move(data));
auto position = qint64(0);
@ -81,7 +81,7 @@ void Track::fillFromData(base::byte_vector &&data) {
auto samplesAdded = int64(0);
auto result = loader.readMore(buffer, samplesAdded);
if (samplesAdded > 0) {
auto sampleBytes = gsl::as_bytes(gsl::make_span(buffer));
auto sampleBytes = bytes::make_span(buffer);
_samplesCount += samplesAdded;
_samples.insert(_samples.end(), sampleBytes.data(), sampleBytes.data() + sampleBytes.size());
if (peaksCount) {
@ -126,7 +126,7 @@ void Track::fillFromFile(const QString &filePath) {
if (f.open(QIODevice::ReadOnly)) {
auto size = f.size();
if (size > 0 && size <= kMaxFileSize) {
auto bytes = base::byte_vector(size);
auto bytes = bytes::vector(size);
if (f.read(reinterpret_cast<char*>(bytes.data()), bytes.size()) == bytes.size()) {
fillFromData(std::move(bytes));
} else {

View File

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once
#include "base/timer.h"
#include "base/bytes.h"
namespace Media {
namespace Audio {
@ -20,7 +21,7 @@ public:
void samplePeakEach(TimeMs peakDuration);
void fillFromData(base::byte_vector &&data);
void fillFromData(bytes::vector &&data);
void fillFromFile(const FileLocation &location);
void fillFromFile(const QString &filePath);
@ -66,7 +67,7 @@ private:
int64 _samplesCount = 0;
int32 _sampleRate = 0;
base::byte_vector _samples;
bytes::vector _samples;
TimeMs _peakDurationMs = 0;
int _peakEachPosition = 0;

View File

@ -38,7 +38,7 @@ ChildFFMpegLoader::ChildFFMpegLoader(std::unique_ptr<VideoSoundData> &&data)
: AbstractAudioFFMpegLoader(
FileLocation(),
QByteArray(),
base::byte_vector())
bytes::vector())
, _parentData(std::move(data)) {
}

View File

@ -60,15 +60,15 @@ public:
return other ? (_key == other->_key) : false;
}
static void FillData(Data &authKey, base::const_byte_span computedAuthKey) {
static void FillData(Data &authKey, bytes::const_span computedAuthKey) {
auto computedAuthKeySize = computedAuthKey.size();
Assert(computedAuthKeySize <= kSize);
auto authKeyBytes = gsl::make_span(authKey);
if (computedAuthKeySize < kSize) {
base::set_bytes(authKeyBytes.subspan(0, kSize - computedAuthKeySize), gsl::byte());
base::copy_bytes(authKeyBytes.subspan(kSize - computedAuthKeySize), computedAuthKey);
bytes::set_with_const(authKeyBytes.subspan(0, kSize - computedAuthKeySize), gsl::byte());
bytes::copy(authKeyBytes.subspan(kSize - computedAuthKeySize), computedAuthKey);
} else {
base::copy_bytes(authKeyBytes, computedAuthKey);
bytes::copy(authKeyBytes, computedAuthKey);
}
}

View File

@ -139,7 +139,7 @@ bool IsPrimeAndGoodCheck(const openssl::BigNum &prime, int g) {
return true;
}
bool IsPrimeAndGood(base::const_byte_span primeBytes, int g) {
bool IsPrimeAndGood(bytes::const_span primeBytes, int g) {
static constexpr unsigned char GoodPrime[] = {
0xC7, 0x1C, 0xAE, 0xB9, 0xC6, 0xB1, 0xC9, 0x04, 0x8E, 0x6C, 0x52, 0x2F, 0x70, 0xF1, 0x3F, 0x73,
0x98, 0x0D, 0x40, 0x23, 0x8E, 0x3E, 0x21, 0xC1, 0x49, 0x34, 0xD0, 0x37, 0x56, 0x3D, 0x93, 0x0F,
@ -158,7 +158,7 @@ bool IsPrimeAndGood(base::const_byte_span primeBytes, int g) {
0x0D, 0x81, 0x15, 0xF6, 0x35, 0xB1, 0x05, 0xEE, 0x2E, 0x4E, 0x15, 0xD0, 0x4B, 0x24, 0x54, 0xBF,
0x6F, 0x4F, 0xAD, 0xF0, 0x34, 0xB1, 0x04, 0x03, 0x11, 0x9C, 0xD8, 0xE3, 0xB9, 0x2F, 0xCC, 0x5B };
if (!base::compare_bytes(gsl::as_bytes(gsl::make_span(GoodPrime)), primeBytes)) {
if (!bytes::compare(bytes::make_span(GoodPrime), primeBytes)) {
if (g == 3 || g == 4 || g == 5 || g == 7) {
return true;
}
@ -167,31 +167,32 @@ bool IsPrimeAndGood(base::const_byte_span primeBytes, int g) {
return IsPrimeAndGoodCheck(openssl::BigNum(primeBytes), g);
}
std::vector<gsl::byte> CreateAuthKey(
base::const_byte_span firstBytes,
base::const_byte_span randomBytes,
base::const_byte_span primeBytes) {
bytes::vector CreateAuthKey(
bytes::const_span firstBytes,
bytes::const_span randomBytes,
bytes::const_span primeBytes) {
using openssl::BigNum;
BigNum first(firstBytes);
BigNum prime(primeBytes);
if (!IsGoodModExpFirst(first, prime)) {
LOG(("AuthKey Error: Bad first prime in CreateAuthKey()."));
return std::vector<gsl::byte>();
return {};
}
return BigNum::ModExp(first, BigNum(randomBytes), prime).getBytes();
}
ModExpFirst CreateModExp(
int g,
base::const_byte_span primeBytes,
base::const_byte_span randomSeed) {
bytes::const_span primeBytes,
bytes::const_span randomSeed) {
Expects(randomSeed.size() == ModExpFirst::kRandomPowerSize);
using namespace openssl;
BigNum prime(primeBytes);
ModExpFirst result;
auto result = ModExpFirst();
constexpr auto kMaxModExpFirstTries = 5;
result.randomPower.resize(ModExpFirst::kRandomPowerSize);
for (auto tries = 0; tries != kMaxModExpFirstTries; ++tries) {
bytes::set_random(result.randomPower);
for (auto i = 0; i != ModExpFirst::kRandomPowerSize; ++i) {
@ -2606,7 +2607,9 @@ void ConnectionPrivate::pqAnswered() {
sendRequestNotSecure(req_DH_params);
}
base::byte_vector ConnectionPrivate::encryptPQInnerRSA(const MTPP_Q_inner_data &data, const MTP::internal::RSAPublicKey &key) {
bytes::vector ConnectionPrivate::encryptPQInnerRSA(
const MTPP_Q_inner_data &data,
const MTP::internal::RSAPublicKey &key) {
auto p_q_inner_size = data.innerLength();
auto encSize = (p_q_inner_size >> 2) + 6;
if (encSize >= 65) {
@ -2615,7 +2618,7 @@ base::byte_vector ConnectionPrivate::encryptPQInnerRSA(const MTPP_Q_inner_data &
data.write(tmp);
LOG(("AuthKey Error: too large data for RSA encrypt, size %1").arg(encSize * sizeof(mtpPrime)));
DEBUG_LOG(("AuthKey Error: bad data for RSA encrypt %1").arg(Logs::mb(&tmp[0], tmp.size() * 4).str()));
return base::byte_vector(); // can't be 255-byte string
return {}; // can't be 255-byte string
}
auto encBuffer = mtpBuffer();
@ -2630,7 +2633,7 @@ base::byte_vector ConnectionPrivate::encryptPQInnerRSA(const MTPP_Q_inner_data &
memset_rand(&encBuffer[encSize], (65 - encSize) * sizeof(mtpPrime));
}
auto bytes = gsl::as_bytes(gsl::make_span(encBuffer));
auto bytes = bytes::make_span(encBuffer);
auto bytesToEncrypt = bytes.subspan(3, 256);
return key.encrypt(bytesToEncrypt);
}
@ -2710,14 +2713,15 @@ void ConnectionPrivate::dhParamsAnswered() {
unixtimeSet(dh_inner_data.vserver_time.v);
// check that dhPrime and (dhPrime - 1) / 2 are really prime
if (!IsPrimeAndGood(bytesFromMTP(dh_inner_data.vdh_prime), dh_inner_data.vg.v)) {
if (!IsPrimeAndGood(bytes::make_span(dh_inner_data.vdh_prime.v), dh_inner_data.vg.v)) {
LOG(("AuthKey Error: bad dh_prime primality!"));
return restart();
}
_authKeyStrings->dh_prime = byteVectorFromMTP(dh_inner_data.vdh_prime);
_authKeyStrings->dh_prime = bytes::make_vector(
dh_inner_data.vdh_prime.v);
_authKeyData->g = dh_inner_data.vg.v;
_authKeyStrings->g_a = byteVectorFromMTP(dh_inner_data.vg_a);
_authKeyStrings->g_a = bytes::make_vector(dh_inner_data.vg_a.v);
_authKeyData->retry_id = MTP_long(0);
_authKeyData->retries = 0;
} return dhClientParamsSend();
@ -2755,7 +2759,7 @@ void ConnectionPrivate::dhClientParamsSend() {
}
// gen rand 'b'
auto randomSeed = std::array<gsl::byte, ModExpFirst::kRandomPowerSize>();
auto randomSeed = bytes::vector(ModExpFirst::kRandomPowerSize);
bytes::set_random(randomSeed);
auto g_b_data = CreateModExp(_authKeyData->g, _authKeyStrings->dh_prime, randomSeed);
if (g_b_data.modexp.empty()) {
@ -2957,7 +2961,7 @@ void ConnectionPrivate::authKeyCreated() {
}
void ConnectionPrivate::clearAuthKeyData() {
auto zeroMemory = [](base::byte_span bytes) {
auto zeroMemory = [](bytes::span bytes) {
#ifdef Q_OS_WIN2
SecureZeroMemory(bytes.data(), bytes.size());
#else // Q_OS_WIN
@ -3227,15 +3231,15 @@ void ConnectionPrivate::stop() {
} // namespace internal
bool IsPrimeAndGood(base::const_byte_span primeBytes, int g) {
bool IsPrimeAndGood(bytes::const_span primeBytes, int g) {
return internal::IsPrimeAndGood(primeBytes, g);
}
ModExpFirst CreateModExp(int g, base::const_byte_span primeBytes, base::const_byte_span randomSeed) {
ModExpFirst CreateModExp(int g, bytes::const_span primeBytes, bytes::const_span randomSeed) {
return internal::CreateModExp(g, primeBytes, randomSeed);
}
std::vector<gsl::byte> CreateAuthKey(base::const_byte_span firstBytes, base::const_byte_span randomBytes, base::const_byte_span primeBytes) {
bytes::vector CreateAuthKey(bytes::const_span firstBytes, bytes::const_span randomBytes, bytes::const_span primeBytes) {
return internal::CreateAuthKey(firstBytes, randomBytes, primeBytes);
}

View File

@ -16,15 +16,15 @@ namespace MTP {
class Instance;
bool IsPrimeAndGood(base::const_byte_span primeBytes, int g);
bool IsPrimeAndGood(bytes::const_span primeBytes, int g);
struct ModExpFirst {
static constexpr auto kRandomPowerSize = 256;
std::vector<gsl::byte> modexp;
std::array<gsl::byte, kRandomPowerSize> randomPower;
bytes::vector modexp;
bytes::vector randomPower;
};
ModExpFirst CreateModExp(int g, base::const_byte_span primeBytes, base::const_byte_span randomSeed);
std::vector<gsl::byte> CreateAuthKey(base::const_byte_span firstBytes, base::const_byte_span randomBytes, base::const_byte_span primeBytes);
ModExpFirst CreateModExp(int g, bytes::const_span primeBytes, bytes::const_span randomSeed);
bytes::vector CreateAuthKey(bytes::const_span firstBytes, bytes::const_span randomBytes, bytes::const_span primeBytes);
namespace internal {
@ -190,7 +190,7 @@ private:
bool setState(int32 state, int32 ifState = Connection::UpdateAlways);
base::byte_vector encryptPQInnerRSA(const MTPP_Q_inner_data &data, const MTP::internal::RSAPublicKey &key);
bytes::vector encryptPQInnerRSA(const MTPP_Q_inner_data &data, const MTP::internal::RSAPublicKey &key);
std::string encryptClientDHInner(const MTPClient_DH_Inner_Data &data);
void appendTestConnection(
DcOptions::Variants::Protocol protocol,
@ -286,8 +286,8 @@ private:
uint32 msgs_sent = 0;
};
struct AuthKeyCreateStrings {
std::vector<gsl::byte> dh_prime;
std::vector<gsl::byte> g_a;
bytes::vector dh_prime;
bytes::vector g_a;
AuthKey::Data auth_key = { { gsl::byte{} } };
};
std::unique_ptr<AuthKeyCreateData> _authKeyData;

View File

@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/basic_types.h"
#include "base/flags.h"
#include "base/bytes.h"
namespace MTP {
@ -625,15 +626,13 @@ inline MTPbytes MTP_bytes(const QByteArray &v) {
inline MTPbytes MTP_bytes(QByteArray &&v) {
return MTPbytes(std::move(v));
}
inline MTPbytes MTP_bytes(base::const_byte_span bytes) {
return MTP_bytes(QByteArray(reinterpret_cast<const char*>(bytes.data()), bytes.size()));
inline MTPbytes MTP_bytes(bytes::const_span buffer) {
return MTP_bytes(QByteArray(
reinterpret_cast<const char*>(buffer.data()),
buffer.size()));
}
inline MTPbytes MTP_bytes(const std::vector<gsl::byte> &bytes) {
return MTP_bytes(gsl::make_span(bytes));
}
template <size_t N>
inline MTPbytes MTP_bytes(const std::array<gsl::byte, N> &bytes) {
return MTP_bytes(gsl::make_span(bytes));
inline MTPbytes MTP_bytes(const bytes::vector &buffer) {
return MTP_bytes(bytes::make_span(buffer));
}
inline bool operator==(const MTPstring &a, const MTPstring &b) {
@ -651,15 +650,6 @@ inline QByteArray qba(const MTPstring &v) {
return v.v;
}
inline base::const_byte_span bytesFromMTP(const MTPbytes &v) {
return gsl::as_bytes(gsl::make_span(v.v));
}
inline std::vector<gsl::byte> byteVectorFromMTP(const MTPbytes &v) {
auto bytes = bytesFromMTP(v);
return std::vector<gsl::byte>(bytes.cbegin(), bytes.cend());
}
template <typename T>
class MTPvector {
public:

View File

@ -89,8 +89,8 @@ private:
void DcOptions::readBuiltInPublicKeys() {
for (const auto key : PublicRSAKeys) {
const auto keyBytes = gsl::make_span(key, key + strlen(key));
auto parsed = internal::RSAPublicKey(gsl::as_bytes(keyBytes));
const auto keyBytes = bytes::make_span(key, strlen(key));
auto parsed = internal::RSAPublicKey(keyBytes);
if (parsed.isValid()) {
_publicKeys.emplace(parsed.getFingerPrint(), std::move(parsed));
} else {
@ -352,8 +352,8 @@ QByteArray DcOptions::serialize() const {
}
struct SerializedPublicKey {
DcId dcId;
base::byte_vector n;
base::byte_vector e;
bytes::vector n;
bytes::vector e;
};
std::vector<SerializedPublicKey> publicKeys;
publicKeys.reserve(count);
@ -485,7 +485,7 @@ void DcOptions::constructFromSerialized(const QByteArray &serialized) {
for (auto i = 0; i != count; ++i) {
qint32 dcId = 0;
base::byte_vector n, e;
bytes::vector n, e;
stream >> dcId >> Serialize::bytes(n) >> Serialize::bytes(e);
if (stream.status() != QDataStream::Ok) {
LOG(("MTP Error: Bad data for CDN config inside DcOptions::constructFromSerialized()"));
@ -540,8 +540,8 @@ void DcOptions::setCDNConfig(const MTPDcdnConfig &config) {
for_const (auto &publicKey, config.vpublic_keys.v) {
Expects(publicKey.type() == mtpc_cdnPublicKey);
const auto &keyData = publicKey.c_cdnPublicKey();
const auto keyBytes = gsl::make_span(keyData.vpublic_key.v);
auto key = internal::RSAPublicKey(gsl::as_bytes(keyBytes));
const auto keyBytes = bytes::make_span(keyData.vpublic_key.v);
auto key = internal::RSAPublicKey(keyBytes);
if (key.isValid()) {
_cdnPublicKeys[keyData.vdc_id.v].emplace(
key.getFingerPrint(),

View File

@ -59,7 +59,7 @@ enum class Format {
Unknown,
};
Format GuessFormat(base::const_byte_span key) {
Format GuessFormat(bytes::const_span key) {
const auto array = QByteArray::fromRawData(
reinterpret_cast<const char*>(key.data()),
key.size());
@ -71,7 +71,7 @@ Format GuessFormat(base::const_byte_span key) {
return Format::Unknown;
}
RSA *CreateRaw(base::const_byte_span key) {
RSA *CreateRaw(bytes::const_span key) {
const auto format = GuessFormat(key);
const auto bio = BIO_new_mem_buf(
const_cast<gsl::byte*>(key.data()),
@ -89,13 +89,13 @@ RSA *CreateRaw(base::const_byte_span key) {
class RSAPublicKey::Private {
public:
Private(base::const_byte_span key)
Private(bytes::const_span key)
: _rsa(CreateRaw(key)) {
if (_rsa) {
computeFingerprint();
}
}
Private(base::const_byte_span nBytes, base::const_byte_span eBytes)
Private(bytes::const_span nBytes, bytes::const_span eBytes)
: _rsa(RSA_new()) {
if (_rsa) {
auto n = openssl::BigNum(nBytes).takeRaw();
@ -110,14 +110,16 @@ public:
}
}
}
base::byte_vector getN() const {
bytes::vector getN() const {
Expects(isValid());
const BIGNUM *n;
RSA_get0_key(_rsa, &n, nullptr, nullptr);
return toBytes(n);
}
base::byte_vector getE() const {
bytes::vector getE() const {
Expects(isValid());
const BIGNUM *e;
RSA_get0_key(_rsa, nullptr, &e, nullptr);
return toBytes(e);
@ -128,37 +130,37 @@ public:
bool isValid() const {
return _rsa != nullptr;
}
base::byte_vector encrypt(base::const_byte_span data) const {
bytes::vector encrypt(bytes::const_span data) const {
Expects(isValid());
constexpr auto kEncryptSize = 256;
auto result = base::byte_vector(kEncryptSize, gsl::byte {});
auto result = bytes::vector(kEncryptSize, gsl::byte {});
auto res = RSA_public_encrypt(kEncryptSize, reinterpret_cast<const unsigned char*>(data.data()), reinterpret_cast<unsigned char*>(result.data()), _rsa, RSA_NO_PADDING);
if (res < 0 || res > kEncryptSize) {
ERR_load_crypto_strings();
LOG(("RSA Error: RSA_public_encrypt failed, key fp: %1, result: %2, error: %3").arg(getFingerPrint()).arg(res).arg(ERR_error_string(ERR_get_error(), 0)));
return base::byte_vector();
return {};
} else if (auto zeroBytes = kEncryptSize - res) {
auto resultBytes = gsl::make_span(result);
base::move_bytes(resultBytes.subspan(zeroBytes, res), resultBytes.subspan(0, res));
base::set_bytes(resultBytes.subspan(0, zeroBytes), gsl::byte {});
bytes::move(resultBytes.subspan(zeroBytes, res), resultBytes.subspan(0, res));
bytes::set_with_const(resultBytes.subspan(0, zeroBytes), gsl::byte {});
}
return result;
}
base::byte_vector decrypt(base::const_byte_span data) const {
bytes::vector decrypt(bytes::const_span data) const {
Expects(isValid());
constexpr auto kDecryptSize = 256;
auto result = base::byte_vector(kDecryptSize, gsl::byte {});
auto result = bytes::vector(kDecryptSize, gsl::byte {});
auto res = RSA_public_decrypt(kDecryptSize, reinterpret_cast<const unsigned char*>(data.data()), reinterpret_cast<unsigned char*>(result.data()), _rsa, RSA_NO_PADDING);
if (res < 0 || res > kDecryptSize) {
ERR_load_crypto_strings();
LOG(("RSA Error: RSA_public_encrypt failed, key fp: %1, result: %2, error: %3").arg(getFingerPrint()).arg(res).arg(ERR_error_string(ERR_get_error(), 0)));
return base::byte_vector();
return {};
} else if (auto zeroBytes = kDecryptSize - res) {
auto resultBytes = gsl::make_span(result);
base::move_bytes(resultBytes.subspan(zeroBytes - res, res), resultBytes.subspan(0, res));
base::set_bytes(resultBytes.subspan(0, zeroBytes - res), gsl::byte {});
bytes::move(resultBytes.subspan(zeroBytes - res, res), resultBytes.subspan(0, res));
bytes::set_with_const(resultBytes.subspan(0, zeroBytes - res), gsl::byte {});
}
return result;
}
@ -179,9 +181,9 @@ private:
uchar sha1Buffer[20];
_fingerprint = *(uint64*)(hashSha1(&string[0], string.size() * sizeof(mtpPrime), sha1Buffer) + 3);
}
static base::byte_vector toBytes(const BIGNUM *number) {
static bytes::vector toBytes(const BIGNUM *number) {
auto size = BN_num_bytes(number);
auto result = base::byte_vector(size, gsl::byte {});
auto result = bytes::vector(size, gsl::byte {});
BN_bn2bin(number, reinterpret_cast<unsigned char*>(result.data()));
return result;
}
@ -191,13 +193,13 @@ private:
};
RSAPublicKey::RSAPublicKey(base::const_byte_span key)
RSAPublicKey::RSAPublicKey(bytes::const_span key)
: _private(std::make_shared<Private>(key)) {
}
RSAPublicKey::RSAPublicKey(
base::const_byte_span nBytes,
base::const_byte_span eBytes)
bytes::const_span nBytes,
bytes::const_span eBytes)
: _private(std::make_shared<Private>(nBytes, eBytes)) {
}
@ -210,23 +212,27 @@ uint64 RSAPublicKey::getFingerPrint() const {
return _private->getFingerPrint();
}
base::byte_vector RSAPublicKey::getN() const {
bytes::vector RSAPublicKey::getN() const {
Expects(isValid());
return _private->getN();
}
base::byte_vector RSAPublicKey::getE() const {
bytes::vector RSAPublicKey::getE() const {
Expects(isValid());
return _private->getE();
}
base::byte_vector RSAPublicKey::encrypt(base::const_byte_span data) const {
bytes::vector RSAPublicKey::encrypt(bytes::const_span data) const {
Expects(isValid());
return _private->encrypt(data);
}
base::byte_vector RSAPublicKey::decrypt(base::const_byte_span data) const {
bytes::vector RSAPublicKey::decrypt(bytes::const_span data) const {
Expects(isValid());
return _private->decrypt(data);
}

View File

@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "base/bytes.h"
namespace MTP {
namespace internal {
@ -14,7 +16,7 @@ namespace internal {
class RSAPublicKey final {
public:
RSAPublicKey() = default;
RSAPublicKey(base::const_byte_span nBytes, base::const_byte_span eBytes);
RSAPublicKey(bytes::const_span nBytes, bytes::const_span eBytes);
RSAPublicKey(RSAPublicKey &&other) = default;
RSAPublicKey(const RSAPublicKey &other) = default;
RSAPublicKey &operator=(RSAPublicKey &&other) = default;
@ -22,18 +24,18 @@ public:
// key in "-----BEGIN RSA PUBLIC KEY----- ..." format
// or in "-----BEGIN PUBLIC KEY----- ..." format
explicit RSAPublicKey(base::const_byte_span key);
explicit RSAPublicKey(bytes::const_span key);
bool isValid() const;
uint64 getFingerPrint() const;
base::byte_vector getN() const;
base::byte_vector getE() const;
bytes::vector getN() const;
bytes::vector getE() const;
// data has exactly 256 chars to be encrypted
base::byte_vector encrypt(base::const_byte_span data) const;
bytes::vector encrypt(bytes::const_span data) const;
// data has exactly 256 chars to be decrypted
base::byte_vector decrypt(base::const_byte_span data) const;
bytes::vector decrypt(bytes::const_span data) const;
private:
class Private;

View File

@ -286,16 +286,13 @@ void Session::sendPong(quint64 msgId, quint64 pingId) {
}
void Session::sendMsgsStateInfo(quint64 msgId, QByteArray data) {
auto info = std::string();
auto info = bytes::vector();
if (!data.isEmpty()) {
info.resize(data.size());
auto src = gsl::as_bytes(gsl::make_span(data));
// auto dst = gsl::as_writeable_bytes(gsl::make_span(info));
auto dst = gsl::as_writeable_bytes(gsl::make_span(&info[0], info.size()));
base::copy_bytes(dst, src);
bytes::copy(info, bytes::make_span(data));
}
send(mtpRequestData::serialize(MTPMsgsStateInfo(
MTP_msgs_state_info(MTP_long(msgId), MTP_string(std::move(info))))));
MTP_msgs_state_info(MTP_long(msgId), MTP_bytes(data)))));
}
void Session::checkRequestsByTimer() {

View File

@ -276,33 +276,30 @@ bool SpecialConfigRequest::decryptSimpleConfig(const QByteArray &bytes) {
return false;
}
auto publicKey = internal::RSAPublicKey(gsl::as_bytes(gsl::make_span(
auto publicKey = internal::RSAPublicKey(bytes::make_span(
kPublicKey.c_str(),
kPublicKey.size())));
auto decrypted = publicKey.decrypt(gsl::as_bytes(gsl::make_span(decodedBytes)));
kPublicKey.size()));
auto decrypted = publicKey.decrypt(bytes::make_span(decodedBytes));
auto decryptedBytes = gsl::make_span(decrypted);
constexpr auto kAesKeySize = CTRState::KeySize;
constexpr auto kAesIvecSize = CTRState::IvecSize;
auto aesEncryptedBytes = decryptedBytes.subspan(kAesKeySize);
base::byte_array<kAesIvecSize> aesivec;
base::copy_bytes(aesivec, decryptedBytes.subspan(CTRState::KeySize - CTRState::IvecSize, CTRState::IvecSize));
auto aesEncryptedBytes = decryptedBytes.subspan(CTRState::KeySize);
auto aesivec = bytes::make_vector(decryptedBytes.subspan(CTRState::KeySize - CTRState::IvecSize, CTRState::IvecSize));
AES_KEY aeskey;
AES_set_decrypt_key(reinterpret_cast<const unsigned char*>(decryptedBytes.data()), kAesKeySize * CHAR_BIT, &aeskey);
AES_set_decrypt_key(reinterpret_cast<const unsigned char*>(decryptedBytes.data()), CTRState::KeySize * CHAR_BIT, &aeskey);
AES_cbc_encrypt(reinterpret_cast<const unsigned char*>(aesEncryptedBytes.data()), reinterpret_cast<unsigned char*>(aesEncryptedBytes.data()), aesEncryptedBytes.size(), &aeskey, reinterpret_cast<unsigned char*>(aesivec.data()), AES_DECRYPT);
constexpr auto kDigestSize = 16;
auto dataSize = aesEncryptedBytes.size() - kDigestSize;
auto data = aesEncryptedBytes.subspan(0, dataSize);
auto hash = openssl::Sha256(data);
if (base::compare_bytes(gsl::make_span(hash).subspan(0, kDigestSize), aesEncryptedBytes.subspan(dataSize)) != 0) {
if (bytes::compare(gsl::make_span(hash).subspan(0, kDigestSize), aesEncryptedBytes.subspan(dataSize)) != 0) {
LOG(("Config Error: Bad digest."));
return false;
}
mtpBuffer buffer;
buffer.resize(data.size() / sizeof(mtpPrime));
base::copy_bytes(gsl::as_writeable_bytes(gsl::make_span(buffer)), data);
bytes::copy(bytes::make_span(buffer), data);
auto from = &*buffer.cbegin();
auto end = from + buffer.size();
auto realLength = *from++;

View File

@ -9,9 +9,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/openssl_help.h"
#include <openssl/aes.h>
#include <openssl/crypto.h>
namespace Passport {
namespace {
@ -25,27 +22,27 @@ constexpr auto kAlignTo = 16;
} // namespace
struct AesParams {
base::byte_array<kAesKeyLength> key;
base::byte_array<kAesIvLength> iv;
bytes::vector key;
bytes::vector iv;
};
AesParams PrepareAesParams(base::const_byte_span secretHash) {
AesParams PrepareAesParams(bytes::const_span secretHash) {
const auto hash = openssl::Sha512(secretHash);
const auto view = gsl::make_span(hash);
const auto key = view.subspan(0, kAesKeyLength);
const auto iv = view.subspan(kAesKeyLength, kAesIvLength);
auto result = AesParams();
base::copy_bytes(result.key, view.subspan(0, kAesKeyLength));
base::copy_bytes(result.iv, view.subspan(kAesKeyLength, kAesIvLength));
result.key = bytes::make_vector(view.subspan(0, kAesKeyLength));
result.iv = bytes::make_vector(view.subspan(kAesKeyLength, kAesIvLength));
return result;
}
base::byte_vector EncryptOrDecrypt(
base::const_byte_span initial,
bytes::vector EncryptOrDecrypt(
bytes::const_span initial,
AesParams &&params,
int encryptOrDecrypt) {
Expects((initial.size() & 0x0F) == 0);
Expects(params.key.size() == kAesKeyLength);
Expects(params.iv.size() == kAesIvLength);
auto aesKey = AES_KEY();
const auto error = (encryptOrDecrypt == AES_ENCRYPT)
@ -62,7 +59,7 @@ base::byte_vector EncryptOrDecrypt(
).arg(error));
return {};
}
auto result = base::byte_vector(initial.size());
auto result = bytes::vector(initial.size());
AES_cbc_encrypt(
reinterpret_cast<const uchar*>(initial.data()),
reinterpret_cast<uchar*>(result.data()),
@ -73,27 +70,27 @@ base::byte_vector EncryptOrDecrypt(
return result;
}
base::byte_vector Encrypt(
base::const_byte_span decrypted,
bytes::vector Encrypt(
bytes::const_span decrypted,
AesParams &&params) {
return EncryptOrDecrypt(decrypted, std::move(params), AES_ENCRYPT);
}
base::byte_vector Decrypt(
base::const_byte_span encrypted,
bytes::vector Decrypt(
bytes::const_span encrypted,
AesParams &&params) {
return EncryptOrDecrypt(encrypted, std::move(params), AES_DECRYPT);
}
base::byte_vector PasswordHashForSecret(
base::const_byte_span passwordUtf8) {
bytes::vector PasswordHashForSecret(
bytes::const_span passwordUtf8) {
//new_secure_salt = new_salt + random_bytes(8) // #TODO
//password_hash = SHA512(new_secure_salt + password + new_secure_salt)
const auto result = openssl::Sha512(passwordUtf8);
return { result.begin(), result.end() };
}
bool CheckBytesMod255(base::const_byte_span bytes) {
bool CheckBytesMod255(bytes::const_span bytes) {
const auto full = ranges::accumulate(
bytes,
0ULL,
@ -102,12 +99,12 @@ bool CheckBytesMod255(base::const_byte_span bytes) {
return (mod == 239);
}
bool CheckSecretBytes(base::const_byte_span secret) {
bool CheckSecretBytes(bytes::const_span secret) {
return CheckBytesMod255(secret);
}
base::byte_vector GenerateSecretBytes() {
auto result = base::byte_vector(kSecretSize);
bytes::vector GenerateSecretBytes() {
auto result = bytes::vector(kSecretSize);
memset_rand(result.data(), result.size());
const auto full = ranges::accumulate(
result,
@ -120,9 +117,9 @@ base::byte_vector GenerateSecretBytes() {
return result;
}
base::byte_vector DecryptSecretBytes(
base::const_byte_span encryptedSecret,
base::const_byte_span passwordHashForSecret) {
bytes::vector DecryptSecretBytes(
bytes::const_span encryptedSecret,
bytes::const_span passwordHashForSecret) {
if (encryptedSecret.empty()) {
return {};
} else if (encryptedSecret.size() != kSecretSize) {
@ -139,9 +136,9 @@ base::byte_vector DecryptSecretBytes(
return result;
}
base::byte_vector EncryptSecretBytes(
base::const_byte_span secret,
base::const_byte_span passwordHashForSecret) {
bytes::vector EncryptSecretBytes(
bytes::const_span secret,
bytes::const_span passwordHashForSecret) {
Expects(secret.size() == kSecretSize);
Expects(CheckSecretBytes(secret) == true);
@ -149,27 +146,26 @@ base::byte_vector EncryptSecretBytes(
return Encrypt(secret, std::move(params));
}
base::byte_vector Concatenate(
base::const_byte_span a,
base::const_byte_span b) {
auto result = base::byte_vector(a.size() + b.size());
base::copy_bytes(result, a);
base::copy_bytes(gsl::make_span(result).subspan(a.size()), b);
bytes::vector Concatenate(
bytes::const_span a,
bytes::const_span b) {
auto result = bytes::vector(a.size() + b.size());
bytes::copy(result, a);
bytes::copy(gsl::make_span(result).subspan(a.size()), b);
return result;
}
base::byte_vector SerializeData(const std::map<QString, QString> &data) {
bytes::vector SerializeData(const std::map<QString, QString> &data) {
auto root = QJsonObject();
for (const auto &[key, value] : data) {
root.insert(key, value);
}
auto document = QJsonDocument(root);
const auto result = document.toJson(QJsonDocument::Compact);
const auto bytes = gsl::as_bytes(gsl::make_span(result));
return { bytes.begin(), bytes.end() };
return bytes::make_vector(result);
}
std::map<QString, QString> DeserializeData(base::const_byte_span bytes) {
std::map<QString, QString> DeserializeData(bytes::const_span bytes) {
const auto serialized = QByteArray::fromRawData(
reinterpret_cast<const char*>(bytes.data()),
bytes.size());
@ -226,13 +222,13 @@ std::map<QString, QString> DeserializeData(base::const_byte_span bytes) {
return result;
}
EncryptedData EncryptData(base::const_byte_span bytes) {
EncryptedData EncryptData(bytes::const_span bytes) {
return EncryptData(bytes, GenerateSecretBytes());
}
EncryptedData EncryptData(
base::const_byte_span bytes,
base::const_byte_span dataSecret) {
bytes::const_span bytes,
bytes::const_span dataSecret) {
constexpr auto kFromPadding = kMinPadding + kAlignTo - 1;
constexpr auto kPaddingDelta = kMaxPadding - kFromPadding;
const auto randomPadding = kFromPadding
@ -241,12 +237,12 @@ EncryptedData EncryptData(
- ((bytes.size() + randomPadding) % kAlignTo);
Assert(padding >= kMinPadding && padding <= kMaxPadding);
auto unencrypted = base::byte_vector(padding + bytes.size());
auto unencrypted = bytes::vector(padding + bytes.size());
Assert(unencrypted.size() % kAlignTo == 0);
unencrypted[0] = static_cast<gsl::byte>(padding);
memset_rand(unencrypted.data() + 1, padding - 1);
base::copy_bytes(
bytes::copy(
gsl::make_span(unencrypted).subspan(padding),
bytes);
const auto dataHash = openssl::Sha256(unencrypted);
@ -261,10 +257,10 @@ EncryptedData EncryptData(
};
}
base::byte_vector DecryptData(
base::const_byte_span encrypted,
base::const_byte_span dataHash,
base::const_byte_span dataSecret) {
bytes::vector DecryptData(
bytes::const_span encrypted,
bytes::const_span dataHash,
bytes::const_span dataSecret) {
constexpr auto kDataHashSize = 32;
if (encrypted.empty()) {
return {};
@ -280,7 +276,7 @@ base::byte_vector DecryptData(
Concatenate(dataSecret, dataHash));
auto params = PrepareAesParams(dataSecretHash);
const auto decrypted = Decrypt(encrypted, std::move(params));
if (base::compare_bytes(openssl::Sha256(decrypted), dataHash) != 0) {
if (bytes::compare(openssl::Sha256(decrypted), dataHash) != 0) {
LOG(("API Error: Bad data hash."));
return {};
}
@ -295,17 +291,17 @@ base::byte_vector DecryptData(
return { bytes.begin(), bytes.end() };
}
base::byte_vector PrepareValueHash(
base::const_byte_span dataHash,
base::const_byte_span valueSecret) {
bytes::vector PrepareValueHash(
bytes::const_span dataHash,
bytes::const_span valueSecret) {
const auto result = openssl::Sha256(Concatenate(dataHash, valueSecret));
return { result.begin(), result.end() };
}
base::byte_vector PrepareFilesHash(
gsl::span<base::const_byte_span> fileHashes,
base::const_byte_span valueSecret) {
auto resultInner = base::byte_vector{
bytes::vector PrepareFilesHash(
gsl::span<bytes::const_span> fileHashes,
bytes::const_span valueSecret) {
auto resultInner = bytes::vector{
valueSecret.begin(),
valueSecret.end()
};
@ -316,19 +312,19 @@ base::byte_vector PrepareFilesHash(
return { result.begin(), result.end() };
}
base::byte_vector EncryptValueSecret(
base::const_byte_span valueSecret,
base::const_byte_span secret,
base::const_byte_span valueHash) {
bytes::vector EncryptValueSecret(
bytes::const_span valueSecret,
bytes::const_span secret,
bytes::const_span valueHash) {
const auto valueSecretHash = openssl::Sha512(
Concatenate(secret, valueHash));
return EncryptSecretBytes(valueSecret, valueSecretHash);
}
base::byte_vector DecryptValueSecret(
base::const_byte_span encrypted,
base::const_byte_span secret,
base::const_byte_span valueHash) {
bytes::vector DecryptValueSecret(
bytes::const_span encrypted,
bytes::const_span secret,
bytes::const_span valueHash) {
const auto valueSecretHash = openssl::Sha512(
Concatenate(secret, valueHash));
return DecryptSecretBytes(encrypted, valueSecretHash);

View File

@ -9,53 +9,53 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Passport {
base::byte_vector GenerateSecretBytes();
bytes::vector GenerateSecretBytes();
base::byte_vector EncryptSecretBytes(
base::const_byte_span secret,
base::const_byte_span passwordHashForSecret);
base::byte_vector DecryptSecretBytes(
base::const_byte_span encryptedSecret,
base::const_byte_span passwordHashForSecret);
bytes::vector EncryptSecretBytes(
bytes::const_span secret,
bytes::const_span passwordHashForSecret);
bytes::vector DecryptSecretBytes(
bytes::const_span encryptedSecret,
bytes::const_span passwordHashForSecret);
base::byte_vector PasswordHashForSecret(base::const_byte_span passwordUtf8);
bytes::vector PasswordHashForSecret(bytes::const_span passwordUtf8);
base::byte_vector SerializeData(const std::map<QString, QString> &data);
std::map<QString, QString> DeserializeData(base::const_byte_span bytes);
bytes::vector SerializeData(const std::map<QString, QString> &data);
std::map<QString, QString> DeserializeData(bytes::const_span bytes);
struct EncryptedData {
base::byte_vector secret;
base::byte_vector hash;
base::byte_vector bytes;
bytes::vector secret;
bytes::vector hash;
bytes::vector bytes;
};
EncryptedData EncryptData(base::const_byte_span bytes);
EncryptedData EncryptData(bytes::const_span bytes);
EncryptedData EncryptData(
base::const_byte_span bytes,
base::const_byte_span dataSecret);
bytes::const_span bytes,
bytes::const_span dataSecret);
base::byte_vector DecryptData(
base::const_byte_span encrypted,
base::const_byte_span dataHash,
base::const_byte_span dataSecret);
bytes::vector DecryptData(
bytes::const_span encrypted,
bytes::const_span dataHash,
bytes::const_span dataSecret);
base::byte_vector PrepareValueHash(
base::const_byte_span dataHash,
base::const_byte_span valueSecret);
bytes::vector PrepareValueHash(
bytes::const_span dataHash,
bytes::const_span valueSecret);
base::byte_vector EncryptValueSecret(
base::const_byte_span valueSecret,
base::const_byte_span secret,
base::const_byte_span valueHash);
bytes::vector EncryptValueSecret(
bytes::const_span valueSecret,
bytes::const_span secret,
bytes::const_span valueHash);
base::byte_vector DecryptValueSecret(
base::const_byte_span encrypted,
base::const_byte_span secret,
base::const_byte_span valueHash);
bytes::vector DecryptValueSecret(
bytes::const_span encrypted,
bytes::const_span secret,
bytes::const_span valueHash);
base::byte_vector PrepareFilesHash(
gsl::span<base::const_byte_span> fileHashes,
base::const_byte_span valueSecret);
bytes::vector PrepareFilesHash(
gsl::span<bytes::const_span> fileHashes,
bytes::const_span valueSecret);
} // namespace Passport

View File

@ -49,12 +49,13 @@ FormController::Field::Field(Type type) : type(type) {
}
template <typename FileHashes>
base::byte_vector FormController::computeFilesHash(
bytes::vector FormController::computeFilesHash(
FileHashes fileHashes,
base::const_byte_span valueSecret) {
auto hashesVector = std::vector<base::const_byte_span>();
bytes::const_span valueSecret) {
auto vec = bytes::concatenate(fileHashes);
auto hashesVector = std::vector<bytes::const_span>();
for (const auto &hash : fileHashes) {
hashesVector.push_back(gsl::as_bytes(gsl::make_span(hash)));
hashesVector.push_back(bytes::make_span(hash));
}
return PrepareFilesHash(hashesVector, valueSecret);
}
@ -82,9 +83,10 @@ void FormController::submitPassword(const QString &password) {
_passwordError.fire(QString());
}
const auto passwordBytes = password.toUtf8();
const auto data = _password.salt + passwordBytes + _password.salt;
const auto hash = openssl::Sha256(gsl::as_bytes(gsl::make_span(data)));
_passwordHashForAuth = { hash.begin(), hash.end() };
_passwordHashForAuth = openssl::Sha256(bytes::concatenate(
bytes::make_span(_password.salt),
bytes::make_span(passwordBytes),
bytes::make_span(_password.salt)));
_passwordCheckRequestId = request(MTPaccount_GetPasswordSettings(
MTP_bytes(_passwordHashForAuth)
)).handleFloodErrors(
@ -94,17 +96,16 @@ void FormController::submitPassword(const QString &password) {
_passwordCheckRequestId = 0;
const auto &data = result.c_account_passwordSettings();
_passwordEmail = qs(data.vemail);
const auto hash = openssl::Sha512(gsl::as_bytes(gsl::make_span(passwordBytes)));
_passwordHashForSecret = { hash.begin(), hash.end() };
_passwordHashForSecret = openssl::Sha512(bytes::make_span(passwordBytes));
_secret = DecryptSecretBytes(
bytesFromMTP(data.vsecure_secret),
bytes::make_span(data.vsecure_secret.v),
_passwordHashForSecret);
for (auto &field : _form.fields) {
field.data.values = fillData(field.data);
if (auto &document = field.document) {
const auto filesHash = gsl::as_bytes(gsl::make_span(document->filesHash));
const auto filesHash = bytes::make_span(document->filesHash);
document->filesSecret = DecryptValueSecret(
gsl::as_bytes(gsl::make_span(document->filesSecretEncrypted)),
bytes::make_span(document->filesSecretEncrypted),
_secret,
filesHash);
if (document->filesSecret.empty()
@ -154,7 +155,7 @@ void FormController::uploadScan(int index, QByteArray &&content) {
filesSecret = document.filesSecret
] {
auto data = EncryptData(
gsl::as_bytes(gsl::make_span(bytes)),
bytes::make_span(bytes),
filesSecret);
auto result = UploadedScan();
result.fileId = rand_value<uint64>();
@ -350,7 +351,7 @@ void FormController::loadFiles(const std::vector<File> &files) {
void FormController::fileLoaded(FileKey key, const QByteArray &bytes) {
if (const auto [field, file] = findFile(key); file != nullptr) {
const auto decrypted = DecryptData(
gsl::as_bytes(gsl::make_span(bytes)),
bytes::make_span(bytes),
file->fileHash,
field->document->filesSecret);
auto image = App::readImage(QByteArray::fromRawData(
@ -413,13 +414,13 @@ std::map<QString, QString> FormController::fillData(
if (from.dataEncrypted.isEmpty()) {
return {};
}
const auto valueHash = gsl::as_bytes(gsl::make_span(from.dataHash));
const auto valueHash = bytes::make_span(from.dataHash);
const auto valueSecret = DecryptValueSecret(
gsl::as_bytes(gsl::make_span(from.dataSecretEncrypted)),
bytes::make_span(from.dataSecretEncrypted),
_secret,
valueHash);
return DeserializeData(DecryptData(
gsl::as_bytes(gsl::make_span(from.dataEncrypted)),
bytes::make_span(from.dataEncrypted),
valueHash,
valueSecret));
}
@ -490,7 +491,7 @@ void FormController::saveFiles(int index) {
ranges::view::all(
document.filesInEdit
) | ranges::view::transform([=](const EditFile &file) {
return gsl::as_bytes(gsl::make_span(file.fields.fileHash));
return bytes::make_span(file.fields.fileHash);
}),
document.filesSecret);
@ -714,7 +715,7 @@ auto FormController::convertValue(
if (normal.fileHash.size() != 32) {
normal.fileHash.clear();
}
// normal.fileHash = byteVectorFromMTP(fields.vfile_hash);
// normal.fileHash = bytes::make_vector(fields.vfile_hash.v);
result.files.push_back(std::move(normal));
} break;
}
@ -837,8 +838,7 @@ void FormController::passwordFail(const RPCError &error) {
void FormController::parsePassword(const MTPDaccount_noPassword &result) {
_password.unconfirmedPattern = qs(result.vemail_unconfirmed_pattern);
_password.newSalt = result.vnew_salt.v;
openssl::AddRandomSeed(
gsl::as_bytes(gsl::make_span(result.vsecret_random.v)));
openssl::AddRandomSeed(bytes::make_span(result.vsecret_random.v));
}
void FormController::parsePassword(const MTPDaccount_password &result) {
@ -847,8 +847,7 @@ void FormController::parsePassword(const MTPDaccount_password &result) {
_password.salt = result.vcurrent_salt.v;
_password.unconfirmedPattern = qs(result.vemail_unconfirmed_pattern);
_password.newSalt = result.vnew_salt.v;
openssl::AddRandomSeed(
gsl::as_bytes(gsl::make_span(result.vsecret_random.v)));
openssl::AddRandomSeed(bytes::make_span(result.vsecret_random.v));
}
FormController::~FormController() = default;

View File

@ -109,16 +109,16 @@ private:
uint64 fileId = 0;
int partsCount = 0;
QByteArray md5checksum;
base::byte_vector hash;
base::byte_vector bytes;
bytes::vector hash;
bytes::vector bytes;
};
struct File {
uint64 id = 0;
uint64 accessHash = 0;
int32 size = 0;
int32 dcId = 0;
base::byte_vector fileHash;
base::byte_vector bytes;
bytes::vector fileHash;
bytes::vector bytes;
};
struct EditFile {
EditFile(
@ -142,7 +142,7 @@ private:
std::vector<File> files;
QByteArray filesHash;
QByteArray filesSecretEncrypted;
base::byte_vector filesSecret;
bytes::vector filesSecret;
std::vector<EditFile> filesInEdit;
};
@ -199,9 +199,9 @@ private:
void generateSecret(base::lambda<void()> callback);
template <typename FileHashes>
base::byte_vector computeFilesHash(
bytes::vector computeFilesHash(
FileHashes fileHashes,
base::const_byte_span valueHash);
bytes::const_span valueHash);
void subscribeToUploader();
void uploadEncryptedScan(int index, UploadedScan &&data);
@ -221,9 +221,9 @@ private:
std::map<FileKey, std::unique_ptr<mtpFileLoader>> _fileLoaders;
rpl::event_stream<ScanInfo> _scanUpdated;
base::byte_vector _passwordHashForSecret;
base::byte_vector _passwordHashForAuth;
base::byte_vector _secret;
bytes::vector _passwordHashForSecret;
bytes::vector _passwordHashForAuth;
bytes::vector _secret;
std::vector<base::lambda<void()>> _secretCallbacks;
mtpRequestId _saveSecretRequestId = 0;
QString _passwordEmail;

View File

@ -15,6 +15,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "platform/platform_file_utilities.h"
#include "auth_session.h"
#include "core/crash_reports.h"
#include "base/bytes.h"
#include "base/openssl_help.h"
namespace Storage {
@ -530,8 +532,8 @@ void mtpFileLoader::normalPartLoaded(const MTPupload_File &result, mtpRequestId
if (result.type() == mtpc_upload_fileCdnRedirect) {
return switchToCDN(offset, result.c_upload_fileCdnRedirect());
}
auto bytes = gsl::as_bytes(gsl::make_span(result.c_upload_file().vbytes.v));
return partLoaded(offset, bytes);
auto buffer = bytes::make_span(result.c_upload_file().vbytes.v);
return partLoaded(offset, buffer);
}
void mtpFileLoader::webPartLoaded(const MTPupload_WebFile &result, mtpRequestId requestId) {
@ -545,8 +547,8 @@ void mtpFileLoader::webPartLoaded(const MTPupload_WebFile &result, mtpRequestId
LOG(("MTP Error: Bad size provided by bot for webDocument: %1, real: %2").arg(_size).arg(webFile.vsize.v));
return cancel(true);
}
auto bytes = gsl::as_bytes(gsl::make_span(webFile.vbytes.v));
return partLoaded(offset, bytes);
auto buffer = bytes::make_span(webFile.vbytes.v);
return partLoaded(offset, buffer);
}
void mtpFileLoader::cdnPartLoaded(const MTPupload_CdnFile &result, mtpRequestId requestId) {
@ -565,13 +567,13 @@ void mtpFileLoader::cdnPartLoaded(const MTPupload_CdnFile &result, mtpRequestId
}
Expects(result.type() == mtpc_upload_cdnFile);
auto key = gsl::as_bytes(gsl::make_span(_cdnEncryptionKey));
auto iv = gsl::as_bytes(gsl::make_span(_cdnEncryptionIV));
auto key = bytes::make_span(_cdnEncryptionKey);
auto iv = bytes::make_span(_cdnEncryptionIV);
Expects(key.size() == MTP::CTRState::KeySize);
Expects(iv.size() == MTP::CTRState::IvecSize);
auto state = MTP::CTRState();
auto ivec = gsl::as_writeable_bytes(gsl::make_span(state.ivec));
auto ivec = bytes::make_span(state.ivec);
std::copy(iv.begin(), iv.end(), ivec.begin());
auto counterOffset = static_cast<uint32>(offset) >> 4;
@ -582,9 +584,9 @@ void mtpFileLoader::cdnPartLoaded(const MTPupload_CdnFile &result, mtpRequestId
auto decryptInPlace = result.c_upload_cdnFile().vbytes.v;
MTP::aesCtrEncrypt(decryptInPlace.data(), decryptInPlace.size(), key.data(), &state);
auto bytes = gsl::as_bytes(gsl::make_span(decryptInPlace));
auto buffer = bytes::make_span(decryptInPlace);
switch (checkCdnFileHash(offset, bytes)) {
switch (checkCdnFileHash(offset, buffer)) {
case CheckCdnHashResult::NoHash: {
_cdnUncheckedParts.emplace(offset, decryptInPlace);
requestMoreCdnFileHashes();
@ -595,18 +597,18 @@ void mtpFileLoader::cdnPartLoaded(const MTPupload_CdnFile &result, mtpRequestId
cancel(true);
} return;
case CheckCdnHashResult::Good: return partLoaded(offset, bytes);
case CheckCdnHashResult::Good: return partLoaded(offset, buffer);
}
Unexpected("Result of checkCdnFileHash()");
}
mtpFileLoader::CheckCdnHashResult mtpFileLoader::checkCdnFileHash(int offset, base::const_byte_span bytes) {
mtpFileLoader::CheckCdnHashResult mtpFileLoader::checkCdnFileHash(int offset, bytes::const_span buffer) {
auto cdnFileHashIt = _cdnFileHashes.find(offset);
if (cdnFileHashIt == _cdnFileHashes.cend()) {
return CheckCdnHashResult::NoHash;
}
auto realHash = hashSha256(bytes.data(), bytes.size());
if (base::compare_bytes(gsl::as_bytes(gsl::make_span(realHash)), gsl::as_bytes(gsl::make_span(cdnFileHashIt->second.hash)))) {
auto realHash = openssl::Sha256(buffer);
if (bytes::compare(realHash, bytes::make_span(cdnFileHashIt->second.hash))) {
return CheckCdnHashResult::Invalid;
}
return CheckCdnHashResult::Good;
@ -629,7 +631,7 @@ void mtpFileLoader::getCdnFileHashesDone(const MTPVector<MTPFileHash> &result, m
auto someMoreChecked = false;
for (auto i = _cdnUncheckedParts.begin(); i != _cdnUncheckedParts.cend();) {
const auto uncheckedOffset = i->first;
const auto uncheckedBytes = gsl::as_bytes(gsl::make_span(i->second));
const auto uncheckedBytes = bytes::make_span(i->second);
switch (checkCdnFileHash(uncheckedOffset, uncheckedBytes)) {
case CheckCdnHashResult::NoHash: {
@ -646,10 +648,9 @@ void mtpFileLoader::getCdnFileHashesDone(const MTPVector<MTPFileHash> &result, m
someMoreChecked = true;
const auto goodOffset = uncheckedOffset;
const auto goodBytes = std::move(i->second);
const auto goodBytesSpan = gsl::make_span(goodBytes);
const auto weak = QPointer<mtpFileLoader>(this);
i = _cdnUncheckedParts.erase(i);
if (!feedPart(goodOffset, gsl::as_bytes(goodBytesSpan))
if (!feedPart(goodOffset, bytes::make_span(goodBytes))
|| !weak) {
return;
} else if (_finished) {
@ -692,30 +693,30 @@ int mtpFileLoader::finishSentRequestGetOffset(mtpRequestId requestId) {
return requestData.offset;
}
bool mtpFileLoader::feedPart(int offset, base::const_byte_span bytes) {
bool mtpFileLoader::feedPart(int offset, bytes::const_span buffer) {
Expects(!_finished);
if (bytes.size()) {
if (buffer.size()) {
if (_fileIsOpen) {
auto fsize = _file.size();
if (offset < fsize) {
_skippedBytes -= bytes.size();
_skippedBytes -= buffer.size();
} else if (offset > fsize) {
_skippedBytes += offset - fsize;
}
_file.seek(offset);
if (_file.write(reinterpret_cast<const char*>(bytes.data()), bytes.size()) != qint64(bytes.size())) {
if (_file.write(reinterpret_cast<const char*>(buffer.data()), buffer.size()) != qint64(buffer.size())) {
cancel(true);
return false;
}
} else {
if (offset > 100 * 1024 * 1024) {
// Debugging weird out of memory crashes.
auto info = QString("offset: %1, size: %2, cancelled: %3, finished: %4, filename: '%5', tocache: %6, fromcloud: %7, data: %8, fullsize: %9").arg(offset).arg(bytes.size()).arg(Logs::b(_cancelled)).arg(Logs::b(_finished)).arg(_filename).arg(int(_toCache)).arg(int(_fromCloud)).arg(_data.size()).arg(_size);
auto info = QString("offset: %1, size: %2, cancelled: %3, finished: %4, filename: '%5', tocache: %6, fromcloud: %7, data: %8, fullsize: %9").arg(offset).arg(buffer.size()).arg(Logs::b(_cancelled)).arg(Logs::b(_finished)).arg(_filename).arg(int(_toCache)).arg(int(_fromCloud)).arg(_data.size()).arg(_size);
info += QString(", locationtype: %1, inqueue: %2, localstatus: %3").arg(int(_locationType)).arg(Logs::b(_inQueue)).arg(int(_localStatus));
CrashReports::SetAnnotation("DebugInfo", info);
}
_data.reserve(offset + bytes.size());
_data.reserve(offset + buffer.size());
if (offset > 100 * 1024 * 1024) {
CrashReports::ClearAnnotation("DebugInfo");
}
@ -725,19 +726,18 @@ bool mtpFileLoader::feedPart(int offset, base::const_byte_span bytes) {
_data.resize(offset);
}
if (offset == _data.size()) {
_data.append(reinterpret_cast<const char*>(bytes.data()), bytes.size());
_data.append(reinterpret_cast<const char*>(buffer.data()), buffer.size());
} else {
_skippedBytes -= bytes.size();
if (int64(offset + bytes.size()) > _data.size()) {
_data.resize(offset + bytes.size());
_skippedBytes -= buffer.size();
if (int64(offset + buffer.size()) > _data.size()) {
_data.resize(offset + buffer.size());
}
auto src = bytes;
auto dst = gsl::make_span(_data).subspan(offset, bytes.size());
base::copy_bytes(gsl::as_writeable_bytes(dst), src);
auto dst = bytes::make_span(_data).subspan(offset, buffer.size());
bytes::copy(dst, buffer);
}
}
}
if (!bytes.size() || (bytes.size() % 1024)) { // bad next offset
if (!buffer.size() || (buffer.size() % 1024)) { // bad next offset
_lastComplete = true;
}
if (_sentRequests.empty()
@ -786,8 +786,8 @@ bool mtpFileLoader::feedPart(int offset, base::const_byte_span bytes) {
return true;
}
void mtpFileLoader::partLoaded(int offset, base::const_byte_span bytes) {
if (feedPart(offset, bytes)) {
void mtpFileLoader::partLoaded(int offset, bytes::const_span buffer) {
if (feedPart(offset, buffer)) {
emit progress(this);
loadNext();
}

View File

@ -226,8 +226,8 @@ private:
void requestMoreCdnFileHashes();
void getCdnFileHashesDone(const MTPVector<MTPFileHash> &result, mtpRequestId requestId);
bool feedPart(int offset, base::const_byte_span bytes);
void partLoaded(int offset, base::const_byte_span bytes);
bool feedPart(int offset, bytes::const_span buffer);
void partLoaded(int offset, bytes::const_span buffer);
bool partFailed(const RPCError &error);
bool cdnPartFailed(const RPCError &error, mtpRequestId requestId);
@ -243,7 +243,7 @@ private:
Invalid,
Good,
};
CheckCdnHashResult checkCdnFileHash(int offset, base::const_byte_span bytes);
CheckCdnHashResult checkCdnFileHash(int offset, bytes::const_span buffer);
std::map<mtpRequestId, RequestData> _sentRequests;

View File

@ -20,15 +20,15 @@ inline int bytearraySize(const QByteArray &arr) {
return sizeof(quint32) + arr.size();
}
inline int bytesSize(base::const_byte_span bytes) {
inline int bytesSize(bytes::const_span bytes) {
return sizeof(quint32) + bytes.size();
}
struct ReadBytesVectorWrap {
base::byte_vector &bytes;
bytes::vector &bytes;
};
inline ReadBytesVectorWrap bytes(base::byte_vector &bytes) {
inline ReadBytesVectorWrap bytes(bytes::vector &bytes) {
return ReadBytesVectorWrap { bytes };
}
@ -58,10 +58,10 @@ inline QDataStream &operator>>(QDataStream &stream, ReadBytesVectorWrap data) {
}
struct WriteBytesWrap {
base::const_byte_span bytes;
bytes::const_span bytes;
};
inline WriteBytesWrap bytes(base::const_byte_span bytes) {
inline WriteBytesWrap bytes(bytes::const_span bytes) {
return WriteBytesWrap { bytes };
}