Commit f98299a8 authored by Mikel Astiz's avatar Mikel Astiz Committed by Commit Bot

Treat pending trusted vault keys as crypto errors

Prior to this patch, DataTypeManagerImpl::Restart() used
IsPassphraseRequired() as the way to determine whether encrypted
datatypes should enter the crypto-error state.

This patch generalizes the concept to accomodate the
trusted-vault-keys case, which doesn't have a corresponding API to
IsPassphraseRequired().

To achieve this without poluting the public APIs,
DataTypeEncryptionHandler is decoupled from SyncUserSettings.

Bug: 1010189
Change-Id: Ia75f30d11d0c9077c301d6245ac51b5a810b5a7a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1873753
Commit-Queue: Mikel Astiz <mastiz@chromium.org>
Reviewed-by: default avatarMarc Treib <treib@chromium.org>
Cr-Commit-Position: refs/heads/master@{#708622}
parent 255216ea
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "chrome/browser/sync/test/integration/encryption_helper.h" #include "chrome/browser/sync/test/integration/encryption_helper.h"
#include "chrome/browser/sync/test/integration/passwords_helper.h" #include "chrome/browser/sync/test/integration/passwords_helper.h"
#include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
#include "chrome/browser/sync/test/integration/single_client_status_change_checker.h"
#include "chrome/browser/sync/test/integration/status_change_checker.h" #include "chrome/browser/sync/test/integration/status_change_checker.h"
#include "chrome/browser/sync/test/integration/sync_test.h" #include "chrome/browser/sync/test/integration/sync_test.h"
#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser.h"
...@@ -164,6 +165,25 @@ class PageTitleChecker : public StatusChangeChecker, ...@@ -164,6 +165,25 @@ class PageTitleChecker : public StatusChangeChecker,
DISALLOW_COPY_AND_ASSIGN(PageTitleChecker); DISALLOW_COPY_AND_ASSIGN(PageTitleChecker);
}; };
class PasswordsDataTypeActiveChecker : public SingleClientStatusChangeChecker {
public:
explicit PasswordsDataTypeActiveChecker(syncer::ProfileSyncService* service)
: SingleClientStatusChangeChecker(service) {}
~PasswordsDataTypeActiveChecker() override {}
// StatusChangeChecker implementation.
bool IsExitConditionSatisfied() override {
return service()->GetActiveDataTypes().Has(syncer::PASSWORDS);
}
std::string GetDebugMessage() const override {
return "Waiting for PASSWORDS to become active";
}
private:
DISALLOW_COPY_AND_ASSIGN(PasswordsDataTypeActiveChecker);
};
class SingleClientNigoriSyncTestWithUssTests class SingleClientNigoriSyncTestWithUssTests
: public SyncTest, : public SyncTest,
public testing::WithParamInterface<bool> { public testing::WithParamInterface<bool> {
...@@ -379,6 +399,7 @@ IN_PROC_BROWSER_TEST_F(SingleClientNigoriWithWebApiTest, ...@@ -379,6 +399,7 @@ IN_PROC_BROWSER_TEST_F(SingleClientNigoriWithWebApiTest,
ASSERT_TRUE(TrustedVaultKeyRequiredStateChecker(GetSyncService(0), ASSERT_TRUE(TrustedVaultKeyRequiredStateChecker(GetSyncService(0),
/*desired_state=*/true) /*desired_state=*/true)
.Wait()); .Wait());
ASSERT_FALSE(GetSyncService(0)->GetActiveDataTypes().Has(syncer::PASSWORDS));
// Mimic opening a web page where the user can interact with the retrieval // Mimic opening a web page where the user can interact with the retrieval
// flow. // flow.
...@@ -393,9 +414,10 @@ IN_PROC_BROWSER_TEST_F(SingleClientNigoriWithWebApiTest, ...@@ -393,9 +414,10 @@ IN_PROC_BROWSER_TEST_F(SingleClientNigoriWithWebApiTest,
GetBrowser(0)->tab_strip_model()->GetActiveWebContents()); GetBrowser(0)->tab_strip_model()->GetActiveWebContents());
EXPECT_TRUE(title_checker.Wait()); EXPECT_TRUE(title_checker.Wait());
ASSERT_TRUE(TrustedVaultKeyRequiredStateChecker(GetSyncService(0), EXPECT_TRUE(TrustedVaultKeyRequiredStateChecker(GetSyncService(0),
/*desired_state=*/false) /*desired_state=*/false)
.Wait()); .Wait());
EXPECT_TRUE(PasswordsDataTypeActiveChecker(GetSyncService(0)).Wait());
} }
IN_PROC_BROWSER_TEST_F(SingleClientNigoriWithWebApiTest, IN_PROC_BROWSER_TEST_F(SingleClientNigoriWithWebApiTest,
...@@ -436,6 +458,7 @@ IN_PROC_BROWSER_TEST_F(SingleClientNigoriWithWebApiTest, ...@@ -436,6 +458,7 @@ IN_PROC_BROWSER_TEST_F(SingleClientNigoriWithWebApiTest,
EXPECT_FALSE(GetSyncService(0) EXPECT_FALSE(GetSyncService(0)
->GetUserSettings() ->GetUserSettings()
->IsTrustedVaultKeyRequiredForPreferredDataTypes()); ->IsTrustedVaultKeyRequiredForPreferredDataTypes());
EXPECT_TRUE(GetSyncService(0)->GetActiveDataTypes().Has(syncer::PASSWORDS));
} }
// Same as SingleClientNigoriWithWebApiTest but does NOT override // Same as SingleClientNigoriWithWebApiTest but does NOT override
......
...@@ -15,9 +15,11 @@ class DataTypeEncryptionHandler { ...@@ -15,9 +15,11 @@ class DataTypeEncryptionHandler {
DataTypeEncryptionHandler(); DataTypeEncryptionHandler();
virtual ~DataTypeEncryptionHandler(); virtual ~DataTypeEncryptionHandler();
// Returns whether a passphrase is required for encryption or decryption to // Returns whether there is an error that prevents encryption or decryption
// proceed. // from proceeding. This does not necessarily mean that the UI will display an
virtual bool IsPassphraseRequired() const = 0; // error state, for example if there's a user-transparent attempt to resolve
// the crypto error.
virtual bool HasCryptoError() const = 0;
// Returns the current set of encrypted data types. // Returns the current set of encrypted data types.
virtual ModelTypeSet GetEncryptedDataTypes() const = 0; virtual ModelTypeSet GetEncryptedDataTypes() const = 0;
......
...@@ -302,7 +302,7 @@ void DataTypeManagerImpl::Restart() { ...@@ -302,7 +302,7 @@ void DataTypeManagerImpl::Restart() {
} }
// Check for new or resolved data type crypto errors. // Check for new or resolved data type crypto errors.
if (encryption_handler_->IsPassphraseRequired()) { if (encryption_handler_->HasCryptoError()) {
ModelTypeSet encrypted_types = encryption_handler_->GetEncryptedDataTypes(); ModelTypeSet encrypted_types = encryption_handler_->GetEncryptedDataTypes();
encrypted_types.RetainAll(last_requested_types_); encrypted_types.RetainAll(last_requested_types_);
encrypted_types.RemoveAll(data_type_status_table_.GetCryptoErrorTypes()); encrypted_types.RemoveAll(data_type_status_table_.GetCryptoErrorTypes());
......
...@@ -180,27 +180,25 @@ class FakeDataTypeEncryptionHandler : public DataTypeEncryptionHandler { ...@@ -180,27 +180,25 @@ class FakeDataTypeEncryptionHandler : public DataTypeEncryptionHandler {
FakeDataTypeEncryptionHandler(); FakeDataTypeEncryptionHandler();
~FakeDataTypeEncryptionHandler() override; ~FakeDataTypeEncryptionHandler() override;
bool IsPassphraseRequired() const override; bool HasCryptoError() const override;
ModelTypeSet GetEncryptedDataTypes() const override; ModelTypeSet GetEncryptedDataTypes() const override;
void set_passphrase_required(bool passphrase_required) { void set_crypto_error(bool crypto_error) { crypto_error_ = crypto_error; }
passphrase_required_ = passphrase_required;
}
void set_encrypted_types(ModelTypeSet encrypted_types) { void set_encrypted_types(ModelTypeSet encrypted_types) {
encrypted_types_ = encrypted_types; encrypted_types_ = encrypted_types;
} }
private: private:
bool passphrase_required_; bool crypto_error_;
ModelTypeSet encrypted_types_; ModelTypeSet encrypted_types_;
}; };
FakeDataTypeEncryptionHandler::FakeDataTypeEncryptionHandler() FakeDataTypeEncryptionHandler::FakeDataTypeEncryptionHandler()
: passphrase_required_(false) {} : crypto_error_(false) {}
FakeDataTypeEncryptionHandler::~FakeDataTypeEncryptionHandler() {} FakeDataTypeEncryptionHandler::~FakeDataTypeEncryptionHandler() {}
bool FakeDataTypeEncryptionHandler::IsPassphraseRequired() const { bool FakeDataTypeEncryptionHandler::HasCryptoError() const {
return passphrase_required_; return crypto_error_;
} }
ModelTypeSet FakeDataTypeEncryptionHandler::GetEncryptedDataTypes() const { ModelTypeSet FakeDataTypeEncryptionHandler::GetEncryptedDataTypes() const {
...@@ -321,7 +319,7 @@ class SyncDataTypeManagerImplTest : public testing::Test { ...@@ -321,7 +319,7 @@ class SyncDataTypeManagerImplTest : public testing::Test {
} }
void FailEncryptionFor(ModelTypeSet encrypted_types) { void FailEncryptionFor(ModelTypeSet encrypted_types) {
encryption_handler_.set_passphrase_required(true); encryption_handler_.set_crypto_error(true);
encryption_handler_.set_encrypted_types(encrypted_types); encryption_handler_.set_encrypted_types(encrypted_types);
} }
......
...@@ -864,8 +864,8 @@ void ProfileSyncService::OnEngineInitialized( ...@@ -864,8 +864,8 @@ void ProfileSyncService::OnEngineInitialized(
data_type_manager_ = data_type_manager_ =
sync_client_->GetSyncApiComponentFactory()->CreateDataTypeManager( sync_client_->GetSyncApiComponentFactory()->CreateDataTypeManager(
initial_types, debug_info_listener, &data_type_controllers_, initial_types, debug_info_listener, &data_type_controllers_, &crypto_,
user_settings_.get(), engine_.get(), this); engine_.get(), this);
crypto_.SetSyncEngine(GetAuthenticatedAccountInfo(), engine_.get()); crypto_.SetSyncEngine(GetAuthenticatedAccountInfo(), engine_.get());
......
...@@ -340,6 +340,27 @@ ModelTypeSet SyncServiceCrypto::GetEncryptedDataTypes() const { ...@@ -340,6 +340,27 @@ ModelTypeSet SyncServiceCrypto::GetEncryptedDataTypes() const {
return state_.encrypted_types; return state_.encrypted_types;
} }
bool SyncServiceCrypto::HasCryptoError() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// This determines whether DataTypeManager should issue crypto errors for
// encrypted datatypes. This may differ from whether the UI represents the
// error state or not.
switch (state_.required_user_action) {
case RequiredUserAction::kNone:
return false;
case RequiredUserAction::kFetchingTrustedVaultKeys:
case RequiredUserAction::kTrustedVaultKeyRequired:
case RequiredUserAction::kPassphraseRequiredForDecryption:
case RequiredUserAction::kPassphraseRequiredForEncryption:
return true;
}
NOTREACHED();
return false;
}
void SyncServiceCrypto::OnPassphraseRequired( void SyncServiceCrypto::OnPassphraseRequired(
PassphraseRequiredReason reason, PassphraseRequiredReason reason,
const KeyDerivationParams& key_derivation_params, const KeyDerivationParams& key_derivation_params,
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "base/sequence_checker.h" #include "base/sequence_checker.h"
#include "components/signin/public/identity_manager/account_info.h" #include "components/signin/public/identity_manager/account_info.h"
#include "components/sync/base/model_type.h" #include "components/sync/base/model_type.h"
#include "components/sync/driver/data_type_encryption_handler.h"
#include "components/sync/engine/configure_reason.h" #include "components/sync/engine/configure_reason.h"
#include "components/sync/engine/sync_encryption_handler.h" #include "components/sync/engine/sync_encryption_handler.h"
#include "components/sync/engine/sync_engine.h" #include "components/sync/engine/sync_engine.h"
...@@ -26,7 +27,8 @@ class TrustedVaultClient; ...@@ -26,7 +27,8 @@ class TrustedVaultClient;
// This class functions as mostly independent component of SyncService that // This class functions as mostly independent component of SyncService that
// handles things related to encryption, including holding lots of state and // handles things related to encryption, including holding lots of state and
// encryption communications with the sync thread. // encryption communications with the sync thread.
class SyncServiceCrypto : public SyncEncryptionHandler::Observer { class SyncServiceCrypto : public SyncEncryptionHandler::Observer,
public DataTypeEncryptionHandler {
public: public:
// |sync_prefs| must not be null and must outlive this object. // |sync_prefs| must not be null and must outlive this object.
// |trusted_vault_client| may be null, but if non-null, the pointee must // |trusted_vault_client| may be null, but if non-null, the pointee must
...@@ -55,9 +57,6 @@ class SyncServiceCrypto : public SyncEncryptionHandler::Observer { ...@@ -55,9 +57,6 @@ class SyncServiceCrypto : public SyncEncryptionHandler::Observer {
// Returns the actual passphrase type being used for encryption. // Returns the actual passphrase type being used for encryption.
PassphraseType GetPassphraseType() const; PassphraseType GetPassphraseType() const;
// Returns the current set of encrypted data types.
ModelTypeSet GetEncryptedDataTypes() const;
// SyncEncryptionHandler::Observer implementation. // SyncEncryptionHandler::Observer implementation.
void OnPassphraseRequired( void OnPassphraseRequired(
PassphraseRequiredReason reason, PassphraseRequiredReason reason,
...@@ -76,6 +75,10 @@ class SyncServiceCrypto : public SyncEncryptionHandler::Observer { ...@@ -76,6 +75,10 @@ class SyncServiceCrypto : public SyncEncryptionHandler::Observer {
void OnPassphraseTypeChanged(PassphraseType type, void OnPassphraseTypeChanged(PassphraseType type,
base::Time passphrase_time) override; base::Time passphrase_time) override;
// DataTypeEncryptionHandler implementation.
bool HasCryptoError() const override;
ModelTypeSet GetEncryptedDataTypes() const override;
// Used to provide the engine when it is initialized. // Used to provide the engine when it is initialized.
void SetSyncEngine(const CoreAccountInfo& account_info, SyncEngine* engine); void SetSyncEngine(const CoreAccountInfo& account_info, SyncEngine* engine);
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
#include "components/sync/base/model_type.h" #include "components/sync/base/model_type.h"
#include "components/sync/base/passphrase_enums.h" #include "components/sync/base/passphrase_enums.h"
#include "components/sync/base/user_selectable_type.h" #include "components/sync/base/user_selectable_type.h"
#include "components/sync/driver/data_type_encryption_handler.h"
namespace syncer { namespace syncer {
...@@ -30,9 +29,9 @@ enum class SyncFirstSetupCompleteSource { ...@@ -30,9 +29,9 @@ enum class SyncFirstSetupCompleteSource {
}; };
// This class encapsulates all the user-configurable bits of Sync. // This class encapsulates all the user-configurable bits of Sync.
class SyncUserSettings : public syncer::DataTypeEncryptionHandler { class SyncUserSettings {
public: public:
~SyncUserSettings() override = default; virtual ~SyncUserSettings() = default;
// Whether the user wants Sync to run. This is false by default, but gets set // Whether the user wants Sync to run. This is false by default, but gets set
// to true early in the Sync setup flow, after the user has pressed "turn on // to true early in the Sync setup flow, after the user has pressed "turn on
...@@ -87,11 +86,11 @@ class SyncUserSettings : public syncer::DataTypeEncryptionHandler { ...@@ -87,11 +86,11 @@ class SyncUserSettings : public syncer::DataTypeEncryptionHandler {
virtual void EnableEncryptEverything() = 0; virtual void EnableEncryptEverything() = 0;
// The current set of encrypted data types. // The current set of encrypted data types.
ModelTypeSet GetEncryptedDataTypes() const override = 0; virtual ModelTypeSet GetEncryptedDataTypes() const = 0;
// Whether a passphrase is required for encryption or decryption to proceed. // Whether a passphrase is required for encryption or decryption to proceed.
// Note that Sync might still be working fine if the user has disabled all // Note that Sync might still be working fine if the user has disabled all
// encrypted data types. // encrypted data types.
bool IsPassphraseRequired() const override = 0; virtual bool IsPassphraseRequired() const = 0;
// Whether a passphrase is required to decrypt the data for any currently // Whether a passphrase is required to decrypt the data for any currently
// enabled data type. // enabled data type.
virtual bool IsPassphraseRequiredForPreferredDataTypes() const = 0; virtual bool IsPassphraseRequiredForPreferredDataTypes() const = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment