Fix storing credentials.

GitOrigin-RevId: f621726534338e3dc198b36c1f14996f049a4cb4
This commit is contained in:
levlam 2018-04-17 15:39:23 +03:00
parent a1d6be72ff
commit 1805b770ac
4 changed files with 47 additions and 14 deletions

View File

@ -488,21 +488,49 @@ void SecureManager::get_passport_authorization_form(string password, UserId bot_
Promise<TdApiAuthorizationForm> promise) { 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_user_id, scope, public_key, payload}; authorization_forms_[authorization_form_id] =
AuthorizationForm{bot_user_id, scope, public_key, payload, false, false};
auto new_promise =
PromiseCreator::lambda([actor_id = actor_id(this), authorization_form_id, promise = std::move(promise)](
Result<TdApiAuthorizationForm> r_authorization_form) mutable {
send_closure(actor_id, &SecureManager::on_get_passport_authorization_form, authorization_form_id,
std::move(promise), std::move(r_authorization_form));
});
create_actor<GetPassportAuthorizationForm>("GetPassportAuthorizationForm", actor_shared(), std::move(password), create_actor<GetPassportAuthorizationForm>("GetPassportAuthorizationForm", actor_shared(), std::move(password),
authorization_form_id, bot_user_id, std::move(scope), authorization_form_id, bot_user_id, std::move(scope),
std::move(public_key), std::move(promise)) std::move(public_key), std::move(new_promise))
.release(); .release();
} }
void SecureManager::on_get_passport_authorization_form(int32 authorization_form_id,
Promise<TdApiAuthorizationForm> promise,
Result<TdApiAuthorizationForm> r_authorization_form) {
auto it = authorization_forms_.find(authorization_form_id);
CHECK(it != authorization_forms_.end());
CHECK(it->second.is_received == false);
if (r_authorization_form.is_error()) {
authorization_forms_.erase(it);
return promise.set_error(r_authorization_form.move_as_error());
}
it->second.is_received = true;
auto authorization_form = r_authorization_form.move_as_ok();
CHECK(authorization_form != nullptr);
it->second.is_selfie_required = authorization_form->is_selfie_required_;
promise.set_value(std::move(authorization_form));
}
void SecureManager::send_passport_authorization_form(string password, int32 authorization_form_id, void SecureManager::send_passport_authorization_form(string password, int32 authorization_form_id,
std::vector<SecureValueType> types, Promise<> promise) { std::vector<SecureValueType> types, Promise<> promise) {
auto it = authorization_forms_.find(authorization_form_id); auto it = authorization_forms_.find(authorization_form_id);
if (it == authorization_forms_.end()) { if (it == authorization_forms_.end()) {
return promise.set_error(Status::Error(400, "Unknown authorization_form_id")); return promise.set_error(Status::Error(400, "Unknown authorization_form_id"));
} }
if (!it->second.is_received) {
return promise.set_error(Status::Error(400, "Authorization form isn't received yet"));
}
if (types.empty()) { if (types.empty()) {
return promise.set_error(Status::Error(400, "Empty types")); return promise.set_error(Status::Error(400, "Types must be non-empty"));
} }
struct JoinPromise { struct JoinPromise {
@ -562,7 +590,8 @@ void SecureManager::do_send_passport_authorization_form(int32 authorization_form
BufferSlice(c.hash))); BufferSlice(c.hash)));
} }
auto r_encrypted_credentials = encrypted_credentials(credentials, it->second.payload, it->second.public_key); auto r_encrypted_credentials =
get_encrypted_credentials(credentials, it->second.payload, it->second.is_selfie_required, it->second.public_key);
if (r_encrypted_credentials.is_error()) { if (r_encrypted_credentials.is_error()) {
return promise.set_error(r_encrypted_credentials.move_as_error()); return promise.set_error(r_encrypted_credentials.move_as_error());
} }

View File

