getAllPasswordData and various fixes.

GitOrigin-RevId: e423dfdaf97b06f0067bda3d1fb847869697234f
This commit is contained in:
levlam 2018-04-07 01:29:36 +03:00
parent 0eee63b723
commit 775c2eea25
12 changed files with 214 additions and 60 deletions

View File

@ -836,9 +836,12 @@ passportData type:PassportDataType data:string files:vector<file> selfie:file =
//@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:InputFile = InputPassportData; inputPassportData type:PassportDataType data:string files:vector<InputFile> selfie:InputFile = InputPassportData;
//@description Contains information about all filled Telegram Passport data @data All filled Telegram Passport data
allPassportData data:vector<passportData> = AllPassportData;
//@description Contains information about requested Telegram Passport authorization form @id Authorization form unique identifier @data Available data
passportAuthorizationForm id:int32 data:vector<passportData> selfie_required:Bool privacy_policy_url:string = PassportAuthorizationForm; //@description Contains information about requested Telegram Passport authorization form @id Authorization form unique identifier @data Available data @is_selfie_required True, if selfie is required with a document @privacy_policy_url URL with the service privacy policy
passportAuthorizationForm id:int32 data:vector<passportData> is_selfie_required:Bool privacy_policy_url:string = PassportAuthorizationForm;
//@description Contains an encrypted Telegram Passport data credentials @data The encrypted credentials @hash The decrypted data hash @secret Encrypted by service public key secret for data decryption //@description Contains an encrypted Telegram Passport data credentials @data The encrypted credentials @hash The decrypted data hash @secret Encrypted by service public key secret for data decryption
@ -2881,6 +2884,9 @@ resetNetworkStatistics = Ok;
//@description Returns filled Telegram Passport data @type Data type @password Password of the current user //@description Returns filled Telegram Passport data @type Data type @password Password of the current user
getPassportData type:PassportDataType password:string = PassportData; getPassportData type:PassportDataType password:string = PassportData;
//@description Returns all filled Telegram Passport data @password Password of the current user
getAllPassportData password:string = AllPassportData;
//@description Sets Telegram Passport data @data Input Telegram Passport data @password Password of the current user //@description Sets Telegram Passport data @data Input Telegram Passport data @password Password of the current user
setPassportData data:inputPassportData password:string = PassportData; setPassportData data:inputPassportData password:string = PassportData;
@ -2909,10 +2915,10 @@ resendEmailAddressVerificationCode = EmailAddressAuthenticationCodeInfo;
checkEmailAddressVerificationCode code:string = Ok; checkEmailAddressVerificationCode code:string = Ok;
//@description Returns Telegram Passport authorization form for sharing data with a service @bot_id Service's bot identifier @scope Telegram Passport data types requested by the service @public_key Service's public_key @password Password of the current user //@description Returns Telegram Passport authorization form for sharing data with a service @bot_user_id Service's bot user identifier @scope Telegram Passport data types requested by the service @public_key Service's public_key @payload Authorization form payload provided by the service @password Password of the current user
getPassportAuthorizationForm bot_id:int32 scope:string public_key:string payload:string password:string = PassportAuthorizationForm; getPassportAuthorizationForm bot_user_id:int32 scope:string public_key:string payload:string password:string = PassportAuthorizationForm;
//@description Sends Telegram Passport authorization form, effectively sharing data with the service @autorization_form_id Authorization form identifier //@description Sends Telegram Passport authorization form, effectively sharing data with the service @autorization_form_id Authorization form identifier @types Types of Telegram Passport data chosen by user to complete the authorization form @password Password of the current user
sendPassportAuthorizationForm autorization_form_id:int32 types:vector<PassportDataType> password:string = Ok; sendPassportAuthorizationForm autorization_form_id:int32 types:vector<PassportDataType> password:string = Ok;

Binary file not shown.

View File

@ -932,6 +932,7 @@ account.getTmpPassword#4a82327e password_hash:bytes period:int = account.TmpPass
account.getWebAuthorizations#182e6d6f = account.WebAuthorizations; account.getWebAuthorizations#182e6d6f = account.WebAuthorizations;
account.resetWebAuthorization#2d01b9ef hash:long = Bool; account.resetWebAuthorization#2d01b9ef hash:long = Bool;
account.resetWebAuthorizations#682d2594 = Bool; account.resetWebAuthorizations#682d2594 = Bool;
account.getAllSecureValues#b288bc7d = Vector<SecureValue>;
account.getSecureValue#73665bc2 types:Vector<SecureValueType> = Vector<SecureValue>; account.getSecureValue#73665bc2 types:Vector<SecureValueType> = Vector<SecureValue>;
account.saveSecureValue#899fe31d value:InputSecureValue secure_secret_id:long = SecureValue; account.saveSecureValue#899fe31d value:InputSecureValue secure_secret_id:long = SecureValue;
account.deleteSecureValue#b880bc4b types:Vector<SecureValueType> = Bool; account.deleteSecureValue#b880bc4b types:Vector<SecureValueType> = Bool;

Binary file not shown.

View File

@ -21554,7 +21554,7 @@ unique_ptr<MessageContent> MessagesManager::get_message_action_content(
auto secure_values = move_tl_object_as<telegram_api::messageActionSecureValuesSentMe>(action); auto secure_values = move_tl_object_as<telegram_api::messageActionSecureValuesSentMe>(action);
return make_unique<MessagePassportDataReceived>( return make_unique<MessagePassportDataReceived>(
get_encrypted_secure_values(td_->file_manager_.get(), std::move(secure_values->values_)), get_encrypted_secure_values(td_->file_manager_.get(), std::move(secure_values->values_)),
get_secure_credentials(std::move(secure_values->credentials_))); get_encrypted_secure_credentials(std::move(secure_values->credentials_)));
} }
default: default:
UNREACHABLE(); UNREACHABLE();

View File

@ -6,11 +6,14 @@
// //
#include "td/telegram/SecureManager.h" #include "td/telegram/SecureManager.h"
#include "td/telegram/files/FileManager.h"
#include "td/telegram/Global.h" #include "td/telegram/Global.h"
#include "td/telegram/PasswordManager.h"
#include "td/telegram/net/NetQueryDispatcher.h" #include "td/telegram/net/NetQueryDispatcher.h"
#include "td/telegram/PasswordManager.h"
#include "td/telegram/Td.h"
namespace td { namespace td {
GetSecureValue::GetSecureValue(ActorShared<> parent, std::string password, SecureValueType type, GetSecureValue::GetSecureValue(ActorShared<> parent, std::string password, SecureValueType type,
Promise<SecureValueWithCredentials> promise) Promise<SecureValueWithCredentials> promise)
: parent_(std::move(parent)), password_(std::move(password)), type_(type), promise_(std::move(promise)) { : parent_(std::move(parent)), password_(std::move(password)), type_(type), promise_(std::move(promise)) {
@ -35,7 +38,8 @@ void GetSecureValue::loop() {
if (!encrypted_secure_value_ || !secret_) { if (!encrypted_secure_value_ || !secret_) {
return; return;
} }
auto *file_manager = G()->file_manager().get_actor_unsafe();
auto *file_manager = G()->td().get_actor_unsafe()->file_manager_.get();
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()) {
return on_error(r_secure_value.move_as_error()); return on_error(r_secure_value.move_as_error());
@ -64,11 +68,72 @@ void GetSecureValue::on_result(NetQueryPtr query) {
return on_error(r_result.move_as_error()); return on_error(r_result.move_as_error());
} }
auto result = r_result.move_as_ok(); auto result = r_result.move_as_ok();
if (result.empty()) {
return on_error(Status::Error(404, "Not Found"));
}
if (result.size() != 1) { if (result.size() != 1) {
return on_error(Status::Error(PSLICE() << "Expected vector of size 1 got " << result.size())); return on_error(Status::Error(PSLICE() << "Expected vector of size 1 got " << result.size()));
} }
LOG(ERROR) << to_string(result[0]); LOG(ERROR) << to_string(result[0]);
encrypted_secure_value_ = get_encrypted_secure_value(G()->file_manager().get_actor_unsafe(), std::move(result[0])); encrypted_secure_value_ =
get_encrypted_secure_value(G()->td().get_actor_unsafe()->file_manager_.get(), std::move(result[0]));
loop();
}
GetAllSecureValues::GetAllSecureValues(ActorShared<> parent, std::string password,
Promise<TdApiAllSecureValues> promise)
: parent_(std::move(parent)), password_(std::move(password)), promise_(std::move(promise)) {
}
void GetAllSecureValues::on_error(Status status) {
promise_.set_error(std::move(status));
stop();
}
void GetAllSecureValues::on_secret(Result<secure_storage::Secret> r_secret, bool dummy) {
LOG_IF(ERROR, r_secret.is_error()) << r_secret.error();
LOG_IF(ERROR, r_secret.is_ok()) << r_secret.ok().get_hash();
if (r_secret.is_error()) {
return on_error(r_secret.move_as_error());
}
secret_ = r_secret.move_as_ok();
loop();
}
void GetAllSecureValues::loop() {
if (!encrypted_secure_values_ || !secret_) {
return;
}
auto *file_manager = G()->td().get_actor_unsafe()->file_manager_.get();
auto r_secure_values = decrypt_encrypted_secure_values(file_manager, *secret_, *encrypted_secure_values_);
if (r_secure_values.is_error()) {
return on_error(r_secure_values.move_as_error());
}
auto secure_values = transform(r_secure_values.move_as_ok(),
[](SecureValueWithCredentials &&value) { return std::move(value.value); });
promise_.set_result(get_all_passport_data_object(file_manager, std::move(secure_values)));
stop();
}
void GetAllSecureValues::start_up() {
auto query = G()->net_query_creator().create(create_storer(telegram_api::account_getAllSecureValues()));
G()->net_query_dispatcher().dispatch_with_callback(std::move(query), actor_shared(this));
send_closure(G()->password_manager(), &PasswordManager::get_secure_secret, password_, optional<int64>(),
PromiseCreator::lambda([actor_id = actor_id(this)](Result<secure_storage::Secret> r_secret) {
send_closure(actor_id, &GetAllSecureValues::on_secret, std::move(r_secret), true);
}));
}
void GetAllSecureValues::on_result(NetQueryPtr query) {
auto r_result = fetch_result<telegram_api::account_getAllSecureValues>(std::move(query));
if (r_result.is_error()) {
return on_error(r_result.move_as_error());
}
encrypted_secure_values_ =
get_encrypted_secure_values(G()->td().get_actor_unsafe()->file_manager_.get(), r_result.move_as_ok());
loop(); loop();
} }
@ -188,7 +253,7 @@ void SetSecureValue::loop() {
if (files_left_to_upload_ != 0) { if (files_left_to_upload_ != 0) {
return; return;
} }
auto *file_manager = G()->file_manager().get_actor_unsafe(); auto *file_manager = G()->td().get_actor_unsafe()->file_manager_.get();
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_, selfie_); file_manager, encrypt_secure_value(file_manager, *secret_, secure_value_), to_upload_, selfie_);
auto save_secure_value = auto save_secure_value =
@ -202,7 +267,7 @@ void SetSecureValue::loop() {
} }
void SetSecureValue::tear_down() { void SetSecureValue::tear_down() {
auto *file_manager = G()->file_manager().get_actor_unsafe(); auto *file_manager = G()->td().get_actor_unsafe()->file_manager_.get();
for (auto &file_info : to_upload_) { for (auto &file_info : to_upload_) {
file_manager->upload(file_info.file_id, nullptr, 0, 0); file_manager->upload(file_info.file_id, nullptr, 0, 0);
} }
@ -215,7 +280,7 @@ void SetSecureValue::on_result(NetQueryPtr query) {
} }
auto result = r_result.move_as_ok(); auto result = r_result.move_as_ok();
LOG(ERROR) << to_string(result); LOG(ERROR) << to_string(result);
auto *file_manager = G()->file_manager().get_actor_unsafe(); auto *file_manager = G()->td().get_actor_unsafe()->file_manager_.get();
auto encrypted_secure_value = get_encrypted_secure_value(file_manager, std::move(result)); auto encrypted_secure_value = get_encrypted_secure_value(file_manager, std::move(result));
if (secure_value_.files.size() != encrypted_secure_value.files.size()) { if (secure_value_.files.size() != encrypted_secure_value.files.size()) {
return on_error(Status::Error("Different files count")); return on_error(Status::Error("Different files count"));
@ -248,12 +313,12 @@ void SetSecureValue::merge(FileManager *file_manager, FileId file_id, EncryptedS
class GetPassportAuthorizationForm : public NetQueryCallback { class GetPassportAuthorizationForm : public NetQueryCallback {
public: public:
GetPassportAuthorizationForm(ActorShared<> parent, string password, int32 authorization_form_id, int32 bot_id, GetPassportAuthorizationForm(ActorShared<> parent, string password, int32 authorization_form_id, UserId bot_user_id,
string scope, string public_key, Promise<TdApiAuthorizationForm> promise) string scope, string public_key, Promise<TdApiAuthorizationForm> promise)
: parent_(std::move(parent)) : parent_(std::move(parent))
, password_(std::move(password)) , password_(std::move(password))
, authorization_form_id_(authorization_form_id) , authorization_form_id_(authorization_form_id)
, bot_id_(bot_id) , bot_user_id_(bot_user_id)
, scope_(std::move(scope)) , scope_(std::move(scope))
, public_key_(std::move(public_key)) , public_key_(std::move(public_key))
, promise_(std::move(promise)) { , promise_(std::move(promise)) {
@ -263,7 +328,7 @@ class GetPassportAuthorizationForm : public NetQueryCallback {
ActorShared<> parent_; ActorShared<> parent_;
string password_; string password_;
int32 authorization_form_id_; int32 authorization_form_id_;
int32 bot_id_; UserId bot_user_id_;
string scope_; string scope_;
string public_key_; string public_key_;
Promise<TdApiAuthorizationForm> promise_; Promise<TdApiAuthorizationForm> promise_;
@ -287,7 +352,7 @@ class GetPassportAuthorizationForm : public NetQueryCallback {
void start_up() override { void start_up() override {
auto account_get_authorization_form = auto account_get_authorization_form =
telegram_api::account_getAuthorizationForm(bot_id_, std::move(scope_), std::move(public_key_)); telegram_api::account_getAuthorizationForm(bot_user_id_.get(), std::move(scope_), std::move(public_key_));
auto query = G()->net_query_creator().create(create_storer(account_get_authorization_form)); auto query = G()->net_query_creator().create(create_storer(account_get_authorization_form));
G()->net_query_dispatcher().dispatch_with_callback(std::move(query), actor_shared(this)); G()->net_query_dispatcher().dispatch_with_callback(std::move(query), actor_shared(this));
@ -310,7 +375,7 @@ class GetPassportAuthorizationForm : public NetQueryCallback {
if (!secret_ || !authorization_form_) { if (!secret_ || !authorization_form_) {
return; return;
} }
auto *file_manager = G()->file_manager().get_actor_unsafe(); auto *file_manager = G()->td().get_actor_unsafe()->file_manager_.get();
std::vector<TdApiSecureValue> values; std::vector<TdApiSecureValue> values;
auto types = get_secure_value_types(std::move(authorization_form_->required_types_)); auto types = get_secure_value_types(std::move(authorization_form_->required_types_));
for (auto type : types) { for (auto type : types) {
@ -353,7 +418,7 @@ void SecureManager::get_secure_value(std::string password, SecureValueType type,
if (r_secure_value.is_error()) { if (r_secure_value.is_error()) {
return promise.set_error(r_secure_value.move_as_error()); return promise.set_error(r_secure_value.move_as_error());
} }
auto *file_manager = G()->file_manager().get_actor_unsafe(); auto *file_manager = G()->td().get_actor_unsafe()->file_manager_.get();
promise.set_value(get_passport_data_object(file_manager, r_secure_value.move_as_ok().value)); promise.set_value(get_passport_data_object(file_manager, r_secure_value.move_as_ok().value));
}); });
do_get_secure_value(std::move(password), type, std::move(new_promise)); do_get_secure_value(std::move(password), type, std::move(new_promise));
@ -366,6 +431,12 @@ void SecureManager::do_get_secure_value(std::string password, SecureValueType ty
.release(); .release();
} }
void SecureManager::get_all_secure_values(std::string password, Promise<TdApiAllSecureValues> promise) {
refcnt_++;
create_actor<GetAllSecureValues>("GetAllSecureValues", actor_shared(), std::move(password), std::move(promise))
.release();
}
void SecureManager::set_secure_value(string password, SecureValue secure_value, Promise<TdApiSecureValue> promise) { void SecureManager::set_secure_value(string password, SecureValue secure_value, Promise<TdApiSecureValue> promise) {
refcnt_++; refcnt_++;
auto type = secure_value.type; auto type = secure_value.type;
@ -374,21 +445,22 @@ void SecureManager::set_secure_value(string password, SecureValue secure_value,
if (r_secure_value.is_error()) { if (r_secure_value.is_error()) {
return promise.set_error(r_secure_value.move_as_error()); return promise.set_error(r_secure_value.move_as_error());
} }
auto *file_manager = G()->file_manager().get_actor_unsafe(); auto *file_manager = G()->td().get_actor_unsafe()->file_manager_.get();
promise.set_value(get_passport_data_object(file_manager, r_secure_value.move_as_ok().value)); promise.set_value(get_passport_data_object(file_manager, r_secure_value.move_as_ok().value));
}); });
set_secure_value_queries_[type] = create_actor<SetSecureValue>("SetSecureValue", actor_shared(), std::move(password), set_secure_value_queries_[type] = create_actor<SetSecureValue>("SetSecureValue", actor_shared(), std::move(password),
std::move(secure_value), std::move(new_promise)); std::move(secure_value), std::move(new_promise));
} }
void SecureManager::get_passport_authorization_form(string password, int32 bot_id, string scope, string public_key, void SecureManager::get_passport_authorization_form(string password, UserId bot_user_id, string scope,
string payload, Promise<TdApiAuthorizationForm> promise) { string public_key, string payload,
Promise<TdApiAuthorizationForm> promise) {
refcnt_++; refcnt_++;
auto authorization_form_id = ++authorization_form_id_; auto authorization_form_id = ++authorization_form_id_;
authorization_forms_[authorization_form_id] = AuthorizationForm{bot_id, scope, public_key, payload}; authorization_forms_[authorization_form_id] = AuthorizationForm{bot_user_id, scope, public_key, payload};
create_actor<GetPassportAuthorizationForm>("GetPassportAuthorizationForm", actor_shared(), std::move(password), create_actor<GetPassportAuthorizationForm>("GetPassportAuthorizationForm", actor_shared(), std::move(password),
authorization_form_id, bot_id, std::move(scope), std::move(public_key), authorization_form_id, bot_user_id, std::move(scope),
std::move(promise)) std::move(public_key), std::move(promise))
.release(); .release();
} }
@ -465,7 +537,7 @@ void SecureManager::do_send_passport_authorization_form(int32 authorization_form
} }
auto td_query = telegram_api::account_acceptAuthorization( auto td_query = telegram_api::account_acceptAuthorization(
it->second.bot_id, it->second.scope, it->second.public_key, std::move(hashes), it->second.bot_user_id.get(), it->second.scope, it->second.public_key, std::move(hashes),
get_secure_credentials_encrypted_object(r_encrypted_credentials.move_as_ok())); get_secure_credentials_encrypted_object(r_encrypted_credentials.move_as_ok()));
LOG(ERROR) << to_string(td_query); LOG(ERROR) << to_string(td_query);
auto query = G()->net_query_creator().create(create_storer(td_query)); auto query = G()->net_query_creator().create(create_storer(td_query));
@ -490,12 +562,14 @@ void SecureManager::hangup() {
void SecureManager::hangup_shared() { void SecureManager::hangup_shared() {
dec_refcnt(); dec_refcnt();
} }
void SecureManager::dec_refcnt() { void SecureManager::dec_refcnt() {
refcnt_--; refcnt_--;
if (refcnt_ == 0) { if (refcnt_ == 0) {
stop(); stop();
} }
} }
void SecureManager::on_result(NetQueryPtr query) { void SecureManager::on_result(NetQueryPtr query) {
auto token = get_link_token(); auto token = get_link_token();
container_.extract(token).set_value(std::move(query)); container_.extract(token).set_value(std::move(query));
@ -505,4 +579,5 @@ void SecureManager::send_with_promise(NetQueryPtr query, Promise<NetQueryPtr> pr
auto id = container_.create(std::move(promise)); auto id = container_.create(std::move(promise));
G()->net_query_dispatcher().dispatch_with_callback(std::move(query), actor_shared(this, id)); G()->net_query_dispatcher().dispatch_with_callback(std::move(query), actor_shared(this, id));
} }
} // namespace td } // namespace td

View File

@ -5,19 +5,24 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// //
#pragma once #pragma once
#include "td/actor/actor.h" #include "td/actor/actor.h"
#include "td/telegram/files/FileManager.h"
#include "td/telegram/net/NetQuery.h" #include "td/telegram/net/NetQuery.h"
#include "td/telegram/SecureValue.h" #include "td/telegram/SecureValue.h"
#include "td/telegram/files/FileManager.h" #include "td/telegram/UserId.h"
#include "td/telegram/td_api.h" #include "td/telegram/td_api.h"
#include "td/utils/optional.h" #include "td/utils/optional.h"
namespace td { namespace td {
using TdApiSecureValue = td_api::object_ptr<td_api::passportData>; using TdApiSecureValue = td_api::object_ptr<td_api::passportData>;
using TdApiAllSecureValues = td_api::object_ptr<td_api::allPassportData>;
using TdApiAuthorizationForm = td_api::object_ptr<td_api::passportAuthorizationForm>; using TdApiAuthorizationForm = td_api::object_ptr<td_api::passportAuthorizationForm>;
class GetSecureValue : public NetQueryCallback { class GetSecureValue : public NetQueryCallback {
public: public:
GetSecureValue(ActorShared<> parent, std::string password, SecureValueType type, GetSecureValue(ActorShared<> parent, std::string password, SecureValueType type,
@ -39,6 +44,25 @@ class GetSecureValue : public NetQueryCallback {
void on_result(NetQueryPtr query) override; void on_result(NetQueryPtr query) override;
}; };
class GetAllSecureValues : public NetQueryCallback {
public:
GetAllSecureValues(ActorShared<> parent, std::string password, Promise<TdApiAllSecureValues> promise);
private:
ActorShared<> parent_;
string password_;
Promise<TdApiAllSecureValues> promise_;
optional<vector<EncryptedSecureValue>> encrypted_secure_values_;
optional<secure_storage::Secret> secret_;
void on_error(Status status);
void on_secret(Result<secure_storage::Secret> r_secret, bool dummy);
void loop() override;
void start_up() override;
void on_result(NetQueryPtr query) override;
};
class SetSecureValue : public NetQueryCallback { class SetSecureValue : public NetQueryCallback {
public: public:
SetSecureValue(ActorShared<> parent, string password, SecureValue secure_value, SetSecureValue(ActorShared<> parent, string password, SecureValue secure_value,
@ -91,13 +115,14 @@ class SetSecureValue : public NetQueryCallback {
class SecureManager : public NetQueryCallback { class SecureManager : public NetQueryCallback {
public: public:
SecureManager(ActorShared<> parent); explicit SecureManager(ActorShared<> parent);
void get_secure_value(std::string password, SecureValueType type, Promise<TdApiSecureValue> promise); void get_secure_value(std::string password, SecureValueType type, Promise<TdApiSecureValue> promise);
void get_all_secure_values(std::string password, Promise<TdApiAllSecureValues> promise);
void set_secure_value(string password, SecureValue secure_value, Promise<TdApiSecureValue> promise); void set_secure_value(string password, SecureValue secure_value, Promise<TdApiSecureValue> promise);
void get_passport_authorization_form(string password, int32 bot_id, string scope, string public_key, string payload, void get_passport_authorization_form(string password, UserId bot_user_id, string scope, string public_key,
Promise<TdApiAuthorizationForm> promise); string payload, Promise<TdApiAuthorizationForm> promise);
void send_passport_authorization_form(string password, int32 authorization_form_id, void send_passport_authorization_form(string password, int32 authorization_form_id,
std::vector<SecureValueType> types, Promise<> promise); std::vector<SecureValueType> types, Promise<> promise);
@ -107,7 +132,7 @@ class SecureManager : public NetQueryCallback {
std::map<SecureValueType, ActorOwn<>> set_secure_value_queries_; std::map<SecureValueType, ActorOwn<>> set_secure_value_queries_;
struct AuthorizationForm { struct AuthorizationForm {
int32 bot_id; UserId bot_user_id;
string scope; string scope;
string public_key; string public_key;
string payload; string payload;
@ -127,4 +152,5 @@ class SecureManager : public NetQueryCallback {
Container<Promise<NetQueryPtr>> container_; Container<Promise<NetQueryPtr>> container_;
void send_with_promise(NetQueryPtr query, Promise<NetQueryPtr> promise); void send_with_promise(NetQueryPtr query, Promise<NetQueryPtr> promise);
}; };
} // namespace td } // namespace td

View File

@ -7,14 +7,17 @@
#include "td/telegram/SecureValue.h" #include "td/telegram/SecureValue.h"
#include "td/telegram/files/FileManager.h" #include "td/telegram/files/FileManager.h"
#include "td/telegram/td_api.h" #include "td/telegram/td_api.h"
#include "td/telegram/telegram_api.h" #include "td/telegram/telegram_api.h"
#include "td/telegram/telegram_api.hpp" #include "td/telegram/telegram_api.hpp"
#include "td/utils/base64.h"
#include "td/utils/JsonBuilder.h"
#include "td/utils/misc.h" #include "td/utils/misc.h"
#include "td/utils/overloaded.h" #include "td/utils/overloaded.h"
#include "td/utils/JsonBuilder.h"
#include "td/utils/base64.h" #include <tuple>
namespace td { namespace td {
@ -157,7 +160,7 @@ bool operator!=(const EncryptedSecureFile &lhs, const EncryptedSecureFile &rhs)
return !(lhs == rhs); return !(lhs == rhs);
} }
EncryptedSecureFile get_secure_file(FileManager *file_manager, EncryptedSecureFile get_encrypted_secure_file(FileManager *file_manager,
tl_object_ptr<telegram_api::SecureFile> &&secure_file_ptr) { tl_object_ptr<telegram_api::SecureFile> &&secure_file_ptr) {
CHECK(secure_file_ptr != nullptr); CHECK(secure_file_ptr != nullptr);
EncryptedSecureFile result; EncryptedSecureFile result;
@ -184,12 +187,12 @@ EncryptedSecureFile get_secure_file(FileManager *file_manager,
return result; return result;
} }
vector<EncryptedSecureFile> get_secure_files(FileManager *file_manager, vector<EncryptedSecureFile> get_encrypted_secure_files(FileManager *file_manager,
vector<tl_object_ptr<telegram_api::SecureFile>> &&secure_files) { vector<tl_object_ptr<telegram_api::SecureFile>> &&secure_files) {
vector<EncryptedSecureFile> results; vector<EncryptedSecureFile> results;
results.reserve(secure_files.size()); results.reserve(secure_files.size());
for (auto &secure_file : secure_files) { for (auto &secure_file : secure_files) {
auto result = get_secure_file(file_manager, std::move(secure_file)); auto result = get_encrypted_secure_file(file_manager, std::move(secure_file));
if (result.file_id.is_valid()) { if (result.file_id.is_valid()) {
results.push_back(std::move(result)); results.push_back(std::move(result));
} }
@ -250,7 +253,7 @@ bool operator!=(const EncryptedSecureData &lhs, const EncryptedSecureData &rhs)
return !(lhs == rhs); return !(lhs == rhs);
} }
EncryptedSecureData get_secure_data(tl_object_ptr<telegram_api::secureData> &&secure_data) { EncryptedSecureData get_encrypted_secure_data(tl_object_ptr<telegram_api::secureData> &&secure_data) {
CHECK(secure_data != nullptr); CHECK(secure_data != nullptr);
EncryptedSecureData result; EncryptedSecureData result;
result.data = secure_data->data_.as_slice().str(); result.data = secure_data->data_.as_slice().str();
@ -292,11 +295,11 @@ EncryptedSecureValue get_encrypted_secure_value(FileManager *file_manager,
} }
} }
if (secure_value->data_ != nullptr) { if (secure_value->data_ != nullptr) {
result.data = get_secure_data(std::move(secure_value->data_)); result.data = get_encrypted_secure_data(std::move(secure_value->data_));
} }
result.files = get_secure_files(file_manager, std::move(secure_value->files_)); result.files = get_encrypted_secure_files(file_manager, std::move(secure_value->files_));
if (secure_value->selfie_ != nullptr) { if (secure_value->selfie_ != nullptr) {
result.selfie = get_secure_file(file_manager, std::move(secure_value->selfie_)); result.selfie = get_encrypted_secure_file(file_manager, std::move(secure_value->selfie_));
} }
result.hash = secure_value->hash_.as_slice().str(); result.hash = secure_value->hash_.as_slice().str();
return result; return result;
@ -369,7 +372,7 @@ telegram_api::object_ptr<telegram_api::secureCredentialsEncrypted> get_secure_cr
BufferSlice(credentials.data), BufferSlice(credentials.hash), BufferSlice(credentials.encrypted_secret)); BufferSlice(credentials.data), BufferSlice(credentials.hash), BufferSlice(credentials.encrypted_secret));
} }
EncryptedSecureCredentials get_secure_credentials( EncryptedSecureCredentials get_encrypted_secure_credentials(
tl_object_ptr<telegram_api::secureCredentialsEncrypted> &&credentials) { tl_object_ptr<telegram_api::secureCredentialsEncrypted> &&credentials) {
CHECK(credentials != nullptr); CHECK(credentials != nullptr);
EncryptedSecureCredentials result; EncryptedSecureCredentials result;
@ -419,6 +422,12 @@ td_api::object_ptr<td_api::passportData> get_passport_data_object(FileManager *f
std::move(files), std::move(selfie)); std::move(files), std::move(selfie));
} }
td_api::object_ptr<td_api::allPassportData> get_all_passport_data_object(FileManager *file_manager,
const vector<SecureValue> &value) {
return td_api::make_object<td_api::allPassportData>(transform(
value, [file_manager](const SecureValue &value) { return get_passport_data_object(file_manager, value); }));
}
Result<std::pair<FileId, SecureFileCredentials>> decrypt_secure_file(FileManager *file_manager, Result<std::pair<FileId, SecureFileCredentials>> decrypt_secure_file(FileManager *file_manager,
const secure_storage::Secret &master_secret, const secure_storage::Secret &master_secret,
const EncryptedSecureFile &secure_file) { const EncryptedSecureFile &secure_file) {
@ -447,6 +456,7 @@ Result<std::pair<vector<FileId>, vector<SecureFileCredentials>>> decrypt_secure_
return std::make_pair(std::move(res), std::move(credentials)); return std::make_pair(std::move(res), std::move(credentials));
} }
Result<std::pair<string, SecureDataCredentials>> decrypt_secure_data(const secure_storage::Secret &master_secret, Result<std::pair<string, SecureDataCredentials>> decrypt_secure_data(const secure_storage::Secret &master_secret,
const EncryptedSecureData &secure_data) { const EncryptedSecureData &secure_data) {
TRY_RESULT(hash, secure_storage::ValueHash::create(secure_data.hash)); TRY_RESULT(hash, secure_storage::ValueHash::create(secure_data.hash));
@ -489,6 +499,19 @@ Result<SecureValueWithCredentials> decrypt_encrypted_secure_value(FileManager *f
return SecureValueWithCredentials{std::move(res), std::move(res_credentials)}; return SecureValueWithCredentials{std::move(res), std::move(res_credentials)};
} }
Result<vector<SecureValueWithCredentials>> decrypt_encrypted_secure_values(
FileManager *file_manager, const secure_storage::Secret &secret,
const vector<EncryptedSecureValue> &encrypted_secure_values) {
vector<SecureValueWithCredentials> result;
result.reserve(encrypted_secure_values.size());
for (auto &encrypted_secure_value : encrypted_secure_values) {
TRY_RESULT(secure_value_with_credentials,
decrypt_encrypted_secure_value(file_manager, secret, encrypted_secure_value));
result.push_back(std::move(secure_value_with_credentials));
}
return std::move(result);
}
EncryptedSecureFile encrypt_secure_file(FileManager *file_manager, const secure_storage::Secret &master_secret, EncryptedSecureFile encrypt_secure_file(FileManager *file_manager, const secure_storage::Secret &master_secret,
FileId file, string &to_hash) { FileId file, string &to_hash) {
auto file_view = file_manager->get_file_view(file); auto file_view = file_manager->get_file_view(file);
@ -560,7 +583,7 @@ EncryptedSecureValue encrypt_secure_value(FileManager *file_manager, const secur
template <class T> template <class T>
class AsJsonable : public Jsonable { class AsJsonable : public Jsonable {
public: public:
AsJsonable(const T &value) : value_(value) { explicit AsJsonable(const T &value) : value_(value) {
} }
void store(JsonValueScope *scope) const { void store(JsonValueScope *scope) const {
*scope + value_; *scope + value_;
@ -630,9 +653,9 @@ Slice secure_value_type_as_slice(SecureValueType type) {
case SecureValueType::RentalAgreement: case SecureValueType::RentalAgreement:
return "rental_agreement"; return "rental_agreement";
case SecureValueType::PhoneNumber: case SecureValueType::PhoneNumber:
return "phone_number"; return "phone";
case SecureValueType::EmailAddress: case SecureValueType::EmailAddress:
return "email_address"; return "email";
default: default:
case SecureValueType::None: case SecureValueType::None:
UNREACHABLE(); UNREACHABLE();
@ -649,10 +672,10 @@ JsonScope &operator+(JsonValueScope &scope, const std::vector<SecureValueCredent
} }
JsonScope &operator+(JsonValueScope &scope, JsonScope &operator+(JsonValueScope &scope,
const std::pair<const std::vector<SecureValueCredentials> &, const Slice &> &credentials) { const std::tuple<const std::vector<SecureValueCredentials> &, const Slice &> &credentials) {
auto object = scope.enter_object(); auto object = scope.enter_object();
object << ctie("secure_data", as_jsonable(credentials.first)); object << ctie("secure_data", as_jsonable(std::get<0>(credentials)));
object << ctie("payload", credentials.second); object << ctie("payload", std::get<1>(credentials));
return scope; return scope;
} }
@ -665,7 +688,7 @@ Result<EncryptedSecureCredentials> encrypted_credentials(std::vector<SecureValue
auto encrypted_value = secure_storage::encrypt_value(secret, encoded_credentials).move_as_ok(); auto encrypted_value = secure_storage::encrypt_value(secret, encoded_credentials).move_as_ok();
EncryptedSecureCredentials res; EncryptedSecureCredentials res;
res.data = encrypted_value.data.as_slice().str(); res.data = encrypted_value.data.as_slice().str();
res.hash = encrypted_value.data.as_slice().str(); res.hash = encrypted_value.hash.as_slice().str();
TRY_RESULT(encrypted_secret, rsa_encrypt_pkcs1_oaep(public_key, secret.as_slice())); TRY_RESULT(encrypted_secret, rsa_encrypt_pkcs1_oaep(public_key, secret.as_slice()));
res.encrypted_secret = encrypted_secret.as_slice().str(); res.encrypted_secret = encrypted_secret.as_slice().str();
return res; return res;

View File

@ -13,7 +13,6 @@
#include "td/telegram/SecureStorage.h" #include "td/telegram/SecureStorage.h"
#include "td/utils/common.h" #include "td/utils/common.h"
#include "td/utils/JsonBuilder.h"
#include "td/utils/optional.h" #include "td/utils/optional.h"
#include "td/utils/Status.h" #include "td/utils/Status.h"
@ -58,10 +57,10 @@ struct EncryptedSecureFile {
bool operator==(const EncryptedSecureFile &lhs, const EncryptedSecureFile &rhs); bool operator==(const EncryptedSecureFile &lhs, const EncryptedSecureFile &rhs);
bool operator!=(const EncryptedSecureFile &lhs, const EncryptedSecureFile &rhs); bool operator!=(const EncryptedSecureFile &lhs, const EncryptedSecureFile &rhs);
EncryptedSecureFile get_secure_file(FileManager *file_manager, EncryptedSecureFile get_encrypted_secure_file(FileManager *file_manager,
tl_object_ptr<telegram_api::SecureFile> &&secure_file_ptr); tl_object_ptr<telegram_api::SecureFile> &&secure_file_ptr);
vector<EncryptedSecureFile> get_secure_files(FileManager *file_manager, vector<EncryptedSecureFile> get_encrypted_secure_files(FileManager *file_manager,
vector<tl_object_ptr<telegram_api::SecureFile>> &&secure_files); vector<tl_object_ptr<telegram_api::SecureFile>> &&secure_files);
struct SecureInputFile { struct SecureInputFile {
@ -89,7 +88,7 @@ struct EncryptedSecureData {
bool operator==(const EncryptedSecureData &lhs, const EncryptedSecureData &rhs); bool operator==(const EncryptedSecureData &lhs, const EncryptedSecureData &rhs);
bool operator!=(const EncryptedSecureData &lhs, const EncryptedSecureData &rhs); bool operator!=(const EncryptedSecureData &lhs, const EncryptedSecureData &rhs);
EncryptedSecureData get_secure_data(tl_object_ptr<telegram_api::secureData> &&secure_data); EncryptedSecureData get_encrypted_secure_data(tl_object_ptr<telegram_api::secureData> &&secure_data);
telegram_api::object_ptr<telegram_api::secureData> get_secure_data_object(const EncryptedSecureData &data); telegram_api::object_ptr<telegram_api::secureData> get_secure_data_object(const EncryptedSecureData &data);
@ -128,7 +127,7 @@ struct EncryptedSecureCredentials {
bool operator==(const EncryptedSecureCredentials &lhs, const EncryptedSecureCredentials &rhs); bool operator==(const EncryptedSecureCredentials &lhs, const EncryptedSecureCredentials &rhs);
bool operator!=(const EncryptedSecureCredentials &lhs, const EncryptedSecureCredentials &rhs); bool operator!=(const EncryptedSecureCredentials &lhs, const EncryptedSecureCredentials &rhs);
EncryptedSecureCredentials get_secure_credentials( EncryptedSecureCredentials get_encrypted_secure_credentials(
tl_object_ptr<telegram_api::secureCredentialsEncrypted> &&credentials); tl_object_ptr<telegram_api::secureCredentialsEncrypted> &&credentials);
telegram_api::object_ptr<telegram_api::secureCredentialsEncrypted> get_secure_credentials_encrypted_object( telegram_api::object_ptr<telegram_api::secureCredentialsEncrypted> get_secure_credentials_encrypted_object(
@ -174,6 +173,9 @@ Result<SecureValue> get_secure_value(FileManager *file_manager,
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);
td_api::object_ptr<td_api::allPassportData> get_all_passport_data_object(FileManager *file_manager,
const vector<SecureValue> &value);
Result<std::pair<FileId, SecureFileCredentials>> decrypt_secure_file(FileManager *file_manager, Result<std::pair<FileId, SecureFileCredentials>> decrypt_secure_file(FileManager *file_manager,
const secure_storage::Secret &secret, const secure_storage::Secret &secret,
const EncryptedSecureFile &secure_file); const EncryptedSecureFile &secure_file);
@ -184,6 +186,9 @@ Result<std::pair<string, SecureDataCredentials>> decrypt_secure_data(const secur
Result<SecureValueWithCredentials> decrypt_encrypted_secure_value(FileManager *file_manager, Result<SecureValueWithCredentials> decrypt_encrypted_secure_value(FileManager *file_manager,
const secure_storage::Secret &secret, const secure_storage::Secret &secret,
const EncryptedSecureValue &encrypted_secure_value); const EncryptedSecureValue &encrypted_secure_value);
Result<vector<SecureValueWithCredentials>> decrypt_encrypted_secure_values(
FileManager *file_manager, const secure_storage::Secret &secret,
const vector<EncryptedSecureValue> &encrypted_secure_values);
EncryptedSecureFile encrypt_secure_file(FileManager *file_manager, const secure_storage::Secret &master_secret, EncryptedSecureFile encrypt_secure_file(FileManager *file_manager, const secure_storage::Secret &master_secret,
FileId file, string &to_hash); FileId file, string &to_hash);

View File

@ -6829,14 +6829,23 @@ void Td::on_request(uint64 id, td_api::getPassportData &request) {
CHECK_AUTH(); CHECK_AUTH();
CHECK_IS_USER(); CHECK_IS_USER();
CLEAN_INPUT_STRING(request.password_); CLEAN_INPUT_STRING(request.password_);
CREATE_REQUEST_PROMISE(promise);
if (request.type_ == nullptr) { if (request.type_ == nullptr) {
return promise.set_error(Status::Error(400, "Type must not be empty")); return send_error_raw(id, 400, "Type must not be empty");
} }
CREATE_REQUEST_PROMISE(promise);
send_closure(secure_manager_, &SecureManager::get_secure_value, std::move(request.password_), send_closure(secure_manager_, &SecureManager::get_secure_value, std::move(request.password_),
get_secure_value_type_td_api(std::move(request.type_)), std::move(promise)); get_secure_value_type_td_api(std::move(request.type_)), std::move(promise));
} }
void Td::on_request(uint64 id, td_api::getAllPassportData &request) {
CHECK_AUTH();
CHECK_IS_USER();
CLEAN_INPUT_STRING(request.password_);
CREATE_REQUEST_PROMISE(promise);
send_closure(secure_manager_, &SecureManager::get_all_secure_values, std::move(request.password_),
std::move(promise));
}
void Td::on_request(uint64 id, td_api::setPassportData &request) { void Td::on_request(uint64 id, td_api::setPassportData &request) {
CHECK_AUTH(); CHECK_AUTH();
CHECK_IS_USER(); CHECK_IS_USER();
@ -6903,8 +6912,12 @@ void Td::on_request(uint64 id, td_api::getPassportAuthorizationForm &request) {
CLEAN_INPUT_STRING(request.public_key_); CLEAN_INPUT_STRING(request.public_key_);
CLEAN_INPUT_STRING(request.scope_); CLEAN_INPUT_STRING(request.scope_);
CLEAN_INPUT_STRING(request.payload_); CLEAN_INPUT_STRING(request.payload_);
UserId bot_user_id(request.bot_user_id_);
if (!bot_user_id.is_valid()) {
return send_error_raw(id, 400, "Bot user identifier invalid");
}
CREATE_REQUEST_PROMISE(promise); CREATE_REQUEST_PROMISE(promise);
send_closure(secure_manager_, &SecureManager::get_passport_authorization_form, request.password_, request.bot_id_, send_closure(secure_manager_, &SecureManager::get_passport_authorization_form, request.password_, bot_user_id,
request.scope_, request.public_key_, request.payload_, std::move(promise)); request.scope_, request.public_key_, request.payload_, std::move(promise));
} }

View File

@ -751,6 +751,8 @@ class Td final : public NetQueryCallback {
void on_request(uint64 id, td_api::getPassportData &request); void on_request(uint64 id, td_api::getPassportData &request);
void on_request(uint64 id, td_api::getAllPassportData &request);
void on_request(uint64 id, td_api::setPassportData &request); void on_request(uint64 id, td_api::setPassportData &request);
void on_request(uint64 id, const td_api::deletePassportData &request); void on_request(uint64 id, const td_api::deletePassportData &request);

View File

@ -1078,7 +1078,7 @@ class CliClient final : public Actor {
recovery_email_address = ""; recovery_email_address = "";
} }
send_request(make_tl_object<td_api::setPassword>(password, new_password, new_hint, true, recovery_email_address)); send_request(make_tl_object<td_api::setPassword>(password, new_password, new_hint, true, recovery_email_address));
} else if (op == "secureid") { } else if (op == "gpaf" || op == "secureid") {
string password; string password;
std::tie(password, args) = split(args); std::tie(password, args) = split(args);
ChainBufferWriter writer; ChainBufferWriter writer;
@ -1127,6 +1127,9 @@ class CliClient final : public Actor {
string passport_data_type; string passport_data_type;
std::tie(password, passport_data_type) = split(args); std::tie(password, passport_data_type) = split(args);
send_request(make_tl_object<td_api::getPassportData>(as_passport_data_type(passport_data_type), password)); send_request(make_tl_object<td_api::getPassportData>(as_passport_data_type(passport_data_type), password));
} else if (op == "gapd") {
string password = args;
send_request(make_tl_object<td_api::getAllPassportData>(password));
} else if (op == "spd") { } else if (op == "spd") {
string password; string password;
string passport_data_type; string passport_data_type;