Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(278)

Side by Side Diff: components/sync/core_impl/sync_encryption_handler_impl.h

Issue 2413313004: [Sync] Move the last things out of core/. (Closed)
Patch Set: Address comments. Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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_
OLDNEW
« no previous file with comments | « components/sync/core_impl/protocol_event_buffer_unittest.cc ('k') | components/sync/core_impl/sync_encryption_handler_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698