SecureManager: selfie support
GitOrigin-RevId: 79d3fe5c6a0c7f50067c532649fcf54c028e9248
This commit is contained in:
parent
09600304b9
commit
d584e80cf9
@ -834,7 +834,7 @@ passportDataTypeEmailAddress = PassportDataType;
|
|||||||
passportData type:PassportDataType data:string files:vector<file> selfie:file = PassportData;
|
passportData type:PassportDataType data:string files:vector<file> selfie:file = PassportData;
|
||||||
|
|
||||||
//@description Contains information about a Telegram Passport data to save @type Telegram Passport data type @data TODO data should be typed @files List of attached files with a document @selfie Selfie with the document
|
//@description Contains information about a Telegram Passport data to save @type Telegram Passport data type @data TODO data should be typed @files List of attached files with a document @selfie Selfie with the document
|
||||||
inputPassportData type:PassportDataType data:string files:vector<InputFile> selfie:file = InputPassportData;
|
inputPassportData type:PassportDataType data:string files:vector<InputFile> selfie:InputFile = InputPassportData;
|
||||||
|
|
||||||
|
|
||||||
//@class PassportAuthorizationForm Contains information about requested Telegram Passport authorization form @data Available data
|
//@class PassportAuthorizationForm Contains information about requested Telegram Passport authorization form @data Available data
|
||||||
|
Binary file not shown.
@ -43,6 +43,7 @@ void GetSecureValue::loop() {
|
|||||||
promise_.set_result(get_passport_data_object(file_manager, r_secure_value.move_as_ok()));
|
promise_.set_result(get_passport_data_object(file_manager, r_secure_value.move_as_ok()));
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetSecureValue::start_up() {
|
void GetSecureValue::start_up() {
|
||||||
std::vector<telegram_api::object_ptr<telegram_api::SecureValueType>> vec;
|
std::vector<telegram_api::object_ptr<telegram_api::SecureValueType>> vec;
|
||||||
vec.push_back(get_secure_value_type_telegram_object(type_));
|
vec.push_back(get_secure_value_type_telegram_object(type_));
|
||||||
@ -98,17 +99,24 @@ void SetSecureValue::UploadCallback::on_upload_error(FileId file_id, Status erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SetSecureValue::on_upload_ok(FileId file_id, tl_object_ptr<telegram_api::InputSecureFile> input_file) {
|
void SetSecureValue::on_upload_ok(FileId file_id, tl_object_ptr<telegram_api::InputSecureFile> input_file) {
|
||||||
|
SecureInputFile *info_ptr = nullptr;
|
||||||
for (auto &info : to_upload_) {
|
for (auto &info : to_upload_) {
|
||||||
if (info.file_id != file_id) {
|
if (info.file_id != file_id) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
CHECK(!info.input_file);
|
info_ptr = &info;
|
||||||
info.input_file = std::move(input_file);
|
break;
|
||||||
CHECK(files_left_to_upload_ != 0);
|
|
||||||
files_left_to_upload_--;
|
|
||||||
return loop();
|
|
||||||
}
|
}
|
||||||
UNREACHABLE();
|
if (selfie_ && selfie_.value().file_id == file_id) {
|
||||||
|
info_ptr = &selfie_.value();
|
||||||
|
}
|
||||||
|
CHECK(info_ptr);
|
||||||
|
auto &info = *info_ptr;
|
||||||
|
CHECK(!info.input_file);
|
||||||
|
info.input_file = std::move(input_file);
|
||||||
|
CHECK(files_left_to_upload_ != 0);
|
||||||
|
files_left_to_upload_--;
|
||||||
|
return loop();
|
||||||
}
|
}
|
||||||
void SetSecureValue::on_upload_error(FileId file_id, Status error) {
|
void SetSecureValue::on_upload_error(FileId file_id, Status error) {
|
||||||
return on_error(std::move(error));
|
return on_error(std::move(error));
|
||||||
@ -145,6 +153,10 @@ void SetSecureValue::start_up() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (secure_value_.selfie.is_valid() &&
|
||||||
|
file_manager->get_file_view(*it).file_id() == file_manager->get_file_view(secure_value_.selfie).file_id()) {
|
||||||
|
is_duplicate = true;
|
||||||
|
}
|
||||||
if (is_duplicate) {
|
if (is_duplicate) {
|
||||||
it = secure_value_.files.erase(it);
|
it = secure_value_.files.erase(it);
|
||||||
} else {
|
} else {
|
||||||
@ -155,10 +167,17 @@ void SetSecureValue::start_up() {
|
|||||||
to_upload_.resize(secure_value_.files.size());
|
to_upload_.resize(secure_value_.files.size());
|
||||||
upload_callback_ = std::make_shared<UploadCallback>(actor_id(this));
|
upload_callback_ = std::make_shared<UploadCallback>(actor_id(this));
|
||||||
for (size_t i = 0; i < to_upload_.size(); i++) {
|
for (size_t i = 0; i < to_upload_.size(); i++) {
|
||||||
to_upload_[i].file_id = file_manager->dup_file_id(secure_value_.files[i]);
|
start_upload(file_manager, secure_value_.files[i], to_upload_[i]);
|
||||||
file_manager->upload(to_upload_[i].file_id, upload_callback_, 1, 0);
|
|
||||||
files_left_to_upload_++;
|
|
||||||
}
|
}
|
||||||
|
if (selfie_) {
|
||||||
|
start_upload(file_manager, secure_value_.selfie, selfie_.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetSecureValue::start_upload(FileManager *file_manager, FileId file_id, SecureInputFile &info) {
|
||||||
|
info.file_id = file_manager->dup_file_id(file_id);
|
||||||
|
file_manager->upload(info.file_id, upload_callback_, 1, 0);
|
||||||
|
files_left_to_upload_++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetSecureValue::loop() {
|
void SetSecureValue::loop() {
|
||||||
@ -171,7 +190,7 @@ void SetSecureValue::loop() {
|
|||||||
}
|
}
|
||||||
auto *file_manager = G()->file_manager().get_actor_unsafe();
|
auto *file_manager = G()->file_manager().get_actor_unsafe();
|
||||||
auto input_secure_value = get_input_secure_value_object(
|
auto input_secure_value = get_input_secure_value_object(
|
||||||
file_manager, encrypt_secure_value(file_manager, *secret_, secure_value_), to_upload_);
|
file_manager, encrypt_secure_value(file_manager, *secret_, secure_value_), to_upload_, selfie_);
|
||||||
auto save_secure_value =
|
auto save_secure_value =
|
||||||
telegram_api::account_saveSecureValue(std::move(input_secure_value), secret_.value().get_hash());
|
telegram_api::account_saveSecureValue(std::move(input_secure_value), secret_.value().get_hash());
|
||||||
LOG(ERROR) << to_string(save_secure_value);
|
LOG(ERROR) << to_string(save_secure_value);
|
||||||
@ -181,6 +200,14 @@ void SetSecureValue::loop() {
|
|||||||
state_ = State::WaitSetValue;
|
state_ = State::WaitSetValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetSecureValue::tear_down() {
|
||||||
|
auto *file_manager = G()->file_manager().get_actor_unsafe();
|
||||||
|
for (auto &file_info : to_upload_) {
|
||||||
|
file_manager->upload(file_info.file_id, nullptr, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SetSecureValue::on_result(NetQueryPtr query) {
|
void SetSecureValue::on_result(NetQueryPtr query) {
|
||||||
auto r_result = fetch_result<telegram_api::account_saveSecureValue>(std::move(query));
|
auto r_result = fetch_result<telegram_api::account_saveSecureValue>(std::move(query));
|
||||||
if (r_result.is_error()) {
|
if (r_result.is_error()) {
|
||||||
@ -194,15 +221,10 @@ void SetSecureValue::on_result(NetQueryPtr query) {
|
|||||||
return on_error(Status::Error("Different files count"));
|
return on_error(Status::Error("Different files count"));
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < secure_value_.files.size(); i++) {
|
for (size_t i = 0; i < secure_value_.files.size(); i++) {
|
||||||
auto file_view = file_manager->get_file_view(secure_value_.files[i]);
|
merge(file_manager, secure_value_.files[i], encrypted_secure_value.files[i]);
|
||||||
CHECK(!file_view.empty());
|
}
|
||||||
CHECK(file_view.encryption_key().has_value_hash());
|
if (secure_value_.selfie.is_valid()) {
|
||||||
if (file_view.encryption_key().value_hash().as_slice() != encrypted_secure_value.files[i].file_hash) {
|
merge(file_manager, secure_value_.selfie, encrypted_secure_value.selfie);
|
||||||
LOG(ERROR) << "hash mismatch";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
auto status = file_manager->merge(encrypted_secure_value.files[i].file_id, secure_value_.files[i]);
|
|
||||||
LOG_IF(ERROR, status.is_error()) << status.error();
|
|
||||||
}
|
}
|
||||||
auto r_secure_value = decrypt_encrypted_secure_value(file_manager, *secret_, encrypted_secure_value);
|
auto r_secure_value = decrypt_encrypted_secure_value(file_manager, *secret_, encrypted_secure_value);
|
||||||
if (r_secure_value.is_error()) {
|
if (r_secure_value.is_error()) {
|
||||||
@ -212,6 +234,18 @@ void SetSecureValue::on_result(NetQueryPtr query) {
|
|||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetSecureValue::merge(FileManager *file_manager, FileId file_id, SecureFile &encrypted_file) {
|
||||||
|
auto file_view = file_manager->get_file_view(file_id);
|
||||||
|
CHECK(!file_view.empty());
|
||||||
|
CHECK(file_view.encryption_key().has_value_hash());
|
||||||
|
if (file_view.encryption_key().value_hash().as_slice() != encrypted_file.file_hash) {
|
||||||
|
LOG(ERROR) << "hash mismatch";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto status = file_manager->merge(encrypted_file.file_id, file_id);
|
||||||
|
LOG_IF(ERROR, status.is_error()) << status.error();
|
||||||
|
}
|
||||||
|
|
||||||
SecureManager::SecureManager(ActorShared<> parent) : parent_(std::move(parent)) {
|
SecureManager::SecureManager(ActorShared<> parent) : parent_(std::move(parent)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,6 +50,8 @@ class SetSecureValue : public NetQueryCallback {
|
|||||||
|
|
||||||
size_t files_left_to_upload_ = 0;
|
size_t files_left_to_upload_ = 0;
|
||||||
vector<SecureInputFile> to_upload_;
|
vector<SecureInputFile> to_upload_;
|
||||||
|
optional<SecureInputFile> selfie_;
|
||||||
|
|
||||||
class UploadCallback;
|
class UploadCallback;
|
||||||
std::shared_ptr<UploadCallback> upload_callback_;
|
std::shared_ptr<UploadCallback> upload_callback_;
|
||||||
|
|
||||||
@ -75,9 +77,13 @@ class SetSecureValue : public NetQueryCallback {
|
|||||||
void on_secret(Result<secure_storage::Secret> r_secret, bool x);
|
void on_secret(Result<secure_storage::Secret> r_secret, bool x);
|
||||||
|
|
||||||
void start_up() override;
|
void start_up() override;
|
||||||
|
void tear_down() override;
|
||||||
|
|
||||||
void loop() override;
|
void loop() override;
|
||||||
void on_result(NetQueryPtr query) override;
|
void on_result(NetQueryPtr query) override;
|
||||||
|
|
||||||
|
void start_upload(FileManager *file_manager, FileId file_id, SecureInputFile &info);
|
||||||
|
void merge(FileManager *file_manager, FileId file_id, SecureFile &encrypted_file);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SecureManager : public Actor {
|
class SecureManager : public Actor {
|
||||||
|
@ -310,7 +310,8 @@ td_api::object_ptr<td_api::encryptedPassportData> get_encrypted_passport_data_ob
|
|||||||
}
|
}
|
||||||
|
|
||||||
telegram_api::object_ptr<telegram_api::inputSecureValue> get_input_secure_value_object(
|
telegram_api::object_ptr<telegram_api::inputSecureValue> get_input_secure_value_object(
|
||||||
FileManager *file_manager, const EncryptedSecureValue &value, std::vector<SecureInputFile> &input_files) {
|
FileManager *file_manager, const EncryptedSecureValue &value, std::vector<SecureInputFile> &input_files,
|
||||||
|
optional<SecureInputFile> &selfie) {
|
||||||
bool is_plain = value.type == SecureValueType::PhoneNumber || value.type == SecureValueType::EmailAddress;
|
bool is_plain = value.type == SecureValueType::PhoneNumber || value.type == SecureValueType::EmailAddress;
|
||||||
bool has_selfie = value.selfie.file_id.is_valid();
|
bool has_selfie = value.selfie.file_id.is_valid();
|
||||||
int32 flags = 0;
|
int32 flags = 0;
|
||||||
@ -330,11 +331,12 @@ telegram_api::object_ptr<telegram_api::inputSecureValue> get_input_secure_value_
|
|||||||
}
|
}
|
||||||
if (has_selfie) {
|
if (has_selfie) {
|
||||||
flags |= telegram_api::inputSecureValue::SELFIE_MASK;
|
flags |= telegram_api::inputSecureValue::SELFIE_MASK;
|
||||||
|
CHECK(selfie);
|
||||||
}
|
}
|
||||||
return telegram_api::make_object<telegram_api::inputSecureValue>(
|
return telegram_api::make_object<telegram_api::inputSecureValue>(
|
||||||
flags, get_secure_value_type_telegram_object(value.type), is_plain ? nullptr : get_secure_data_object(value.data),
|
flags, get_secure_value_type_telegram_object(value.type), is_plain ? nullptr : get_secure_data_object(value.data),
|
||||||
get_input_secure_files_object(file_manager, value.files, input_files), std::move(plain_data),
|
get_input_secure_files_object(file_manager, value.files, input_files), std::move(plain_data),
|
||||||
has_selfie ? /*TODO*/ nullptr : nullptr);
|
has_selfie ? get_input_secure_file_object(file_manager, value.selfie, *selfie) : nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<td_api::object_ptr<td_api::encryptedPassportData>> get_encrypted_passport_data_object(
|
vector<td_api::object_ptr<td_api::encryptedPassportData>> get_encrypted_passport_data_object(
|
||||||
@ -381,15 +383,24 @@ Result<SecureValue> get_secure_value(FileManager *file_manager,
|
|||||||
false, true));
|
false, true));
|
||||||
res.files.push_back(file_id);
|
res.files.push_back(file_id);
|
||||||
}
|
}
|
||||||
// res.selfie = TODO
|
if (input_passport_data->selfie_) {
|
||||||
|
TRY_RESULT(file_id, file_manager->get_input_file_id(FileType::Secure, std::move(input_passport_data->selfie_),
|
||||||
|
DialogId{}, false, false, false, true));
|
||||||
|
res.selfie = file_id;
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
td_api::object_ptr<td_api::passportData> get_passport_data_object(FileManager *file_manager, const SecureValue &value) {
|
td_api::object_ptr<td_api::passportData> get_passport_data_object(FileManager *file_manager, const SecureValue &value) {
|
||||||
std::vector<td_api::object_ptr<td_api::file>> files;
|
std::vector<td_api::object_ptr<td_api::file>> files;
|
||||||
files = transform(value.files, [&](FileId id) { return file_manager->get_file_object(id, true); });
|
files = transform(value.files, [&](FileId id) { return file_manager->get_file_object(id, true); });
|
||||||
//TODO selfie
|
|
||||||
|
td_api::object_ptr<td_api::file> selfie;
|
||||||
|
if (value.selfie.is_valid()) {
|
||||||
|
selfie = file_manager->get_file_object(value.selfie, true);
|
||||||
|
}
|
||||||
|
|
||||||
return td_api::make_object<td_api::passportData>(get_passport_data_type_object(value.type), value.data,
|
return td_api::make_object<td_api::passportData>(get_passport_data_type_object(value.type), value.data,
|
||||||
std::move(files), nullptr);
|
std::move(files), std::move(selfie));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<FileId> decrypt_secure_file(FileManager *file_manager, const secure_storage::Secret &master_secret,
|
Result<FileId> decrypt_secure_file(FileManager *file_manager, const secure_storage::Secret &master_secret,
|
||||||
@ -436,9 +447,8 @@ Result<SecureValue> decrypt_encrypted_secure_value(FileManager *file_manager, co
|
|||||||
res.data = std::move(data);
|
res.data = std::move(data);
|
||||||
TRY_RESULT(files, decrypt_secure_files(file_manager, secret, encrypted_secure_value.files));
|
TRY_RESULT(files, decrypt_secure_files(file_manager, secret, encrypted_secure_value.files));
|
||||||
res.files = std::move(files);
|
res.files = std::move(files);
|
||||||
// TODO
|
TRY_RESULT(selfie, decrypt_secure_file(file_manager, secret, encrypted_secure_value.selfie));
|
||||||
//TRY_RESULT(selfie, decrypt_secure_file(file_manager, secret, encrypted_secure_value.selfie));
|
res.selfie = std::move(selfie);
|
||||||
//res.selfie = std::move(selfie);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -506,8 +516,7 @@ EncryptedSecureValue encrypt_secure_value(FileManager *file_manager, const secur
|
|||||||
string to_hash;
|
string to_hash;
|
||||||
res.data = encrypt_secure_data(master_secret, secure_value.data, to_hash);
|
res.data = encrypt_secure_data(master_secret, secure_value.data, to_hash);
|
||||||
res.files = encrypt_secure_files(file_manager, master_secret, secure_value.files, to_hash);
|
res.files = encrypt_secure_files(file_manager, master_secret, secure_value.files, to_hash);
|
||||||
// TODO
|
res.selfie = encrypt_secure_file(file_manager, master_secret, secure_value.selfie, to_hash);
|
||||||
//res.selfie = encrypt_secure_file(file_manager, master_secret, secure_value.selfie, to_hash);
|
|
||||||
res.hash = ss::calc_value_hash(to_hash).as_slice().str();
|
res.hash = ss::calc_value_hash(to_hash).as_slice().str();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "td/telegram/SecureStorage.h"
|
#include "td/telegram/SecureStorage.h"
|
||||||
|
|
||||||
#include "td/utils/common.h"
|
#include "td/utils/common.h"
|
||||||
|
#include "td/utils/optional.h"
|
||||||
#include "td/utils/Status.h"
|
#include "td/utils/Status.h"
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
@ -108,7 +109,8 @@ vector<EncryptedSecureValue> get_encrypted_secure_values(
|
|||||||
td_api::object_ptr<td_api::encryptedPassportData> get_encrypted_passport_data_object(FileManager *file_manager,
|
td_api::object_ptr<td_api::encryptedPassportData> get_encrypted_passport_data_object(FileManager *file_manager,
|
||||||
const EncryptedSecureValue &value);
|
const EncryptedSecureValue &value);
|
||||||
telegram_api::object_ptr<telegram_api::inputSecureValue> get_input_secure_value_object(
|
telegram_api::object_ptr<telegram_api::inputSecureValue> get_input_secure_value_object(
|
||||||
FileManager *file_manager, const EncryptedSecureValue &value, vector<SecureInputFile> &input_files);
|
FileManager *file_manager, const EncryptedSecureValue &value, vector<SecureInputFile> &input_files,
|
||||||
|
optional<SecureInputFile> &selfie);
|
||||||
|
|
||||||
vector<td_api::object_ptr<td_api::encryptedPassportData>> get_encrypted_passport_data_object(
|
vector<td_api::object_ptr<td_api::encryptedPassportData>> get_encrypted_passport_data_object(
|
||||||
FileManager *file_manager, const vector<EncryptedSecureValue> &values);
|
FileManager *file_manager, const vector<EncryptedSecureValue> &values);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user