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