Add NewPasswordState struct.
This commit is contained in:
parent
3c400f12b4
commit
b35faee529
@ -371,6 +371,7 @@ set(TDLIB_SOURCE
|
|||||||
td/telegram/net/Session.cpp
|
td/telegram/net/Session.cpp
|
||||||
td/telegram/net/SessionProxy.cpp
|
td/telegram/net/SessionProxy.cpp
|
||||||
td/telegram/net/SessionMultiProxy.cpp
|
td/telegram/net/SessionMultiProxy.cpp
|
||||||
|
td/telegram/NewPasswordState.cpp
|
||||||
td/telegram/NotificationManager.cpp
|
td/telegram/NotificationManager.cpp
|
||||||
td/telegram/NotificationSettings.cpp
|
td/telegram/NotificationSettings.cpp
|
||||||
td/telegram/NotificationType.cpp
|
td/telegram/NotificationType.cpp
|
||||||
@ -564,6 +565,7 @@ set(TDLIB_SOURCE
|
|||||||
td/telegram/net/SessionProxy.h
|
td/telegram/net/SessionProxy.h
|
||||||
td/telegram/net/SessionMultiProxy.h
|
td/telegram/net/SessionMultiProxy.h
|
||||||
td/telegram/net/TempAuthKeyWatchdog.h
|
td/telegram/net/TempAuthKeyWatchdog.h
|
||||||
|
td/telegram/NewPasswordState.h
|
||||||
td/telegram/Notification.h
|
td/telegram/Notification.h
|
||||||
td/telegram/NotificationGroupId.h
|
td/telegram/NotificationGroupId.h
|
||||||
td/telegram/NotificationGroupKey.h
|
td/telegram/NotificationGroupKey.h
|
||||||
|
59
td/telegram/NewPasswordState.cpp
Normal file
59
td/telegram/NewPasswordState.cpp
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
//
|
||||||
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#include "td/telegram/NewPasswordState.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
Result<NewPasswordState> get_new_password_state(
|
||||||
|
tl_object_ptr<telegram_api::PasswordKdfAlgo> new_algo,
|
||||||
|
tl_object_ptr<telegram_api::SecurePasswordKdfAlgo> new_secure_algo) {
|
||||||
|
NewPasswordState state;
|
||||||
|
CHECK(new_algo != nullptr);
|
||||||
|
switch (new_algo->get_id()) {
|
||||||
|
case telegram_api::passwordKdfAlgoUnknown::ID:
|
||||||
|
return Status::Error(400, "Please update client to continue");
|
||||||
|
case telegram_api::passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow::ID: {
|
||||||
|
auto algo =
|
||||||
|
move_tl_object_as<telegram_api::passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow>(new_algo);
|
||||||
|
state.client_salt = algo->salt1_.as_slice().str();
|
||||||
|
state.server_salt = algo->salt2_.as_slice().str();
|
||||||
|
state.srp_g = algo->g_;
|
||||||
|
state.srp_p = algo->p_.as_slice().str();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK(new_secure_algo != nullptr);
|
||||||
|
switch (new_secure_algo->get_id()) {
|
||||||
|
case telegram_api::securePasswordKdfAlgoUnknown::ID:
|
||||||
|
return Status::Error(400, "Please update client to continue");
|
||||||
|
case telegram_api::securePasswordKdfAlgoSHA512::ID:
|
||||||
|
return Status::Error(500, "Server has sent outdated secret encryption mode");
|
||||||
|
case telegram_api::securePasswordKdfAlgoPBKDF2HMACSHA512iter100000::ID: {
|
||||||
|
auto algo = move_tl_object_as<telegram_api::securePasswordKdfAlgoPBKDF2HMACSHA512iter100000>(new_secure_algo);
|
||||||
|
state.secure_salt = algo->salt_.as_slice().str();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr size_t MIN_NEW_SECURE_SALT_SIZE = 8;
|
||||||
|
if (state.secure_salt.size() < MIN_NEW_SECURE_SALT_SIZE) {
|
||||||
|
return Status::Error(500, "New secure salt length too small");
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr size_t MIN_NEW_SALT_SIZE = 8;
|
||||||
|
if (state.client_salt.size() < MIN_NEW_SALT_SIZE) {
|
||||||
|
return Status::Error(500, "New salt length too small");
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace td
|
28
td/telegram/NewPasswordState.h
Normal file
28
td/telegram/NewPasswordState.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
//
|
||||||
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/telegram/telegram_api.h"
|
||||||
|
|
||||||
|
#include "td/utils/common.h"
|
||||||
|
#include "td/utils/Status.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
struct NewPasswordState {
|
||||||
|
string client_salt;
|
||||||
|
string server_salt;
|
||||||
|
string srp_p;
|
||||||
|
string secure_salt;
|
||||||
|
int32 srp_g = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
Result<NewPasswordState> get_new_password_state(
|
||||||
|
tl_object_ptr<telegram_api::PasswordKdfAlgo> new_algo,
|
||||||
|
tl_object_ptr<telegram_api::SecurePasswordKdfAlgo> new_secure_algo);
|
||||||
|
|
||||||
|
} // namespace td
|
@ -496,7 +496,9 @@ void PasswordManager::recover_password(string code, string new_password, string
|
|||||||
return promise.set_error(r_state.move_as_error());
|
return promise.set_error(r_state.move_as_error());
|
||||||
}
|
}
|
||||||
|
|
||||||
TRY_RESULT_PROMISE(promise, new_settings, get_password_input_settings(update_settings, r_state.ok(), nullptr));
|
TRY_RESULT_PROMISE(
|
||||||
|
promise, new_settings,
|
||||||
|
get_password_input_settings(update_settings, r_state.ok().has_password, r_state.ok().new_state, nullptr));
|
||||||
|
|
||||||
send_closure(actor_id, &PasswordManager::do_recover_password, std::move(code), std::move(new_settings),
|
send_closure(actor_id, &PasswordManager::do_recover_password, std::move(code), std::move(new_settings),
|
||||||
std::move(promise));
|
std::move(promise));
|
||||||
@ -568,7 +570,8 @@ void PasswordManager::do_update_password_settings(UpdateSettings update_settings
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result<PasswordManager::PasswordInputSettings> PasswordManager::get_password_input_settings(
|
Result<PasswordManager::PasswordInputSettings> PasswordManager::get_password_input_settings(
|
||||||
const UpdateSettings &update_settings, const PasswordState &state, const PasswordPrivateState *private_state) {
|
const UpdateSettings &update_settings, bool has_password, const NewPasswordState &state,
|
||||||
|
const PasswordPrivateState *private_state) {
|
||||||
auto 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;
|
bool have_secret = private_state != nullptr && private_state->secret;
|
||||||
auto update_secure_secret = update_settings.update_secure_secret;
|
auto update_secure_secret = update_settings.update_secure_secret;
|
||||||
@ -577,18 +580,17 @@ Result<PasswordManager::PasswordInputSettings> PasswordManager::get_password_inp
|
|||||||
settings->flags_ |= telegram_api::account_passwordInputSettings::NEW_ALGO_MASK;
|
settings->flags_ |= telegram_api::account_passwordInputSettings::NEW_ALGO_MASK;
|
||||||
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.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.server_salt, state.srp_g, state.srp_p);
|
||||||
if (new_hash.is_error()) {
|
if (new_hash.is_error()) {
|
||||||
return 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");
|
||||||
}
|
}
|
||||||
settings->new_password_hash_ = new_hash.move_as_ok();
|
settings->new_password_hash_ = new_hash.move_as_ok();
|
||||||
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.server_salt), state.srp_g, BufferSlice(state.srp_p));
|
||||||
BufferSlice(state.new_srp_p));
|
|
||||||
settings->hint_ = std::move(update_settings.new_hint);
|
settings->hint_ = std::move(update_settings.new_hint);
|
||||||
if (have_secret) {
|
if (have_secret) {
|
||||||
update_secure_secret = true;
|
update_secure_secret = true;
|
||||||
@ -599,7 +601,7 @@ Result<PasswordManager::PasswordInputSettings> PasswordManager::get_password_inp
|
|||||||
}
|
}
|
||||||
|
|
||||||
// have 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 && !has_password) {
|
||||||
update_secure_secret = false;
|
update_secure_secret = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -610,8 +612,8 @@ Result<PasswordManager::PasswordInputSettings> PasswordManager::get_password_inp
|
|||||||
|
|
||||||
if (update_secure_secret) {
|
if (update_secure_secret) {
|
||||||
auto secret = have_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 =
|
||||||
create_salt(state.new_secure_salt));
|
make_tl_object<telegram_api::securePasswordKdfAlgoPBKDF2HMACSHA512iter100000>(create_salt(state.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);
|
||||||
@ -629,7 +631,8 @@ Result<PasswordManager::PasswordInputSettings> PasswordManager::get_password_inp
|
|||||||
|
|
||||||
void PasswordManager::do_update_password_settings_impl(UpdateSettings update_settings, PasswordState state,
|
void PasswordManager::do_update_password_settings_impl(UpdateSettings update_settings, PasswordState state,
|
||||||
PasswordPrivateState private_state, Promise<bool> promise) {
|
PasswordPrivateState private_state, Promise<bool> promise) {
|
||||||
TRY_RESULT_PROMISE(promise, new_settings, get_password_input_settings(update_settings, state, &private_state));
|
TRY_RESULT_PROMISE(promise, new_settings,
|
||||||
|
get_password_input_settings(update_settings, state.has_password, state.new_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)));
|
||||||
@ -718,46 +721,11 @@ void PasswordManager::do_get_state(Promise<PasswordState> promise) {
|
|||||||
state.unconfirmed_recovery_email_address_pattern = std::move(password->email_unconfirmed_pattern_);
|
state.unconfirmed_recovery_email_address_pattern = std::move(password->email_unconfirmed_pattern_);
|
||||||
state.code_length = code_length;
|
state.code_length = code_length;
|
||||||
|
|
||||||
CHECK(password->new_algo_ != nullptr);
|
auto &new_state = state.new_state;
|
||||||
switch (password->new_algo_->get_id()) {
|
TRY_RESULT_PROMISE_ASSIGN(
|
||||||
case telegram_api::passwordKdfAlgoUnknown::ID:
|
promise, new_state,
|
||||||
return promise.set_error(Status::Error(400, "Please update client to continue"));
|
get_new_password_state(std::move(password->new_algo_), std::move(password->new_secure_algo_)));
|
||||||
case telegram_api::passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow::ID: {
|
|
||||||
auto algo =
|
|
||||||
move_tl_object_as<telegram_api::passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow>(
|
|
||||||
password->new_algo_);
|
|
||||||
state.new_client_salt = algo->salt1_.as_slice().str();
|
|
||||||
state.new_server_salt = algo->salt2_.as_slice().str();
|
|
||||||
state.new_srp_g = algo->g_;
|
|
||||||
state.new_srp_p = algo->p_.as_slice().str();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
CHECK(password->new_secure_algo_ != nullptr);
|
|
||||||
switch (password->new_secure_algo_->get_id()) {
|
|
||||||
case telegram_api::securePasswordKdfAlgoUnknown::ID:
|
|
||||||
return promise.set_error(Status::Error(400, "Please update client to continue"));
|
|
||||||
case telegram_api::securePasswordKdfAlgoSHA512::ID:
|
|
||||||
return promise.set_error(Status::Error(500, "Server has sent outdated secret encryption mode"));
|
|
||||||
case telegram_api::securePasswordKdfAlgoPBKDF2HMACSHA512iter100000::ID: {
|
|
||||||
auto algo = move_tl_object_as<telegram_api::securePasswordKdfAlgoPBKDF2HMACSHA512iter100000>(
|
|
||||||
password->new_secure_algo_);
|
|
||||||
state.new_secure_salt = algo->salt_.as_slice().str();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.new_secure_salt.size() < MIN_NEW_SECURE_SALT_SIZE) {
|
|
||||||
return promise.set_error(Status::Error(500, "New secure salt length too small"));
|
|
||||||
}
|
|
||||||
if (state.new_client_salt.size() < MIN_NEW_SALT_SIZE) {
|
|
||||||
return promise.set_error(Status::Error(500, "New salt length too small"));
|
|
||||||
}
|
|
||||||
promise.set_value(std::move(state));
|
promise.set_value(std::move(state));
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "td/telegram/net/NetQuery.h"
|
#include "td/telegram/net/NetQuery.h"
|
||||||
|
#include "td/telegram/NewPasswordState.h"
|
||||||
#include "td/telegram/SecureStorage.h"
|
#include "td/telegram/SecureStorage.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"
|
||||||
@ -90,9 +91,6 @@ class PasswordManager : public NetQueryCallback {
|
|||||||
static TempPasswordState get_temp_password_state_sync();
|
static TempPasswordState get_temp_password_state_sync();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr size_t MIN_NEW_SALT_SIZE = 8;
|
|
||||||
static constexpr size_t MIN_NEW_SECURE_SALT_SIZE = 8;
|
|
||||||
|
|
||||||
ActorShared<> parent_;
|
ActorShared<> parent_;
|
||||||
|
|
||||||
struct PasswordState {
|
struct PasswordState {
|
||||||
@ -109,12 +107,8 @@ class PasswordManager : public NetQueryCallback {
|
|||||||
string current_srp_p;
|
string current_srp_p;
|
||||||
string current_srp_B;
|
string current_srp_B;
|
||||||
int64 current_srp_id;
|
int64 current_srp_id;
|
||||||
string new_client_salt;
|
|
||||||
string new_server_salt;
|
|
||||||
int32 new_srp_g;
|
|
||||||
string new_srp_p;
|
|
||||||
|
|
||||||
string new_secure_salt;
|
NewPasswordState new_state;
|
||||||
|
|
||||||
State get_password_state_object() const {
|
State get_password_state_object() const {
|
||||||
td_api::object_ptr<td_api::emailAddressAuthenticationCodeInfo> code_info;
|
td_api::object_ptr<td_api::emailAddressAuthenticationCodeInfo> code_info;
|
||||||
@ -172,7 +166,7 @@ class PasswordManager : public NetQueryCallback {
|
|||||||
const PasswordState &state);
|
const PasswordState &state);
|
||||||
|
|
||||||
static Result<PasswordInputSettings> get_password_input_settings(const UpdateSettings &update_settings,
|
static Result<PasswordInputSettings> get_password_input_settings(const UpdateSettings &update_settings,
|
||||||
const PasswordState &state,
|
bool has_password, const NewPasswordState &state,
|
||||||
const PasswordPrivateState *private_state);
|
const PasswordPrivateState *private_state);
|
||||||
|
|
||||||
void do_recover_password(string code, PasswordInputSettings &&new_settings, Promise<State> &&promise);
|
void do_recover_password(string code, PasswordInputSettings &&new_settings, Promise<State> &&promise);
|
||||||
|
Loading…
Reference in New Issue
Block a user