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

Side by Side Diff: sync/internal_api/sync_encryption_handler_impl.cc

Issue 10916036: [Sync] Implement keystore migration support. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 8 years, 3 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "sync/internal_api/sync_encryption_handler_impl.h" 5 #include "sync/internal_api/sync_encryption_handler_impl.h"
6 6
7 #include <queue> 7 #include <queue>
8 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/message_loop.h" 11 #include "base/message_loop.h"
12 #include "base/time.h"
12 #include "base/tracked_objects.h" 13 #include "base/tracked_objects.h"
13 #include "base/metrics/histogram.h" 14 #include "base/metrics/histogram.h"
14 #include "sync/internal_api/public/read_node.h" 15 #include "sync/internal_api/public/read_node.h"
15 #include "sync/internal_api/public/read_transaction.h" 16 #include "sync/internal_api/public/read_transaction.h"
16 #include "sync/internal_api/public/user_share.h" 17 #include "sync/internal_api/public/user_share.h"
17 #include "sync/internal_api/public/util/experiments.h" 18 #include "sync/internal_api/public/util/experiments.h"
18 #include "sync/internal_api/public/write_node.h" 19 #include "sync/internal_api/public/write_node.h"
19 #include "sync/internal_api/public/write_transaction.h" 20 #include "sync/internal_api/public/write_transaction.h"
21 #include "sync/internal_api/public/util/sync_string_conversions.h"
20 #include "sync/protocol/encryption.pb.h" 22 #include "sync/protocol/encryption.pb.h"
21 #include "sync/protocol/nigori_specifics.pb.h" 23 #include "sync/protocol/nigori_specifics.pb.h"
22 #include "sync/protocol/sync.pb.h" 24 #include "sync/protocol/sync.pb.h"
23 #include "sync/syncable/base_transaction.h" 25 #include "sync/syncable/base_transaction.h"
24 #include "sync/syncable/directory.h" 26 #include "sync/syncable/directory.h"
25 #include "sync/syncable/entry.h" 27 #include "sync/syncable/entry.h"
26 #include "sync/syncable/nigori_util.h" 28 #include "sync/syncable/nigori_util.h"
27 #include "sync/util/cryptographer.h" 29 #include "sync/util/cryptographer.h"
30 #include "sync/util/time.h"
28 31
29 namespace syncer { 32 namespace syncer {
30 33
31 namespace { 34 namespace {
35
32 // The maximum number of times we will automatically overwrite the nigori node 36 // The maximum number of times we will automatically overwrite the nigori node
33 // because the encryption keys don't match (per chrome instantiation). 37 // because the encryption keys don't match (per chrome instantiation).
34 // We protect ourselves against nigori rollbacks, but it's possible two 38 // We protect ourselves against nigori rollbacks, but it's possible two
35 // different clients might have contrasting view of what the nigori node state 39 // different clients might have contrasting view of what the nigori node state
36 // should be, in which case they might ping pong (see crbug.com/119207). 40 // should be, in which case they might ping pong (see crbug.com/119207).
37 static const int kNigoriOverwriteLimit = 10; 41 static const int kNigoriOverwriteLimit = 10;
42
43 // The new passphrase state is sufficient to determine whether a nigori node
44 // is migrated to support keystore encryption. In addition though, we also
45 // want to verify the conditions for proper keystore encryption functionality.
46 // 1. Passphrase state is set.
47 // 2. Migration time is set.
48 // 3. Frozen keybag is true
49 // 4. If passphrase state is keystore, keystore_decryptor_token is set.
50 bool IsNigoriMigratedToKeystore(const sync_pb::NigoriSpecifics& nigori) {
51 if (!nigori.has_passphrase_type())
52 return false;
53 if (!nigori.has_keystore_migration_time())
54 return false;
55 if (!nigori.keybag_is_frozen())
56 return false;
57 if (nigori.passphrase_type() ==
58 sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE)
59 return false;
60 if (nigori.passphrase_type() ==
61 sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE &&
62 nigori.keystore_decryptor_token().blob().empty())
63 return false;
64 if (!nigori.has_keystore_migration_time())
65 return false;
66 return true;
38 } 67 }
39 68
69 PassphraseType ProtoPassphraseTypeToEnum(
70 sync_pb::NigoriSpecifics::PassphraseType type) {
71 switch(type) {
72 case sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE:
73 return IMPLICIT_PASSPHRASE;
74 case sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE:
75 return KEYSTORE_PASSPHRASE;
76 case sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE:
77 return CUSTOM_PASSPHRASE;
78 case sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE:
79 return FROZEN_IMPLICIT_PASSPHRASE;
80 default:
81 NOTREACHED();
82 return IMPLICIT_PASSPHRASE;
83 };
84 }
85
86 sync_pb::NigoriSpecifics::PassphraseType
87 EnumPassphraseTypeToProto(PassphraseType type) {
88 switch(type) {
89 case IMPLICIT_PASSPHRASE:
90 return sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE;
91 case KEYSTORE_PASSPHRASE:
92 return sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE;
93 case CUSTOM_PASSPHRASE:
94 return sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE;
95 case FROZEN_IMPLICIT_PASSPHRASE:
96 return sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE;
97 default:
98 NOTREACHED();
99 return sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE;;
100 };
101 }
102
103 bool IsExplicitPassphrase(PassphraseType type) {
104 return type == CUSTOM_PASSPHRASE || type == FROZEN_IMPLICIT_PASSPHRASE;
105 }
106
107 } // namespace
108
40 SyncEncryptionHandlerImpl::Vault::Vault( 109 SyncEncryptionHandlerImpl::Vault::Vault(
41 Encryptor* encryptor, 110 Encryptor* encryptor,
42 ModelTypeSet encrypted_types) 111 ModelTypeSet encrypted_types)
43 : cryptographer(encryptor), 112 : cryptographer(encryptor),
44 encrypted_types(encrypted_types) { 113 encrypted_types(encrypted_types) {
45 } 114 }
46 115
47 SyncEncryptionHandlerImpl::Vault::~Vault() { 116 SyncEncryptionHandlerImpl::Vault::~Vault() {
48 } 117 }
49 118
50 SyncEncryptionHandlerImpl::SyncEncryptionHandlerImpl( 119 SyncEncryptionHandlerImpl::SyncEncryptionHandlerImpl(
51 UserShare* user_share, 120 UserShare* user_share,
52 Encryptor* encryptor, 121 Encryptor* encryptor,
53 const std::string& restored_key_for_bootstrapping, 122 const std::string& restored_key_for_bootstrapping,
54 const std::string& restored_keystore_key_for_bootstrapping) 123 const std::string& restored_keystore_key_for_bootstrapping)
55 : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), 124 : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
56 user_share_(user_share), 125 user_share_(user_share),
57 vault_unsafe_(encryptor, SensitiveTypes()), 126 vault_unsafe_(encryptor, SensitiveTypes()),
58 encrypt_everything_(false), 127 encrypt_everything_(false),
59 passphrase_state_(IMPLICIT_PASSPHRASE), 128 passphrase_type_(IMPLICIT_PASSPHRASE),
60 keystore_key_(restored_keystore_key_for_bootstrapping), 129 keystore_key_(restored_keystore_key_for_bootstrapping),
61 nigori_overwrite_count_(0) { 130 nigori_overwrite_count_(0),
131 migration_time_ms_(0) {
62 // We only bootstrap the user provided passphrase. The keystore key is handled 132 // We only bootstrap the user provided passphrase. The keystore key is handled
63 // at Init time once we're sure the nigori is downloaded. 133 // at Init time once we're sure the nigori is downloaded.
64 vault_unsafe_.cryptographer.Bootstrap(restored_key_for_bootstrapping); 134 vault_unsafe_.cryptographer.Bootstrap(restored_key_for_bootstrapping);
65 } 135 }
66 136
67 SyncEncryptionHandlerImpl::~SyncEncryptionHandlerImpl() {} 137 SyncEncryptionHandlerImpl::~SyncEncryptionHandlerImpl() {}
68 138
69 void SyncEncryptionHandlerImpl::AddObserver(Observer* observer) { 139 void SyncEncryptionHandlerImpl::AddObserver(Observer* observer) {
70 DCHECK(thread_checker_.CalledOnValidThread()); 140 DCHECK(thread_checker_.CalledOnValidThread());
71 DCHECK(!observers_.HasObserver(observer)); 141 DCHECK(!observers_.HasObserver(observer));
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 193
124 // All accesses to the cryptographer are protected by a transaction. 194 // All accesses to the cryptographer are protected by a transaction.
125 WriteTransaction trans(FROM_HERE, user_share_); 195 WriteTransaction trans(FROM_HERE, user_share_);
126 KeyParams key_params = {"localhost", "dummy", passphrase}; 196 KeyParams key_params = {"localhost", "dummy", passphrase};
127 WriteNode node(&trans); 197 WriteNode node(&trans);
128 if (node.InitByTagLookup(kNigoriTag) != BaseNode::INIT_OK) { 198 if (node.InitByTagLookup(kNigoriTag) != BaseNode::INIT_OK) {
129 NOTREACHED(); 199 NOTREACHED();
130 return; 200 return;
131 } 201 }
132 202
133 bool nigori_has_explicit_passphrase = 203 Cryptographer* cryptographer =
134 node.GetNigoriSpecifics().using_explicit_passphrase(); 204 &UnlockVaultMutable(trans.GetWrappedTrans())->cryptographer;
205
206 // Once we've migrated to keystore, the only way to set a passphrase for
207 // encryption is to set a custom passphrase.
208 if (IsNigoriMigratedToKeystore(node.GetNigoriSpecifics())) {
209 if (!is_explicit) {
210 DCHECK(cryptographer->is_ready());
211 // The user is setting a new implicit passphrase. At this point we don't
212 // care, so drop it on the floor. This is safe because if we have a
213 // migrated nigori node, then we don't need to create an initial
214 // encryption key.
215 LOG(WARNING) << "Ignoring new implicit passphrase. Keystore migration "
216 << "already performed.";
217 return;
218 }
219 // Will fail if we already have an explicit passphrase or we have pending
220 // keys.
221 SetCustomPassphrase(passphrase, &trans, &node);
222 return;
223 }
224
135 std::string bootstrap_token; 225 std::string bootstrap_token;
136 sync_pb::EncryptedData pending_keys; 226 sync_pb::EncryptedData pending_keys;
137 Cryptographer* cryptographer =
138 &UnlockVaultMutable(trans.GetWrappedTrans())->cryptographer;
139 if (cryptographer->has_pending_keys()) 227 if (cryptographer->has_pending_keys())
140 pending_keys = cryptographer->GetPendingKeys(); 228 pending_keys = cryptographer->GetPendingKeys();
141 bool success = false; 229 bool success = false;
142 230
143 // There are six cases to handle here: 231 // There are six cases to handle here:
144 // 1. The user has no pending keys and is setting their current GAIA password 232 // 1. The user has no pending keys and is setting their current GAIA password
145 // as the encryption passphrase. This happens either during first time sync 233 // as the encryption passphrase. This happens either during first time sync
146 // with a clean profile, or after re-authenticating on a profile that was 234 // with a clean profile, or after re-authenticating on a profile that was
147 // already signed in with the cryptographer ready. 235 // already signed in with the cryptographer ready.
148 // 2. The user has no pending keys, and is overwriting an (already provided) 236 // 2. The user has no pending keys, and is overwriting an (already provided)
149 // implicit passphrase with an explicit (custom) passphrase. 237 // implicit passphrase with an explicit (custom) passphrase.
150 // 3. The user has pending keys for an explicit passphrase that is somehow set 238 // 3. The user has pending keys for an explicit passphrase that is somehow set
151 // to their current GAIA passphrase. 239 // to their current GAIA passphrase.
152 // 4. The user has pending keys encrypted with their current GAIA passphrase 240 // 4. The user has pending keys encrypted with their current GAIA passphrase
153 // and the caller passes in the current GAIA passphrase. 241 // and the caller passes in the current GAIA passphrase.
154 // 5. The user has pending keys encrypted with an older GAIA passphrase 242 // 5. The user has pending keys encrypted with an older GAIA passphrase
155 // and the caller passes in the current GAIA passphrase. 243 // and the caller passes in the current GAIA passphrase.
156 // 6. The user has previously done encryption with an explicit passphrase. 244 // 6. The user has previously done encryption with an explicit passphrase.
157 // Furthermore, we enforce the fact that the bootstrap encryption token will 245 // Furthermore, we enforce the fact that the bootstrap encryption token will
158 // always be derived from the newest GAIA password if the account is using 246 // always be derived from the newest GAIA password if the account is using
159 // an implicit passphrase (even if the data is encrypted with an old GAIA 247 // an implicit passphrase (even if the data is encrypted with an old GAIA
160 // password). If the account is using an explicit (custom) passphrase, the 248 // password). If the account is using an explicit (custom) passphrase, the
161 // bootstrap token will be derived from the most recently provided explicit 249 // bootstrap token will be derived from the most recently provided explicit
162 // passphrase (that was able to decrypt the data). 250 // passphrase (that was able to decrypt the data).
163 if (!nigori_has_explicit_passphrase) { 251 if (!IsExplicitPassphrase(passphrase_type_)) {
164 if (!cryptographer->has_pending_keys()) { 252 if (!cryptographer->has_pending_keys()) {
165 if (cryptographer->AddKey(key_params)) { 253 if (cryptographer->AddKey(key_params)) {
166 // Case 1 and 2. We set a new GAIA passphrase when there are no pending 254 // Case 1 and 2. We set a new GAIA passphrase when there are no pending
167 // keys (1), or overwriting an implicit passphrase with a new explicit 255 // keys (1), or overwriting an implicit passphrase with a new explicit
168 // one (2) when there are no pending keys. 256 // one (2) when there are no pending keys.
169 DVLOG(1) << "Setting " << (is_explicit ? "explicit" : "implicit" ) 257 if (is_explicit) {
170 << " passphrase for encryption."; 258 DVLOG(1) << "Setting explicit passphrase for encryption.";
259 passphrase_type_ = CUSTOM_PASSPHRASE;
260 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
261 OnPassphraseTypeChanged(passphrase_type_));
262 } else {
263 DVLOG(1) << "Setting implicit passphrase for encryption.";
264 }
171 cryptographer->GetBootstrapToken(&bootstrap_token); 265 cryptographer->GetBootstrapToken(&bootstrap_token);
172 success = true; 266 success = true;
173 } else { 267 } else {
174 NOTREACHED() << "Failed to add key to cryptographer."; 268 NOTREACHED() << "Failed to add key to cryptographer.";
175 success = false; 269 success = false;
176 } 270 }
177 } else { // cryptographer->has_pending_keys() == true 271 } else { // cryptographer->has_pending_keys() == true
178 if (is_explicit) { 272 if (is_explicit) {
179 // This can only happen if the nigori node is updated with a new 273 // This can only happen if the nigori node is updated with a new
180 // implicit passphrase while a client is attempting to set a new custom 274 // implicit passphrase while a client is attempting to set a new custom
(...skipping 21 matching lines...) Expand all
202 temp_cryptographer.GetBootstrapToken(&bootstrap_token); 296 temp_cryptographer.GetBootstrapToken(&bootstrap_token);
203 // We then set the new passphrase as the default passphrase of the 297 // We then set the new passphrase as the default passphrase of the
204 // real cryptographer, even though we have pending keys. This is safe, 298 // real cryptographer, even though we have pending keys. This is safe,
205 // as although Cryptographer::is_initialized() will now be true, 299 // as although Cryptographer::is_initialized() will now be true,
206 // is_ready() will remain false due to having pending keys. 300 // is_ready() will remain false due to having pending keys.
207 cryptographer->AddKey(key_params); 301 cryptographer->AddKey(key_params);
208 success = false; 302 success = false;
209 } 303 }
210 } // is_explicit 304 } // is_explicit
211 } // cryptographer->has_pending_keys() 305 } // cryptographer->has_pending_keys()
212 } else { // nigori_has_explicit_passphrase == true 306 } else { // IsExplicitPassphrase(passphrase_type_) == true.
213 // Case 6. We do not want to override a previously set explicit passphrase, 307 // Case 6. We do not want to override a previously set explicit passphrase,
214 // so we return a failure. 308 // so we return a failure.
215 DVLOG(1) << "Failing because an explicit passphrase is already set."; 309 DVLOG(1) << "Failing because an explicit passphrase is already set.";
216 success = false; 310 success = false;
217 } 311 }
218 312
219 DVLOG_IF(1, !success) 313 DVLOG_IF(1, !success)
220 << "Failure in SetEncryptionPassphrase; notifying and returning."; 314 << "Failure in SetEncryptionPassphrase; notifying and returning.";
221 DVLOG_IF(1, success) 315 DVLOG_IF(1, success)
222 << "Successfully set encryption passphrase; updating nigori and " 316 << "Successfully set encryption passphrase; updating nigori and "
223 "reencrypting."; 317 "reencrypting.";
224 318
225 FinishSetPassphrase( 319 FinishSetPassphrase(success, bootstrap_token, &trans, &node);
226 success, bootstrap_token, is_explicit, &trans, &node);
227 } 320 }
228 321
229 void SyncEncryptionHandlerImpl::SetDecryptionPassphrase( 322 void SyncEncryptionHandlerImpl::SetDecryptionPassphrase(
230 const std::string& passphrase) { 323 const std::string& passphrase) {
231 DCHECK(thread_checker_.CalledOnValidThread()); 324 DCHECK(thread_checker_.CalledOnValidThread());
232 // We do not accept empty passphrases. 325 // We do not accept empty passphrases.
233 if (passphrase.empty()) { 326 if (passphrase.empty()) {
234 NOTREACHED() << "Cannot decrypt with an empty passphrase."; 327 NOTREACHED() << "Cannot decrypt with an empty passphrase.";
235 return; 328 return;
236 } 329 }
237 330
238 // All accesses to the cryptographer are protected by a transaction. 331 // All accesses to the cryptographer are protected by a transaction.
239 WriteTransaction trans(FROM_HERE, user_share_); 332 WriteTransaction trans(FROM_HERE, user_share_);
240 KeyParams key_params = {"localhost", "dummy", passphrase}; 333 KeyParams key_params = {"localhost", "dummy", passphrase};
241 WriteNode node(&trans); 334 WriteNode node(&trans);
242 if (node.InitByTagLookup(kNigoriTag) != BaseNode::INIT_OK) { 335 if (node.InitByTagLookup(kNigoriTag) != BaseNode::INIT_OK) {
243 NOTREACHED(); 336 NOTREACHED();
244 return; 337 return;
245 } 338 }
246 339
340 // Once we've migrated to keystore, we're only ever decrypting keys derived
341 // from an explicit passphrase. But, for clients without a keystore key yet
342 // (either not on by default or failed to download one), we still support
343 // decrypting with a gaia passphrase, and therefore bypass the
344 // DecryptPendingKeysWithExplicitPassphrase logic.
345 if (IsNigoriMigratedToKeystore(node.GetNigoriSpecifics()) &&
346 IsExplicitPassphrase(passphrase_type_)) {
347 DecryptPendingKeysWithExplicitPassphrase(passphrase, &trans, &node);
348 return;
349 }
350
247 Cryptographer* cryptographer = 351 Cryptographer* cryptographer =
248 &UnlockVaultMutable(trans.GetWrappedTrans())->cryptographer; 352 &UnlockVaultMutable(trans.GetWrappedTrans())->cryptographer;
249 if (!cryptographer->has_pending_keys()) { 353 if (!cryptographer->has_pending_keys()) {
250 // Note that this *can* happen in a rare situation where data is 354 // Note that this *can* happen in a rare situation where data is
251 // re-encrypted on another client while a SetDecryptionPassphrase() call is 355 // re-encrypted on another client while a SetDecryptionPassphrase() call is
252 // in-flight on this client. It is rare enough that we choose to do nothing. 356 // in-flight on this client. It is rare enough that we choose to do nothing.
253 NOTREACHED() << "Attempt to set decryption passphrase failed because there " 357 NOTREACHED() << "Attempt to set decryption passphrase failed because there "
254 << "were no pending keys."; 358 << "were no pending keys.";
255 return; 359 return;
256 } 360 }
257 361
258 bool nigori_has_explicit_passphrase =
259 node.GetNigoriSpecifics().using_explicit_passphrase();
260 std::string bootstrap_token; 362 std::string bootstrap_token;
261 sync_pb::EncryptedData pending_keys; 363 sync_pb::EncryptedData pending_keys;
262 pending_keys = cryptographer->GetPendingKeys(); 364 pending_keys = cryptographer->GetPendingKeys();
263 bool success = false; 365 bool success = false;
264 366
265 // There are three cases to handle here: 367 // There are three cases to handle here:
266 // 7. We're using the current GAIA password to decrypt the pending keys. This 368 // 7. We're using the current GAIA password to decrypt the pending keys. This
267 // happens when signing in to an account with a previously set implicit 369 // happens when signing in to an account with a previously set implicit
268 // passphrase, where the data is already encrypted with the newest GAIA 370 // passphrase, where the data is already encrypted with the newest GAIA
269 // password. 371 // password.
270 // 8. The user is providing an old GAIA password to decrypt the pending keys. 372 // 8. The user is providing an old GAIA password to decrypt the pending keys.
271 // In this case, the user is using an implicit passphrase, but has changed 373 // In this case, the user is using an implicit passphrase, but has changed
272 // their password since they last encrypted their data, and therefore 374 // their password since they last encrypted their data, and therefore
273 // their current GAIA password was unable to decrypt the data. This will 375 // their current GAIA password was unable to decrypt the data. This will
274 // happen when the user is setting up a new profile with a previously 376 // happen when the user is setting up a new profile with a previously
275 // encrypted account (after changing passwords). 377 // encrypted account (after changing passwords).
276 // 9. The user is providing a previously set explicit passphrase to decrypt 378 // 9. The user is providing a previously set explicit passphrase to decrypt
277 // the pending keys. 379 // the pending keys.
278 if (!nigori_has_explicit_passphrase) { 380 if (!IsExplicitPassphrase(passphrase_type_)) {
279 if (cryptographer->is_initialized()) { 381 if (cryptographer->is_initialized()) {
280 // We only want to change the default encryption key to the pending 382 // We only want to change the default encryption key to the pending
281 // one if the pending keybag already contains the current default. 383 // one if the pending keybag already contains the current default.
282 // This covers the case where a different client re-encrypted 384 // This covers the case where a different client re-encrypted
283 // everything with a newer gaia passphrase (and hence the keybag 385 // everything with a newer gaia passphrase (and hence the keybag
284 // contains keys from all previously used gaia passphrases). 386 // contains keys from all previously used gaia passphrases).
285 // Otherwise, we're in a situation where the pending keys are 387 // Otherwise, we're in a situation where the pending keys are
286 // encrypted with an old gaia passphrase, while the default is the 388 // encrypted with an old gaia passphrase, while the default is the
287 // current gaia passphrase. In that case, we preserve the default. 389 // current gaia passphrase. In that case, we preserve the default.
288 Cryptographer temp_cryptographer(cryptographer->encryptor()); 390 Cryptographer temp_cryptographer(cryptographer->encryptor());
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 success = false; 457 success = false;
356 } 458 }
357 } // nigori_has_explicit_passphrase 459 } // nigori_has_explicit_passphrase
358 460
359 DVLOG_IF(1, !success) 461 DVLOG_IF(1, !success)
360 << "Failure in SetDecryptionPassphrase; notifying and returning."; 462 << "Failure in SetDecryptionPassphrase; notifying and returning.";
361 DVLOG_IF(1, success) 463 DVLOG_IF(1, success)
362 << "Successfully set decryption passphrase; updating nigori and " 464 << "Successfully set decryption passphrase; updating nigori and "
363 "reencrypting."; 465 "reencrypting.";
364 466
365 FinishSetPassphrase(success, 467 FinishSetPassphrase(success, bootstrap_token, &trans, &node);
366 bootstrap_token,
367 nigori_has_explicit_passphrase,
368 &trans,
369 &node);
370 } 468 }
371 469
372 void SyncEncryptionHandlerImpl::EnableEncryptEverything() { 470 void SyncEncryptionHandlerImpl::EnableEncryptEverything() {
373 DCHECK(thread_checker_.CalledOnValidThread()); 471 DCHECK(thread_checker_.CalledOnValidThread());
374 WriteTransaction trans(FROM_HERE, user_share_); 472 WriteTransaction trans(FROM_HERE, user_share_);
375 ModelTypeSet* encrypted_types = 473 DVLOG(1) << "Enabling encrypt everything.";
376 &UnlockVaultMutable(trans.GetWrappedTrans())->encrypted_types; 474 if (encrypt_everything_)
377 if (encrypt_everything_) {
378 DCHECK(encrypted_types->Equals(UserTypes()));
379 return; 475 return;
380 } 476 EnableEncryptEverythingImpl(trans.GetWrappedTrans());
381 DVLOG(1) << "Enabling encrypt everything.";
382 encrypt_everything_ = true;
383 // Change |encrypted_types_| directly to avoid sending more than one
384 // notification.
385 *encrypted_types = UserTypes();
386 FOR_EACH_OBSERVER(
387 Observer, observers_,
388 OnEncryptedTypesChanged(*encrypted_types, encrypt_everything_));
389 WriteEncryptionStateToNigori(&trans); 477 WriteEncryptionStateToNigori(&trans);
390 if (UnlockVault(trans.GetWrappedTrans()).cryptographer.is_ready()) 478 if (UnlockVault(trans.GetWrappedTrans()).cryptographer.is_ready())
391 ReEncryptEverything(&trans); 479 ReEncryptEverything(&trans);
392 } 480 }
393 481
394 bool SyncEncryptionHandlerImpl::EncryptEverythingEnabled() const { 482 bool SyncEncryptionHandlerImpl::EncryptEverythingEnabled() const {
395 DCHECK(thread_checker_.CalledOnValidThread()); 483 DCHECK(thread_checker_.CalledOnValidThread());
396 return encrypt_everything_; 484 return encrypt_everything_;
397 } 485 }
398 486
399 PassphraseState SyncEncryptionHandlerImpl::GetPassphraseState() const { 487 PassphraseType SyncEncryptionHandlerImpl::GetPassphraseType() const {
400 DCHECK(thread_checker_.CalledOnValidThread()); 488 DCHECK(thread_checker_.CalledOnValidThread());
401 return passphrase_state_; 489 return passphrase_type_;
402 } 490 }
403 491
404 // Note: this is called from within a syncable transaction, so we need to post 492 // Note: this is called from within a syncable transaction, so we need to post
405 // tasks if we want to do any work that creates a new sync_api transaction. 493 // tasks if we want to do any work that creates a new sync_api transaction.
406 void SyncEncryptionHandlerImpl::ApplyNigoriUpdate( 494 void SyncEncryptionHandlerImpl::ApplyNigoriUpdate(
407 const sync_pb::NigoriSpecifics& nigori, 495 const sync_pb::NigoriSpecifics& nigori,
408 syncable::BaseTransaction* const trans) { 496 syncable::BaseTransaction* const trans) {
409 DCHECK(thread_checker_.CalledOnValidThread()); 497 DCHECK(thread_checker_.CalledOnValidThread());
410 DCHECK(trans); 498 DCHECK(trans);
411 if (!ApplyNigoriUpdateImpl(nigori, trans)) { 499 if (!ApplyNigoriUpdateImpl(nigori, trans)) {
412 MessageLoop::current()->PostTask( 500 MessageLoop::current()->PostTask(
413 FROM_HERE, 501 FROM_HERE,
414 base::Bind(&SyncEncryptionHandlerImpl::RewriteNigori, 502 base::Bind(&SyncEncryptionHandlerImpl::RewriteNigori,
415 weak_ptr_factory_.GetWeakPtr())); 503 weak_ptr_factory_.GetWeakPtr()));
416 } 504 }
417 505
418 FOR_EACH_OBSERVER( 506 FOR_EACH_OBSERVER(
419 SyncEncryptionHandler::Observer, 507 SyncEncryptionHandler::Observer,
420 observers_, 508 observers_,
421 OnCryptographerStateChanged( 509 OnCryptographerStateChanged(
422 &UnlockVaultMutable(trans)->cryptographer)); 510 &UnlockVaultMutable(trans)->cryptographer));
423 } 511 }
424 512
425 void SyncEncryptionHandlerImpl::UpdateNigoriFromEncryptedTypes( 513 void SyncEncryptionHandlerImpl::UpdateNigoriFromEncryptedTypes(
426 sync_pb::NigoriSpecifics* nigori, 514 sync_pb::NigoriSpecifics* nigori,
427 syncable::BaseTransaction* const trans) const { 515 syncable::BaseTransaction* const trans) const {
516 DCHECK(thread_checker_.CalledOnValidThread());
428 syncable::UpdateNigoriFromEncryptedTypes(UnlockVault(trans).encrypted_types, 517 syncable::UpdateNigoriFromEncryptedTypes(UnlockVault(trans).encrypted_types,
429 encrypt_everything_, 518 encrypt_everything_,
430 nigori); 519 nigori);
431 } 520 }
432 521
433 bool SyncEncryptionHandlerImpl::NeedKeystoreKey( 522 bool SyncEncryptionHandlerImpl::NeedKeystoreKey(
434 syncable::BaseTransaction* const trans) const { 523 syncable::BaseTransaction* const trans) const {
524 DCHECK(thread_checker_.CalledOnValidThread());
435 return keystore_key_.empty(); 525 return keystore_key_.empty();
436 } 526 }
437 527
438 bool SyncEncryptionHandlerImpl::SetKeystoreKey( 528 bool SyncEncryptionHandlerImpl::SetKeystoreKey(
439 const std::string& key, 529 const std::string& key,
440 syncable::BaseTransaction* const trans) { 530 syncable::BaseTransaction* const trans) {
531 DCHECK(thread_checker_.CalledOnValidThread());
441 if (!keystore_key_.empty() || key.empty()) 532 if (!keystore_key_.empty() || key.empty())
442 return false; 533 return false;
443 keystore_key_ = key; 534 keystore_key_ = key;
444 535
445 // TODO(zea): trigger migration if necessary.
446
447 DVLOG(1) << "Keystore bootstrap token updated."; 536 DVLOG(1) << "Keystore bootstrap token updated.";
448 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, 537 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
449 OnBootstrapTokenUpdated(key, 538 OnBootstrapTokenUpdated(key,
450 KEYSTORE_BOOTSTRAP_TOKEN)); 539 KEYSTORE_BOOTSTRAP_TOKEN));
540
541 Cryptographer* cryptographer = &UnlockVaultMutable(trans)->cryptographer;
542 syncable::Entry entry(trans, syncable::GET_BY_SERVER_TAG, kNigoriTag);
543 if (entry.good()) {
544 const sync_pb::NigoriSpecifics& nigori =
545 entry.Get(syncable::SPECIFICS).nigori();
546 if (cryptographer->has_pending_keys() &&
547 IsNigoriMigratedToKeystore(nigori) &&
548 !nigori.keystore_decryptor_token().blob().empty()) {
549 // If the nigori is already migrated and we have pending keys, we might
550 // be able to decrypt them using the keystore decryptor token.
551 DecryptPendingKeysWithKeystoreKey(keystore_key_,
552 nigori.keystore_decryptor_token(),
553 cryptographer);
554 } else if (ShouldTriggerMigration(nigori, *cryptographer)) {
555 // We call rewrite nigori to attempt to trigger migration.
556 // Need to post a task to open a new sync_api transaction.
557 MessageLoop::current()->PostTask(
558 FROM_HERE,
559 base::Bind(&SyncEncryptionHandlerImpl::RewriteNigori,
560 weak_ptr_factory_.GetWeakPtr()));
561 }
562 }
563
451 return true; 564 return true;
452 } 565 }
453 566
454 ModelTypeSet SyncEncryptionHandlerImpl::GetEncryptedTypes( 567 ModelTypeSet SyncEncryptionHandlerImpl::GetEncryptedTypes(
455 syncable::BaseTransaction* const trans) const { 568 syncable::BaseTransaction* const trans) const {
456 return UnlockVault(trans).encrypted_types; 569 return UnlockVault(trans).encrypted_types;
457 } 570 }
458 571
459 Cryptographer* SyncEncryptionHandlerImpl::GetCryptographerUnsafe() { 572 Cryptographer* SyncEncryptionHandlerImpl::GetCryptographerUnsafe() {
460 DCHECK(thread_checker_.CalledOnValidThread()); 573 DCHECK(thread_checker_.CalledOnValidThread());
461 return &vault_unsafe_.cryptographer; 574 return &vault_unsafe_.cryptographer;
462 } 575 }
463 576
464 ModelTypeSet SyncEncryptionHandlerImpl::GetEncryptedTypesUnsafe() { 577 ModelTypeSet SyncEncryptionHandlerImpl::GetEncryptedTypesUnsafe() {
465 DCHECK(thread_checker_.CalledOnValidThread()); 578 DCHECK(thread_checker_.CalledOnValidThread());
466 return vault_unsafe_.encrypted_types; 579 return vault_unsafe_.encrypted_types;
467 } 580 }
468 581
582 bool SyncEncryptionHandlerImpl::MigratedToKeystore() {
583 DCHECK(thread_checker_.CalledOnValidThread());
584 ReadTransaction trans(FROM_HERE, user_share_);
585 ReadNode nigori_node(&trans);
586 if (nigori_node.InitByTagLookup(kNigoriTag) != BaseNode::INIT_OK)
587 return false;
588 return IsNigoriMigratedToKeystore(nigori_node.GetNigoriSpecifics());
589 }
590
469 // This function iterates over all encrypted types. There are many scenarios in 591 // This function iterates over all encrypted types. There are many scenarios in
470 // which data for some or all types is not currently available. In that case, 592 // which data for some or all types is not currently available. In that case,
471 // the lookup of the root node will fail and we will skip encryption for that 593 // the lookup of the root node will fail and we will skip encryption for that
472 // type. 594 // type.
473 void SyncEncryptionHandlerImpl::ReEncryptEverything( 595 void SyncEncryptionHandlerImpl::ReEncryptEverything(
474 WriteTransaction* trans) { 596 WriteTransaction* trans) {
475 DCHECK(thread_checker_.CalledOnValidThread()); 597 DCHECK(thread_checker_.CalledOnValidThread());
476 DCHECK(UnlockVault(trans->GetWrappedTrans()).cryptographer.is_ready()); 598 DCHECK(UnlockVault(trans->GetWrappedTrans()).cryptographer.is_ready());
477 for (ModelTypeSet::Iterator iter = 599 for (ModelTypeSet::Iterator iter =
478 UnlockVault(trans->GetWrappedTrans()).encrypted_types.First(); 600 UnlockVault(trans->GetWrappedTrans()).encrypted_types.First();
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 OnEncryptionComplete()); 659 OnEncryptionComplete());
538 } 660 }
539 661
540 bool SyncEncryptionHandlerImpl::ApplyNigoriUpdateImpl( 662 bool SyncEncryptionHandlerImpl::ApplyNigoriUpdateImpl(
541 const sync_pb::NigoriSpecifics& nigori, 663 const sync_pb::NigoriSpecifics& nigori,
542 syncable::BaseTransaction* const trans) { 664 syncable::BaseTransaction* const trans) {
543 DCHECK(thread_checker_.CalledOnValidThread()); 665 DCHECK(thread_checker_.CalledOnValidThread());
544 DVLOG(1) << "Applying nigori node update."; 666 DVLOG(1) << "Applying nigori node update.";
545 bool nigori_types_need_update = !UpdateEncryptedTypesFromNigori(nigori, 667 bool nigori_types_need_update = !UpdateEncryptedTypesFromNigori(nigori,
546 trans); 668 trans);
547 if (nigori.using_explicit_passphrase() && 669 bool is_nigori_migrated = IsNigoriMigratedToKeystore(nigori);
548 passphrase_state_ != CUSTOM_PASSPHRASE) { 670 if (is_nigori_migrated) {
549 passphrase_state_ = CUSTOM_PASSPHRASE; 671 migration_time_ms_ = nigori.keystore_migration_time();
550 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, 672 PassphraseType nigori_passphrase_type =
551 OnPassphraseStateChanged(passphrase_state_)); 673 ProtoPassphraseTypeToEnum(nigori.passphrase_type());
674
675 // Only update the local passphrase state if it's a valid transition:
676 // - implicit -> keystore
677 // - implicit -> frozen implicit
678 // - implicit -> custom
679 // - keystore -> custom
680 // Note: frozen implicit -> custom is not technically a valid transition,
681 // but we let it through here as well in case future versions do add support
682 // for this transition.
683 if (passphrase_type_ != nigori_passphrase_type &&
684 nigori_passphrase_type != IMPLICIT_PASSPHRASE &&
685 (passphrase_type_ == IMPLICIT_PASSPHRASE ||
686 nigori_passphrase_type == CUSTOM_PASSPHRASE)) {
687 DVLOG(1) << "Changing passphrase state from "
688 << PassphraseTypeToString(passphrase_type_)
689 << " to "
690 << PassphraseTypeToString(nigori_passphrase_type);
691 passphrase_type_ = nigori_passphrase_type;
692 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
693 OnPassphraseTypeChanged(passphrase_type_));
694 }
695 if (passphrase_type_ == KEYSTORE_PASSPHRASE && encrypt_everything_) {
696 // This is the case where another client that didn't support keystore
697 // encryption attempted to enable full encryption. We detect it
698 // and switch the passphrase type to frozen implicit passphrase instead
699 // due to full encryption not being compatible with keystore passphrase.
700 // Because the local passphrase type will not match the nigori passphrase
701 // type, we will trigger a rewrite and subsequently a re-migration.
702 DVLOG(1) << "Changing passphrase state to FROZEN_IMPLICIT_PASSPHRASE "
703 << "due to full encryption.";
704 passphrase_type_ = FROZEN_IMPLICIT_PASSPHRASE;
705 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
706 OnPassphraseTypeChanged(passphrase_type_));
707 }
708 } else {
709 // It's possible that while we're waiting for migration a client that does
710 // not have keystore encryption enabled switches to a custom passphrase.
711 if (nigori.keybag_is_frozen() &&
712 passphrase_type_ != CUSTOM_PASSPHRASE) {
713 passphrase_type_ = CUSTOM_PASSPHRASE;
714 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
715 OnPassphraseTypeChanged(passphrase_type_));
716 }
552 } 717 }
553 718
554 Cryptographer* cryptographer = &UnlockVaultMutable(trans)->cryptographer; 719 Cryptographer* cryptographer = &UnlockVaultMutable(trans)->cryptographer;
555 bool nigori_needs_new_keys = false; 720 bool nigori_needs_new_keys = false;
556 if (!nigori.encrypted().blob().empty()) { 721 if (!nigori.encryption_keybag().blob().empty()) {
557 if (cryptographer->CanDecrypt(nigori.encrypted())) { 722 // We only update the default key if this was a new explicit passphrase.
558 cryptographer->InstallKeys(nigori.encrypted()); 723 // Else, since it was decryptable, it must not have been a new key.
559 // We only update the default passphrase if this was a new explicit 724 bool need_new_default_key = false;
560 // passphrase. Else, since it was decryptable, it must not have been a new 725 if (is_nigori_migrated) {
561 // key. 726 need_new_default_key = IsExplicitPassphrase(
562 if (nigori.using_explicit_passphrase()) 727 ProtoPassphraseTypeToEnum(nigori.passphrase_type()));
563 cryptographer->SetDefaultKey(nigori.encrypted().key_name());
564
565 // Check if the cryptographer's keybag is newer than the nigori's
566 // keybag. If so, we need to overwrite the nigori node.
567 sync_pb::EncryptedData new_keys = nigori.encrypted();
568 if (!cryptographer->GetKeys(&new_keys))
569 NOTREACHED();
570 if (nigori.encrypted().SerializeAsString() !=
571 new_keys.SerializeAsString())
572 nigori_needs_new_keys = true;
573 } else { 728 } else {
574 cryptographer->SetPendingKeys(nigori.encrypted()); 729 need_new_default_key = nigori.keybag_is_frozen();
730 }
731 if (!AttemptToInstallKeybag(nigori.encryption_keybag(),
732 need_new_default_key,
733 cryptographer)) {
734 // Check to see if we can decrypt the keybag using the keystore decryptor
735 // token.
736 cryptographer->SetPendingKeys(nigori.encryption_keybag());
737 if (!nigori.keystore_decryptor_token().blob().empty() &&
738 !keystore_key_.empty()) {
739 if (DecryptPendingKeysWithKeystoreKey(keystore_key_,
740 nigori.keystore_decryptor_token(),
741 cryptographer)) {
742 nigori_needs_new_keys =
743 cryptographer->KeybagIsStale(nigori.encryption_keybag());
744 } else {
745 LOG(ERROR) << "Failed to decrypt pending keys using keystore "
746 << "bootstrap key.";
747 }
748 }
749 } else {
750 // Keybag was installed. We write back our local keybag into the nigori
751 // node if the nigori node's keybag either contains less keys or
752 // has a different default key.
753 nigori_needs_new_keys =
754 cryptographer->KeybagIsStale(nigori.encryption_keybag());
575 } 755 }
576 } else { 756 } else {
757 // The nigori node has an empty encryption keybag. Attempt to write our
758 // local encryption keys into it.
759 LOG(WARNING) << "Nigori had empty encryption keybag.";
577 nigori_needs_new_keys = true; 760 nigori_needs_new_keys = true;
578 } 761 }
579 762
580 // If we've completed a sync cycle and the cryptographer isn't ready 763 // If we've completed a sync cycle and the cryptographer isn't ready
581 // yet or has pending keys, prompt the user for a passphrase. 764 // yet or has pending keys, prompt the user for a passphrase.
582 if (cryptographer->has_pending_keys()) { 765 if (cryptographer->has_pending_keys()) {
583 DVLOG(1) << "OnPassphraseRequired Sent"; 766 DVLOG(1) << "OnPassphraseRequired Sent";
584 sync_pb::EncryptedData pending_keys = cryptographer->GetPendingKeys(); 767 sync_pb::EncryptedData pending_keys = cryptographer->GetPendingKeys();
585 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, 768 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
586 OnPassphraseRequired(REASON_DECRYPTION, 769 OnPassphraseRequired(REASON_DECRYPTION,
587 pending_keys)); 770 pending_keys));
588 } else if (!cryptographer->is_ready()) { 771 } else if (!cryptographer->is_ready()) {
589 DVLOG(1) << "OnPassphraseRequired sent because cryptographer is not " 772 DVLOG(1) << "OnPassphraseRequired sent because cryptographer is not "
590 << "ready"; 773 << "ready";
591 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, 774 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
592 OnPassphraseRequired(REASON_ENCRYPTION, 775 OnPassphraseRequired(REASON_ENCRYPTION,
593 sync_pb::EncryptedData())); 776 sync_pb::EncryptedData()));
594 } 777 }
595 778
596 // Check if the current local encryption state is stricter/newer than the 779 // Check if the current local encryption state is stricter/newer than the
597 // nigori state. If so, we need to overwrite the nigori node with the local 780 // nigori state. If so, we need to overwrite the nigori node with the local
598 // state. 781 // state.
599 bool explicit_passphrase = passphrase_state_ == CUSTOM_PASSPHRASE; 782 bool passphrase_type_matches = true;
600 if (nigori.using_explicit_passphrase() != explicit_passphrase || 783 if (!is_nigori_migrated) {
784 DCHECK(passphrase_type_ == CUSTOM_PASSPHRASE ||
785 passphrase_type_ == IMPLICIT_PASSPHRASE);
786 passphrase_type_matches =
787 nigori.keybag_is_frozen() == IsExplicitPassphrase(passphrase_type_);
788 } else {
789 passphrase_type_matches =
790 (ProtoPassphraseTypeToEnum(nigori.passphrase_type()) ==
791 passphrase_type_);
792 }
793 if (!passphrase_type_matches ||
601 nigori.encrypt_everything() != encrypt_everything_ || 794 nigori.encrypt_everything() != encrypt_everything_ ||
602 nigori_types_need_update || 795 nigori_types_need_update ||
603 nigori_needs_new_keys) { 796 nigori_needs_new_keys) {
797 DVLOG(1) << "Triggering nigori rewrite.";
604 return false; 798 return false;
605 } 799 }
606 return true; 800 return true;
607 } 801 }
608 802
609 void SyncEncryptionHandlerImpl::RewriteNigori() { 803 void SyncEncryptionHandlerImpl::RewriteNigori() {
610 DVLOG(1) << "Overwriting stale nigori node."; 804 DVLOG(1) << "Writing local encryption state into nigori.";
611 DCHECK(thread_checker_.CalledOnValidThread()); 805 DCHECK(thread_checker_.CalledOnValidThread());
612 WriteTransaction trans(FROM_HERE, user_share_); 806 WriteTransaction trans(FROM_HERE, user_share_);
613 WriteEncryptionStateToNigori(&trans); 807 WriteEncryptionStateToNigori(&trans);
614 } 808 }
615 809
616 void SyncEncryptionHandlerImpl::WriteEncryptionStateToNigori( 810 void SyncEncryptionHandlerImpl::WriteEncryptionStateToNigori(
617 WriteTransaction* trans) { 811 WriteTransaction* trans) {
618 DCHECK(thread_checker_.CalledOnValidThread()); 812 DCHECK(thread_checker_.CalledOnValidThread());
619 WriteNode nigori_node(trans); 813 WriteNode nigori_node(trans);
620 // This can happen in tests that don't have nigori nodes. 814 // This can happen in tests that don't have nigori nodes.
621 if (nigori_node.InitByTagLookup(kNigoriTag) != BaseNode::INIT_OK) 815 if (nigori_node.InitByTagLookup(kNigoriTag) != BaseNode::INIT_OK)
622 return; 816 return;
817
623 sync_pb::NigoriSpecifics nigori = nigori_node.GetNigoriSpecifics(); 818 sync_pb::NigoriSpecifics nigori = nigori_node.GetNigoriSpecifics();
624 const Cryptographer& cryptographer = 819 const Cryptographer& cryptographer =
625 UnlockVault(trans->GetWrappedTrans()).cryptographer; 820 UnlockVault(trans->GetWrappedTrans()).cryptographer;
626 if (cryptographer.is_ready() &&
627 nigori_overwrite_count_ < kNigoriOverwriteLimit) {
628 // Does not modify the encrypted blob if the unencrypted data already
629 // matches what is about to be written.
630 sync_pb::EncryptedData original_keys = nigori.encrypted();
631 if (!cryptographer.GetKeys(nigori.mutable_encrypted()))
632 NOTREACHED();
633 821
634 if (nigori.encrypted().SerializeAsString() != 822 // Will not do anything if we shouldn't or can't migrate. Otherwise
635 original_keys.SerializeAsString()) { 823 // migrates, writing the full encryption state as it does.
636 // We've updated the nigori node's encryption keys. In order to prevent 824 if (!AttemptToMigrateNigoriToKeystore(trans, &nigori_node)) {
637 // a possible looping of two clients constantly overwriting each other, 825 if (cryptographer.is_ready() &&
638 // we limit the absolute number of overwrites per client instantiation. 826 nigori_overwrite_count_ < kNigoriOverwriteLimit) {
639 nigori_overwrite_count_++; 827 // Does not modify the encrypted blob if the unencrypted data already
640 UMA_HISTOGRAM_COUNTS("Sync.AutoNigoriOverwrites", 828 // matches what is about to be written.
641 nigori_overwrite_count_); 829 sync_pb::EncryptedData original_keys = nigori.encryption_keybag();
830 if (!cryptographer.GetKeys(nigori.mutable_encryption_keybag()))
831 NOTREACHED();
832
833 if (nigori.encryption_keybag().SerializeAsString() !=
834 original_keys.SerializeAsString()) {
835 // We've updated the nigori node's encryption keys. In order to prevent
836 // a possible looping of two clients constantly overwriting each other,
837 // we limit the absolute number of overwrites per client instantiation.
838 nigori_overwrite_count_++;
839 UMA_HISTOGRAM_COUNTS("Sync.AutoNigoriOverwrites",
840 nigori_overwrite_count_);
841 }
842
843 // Note: we don't try to set keybag_is_frozen here since if that
844 // is lost the user can always set it again (and we don't want to clobber
845 // any migration state). The main goal at this point is to preserve
846 // the encryption keys so all data remains decryptable.
642 } 847 }
848 syncable::UpdateNigoriFromEncryptedTypes(
849 UnlockVault(trans->GetWrappedTrans()).encrypted_types,
850 encrypt_everything_,
851 &nigori);
643 852
644 // Note: we don't try to set using_explicit_passphrase here since if that 853 // If nothing has changed, this is a no-op.
645 // is lost the user can always set it again. The main point is to preserve 854 nigori_node.SetNigoriSpecifics(nigori);
646 // the encryption keys so all data remains decryptable.
647 } 855 }
648 syncable::UpdateNigoriFromEncryptedTypes(
649 UnlockVault(trans->GetWrappedTrans()).encrypted_types,
650 encrypt_everything_,
651 &nigori);
652
653 // If nothing has changed, this is a no-op.
654 nigori_node.SetNigoriSpecifics(nigori);
655 } 856 }
656 857
657 bool SyncEncryptionHandlerImpl::UpdateEncryptedTypesFromNigori( 858 bool SyncEncryptionHandlerImpl::UpdateEncryptedTypesFromNigori(
658 const sync_pb::NigoriSpecifics& nigori, 859 const sync_pb::NigoriSpecifics& nigori,
659 syncable::BaseTransaction* const trans) { 860 syncable::BaseTransaction* const trans) {
660 DCHECK(thread_checker_.CalledOnValidThread()); 861 DCHECK(thread_checker_.CalledOnValidThread());
661 ModelTypeSet* encrypted_types = &UnlockVaultMutable(trans)->encrypted_types; 862 ModelTypeSet* encrypted_types = &UnlockVaultMutable(trans)->encrypted_types;
662 if (nigori.encrypt_everything()) { 863 if (nigori.encrypt_everything()) {
663 if (!encrypt_everything_) { 864 EnableEncryptEverythingImpl(trans);
664 encrypt_everything_ = true;
665 *encrypted_types = UserTypes();
666 DVLOG(1) << "Enabling encrypt everything via nigori node update";
667 FOR_EACH_OBSERVER(
668 Observer, observers_,
669 OnEncryptedTypesChanged(*encrypted_types, encrypt_everything_));
670 }
671 DCHECK(encrypted_types->Equals(UserTypes())); 865 DCHECK(encrypted_types->Equals(UserTypes()));
672 return true; 866 return true;
867 } else if (encrypt_everything_) {
868 DCHECK(encrypted_types->Equals(UserTypes()));
869 return false;
673 } 870 }
674 871
675 ModelTypeSet nigori_encrypted_types; 872 ModelTypeSet nigori_encrypted_types;
676 nigori_encrypted_types = syncable::GetEncryptedTypesFromNigori(nigori); 873 nigori_encrypted_types = syncable::GetEncryptedTypesFromNigori(nigori);
677 nigori_encrypted_types.PutAll(SensitiveTypes()); 874 nigori_encrypted_types.PutAll(SensitiveTypes());
678 875
679 // If anything more than the sensitive types were encrypted, and 876 // If anything more than the sensitive types were encrypted, and
680 // encrypt_everything is not explicitly set to false, we assume it means 877 // encrypt_everything is not explicitly set to false, we assume it means
681 // a client intended to enable encrypt everything. 878 // a client intended to enable encrypt everything.
682 if (!nigori.has_encrypt_everything() && 879 if (!nigori.has_encrypt_everything() &&
683 !Difference(nigori_encrypted_types, SensitiveTypes()).Empty()) { 880 !Difference(nigori_encrypted_types, SensitiveTypes()).Empty()) {
684 if (!encrypt_everything_) { 881 if (!encrypt_everything_) {
685 encrypt_everything_ = true; 882 encrypt_everything_ = true;
686 *encrypted_types = UserTypes(); 883 *encrypted_types = UserTypes();
687 FOR_EACH_OBSERVER( 884 FOR_EACH_OBSERVER(
688 Observer, observers_, 885 Observer, observers_,
689 OnEncryptedTypesChanged(*encrypted_types, encrypt_everything_)); 886 OnEncryptedTypesChanged(*encrypted_types, encrypt_everything_));
690 } 887 }
691 DCHECK(encrypted_types->Equals(UserTypes())); 888 DCHECK(encrypted_types->Equals(UserTypes()));
692 return false; 889 return false;
693 } 890 }
694 891
695 MergeEncryptedTypes(nigori_encrypted_types, trans); 892 MergeEncryptedTypes(nigori_encrypted_types, trans);
696 return encrypted_types->Equals(nigori_encrypted_types); 893 return encrypted_types->Equals(nigori_encrypted_types);
697 } 894 }
698 895
896 void SyncEncryptionHandlerImpl::SetCustomPassphrase(
897 const std::string& passphrase,
898 WriteTransaction* trans,
899 WriteNode* nigori_node) {
900 DCHECK(thread_checker_.CalledOnValidThread());
901 DCHECK(IsNigoriMigratedToKeystore(nigori_node->GetNigoriSpecifics()));
902 KeyParams key_params = {"localhost", "dummy", passphrase};
903
904 if (passphrase_type_ != KEYSTORE_PASSPHRASE) {
905 DVLOG(1) << "Failing to set a custom passphrase because one has already "
906 << "been set.";
907 FinishSetPassphrase(false, "", trans, nigori_node);
908 return;
909 }
910
911 Cryptographer* cryptographer =
912 &UnlockVaultMutable(trans->GetWrappedTrans())->cryptographer;
913 if (cryptographer->has_pending_keys()) {
914 // This theoretically shouldn't happen, because the only way to have pending
915 // keys after migrating to keystore support is if a custom passphrase was
916 // set, which should update passpshrase_state_ and should be caught by the
917 // if statement above. For the sake of safety though, we check for it in
918 // case a client is misbehaving.
919 LOG(ERROR) << "Failing to set custom passphrase because of pending keys.";
920 FinishSetPassphrase(false, "", trans, nigori_node);
921 return;
922 }
923
924 std::string bootstrap_token;
925 if (cryptographer->AddKey(key_params)) {
926 DVLOG(1) << "Setting custom passphrase.";
927 cryptographer->GetBootstrapToken(&bootstrap_token);
928 passphrase_type_ = CUSTOM_PASSPHRASE;
929 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
930 OnPassphraseTypeChanged(passphrase_type_));
931 } else {
932 NOTREACHED() << "Failed to add key to cryptographer.";
933 return;
934 }
935 FinishSetPassphrase(true, bootstrap_token, trans, nigori_node);
936 }
937
938 void SyncEncryptionHandlerImpl::DecryptPendingKeysWithExplicitPassphrase(
939 const std::string& passphrase,
940 WriteTransaction* trans,
941 WriteNode* nigori_node) {
942 DCHECK(thread_checker_.CalledOnValidThread());
943 DCHECK(IsExplicitPassphrase(passphrase_type_));
944 KeyParams key_params = {"localhost", "dummy", passphrase};
945
946 Cryptographer* cryptographer =
947 &UnlockVaultMutable(trans->GetWrappedTrans())->cryptographer;
948 if (!cryptographer->has_pending_keys()) {
949 // Note that this *can* happen in a rare situation where data is
950 // re-encrypted on another client while a SetDecryptionPassphrase() call is
951 // in-flight on this client. It is rare enough that we choose to do nothing.
952 NOTREACHED() << "Attempt to set decryption passphrase failed because there "
953 << "were no pending keys.";
954 return;
955 }
956
957 DCHECK(IsExplicitPassphrase(passphrase_type_));
958 bool success = false;
959 std::string bootstrap_token;
960 if (cryptographer->DecryptPendingKeys(key_params)) {
961 DVLOG(1) << "Explicit passphrase accepted for decryption.";
962 cryptographer->GetBootstrapToken(&bootstrap_token);
963 success = true;
964 } else {
965 DVLOG(1) << "Explicit passphrase failed to decrypt.";
966 success = false;
967 }
968 if (success && !keystore_key_.empty()) {
969 // Should already be part of the encryption keybag, but we add it just
970 // in case.
971 KeyParams key_params = {"localhost", "dummy", keystore_key_};
972 cryptographer->AddNonDefaultKey(key_params);
973 }
974 FinishSetPassphrase(success, bootstrap_token, trans, nigori_node);
975 }
976
699 void SyncEncryptionHandlerImpl::FinishSetPassphrase( 977 void SyncEncryptionHandlerImpl::FinishSetPassphrase(
700 bool success, 978 bool success,
701 const std::string& bootstrap_token, 979 const std::string& bootstrap_token,
702 bool is_explicit,
703 WriteTransaction* trans, 980 WriteTransaction* trans,
704 WriteNode* nigori_node) { 981 WriteNode* nigori_node) {
705 DCHECK(thread_checker_.CalledOnValidThread()); 982 DCHECK(thread_checker_.CalledOnValidThread());
706 FOR_EACH_OBSERVER( 983 FOR_EACH_OBSERVER(
707 SyncEncryptionHandler::Observer, 984 SyncEncryptionHandler::Observer,
708 observers_, 985 observers_,
709 OnCryptographerStateChanged( 986 OnCryptographerStateChanged(
710 &UnlockVaultMutable(trans->GetWrappedTrans())->cryptographer)); 987 &UnlockVaultMutable(trans->GetWrappedTrans())->cryptographer));
711 988
712 // It's possible we need to change the bootstrap token even if we failed to 989 // It's possible we need to change the bootstrap token even if we failed to
(...skipping 16 matching lines...) Expand all
729 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, 1006 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
730 OnPassphraseRequired(REASON_DECRYPTION, 1007 OnPassphraseRequired(REASON_DECRYPTION,
731 cryptographer.GetPendingKeys())); 1008 cryptographer.GetPendingKeys()));
732 } else { 1009 } else {
733 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, 1010 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
734 OnPassphraseRequired(REASON_ENCRYPTION, 1011 OnPassphraseRequired(REASON_ENCRYPTION,
735 sync_pb::EncryptedData())); 1012 sync_pb::EncryptedData()));
736 } 1013 }
737 return; 1014 return;
738 } 1015 }
739 1016 DCHECK(success);
740 DCHECK(cryptographer.is_ready()); 1017 DCHECK(cryptographer.is_ready());
741 1018
742 // TODO(zea): trigger migration if necessary. 1019 // Will do nothing if we're already properly migrated or unable to migrate
1020 // (in otherwords, if ShouldTriggerMigration is false).
1021 // Otherwise will update the nigori node with the current migrated state,
1022 // writing all encryption state as it does.
1023 if (!AttemptToMigrateNigoriToKeystore(trans, nigori_node)) {
1024 sync_pb::NigoriSpecifics nigori(nigori_node->GetNigoriSpecifics());
1025 // Does not modify nigori.encryption_keybag() if the original decrypted
1026 // data was the same.
1027 if (!cryptographer.GetKeys(nigori.mutable_encryption_keybag()))
1028 NOTREACHED();
1029 if (IsNigoriMigratedToKeystore(nigori)) {
1030 DCHECK(keystore_key_.empty() || IsExplicitPassphrase(passphrase_type_));
1031 DVLOG(1) << "Leaving nigori migration state untouched after setting"
1032 << " passphrase.";
1033 } else {
1034 nigori.set_keybag_is_frozen(
1035 IsExplicitPassphrase(passphrase_type_));
1036 }
1037 nigori_node->SetNigoriSpecifics(nigori);
1038 }
743 1039
744 sync_pb::NigoriSpecifics specifics(nigori_node->GetNigoriSpecifics()); 1040 // Must do this after OnPassphraseTypeChanged, in order to ensure the PSS
745 // Does not modify specifics.encrypted() if the original decrypted data was
746 // the same.
747 if (!cryptographer.GetKeys(specifics.mutable_encrypted()))
748 NOTREACHED();
749 if (is_explicit && passphrase_state_ != CUSTOM_PASSPHRASE) {
750 passphrase_state_ = CUSTOM_PASSPHRASE;
751 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
752 OnPassphraseStateChanged(passphrase_state_));
753 }
754 specifics.set_using_explicit_passphrase(is_explicit);
755 nigori_node->SetNigoriSpecifics(specifics);
756
757 // Must do this after OnPassphraseStateChanged, in order to ensure the PSS
758 // checks the passphrase state after it has been set. 1041 // checks the passphrase state after it has been set.
759 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, 1042 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
760 OnPassphraseAccepted()); 1043 OnPassphraseAccepted());
761 1044
762 // Does nothing if everything is already encrypted. 1045 // Does nothing if everything is already encrypted.
1046 // TODO(zea): If we just migrated and enabled encryption, this will be
1047 // redundant. Figure out a way to not do this unnecessarily.
763 ReEncryptEverything(trans); 1048 ReEncryptEverything(trans);
764 } 1049 }
765 1050
766 void SyncEncryptionHandlerImpl::MergeEncryptedTypes( 1051 void SyncEncryptionHandlerImpl::MergeEncryptedTypes(
767 ModelTypeSet new_encrypted_types, 1052 ModelTypeSet new_encrypted_types,
768 syncable::BaseTransaction* const trans) { 1053 syncable::BaseTransaction* const trans) {
769 DCHECK(thread_checker_.CalledOnValidThread()); 1054 DCHECK(thread_checker_.CalledOnValidThread());
770 1055
771 // Only UserTypes may be encrypted. 1056 // Only UserTypes may be encrypted.
772 DCHECK(UserTypes().HasAll(new_encrypted_types)); 1057 DCHECK(UserTypes().HasAll(new_encrypted_types));
(...skipping 12 matching lines...) Expand all
785 DCHECK_EQ(user_share_->directory.get(), trans->directory()); 1070 DCHECK_EQ(user_share_->directory.get(), trans->directory());
786 return &vault_unsafe_; 1071 return &vault_unsafe_;
787 } 1072 }
788 1073
789 const SyncEncryptionHandlerImpl::Vault& SyncEncryptionHandlerImpl::UnlockVault( 1074 const SyncEncryptionHandlerImpl::Vault& SyncEncryptionHandlerImpl::UnlockVault(
790 syncable::BaseTransaction* const trans) const { 1075 syncable::BaseTransaction* const trans) const {
791 DCHECK_EQ(user_share_->directory.get(), trans->directory()); 1076 DCHECK_EQ(user_share_->directory.get(), trans->directory());
792 return vault_unsafe_; 1077 return vault_unsafe_;
793 } 1078 }
794 1079
1080 bool SyncEncryptionHandlerImpl::ShouldTriggerMigration(
1081 const sync_pb::NigoriSpecifics& nigori,
1082 const Cryptographer& cryptographer) const {
1083 DCHECK(thread_checker_.CalledOnValidThread());
1084 // TODO(zea): once we're willing to have the keystore key be the only
1085 // encryption key, change this to !has_pending_keys(). For now, we need the
1086 // cryptographer to be initialized with the current GAIA pass so that older
1087 // clients (that don't have keystore support) can decrypt the keybag.
1088 if (!cryptographer.is_ready())
1089 return false;
1090 if (IsNigoriMigratedToKeystore(nigori)) {
1091 // If the nigori is already migrated but does not reflect the explicit
1092 // passphrase state, remigrate. Similarly, if the nigori has an explicit
1093 // passphrase but does not have full encryption, or the nigori has an
1094 // implicit passphrase but does have full encryption, re-migrate.
1095 // Note that this is to defend against other clients without keystore
1096 // encryption enabled transitioning to states that are no longer valid.
1097 if (passphrase_type_ != KEYSTORE_PASSPHRASE &&
1098 nigori.passphrase_type() ==
1099 sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE) {
1100 return true;
1101 } else if (IsExplicitPassphrase(passphrase_type_) &&
1102 !encrypt_everything_) {
1103 return true;
1104 } else if (passphrase_type_ == KEYSTORE_PASSPHRASE &&
1105 encrypt_everything_) {
1106 return true;
1107 } else {
1108 return false;
1109 }
1110 } else if (keystore_key_.empty()) {
1111 // If we haven't already migrated, we don't want to do anything unless
1112 // a keystore key is available (so that those clients without keystore
1113 // encryption enabled aren't forced into new states, e.g. frozen implicit
1114 // passphrase).
1115 return false;
1116 }
1117 return true;
1118 }
1119
1120 bool SyncEncryptionHandlerImpl::AttemptToMigrateNigoriToKeystore(
1121 WriteTransaction* trans,
1122 WriteNode* nigori_node) {
1123 DCHECK(thread_checker_.CalledOnValidThread());
1124 const sync_pb::NigoriSpecifics& old_nigori =
1125 nigori_node->GetNigoriSpecifics();
1126 Cryptographer* cryptographer =
1127 &UnlockVaultMutable(trans->GetWrappedTrans())->cryptographer;
1128
1129 if (!ShouldTriggerMigration(old_nigori, *cryptographer))
1130 return false;
1131
1132 DVLOG(1) << "Starting nigori migration to keystore support.";
1133 if (migration_time_ms_ == 0)
1134 migration_time_ms_ = TimeToProtoTime(base::Time::Now());
1135 sync_pb::NigoriSpecifics migrated_nigori(old_nigori);
1136 migrated_nigori.set_keystore_migration_time(migration_time_ms_);
1137
1138 PassphraseType new_passphrase_type = passphrase_type_;
1139 bool new_encrypt_everything = encrypt_everything_;
1140 if (encrypt_everything_ && !IsExplicitPassphrase(passphrase_type_)) {
1141 DVLOG(1) << "Switching to frozen implicit passphrase due to already having "
1142 << "full encryption.";
1143 new_passphrase_type = FROZEN_IMPLICIT_PASSPHRASE;
1144 migrated_nigori.clear_keystore_decryptor_token();
1145 } else if (IsExplicitPassphrase(passphrase_type_)) {
1146 DVLOG_IF(1, !encrypt_everything_) << "Enabling encrypt everything due to "
1147 << "explicit passphrase";
1148 new_encrypt_everything = true;
1149 migrated_nigori.clear_keystore_decryptor_token();
1150 } else {
1151 DCHECK_EQ(passphrase_type_, IMPLICIT_PASSPHRASE);
1152 DCHECK(!encrypt_everything_);
1153 new_passphrase_type = KEYSTORE_PASSPHRASE;
1154 DVLOG(1) << "Switching to keystore passphrase state.";
1155 }
1156 migrated_nigori.set_encrypt_everything(new_encrypt_everything);
1157 migrated_nigori.set_passphrase_type(
1158 EnumPassphraseTypeToProto(new_passphrase_type));
1159 migrated_nigori.set_keybag_is_frozen(true);
1160
1161 if (!keystore_key_.empty()) {
1162 KeyParams key_params = {"localhost", "dummy", keystore_key_};
1163 if (!cryptographer->AddNonDefaultKey(key_params)) {
1164 LOG(ERROR) << "Failed to add keystore key as non-default key.";
1165 return false;
1166 }
1167 }
1168 if (new_passphrase_type == KEYSTORE_PASSPHRASE &&
1169 !GetKeystoreDecryptor(
1170 *cryptographer,
1171 keystore_key_,
1172 migrated_nigori.mutable_keystore_decryptor_token())) {
1173 LOG(ERROR) << "Failed to extract keystore decryptor token.";
1174 return false;
1175 }
1176 if (!cryptographer->GetKeys(migrated_nigori.mutable_encryption_keybag())) {
1177 LOG(ERROR) << "Failed to extract encryption keybag.";
1178 return false;
1179 }
1180
1181 DVLOG(1) << "Completing nigori migration to keystore support.";
1182 nigori_node->SetNigoriSpecifics(migrated_nigori);
1183 if (passphrase_type_ != new_passphrase_type) {
1184 passphrase_type_ = new_passphrase_type;
1185 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
1186 OnPassphraseTypeChanged(passphrase_type_));
1187 }
1188 if (new_encrypt_everything && !encrypt_everything_) {
1189 EnableEncryptEverythingImpl(trans->GetWrappedTrans());
1190 ReEncryptEverything(trans);
1191 }
1192 return true;
1193 }
1194
1195 bool SyncEncryptionHandlerImpl::GetKeystoreDecryptor(
1196 const Cryptographer& cryptographer,
1197 const std::string& keystore_key,
1198 sync_pb::EncryptedData* encrypted_blob) {
1199 DCHECK(thread_checker_.CalledOnValidThread());
1200 DCHECK(!keystore_key.empty());
1201 DCHECK(cryptographer.is_ready());
1202 std::string serialized_nigori;
1203 serialized_nigori = cryptographer.GetDefaultNigoriKey();
1204 if (serialized_nigori.empty()) {
1205 LOG(ERROR) << "Failed to get cryptographer bootstrap token.";
1206 return false;
1207 }
1208 Cryptographer temp_cryptographer(cryptographer.encryptor());
1209 KeyParams key_params = {"localhost", "dummy", keystore_key};
1210 if (!temp_cryptographer.AddKey(key_params))
1211 return false;
1212 if (!temp_cryptographer.EncryptString(serialized_nigori, encrypted_blob))
1213 return false;
1214 return true;
1215 }
1216
1217 bool SyncEncryptionHandlerImpl::AttemptToInstallKeybag(
1218 const sync_pb::EncryptedData& keybag,
1219 bool update_default,
1220 Cryptographer* cryptographer) {
1221 if (!cryptographer->CanDecrypt(keybag))
1222 return false;
1223 cryptographer->InstallKeys(keybag);
1224 if (update_default)
1225 cryptographer->SetDefaultKey(keybag.key_name());
1226 return true;
1227 }
1228
1229 void SyncEncryptionHandlerImpl::EnableEncryptEverythingImpl(
1230 syncable::BaseTransaction* const trans) {
1231 ModelTypeSet* encrypted_types = &UnlockVaultMutable(trans)->encrypted_types;
1232 if (encrypt_everything_) {
1233 DCHECK(encrypted_types->Equals(UserTypes()));
1234 return;
1235 }
1236 encrypt_everything_ = true;
1237 *encrypted_types = UserTypes();
1238 FOR_EACH_OBSERVER(
1239 Observer, observers_,
1240 OnEncryptedTypesChanged(*encrypted_types, encrypt_everything_));
1241 }
1242
1243 bool SyncEncryptionHandlerImpl::DecryptPendingKeysWithKeystoreKey(
1244 const std::string& keystore_key,
1245 const sync_pb::EncryptedData& keystore_decryptor_token,
1246 Cryptographer* cryptographer) {
1247 DCHECK(cryptographer->has_pending_keys());
1248 if (keystore_decryptor_token.blob().empty())
1249 return false;
1250 Cryptographer temp_cryptographer(cryptographer->encryptor());
1251 KeyParams keystore_params = {"localhost", "dummy", keystore_key_};
1252 if (temp_cryptographer.AddKey(keystore_params) &&
1253 temp_cryptographer.CanDecrypt(keystore_decryptor_token)) {
1254 // Someone else migrated the nigori for us! How generous! Go ahead and
1255 // install both the keystore key and the new default encryption key
1256 // (i.e. the one provided by the keystore decryptor token) into the
1257 // cryptographer.
1258 // The keystore decryptor token is a keystore key encrypted blob containing
1259 // the current serialized default encryption key (and as such should be
1260 // able to decrypt the nigori node's encryption keybag).
1261 DVLOG(1) << "Attempting to decrypt pending keys using "
1262 << "keystore decryptor token.";
1263 std::string serialized_nigori =
1264 temp_cryptographer.DecryptToString(keystore_decryptor_token);
1265 // This will decrypt the pending keys and add them if possible. The key
1266 // within |serialized_nigori| will be the default after.
1267 cryptographer->ImportNigoriKey(serialized_nigori);
1268 // Theoretically the encryption keybag should already contain the keystore
1269 // key. We explicitly add it as a safety measure.
1270 cryptographer->AddNonDefaultKey(keystore_params);
1271 if (cryptographer->is_ready()) {
1272 std::string bootstrap_token;
1273 cryptographer->GetBootstrapToken(&bootstrap_token);
1274 DVLOG(1) << "Keystore decryptor token decrypted pending keys.";
1275 FOR_EACH_OBSERVER(
1276 SyncEncryptionHandler::Observer,
1277 observers_,
1278 OnBootstrapTokenUpdated(bootstrap_token,
1279 PASSPHRASE_BOOTSTRAP_TOKEN));
1280 FOR_EACH_OBSERVER(
1281 SyncEncryptionHandler::Observer,
1282 observers_,
1283 OnCryptographerStateChanged(cryptographer));
1284 return true;
1285 }
1286 }
1287 return false;
1288 }
1289
795 } // namespace browser_sync 1290 } // namespace browser_sync
OLDNEW
« no previous file with comments | « sync/internal_api/sync_encryption_handler_impl.h ('k') | sync/internal_api/sync_encryption_handler_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698