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.
5 #ifndef SYNC_INTERNAL_API_SYNC_ENCRYPTION_HANDLER_IMPL_H_
6 #define SYNC_INTERNAL_API_SYNC_ENCRYPTION_HANDLER_IMPL_H_
10 #include "base/compiler_specific.h"
11 #include "base/gtest_prod_util.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/observer_list.h"
15 #include "base/threading/thread_checker.h"
16 #include "base/time/time.h"
17 #include "sync/base/sync_export.h"
18 #include "sync/internal_api/public/sync_encryption_handler.h"
19 #include "sync/syncable/nigori_handler.h"
20 #include "sync/util/cryptographer.h"
27 class WriteTransaction
;
29 // Sync encryption handler implementation.
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.
37 // The class should live as long as the directory itself in order to ensure
38 // any data read/written is properly decrypted/encrypted.
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
43 // All methods are non-thread-safe and should only be called from the sync
44 // thread unless explicitly noted otherwise.
45 class SYNC_EXPORT_PRIVATE SyncEncryptionHandlerImpl
46 : public SyncEncryptionHandler
,
47 public syncable::NigoriHandler
{
49 // |clear_data_option| controls whether this object should update the Nigori
50 // node to indiciate that we are to clear server data as part of the
51 // transition to passphrase encryption.
52 SyncEncryptionHandlerImpl(
53 UserShare
* user_share
,
55 const std::string
& restored_key_for_bootstrapping
,
56 const std::string
& restored_keystore_key_for_bootstrapping
,
57 PassphraseTransitionClearDataOption clear_data_option
);
58 ~SyncEncryptionHandlerImpl() override
;
60 // SyncEncryptionHandler implementation.
61 void AddObserver(Observer
* observer
) override
;
62 void RemoveObserver(Observer
* observer
) override
;
64 void SetEncryptionPassphrase(const std::string
& passphrase
,
65 bool is_explicit
) override
;
66 void SetDecryptionPassphrase(const std::string
& passphrase
) override
;
67 void EnableEncryptEverything() override
;
68 bool IsEncryptEverythingEnabled() const override
;
69 PassphraseType
GetPassphraseType() const override
;
71 // NigoriHandler implementation.
72 // Note: all methods are invoked while the caller holds a transaction.
73 void ApplyNigoriUpdate(const sync_pb::NigoriSpecifics
& nigori
,
74 syncable::BaseTransaction
* const trans
) override
;
75 void UpdateNigoriFromEncryptedTypes(
76 sync_pb::NigoriSpecifics
* nigori
,
77 syncable::BaseTransaction
* const trans
) const override
;
78 bool NeedKeystoreKey(syncable::BaseTransaction
* const trans
) const override
;
80 const google::protobuf::RepeatedPtrField
<google::protobuf::string
>& keys
,
81 syncable::BaseTransaction
* const trans
) override
;
82 // Can be called from any thread.
83 ModelTypeSet
GetEncryptedTypes(
84 syncable::BaseTransaction
* const trans
) const override
;
86 // Unsafe getters. Use only if sync is not up and running and there is no risk
87 // of other threads calling this.
88 Cryptographer
* GetCryptographerUnsafe();
89 ModelTypeSet
GetEncryptedTypesUnsafe();
91 bool MigratedToKeystore();
92 base::Time
migration_time() const;
93 base::Time
custom_passphrase_time() const;
95 // Restore a saved nigori obtained from OnLocalSetPassphraseEncryption.
97 // Writes the nigori to the Directory and updates the Cryptographer.
98 void RestoreNigori(const SyncEncryptionHandler::NigoriState
& nigori_state
);
101 friend class SyncEncryptionHandlerImplTest
;
102 FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest
,
103 NigoriEncryptionTypes
);
104 FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest
,
105 EncryptEverythingExplicit
);
106 FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest
,
107 EncryptEverythingImplicit
);
108 FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest
,
109 UnknownSensitiveTypes
);
110 FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest
,
111 GetKeystoreDecryptor
);
112 FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest
,
113 ReceiveMigratedNigoriKeystorePass
);
114 FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest
,
115 ReceiveUmigratedNigoriAfterMigration
);
116 FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest
,
117 ReceiveOldMigratedNigori
);
118 FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest
,
119 SetKeystoreAfterReceivingMigratedNigori
);
120 FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest
,
121 SetCustomPassAfterMigration
);
122 FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest
,
123 SetCustomPassAfterMigrationNoKeystoreKey
);
124 FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest
,
125 SetImplicitPassAfterMigrationNoKeystoreKey
);
126 FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest
,
127 MigrateOnEncryptEverythingKeystorePassphrase
);
128 FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest
,
129 ReceiveMigratedNigoriWithOldPassphrase
);
131 // Container for members that require thread safety protection. All members
132 // that can be accessed from more than one thread should be held here and
133 // accessed via UnlockVault(..) and UnlockVaultMutable(..), which enforce
134 // that a transaction is held.
136 Vault(Encryptor
* encryptor
, ModelTypeSet encrypted_types
);
139 // Sync's cryptographer. Used for encrypting and decrypting sync data.
140 Cryptographer cryptographer
;
141 // The set of types that require encryption.
142 ModelTypeSet encrypted_types
;
145 DISALLOW_COPY_AND_ASSIGN(Vault
);
148 // Iterate over all encrypted types ensuring each entry is properly encrypted.
149 void ReEncryptEverything(WriteTransaction
* trans
);
151 // Updates internal and cryptographer state.
153 // Assumes |nigori| is already present in the Sync Directory.
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
);
161 // Wrapper around WriteEncryptionStateToNigori that creates a new write
163 void RewriteNigori();
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
);
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(
177 const sync_pb::NigoriSpecifics
& nigori
,
178 syncable::BaseTransaction
* const trans
);
180 // TODO(zea): make these public and have them replace SetEncryptionPassphrase
181 // and SetDecryptionPassphrase.
182 // Helper methods for handling passphrases once keystore migration has taken
185 // Sets a new custom passphrase. Should only be called if a custom passphrase
186 // is not already set.
187 // Triggers OnPassphraseAccepted on success, OnPassphraseRequired if a custom
188 // passphrase already existed.
189 void SetCustomPassphrase(const std::string
& passphrase
,
190 WriteTransaction
* trans
,
191 WriteNode
* nigori_node
);
192 // Decrypt the encryption keybag using a user provided passphrase.
193 // Should only be called if the current passphrase is a frozen implicit
194 // passphrase or a custom passphrase.
195 // Triggers OnPassphraseAccepted on success, OnPassphraseRequired on failure.
196 void DecryptPendingKeysWithExplicitPassphrase(const std::string
& passphrase
,
197 WriteTransaction
* trans
,
198 WriteNode
* nigori_node
);
200 // The final step of SetEncryptionPassphrase and SetDecryptionPassphrase that
201 // notifies observers of the result of the set passphrase operation, updates
202 // the nigori node, and does re-encryption.
203 // |success|: true if the operation was successful and false otherwise. If
204 // success == false, we send an OnPassphraseRequired notification.
205 // |bootstrap_token|: used to inform observers if the cryptographer's
206 // bootstrap token was updated.
207 // |is_explicit|: used to differentiate between a custom passphrase (true) and
208 // a GAIA passphrase that is implicitly used for encryption
210 // |trans| and |nigori_node|: used to access data in the cryptographer.
211 void FinishSetPassphrase(bool success
,
212 const std::string
& bootstrap_token
,
213 WriteTransaction
* trans
,
214 WriteNode
* nigori_node
);
216 // Merges the given set of encrypted types with the existing set and emits a
217 // notification if necessary.
218 // Note: must be called from within a transaction.
219 void MergeEncryptedTypes(ModelTypeSet new_encrypted_types
,
220 syncable::BaseTransaction
* const trans
);
222 // Helper methods for ensuring transactions are held when accessing
224 Vault
* UnlockVaultMutable(syncable::BaseTransaction
* const trans
);
225 const Vault
& UnlockVault(syncable::BaseTransaction
* const trans
) const;
227 // Helper method for determining if migration of a nigori node should be
229 // Conditions for triggering migration:
230 // 1. Cryptographer has no pending keys
231 // 2. Nigori node isn't already properly migrated or we need to rotate keys.
232 // 3. Keystore key is available.
233 // Note: if the nigori node is migrated but has an invalid state, will return
234 // true (e.g. node has KEYSTORE_PASSPHRASE, local is CUSTOM_PASSPHRASE).
235 bool ShouldTriggerMigration(const sync_pb::NigoriSpecifics
& nigori
,
236 const Cryptographer
& cryptographer
) const;
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
);
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(
248 const Cryptographer
& cryptographer
,
249 const std::string
& keystore_key
,
250 sync_pb::EncryptedData
* encrypted_blob
);
252 // Helper method for installing the keys encrypted in |encryption_keybag|
253 // into |cryptographer|.
254 // Returns true on success, false if we were unable to install the keybag.
255 // Will not update the default key.
256 bool AttemptToInstallKeybag(const sync_pb::EncryptedData
& keybag
,
258 Cryptographer
* cryptographer
);
260 // Helper method for decrypting pending keys with the keystore bootstrap.
261 // If successful, the default will become the key encrypted in the keystore
262 // bootstrap, and will return true. Else will return false.
263 bool DecryptPendingKeysWithKeystoreKey(
264 const std::string
& keystore_key
,
265 const sync_pb::EncryptedData
& keystore_bootstrap
,
266 Cryptographer
* cryptographer
);
268 // Helper to enable encrypt everything, notifying observers if necessary.
269 // Will not perform re-encryption.
270 void EnableEncryptEverythingImpl(syncable::BaseTransaction
* const trans
);
272 // If an explicit passphrase is in use, returns the time at which it was set
273 // (if known). Else return base::Time().
274 base::Time
GetExplicitPassphraseTime() const;
276 // Notify observers when a custom passphrase is set by this device.
277 void NotifyObserversOfLocalCustomPassphrase(WriteTransaction
* trans
);
279 base::ThreadChecker thread_checker_
;
281 base::ObserverList
<SyncEncryptionHandler::Observer
> observers_
;
283 // The current user share (for creating transactions).
284 UserShare
* user_share_
;
286 // Container for all data that can be accessed from multiple threads. Do not
287 // access this object directly. Instead access it via UnlockVault(..) and
288 // UnlockVaultMutable(..).
291 // Sync encryption state that is only modified and accessed from the sync
293 // Whether all current and future types should be encrypted.
294 bool encrypt_everything_
;
295 // The current state of the passphrase required to decrypt the encryption
296 // keys stored in the nigori node.
297 PassphraseType passphrase_type_
;
299 // The current keystore key provided by the server.
300 std::string keystore_key_
;
302 // The set of old keystore keys. Every time a key rotation occurs, the server
303 // sends down all previous keystore keys as well as the new key. We preserve
304 // the old keys so that when we re-encrypt we can ensure they're all added to
305 // the keybag (and to detect that a key rotation has occurred).
306 std::vector
<std::string
> old_keystore_keys_
;
308 // The number of times we've automatically (i.e. not via SetPassphrase or
309 // conflict resolver) updated the nigori's encryption keys in this chrome
311 int nigori_overwrite_count_
;
313 // The time the nigori was migrated to support keystore encryption.
314 base::Time migration_time_
;
316 // The time the custom passphrase was set for this account. Not valid
317 // if there is no custom passphrase or the custom passphrase was set
318 // before support for this field was added.
319 base::Time custom_passphrase_time_
;
321 const PassphraseTransitionClearDataOption clear_data_option_
;
323 base::WeakPtrFactory
<SyncEncryptionHandlerImpl
> weak_ptr_factory_
;
325 DISALLOW_COPY_AND_ASSIGN(SyncEncryptionHandlerImpl
);
328 } // namespace syncer
330 #endif // SYNC_INTERNAL_API_PUBLIC_SYNC_ENCRYPTION_HANDLER_IMPL_H_