1 // Copyright 2019 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef COMPONENTS_SYNC_NIGORI_NIGORI_SYNC_BRIDGE_IMPL_H_ 6 #define COMPONENTS_SYNC_NIGORI_NIGORI_SYNC_BRIDGE_IMPL_H_ 7 8 #include <list> 9 #include <memory> 10 #include <string> 11 #include <vector> 12 13 #include "base/callback.h" 14 #include "base/macros.h" 15 #include "base/observer_list.h" 16 #include "base/optional.h" 17 #include "base/sequence_checker.h" 18 #include "base/time/time.h" 19 #include "components/sync/engine/sync_encryption_handler.h" 20 #include "components/sync/model/conflict_resolution.h" 21 #include "components/sync/model/model_error.h" 22 #include "components/sync/nigori/cryptographer_impl.h" 23 #include "components/sync/nigori/keystore_keys_handler.h" 24 #include "components/sync/nigori/nigori_local_change_processor.h" 25 #include "components/sync/nigori/nigori_state.h" 26 #include "components/sync/nigori/nigori_sync_bridge.h" 27 28 namespace sync_pb { 29 class NigoriLocalData; 30 } // namespace sync_pb 31 32 namespace syncer { 33 34 class Encryptor; 35 class KeyDerivationParams; 36 class NigoriStorage; 37 class PendingLocalNigoriCommit; 38 39 // USS implementation of SyncEncryptionHandler. 40 // This class holds the current Nigori state and processes incoming changes and 41 // queries: 42 // 1. Serves observers of SyncEncryptionHandler interface. 43 // 2. Allows the passphrase manipulations (via SyncEncryptionHandler). 44 // 3. Communicates local and remote changes with a processor (via 45 // NigoriSyncBridge). 46 // 4. Handles keystore keys from a sync server (via KeystoreKeysHandler). 47 class NigoriSyncBridgeImpl : public KeystoreKeysHandler, 48 public NigoriSyncBridge, 49 public SyncEncryptionHandler { 50 public: 51 // |encryptor| must be not null and must outlive this object. 52 NigoriSyncBridgeImpl( 53 std::unique_ptr<NigoriLocalChangeProcessor> processor, 54 std::unique_ptr<NigoriStorage> storage, 55 const Encryptor* encryptor, 56 const base::RepeatingCallback<std::string()>& random_salt_generator, 57 const std::string& packed_explicit_passphrase_key, 58 const std::string& packed_keystore_keys); 59 ~NigoriSyncBridgeImpl() override; 60 61 // SyncEncryptionHandler implementation. 62 void AddObserver(Observer* observer) override; 63 void RemoveObserver(Observer* observer) override; 64 bool Init() override; 65 void SetEncryptionPassphrase(const std::string& passphrase) override; 66 void SetDecryptionPassphrase(const std::string& passphrase) override; 67 void AddTrustedVaultDecryptionKeys( 68 const std::vector<std::vector<uint8_t>>& keys) override; 69 base::Time GetKeystoreMigrationTime() const override; 70 KeystoreKeysHandler* GetKeystoreKeysHandler() override; 71 72 // KeystoreKeysHandler implementation. 73 bool NeedKeystoreKey() const override; 74 bool SetKeystoreKeys(const std::vector<std::vector<uint8_t>>& keys) override; 75 76 // NigoriSyncBridge implementation. 77 base::Optional<ModelError> MergeSyncData( 78 base::Optional<EntityData> data) override; 79 base::Optional<ModelError> ApplySyncChanges( 80 base::Optional<EntityData> data) override; 81 std::unique_ptr<EntityData> GetData() override; 82 void ApplyDisableSyncChanges() override; 83 84 // TODO(crbug.com/922900): investigate whether we need this getter outside of 85 // tests and decide whether this method should be a part of 86 // SyncEncryptionHandler interface. 87 const CryptographerImpl& GetCryptographerForTesting() const; 88 sync_pb::NigoriSpecifics::PassphraseType GetPassphraseTypeForTesting() const; 89 ModelTypeSet GetEncryptedTypesForTesting() const; 90 bool HasPendingKeysForTesting() const; 91 KeyDerivationParams GetCustomPassphraseKeyDerivationParamsForTesting() const; 92 93 static std::string PackExplicitPassphraseKeyForTesting( 94 const Encryptor& encryptor, 95 const CryptographerImpl& cryptographer); 96 97 private: 98 base::Optional<ModelError> UpdateLocalState( 99 const sync_pb::NigoriSpecifics& specifics); 100 101 base::Optional<ModelError> UpdateCryptographer( 102 const sync_pb::EncryptedData& encryption_keybag, 103 const NigoriKeyBag& decryption_key_bag); 104 105 base::Optional<sync_pb::NigoriKey> TryDecryptPendingKeystoreDecryptorToken( 106 const sync_pb::EncryptedData& keystore_decryptor_token); 107 108 // Builds NigoriKeyBag, which contains keys acceptable for decryption of 109 // |encryption_keybag| from remote NigoriSpecifics. Its content depends on 110 // current passphrase type and available keys: for KEYSTORE_PASSPHRASE it 111 // contains only |keystore_decryptor_key|, for all other passphrase types 112 // it contains deserialized |explicit_passphrase_key_| and current default 113 // encryption key. 114 NigoriKeyBag BuildDecryptionKeyBagForRemoteKeybag( 115 const base::Optional<sync_pb::NigoriKey>& keystore_decryptor_key) const; 116 117 // Uses |key_bag| to try to decrypt pending keys as represented in 118 // |state_.pending_keys| (which must be set). 119 // 120 // If decryption is possible, the newly decrypted keys are put in the 121 // |state_.cryptographer|'s keybag and the default key is updated. In that 122 // case pending keys are cleared. 123 // 124 // If |key_bag| is not capable of decrypting pending keys, 125 // |state_.pending_keys| stays set. Such outcome is not itself considered 126 // and error and returns base::nullopt. 127 // 128 // Errors may be returned, in rare cases, for fatal protocol violations. 129 base::Optional<ModelError> TryDecryptPendingKeysWith( 130 const NigoriKeyBag& key_bag); 131 132 base::Time GetExplicitPassphraseTime() const; 133 134 // Returns key derivation params based on |passphrase_type_| and 135 // |custom_passphrase_key_derivation_params_|. Should be called only if 136 // |passphrase_type_| is an explicit passphrase. 137 KeyDerivationParams GetKeyDerivationParamsForPendingKeys() const; 138 139 // If there are pending keys and depending on the passphrase type, it invokes 140 // the appropriate observer methods (if any). 141 void MaybeNotifyOfPendingKeys() const; 142 143 // Persists Nigori derived from explicit passphrase into preferences, in case 144 // error occurs during serialization/encryption, corresponding preference 145 // just won't be updated. 146 void MaybeNotifyBootstrapTokenUpdated() const; 147 148 // Queues keystore rotation or full keystore migration if current state 149 // assumes it should happen. 150 void MaybeTriggerKeystoreReencryption(); 151 152 // Prior to USS keystore keys were stored in preferences. To avoid redundant 153 // requests to the server and make USS implementation more robust against 154 // failing such requests, the value restored from preferences should be 155 // populated to current |state_|. Performs unpacking of 156 // |packed_keystore_keys| and populates them to 157 // |keystore_keys_cryptographer|. Has no effect if |packed_keystore_keys| is 158 // empty, errors occur during deserealization or 159 // |keystore_keys_cryptographer| already has keys. 160 void MaybeMigrateKeystoreKeys(const std::string& packed_keystore_keys); 161 162 // Serializes state of the bridge and sync metadata into the proto. 163 sync_pb::NigoriLocalData SerializeAsNigoriLocalData() const; 164 165 // Appends |local_commit| to |pending_local_commit_queue_| and if appropriate 166 // calls Put() to trigger the commit. 167 void QueuePendingLocalCommit( 168 std::unique_ptr<PendingLocalNigoriCommit> local_commit); 169 170 // Processes |pending_local_commit_queue_| FIFO such that all non-applicable 171 // pending commits issue a failure, until the first one that is applicable is 172 // found (if any). If such applicable commit is found, the corresponding Put() 173 // call is issued. 174 void PutNextApplicablePendingLocalCommit(); 175 176 // Populates keystore keys into |cryptographer| in case it doesn't contain 177 // them already and |passphrase_type| isn't KEYSTORE_PASSPHRASE. This 178 // function only updates local state and doesn't trigger a commit. 179 void MaybePopulateKeystoreKeysIntoCryptographer(); 180 181 const Encryptor* const encryptor_; 182 183 const std::unique_ptr<NigoriLocalChangeProcessor> processor_; 184 const std::unique_ptr<NigoriStorage> storage_; 185 186 // Used for generation of random salt for deriving keys from custom 187 // passphrase if SCRYPT is enabled. 188 const base::RepeatingCallback<std::string()> random_salt_generator_; 189 190 // Stores a key derived from explicit passphrase and loaded from the prefs. 191 // Empty (i.e. default value) if prefs doesn't contain this key or in case of 192 // decryption/decoding errors. 193 const sync_pb::NigoriKey explicit_passphrase_key_; 194 195 syncer::NigoriState state_; 196 197 std::list<std::unique_ptr<PendingLocalNigoriCommit>> 198 pending_local_commit_queue_; 199 200 // Observer that owns the list of actual observers, and broadcasts 201 // notifications to all observers in the list. 202 class BroadcastingObserver; 203 const std::unique_ptr<BroadcastingObserver> broadcasting_observer_; 204 205 SEQUENCE_CHECKER(sequence_checker_); 206 207 DISALLOW_COPY_AND_ASSIGN(NigoriSyncBridgeImpl); 208 }; 209 210 } // namespace syncer 211 212 #endif // COMPONENTS_SYNC_NIGORI_NIGORI_SYNC_BRIDGE_IMPL_H_ 213