Add PasswordManager::get_password_input_settings.

This commit is contained in:
levlam 2021-06-28 19:24:44 +03:00
parent f210906dca
commit ab2223b034
2 changed files with 34 additions and 23 deletions

View File

@ -538,61 +538,69 @@ void PasswordManager::do_update_password_settings(UpdateSettings update_settings
})); }));
} }
void PasswordManager::do_update_password_settings_impl(UpdateSettings update_settings, PasswordState state, Result<tl_object_ptr<telegram_api::account_passwordInputSettings>> PasswordManager::get_password_input_settings(
PasswordPrivateState private_state, Promise<bool> promise) { const UpdateSettings &update_settings, const PasswordState &state, const PasswordPrivateState *private_state) {
auto new_settings = make_tl_object<telegram_api::account_passwordInputSettings>(); auto settings = make_tl_object<telegram_api::account_passwordInputSettings>();
bool have_secret = private_state != nullptr && private_state->secret;
auto update_secure_secret = update_settings.update_secure_secret;
if (update_settings.update_password) { if (update_settings.update_password) {
new_settings->flags_ |= telegram_api::account_passwordInputSettings::NEW_PASSWORD_HASH_MASK; settings->flags_ |= telegram_api::account_passwordInputSettings::NEW_PASSWORD_HASH_MASK;
new_settings->flags_ |= telegram_api::account_passwordInputSettings::NEW_ALGO_MASK; settings->flags_ |= telegram_api::account_passwordInputSettings::NEW_ALGO_MASK;
new_settings->flags_ |= telegram_api::account_passwordInputSettings::HINT_MASK; settings->flags_ |= telegram_api::account_passwordInputSettings::HINT_MASK;
if (!update_settings.new_password.empty()) { if (!update_settings.new_password.empty()) {
auto new_client_salt = create_salt(state.new_client_salt); auto new_client_salt = create_salt(state.new_client_salt);
auto new_hash = calc_password_srp_hash(update_settings.new_password, new_client_salt.as_slice(), auto new_hash = calc_password_srp_hash(update_settings.new_password, new_client_salt.as_slice(),
state.new_server_salt, state.new_srp_g, state.new_srp_p); state.new_server_salt, state.new_srp_g, state.new_srp_p);
if (new_hash.is_error()) { if (new_hash.is_error()) {
return promise.set_error(Status::Error(400, "Unable to change password, because it may be unsafe")); return Status::Error(400, "Unable to change password, because it may be unsafe");
} }
new_settings->new_password_hash_ = new_hash.move_as_ok(); settings->new_password_hash_ = new_hash.move_as_ok();
new_settings->new_algo_ = settings->new_algo_ =
make_tl_object<telegram_api::passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow>( make_tl_object<telegram_api::passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow>(
std::move(new_client_salt), BufferSlice(state.new_server_salt), state.new_srp_g, std::move(new_client_salt), BufferSlice(state.new_server_salt), state.new_srp_g,
BufferSlice(state.new_srp_p)); BufferSlice(state.new_srp_p));
new_settings->hint_ = std::move(update_settings.new_hint); settings->hint_ = std::move(update_settings.new_hint);
if (private_state.secret) { if (have_secret) {
update_settings.update_secure_secret = true; update_secure_secret = true;
} }
} else { } else {
new_settings->new_algo_ = make_tl_object<telegram_api::passwordKdfAlgoUnknown>(); settings->new_algo_ = make_tl_object<telegram_api::passwordKdfAlgoUnknown>();
} }
} }
// Has no password and not setting one. // have no password and not setting one
if (!update_settings.update_password && !state.has_password) { if (!update_settings.update_password && !state.has_password) {
update_settings.update_secure_secret = false; update_secure_secret = false;
} }
// Setting an empty password // setting an empty password
if (update_settings.update_password && update_settings.new_password.empty()) { if (update_settings.update_password && update_settings.new_password.empty()) {
update_settings.update_secure_secret = false; update_secure_secret = false;
} }
if (update_settings.update_secure_secret) { if (update_secure_secret) {
auto secret = private_state.secret ? std::move(private_state.secret.value()) : secure_storage::Secret::create_new(); auto secret = have_secret ? std::move(private_state->secret.value()) : secure_storage::Secret::create_new();
auto algorithm = make_tl_object<telegram_api::securePasswordKdfAlgoPBKDF2HMACSHA512iter100000>( auto algorithm = make_tl_object<telegram_api::securePasswordKdfAlgoPBKDF2HMACSHA512iter100000>(
create_salt(state.new_secure_salt)); create_salt(state.new_secure_salt));
auto encrypted_secret = secret.encrypt( auto encrypted_secret = secret.encrypt(
update_settings.update_password ? update_settings.new_password : update_settings.current_password, update_settings.update_password ? update_settings.new_password : update_settings.current_password,
algorithm->salt_.as_slice(), secure_storage::EnryptionAlgorithm::Pbkdf2); algorithm->salt_.as_slice(), secure_storage::EnryptionAlgorithm::Pbkdf2);
new_settings->flags_ |= telegram_api::account_passwordInputSettings::NEW_SECURE_SETTINGS_MASK; settings->flags_ |= telegram_api::account_passwordInputSettings::NEW_SECURE_SETTINGS_MASK;
new_settings->new_secure_settings_ = make_tl_object<telegram_api::secureSecretSettings>( settings->new_secure_settings_ = make_tl_object<telegram_api::secureSecretSettings>(
std::move(algorithm), BufferSlice(encrypted_secret.as_slice()), secret.get_hash()); std::move(algorithm), BufferSlice(encrypted_secret.as_slice()), secret.get_hash());
} }
if (update_settings.update_recovery_email_address) { if (update_settings.update_recovery_email_address) {
new_settings->flags_ |= telegram_api::account_passwordInputSettings::EMAIL_MASK; settings->flags_ |= telegram_api::account_passwordInputSettings::EMAIL_MASK;
new_settings->email_ = std::move(update_settings.recovery_email_address); settings->email_ = std::move(update_settings.recovery_email_address);
} }
return settings;
}
void PasswordManager::do_update_password_settings_impl(UpdateSettings update_settings, PasswordState state,
PasswordPrivateState private_state, Promise<bool> promise) {
TRY_RESULT_PROMISE(promise, new_settings, get_password_input_settings(update_settings, state, &private_state));
auto current_hash = get_input_check_password(state.has_password ? update_settings.current_password : Slice(), state); auto current_hash = get_input_check_password(state.has_password ? update_settings.current_password : Slice(), state);
auto query = G()->net_query_creator().create( auto query = G()->net_query_creator().create(
telegram_api::account_updatePasswordSettings(std::move(current_hash), std::move(new_settings))); telegram_api::account_updatePasswordSettings(std::move(current_hash), std::move(new_settings)));

View File

@ -170,6 +170,9 @@ class PasswordManager : public NetQueryCallback {
static tl_object_ptr<telegram_api::InputCheckPasswordSRP> get_input_check_password(Slice password, static tl_object_ptr<telegram_api::InputCheckPasswordSRP> get_input_check_password(Slice password,
const PasswordState &state); const PasswordState &state);
static Result<tl_object_ptr<telegram_api::account_passwordInputSettings>> get_password_input_settings(
const UpdateSettings &update_settings, const PasswordState &state, const PasswordPrivateState *private_state);
void update_password_settings(UpdateSettings update_settings, Promise<State> promise); void update_password_settings(UpdateSettings update_settings, Promise<State> promise);
void do_update_password_settings(UpdateSettings update_settings, PasswordFullState full_state, Promise<bool> promise); void do_update_password_settings(UpdateSettings update_settings, PasswordFullState full_state, Promise<bool> promise);
void do_update_password_settings_impl(UpdateSettings update_settings, PasswordState state, void do_update_password_settings_impl(UpdateSettings update_settings, PasswordState state,