@ -144,6 +144,8 @@ class SecureManager : public NetQueryCallback {
string scope; string scope;
string public_key; string public_key;
string payload; string payload;
bool is_selfie_required;
bool is_received;
}; };
std::map<int32, AuthorizationForm> authorization_forms_; std::map<int32, AuthorizationForm> authorization_forms_;
@ -153,6 +155,8 @@ class SecureManager : public NetQueryCallback {
void hangup_shared() override; void hangup_shared() override;
void dec_refcnt(); void dec_refcnt();
void do_get_secure_value(std::string password, SecureValueType type, Promise<SecureValueWithCredentials> promise); void do_get_secure_value(std::string password, SecureValueType type, Promise<SecureValueWithCredentials> promise);
void on_get_passport_authorization_form(int32 authorization_form_id, Promise<TdApiAuthorizationForm> promise,
Result<TdApiAuthorizationForm> r_authorization_form);
void do_send_passport_authorization_form(int32 authorization_form_id, vector<SecureValueCredentials> credentials, void do_send_passport_authorization_form(int32 authorization_form_id, vector<SecureValueCredentials> credentials,
Promise<> promise); Promise<> promise);

View File

@ -981,22 +981,22 @@ static Slice secure_value_type_as_slice(SecureValueType type) {
} }
} }
static auto credentials_as_jsonable(std::vector<SecureValueCredentials> &credentials, Slice payload) { static auto credentials_as_jsonable(std::vector<SecureValueCredentials> &credentials, Slice payload, bool with_selfie) {
return json_object([&credentials, &payload](auto &o) { return json_object([&credentials, &payload, with_selfie](auto &o) {
o("secure_data", json_object([&credentials](auto &o) { o("secure_data", json_object([&credentials, with_selfie](auto &o) {
for (auto &c : credentials) { for (auto &c : credentials) {
if (c.type == SecureValueType::PhoneNumber || c.type == SecureValueType::EmailAddress) { if (c.type == SecureValueType::PhoneNumber || c.type == SecureValueType::EmailAddress) {
continue; continue;
} }
o(secure_value_type_as_slice(c.type), json_object([&credentials = c](auto &o) { o(secure_value_type_as_slice(c.type), json_object([&credentials = c, with_selfie](auto &o) {
if (credentials.data) { if (credentials.data) {
o("data", as_jsonable(credentials.data.value())); o("data", as_jsonable(credentials.data.value()));
} }
if (!credentials.files.empty()) { if (!credentials.files.empty()) {
o("files", as_jsonable(credentials.files)); o("files", as_jsonable(credentials.files));
} }
if (credentials.selfie) { if (credentials.selfie && with_selfie) {
o("selfie", as_jsonable(credentials.selfie.value())); o("selfie", as_jsonable(credentials.selfie.value()));
} }
})); }));
@ -1006,9 +1006,9 @@ static auto credentials_as_jsonable(std::vector<SecureValueCredentials> &credent
}); });
} }
Result<EncryptedSecureCredentials> encrypted_credentials(std::vector<SecureValueCredentials> &credentials, Result<EncryptedSecureCredentials> get_encrypted_credentials(std::vector<SecureValueCredentials> &credentials,
Slice payload, Slice public_key) { Slice payload, bool with_selfie, Slice public_key) {
auto encoded_credentials = json_encode<std::string>(credentials_as_jsonable(credentials, payload)); auto encoded_credentials = json_encode<std::string>(credentials_as_jsonable(credentials, payload, with_selfie));
auto secret = secure_storage::Secret::create_new(); auto secret = secure_storage::Secret::create_new();
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();

View File

@ -155,8 +155,8 @@ struct SecureValueCredentials {
optional<SecureFileCredentials> selfie; optional<SecureFileCredentials> selfie;
}; };
Result<EncryptedSecureCredentials> encrypted_credentials(std::vector<SecureValueCredentials> &credentials, Result<EncryptedSecureCredentials> get_encrypted_credentials(std::vector<SecureValueCredentials> &credentials,
Slice payload, Slice public_key); Slice payload, bool with_selfie, Slice public_key);
class SecureValue { class SecureValue {
public: public: