blob: 7f05601c617981d43acfad0b85ecf2856efbde95 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_SYNC_NIGORI_NIGORI_SYNC_BRIDGE_IMPL_H_
#define COMPONENTS_SYNC_NIGORI_NIGORI_SYNC_BRIDGE_IMPL_H_
#include <memory>
#include <string>
#include <vector>
#include "base/callback.h"
#include "base/macros.h"
#include "base/observer_list.h"
#include "base/optional.h"
#include "base/sequence_checker.h"
#include "base/time/time.h"
#include "components/sync/engine/sync_encryption_handler.h"
#include "components/sync/model/conflict_resolution.h"
#include "components/sync/model/model_error.h"
#include "components/sync/nigori/cryptographer_impl.h"
#include "components/sync/nigori/keystore_keys_handler.h"
#include "components/sync/nigori/nigori_local_change_processor.h"
#include "components/sync/nigori/nigori_state.h"
#include "components/sync/nigori/nigori_sync_bridge.h"
namespace sync_pb {
class NigoriLocalData;
} // namespace sync_pb
namespace syncer {
class Encryptor;
class NigoriStorage;
// USS implementation of SyncEncryptionHandler.
// This class holds the current Nigori state and processes incoming changes and
// queries:
// 1. Serves observers of SyncEncryptionHandler interface.
// 2. Allows the passphrase manipulations (via SyncEncryptionHandler).
// 3. Communicates local and remote changes with a processor (via
// NigoriSyncBridge).
// 4. Handles keystore keys from a sync server (via KeystoreKeysHandler).
class NigoriSyncBridgeImpl : public KeystoreKeysHandler,
public NigoriSyncBridge,
public SyncEncryptionHandler {
public:
// |encryptor| must be not null and must outlive this object.
NigoriSyncBridgeImpl(
std::unique_ptr<NigoriLocalChangeProcessor> processor,
std::unique_ptr<NigoriStorage> storage,
const Encryptor* encryptor,
const base::RepeatingCallback<std::string()>& random_salt_generator,
const std::string& packed_explicit_passphrase_key);
~NigoriSyncBridgeImpl() override;
// SyncEncryptionHandler implementation.
void AddObserver(Observer* observer) override;
void RemoveObserver(Observer* observer) override;
bool Init() override;
void SetEncryptionPassphrase(const std::string& passphrase) override;
void SetDecryptionPassphrase(const std::string& passphrase) override;
void AddTrustedVaultDecryptionKeys(
const std::vector<std::string>& keys) override;
void EnableEncryptEverything() override;
bool IsEncryptEverythingEnabled() const override;
base::Time GetKeystoreMigrationTime() const override;
KeystoreKeysHandler* GetKeystoreKeysHandler() override;
// KeystoreKeysHandler implementation.
bool NeedKeystoreKey() const override;
bool SetKeystoreKeys(const std::vector<std::string>& keys) override;
// NigoriSyncBridge implementation.
base::Optional<ModelError> MergeSyncData(
base::Optional<EntityData> data) override;
base::Optional<ModelError> ApplySyncChanges(
base::Optional<EntityData> data) override;
std::unique_ptr<EntityData> GetData() override;
ConflictResolution ResolveConflict(const EntityData& local_data,
const EntityData& remote_data) override;
void ApplyDisableSyncChanges() override;
// TODO(crbug.com/922900): investigate whether we need this getter outside of
// tests and decide whether this method should be a part of
// SyncEncryptionHandler interface.
const Cryptographer& GetCryptographerForTesting() const;
sync_pb::NigoriSpecifics::PassphraseType GetPassphraseTypeForTesting() const;
ModelTypeSet GetEncryptedTypesForTesting() const;
bool HasPendingKeysForTesting() const;
static std::string PackExplicitPassphraseKeyForTesting(
const Encryptor& encryptor,
const CryptographerImpl& cryptographer);
private:
base::Optional<ModelError> UpdateLocalState(
const sync_pb::NigoriSpecifics& specifics);
base::Optional<ModelError> UpdateCryptographerFromKeystoreNigori(
const sync_pb::EncryptedData& encryption_keybag,
const sync_pb::EncryptedData& keystore_decryptor_token);
void UpdateCryptographerFromNonKeystoreNigori(
const sync_pb::EncryptedData& keybag);
// Uses the cryptographer to try to decrypt pending keys. If success, the
// newly decrypted keys are put in the cryptographer's keybag, pending keys
// are cleared and the function returns true. Otherwise, it returns false and
// the state remains unchanged. It does not change the default key.
bool TryDecryptPendingKeys();
base::Time GetExplicitPassphraseTime() const;
// Returns key derivation params based on |passphrase_type_| and
// |custom_passphrase_key_derivation_params_|. Should be called only if
// |passphrase_type_| is an explicit passphrase.
KeyDerivationParams GetKeyDerivationParamsForPendingKeys() const;
// Persists Nigori derived from explicit passphrase into preferences, in case
// error occurs during serialization/encryption, corresponding preference
// just won't be updated.
void MaybeNotifyBootstrapTokenUpdated() const;
// Serializes state of the bridge and sync metadata into the proto.
sync_pb::NigoriLocalData SerializeAsNigoriLocalData() const;
const Encryptor* const encryptor_;
const std::unique_ptr<NigoriLocalChangeProcessor> processor_;
const std::unique_ptr<NigoriStorage> storage_;
// Used for generation of random salt for deriving keys from custom
// passphrase if SCRYPT is enabled.
const base::RepeatingCallback<std::string()> random_salt_generator_;
// Stores a key derived from explicit passphrase and loaded from the prefs.
// Empty (i.e. default value) if prefs doesn't contain this key or in case of
// decryption/decoding errors.
const sync_pb::NigoriKey explicit_passphrase_key_;
syncer::NigoriState state_;
// TODO(crbug/922900): consider using checked ObserverList once
// SyncEncryptionHandlerImpl is no longer needed or consider refactoring old
// implementation to use checked ObserverList as well.
base::ObserverList<SyncEncryptionHandler::Observer>::Unchecked observers_;
SEQUENCE_CHECKER(sequence_checker_);
DISALLOW_COPY_AND_ASSIGN(NigoriSyncBridgeImpl);
};
} // namespace syncer
#endif // COMPONENTS_SYNC_NIGORI_NIGORI_SYNC_BRIDGE_IMPL_H_