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 #include "sync/internal_api/sync_encryption_handler_impl.h"
6
7 #include <queue>
8 #include <string>
9
10 #include "base/base64.h"
11 #include "base/bind.h"
12 #include "base/json/json_string_value_serializer.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/metrics/histogram.h"
15 #include "base/time/time.h"
16 #include "base/tracked_objects.h"
17 #include "sync/internal_api/public/read_node.h"
18 #include "sync/internal_api/public/read_transaction.h"
19 #include "sync/internal_api/public/user_share.h"
20 #include "sync/internal_api/public/util/experiments.h"
21 #include "sync/internal_api/public/util/sync_string_conversions.h"
22 #include "sync/internal_api/public/write_node.h"
23 #include "sync/internal_api/public/write_transaction.h"
24 #include "sync/protocol/encryption.pb.h"
25 #include "sync/protocol/nigori_specifics.pb.h"
26 #include "sync/protocol/sync.pb.h"
27 #include "sync/syncable/directory.h"
28 #include "sync/syncable/entry.h"
29 #include "sync/syncable/nigori_util.h"
30 #include "sync/syncable/syncable_base_transaction.h"
31 #include "sync/util/cryptographer.h"
32 #include "sync/util/encryptor.h"
33 #include "sync/util/time.h"
34
35 namespace syncer {
36
37 namespace {
38
39 // The maximum number of times we will automatically overwrite the nigori node
40 // because the encryption keys don't match (per chrome instantiation).
41 // We protect ourselves against nigori rollbacks, but it's possible two
42 // different clients might have contrasting view of what the nigori node state
43 // should be, in which case they might ping pong (see crbug.com/119207).
44 static const int kNigoriOverwriteLimit = 10;
45
46 // Enumeration of nigori keystore migration results (for use in UMA stats).
47 enum NigoriMigrationResult {
48 FAILED_TO_SET_DEFAULT_KEYSTORE,
49 FAILED_TO_SET_NONDEFAULT_KEYSTORE,
50 FAILED_TO_EXTRACT_DECRYPTOR,
51 FAILED_TO_EXTRACT_KEYBAG,
52 MIGRATION_SUCCESS_KEYSTORE_NONDEFAULT,
53 MIGRATION_SUCCESS_KEYSTORE_DEFAULT,
54 MIGRATION_SUCCESS_FROZEN_IMPLICIT,
55 MIGRATION_SUCCESS_CUSTOM,
56 MIGRATION_RESULT_SIZE,
57 };
58
59 enum NigoriMigrationState {
60 MIGRATED,
61 NOT_MIGRATED_CRYPTO_NOT_READY,
62 NOT_MIGRATED_NO_KEYSTORE_KEY,
63 NOT_MIGRATED_UNKNOWN_REASON,
64 MIGRATION_STATE_SIZE,
65 };
66
67 // The new passphrase state is sufficient to determine whether a nigori node
68 // is migrated to support keystore encryption. In addition though, we also
69 // want to verify the conditions for proper keystore encryption functionality.
70 // 1. Passphrase state is set.
71 // 2. Migration time is set.
72 // 3. Frozen keybag is true
73 // 4. If passphrase state is keystore, keystore_decryptor_token is set.
IsNigoriMigratedToKeystore(const sync_pb::NigoriSpecifics & nigori)74 bool IsNigoriMigratedToKeystore(const sync_pb::NigoriSpecifics& nigori) {
75 if (!nigori.has_passphrase_type())
76 return false;
77 if (!nigori.has_keystore_migration_time())
78 return false;
79 if (!nigori.keybag_is_frozen())
80 return false;
81 if (nigori.passphrase_type() ==
82 sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE)
83 return false;
84 if (nigori.passphrase_type() ==
85 sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE &&
86 nigori.keystore_decryptor_token().blob().empty())
87 return false;
88 if (!nigori.has_keystore_migration_time())
89 return false;
90 return true;
91 }
92
ProtoPassphraseTypeToEnum(sync_pb::NigoriSpecifics::PassphraseType type)93 PassphraseType ProtoPassphraseTypeToEnum(
94 sync_pb::NigoriSpecifics::PassphraseType type) {
95 switch(type) {
96 case sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE:
97 return IMPLICIT_PASSPHRASE;
98 case sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE:
99 return KEYSTORE_PASSPHRASE;
100 case sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE:
101 return CUSTOM_PASSPHRASE;
102 case sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE:
103 return FROZEN_IMPLICIT_PASSPHRASE;
104 default:
105 NOTREACHED();
106 return IMPLICIT_PASSPHRASE;
107 };
108 }
109
110 sync_pb::NigoriSpecifics::PassphraseType
EnumPassphraseTypeToProto(PassphraseType type)111 EnumPassphraseTypeToProto(PassphraseType type) {
112 switch(type) {
113 case IMPLICIT_PASSPHRASE:
114 return sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE;
115 case KEYSTORE_PASSPHRASE:
116 return sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE;
117 case CUSTOM_PASSPHRASE:
118 return sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE;
119 case FROZEN_IMPLICIT_PASSPHRASE:
120 return sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE;
121 default:
122 NOTREACHED();
123 return sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE;
124 };
125 }
126
IsExplicitPassphrase(PassphraseType type)127 bool IsExplicitPassphrase(PassphraseType type) {
128 return type == CUSTOM_PASSPHRASE || type == FROZEN_IMPLICIT_PASSPHRASE;
129 }
130
131 // Keystore Bootstrap Token helper methods.
132 // The bootstrap is a base64 encoded, encrypted, ListValue of keystore key
133 // strings, with the current keystore key as the last value in the list.
PackKeystoreBootstrapToken(const std::vector<std::string> & old_keystore_keys,const std::string & current_keystore_key,Encryptor * encryptor)134 std::string PackKeystoreBootstrapToken(
135 const std::vector<std::string>& old_keystore_keys,
136 const std::string& current_keystore_key,
137 Encryptor* encryptor) {
138 if (current_keystore_key.empty())
139 return std::string();
140
141 base::ListValue keystore_key_values;
142 for (size_t i = 0; i < old_keystore_keys.size(); ++i)
143 keystore_key_values.AppendString(old_keystore_keys[i]);
144 keystore_key_values.AppendString(current_keystore_key);
145
146 // Update the bootstrap token.
147 // The bootstrap is a base64 encoded, encrypted, ListValue of keystore key
148 // strings, with the current keystore key as the last value in the list.
149 std::string serialized_keystores;
150 JSONStringValueSerializer json(&serialized_keystores);
151 json.Serialize(keystore_key_values);
152 std::string encrypted_keystores;
153 encryptor->EncryptString(serialized_keystores,
154 &encrypted_keystores);
155 std::string keystore_bootstrap;
156 base::Base64Encode(encrypted_keystores, &keystore_bootstrap);
157 return keystore_bootstrap;
158 }
159
UnpackKeystoreBootstrapToken(const std::string & keystore_bootstrap_token,Encryptor * encryptor,std::vector<std::string> * old_keystore_keys,std::string * current_keystore_key)160 bool UnpackKeystoreBootstrapToken(
161 const std::string& keystore_bootstrap_token,
162 Encryptor* encryptor,
163 std::vector<std::string>* old_keystore_keys,
164 std::string* current_keystore_key) {
165 if (keystore_bootstrap_token.empty())
166 return false;
167 std::string base64_decoded_keystore_bootstrap;
168 if (!base::Base64Decode(keystore_bootstrap_token,
169 &base64_decoded_keystore_bootstrap)) {
170 return false;
171 }
172 std::string decrypted_keystore_bootstrap;
173 if (!encryptor->DecryptString(base64_decoded_keystore_bootstrap,
174 &decrypted_keystore_bootstrap)) {
175 return false;
176 }
177 JSONStringValueSerializer json(&decrypted_keystore_bootstrap);
178 scoped_ptr<base::Value> deserialized_keystore_keys(
179 json.Deserialize(NULL, NULL));
180 if (!deserialized_keystore_keys)
181 return false;
182 base::ListValue* internal_list_value = NULL;
183 if (!deserialized_keystore_keys->GetAsList(&internal_list_value))
184 return false;
185 int number_of_keystore_keys = internal_list_value->GetSize();
186 if (!internal_list_value->GetString(number_of_keystore_keys - 1,
187 current_keystore_key)) {
188 return false;
189 }
190 old_keystore_keys->resize(number_of_keystore_keys - 1);
191 for (int i = 0; i < number_of_keystore_keys - 1; ++i)
192 internal_list_value->GetString(i, &(*old_keystore_keys)[i]);
193 return true;
194 }
195
196 } // namespace
197
Vault(Encryptor * encryptor,ModelTypeSet encrypted_types)198 SyncEncryptionHandlerImpl::Vault::Vault(
199 Encryptor* encryptor,
200 ModelTypeSet encrypted_types)
201 : cryptographer(encryptor),
202 encrypted_types(encrypted_types) {
203 }
204
~Vault()205 SyncEncryptionHandlerImpl::Vault::~Vault() {
206 }
207
SyncEncryptionHandlerImpl(UserShare * user_share,Encryptor * encryptor,const std::string & restored_key_for_bootstrapping,const std::string & restored_keystore_key_for_bootstrapping)208 SyncEncryptionHandlerImpl::SyncEncryptionHandlerImpl(
209 UserShare* user_share,
210 Encryptor* encryptor,
211 const std::string& restored_key_for_bootstrapping,
212 const std::string& restored_keystore_key_for_bootstrapping)
213 : user_share_(user_share),
214 vault_unsafe_(encryptor, SensitiveTypes()),
215 encrypt_everything_(false),
216 passphrase_type_(IMPLICIT_PASSPHRASE),
217 nigori_overwrite_count_(0),
218 weak_ptr_factory_(this) {
219 // Restore the cryptographer's previous keys. Note that we don't add the
220 // keystore keys into the cryptographer here, in case a migration was pending.
221 vault_unsafe_.cryptographer.Bootstrap(restored_key_for_bootstrapping);
222
223 // If this fails, we won't have a valid keystore key, and will simply request
224 // new ones from the server on the next DownloadUpdates.
225 UnpackKeystoreBootstrapToken(
226 restored_keystore_key_for_bootstrapping,
227 encryptor,
228 &old_keystore_keys_,
229 &keystore_key_);
230 }
231
~SyncEncryptionHandlerImpl()232 SyncEncryptionHandlerImpl::~SyncEncryptionHandlerImpl() {}
233
AddObserver(Observer * observer)234 void SyncEncryptionHandlerImpl::AddObserver(Observer* observer) {
235 DCHECK(thread_checker_.CalledOnValidThread());
236 DCHECK(!observers_.HasObserver(observer));
237 observers_.AddObserver(observer);
238 }
239
RemoveObserver(Observer * observer)240 void SyncEncryptionHandlerImpl::RemoveObserver(Observer* observer) {
241 DCHECK(thread_checker_.CalledOnValidThread());
242 DCHECK(observers_.HasObserver(observer));
243 observers_.RemoveObserver(observer);
244 }
245
Init()246 void SyncEncryptionHandlerImpl::Init() {
247 DCHECK(thread_checker_.CalledOnValidThread());
248 WriteTransaction trans(FROM_HERE, user_share_);
249 WriteNode node(&trans);
250
251 if (node.InitTypeRoot(NIGORI) != BaseNode::INIT_OK)
252 return;
253 if (!ApplyNigoriUpdateImpl(node.GetNigoriSpecifics(),
254 trans.GetWrappedTrans())) {
255 WriteEncryptionStateToNigori(&trans);
256 }
257
258 bool has_pending_keys = UnlockVault(
259 trans.GetWrappedTrans()).cryptographer.has_pending_keys();
260 bool is_ready = UnlockVault(
261 trans.GetWrappedTrans()).cryptographer.is_ready();
262 // Log the state of the cryptographer regardless of migration state.
263 UMA_HISTOGRAM_BOOLEAN("Sync.CryptographerReady", is_ready);
264 UMA_HISTOGRAM_BOOLEAN("Sync.CryptographerPendingKeys", has_pending_keys);
265 if (IsNigoriMigratedToKeystore(node.GetNigoriSpecifics())) {
266 // This account has a nigori node that has been migrated to support
267 // keystore.
268 UMA_HISTOGRAM_ENUMERATION("Sync.NigoriMigrationState",
269 MIGRATED,
270 MIGRATION_STATE_SIZE);
271 if (has_pending_keys && passphrase_type_ == KEYSTORE_PASSPHRASE) {
272 // If this is happening, it means the keystore decryptor is either
273 // undecryptable with the available keystore keys or does not match the
274 // nigori keybag's encryption key. Otherwise we're simply missing the
275 // keystore key.
276 UMA_HISTOGRAM_BOOLEAN("Sync.KeystoreDecryptionFailed",
277 !keystore_key_.empty());
278 }
279 } else if (!is_ready) {
280 // Migration cannot occur until the cryptographer is ready (initialized
281 // with GAIA password and any pending keys resolved).
282 UMA_HISTOGRAM_ENUMERATION("Sync.NigoriMigrationState",
283 NOT_MIGRATED_CRYPTO_NOT_READY,
284 MIGRATION_STATE_SIZE);
285 } else if (keystore_key_.empty()) {
286 // The client has no keystore key, either because it is not yet enabled or
287 // the server is not sending a valid keystore key.
288 UMA_HISTOGRAM_ENUMERATION("Sync.NigoriMigrationState",
289 NOT_MIGRATED_NO_KEYSTORE_KEY,
290 MIGRATION_STATE_SIZE);
291 } else {
292 // If the above conditions have been met and the nigori node is still not
293 // migrated, something failed in the migration process.
294 UMA_HISTOGRAM_ENUMERATION("Sync.NigoriMigrationState",
295 NOT_MIGRATED_UNKNOWN_REASON,
296 MIGRATION_STATE_SIZE);
297 }
298
299
300 // Always trigger an encrypted types and cryptographer state change event at
301 // init time so observers get the initial values.
302 FOR_EACH_OBSERVER(
303 Observer, observers_,
304 OnEncryptedTypesChanged(
305 UnlockVault(trans.GetWrappedTrans()).encrypted_types,
306 encrypt_everything_));
307 FOR_EACH_OBSERVER(
308 SyncEncryptionHandler::Observer,
309 observers_,
310 OnCryptographerStateChanged(
311 &UnlockVaultMutable(trans.GetWrappedTrans())->cryptographer));
312
313 // If the cryptographer is not ready (either it has pending keys or we
314 // failed to initialize it), we don't want to try and re-encrypt the data.
315 // If we had encrypted types, the DataTypeManager will block, preventing
316 // sync from happening until the the passphrase is provided.
317 if (UnlockVault(trans.GetWrappedTrans()).cryptographer.is_ready())
318 ReEncryptEverything(&trans);
319 }
320
SetEncryptionPassphrase(const std::string & passphrase,bool is_explicit)321 void SyncEncryptionHandlerImpl::SetEncryptionPassphrase(
322 const std::string& passphrase,
323 bool is_explicit) {
324 DCHECK(thread_checker_.CalledOnValidThread());
325 // We do not accept empty passphrases.
326 if (passphrase.empty()) {
327 NOTREACHED() << "Cannot encrypt with an empty passphrase.";
328 return;
329 }
330
331 // All accesses to the cryptographer are protected by a transaction.
332 WriteTransaction trans(FROM_HERE, user_share_);
333 KeyParams key_params = {"localhost", "dummy", passphrase};
334 WriteNode node(&trans);
335 if (node.InitTypeRoot(NIGORI) != BaseNode::INIT_OK) {
336 NOTREACHED();
337 return;
338 }
339
340 Cryptographer* cryptographer =
341 &UnlockVaultMutable(trans.GetWrappedTrans())->cryptographer;
342
343 // Once we've migrated to keystore, the only way to set a passphrase for
344 // encryption is to set a custom passphrase.
345 if (IsNigoriMigratedToKeystore(node.GetNigoriSpecifics())) {
346 if (!is_explicit) {
347 // The user is setting a new implicit passphrase. At this point we don't
348 // care, so drop it on the floor. This is safe because if we have a
349 // migrated nigori node, then we don't need to create an initial
350 // encryption key.
351 LOG(WARNING) << "Ignoring new implicit passphrase. Keystore migration "
352 << "already performed.";
353 return;
354 }
355 // Will fail if we already have an explicit passphrase or we have pending
356 // keys.
357 SetCustomPassphrase(passphrase, &trans, &node);
358
359 // When keystore migration occurs, the "CustomEncryption" UMA stat must be
360 // logged as true.
361 UMA_HISTOGRAM_BOOLEAN("Sync.CustomEncryption", true);
362 return;
363 }
364
365 std::string bootstrap_token;
366 sync_pb::EncryptedData pending_keys;
367 if (cryptographer->has_pending_keys())
368 pending_keys = cryptographer->GetPendingKeys();
369 bool success = false;
370
371 // There are six cases to handle here:
372 // 1. The user has no pending keys and is setting their current GAIA password
373 // as the encryption passphrase. This happens either during first time sync
374 // with a clean profile, or after re-authenticating on a profile that was
375 // already signed in with the cryptographer ready.
376 // 2. The user has no pending keys, and is overwriting an (already provided)
377 // implicit passphrase with an explicit (custom) passphrase.
378 // 3. The user has pending keys for an explicit passphrase that is somehow set
379 // to their current GAIA passphrase.
380 // 4. The user has pending keys encrypted with their current GAIA passphrase
381 // and the caller passes in the current GAIA passphrase.
382 // 5. The user has pending keys encrypted with an older GAIA passphrase
383 // and the caller passes in the current GAIA passphrase.
384 // 6. The user has previously done encryption with an explicit passphrase.
385 // Furthermore, we enforce the fact that the bootstrap encryption token will
386 // always be derived from the newest GAIA password if the account is using
387 // an implicit passphrase (even if the data is encrypted with an old GAIA
388 // password). If the account is using an explicit (custom) passphrase, the
389 // bootstrap token will be derived from the most recently provided explicit
390 // passphrase (that was able to decrypt the data).
391 if (!IsExplicitPassphrase(passphrase_type_)) {
392 if (!cryptographer->has_pending_keys()) {
393 if (cryptographer->AddKey(key_params)) {
394 // Case 1 and 2. We set a new GAIA passphrase when there are no pending
395 // keys (1), or overwriting an implicit passphrase with a new explicit
396 // one (2) when there are no pending keys.
397 if (is_explicit) {
398 DVLOG(1) << "Setting explicit passphrase for encryption.";
399 passphrase_type_ = CUSTOM_PASSPHRASE;
400 custom_passphrase_time_ = base::Time::Now();
401 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
402 OnPassphraseTypeChanged(
403 passphrase_type_,
404 GetExplicitPassphraseTime()));
405 } else {
406 DVLOG(1) << "Setting implicit passphrase for encryption.";
407 }
408 cryptographer->GetBootstrapToken(&bootstrap_token);
409
410 // With M26, sync accounts can be in only one of two encryption states:
411 // 1) Encrypt only passwords with an implicit passphrase.
412 // 2) Encrypt all sync datatypes with an explicit passphrase.
413 // We deprecate the "EncryptAllData" and "CustomPassphrase" histograms,
414 // and keep track of an account's encryption state via the
415 // "CustomEncryption" histogram. See http://crbug.com/131478.
416 UMA_HISTOGRAM_BOOLEAN("Sync.CustomEncryption", is_explicit);
417
418 success = true;
419 } else {
420 NOTREACHED() << "Failed to add key to cryptographer.";
421 success = false;
422 }
423 } else { // cryptographer->has_pending_keys() == true
424 if (is_explicit) {
425 // This can only happen if the nigori node is updated with a new
426 // implicit passphrase while a client is attempting to set a new custom
427 // passphrase (race condition).
428 DVLOG(1) << "Failing because an implicit passphrase is already set.";
429 success = false;
430 } else { // is_explicit == false
431 if (cryptographer->DecryptPendingKeys(key_params)) {
432 // Case 4. We successfully decrypted with the implicit GAIA passphrase
433 // passed in.
434 DVLOG(1) << "Implicit internal passphrase accepted for decryption.";
435 cryptographer->GetBootstrapToken(&bootstrap_token);
436 success = true;
437 } else {
438 // Case 5. Encryption was done with an old GAIA password, but we were
439 // provided with the current GAIA password. We need to generate a new
440 // bootstrap token to preserve it. We build a temporary cryptographer
441 // to allow us to extract these params without polluting our current
442 // cryptographer.
443 DVLOG(1) << "Implicit internal passphrase failed to decrypt, adding "
444 << "anyways as default passphrase and persisting via "
445 << "bootstrap token.";
446 Cryptographer temp_cryptographer(cryptographer->encryptor());
447 temp_cryptographer.AddKey(key_params);
448 temp_cryptographer.GetBootstrapToken(&bootstrap_token);
449 // We then set the new passphrase as the default passphrase of the
450 // real cryptographer, even though we have pending keys. This is safe,
451 // as although Cryptographer::is_initialized() will now be true,
452 // is_ready() will remain false due to having pending keys.
453 cryptographer->AddKey(key_params);
454 success = false;
455 }
456 } // is_explicit
457 } // cryptographer->has_pending_keys()
458 } else { // IsExplicitPassphrase(passphrase_type_) == true.
459 // Case 6. We do not want to override a previously set explicit passphrase,
460 // so we return a failure.
461 DVLOG(1) << "Failing because an explicit passphrase is already set.";
462 success = false;
463 }
464
465 DVLOG_IF(1, !success)
466 << "Failure in SetEncryptionPassphrase; notifying and returning.";
467 DVLOG_IF(1, success)
468 << "Successfully set encryption passphrase; updating nigori and "
469 "reencrypting.";
470
471 FinishSetPassphrase(success, bootstrap_token, &trans, &node);
472 }
473
SetDecryptionPassphrase(const std::string & passphrase)474 void SyncEncryptionHandlerImpl::SetDecryptionPassphrase(
475 const std::string& passphrase) {
476 DCHECK(thread_checker_.CalledOnValidThread());
477 // We do not accept empty passphrases.
478 if (passphrase.empty()) {
479 NOTREACHED() << "Cannot decrypt with an empty passphrase.";
480 return;
481 }
482
483 // All accesses to the cryptographer are protected by a transaction.
484 WriteTransaction trans(FROM_HERE, user_share_);
485 KeyParams key_params = {"localhost", "dummy", passphrase};
486 WriteNode node(&trans);
487 if (node.InitTypeRoot(NIGORI) != BaseNode::INIT_OK) {
488 NOTREACHED();
489 return;
490 }
491
492 // Once we've migrated to keystore, we're only ever decrypting keys derived
493 // from an explicit passphrase. But, for clients without a keystore key yet
494 // (either not on by default or failed to download one), we still support
495 // decrypting with a gaia passphrase, and therefore bypass the
496 // DecryptPendingKeysWithExplicitPassphrase logic.
497 if (IsNigoriMigratedToKeystore(node.GetNigoriSpecifics()) &&
498 IsExplicitPassphrase(passphrase_type_)) {
499 DecryptPendingKeysWithExplicitPassphrase(passphrase, &trans, &node);
500 return;
501 }
502
503 Cryptographer* cryptographer =
504 &UnlockVaultMutable(trans.GetWrappedTrans())->cryptographer;
505 if (!cryptographer->has_pending_keys()) {
506 // Note that this *can* happen in a rare situation where data is
507 // re-encrypted on another client while a SetDecryptionPassphrase() call is
508 // in-flight on this client. It is rare enough that we choose to do nothing.
509 NOTREACHED() << "Attempt to set decryption passphrase failed because there "
510 << "were no pending keys.";
511 return;
512 }
513
514 std::string bootstrap_token;
515 sync_pb::EncryptedData pending_keys;
516 pending_keys = cryptographer->GetPendingKeys();
517 bool success = false;
518
519 // There are three cases to handle here:
520 // 7. We're using the current GAIA password to decrypt the pending keys. This
521 // happens when signing in to an account with a previously set implicit
522 // passphrase, where the data is already encrypted with the newest GAIA
523 // password.
524 // 8. The user is providing an old GAIA password to decrypt the pending keys.
525 // In this case, the user is using an implicit passphrase, but has changed
526 // their password since they last encrypted their data, and therefore
527 // their current GAIA password was unable to decrypt the data. This will
528 // happen when the user is setting up a new profile with a previously
529 // encrypted account (after changing passwords).
530 // 9. The user is providing a previously set explicit passphrase to decrypt
531 // the pending keys.
532 if (!IsExplicitPassphrase(passphrase_type_)) {
533 if (cryptographer->is_initialized()) {
534 // We only want to change the default encryption key to the pending
535 // one if the pending keybag already contains the current default.
536 // This covers the case where a different client re-encrypted
537 // everything with a newer gaia passphrase (and hence the keybag
538 // contains keys from all previously used gaia passphrases).
539 // Otherwise, we're in a situation where the pending keys are
540 // encrypted with an old gaia passphrase, while the default is the
541 // current gaia passphrase. In that case, we preserve the default.
542 Cryptographer temp_cryptographer(cryptographer->encryptor());
543 temp_cryptographer.SetPendingKeys(cryptographer->GetPendingKeys());
544 if (temp_cryptographer.DecryptPendingKeys(key_params)) {
545 // Check to see if the pending bag of keys contains the current
546 // default key.
547 sync_pb::EncryptedData encrypted;
548 cryptographer->GetKeys(&encrypted);
549 if (temp_cryptographer.CanDecrypt(encrypted)) {
550 DVLOG(1) << "Implicit user provided passphrase accepted for "
551 << "decryption, overwriting default.";
552 // Case 7. The pending keybag contains the current default. Go ahead
553 // and update the cryptographer, letting the default change.
554 cryptographer->DecryptPendingKeys(key_params);
555 cryptographer->GetBootstrapToken(&bootstrap_token);
556 success = true;
557 } else {
558 // Case 8. The pending keybag does not contain the current default
559 // encryption key. We decrypt the pending keys here, and in
560 // FinishSetPassphrase, re-encrypt everything with the current GAIA
561 // passphrase instead of the passphrase just provided by the user.
562 DVLOG(1) << "Implicit user provided passphrase accepted for "
563 << "decryption, restoring implicit internal passphrase "
564 << "as default.";
565 std::string bootstrap_token_from_current_key;
566 cryptographer->GetBootstrapToken(
567 &bootstrap_token_from_current_key);
568 cryptographer->DecryptPendingKeys(key_params);
569 // Overwrite the default from the pending keys.
570 cryptographer->AddKeyFromBootstrapToken(
571 bootstrap_token_from_current_key);
572 success = true;
573 }
574 } else { // !temp_cryptographer.DecryptPendingKeys(..)
575 DVLOG(1) << "Implicit user provided passphrase failed to decrypt.";
576 success = false;
577 } // temp_cryptographer.DecryptPendingKeys(...)
578 } else { // cryptographer->is_initialized() == false
579 if (cryptographer->DecryptPendingKeys(key_params)) {
580 // This can happpen in two cases:
581 // - First time sync on android, where we'll never have a
582 // !user_provided passphrase.
583 // - This is a restart for a client that lost their bootstrap token.
584 // In both cases, we should go ahead and initialize the cryptographer
585 // and persist the new bootstrap token.
586 //
587 // Note: at this point, we cannot distinguish between cases 7 and 8
588 // above. This user provided passphrase could be the current or the
589 // old. But, as long as we persist the token, there's nothing more
590 // we can do.
591 cryptographer->GetBootstrapToken(&bootstrap_token);
592 DVLOG(1) << "Implicit user provided passphrase accepted, initializing"
593 << " cryptographer.";
594 success = true;
595 } else {
596 DVLOG(1) << "Implicit user provided passphrase failed to decrypt.";
597 success = false;
598 }
599 } // cryptographer->is_initialized()
600 } else { // nigori_has_explicit_passphrase == true
601 // Case 9. Encryption was done with an explicit passphrase, and we decrypt
602 // with the passphrase provided by the user.
603 if (cryptographer->DecryptPendingKeys(key_params)) {
604 DVLOG(1) << "Explicit passphrase accepted for decryption.";
605 cryptographer->GetBootstrapToken(&bootstrap_token);
606 success = true;
607 } else {
608 DVLOG(1) << "Explicit passphrase failed to decrypt.";
609 success = false;
610 }
611 } // nigori_has_explicit_passphrase
612
613 DVLOG_IF(1, !success)
614 << "Failure in SetDecryptionPassphrase; notifying and returning.";
615 DVLOG_IF(1, success)
616 << "Successfully set decryption passphrase; updating nigori and "
617 "reencrypting.";
618
619 FinishSetPassphrase(success, bootstrap_token, &trans, &node);
620 }
621
EnableEncryptEverything()622 void SyncEncryptionHandlerImpl::EnableEncryptEverything() {
623 DCHECK(thread_checker_.CalledOnValidThread());
624 WriteTransaction trans(FROM_HERE, user_share_);
625 DVLOG(1) << "Enabling encrypt everything.";
626 if (encrypt_everything_)
627 return;
628 EnableEncryptEverythingImpl(trans.GetWrappedTrans());
629 WriteEncryptionStateToNigori(&trans);
630 if (UnlockVault(trans.GetWrappedTrans()).cryptographer.is_ready())
631 ReEncryptEverything(&trans);
632 }
633
EncryptEverythingEnabled() const634 bool SyncEncryptionHandlerImpl::EncryptEverythingEnabled() const {
635 DCHECK(thread_checker_.CalledOnValidThread());
636 return encrypt_everything_;
637 }
638
GetPassphraseType() const639 PassphraseType SyncEncryptionHandlerImpl::GetPassphraseType() const {
640 DCHECK(thread_checker_.CalledOnValidThread());
641 return passphrase_type_;
642 }
643
644 // Note: this is called from within a syncable transaction, so we need to post
645 // tasks if we want to do any work that creates a new sync_api transaction.
ApplyNigoriUpdate(const sync_pb::NigoriSpecifics & nigori,syncable::BaseTransaction * const trans)646 void SyncEncryptionHandlerImpl::ApplyNigoriUpdate(
647 const sync_pb::NigoriSpecifics& nigori,
648 syncable::BaseTransaction* const trans) {
649 DCHECK(thread_checker_.CalledOnValidThread());
650 DCHECK(trans);
651 if (!ApplyNigoriUpdateImpl(nigori, trans)) {
652 base::MessageLoop::current()->PostTask(
653 FROM_HERE,
654 base::Bind(&SyncEncryptionHandlerImpl::RewriteNigori,
655 weak_ptr_factory_.GetWeakPtr()));
656 }
657
658 FOR_EACH_OBSERVER(
659 SyncEncryptionHandler::Observer,
660 observers_,
661 OnCryptographerStateChanged(
662 &UnlockVaultMutable(trans)->cryptographer));
663 }
664
UpdateNigoriFromEncryptedTypes(sync_pb::NigoriSpecifics * nigori,syncable::BaseTransaction * const trans) const665 void SyncEncryptionHandlerImpl::UpdateNigoriFromEncryptedTypes(
666 sync_pb::NigoriSpecifics* nigori,
667 syncable::BaseTransaction* const trans) const {
668 DCHECK(thread_checker_.CalledOnValidThread());
669 syncable::UpdateNigoriFromEncryptedTypes(UnlockVault(trans).encrypted_types,
670 encrypt_everything_,
671 nigori);
672 }
673
NeedKeystoreKey(syncable::BaseTransaction * const trans) const674 bool SyncEncryptionHandlerImpl::NeedKeystoreKey(
675 syncable::BaseTransaction* const trans) const {
676 DCHECK(thread_checker_.CalledOnValidThread());
677 return keystore_key_.empty();
678 }
679
SetKeystoreKeys(const google::protobuf::RepeatedPtrField<google::protobuf::string> & keys,syncable::BaseTransaction * const trans)680 bool SyncEncryptionHandlerImpl::SetKeystoreKeys(
681 const google::protobuf::RepeatedPtrField<google::protobuf::string>& keys,
682 syncable::BaseTransaction* const trans) {
683 DCHECK(thread_checker_.CalledOnValidThread());
684 if (keys.size() == 0)
685 return false;
686 // The last key in the vector is the current keystore key. The others are kept
687 // around for decryption only.
688 const std::string& raw_keystore_key = keys.Get(keys.size() - 1);
689 if (raw_keystore_key.empty())
690 return false;
691
692 // Note: in order to Pack the keys, they must all be base64 encoded (else
693 // JSON serialization fails).
694 base::Base64Encode(raw_keystore_key, &keystore_key_);
695
696 // Go through and save the old keystore keys. We always persist all keystore
697 // keys the server sends us.
698 old_keystore_keys_.resize(keys.size() - 1);
699 for (int i = 0; i < keys.size() - 1; ++i)
700 base::Base64Encode(keys.Get(i), &old_keystore_keys_[i]);
701
702 Cryptographer* cryptographer = &UnlockVaultMutable(trans)->cryptographer;
703
704 // Update the bootstrap token. If this fails, we persist an empty string,
705 // which will force us to download the keystore keys again on the next
706 // restart.
707 std::string keystore_bootstrap = PackKeystoreBootstrapToken(
708 old_keystore_keys_,
709 keystore_key_,
710 cryptographer->encryptor());
711 DCHECK_EQ(keystore_bootstrap.empty(), keystore_key_.empty());
712 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
713 OnBootstrapTokenUpdated(keystore_bootstrap,
714 KEYSTORE_BOOTSTRAP_TOKEN));
715 DVLOG(1) << "Keystore bootstrap token updated.";
716
717 // If this is a first time sync, we get the encryption keys before we process
718 // the nigori node. Just return for now, ApplyNigoriUpdate will be invoked
719 // once we have the nigori node.
720 syncable::Entry entry(trans, syncable::GET_TYPE_ROOT, NIGORI);
721 if (!entry.good())
722 return true;
723
724 const sync_pb::NigoriSpecifics& nigori =
725 entry.GetSpecifics().nigori();
726 if (cryptographer->has_pending_keys() &&
727 IsNigoriMigratedToKeystore(nigori) &&
728 !nigori.keystore_decryptor_token().blob().empty()) {
729 // If the nigori is already migrated and we have pending keys, we might
730 // be able to decrypt them using either the keystore decryptor token
731 // or the existing keystore keys.
732 DecryptPendingKeysWithKeystoreKey(keystore_key_,
733 nigori.keystore_decryptor_token(),
734 cryptographer);
735 }
736
737 // Note that triggering migration will have no effect if we're already
738 // properly migrated with the newest keystore keys.
739 if (ShouldTriggerMigration(nigori, *cryptographer)) {
740 base::MessageLoop::current()->PostTask(
741 FROM_HERE,
742 base::Bind(&SyncEncryptionHandlerImpl::RewriteNigori,
743 weak_ptr_factory_.GetWeakPtr()));
744 }
745
746 return true;
747 }
748
GetEncryptedTypes(syncable::BaseTransaction * const trans) const749 ModelTypeSet SyncEncryptionHandlerImpl::GetEncryptedTypes(
750 syncable::BaseTransaction* const trans) const {
751 return UnlockVault(trans).encrypted_types;
752 }
753
GetCryptographerUnsafe()754 Cryptographer* SyncEncryptionHandlerImpl::GetCryptographerUnsafe() {
755 DCHECK(thread_checker_.CalledOnValidThread());
756 return &vault_unsafe_.cryptographer;
757 }
758
GetEncryptedTypesUnsafe()759 ModelTypeSet SyncEncryptionHandlerImpl::GetEncryptedTypesUnsafe() {
760 DCHECK(thread_checker_.CalledOnValidThread());
761 return vault_unsafe_.encrypted_types;
762 }
763
MigratedToKeystore()764 bool SyncEncryptionHandlerImpl::MigratedToKeystore() {
765 DCHECK(thread_checker_.CalledOnValidThread());
766 ReadTransaction trans(FROM_HERE, user_share_);
767 ReadNode nigori_node(&trans);
768 if (nigori_node.InitTypeRoot(NIGORI) != BaseNode::INIT_OK)
769 return false;
770 return IsNigoriMigratedToKeystore(nigori_node.GetNigoriSpecifics());
771 }
772
migration_time() const773 base::Time SyncEncryptionHandlerImpl::migration_time() const {
774 return migration_time_;
775 }
776
custom_passphrase_time() const777 base::Time SyncEncryptionHandlerImpl::custom_passphrase_time() const {
778 return custom_passphrase_time_;
779 }
780
781 // This function iterates over all encrypted types. There are many scenarios in
782 // which data for some or all types is not currently available. In that case,
783 // the lookup of the root node will fail and we will skip encryption for that
784 // type.
ReEncryptEverything(WriteTransaction * trans)785 void SyncEncryptionHandlerImpl::ReEncryptEverything(
786 WriteTransaction* trans) {
787 DCHECK(thread_checker_.CalledOnValidThread());
788 DCHECK(UnlockVault(trans->GetWrappedTrans()).cryptographer.is_ready());
789 for (ModelTypeSet::Iterator iter =
790 UnlockVault(trans->GetWrappedTrans()).encrypted_types.First();
791 iter.Good(); iter.Inc()) {
792 if (iter.Get() == PASSWORDS || IsControlType(iter.Get()))
793 continue; // These types handle encryption differently.
794
795 ReadNode type_root(trans);
796 if (type_root.InitTypeRoot(iter.Get()) != BaseNode::INIT_OK)
797 continue; // Don't try to reencrypt if the type's data is unavailable.
798
799 // Iterate through all children of this datatype.
800 std::queue<int64> to_visit;
801 int64 child_id = type_root.GetFirstChildId();
802 to_visit.push(child_id);
803 while (!to_visit.empty()) {
804 child_id = to_visit.front();
805 to_visit.pop();
806 if (child_id == kInvalidId)
807 continue;
808
809 WriteNode child(trans);
810 if (child.InitByIdLookup(child_id) != BaseNode::INIT_OK)
811 continue; // Possible for locally deleted items.
812 if (child.GetIsFolder()) {
813 to_visit.push(child.GetFirstChildId());
814 }
815 if (child.GetEntry()->GetUniqueServerTag().empty()) {
816 // Rewrite the specifics of the node with encrypted data if necessary
817 // (only rewrite the non-unique folders).
818 child.ResetFromSpecifics();
819 }
820 to_visit.push(child.GetSuccessorId());
821 }
822 }
823
824 // Passwords are encrypted with their own legacy scheme. Passwords are always
825 // encrypted so we don't need to check GetEncryptedTypes() here.
826 ReadNode passwords_root(trans);
827 if (passwords_root.InitTypeRoot(PASSWORDS) == BaseNode::INIT_OK) {
828 int64 child_id = passwords_root.GetFirstChildId();
829 while (child_id != kInvalidId) {
830 WriteNode child(trans);
831 if (child.InitByIdLookup(child_id) != BaseNode::INIT_OK) {
832 NOTREACHED();
833 return;
834 }
835 child.SetPasswordSpecifics(child.GetPasswordSpecifics());
836 child_id = child.GetSuccessorId();
837 }
838 }
839
840 DVLOG(1) << "Re-encrypt everything complete.";
841
842 // NOTE: We notify from within a transaction.
843 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
844 OnEncryptionComplete());
845 }
846
ApplyNigoriUpdateImpl(const sync_pb::NigoriSpecifics & nigori,syncable::BaseTransaction * const trans)847 bool SyncEncryptionHandlerImpl::ApplyNigoriUpdateImpl(
848 const sync_pb::NigoriSpecifics& nigori,
849 syncable::BaseTransaction* const trans) {
850 DCHECK(thread_checker_.CalledOnValidThread());
851 DVLOG(1) << "Applying nigori node update.";
852 bool nigori_types_need_update = !UpdateEncryptedTypesFromNigori(nigori,
853 trans);
854
855 if (nigori.custom_passphrase_time() != 0) {
856 custom_passphrase_time_ =
857 ProtoTimeToTime(nigori.custom_passphrase_time());
858 }
859 bool is_nigori_migrated = IsNigoriMigratedToKeystore(nigori);
860 if (is_nigori_migrated) {
861 DCHECK(nigori.has_keystore_migration_time());
862 migration_time_ = ProtoTimeToTime(nigori.keystore_migration_time());
863 PassphraseType nigori_passphrase_type =
864 ProtoPassphraseTypeToEnum(nigori.passphrase_type());
865
866 // Only update the local passphrase state if it's a valid transition:
867 // - implicit -> keystore
868 // - implicit -> frozen implicit
869 // - implicit -> custom
870 // - keystore -> custom
871 // Note: frozen implicit -> custom is not technically a valid transition,
872 // but we let it through here as well in case future versions do add support
873 // for this transition.
874 if (passphrase_type_ != nigori_passphrase_type &&
875 nigori_passphrase_type != IMPLICIT_PASSPHRASE &&
876 (passphrase_type_ == IMPLICIT_PASSPHRASE ||
877 nigori_passphrase_type == CUSTOM_PASSPHRASE)) {
878 DVLOG(1) << "Changing passphrase state from "
879 << PassphraseTypeToString(passphrase_type_)
880 << " to "
881 << PassphraseTypeToString(nigori_passphrase_type);
882 passphrase_type_ = nigori_passphrase_type;
883 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
884 OnPassphraseTypeChanged(
885 passphrase_type_,
886 GetExplicitPassphraseTime()));
887 }
888 if (passphrase_type_ == KEYSTORE_PASSPHRASE && encrypt_everything_) {
889 // This is the case where another client that didn't support keystore
890 // encryption attempted to enable full encryption. We detect it
891 // and switch the passphrase type to frozen implicit passphrase instead
892 // due to full encryption not being compatible with keystore passphrase.
893 // Because the local passphrase type will not match the nigori passphrase
894 // type, we will trigger a rewrite and subsequently a re-migration.
895 DVLOG(1) << "Changing passphrase state to FROZEN_IMPLICIT_PASSPHRASE "
896 << "due to full encryption.";
897 passphrase_type_ = FROZEN_IMPLICIT_PASSPHRASE;
898 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
899 OnPassphraseTypeChanged(
900 passphrase_type_,
901 GetExplicitPassphraseTime()));
902 }
903 } else {
904 // It's possible that while we're waiting for migration a client that does
905 // not have keystore encryption enabled switches to a custom passphrase.
906 if (nigori.keybag_is_frozen() &&
907 passphrase_type_ != CUSTOM_PASSPHRASE) {
908 passphrase_type_ = CUSTOM_PASSPHRASE;
909 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
910 OnPassphraseTypeChanged(
911 passphrase_type_,
912 GetExplicitPassphraseTime()));
913 }
914 }
915
916 Cryptographer* cryptographer = &UnlockVaultMutable(trans)->cryptographer;
917 bool nigori_needs_new_keys = false;
918 if (!nigori.encryption_keybag().blob().empty()) {
919 // We only update the default key if this was a new explicit passphrase.
920 // Else, since it was decryptable, it must not have been a new key.
921 bool need_new_default_key = false;
922 if (is_nigori_migrated) {
923 need_new_default_key = IsExplicitPassphrase(
924 ProtoPassphraseTypeToEnum(nigori.passphrase_type()));
925 } else {
926 need_new_default_key = nigori.keybag_is_frozen();
927 }
928 if (!AttemptToInstallKeybag(nigori.encryption_keybag(),
929 need_new_default_key,
930 cryptographer)) {
931 // Check to see if we can decrypt the keybag using the keystore decryptor
932 // token.
933 cryptographer->SetPendingKeys(nigori.encryption_keybag());
934 if (!nigori.keystore_decryptor_token().blob().empty() &&
935 !keystore_key_.empty()) {
936 if (DecryptPendingKeysWithKeystoreKey(keystore_key_,
937 nigori.keystore_decryptor_token(),
938 cryptographer)) {
939 nigori_needs_new_keys =
940 cryptographer->KeybagIsStale(nigori.encryption_keybag());
941 } else {
942 LOG(ERROR) << "Failed to decrypt pending keys using keystore "
943 << "bootstrap key.";
944 }
945 }
946 } else {
947 // Keybag was installed. We write back our local keybag into the nigori
948 // node if the nigori node's keybag either contains less keys or
949 // has a different default key.
950 nigori_needs_new_keys =
951 cryptographer->KeybagIsStale(nigori.encryption_keybag());
952 }
953 } else {
954 // The nigori node has an empty encryption keybag. Attempt to write our
955 // local encryption keys into it.
956 LOG(WARNING) << "Nigori had empty encryption keybag.";
957 nigori_needs_new_keys = true;
958 }
959
960 // If we've completed a sync cycle and the cryptographer isn't ready
961 // yet or has pending keys, prompt the user for a passphrase.
962 if (cryptographer->has_pending_keys()) {
963 DVLOG(1) << "OnPassphraseRequired Sent";
964 sync_pb::EncryptedData pending_keys = cryptographer->GetPendingKeys();
965 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
966 OnPassphraseRequired(REASON_DECRYPTION,
967 pending_keys));
968 } else if (!cryptographer->is_ready()) {
969 DVLOG(1) << "OnPassphraseRequired sent because cryptographer is not "
970 << "ready";
971 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
972 OnPassphraseRequired(REASON_ENCRYPTION,
973 sync_pb::EncryptedData()));
974 }
975
976 // Check if the current local encryption state is stricter/newer than the
977 // nigori state. If so, we need to overwrite the nigori node with the local
978 // state.
979 bool passphrase_type_matches = true;
980 if (!is_nigori_migrated) {
981 DCHECK(passphrase_type_ == CUSTOM_PASSPHRASE ||
982 passphrase_type_ == IMPLICIT_PASSPHRASE);
983 passphrase_type_matches =
984 nigori.keybag_is_frozen() == IsExplicitPassphrase(passphrase_type_);
985 } else {
986 passphrase_type_matches =
987 (ProtoPassphraseTypeToEnum(nigori.passphrase_type()) ==
988 passphrase_type_);
989 }
990 if (!passphrase_type_matches ||
991 nigori.encrypt_everything() != encrypt_everything_ ||
992 nigori_types_need_update ||
993 nigori_needs_new_keys) {
994 DVLOG(1) << "Triggering nigori rewrite.";
995 return false;
996 }
997 return true;
998 }
999
RewriteNigori()1000 void SyncEncryptionHandlerImpl::RewriteNigori() {
1001 DVLOG(1) << "Writing local encryption state into nigori.";
1002 DCHECK(thread_checker_.CalledOnValidThread());
1003 WriteTransaction trans(FROM_HERE, user_share_);
1004 WriteEncryptionStateToNigori(&trans);
1005 }
1006
WriteEncryptionStateToNigori(WriteTransaction * trans)1007 void SyncEncryptionHandlerImpl::WriteEncryptionStateToNigori(
1008 WriteTransaction* trans) {
1009 DCHECK(thread_checker_.CalledOnValidThread());
1010 WriteNode nigori_node(trans);
1011 // This can happen in tests that don't have nigori nodes.
1012 if (nigori_node.InitTypeRoot(NIGORI) != BaseNode::INIT_OK)
1013 return;
1014
1015 sync_pb::NigoriSpecifics nigori = nigori_node.GetNigoriSpecifics();
1016 const Cryptographer& cryptographer =
1017 UnlockVault(trans->GetWrappedTrans()).cryptographer;
1018
1019 // Will not do anything if we shouldn't or can't migrate. Otherwise
1020 // migrates, writing the full encryption state as it does.
1021 if (!AttemptToMigrateNigoriToKeystore(trans, &nigori_node)) {
1022 if (cryptographer.is_ready() &&
1023 nigori_overwrite_count_ < kNigoriOverwriteLimit) {
1024 // Does not modify the encrypted blob if the unencrypted data already
1025 // matches what is about to be written.
1026 sync_pb::EncryptedData original_keys = nigori.encryption_keybag();
1027 if (!cryptographer.GetKeys(nigori.mutable_encryption_keybag()))
1028 NOTREACHED();
1029
1030 if (nigori.encryption_keybag().SerializeAsString() !=
1031 original_keys.SerializeAsString()) {
1032 // We've updated the nigori node's encryption keys. In order to prevent
1033 // a possible looping of two clients constantly overwriting each other,
1034 // we limit the absolute number of overwrites per client instantiation.
1035 nigori_overwrite_count_++;
1036 UMA_HISTOGRAM_COUNTS("Sync.AutoNigoriOverwrites",
1037 nigori_overwrite_count_);
1038 }
1039
1040 // Note: we don't try to set keybag_is_frozen here since if that
1041 // is lost the user can always set it again (and we don't want to clobber
1042 // any migration state). The main goal at this point is to preserve
1043 // the encryption keys so all data remains decryptable.
1044 }
1045 syncable::UpdateNigoriFromEncryptedTypes(
1046 UnlockVault(trans->GetWrappedTrans()).encrypted_types,
1047 encrypt_everything_,
1048 &nigori);
1049 if (!custom_passphrase_time_.is_null()) {
1050 nigori.set_custom_passphrase_time(
1051 TimeToProtoTime(custom_passphrase_time_));
1052 }
1053
1054 // If nothing has changed, this is a no-op.
1055 nigori_node.SetNigoriSpecifics(nigori);
1056 }
1057 }
1058
UpdateEncryptedTypesFromNigori(const sync_pb::NigoriSpecifics & nigori,syncable::BaseTransaction * const trans)1059 bool SyncEncryptionHandlerImpl::UpdateEncryptedTypesFromNigori(
1060 const sync_pb::NigoriSpecifics& nigori,
1061 syncable::BaseTransaction* const trans) {
1062 DCHECK(thread_checker_.CalledOnValidThread());
1063 ModelTypeSet* encrypted_types = &UnlockVaultMutable(trans)->encrypted_types;
1064 if (nigori.encrypt_everything()) {
1065 EnableEncryptEverythingImpl(trans);
1066 DCHECK(encrypted_types->Equals(EncryptableUserTypes()));
1067 return true;
1068 } else if (encrypt_everything_) {
1069 DCHECK(encrypted_types->Equals(EncryptableUserTypes()));
1070 return false;
1071 }
1072
1073 ModelTypeSet nigori_encrypted_types;
1074 nigori_encrypted_types = syncable::GetEncryptedTypesFromNigori(nigori);
1075 nigori_encrypted_types.PutAll(SensitiveTypes());
1076
1077 // If anything more than the sensitive types were encrypted, and
1078 // encrypt_everything is not explicitly set to false, we assume it means
1079 // a client intended to enable encrypt everything.
1080 if (!nigori.has_encrypt_everything() &&
1081 !Difference(nigori_encrypted_types, SensitiveTypes()).Empty()) {
1082 if (!encrypt_everything_) {
1083 encrypt_everything_ = true;
1084 *encrypted_types = EncryptableUserTypes();
1085 FOR_EACH_OBSERVER(
1086 Observer, observers_,
1087 OnEncryptedTypesChanged(*encrypted_types, encrypt_everything_));
1088 }
1089 DCHECK(encrypted_types->Equals(EncryptableUserTypes()));
1090 return false;
1091 }
1092
1093 MergeEncryptedTypes(nigori_encrypted_types, trans);
1094 return encrypted_types->Equals(nigori_encrypted_types);
1095 }
1096
SetCustomPassphrase(const std::string & passphrase,WriteTransaction * trans,WriteNode * nigori_node)1097 void SyncEncryptionHandlerImpl::SetCustomPassphrase(
1098 const std::string& passphrase,
1099 WriteTransaction* trans,
1100 WriteNode* nigori_node) {
1101 DCHECK(thread_checker_.CalledOnValidThread());
1102 DCHECK(IsNigoriMigratedToKeystore(nigori_node->GetNigoriSpecifics()));
1103 KeyParams key_params = {"localhost", "dummy", passphrase};
1104
1105 if (passphrase_type_ != KEYSTORE_PASSPHRASE) {
1106 DVLOG(1) << "Failing to set a custom passphrase because one has already "
1107 << "been set.";
1108 FinishSetPassphrase(false, std::string(), trans, nigori_node);
1109 return;
1110 }
1111
1112 Cryptographer* cryptographer =
1113 &UnlockVaultMutable(trans->GetWrappedTrans())->cryptographer;
1114 if (cryptographer->has_pending_keys()) {
1115 // This theoretically shouldn't happen, because the only way to have pending
1116 // keys after migrating to keystore support is if a custom passphrase was
1117 // set, which should update passpshrase_state_ and should be caught by the
1118 // if statement above. For the sake of safety though, we check for it in
1119 // case a client is misbehaving.
1120 LOG(ERROR) << "Failing to set custom passphrase because of pending keys.";
1121 FinishSetPassphrase(false, std::string(), trans, nigori_node);
1122 return;
1123 }
1124
1125 std::string bootstrap_token;
1126 if (cryptographer->AddKey(key_params)) {
1127 DVLOG(1) << "Setting custom passphrase.";
1128 cryptographer->GetBootstrapToken(&bootstrap_token);
1129 passphrase_type_ = CUSTOM_PASSPHRASE;
1130 custom_passphrase_time_ = base::Time::Now();
1131 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
1132 OnPassphraseTypeChanged(
1133 passphrase_type_,
1134 GetExplicitPassphraseTime()));
1135 } else {
1136 NOTREACHED() << "Failed to add key to cryptographer.";
1137 return;
1138 }
1139 FinishSetPassphrase(true, bootstrap_token, trans, nigori_node);
1140 }
1141
DecryptPendingKeysWithExplicitPassphrase(const std::string & passphrase,WriteTransaction * trans,WriteNode * nigori_node)1142 void SyncEncryptionHandlerImpl::DecryptPendingKeysWithExplicitPassphrase(
1143 const std::string& passphrase,
1144 WriteTransaction* trans,
1145 WriteNode* nigori_node) {
1146 DCHECK(thread_checker_.CalledOnValidThread());
1147 DCHECK(IsExplicitPassphrase(passphrase_type_));
1148 KeyParams key_params = {"localhost", "dummy", passphrase};
1149
1150 Cryptographer* cryptographer =
1151 &UnlockVaultMutable(trans->GetWrappedTrans())->cryptographer;
1152 if (!cryptographer->has_pending_keys()) {
1153 // Note that this *can* happen in a rare situation where data is
1154 // re-encrypted on another client while a SetDecryptionPassphrase() call is
1155 // in-flight on this client. It is rare enough that we choose to do nothing.
1156 NOTREACHED() << "Attempt to set decryption passphrase failed because there "
1157 << "were no pending keys.";
1158 return;
1159 }
1160
1161 DCHECK(IsExplicitPassphrase(passphrase_type_));
1162 bool success = false;
1163 std::string bootstrap_token;
1164 if (cryptographer->DecryptPendingKeys(key_params)) {
1165 DVLOG(1) << "Explicit passphrase accepted for decryption.";
1166 cryptographer->GetBootstrapToken(&bootstrap_token);
1167 success = true;
1168 } else {
1169 DVLOG(1) << "Explicit passphrase failed to decrypt.";
1170 success = false;
1171 }
1172 if (success && !keystore_key_.empty()) {
1173 // Should already be part of the encryption keybag, but we add it just
1174 // in case.
1175 KeyParams key_params = {"localhost", "dummy", keystore_key_};
1176 cryptographer->AddNonDefaultKey(key_params);
1177 }
1178 FinishSetPassphrase(success, bootstrap_token, trans, nigori_node);
1179 }
1180
FinishSetPassphrase(bool success,const std::string & bootstrap_token,WriteTransaction * trans,WriteNode * nigori_node)1181 void SyncEncryptionHandlerImpl::FinishSetPassphrase(
1182 bool success,
1183 const std::string& bootstrap_token,
1184 WriteTransaction* trans,
1185 WriteNode* nigori_node) {
1186 DCHECK(thread_checker_.CalledOnValidThread());
1187 FOR_EACH_OBSERVER(
1188 SyncEncryptionHandler::Observer,
1189 observers_,
1190 OnCryptographerStateChanged(
1191 &UnlockVaultMutable(trans->GetWrappedTrans())->cryptographer));
1192
1193 // It's possible we need to change the bootstrap token even if we failed to
1194 // set the passphrase (for example if we need to preserve the new GAIA
1195 // passphrase).
1196 if (!bootstrap_token.empty()) {
1197 DVLOG(1) << "Passphrase bootstrap token updated.";
1198 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
1199 OnBootstrapTokenUpdated(bootstrap_token,
1200 PASSPHRASE_BOOTSTRAP_TOKEN));
1201 }
1202
1203 const Cryptographer& cryptographer =
1204 UnlockVault(trans->GetWrappedTrans()).cryptographer;
1205 if (!success) {
1206 if (cryptographer.is_ready()) {
1207 LOG(ERROR) << "Attempt to change passphrase failed while cryptographer "
1208 << "was ready.";
1209 } else if (cryptographer.has_pending_keys()) {
1210 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
1211 OnPassphraseRequired(REASON_DECRYPTION,
1212 cryptographer.GetPendingKeys()));
1213 } else {
1214 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
1215 OnPassphraseRequired(REASON_ENCRYPTION,
1216 sync_pb::EncryptedData()));
1217 }
1218 return;
1219 }
1220 DCHECK(success);
1221 DCHECK(cryptographer.is_ready());
1222
1223 // Will do nothing if we're already properly migrated or unable to migrate
1224 // (in otherwords, if ShouldTriggerMigration is false).
1225 // Otherwise will update the nigori node with the current migrated state,
1226 // writing all encryption state as it does.
1227 if (!AttemptToMigrateNigoriToKeystore(trans, nigori_node)) {
1228 sync_pb::NigoriSpecifics nigori(nigori_node->GetNigoriSpecifics());
1229 // Does not modify nigori.encryption_keybag() if the original decrypted
1230 // data was the same.
1231 if (!cryptographer.GetKeys(nigori.mutable_encryption_keybag()))
1232 NOTREACHED();
1233 if (IsNigoriMigratedToKeystore(nigori)) {
1234 DCHECK(keystore_key_.empty() || IsExplicitPassphrase(passphrase_type_));
1235 DVLOG(1) << "Leaving nigori migration state untouched after setting"
1236 << " passphrase.";
1237 } else {
1238 nigori.set_keybag_is_frozen(
1239 IsExplicitPassphrase(passphrase_type_));
1240 }
1241 // If we set a new custom passphrase, store the timestamp.
1242 if (!custom_passphrase_time_.is_null()) {
1243 nigori.set_custom_passphrase_time(
1244 TimeToProtoTime(custom_passphrase_time_));
1245 }
1246 nigori_node->SetNigoriSpecifics(nigori);
1247 }
1248
1249 // Must do this after OnPassphraseTypeChanged, in order to ensure the PSS
1250 // checks the passphrase state after it has been set.
1251 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
1252 OnPassphraseAccepted());
1253
1254 // Does nothing if everything is already encrypted.
1255 // TODO(zea): If we just migrated and enabled encryption, this will be
1256 // redundant. Figure out a way to not do this unnecessarily.
1257 ReEncryptEverything(trans);
1258 }
1259
MergeEncryptedTypes(ModelTypeSet new_encrypted_types,syncable::BaseTransaction * const trans)1260 void SyncEncryptionHandlerImpl::MergeEncryptedTypes(
1261 ModelTypeSet new_encrypted_types,
1262 syncable::BaseTransaction* const trans) {
1263 DCHECK(thread_checker_.CalledOnValidThread());
1264
1265 // Only UserTypes may be encrypted.
1266 DCHECK(EncryptableUserTypes().HasAll(new_encrypted_types));
1267
1268 ModelTypeSet* encrypted_types = &UnlockVaultMutable(trans)->encrypted_types;
1269 if (!encrypted_types->HasAll(new_encrypted_types)) {
1270 *encrypted_types = new_encrypted_types;
1271 FOR_EACH_OBSERVER(
1272 Observer, observers_,
1273 OnEncryptedTypesChanged(*encrypted_types, encrypt_everything_));
1274 }
1275 }
1276
UnlockVaultMutable(syncable::BaseTransaction * const trans)1277 SyncEncryptionHandlerImpl::Vault* SyncEncryptionHandlerImpl::UnlockVaultMutable(
1278 syncable::BaseTransaction* const trans) {
1279 DCHECK_EQ(user_share_->directory.get(), trans->directory());
1280 return &vault_unsafe_;
1281 }
1282
UnlockVault(syncable::BaseTransaction * const trans) const1283 const SyncEncryptionHandlerImpl::Vault& SyncEncryptionHandlerImpl::UnlockVault(
1284 syncable::BaseTransaction* const trans) const {
1285 DCHECK_EQ(user_share_->directory.get(), trans->directory());
1286 return vault_unsafe_;
1287 }
1288
ShouldTriggerMigration(const sync_pb::NigoriSpecifics & nigori,const Cryptographer & cryptographer) const1289 bool SyncEncryptionHandlerImpl::ShouldTriggerMigration(
1290 const sync_pb::NigoriSpecifics& nigori,
1291 const Cryptographer& cryptographer) const {
1292 DCHECK(thread_checker_.CalledOnValidThread());
1293 // Don't migrate if there are pending encryption keys (because data
1294 // encrypted with the pending keys will not be decryptable).
1295 if (cryptographer.has_pending_keys())
1296 return false;
1297 if (IsNigoriMigratedToKeystore(nigori)) {
1298 // If the nigori is already migrated but does not reflect the explicit
1299 // passphrase state, remigrate. Similarly, if the nigori has an explicit
1300 // passphrase but does not have full encryption, or the nigori has an
1301 // implicit passphrase but does have full encryption, re-migrate.
1302 // Note that this is to defend against other clients without keystore
1303 // encryption enabled transitioning to states that are no longer valid.
1304 if (passphrase_type_ != KEYSTORE_PASSPHRASE &&
1305 nigori.passphrase_type() ==
1306 sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE) {
1307 return true;
1308 } else if (IsExplicitPassphrase(passphrase_type_) &&
1309 !encrypt_everything_) {
1310 return true;
1311 } else if (passphrase_type_ == KEYSTORE_PASSPHRASE &&
1312 encrypt_everything_) {
1313 return true;
1314 } else if (
1315 cryptographer.is_ready() &&
1316 !cryptographer.CanDecryptUsingDefaultKey(nigori.encryption_keybag())) {
1317 // We need to overwrite the keybag. This might involve overwriting the
1318 // keystore decryptor too.
1319 return true;
1320 } else if (old_keystore_keys_.size() > 0 && !keystore_key_.empty()) {
1321 // Check to see if a server key rotation has happened, but the nigori
1322 // node's keys haven't been rotated yet, and hence we should re-migrate.
1323 // Note that once a key rotation has been performed, we no longer
1324 // preserve backwards compatibility, and the keybag will therefore be
1325 // encrypted with the current keystore key.
1326 Cryptographer temp_cryptographer(cryptographer.encryptor());
1327 KeyParams keystore_params = {"localhost", "dummy", keystore_key_};
1328 temp_cryptographer.AddKey(keystore_params);
1329 if (!temp_cryptographer.CanDecryptUsingDefaultKey(
1330 nigori.encryption_keybag())) {
1331 return true;
1332 }
1333 }
1334 return false;
1335 } else if (keystore_key_.empty()) {
1336 // If we haven't already migrated, we don't want to do anything unless
1337 // a keystore key is available (so that those clients without keystore
1338 // encryption enabled aren't forced into new states, e.g. frozen implicit
1339 // passphrase).
1340 return false;
1341 }
1342 return true;
1343 }
1344
AttemptToMigrateNigoriToKeystore(WriteTransaction * trans,WriteNode * nigori_node)1345 bool SyncEncryptionHandlerImpl::AttemptToMigrateNigoriToKeystore(
1346 WriteTransaction* trans,
1347 WriteNode* nigori_node) {
1348 DCHECK(thread_checker_.CalledOnValidThread());
1349 const sync_pb::NigoriSpecifics& old_nigori =
1350 nigori_node->GetNigoriSpecifics();
1351 Cryptographer* cryptographer =
1352 &UnlockVaultMutable(trans->GetWrappedTrans())->cryptographer;
1353
1354 if (!ShouldTriggerMigration(old_nigori, *cryptographer))
1355 return false;
1356
1357 DVLOG(1) << "Starting nigori migration to keystore support.";
1358 sync_pb::NigoriSpecifics migrated_nigori(old_nigori);
1359
1360 PassphraseType new_passphrase_type = passphrase_type_;
1361 bool new_encrypt_everything = encrypt_everything_;
1362 if (encrypt_everything_ && !IsExplicitPassphrase(passphrase_type_)) {
1363 DVLOG(1) << "Switching to frozen implicit passphrase due to already having "
1364 << "full encryption.";
1365 new_passphrase_type = FROZEN_IMPLICIT_PASSPHRASE;
1366 migrated_nigori.clear_keystore_decryptor_token();
1367 } else if (IsExplicitPassphrase(passphrase_type_)) {
1368 DVLOG_IF(1, !encrypt_everything_) << "Enabling encrypt everything due to "
1369 << "explicit passphrase";
1370 new_encrypt_everything = true;
1371 migrated_nigori.clear_keystore_decryptor_token();
1372 } else {
1373 DCHECK(!encrypt_everything_);
1374 new_passphrase_type = KEYSTORE_PASSPHRASE;
1375 DVLOG(1) << "Switching to keystore passphrase state.";
1376 }
1377 migrated_nigori.set_encrypt_everything(new_encrypt_everything);
1378 migrated_nigori.set_passphrase_type(
1379 EnumPassphraseTypeToProto(new_passphrase_type));
1380 migrated_nigori.set_keybag_is_frozen(true);
1381
1382 if (!keystore_key_.empty()) {
1383 KeyParams key_params = {"localhost", "dummy", keystore_key_};
1384 if ((old_keystore_keys_.size() > 0 &&
1385 new_passphrase_type == KEYSTORE_PASSPHRASE) ||
1386 !cryptographer->is_initialized()) {
1387 // Either at least one key rotation has been performed, so we no longer
1388 // care about backwards compatibility, or we're generating keystore-based
1389 // encryption keys without knowing the GAIA password (and therefore the
1390 // cryptographer is not initialized), so we can't support backwards
1391 // compatibility. Ensure the keystore key is the default key.
1392 DVLOG(1) << "Migrating keybag to keystore key.";
1393 bool cryptographer_was_ready = cryptographer->is_ready();
1394 if (!cryptographer->AddKey(key_params)) {
1395 LOG(ERROR) << "Failed to add keystore key as default key";
1396 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1397 FAILED_TO_SET_DEFAULT_KEYSTORE,
1398 MIGRATION_RESULT_SIZE);
1399 return false;
1400 }
1401 if (!cryptographer_was_ready && cryptographer->is_ready()) {
1402 FOR_EACH_OBSERVER(
1403 SyncEncryptionHandler::Observer,
1404 observers_,
1405 OnPassphraseAccepted());
1406 }
1407 } else {
1408 // We're in backwards compatible mode -- either the account has an
1409 // explicit passphrase, or we want to preserve the current GAIA-based key
1410 // as the default because we can (there have been no key rotations since
1411 // the migration).
1412 DVLOG(1) << "Migrating keybag while preserving old key";
1413 if (!cryptographer->AddNonDefaultKey(key_params)) {
1414 LOG(ERROR) << "Failed to add keystore key as non-default key.";
1415 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1416 FAILED_TO_SET_NONDEFAULT_KEYSTORE,
1417 MIGRATION_RESULT_SIZE);
1418 return false;
1419 }
1420 }
1421 }
1422 if (!old_keystore_keys_.empty()) {
1423 // Go through and add all the old keystore keys as non default keys, so
1424 // they'll be preserved in the encryption_keybag when we next write the
1425 // nigori node.
1426 for (std::vector<std::string>::const_iterator iter =
1427 old_keystore_keys_.begin(); iter != old_keystore_keys_.end();
1428 ++iter) {
1429 KeyParams key_params = {"localhost", "dummy", *iter};
1430 cryptographer->AddNonDefaultKey(key_params);
1431 }
1432 }
1433 if (new_passphrase_type == KEYSTORE_PASSPHRASE &&
1434 !GetKeystoreDecryptor(
1435 *cryptographer,
1436 keystore_key_,
1437 migrated_nigori.mutable_keystore_decryptor_token())) {
1438 LOG(ERROR) << "Failed to extract keystore decryptor token.";
1439 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1440 FAILED_TO_EXTRACT_DECRYPTOR,
1441 MIGRATION_RESULT_SIZE);
1442 return false;
1443 }
1444 if (!cryptographer->GetKeys(migrated_nigori.mutable_encryption_keybag())) {
1445 LOG(ERROR) << "Failed to extract encryption keybag.";
1446 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1447 FAILED_TO_EXTRACT_KEYBAG,
1448 MIGRATION_RESULT_SIZE);
1449 return false;
1450 }
1451
1452 if (migration_time_.is_null())
1453 migration_time_ = base::Time::Now();
1454 migrated_nigori.set_keystore_migration_time(TimeToProtoTime(migration_time_));
1455
1456 if (!custom_passphrase_time_.is_null()) {
1457 migrated_nigori.set_custom_passphrase_time(
1458 TimeToProtoTime(custom_passphrase_time_));
1459 }
1460
1461 FOR_EACH_OBSERVER(
1462 SyncEncryptionHandler::Observer,
1463 observers_,
1464 OnCryptographerStateChanged(cryptographer));
1465 if (passphrase_type_ != new_passphrase_type) {
1466 passphrase_type_ = new_passphrase_type;
1467 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
1468 OnPassphraseTypeChanged(
1469 passphrase_type_,
1470 GetExplicitPassphraseTime()));
1471 }
1472
1473 if (new_encrypt_everything && !encrypt_everything_) {
1474 EnableEncryptEverythingImpl(trans->GetWrappedTrans());
1475 ReEncryptEverything(trans);
1476 } else if (!cryptographer->CanDecryptUsingDefaultKey(
1477 old_nigori.encryption_keybag())) {
1478 DVLOG(1) << "Rencrypting everything due to key rotation.";
1479 ReEncryptEverything(trans);
1480 }
1481
1482 DVLOG(1) << "Completing nigori migration to keystore support.";
1483 nigori_node->SetNigoriSpecifics(migrated_nigori);
1484
1485 switch (new_passphrase_type) {
1486 case KEYSTORE_PASSPHRASE:
1487 if (old_keystore_keys_.size() > 0) {
1488 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1489 MIGRATION_SUCCESS_KEYSTORE_NONDEFAULT,
1490 MIGRATION_RESULT_SIZE);
1491 } else {
1492 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1493 MIGRATION_SUCCESS_KEYSTORE_DEFAULT,
1494 MIGRATION_RESULT_SIZE);
1495 }
1496 break;
1497 case FROZEN_IMPLICIT_PASSPHRASE:
1498 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1499 MIGRATION_SUCCESS_FROZEN_IMPLICIT,
1500 MIGRATION_RESULT_SIZE);
1501 break;
1502 case CUSTOM_PASSPHRASE:
1503 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1504 MIGRATION_SUCCESS_CUSTOM,
1505 MIGRATION_RESULT_SIZE);
1506 break;
1507 default:
1508 NOTREACHED();
1509 break;
1510 }
1511 return true;
1512 }
1513
GetKeystoreDecryptor(const Cryptographer & cryptographer,const std::string & keystore_key,sync_pb::EncryptedData * encrypted_blob)1514 bool SyncEncryptionHandlerImpl::GetKeystoreDecryptor(
1515 const Cryptographer& cryptographer,
1516 const std::string& keystore_key,
1517 sync_pb::EncryptedData* encrypted_blob) {
1518 DCHECK(thread_checker_.CalledOnValidThread());
1519 DCHECK(!keystore_key.empty());
1520 DCHECK(cryptographer.is_ready());
1521 std::string serialized_nigori;
1522 serialized_nigori = cryptographer.GetDefaultNigoriKey();
1523 if (serialized_nigori.empty()) {
1524 LOG(ERROR) << "Failed to get cryptographer bootstrap token.";
1525 return false;
1526 }
1527 Cryptographer temp_cryptographer(cryptographer.encryptor());
1528 KeyParams key_params = {"localhost", "dummy", keystore_key};
1529 if (!temp_cryptographer.AddKey(key_params))
1530 return false;
1531 if (!temp_cryptographer.EncryptString(serialized_nigori, encrypted_blob))
1532 return false;
1533 return true;
1534 }
1535
AttemptToInstallKeybag(const sync_pb::EncryptedData & keybag,bool update_default,Cryptographer * cryptographer)1536 bool SyncEncryptionHandlerImpl::AttemptToInstallKeybag(
1537 const sync_pb::EncryptedData& keybag,
1538 bool update_default,
1539 Cryptographer* cryptographer) {
1540 if (!cryptographer->CanDecrypt(keybag))
1541 return false;
1542 cryptographer->InstallKeys(keybag);
1543 if (update_default)
1544 cryptographer->SetDefaultKey(keybag.key_name());
1545 return true;
1546 }
1547
EnableEncryptEverythingImpl(syncable::BaseTransaction * const trans)1548 void SyncEncryptionHandlerImpl::EnableEncryptEverythingImpl(
1549 syncable::BaseTransaction* const trans) {
1550 ModelTypeSet* encrypted_types = &UnlockVaultMutable(trans)->encrypted_types;
1551 if (encrypt_everything_) {
1552 DCHECK(encrypted_types->Equals(EncryptableUserTypes()));
1553 return;
1554 }
1555 encrypt_everything_ = true;
1556 *encrypted_types = EncryptableUserTypes();
1557 FOR_EACH_OBSERVER(
1558 Observer, observers_,
1559 OnEncryptedTypesChanged(*encrypted_types, encrypt_everything_));
1560 }
1561
DecryptPendingKeysWithKeystoreKey(const std::string & keystore_key,const sync_pb::EncryptedData & keystore_decryptor_token,Cryptographer * cryptographer)1562 bool SyncEncryptionHandlerImpl::DecryptPendingKeysWithKeystoreKey(
1563 const std::string& keystore_key,
1564 const sync_pb::EncryptedData& keystore_decryptor_token,
1565 Cryptographer* cryptographer) {
1566 DCHECK(cryptographer->has_pending_keys());
1567 if (keystore_decryptor_token.blob().empty())
1568 return false;
1569 Cryptographer temp_cryptographer(cryptographer->encryptor());
1570
1571 // First, go through and all all the old keystore keys to the temporary
1572 // cryptographer.
1573 for (size_t i = 0; i < old_keystore_keys_.size(); ++i) {
1574 KeyParams old_key_params = {"localhost", "dummy", old_keystore_keys_[i]};
1575 temp_cryptographer.AddKey(old_key_params);
1576 }
1577
1578 // Then add the current keystore key as the default key and see if we can
1579 // decrypt.
1580 KeyParams keystore_params = {"localhost", "dummy", keystore_key_};
1581 if (temp_cryptographer.AddKey(keystore_params) &&
1582 temp_cryptographer.CanDecrypt(keystore_decryptor_token)) {
1583 // Someone else migrated the nigori for us! How generous! Go ahead and
1584 // install both the keystore key and the new default encryption key
1585 // (i.e. the one provided by the keystore decryptor token) into the
1586 // cryptographer.
1587 // The keystore decryptor token is a keystore key encrypted blob containing
1588 // the current serialized default encryption key (and as such should be
1589 // able to decrypt the nigori node's encryption keybag).
1590 // Note: it's possible a key rotation has happened since the migration, and
1591 // we're decrypting using an old keystore key. In that case we need to
1592 // ensure we re-encrypt using the newest key.
1593 DVLOG(1) << "Attempting to decrypt pending keys using "
1594 << "keystore decryptor token.";
1595 std::string serialized_nigori =
1596 temp_cryptographer.DecryptToString(keystore_decryptor_token);
1597
1598 // This will decrypt the pending keys and add them if possible. The key
1599 // within |serialized_nigori| will be the default after.
1600 cryptographer->ImportNigoriKey(serialized_nigori);
1601
1602 if (!temp_cryptographer.CanDecryptUsingDefaultKey(
1603 keystore_decryptor_token)) {
1604 // The keystore decryptor token was derived from an old keystore key.
1605 // A key rotation is necessary, so set the current keystore key as the
1606 // default key (which will trigger a re-migration).
1607 DVLOG(1) << "Pending keys based on old keystore key. Setting newest "
1608 << "keystore key as default.";
1609 cryptographer->AddKey(keystore_params);
1610 } else {
1611 // Theoretically the encryption keybag should already contain the keystore
1612 // key. We explicitly add it as a safety measure.
1613 DVLOG(1) << "Pending keys based on newest keystore key.";
1614 cryptographer->AddNonDefaultKey(keystore_params);
1615 }
1616 if (cryptographer->is_ready()) {
1617 std::string bootstrap_token;
1618 cryptographer->GetBootstrapToken(&bootstrap_token);
1619 DVLOG(1) << "Keystore decryptor token decrypted pending keys.";
1620 FOR_EACH_OBSERVER(
1621 SyncEncryptionHandler::Observer,
1622 observers_,
1623 OnPassphraseAccepted());
1624 FOR_EACH_OBSERVER(
1625 SyncEncryptionHandler::Observer,
1626 observers_,
1627 OnBootstrapTokenUpdated(bootstrap_token,
1628 PASSPHRASE_BOOTSTRAP_TOKEN));
1629 FOR_EACH_OBSERVER(
1630 SyncEncryptionHandler::Observer,
1631 observers_,
1632 OnCryptographerStateChanged(cryptographer));
1633 return true;
1634 }
1635 }
1636 return false;
1637 }
1638
GetExplicitPassphraseTime() const1639 base::Time SyncEncryptionHandlerImpl::GetExplicitPassphraseTime() const {
1640 if (passphrase_type_ == FROZEN_IMPLICIT_PASSPHRASE)
1641 return migration_time();
1642 else if (passphrase_type_ == CUSTOM_PASSPHRASE)
1643 return custom_passphrase_time();
1644 return base::Time();
1645 }
1646
1647 } // namespace browser_sync
1648