| OLD | NEW |
| (Empty) |
| 1 // Copyright 2012 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 SYNC_INTERNAL_API_SYNC_ENCRYPTION_HANDLER_IMPL_H_ | |
| 6 #define SYNC_INTERNAL_API_SYNC_ENCRYPTION_HANDLER_IMPL_H_ | |
| 7 | |
| 8 #include <string> | |
| 9 #include <vector> | |
| 10 | |
| 11 #include "base/compiler_specific.h" | |
| 12 #include "base/gtest_prod_util.h" | |
| 13 #include "base/macros.h" | |
| 14 #include "base/memory/weak_ptr.h" | |
| 15 #include "base/observer_list.h" | |
| 16 #include "base/threading/thread_checker.h" | |
| 17 #include "base/time/time.h" | |
| 18 #include "sync/base/sync_export.h" | |
| 19 #include "sync/internal_api/public/sync_encryption_handler.h" | |
| 20 #include "sync/syncable/nigori_handler.h" | |
| 21 #include "sync/util/cryptographer.h" | |
| 22 | |
| 23 namespace syncer { | |
| 24 | |
| 25 class Encryptor; | |
| 26 struct UserShare; | |
| 27 class WriteNode; | |
| 28 class WriteTransaction; | |
| 29 | |
| 30 // Sync encryption handler implementation. | |
| 31 // | |
| 32 // This class acts as the respository of all sync encryption state, and handles | |
| 33 // encryption related changes/queries coming from both the chrome side and | |
| 34 // the sync side (via NigoriHandler). It is capable of modifying all sync data | |
| 35 // (re-encryption), updating the encrypted types, changing the encryption keys, | |
| 36 // and creating/receiving nigori node updates. | |
| 37 // | |
| 38 // The class should live as long as the directory itself in order to ensure | |
| 39 // any data read/written is properly decrypted/encrypted. | |
| 40 // | |
| 41 // Note: See sync_encryption_handler.h for a description of the chrome visible | |
| 42 // methods and what they do, and nigori_handler.h for a description of the | |
| 43 // sync methods. | |
| 44 // All methods are non-thread-safe and should only be called from the sync | |
| 45 // thread unless explicitly noted otherwise. | |
| 46 class SYNC_EXPORT SyncEncryptionHandlerImpl : public SyncEncryptionHandler, | |
| 47 public syncable::NigoriHandler { | |
| 48 public: | |
| 49 SyncEncryptionHandlerImpl( | |
| 50 UserShare* user_share, | |
| 51 Encryptor* encryptor, | |
| 52 const std::string& restored_key_for_bootstrapping, | |
| 53 const std::string& restored_keystore_key_for_bootstrapping); | |
| 54 ~SyncEncryptionHandlerImpl() override; | |
| 55 | |
| 56 // SyncEncryptionHandler implementation. | |
| 57 void AddObserver(Observer* observer) override; | |
| 58 void RemoveObserver(Observer* observer) override; | |
| 59 void Init() override; | |
| 60 void SetEncryptionPassphrase(const std::string& passphrase, | |
| 61 bool is_explicit) override; | |
| 62 void SetDecryptionPassphrase(const std::string& passphrase) override; | |
| 63 void EnableEncryptEverything() override; | |
| 64 bool IsEncryptEverythingEnabled() const override; | |
| 65 PassphraseType GetPassphraseType() const override; | |
| 66 | |
| 67 // NigoriHandler implementation. | |
| 68 // Note: all methods are invoked while the caller holds a transaction. | |
| 69 void ApplyNigoriUpdate(const sync_pb::NigoriSpecifics& nigori, | |
| 70 syncable::BaseTransaction* const trans) override; | |
| 71 void UpdateNigoriFromEncryptedTypes( | |
| 72 sync_pb::NigoriSpecifics* nigori, | |
| 73 syncable::BaseTransaction* const trans) const override; | |
| 74 bool NeedKeystoreKey(syncable::BaseTransaction* const trans) const override; | |
| 75 bool SetKeystoreKeys( | |
| 76 const google::protobuf::RepeatedPtrField<google::protobuf::string>& keys, | |
| 77 syncable::BaseTransaction* const trans) override; | |
| 78 // Can be called from any thread. | |
| 79 ModelTypeSet GetEncryptedTypes( | |
| 80 syncable::BaseTransaction* const trans) const override; | |
| 81 | |
| 82 // Unsafe getters. Use only if sync is not up and running and there is no risk | |
| 83 // of other threads calling this. | |
| 84 Cryptographer* GetCryptographerUnsafe(); | |
| 85 ModelTypeSet GetEncryptedTypesUnsafe(); | |
| 86 | |
| 87 bool MigratedToKeystore(); | |
| 88 base::Time migration_time() const; | |
| 89 base::Time custom_passphrase_time() const; | |
| 90 | |
| 91 // Restore a saved nigori obtained from OnLocalSetPassphraseEncryption. | |
| 92 // | |
| 93 // Writes the nigori to the Directory and updates the Cryptographer. | |
| 94 void RestoreNigori(const SyncEncryptionHandler::NigoriState& nigori_state); | |
| 95 | |
| 96 private: | |
| 97 friend class SyncEncryptionHandlerImplTest; | |
| 98 FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest, | |
| 99 NigoriEncryptionTypes); | |
| 100 FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest, | |
| 101 EncryptEverythingExplicit); | |
| 102 FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest, | |
| 103 EncryptEverythingImplicit); | |
| 104 FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest, | |
| 105 UnknownSensitiveTypes); | |
| 106 FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest, | |
| 107 GetKeystoreDecryptor); | |
| 108 FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest, | |
| 109 ReceiveMigratedNigoriKeystorePass); | |
| 110 FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest, | |
| 111 ReceiveUmigratedNigoriAfterMigration); | |
| 112 FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest, | |
| 113 ReceiveOldMigratedNigori); | |
| 114 FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest, | |
| 115 SetKeystoreAfterReceivingMigratedNigori); | |
| 116 FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest, | |
| 117 SetCustomPassAfterMigration); | |
| 118 FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest, | |
| 119 SetCustomPassAfterMigrationNoKeystoreKey); | |
| 120 FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest, | |
| 121 SetImplicitPassAfterMigrationNoKeystoreKey); | |
| 122 FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest, | |
| 123 MigrateOnEncryptEverythingKeystorePassphrase); | |
| 124 FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest, | |
| 125 ReceiveMigratedNigoriWithOldPassphrase); | |
| 126 | |
| 127 // Container for members that require thread safety protection. All members | |
| 128 // that can be accessed from more than one thread should be held here and | |
| 129 // accessed via UnlockVault(..) and UnlockVaultMutable(..), which enforce | |
| 130 // that a transaction is held. | |
| 131 struct Vault { | |
| 132 Vault(Encryptor* encryptor, ModelTypeSet encrypted_types); | |
| 133 ~Vault(); | |
| 134 | |
| 135 // Sync's cryptographer. Used for encrypting and decrypting sync data. | |
| 136 Cryptographer cryptographer; | |
| 137 // The set of types that require encryption. | |
| 138 ModelTypeSet encrypted_types; | |
| 139 | |
| 140 private: | |
| 141 DISALLOW_COPY_AND_ASSIGN(Vault); | |
| 142 }; | |
| 143 | |
| 144 // Iterate over all encrypted types ensuring each entry is properly encrypted. | |
| 145 void ReEncryptEverything(WriteTransaction* trans); | |
| 146 | |
| 147 // Updates internal and cryptographer state. | |
| 148 // | |
| 149 // Assumes |nigori| is already present in the Sync Directory. | |
| 150 // | |
| 151 // Returns true on success, false if |nigori| was incompatible, and the | |
| 152 // nigori node must be corrected. | |
| 153 // Note: must be called from within a transaction. | |
| 154 bool ApplyNigoriUpdateImpl(const sync_pb::NigoriSpecifics& nigori, | |
| 155 syncable::BaseTransaction* const trans); | |
| 156 | |
| 157 // Wrapper around WriteEncryptionStateToNigori that creates a new write | |
| 158 // transaction. | |
| 159 void RewriteNigori(); | |
| 160 | |
| 161 // Write the current encryption state into the nigori node. This includes | |
| 162 // the encrypted types/encrypt everything state, as well as the keybag/ | |
| 163 // explicit passphrase state (if the cryptographer is ready). | |
| 164 void WriteEncryptionStateToNigori(WriteTransaction* trans); | |
| 165 | |
| 166 // Updates local encrypted types from |nigori|. | |
| 167 // Returns true if the local set of encrypted types either matched or was | |
| 168 // a subset of that in |nigori|. Returns false if the local state already | |
| 169 // had stricter encryption than |nigori|, and the nigori node needs to be | |
| 170 // updated with the newer encryption state. | |
| 171 // Note: must be called from within a transaction. | |
| 172 bool UpdateEncryptedTypesFromNigori( | |
| 173 const sync_pb::NigoriSpecifics& nigori, | |
| 174 syncable::BaseTransaction* const trans); | |
| 175 | |
| 176 // TODO(zea): make these public and have them replace SetEncryptionPassphrase | |
| 177 // and SetDecryptionPassphrase. | |
| 178 // Helper methods for handling passphrases once keystore migration has taken | |
| 179 // place. | |
| 180 // | |
| 181 // Sets a new custom passphrase. Should only be called if a custom passphrase | |
| 182 // is not already set. | |
| 183 // Triggers OnPassphraseAccepted on success, OnPassphraseRequired if a custom | |
| 184 // passphrase already existed. | |
| 185 void SetCustomPassphrase(const std::string& passphrase, | |
| 186 WriteTransaction* trans, | |
| 187 WriteNode* nigori_node); | |
| 188 // Decrypt the encryption keybag using a user provided passphrase. | |
| 189 // Should only be called if the current passphrase is a frozen implicit | |
| 190 // passphrase or a custom passphrase. | |
| 191 // Triggers OnPassphraseAccepted on success, OnPassphraseRequired on failure. | |
| 192 void DecryptPendingKeysWithExplicitPassphrase(const std::string& passphrase, | |
| 193 WriteTransaction* trans, | |
| 194 WriteNode* nigori_node); | |
| 195 | |
| 196 // The final step of SetEncryptionPassphrase and SetDecryptionPassphrase that | |
| 197 // notifies observers of the result of the set passphrase operation, updates | |
| 198 // the nigori node, and does re-encryption. | |
| 199 // |success|: true if the operation was successful and false otherwise. If | |
| 200 // success == false, we send an OnPassphraseRequired notification. | |
| 201 // |bootstrap_token|: used to inform observers if the cryptographer's | |
| 202 // bootstrap token was updated. | |
| 203 // |is_explicit|: used to differentiate between a custom passphrase (true) and | |
| 204 // a GAIA passphrase that is implicitly used for encryption | |
| 205 // (false). | |
| 206 // |trans| and |nigori_node|: used to access data in the cryptographer. | |
| 207 void FinishSetPassphrase(bool success, | |
| 208 const std::string& bootstrap_token, | |
| 209 WriteTransaction* trans, | |
| 210 WriteNode* nigori_node); | |
| 211 | |
| 212 // Merges the given set of encrypted types with the existing set and emits a | |
| 213 // notification if necessary. | |
| 214 // Note: must be called from within a transaction. | |
| 215 void MergeEncryptedTypes(ModelTypeSet new_encrypted_types, | |
| 216 syncable::BaseTransaction* const trans); | |
| 217 | |
| 218 // Helper methods for ensuring transactions are held when accessing | |
| 219 // |vault_unsafe_|. | |
| 220 Vault* UnlockVaultMutable(syncable::BaseTransaction* const trans); | |
| 221 const Vault& UnlockVault(syncable::BaseTransaction* const trans) const; | |
| 222 | |
| 223 // Helper method for determining if migration of a nigori node should be | |
| 224 // triggered or not. | |
| 225 // Conditions for triggering migration: | |
| 226 // 1. Cryptographer has no pending keys | |
| 227 // 2. Nigori node isn't already properly migrated or we need to rotate keys. | |
| 228 // 3. Keystore key is available. | |
| 229 // Note: if the nigori node is migrated but has an invalid state, will return | |
| 230 // true (e.g. node has KEYSTORE_PASSPHRASE, local is CUSTOM_PASSPHRASE). | |
| 231 bool ShouldTriggerMigration(const sync_pb::NigoriSpecifics& nigori, | |
| 232 const Cryptographer& cryptographer) const; | |
| 233 | |
| 234 // Performs the actual migration of the |nigori_node| to support keystore | |
| 235 // encryption iff ShouldTriggerMigration(..) returns true. | |
| 236 bool AttemptToMigrateNigoriToKeystore(WriteTransaction* trans, | |
| 237 WriteNode* nigori_node); | |
| 238 | |
| 239 // Fill |encrypted_blob| with the keystore decryptor token if | |
| 240 // |encrypted_blob|'s contents didn't already contain the key. | |
| 241 // The keystore decryptor token is the serialized current default encryption | |
| 242 // key, encrypted with the keystore key. | |
| 243 bool GetKeystoreDecryptor( | |
| 244 const Cryptographer& cryptographer, | |
| 245 const std::string& keystore_key, | |
| 246 sync_pb::EncryptedData* encrypted_blob); | |
| 247 | |
| 248 // Helper method for installing the keys encrypted in |encryption_keybag| | |
| 249 // into |cryptographer|. | |
| 250 // Returns true on success, false if we were unable to install the keybag. | |
| 251 // Will not update the default key. | |
| 252 bool AttemptToInstallKeybag(const sync_pb::EncryptedData& keybag, | |
| 253 bool update_default, | |
| 254 Cryptographer* cryptographer); | |
| 255 | |
| 256 // Helper method for decrypting pending keys with the keystore bootstrap. | |
| 257 // If successful, the default will become the key encrypted in the keystore | |
| 258 // bootstrap, and will return true. Else will return false. | |
| 259 bool DecryptPendingKeysWithKeystoreKey( | |
| 260 const std::string& keystore_key, | |
| 261 const sync_pb::EncryptedData& keystore_bootstrap, | |
| 262 Cryptographer* cryptographer); | |
| 263 | |
| 264 // Helper to enable encrypt everything, notifying observers if necessary. | |
| 265 // Will not perform re-encryption. | |
| 266 void EnableEncryptEverythingImpl(syncable::BaseTransaction* const trans); | |
| 267 | |
| 268 // If an explicit passphrase is in use, returns the time at which it was set | |
| 269 // (if known). Else return base::Time(). | |
| 270 base::Time GetExplicitPassphraseTime() const; | |
| 271 | |
| 272 // Notify observers when a custom passphrase is set by this device. | |
| 273 void NotifyObserversOfLocalCustomPassphrase(WriteTransaction* trans); | |
| 274 | |
| 275 base::ThreadChecker thread_checker_; | |
| 276 | |
| 277 base::ObserverList<SyncEncryptionHandler::Observer> observers_; | |
| 278 | |
| 279 // The current user share (for creating transactions). | |
| 280 UserShare* user_share_; | |
| 281 | |
| 282 // Container for all data that can be accessed from multiple threads. Do not | |
| 283 // access this object directly. Instead access it via UnlockVault(..) and | |
| 284 // UnlockVaultMutable(..). | |
| 285 Vault vault_unsafe_; | |
| 286 | |
| 287 // Sync encryption state that is only modified and accessed from the sync | |
| 288 // thread. | |
| 289 // Whether all current and future types should be encrypted. | |
| 290 bool encrypt_everything_; | |
| 291 // The current state of the passphrase required to decrypt the encryption | |
| 292 // keys stored in the nigori node. | |
| 293 PassphraseType passphrase_type_; | |
| 294 | |
| 295 // The current keystore key provided by the server. | |
| 296 std::string keystore_key_; | |
| 297 | |
| 298 // The set of old keystore keys. Every time a key rotation occurs, the server | |
| 299 // sends down all previous keystore keys as well as the new key. We preserve | |
| 300 // the old keys so that when we re-encrypt we can ensure they're all added to | |
| 301 // the keybag (and to detect that a key rotation has occurred). | |
| 302 std::vector<std::string> old_keystore_keys_; | |
| 303 | |
| 304 // The number of times we've automatically (i.e. not via SetPassphrase or | |
| 305 // conflict resolver) updated the nigori's encryption keys in this chrome | |
| 306 // instantiation. | |
| 307 int nigori_overwrite_count_; | |
| 308 | |
| 309 // The time the nigori was migrated to support keystore encryption. | |
| 310 base::Time migration_time_; | |
| 311 | |
| 312 // The time the custom passphrase was set for this account. Not valid | |
| 313 // if there is no custom passphrase or the custom passphrase was set | |
| 314 // before support for this field was added. | |
| 315 base::Time custom_passphrase_time_; | |
| 316 | |
| 317 base::WeakPtrFactory<SyncEncryptionHandlerImpl> weak_ptr_factory_; | |
| 318 | |
| 319 DISALLOW_COPY_AND_ASSIGN(SyncEncryptionHandlerImpl); | |
| 320 }; | |
| 321 | |
| 322 } // namespace syncer | |
| 323 | |
| 324 #endif // SYNC_INTERNAL_API_SYNC_ENCRYPTION_HANDLER_IMPL_H_ | |
| OLD | NEW |