sendAuthorizationForm (with bugs)

GitOrigin-RevId: e68b57a2f6ff2e117913c40779cc9473153828ab
This commit is contained in:
Arseny Smirnov 2018-04-06 22:37:30 +03:00
parent c240d107f6
commit 0eee63b723
13 changed files with 396 additions and 62 deletions

View File

@ -2910,10 +2910,10 @@ 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
getPassportAuthorizationForm bot_id:int32 scope:string public_key:string password:string = PassportAuthorizationForm;
getPassportAuthorizationForm bot_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
sendPassportAuthorizationForm autorization_form_id:int32 types:vector<PassportDataType> = Ok;
sendPassportAuthorizationForm autorization_form_id:int32 types:vector<PassportDataType> password:string = Ok;
//@description Informs the server about the number of pending bot updates if they haven't been processed for a long time; for bots only @pending_update_count The number of pending updates @error_message The last error message

Binary file not shown.

View File

@ -644,10 +644,10 @@ class MessagePassportDataSent : public MessageContent {
class MessagePassportDataReceived : public MessageContent {
public:
vector<EncryptedSecureValue> values;
SecureCredentials credentials;
EncryptedSecureCredentials credentials;
MessagePassportDataReceived() = default;
MessagePassportDataReceived(vector<EncryptedSecureValue> &&values, SecureCredentials &&credentials)
MessagePassportDataReceived(vector<EncryptedSecureValue> &&values, EncryptedSecureCredentials &&credentials)
: values(std::move(values)), credentials(std::move(credentials)) {
}

View File

@ -12,7 +12,7 @@
namespace td {
GetSecureValue::GetSecureValue(ActorShared<> parent, std::string password, SecureValueType type,
Promise<TdApiSecureValue> promise)
Promise<SecureValueWithCredentials> promise)
: parent_(std::move(parent)), password_(std::move(password)), type_(type), promise_(std::move(promise)) {
}
@ -40,7 +40,7 @@ void GetSecureValue::loop() {
if (r_secure_value.is_error()) {
return on_error(r_secure_value.move_as_error());
}
promise_.set_result(get_passport_data_object(file_manager, r_secure_value.move_as_ok()));
promise_.set_result(r_secure_value.move_as_ok());
stop();
}
@ -73,7 +73,7 @@ void GetSecureValue::on_result(NetQueryPtr query) {
}
SetSecureValue::SetSecureValue(ActorShared<> parent, string password, SecureValue secure_value,
Promise<TdApiSecureValue> promise)
Promise<SecureValueWithCredentials> promise)
: parent_(std::move(parent))
, password_(std::move(password))
, secure_value_(std::move(secure_value))
@ -230,7 +230,7 @@ void SetSecureValue::on_result(NetQueryPtr query) {
if (r_secure_value.is_error()) {
return on_error(r_secure_value.move_as_error());
}
promise_.set_result(get_passport_data_object(file_manager, r_secure_value.move_as_ok()));
promise_.set_result(r_secure_value.move_as_ok());
stop();
}
@ -330,7 +330,7 @@ class GetPassportAuthorizationForm : public NetQueryCallback {
auto r_secure_value =
decrypt_encrypted_secure_value(file_manager, *secret_, std::move(*encrypted_secure_value));
if (r_secure_value.is_ok()) {
secure_value = r_secure_value.move_as_ok();
secure_value = r_secure_value.move_as_ok().value;
} else {
LOG(ERROR) << "Failed to decrypt secure value: " << r_secure_value.error();
}
@ -348,6 +348,19 @@ SecureManager::SecureManager(ActorShared<> parent) : parent_(std::move(parent))
}
void SecureManager::get_secure_value(std::string password, SecureValueType type, Promise<TdApiSecureValue> promise) {
auto new_promise =
PromiseCreator::lambda([promise = std::move(promise)](Result<SecureValueWithCredentials> r_secure_value) mutable {
if (r_secure_value.is_error()) {
return promise.set_error(r_secure_value.move_as_error());
}
auto *file_manager = G()->file_manager().get_actor_unsafe();
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));
}
void SecureManager::do_get_secure_value(std::string password, SecureValueType type,
Promise<SecureValueWithCredentials> promise) {
refcnt_++;
create_actor<GetSecureValue>("GetSecureValue", actor_shared(), std::move(password), type, std::move(promise))
.release();
@ -356,15 +369,23 @@ void SecureManager::get_secure_value(std::string password, SecureValueType type,
void SecureManager::set_secure_value(string password, SecureValue secure_value, Promise<TdApiSecureValue> promise) {
refcnt_++;
auto type = secure_value.type;
auto new_promise =
PromiseCreator::lambda([promise = std::move(promise)](Result<SecureValueWithCredentials> r_secure_value) mutable {
if (r_secure_value.is_error()) {
return promise.set_error(r_secure_value.move_as_error());
}
auto *file_manager = G()->file_manager().get_actor_unsafe();
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),
std::move(secure_value), std::move(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,
Promise<TdApiAuthorizationForm> promise) {
string payload, Promise<TdApiAuthorizationForm> promise) {
refcnt_++;
auto authorization_form_id = ++authorization_form_id_;
authorization_forms_[authorization_form_id] = AuthorizationForm{bot_id, public_key};
authorization_forms_[authorization_form_id] = AuthorizationForm{bot_id, scope, public_key, payload};
create_actor<GetPassportAuthorizationForm>("GetPassportAuthorizationForm", actor_shared(), std::move(password),
authorization_form_id, bot_id, std::move(scope), std::move(public_key),
std::move(promise))
@ -377,7 +398,91 @@ void SecureManager::send_passport_authorization_form(string password, int32 auth
if (it == authorization_forms_.end()) {
return promise.set_error(Status::Error(400, "Unknown authorization_form_id"));
}
if (types.empty()) {
return promise.set_error(Status::Error(400, "Empty types"));
}
struct JoinPromise {
std::mutex mutex_;
Promise<std::vector<SecureValueCredentials>> promise_;
std::vector<SecureValueCredentials> credentials_;
int wait_cnt_{0};
};
auto join = std::make_shared<JoinPromise>();
std::lock_guard<std::mutex> guard(join->mutex_);
for (auto type : types) {
join->wait_cnt_++;
do_get_secure_value(password, type,
PromiseCreator::lambda([join](Result<SecureValueWithCredentials> r_secure_value) {
std::lock_guard<std::mutex> guard(join->mutex_);
if (!join->promise_) {
return;
}
if (r_secure_value.is_error()) {
return join->promise_.set_error(r_secure_value.move_as_error());
}
join->credentials_.push_back(r_secure_value.move_as_ok().credentials);
join->wait_cnt_--;
LOG(ERROR) << tag("wait_cnt", join->wait_cnt_);
if (join->wait_cnt_ == 0) {
LOG(ERROR) << "set promise";
join->promise_.set_value(std::move(join->credentials_));
}
}));
}
join->promise_ =
PromiseCreator::lambda([promise = std::move(promise), actor_id = actor_id(this),
authorization_form_id](Result<vector<SecureValueCredentials>> r_credentials) mutable {
LOG(ERROR) << "on promise";
if (r_credentials.is_error()) {
return promise.set_error(r_credentials.move_as_error());
}
send_closure(actor_id, &SecureManager::do_send_passport_authorization_form, authorization_form_id,
r_credentials.move_as_ok(), std::move(promise));
});
}
void SecureManager::do_send_passport_authorization_form(int32 authorization_form_id,
vector<SecureValueCredentials> credentials, Promise<> promise) {
LOG(ERROR) << "do_send_passport_authorization_form";
auto it = authorization_forms_.find(authorization_form_id);
if (it == authorization_forms_.end()) {
return promise.set_error(Status::Error(400, "Unknown authorization_form_id"));
}
if (credentials.empty()) {
return promise.set_error(Status::Error(400, "Empty types"));
}
std::vector<telegram_api::object_ptr<telegram_api::secureValueHash>> hashes;
for (auto &c : credentials) {
hashes.push_back(telegram_api::make_object<telegram_api::secureValueHash>(
get_secure_value_type_telegram_object(c.type), BufferSlice(c.hash)));
}
auto r_encrypted_credentials = encrypted_credentials(credentials, it->second.payload, it->second.public_key);
if (r_encrypted_credentials.is_error()) {
return promise.set_error(r_encrypted_credentials.move_as_error());
}
auto td_query = telegram_api::account_acceptAuthorization(
it->second.bot_id, it->second.scope, it->second.public_key, std::move(hashes),
get_secure_credentials_encrypted_object(r_encrypted_credentials.move_as_ok()));
LOG(ERROR) << to_string(td_query);
auto query = G()->net_query_creator().create(create_storer(td_query));
auto new_promise =
PromiseCreator::lambda([promise = std::move(promise)](Result<NetQueryPtr> r_net_query_ptr) mutable {
if (r_net_query_ptr.is_error()) {
return promise.set_error(r_net_query_ptr.move_as_error());
}
auto r_result = fetch_result<telegram_api::account_acceptAuthorization>(r_net_query_ptr.move_as_ok());
if (r_result.is_error()) {
return promise.set_error(r_result.move_as_error());
}
promise.set_value(Unit());
});
send_with_promise(std::move(query), std::move(new_promise));
}
void SecureManager::hangup() {
dec_refcnt();
}
@ -391,4 +496,13 @@ void SecureManager::dec_refcnt() {
stop();
}
}
void SecureManager::on_result(NetQueryPtr query) {
auto token = get_link_token();
container_.extract(token).set_value(std::move(query));
}
void SecureManager::send_with_promise(NetQueryPtr query, Promise<NetQueryPtr> promise) {
auto id = container_.create(std::move(promise));
G()->net_query_dispatcher().dispatch_with_callback(std::move(query), actor_shared(this, id));
}
} // namespace td

View File

@ -20,13 +20,14 @@ using TdApiSecureValue = td_api::object_ptr<td_api::passportData>;
using TdApiAuthorizationForm = td_api::object_ptr<td_api::passportAuthorizationForm>;
class GetSecureValue : public NetQueryCallback {
public:
GetSecureValue(ActorShared<> parent, std::string password, SecureValueType type, Promise<TdApiSecureValue> promise);
GetSecureValue(ActorShared<> parent, std::string password, SecureValueType type,
Promise<SecureValueWithCredentials> promise);
private:
ActorShared<> parent_;
string password_;
SecureValueType type_;
Promise<TdApiSecureValue> promise_;
Promise<SecureValueWithCredentials> promise_;
optional<EncryptedSecureValue> encrypted_secure_value_;
optional<secure_storage::Secret> secret_;
@ -40,13 +41,14 @@ class GetSecureValue : public NetQueryCallback {
class SetSecureValue : public NetQueryCallback {
public:
SetSecureValue(ActorShared<> parent, string password, SecureValue secure_value, Promise<TdApiSecureValue> promise);
SetSecureValue(ActorShared<> parent, string password, SecureValue secure_value,
Promise<SecureValueWithCredentials> promise);
private:
ActorShared<> parent_;
string password_;
SecureValue secure_value_;
Promise<TdApiSecureValue> promise_;
Promise<SecureValueWithCredentials> promise_;
optional<secure_storage::Secret> secret_;
size_t files_left_to_upload_ = 0;
@ -87,14 +89,14 @@ class SetSecureValue : public NetQueryCallback {
void merge(FileManager *file_manager, FileId file_id, EncryptedSecureFile &encrypted_file);
};
class SecureManager : public Actor {
class SecureManager : public NetQueryCallback {
public:
SecureManager(ActorShared<> parent);
void get_secure_value(std::string password, SecureValueType type, 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,
void get_passport_authorization_form(string password, int32 bot_id, string scope, string public_key, string payload,
Promise<TdApiAuthorizationForm> promise);
void send_passport_authorization_form(string password, int32 authorization_form_id,
std::vector<SecureValueType> types, Promise<> promise);
@ -106,7 +108,9 @@ class SecureManager : public Actor {
struct AuthorizationForm {
int32 bot_id;
string scope;
string public_key;
string payload;
};
std::map<int32, AuthorizationForm> authorization_forms_;
@ -115,5 +119,12 @@ class SecureManager : public Actor {
void hangup() override;
void hangup_shared() override;
void dec_refcnt();
void do_get_secure_value(std::string password, SecureValueType type, Promise<SecureValueWithCredentials> promise);
void do_send_passport_authorization_form(int32 authorization_form_id, vector<SecureValueCredentials> credentials,
Promise<> promise);
void on_result(NetQueryPtr query) override;
Container<Promise<NetQueryPtr>> container_;
void send_with_promise(NetQueryPtr query, Promise<NetQueryPtr> promise);
};
} // namespace td

View File

@ -13,6 +13,8 @@
#include "td/utils/misc.h"
#include "td/utils/overloaded.h"
#include "td/utils/JsonBuilder.h"
#include "td/utils/base64.h"
namespace td {
@ -79,6 +81,11 @@ vector<SecureValueType> get_secure_value_types(
return transform(std::move(secure_value_types), get_secure_value_type);
}
vector<SecureValueType> get_secure_value_types_td_api(
vector<tl_object_ptr<td_api::PassportDataType>> &&secure_value_types) {
return transform(std::move(secure_value_types), get_secure_value_type_td_api);
}
td_api::object_ptr<td_api::PassportDataType> get_passport_data_type_object(SecureValueType type) {
switch (type) {
case SecureValueType::PersonalDetails:
@ -291,6 +298,7 @@ EncryptedSecureValue get_encrypted_secure_value(FileManager *file_manager,
if (secure_value->selfie_ != nullptr) {
result.selfie = get_secure_file(file_manager, std::move(secure_value->selfie_));
}
result.hash = secure_value->hash_.as_slice().str();
return result;
}
@ -347,17 +355,24 @@ vector<td_api::object_ptr<td_api::encryptedPassportData>> get_encrypted_passport
});
}
bool operator==(const SecureCredentials &lhs, const SecureCredentials &rhs) {
bool operator==(const EncryptedSecureCredentials &lhs, const EncryptedSecureCredentials &rhs) {
return lhs.data == rhs.data && lhs.hash == rhs.hash && lhs.encrypted_secret == rhs.encrypted_secret;
}
bool operator!=(const SecureCredentials &lhs, const SecureCredentials &rhs) {
bool operator!=(const EncryptedSecureCredentials &lhs, const EncryptedSecureCredentials &rhs) {
return !(lhs == rhs);
}
SecureCredentials get_secure_credentials(tl_object_ptr<telegram_api::secureCredentialsEncrypted> &&credentials) {
telegram_api::object_ptr<telegram_api::secureCredentialsEncrypted> get_secure_credentials_encrypted_object(
const EncryptedSecureCredentials &credentials) {
return telegram_api::make_object<telegram_api::secureCredentialsEncrypted>(
BufferSlice(credentials.data), BufferSlice(credentials.hash), BufferSlice(credentials.encrypted_secret));
}
EncryptedSecureCredentials get_secure_credentials(
tl_object_ptr<telegram_api::secureCredentialsEncrypted> &&credentials) {
CHECK(credentials != nullptr);
SecureCredentials result;
EncryptedSecureCredentials result;
result.data = credentials->data_.as_slice().str();
result.hash = credentials->hash_.as_slice().str();
result.encrypted_secret = credentials->secret_.as_slice().str();
@ -365,7 +380,7 @@ SecureCredentials get_secure_credentials(tl_object_ptr<telegram_api::secureCrede
}
td_api::object_ptr<td_api::encryptedCredentials> get_encrypted_credentials_object(
const SecureCredentials &credentials) {
const EncryptedSecureCredentials &credentials) {
return td_api::make_object<td_api::encryptedCredentials>(credentials.data, credentials.hash,
credentials.encrypted_secret);
}
@ -404,10 +419,11 @@ td_api::object_ptr<td_api::passportData> get_passport_data_object(FileManager *f
std::move(files), std::move(selfie));
}
Result<FileId> decrypt_secure_file(FileManager *file_manager, const secure_storage::Secret &master_secret,
const EncryptedSecureFile &secure_file) {
Result<std::pair<FileId, SecureFileCredentials>> decrypt_secure_file(FileManager *file_manager,
const secure_storage::Secret &master_secret,
const EncryptedSecureFile &secure_file) {
if (!secure_file.file_id.is_valid()) {
return secure_file.file_id;
return std::make_pair(secure_file.file_id, SecureFileCredentials{});
}
TRY_RESULT(hash, secure_storage::ValueHash::create(secure_file.file_hash));
TRY_RESULT(encrypted_secret, secure_storage::EncryptedSecret::create(secure_file.encrypted_secret));
@ -415,33 +431,39 @@ Result<FileId> decrypt_secure_file(FileManager *file_manager, const secure_stora
FileEncryptionKey key{secret};
key.set_value_hash(hash);
file_manager->set_encryption_key(secure_file.file_id, std::move(key));
return secure_file.file_id;
return std::make_pair(secure_file.file_id, SecureFileCredentials{secret.as_slice().str(), hash.as_slice().str()});
}
Result<vector<FileId>> decrypt_secure_files(FileManager *file_manager, const secure_storage::Secret &secret,
const vector<EncryptedSecureFile> &secure_files) {
Result<std::pair<vector<FileId>, vector<SecureFileCredentials>>> decrypt_secure_files(
FileManager *file_manager, const secure_storage::Secret &secret, const vector<EncryptedSecureFile> &secure_files) {
vector<FileId> res;
vector<SecureFileCredentials> credentials;
res.reserve(secure_files.size());
for (auto &file : secure_files) {
TRY_RESULT(decrypted_file, decrypt_secure_file(file_manager, secret, file));
res.push_back(decrypted_file);
res.push_back(decrypted_file.first);
credentials.push_back(decrypted_file.second);
}
return std::move(res);
return std::make_pair(std::move(res), std::move(credentials));
}
Result<string> decrypt_secure_data(const secure_storage::Secret &master_secret,
const EncryptedSecureData &secure_data) {
Result<std::pair<string, SecureDataCredentials>> decrypt_secure_data(const secure_storage::Secret &master_secret,
const EncryptedSecureData &secure_data) {
TRY_RESULT(hash, secure_storage::ValueHash::create(secure_data.hash));
TRY_RESULT(encrypted_secret, secure_storage::EncryptedSecret::create(secure_data.encrypted_secret));
TRY_RESULT(secret, encrypted_secret.decrypt(PSLICE() << master_secret.as_slice() << hash.as_slice()));
TRY_RESULT(value, secure_storage::decrypt_value(secret, hash, secure_data.data));
return value.as_slice().str();
return std::make_pair(value.as_slice().str(), SecureDataCredentials{secret.as_slice().str(), hash.as_slice().str()});
}
Result<SecureValue> decrypt_encrypted_secure_value(FileManager *file_manager, const secure_storage::Secret &secret,
const EncryptedSecureValue &encrypted_secure_value) {
Result<SecureValueWithCredentials> decrypt_encrypted_secure_value(FileManager *file_manager,
const secure_storage::Secret &secret,
const EncryptedSecureValue &encrypted_secure_value) {
SecureValue res;
SecureValueCredentials res_credentials;
res.type = encrypted_secure_value.type;
res_credentials.type = res.type;
res_credentials.hash = encrypted_secure_value.hash;
switch (encrypted_secure_value.type) {
case SecureValueType::EmailAddress:
case SecureValueType::PhoneNumber:
@ -449,15 +471,22 @@ Result<SecureValue> decrypt_encrypted_secure_value(FileManager *file_manager, co
break;
default: {
TRY_RESULT(data, decrypt_secure_data(secret, encrypted_secure_value.data));
res.data = std::move(data);
res.data = std::move(data.first);
if (!res.data.empty()) {
res_credentials.data = std::move(data.second);
}
TRY_RESULT(files, decrypt_secure_files(file_manager, secret, encrypted_secure_value.files));
res.files = std::move(files);
res.files = std::move(files.first);
res_credentials.files = std::move(files.second);
TRY_RESULT(selfie, decrypt_secure_file(file_manager, secret, encrypted_secure_value.selfie));
res.selfie = std::move(selfie);
res.selfie = std::move(selfie.first);
if (res.selfie.is_valid()) {
res_credentials.selfie = std::move(selfie.second);
}
break;
}
}
return std::move(res);
return SecureValueWithCredentials{std::move(res), std::move(res_credentials)};
}
EncryptedSecureFile encrypt_secure_file(FileManager *file_manager, const secure_storage::Secret &master_secret,
@ -528,4 +557,117 @@ EncryptedSecureValue encrypt_secure_value(FileManager *file_manager, const secur
return res;
}
template <class T>
class AsJsonable : public Jsonable {
public:
AsJsonable(const T &value) : value_(value) {
}
void store(JsonValueScope *scope) const {
*scope + value_;
}
private:
const T &value_;
};
template <class T>
auto as_jsonable(const T &value) {
return AsJsonable<T>(value);
}
JsonScope &operator+(JsonValueScope &scope, const SecureDataCredentials &credentials) {
auto object = scope.enter_object();
object << ctie("data_hash", base64_encode(credentials.hash));
object << ctie("secret", base64_encode(credentials.secret));
return scope;
}
JsonScope &operator+(JsonValueScope &scope, const SecureFileCredentials &credentials) {
auto object = scope.enter_object();
object << ctie("file_hash", base64_encode(credentials.hash));
object << ctie("secret", base64_encode(credentials.secret));
return scope;
}
JsonScope &operator+(JsonValueScope &scope, const vector<SecureFileCredentials> &files) {
auto arr = scope.enter_array();
for (auto &file : files) {
arr << as_jsonable(file);
}
return scope;
}
JsonScope &operator+(JsonValueScope &scope, const SecureValueCredentials &credentials) {
auto object = scope.enter_object();
if (credentials.data) {
object << ctie("data", as_jsonable(credentials.data.value()));
}
if (!credentials.files.empty()) {
object << ctie("files", as_jsonable(credentials.files));
}
if (credentials.selfie) {
object << ctie("selfie", as_jsonable(credentials.selfie.value()));
}
return scope;
}
Slice secure_value_type_as_slice(SecureValueType type) {
switch (type) {
case SecureValueType::PersonalDetails:
return "personal_details";
case SecureValueType::Passport:
return "passport";
case SecureValueType::DriverLicense:
return "driver_license";
case SecureValueType::IdentityCard:
return "identity_card";
case SecureValueType::Address:
return "address";
case SecureValueType::UtilityBill:
return "utility_bill";
case SecureValueType::BankStatement:
return "bank_statement";
case SecureValueType::RentalAgreement:
return "rental_agreement";
case SecureValueType::PhoneNumber:
return "phone_number";
case SecureValueType::EmailAddress:
return "email_address";
default:
case SecureValueType::None:
UNREACHABLE();
return "none";
}
}
JsonScope &operator+(JsonValueScope &scope, const std::vector<SecureValueCredentials> &credentials) {
auto object = scope.enter_object();
for (auto &c : credentials) {
object << ctie(secure_value_type_as_slice(c.type), as_jsonable(c));
}
return scope;
}
JsonScope &operator+(JsonValueScope &scope,
const std::pair<const std::vector<SecureValueCredentials> &, const Slice &> &credentials) {
auto object = scope.enter_object();
object << ctie("secure_data", as_jsonable(credentials.first));
object << ctie("payload", credentials.second);
return scope;
}
Result<EncryptedSecureCredentials> encrypted_credentials(std::vector<SecureValueCredentials> &credentials,
Slice payload, Slice public_key) {
auto encoded_credentials = json_encode<std::string>(as_jsonable(ctie(credentials, payload)));
LOG(ERROR) << encoded_credentials;
auto secret = secure_storage::Secret::create_new();
auto encrypted_value = secure_storage::encrypt_value(secret, encoded_credentials).move_as_ok();
EncryptedSecureCredentials res;
res.data = encrypted_value.data.as_slice().str();
res.hash = encrypted_value.data.as_slice().str();
TRY_RESULT(encrypted_secret, rsa_encrypt_pkcs1_oaep(public_key, secret.as_slice()));
res.encrypted_secret = encrypted_secret.as_slice().str();
return res;
}
} // namespace td

View File

@ -13,6 +13,7 @@
#include "td/telegram/SecureStorage.h"
#include "td/utils/common.h"
#include "td/utils/JsonBuilder.h"
#include "td/utils/optional.h"
#include "td/utils/Status.h"
@ -39,6 +40,8 @@ SecureValueType get_secure_value_type_td_api(tl_object_ptr<td_api::PassportDataT
vector<SecureValueType> get_secure_value_types(
vector<tl_object_ptr<telegram_api::SecureValueType>> &&secure_value_types);
vector<SecureValueType> get_secure_value_types_td_api(
vector<tl_object_ptr<td_api::PassportDataType>> &&secure_value_types);
td_api::object_ptr<td_api::PassportDataType> get_passport_data_type_object(SecureValueType type);
td_api::object_ptr<telegram_api::SecureValueType> get_secure_value_type_telegram_object(SecureValueType type);
@ -116,18 +119,42 @@ telegram_api::object_ptr<telegram_api::inputSecureValue> get_input_secure_value_
vector<td_api::object_ptr<td_api::encryptedPassportData>> get_encrypted_passport_data_object(
FileManager *file_manager, const vector<EncryptedSecureValue> &values);
struct SecureCredentials {
struct EncryptedSecureCredentials {
string data;
string hash;
string encrypted_secret;
};
bool operator==(const SecureCredentials &lhs, const SecureCredentials &rhs);
bool operator!=(const SecureCredentials &lhs, const SecureCredentials &rhs);
bool operator==(const EncryptedSecureCredentials &lhs, const EncryptedSecureCredentials &rhs);
bool operator!=(const EncryptedSecureCredentials &lhs, const EncryptedSecureCredentials &rhs);
SecureCredentials get_secure_credentials(tl_object_ptr<telegram_api::secureCredentialsEncrypted> &&credentials);
EncryptedSecureCredentials get_secure_credentials(
tl_object_ptr<telegram_api::secureCredentialsEncrypted> &&credentials);
td_api::object_ptr<td_api::encryptedCredentials> get_encrypted_credentials_object(const SecureCredentials &credentials);
telegram_api::object_ptr<telegram_api::secureCredentialsEncrypted> get_secure_credentials_encrypted_object(
const EncryptedSecureCredentials &credentials);
td_api::object_ptr<td_api::encryptedCredentials> get_encrypted_credentials_object(
const EncryptedSecureCredentials &credentials);
struct SecureDataCredentials {
string hash;
string secret;
};
struct SecureFileCredentials {
string hash;
string secret;
};
struct SecureValueCredentials {
SecureValueType type;
string hash;
optional<SecureDataCredentials> data;
std::vector<SecureFileCredentials> files;
optional<SecureFileCredentials> selfie;
};
Result<EncryptedSecureCredentials> encrypted_credentials(std::vector<SecureValueCredentials> &credentials,
Slice payload, Slice public_key);
class SecureValue {
public:
@ -137,18 +164,26 @@ class SecureValue {
FileId selfie;
};
struct SecureValueWithCredentials {
SecureValue value;
SecureValueCredentials credentials;
};
Result<SecureValue> get_secure_value(FileManager *file_manager,
td_api::object_ptr<td_api::inputPassportData> &&input_passport_data);
td_api::object_ptr<td_api::passportData> get_passport_data_object(FileManager *file_manager, const SecureValue &value);
Result<FileId> decrypt_secure_file(FileManager *file_manager, const secure_storage::Secret &secret,
const EncryptedSecureFile &secure_file);
Result<vector<FileId>> decrypt_secure_files(FileManager *file_manager, const secure_storage::Secret &secret,
const vector<EncryptedSecureFile> &secure_file);
Result<string> decrypt_secure_data(const secure_storage::Secret &secret, const EncryptedSecureData &secure_data);
Result<SecureValue> decrypt_encrypted_secure_value(FileManager *file_manager, const secure_storage::Secret &secret,
const EncryptedSecureValue &encrypted_secure_value);
Result<std::pair<FileId, SecureFileCredentials>> decrypt_secure_file(FileManager *file_manager,
const secure_storage::Secret &secret,
const EncryptedSecureFile &secure_file);
Result<std::pair<vector<FileId>, vector<SecureFileCredentials>>> decrypt_secure_files(
FileManager *file_manager, const secure_storage::Secret &secret, const vector<EncryptedSecureFile> &secure_file);
Result<std::pair<string, SecureDataCredentials>> decrypt_secure_data(const secure_storage::Secret &secret,
const EncryptedSecureData &secure_data);
Result<SecureValueWithCredentials> decrypt_encrypted_secure_value(FileManager *file_manager,
const secure_storage::Secret &secret,
const EncryptedSecureValue &encrypted_secure_value);
EncryptedSecureFile encrypt_secure_file(FileManager *file_manager, const secure_storage::Secret &master_secret,
FileId file, string &to_hash);

View File

@ -43,14 +43,14 @@ void parse(EncryptedSecureData &data, ParserT &parser) {
}
template <class StorerT>
void store(const SecureCredentials &credentials, StorerT &storer) {
void store(const EncryptedSecureCredentials &credentials, StorerT &storer) {
store(credentials.data, storer);
store(credentials.hash, storer);
store(credentials.encrypted_secret, storer);
}
template <class ParserT>
void parse(SecureCredentials &credentials, ParserT &parser) {
void parse(EncryptedSecureCredentials &credentials, ParserT &parser) {
parse(credentials.data, parser);
parse(credentials.hash, parser);
parse(credentials.encrypted_secret, parser);

View File

@ -6902,15 +6902,27 @@ void Td::on_request(uint64 id, td_api::getPassportAuthorizationForm &request) {
CLEAN_INPUT_STRING(request.password_);
CLEAN_INPUT_STRING(request.public_key_);
CLEAN_INPUT_STRING(request.scope_);
CLEAN_INPUT_STRING(request.payload_);
CREATE_REQUEST_PROMISE(promise);
send_closure(secure_manager_, &SecureManager::get_passport_authorization_form, request.password_, request.bot_id_,
request.scope_, request.public_key_, std::move(promise));
request.scope_, request.public_key_, request.payload_, std::move(promise));
}
void Td::on_request(uint64 id, const td_api::sendPassportAuthorizationForm &request) {
void Td::on_request(uint64 id, td_api::sendPassportAuthorizationForm &request) {
CHECK_AUTH();
CHECK_IS_USER();
LOG(FATAL) << "TODO";
CLEAN_INPUT_STRING(request.password_);
CREATE_REQUEST_PROMISE(promise);
auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result<> result) mutable {
if (result.is_error()) {
promise.set_error(result.move_as_error());
} else {
promise.set_value(make_tl_object<td_api::ok>());
}
});
send_closure(secure_manager_, &SecureManager::send_passport_authorization_form, request.password_,
request.autorization_form_id_, get_secure_value_types_td_api(std::move(request.types_)),
std::move(query_promise));
}
void Td::on_request(uint64 id, const td_api::getSupportUser &request) {

View File

@ -769,7 +769,7 @@ class Td final : public NetQueryCallback {
void on_request(uint64 id, td_api::getPassportAuthorizationForm &request);
void on_request(uint64 id, const td_api::sendPassportAuthorizationForm &request);
void on_request(uint64 id, td_api::sendPassportAuthorizationForm &request);
void on_request(uint64 id, const td_api::getSupportUser &request);

View File

@ -936,7 +936,7 @@ class CliClient final : public Actor {
return nullptr;
}
static tl_object_ptr<td_api::PassportDataType> as_passport_data_type(string passport_data_type) {
static tl_object_ptr<td_api::PassportDataType> as_passport_data_type(Slice passport_data_type) {
if (passport_data_type == "address" || passport_data_type == "a") {
return make_tl_object<td_api::passportDataTypeAddress>();
}
@ -952,6 +952,10 @@ class CliClient final : public Actor {
return make_tl_object<td_api::passportDataTypePassport>();
}
static auto as_passport_data_types(Slice types, char delimiter = ',') {
return transform(full_split(types, delimiter), [](Slice str) { return as_passport_data_type(str); });
}
static tl_object_ptr<td_api::inputPassportData> as_input_passport_data(string passport_data_type, string file) {
vector<td_api::object_ptr<td_api::InputFile>> files;
LOG(ERROR) << "FILE " << file;
@ -1091,9 +1095,18 @@ class CliClient final : public Actor {
string bot_id = query.arg("bot_id").str();
string scope = query.arg("scope").str();
string public_key = query.arg("public_key").str();
send_request(
make_tl_object<td_api::getPassportAuthorizationForm>(to_integer<int32>(bot_id), scope, public_key, password));
string payload = query.arg("payload").str();
LOG(ERROR) << query.arg("callback_url");
send_request(make_tl_object<td_api::getPassportAuthorizationForm>(to_integer<int32>(bot_id), scope, public_key,
payload, password));
} else if (op == "spaf") {
string password;
string id;
string types;
std::tie(password, args) = split(args);
std::tie(id, types) = split(args);
send_request(make_tl_object<td_api::sendPassportAuthorizationForm>(to_integer<int32>(id),
as_passport_data_types(types), password));
} else if (op == "srea" || op == "SetRecoveryEmailAddress") {
string password;
string recovery_email_address;

View File

@ -401,6 +401,10 @@ class Result {
CHECK(status_.is_ok()) << status_;
return value_;
}
const T &ok_ref() const {
CHECK(status_.is_ok()) << status_;
return value_;
}
T move_as_ok() {
CHECK(status_.is_ok()) << status_;
return std::move(value_);

View File

@ -19,12 +19,15 @@ class optional {
template <class T1>
optional(T1 &&t) : impl_(std::forward<T1>(t)) {
}
explicit operator bool() {
explicit operator bool() const {
return impl_.is_ok();
}
T &value() {
return impl_.ok_ref();
}
const T &value() const {
return impl_.ok_ref();
}
T &operator*() {
return value();
}