1 // Copyright 2017 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 "components/sync/driver/sync_service_crypto.h"
6
7 #include <utility>
8
9 #include "base/bind.h"
10 #include "base/callback_helpers.h"
11 #include "base/feature_list.h"
12 #include "base/metrics/histogram_macros.h"
13 #include "base/no_destructor.h"
14 #include "base/sequenced_task_runner.h"
15 #include "base/threading/sequenced_task_runner_handle.h"
16 #include "components/sync/base/passphrase_enums.h"
17 #include "components/sync/base/sync_prefs.h"
18 #include "components/sync/driver/sync_driver_switches.h"
19 #include "components/sync/driver/sync_service.h"
20 #include "components/sync/engine/sync_string_conversions.h"
21 #include "components/sync/nigori/nigori.h"
22
23 namespace syncer {
24
25 namespace {
26
27 // Used for UMA.
28 enum class TrustedVaultFetchKeysAttemptForUMA {
29 kFirstAttempt,
30 kSecondAttempt,
31 kMaxValue = kSecondAttempt
32 };
33
34 // Used for the case where a null client is passed to SyncServiceCrypto.
35 class EmptyTrustedVaultClient : public TrustedVaultClient {
36 public:
37 EmptyTrustedVaultClient() = default;
38 ~EmptyTrustedVaultClient() override = default;
39
40 // TrustedVaultClient implementation.
AddObserver(Observer * observer)41 void AddObserver(Observer* observer) override {}
42
RemoveObserver(Observer * observer)43 void RemoveObserver(Observer* observer) override {}
44
FetchKeys(const CoreAccountInfo & account_info,base::OnceCallback<void (const std::vector<std::vector<uint8_t>> &)> cb)45 void FetchKeys(
46 const CoreAccountInfo& account_info,
47 base::OnceCallback<void(const std::vector<std::vector<uint8_t>>&)> cb)
48 override {
49 std::move(cb).Run({});
50 }
51
StoreKeys(const std::string & gaia_id,const std::vector<std::vector<uint8_t>> & keys,int last_key_version)52 void StoreKeys(const std::string& gaia_id,
53 const std::vector<std::vector<uint8_t>>& keys,
54 int last_key_version) override {
55 // Never invoked by SyncServiceCrypto.
56 NOTREACHED();
57 }
58
RemoveAllStoredKeys()59 void RemoveAllStoredKeys() override {
60 // Never invoked by SyncServiceCrypto.
61 NOTREACHED();
62 }
63
MarkKeysAsStale(const CoreAccountInfo & account_info,base::OnceCallback<void (bool)> cb)64 void MarkKeysAsStale(const CoreAccountInfo& account_info,
65 base::OnceCallback<void(bool)> cb) override {
66 std::move(cb).Run(false);
67 }
68
GetIsRecoverabilityDegraded(const CoreAccountInfo & account_info,base::OnceCallback<void (bool)> cb)69 void GetIsRecoverabilityDegraded(const CoreAccountInfo& account_info,
70 base::OnceCallback<void(bool)> cb) override {
71 std::move(cb).Run(false);
72 }
73
AddTrustedRecoveryMethod(const std::string & gaia_id,const std::vector<uint8_t> & public_key,base::OnceClosure cb)74 void AddTrustedRecoveryMethod(const std::string& gaia_id,
75 const std::vector<uint8_t>& public_key,
76 base::OnceClosure cb) override {
77 // Never invoked by SyncServiceCrypto.
78 NOTREACHED();
79 }
80 };
81
82 // A SyncEncryptionHandler::Observer implementation that simply posts all calls
83 // to another task runner.
84 class SyncEncryptionObserverProxy : public SyncEncryptionHandler::Observer {
85 public:
SyncEncryptionObserverProxy(base::WeakPtr<SyncEncryptionHandler::Observer> observer,scoped_refptr<base::SequencedTaskRunner> task_runner)86 SyncEncryptionObserverProxy(
87 base::WeakPtr<SyncEncryptionHandler::Observer> observer,
88 scoped_refptr<base::SequencedTaskRunner> task_runner)
89 : observer_(observer), task_runner_(std::move(task_runner)) {}
90
OnPassphraseRequired(const KeyDerivationParams & key_derivation_params,const sync_pb::EncryptedData & pending_keys)91 void OnPassphraseRequired(
92 const KeyDerivationParams& key_derivation_params,
93 const sync_pb::EncryptedData& pending_keys) override {
94 task_runner_->PostTask(
95 FROM_HERE,
96 base::BindOnce(&SyncEncryptionHandler::Observer::OnPassphraseRequired,
97 observer_, key_derivation_params, pending_keys));
98 }
99
OnPassphraseAccepted()100 void OnPassphraseAccepted() override {
101 task_runner_->PostTask(
102 FROM_HERE,
103 base::BindOnce(&SyncEncryptionHandler::Observer::OnPassphraseAccepted,
104 observer_));
105 }
106
OnTrustedVaultKeyRequired()107 void OnTrustedVaultKeyRequired() override {
108 task_runner_->PostTask(
109 FROM_HERE,
110 base::BindOnce(
111 &SyncEncryptionHandler::Observer::OnTrustedVaultKeyRequired,
112 observer_));
113 }
114
OnTrustedVaultKeyAccepted()115 void OnTrustedVaultKeyAccepted() override {
116 task_runner_->PostTask(
117 FROM_HERE,
118 base::BindOnce(
119 &SyncEncryptionHandler::Observer::OnTrustedVaultKeyAccepted,
120 observer_));
121 }
122
OnBootstrapTokenUpdated(const std::string & bootstrap_token,BootstrapTokenType type)123 void OnBootstrapTokenUpdated(const std::string& bootstrap_token,
124 BootstrapTokenType type) override {
125 task_runner_->PostTask(
126 FROM_HERE,
127 base::BindOnce(
128 &SyncEncryptionHandler::Observer::OnBootstrapTokenUpdated,
129 observer_, bootstrap_token, type));
130 }
131
OnEncryptedTypesChanged(ModelTypeSet encrypted_types,bool encrypt_everything)132 void OnEncryptedTypesChanged(ModelTypeSet encrypted_types,
133 bool encrypt_everything) override {
134 task_runner_->PostTask(
135 FROM_HERE,
136 base::BindOnce(
137 &SyncEncryptionHandler::Observer::OnEncryptedTypesChanged,
138 observer_, encrypted_types, encrypt_everything));
139 }
140
OnCryptographerStateChanged(Cryptographer * cryptographer,bool has_pending_keys)141 void OnCryptographerStateChanged(Cryptographer* cryptographer,
142 bool has_pending_keys) override {
143 task_runner_->PostTask(
144 FROM_HERE,
145 base::BindOnce(
146 &SyncEncryptionHandler::Observer::OnCryptographerStateChanged,
147 observer_, /*cryptographer=*/nullptr, has_pending_keys));
148 }
149
OnPassphraseTypeChanged(PassphraseType type,base::Time passphrase_time)150 void OnPassphraseTypeChanged(PassphraseType type,
151 base::Time passphrase_time) override {
152 task_runner_->PostTask(
153 FROM_HERE,
154 base::BindOnce(
155 &SyncEncryptionHandler::Observer::OnPassphraseTypeChanged,
156 observer_, type, passphrase_time));
157 }
158
159 private:
160 base::WeakPtr<SyncEncryptionHandler::Observer> observer_;
161 scoped_refptr<base::SequencedTaskRunner> task_runner_;
162 };
163
ResoveNullClient(TrustedVaultClient * client)164 TrustedVaultClient* ResoveNullClient(TrustedVaultClient* client) {
165 if (client) {
166 return client;
167 }
168
169 static base::NoDestructor<EmptyTrustedVaultClient> empty_client;
170 return empty_client.get();
171 }
172
173 // Checks if |passphrase| can be used to decrypt the given pending keys. Returns
174 // true if decryption was successful. Returns false otherwise. Must be called
175 // with non-empty pending keys cache.
CheckPassphraseAgainstPendingKeys(const sync_pb::EncryptedData & pending_keys,const KeyDerivationParams & key_derivation_params,const std::string & passphrase)176 bool CheckPassphraseAgainstPendingKeys(
177 const sync_pb::EncryptedData& pending_keys,
178 const KeyDerivationParams& key_derivation_params,
179 const std::string& passphrase) {
180 DCHECK(pending_keys.has_blob());
181 DCHECK(!passphrase.empty());
182 if (key_derivation_params.method() == KeyDerivationMethod::UNSUPPORTED) {
183 DLOG(ERROR) << "Cannot derive keys using an unsupported key derivation "
184 "method. Rejecting passphrase.";
185 return false;
186 }
187
188 std::unique_ptr<Nigori> nigori =
189 Nigori::CreateByDerivation(key_derivation_params, passphrase);
190 DCHECK(nigori);
191 std::string plaintext;
192 bool decrypt_result = nigori->Decrypt(pending_keys.blob(), &plaintext);
193 DVLOG_IF(1, !decrypt_result) << "Passphrase failed to decrypt pending keys.";
194 return decrypt_result;
195 }
196
197 } // namespace
198
State()199 SyncServiceCrypto::State::State()
200 : passphrase_key_derivation_params(KeyDerivationParams::CreateForPbkdf2()) {
201 }
202
203 SyncServiceCrypto::State::~State() = default;
204
SyncServiceCrypto(const base::RepeatingClosure & notify_observers,const base::RepeatingClosure & notify_required_user_action_changed,const base::RepeatingCallback<void (ConfigureReason)> & reconfigure,CryptoSyncPrefs * sync_prefs,TrustedVaultClient * trusted_vault_client)205 SyncServiceCrypto::SyncServiceCrypto(
206 const base::RepeatingClosure& notify_observers,
207 const base::RepeatingClosure& notify_required_user_action_changed,
208 const base::RepeatingCallback<void(ConfigureReason)>& reconfigure,
209 CryptoSyncPrefs* sync_prefs,
210 TrustedVaultClient* trusted_vault_client)
211 : notify_observers_(notify_observers),
212 notify_required_user_action_changed_(notify_required_user_action_changed),
213 reconfigure_(reconfigure),
214 sync_prefs_(sync_prefs),
215 trusted_vault_client_(ResoveNullClient(trusted_vault_client)) {
216 DCHECK(notify_observers_);
217 DCHECK(reconfigure_);
218 DCHECK(sync_prefs_);
219 DCHECK(trusted_vault_client_);
220
221 trusted_vault_client_->AddObserver(this);
222 }
223
~SyncServiceCrypto()224 SyncServiceCrypto::~SyncServiceCrypto() {
225 trusted_vault_client_->RemoveObserver(this);
226 }
227
Reset()228 void SyncServiceCrypto::Reset() {
229 state_ = State();
230 }
231
GetExplicitPassphraseTime() const232 base::Time SyncServiceCrypto::GetExplicitPassphraseTime() const {
233 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
234 return state_.cached_explicit_passphrase_time;
235 }
236
IsPassphraseRequired() const237 bool SyncServiceCrypto::IsPassphraseRequired() const {
238 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
239
240 switch (state_.required_user_action) {
241 case RequiredUserAction::kUnknownDuringInitialization:
242 case RequiredUserAction::kNone:
243 case RequiredUserAction::kFetchingTrustedVaultKeys:
244 case RequiredUserAction::kTrustedVaultKeyRequired:
245 case RequiredUserAction::kTrustedVaultKeyRequiredButFetching:
246 case RequiredUserAction::kTrustedVaultRecoverabilityDegraded:
247 return false;
248 case RequiredUserAction::kPassphraseRequired:
249 return true;
250 }
251
252 NOTREACHED();
253 return false;
254 }
255
IsUsingSecondaryPassphrase() const256 bool SyncServiceCrypto::IsUsingSecondaryPassphrase() const {
257 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
258 return IsExplicitPassphrase(state_.cached_passphrase_type);
259 }
260
IsTrustedVaultKeyRequired() const261 bool SyncServiceCrypto::IsTrustedVaultKeyRequired() const {
262 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
263 return state_.required_user_action ==
264 RequiredUserAction::kTrustedVaultKeyRequired ||
265 state_.required_user_action ==
266 RequiredUserAction::kTrustedVaultKeyRequiredButFetching;
267 }
268
IsTrustedVaultRecoverabilityDegraded() const269 bool SyncServiceCrypto::IsTrustedVaultRecoverabilityDegraded() const {
270 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
271 return state_.required_user_action ==
272 RequiredUserAction::kTrustedVaultRecoverabilityDegraded;
273 }
274
IsEncryptEverythingEnabled() const275 bool SyncServiceCrypto::IsEncryptEverythingEnabled() const {
276 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
277 DCHECK(state_.engine);
278 return state_.encrypt_everything || state_.encryption_pending;
279 }
280
SetEncryptionPassphrase(const std::string & passphrase)281 void SyncServiceCrypto::SetEncryptionPassphrase(const std::string& passphrase) {
282 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
283 // This should only be called when the engine has been initialized.
284 DCHECK(state_.engine);
285 // We should never be called with an empty passphrase.
286 DCHECK(!passphrase.empty());
287
288 switch (state_.required_user_action) {
289 case RequiredUserAction::kUnknownDuringInitialization:
290 case RequiredUserAction::kNone:
291 case RequiredUserAction::kTrustedVaultRecoverabilityDegraded:
292 break;
293 case RequiredUserAction::kPassphraseRequired:
294 case RequiredUserAction::kFetchingTrustedVaultKeys:
295 case RequiredUserAction::kTrustedVaultKeyRequired:
296 case RequiredUserAction::kTrustedVaultKeyRequiredButFetching:
297 // Cryptographer has pending keys.
298 NOTREACHED()
299 << "Can not set explicit passphrase when decryption is needed.";
300 return;
301 }
302
303 DVLOG(1) << "Setting explicit passphrase for encryption.";
304
305 // SetEncryptionPassphrase() should never be called if we are currently
306 // encrypted with an explicit passphrase.
307 DCHECK(!IsExplicitPassphrase(state_.cached_passphrase_type));
308
309 state_.engine->SetEncryptionPassphrase(passphrase);
310 }
311
SetDecryptionPassphrase(const std::string & passphrase)312 bool SyncServiceCrypto::SetDecryptionPassphrase(const std::string& passphrase) {
313 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
314
315 // We should never be called with an empty passphrase.
316 DCHECK(!passphrase.empty());
317
318 // This should only be called when we have cached pending keys.
319 DCHECK(state_.cached_pending_keys.has_blob());
320
321 // For types other than CUSTOM_PASSPHRASE, we should be using the old PBKDF2
322 // key derivation method.
323 if (state_.cached_passphrase_type != PassphraseType::kCustomPassphrase) {
324 DCHECK_EQ(state_.passphrase_key_derivation_params.method(),
325 KeyDerivationMethod::PBKDF2_HMAC_SHA1_1003);
326 }
327
328 // Check the passphrase that was provided against our local cache of the
329 // cryptographer's pending keys (which we cached during a previous
330 // OnPassphraseRequired() event). If this was unsuccessful, the UI layer can
331 // immediately call OnPassphraseRequired() again without showing the user a
332 // spinner.
333 if (!CheckPassphraseAgainstPendingKeys(
334 state_.cached_pending_keys, state_.passphrase_key_derivation_params,
335 passphrase)) {
336 return false;
337 }
338
339 state_.engine->SetDecryptionPassphrase(passphrase);
340
341 // Since we were able to decrypt the cached pending keys with the passphrase
342 // provided, we immediately alert the UI layer that the passphrase was
343 // accepted. This will avoid the situation where a user enters a passphrase,
344 // clicks OK, immediately reopens the advanced settings dialog, and gets an
345 // unnecessary prompt for a passphrase.
346 // Note: It is not guaranteed that the passphrase will be accepted by the
347 // syncer thread, since we could receive a new nigori node while the task is
348 // pending. This scenario is a valid race, and SetDecryptionPassphrase() can
349 // trigger a new OnPassphraseRequired() if it needs to.
350 OnPassphraseAccepted();
351 return true;
352 }
353
IsTrustedVaultKeyRequiredStateKnown() const354 bool SyncServiceCrypto::IsTrustedVaultKeyRequiredStateKnown() const {
355 switch (state_.required_user_action) {
356 case RequiredUserAction::kUnknownDuringInitialization:
357 case RequiredUserAction::kFetchingTrustedVaultKeys:
358 return false;
359 case RequiredUserAction::kNone:
360 case RequiredUserAction::kPassphraseRequired:
361 case RequiredUserAction::kTrustedVaultKeyRequired:
362 case RequiredUserAction::kTrustedVaultKeyRequiredButFetching:
363 case RequiredUserAction::kTrustedVaultRecoverabilityDegraded:
364 return true;
365 }
366 NOTREACHED();
367 return false;
368 }
369
GetPassphraseType() const370 PassphraseType SyncServiceCrypto::GetPassphraseType() const {
371 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
372 return state_.cached_passphrase_type;
373 }
374
SetSyncEngine(const CoreAccountInfo & account_info,SyncEngine * engine)375 void SyncServiceCrypto::SetSyncEngine(const CoreAccountInfo& account_info,
376 SyncEngine* engine) {
377 DCHECK(engine);
378 state_.account_info = account_info;
379 state_.engine = engine;
380
381 // Since there was no state changes during engine initialization, now the
382 // state is known and no user action required.
383 if (state_.required_user_action ==
384 RequiredUserAction::kUnknownDuringInitialization) {
385 UpdateRequiredUserActionAndNotify(RequiredUserAction::kNone);
386 }
387
388 // This indicates OnTrustedVaultKeyRequired() was called as part of the
389 // engine's initialization.
390 if (state_.required_user_action ==
391 RequiredUserAction::kFetchingTrustedVaultKeys) {
392 FetchTrustedVaultKeys(/*is_second_fetch_attempt=*/false);
393 }
394 }
395
396 std::unique_ptr<SyncEncryptionHandler::Observer>
GetEncryptionObserverProxy()397 SyncServiceCrypto::GetEncryptionObserverProxy() {
398 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
399 return std::make_unique<SyncEncryptionObserverProxy>(
400 weak_factory_.GetWeakPtr(), base::SequencedTaskRunnerHandle::Get());
401 }
402
GetEncryptedDataTypes() const403 ModelTypeSet SyncServiceCrypto::GetEncryptedDataTypes() const {
404 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
405 DCHECK(state_.encrypted_types.Has(PASSWORDS));
406 DCHECK(state_.encrypted_types.Has(WIFI_CONFIGURATIONS));
407 // We may be called during the setup process before we're
408 // initialized. In this case, we default to the sensitive types.
409 return state_.encrypted_types;
410 }
411
HasCryptoError() const412 bool SyncServiceCrypto::HasCryptoError() const {
413 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
414
415 // This determines whether DataTypeManager should issue crypto errors for
416 // encrypted datatypes. This may differ from whether the UI represents the
417 // error state or not.
418
419 switch (state_.required_user_action) {
420 case RequiredUserAction::kUnknownDuringInitialization:
421 case RequiredUserAction::kNone:
422 case RequiredUserAction::kTrustedVaultRecoverabilityDegraded:
423 return false;
424 case RequiredUserAction::kFetchingTrustedVaultKeys:
425 case RequiredUserAction::kTrustedVaultKeyRequired:
426 case RequiredUserAction::kTrustedVaultKeyRequiredButFetching:
427 case RequiredUserAction::kPassphraseRequired:
428 return true;
429 }
430
431 NOTREACHED();
432 return false;
433 }
434
OnPassphraseRequired(const KeyDerivationParams & key_derivation_params,const sync_pb::EncryptedData & pending_keys)435 void SyncServiceCrypto::OnPassphraseRequired(
436 const KeyDerivationParams& key_derivation_params,
437 const sync_pb::EncryptedData& pending_keys) {
438 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
439
440 // Update our cache of the cryptographer's pending keys.
441 state_.cached_pending_keys = pending_keys;
442
443 // Update the key derivation params to be used.
444 state_.passphrase_key_derivation_params = key_derivation_params;
445
446 DVLOG(1) << "Passphrase required.";
447
448 UpdateRequiredUserActionAndNotify(RequiredUserAction::kPassphraseRequired);
449
450 // Reconfigure without the encrypted types (excluded implicitly via the
451 // failed datatypes handler).
452 reconfigure_.Run(CONFIGURE_REASON_CRYPTO);
453 }
454
OnPassphraseAccepted()455 void SyncServiceCrypto::OnPassphraseAccepted() {
456 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
457
458 // Clear our cache of the cryptographer's pending keys.
459 state_.cached_pending_keys.clear_blob();
460
461 // Reset |required_user_action| since we know we no longer require the
462 // passphrase.
463 UpdateRequiredUserActionAndNotify(RequiredUserAction::kNone);
464
465 // Make sure the data types that depend on the passphrase are started at
466 // this time.
467 reconfigure_.Run(CONFIGURE_REASON_CRYPTO);
468 }
469
OnTrustedVaultKeyRequired()470 void SyncServiceCrypto::OnTrustedVaultKeyRequired() {
471 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
472
473 // To be on the safe since, if a passphrase is required, we avoid overriding
474 // |state_.required_user_action|.
475 if (state_.required_user_action != RequiredUserAction::kNone &&
476 state_.required_user_action !=
477 RequiredUserAction::kUnknownDuringInitialization) {
478 return;
479 }
480
481 UpdateRequiredUserActionAndNotify(
482 RequiredUserAction::kFetchingTrustedVaultKeys);
483
484 if (!state_.engine) {
485 // If SetSyncEngine() hasn't been called yet, it means
486 // OnTrustedVaultKeyRequired() was called as part of the engine's
487 // initialization. Fetching the keys is not useful right now because there
488 // is known engine to feed the keys to, so let's defer fetching until
489 // SetSyncEngine() is called.
490 return;
491 }
492
493 FetchTrustedVaultKeys(/*is_second_fetch_attempt=*/false);
494 }
495
OnTrustedVaultKeyAccepted()496 void SyncServiceCrypto::OnTrustedVaultKeyAccepted() {
497 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
498
499 switch (state_.required_user_action) {
500 case RequiredUserAction::kUnknownDuringInitialization:
501 case RequiredUserAction::kNone:
502 case RequiredUserAction::kPassphraseRequired:
503 case RequiredUserAction::kTrustedVaultRecoverabilityDegraded:
504 return;
505 case RequiredUserAction::kFetchingTrustedVaultKeys:
506 case RequiredUserAction::kTrustedVaultKeyRequired:
507 case RequiredUserAction::kTrustedVaultKeyRequiredButFetching:
508 break;
509 }
510
511 UpdateRequiredUserActionAndNotify(RequiredUserAction::kNone);
512
513 // Make sure the data types that depend on the decryption key are started at
514 // this time.
515 reconfigure_.Run(CONFIGURE_REASON_CRYPTO);
516 }
517
OnBootstrapTokenUpdated(const std::string & bootstrap_token,BootstrapTokenType type)518 void SyncServiceCrypto::OnBootstrapTokenUpdated(
519 const std::string& bootstrap_token,
520 BootstrapTokenType type) {
521 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
522 DCHECK(sync_prefs_);
523 if (type == PASSPHRASE_BOOTSTRAP_TOKEN) {
524 sync_prefs_->SetEncryptionBootstrapToken(bootstrap_token);
525 } else {
526 sync_prefs_->SetKeystoreEncryptionBootstrapToken(bootstrap_token);
527 }
528 }
529
OnEncryptedTypesChanged(ModelTypeSet encrypted_types,bool encrypt_everything)530 void SyncServiceCrypto::OnEncryptedTypesChanged(ModelTypeSet encrypted_types,
531 bool encrypt_everything) {
532 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
533 state_.encrypted_types = encrypted_types;
534 state_.encrypt_everything = encrypt_everything;
535 DVLOG(1) << "Encrypted types changed to "
536 << ModelTypeSetToString(state_.encrypted_types)
537 << " (encrypt everything is set to "
538 << (state_.encrypt_everything ? "true" : "false") << ")";
539 DCHECK(state_.encrypted_types.Has(PASSWORDS));
540 DCHECK(state_.encrypted_types.Has(WIFI_CONFIGURATIONS));
541
542 notify_observers_.Run();
543 }
544
OnCryptographerStateChanged(Cryptographer * cryptographer,bool has_pending_keys)545 void SyncServiceCrypto::OnCryptographerStateChanged(
546 Cryptographer* cryptographer,
547 bool has_pending_keys) {
548 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
549 // Do nothing.
550 }
551
OnPassphraseTypeChanged(PassphraseType type,base::Time passphrase_time)552 void SyncServiceCrypto::OnPassphraseTypeChanged(PassphraseType type,
553 base::Time passphrase_time) {
554 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
555
556 DVLOG(1) << "Passphrase type changed to " << PassphraseTypeToString(type);
557
558 state_.cached_passphrase_type = type;
559 state_.cached_explicit_passphrase_time = passphrase_time;
560
561 // Clear recoverability degraded state in case a custom passphrase was set.
562 if (type != PassphraseType::kTrustedVaultPassphrase &&
563 state_.required_user_action ==
564 RequiredUserAction::kTrustedVaultRecoverabilityDegraded) {
565 UpdateRequiredUserActionAndNotify(RequiredUserAction::kNone);
566 }
567
568 notify_observers_.Run();
569 }
570
OnTrustedVaultKeysChanged()571 void SyncServiceCrypto::OnTrustedVaultKeysChanged() {
572 switch (state_.required_user_action) {
573 case RequiredUserAction::kUnknownDuringInitialization:
574 case RequiredUserAction::kNone:
575 case RequiredUserAction::kPassphraseRequired:
576 case RequiredUserAction::kTrustedVaultRecoverabilityDegraded:
577 // If no trusted vault keys are required, there's nothing to do. If they
578 // later are required, a fetch will be triggered in
579 // OnTrustedVaultKeyRequired().
580 return;
581 case RequiredUserAction::kFetchingTrustedVaultKeys:
582 case RequiredUserAction::kTrustedVaultKeyRequiredButFetching:
583 // If there's an ongoing fetch, FetchKeys() cannot be issued immediately
584 // since that violates the function precondition. However, the in-flight
585 // FetchKeys() may end up returning stale keys, so let's make sure
586 // FetchKeys() is invoked again once it becomes possible.
587 state_.deferred_trusted_vault_fetch_keys_pending = true;
588 return;
589 case RequiredUserAction::kTrustedVaultKeyRequired:
590 UpdateRequiredUserActionAndNotify(
591 RequiredUserAction::kTrustedVaultKeyRequiredButFetching);
592 break;
593 }
594
595 FetchTrustedVaultKeys(/*is_second_fetch_attempt=*/false);
596 }
597
OnTrustedVaultRecoverabilityChanged()598 void SyncServiceCrypto::OnTrustedVaultRecoverabilityChanged() {
599 RefreshIsRecoverabilityDegraded();
600 }
601
FetchTrustedVaultKeys(bool is_second_fetch_attempt)602 void SyncServiceCrypto::FetchTrustedVaultKeys(bool is_second_fetch_attempt) {
603 DCHECK(state_.engine);
604 DCHECK(state_.required_user_action ==
605 RequiredUserAction::kFetchingTrustedVaultKeys ||
606 state_.required_user_action ==
607 RequiredUserAction::kTrustedVaultKeyRequiredButFetching);
608
609 UMA_HISTOGRAM_ENUMERATION(
610 "Sync.TrustedVaultFetchKeysAttempt",
611 is_second_fetch_attempt
612 ? TrustedVaultFetchKeysAttemptForUMA::kSecondAttempt
613 : TrustedVaultFetchKeysAttemptForUMA::kFirstAttempt);
614
615 if (!is_second_fetch_attempt) {
616 state_.deferred_trusted_vault_fetch_keys_pending = false;
617 }
618
619 trusted_vault_client_->FetchKeys(
620 state_.account_info,
621 base::BindOnce(&SyncServiceCrypto::TrustedVaultKeysFetchedFromClient,
622 weak_factory_.GetWeakPtr(), is_second_fetch_attempt));
623 }
624
TrustedVaultKeysFetchedFromClient(bool is_second_fetch_attempt,const std::vector<std::vector<uint8_t>> & keys)625 void SyncServiceCrypto::TrustedVaultKeysFetchedFromClient(
626 bool is_second_fetch_attempt,
627 const std::vector<std::vector<uint8_t>>& keys) {
628 if (state_.required_user_action !=
629 RequiredUserAction::kFetchingTrustedVaultKeys &&
630 state_.required_user_action !=
631 RequiredUserAction::kTrustedVaultKeyRequiredButFetching) {
632 return;
633 }
634
635 DCHECK(state_.engine);
636
637 UMA_HISTOGRAM_COUNTS_100("Sync.TrustedVaultFetchedKeysCount", keys.size());
638
639 if (keys.empty()) {
640 // Nothing to do if no keys have been fetched from the client (e.g. user
641 // action is required for fetching additional keys). Let's avoid unnecessary
642 // steps like marking keys as stale.
643 FetchTrustedVaultKeysCompletedButInsufficient();
644 return;
645 }
646
647 state_.engine->AddTrustedVaultDecryptionKeys(
648 keys,
649 base::BindOnce(&SyncServiceCrypto::TrustedVaultKeysAdded,
650 weak_factory_.GetWeakPtr(), is_second_fetch_attempt));
651 }
652
TrustedVaultKeysAdded(bool is_second_fetch_attempt)653 void SyncServiceCrypto::TrustedVaultKeysAdded(bool is_second_fetch_attempt) {
654 // Having kFetchingTrustedVaultKeys or kTrustedVaultKeyRequiredButFetching
655 // indicates OnTrustedVaultKeyAccepted() was not triggered, so the fetched
656 // trusted vault keys were insufficient.
657 bool success = state_.required_user_action !=
658 RequiredUserAction::kFetchingTrustedVaultKeys &&
659 state_.required_user_action !=
660 RequiredUserAction::kTrustedVaultKeyRequiredButFetching;
661
662 UMA_HISTOGRAM_BOOLEAN("Sync.TrustedVaultAddKeysAttemptIsSuccessful", success);
663
664 if (success) {
665 return;
666 }
667
668 // Let trusted vault client know, that fetched keys were insufficient.
669 trusted_vault_client_->MarkKeysAsStale(
670 state_.account_info,
671 base::BindOnce(&SyncServiceCrypto::TrustedVaultKeysMarkedAsStale,
672 weak_factory_.GetWeakPtr(), is_second_fetch_attempt));
673 }
674
TrustedVaultKeysMarkedAsStale(bool is_second_fetch_attempt,bool result)675 void SyncServiceCrypto::TrustedVaultKeysMarkedAsStale(
676 bool is_second_fetch_attempt,
677 bool result) {
678 if (state_.required_user_action !=
679 RequiredUserAction::kFetchingTrustedVaultKeys &&
680 state_.required_user_action !=
681 RequiredUserAction::kTrustedVaultKeyRequiredButFetching) {
682 return;
683 }
684
685 // If nothing has changed (determined by |!result| since false negatives are
686 // disallowed by the API) or this is already a second attempt, the fetching
687 // procedure can be considered completed.
688 if (!result || is_second_fetch_attempt) {
689 FetchTrustedVaultKeysCompletedButInsufficient();
690 return;
691 }
692
693 FetchTrustedVaultKeys(/*is_second_fetch_attempt=*/true);
694 }
695
FetchTrustedVaultKeysCompletedButInsufficient()696 void SyncServiceCrypto::FetchTrustedVaultKeysCompletedButInsufficient() {
697 DCHECK(state_.required_user_action ==
698 RequiredUserAction::kFetchingTrustedVaultKeys ||
699 state_.required_user_action ==
700 RequiredUserAction::kTrustedVaultKeyRequiredButFetching);
701
702 // If FetchKeys() was intended to be called during an already existing ongoing
703 // FetchKeys(), it needs to be invoked now that it's possible.
704 if (state_.deferred_trusted_vault_fetch_keys_pending) {
705 FetchTrustedVaultKeys(/*is_second_fetch_attempt=*/false);
706 return;
707 }
708
709 // Reaching this codepath indicates OnTrustedVaultKeyAccepted() was not
710 // triggered, so the fetched trusted vault keys were insufficient.
711 UpdateRequiredUserActionAndNotify(
712 RequiredUserAction::kTrustedVaultKeyRequired);
713
714 // Reconfigure without the encrypted types (excluded implicitly via the failed
715 // datatypes handler).
716 reconfigure_.Run(CONFIGURE_REASON_CRYPTO);
717 }
718
UpdateRequiredUserActionAndNotify(RequiredUserAction new_required_user_action)719 void SyncServiceCrypto::UpdateRequiredUserActionAndNotify(
720 RequiredUserAction new_required_user_action) {
721 DCHECK_NE(new_required_user_action,
722 RequiredUserAction::kUnknownDuringInitialization);
723
724 if (state_.required_user_action == new_required_user_action) {
725 return;
726 }
727
728 state_.required_user_action = new_required_user_action;
729 notify_required_user_action_changed_.Run();
730
731 RefreshIsRecoverabilityDegraded();
732 }
733
RefreshIsRecoverabilityDegraded()734 void SyncServiceCrypto::RefreshIsRecoverabilityDegraded() {
735 switch (state_.required_user_action) {
736 case RequiredUserAction::kUnknownDuringInitialization:
737 case RequiredUserAction::kFetchingTrustedVaultKeys:
738 case RequiredUserAction::kTrustedVaultKeyRequired:
739 case RequiredUserAction::kTrustedVaultKeyRequiredButFetching:
740 case RequiredUserAction::kPassphraseRequired:
741 return;
742 case RequiredUserAction::kNone:
743 case RequiredUserAction::kTrustedVaultRecoverabilityDegraded:
744 break;
745 }
746
747 if (!base::FeatureList::IsEnabled(
748 switches::kSyncSupportTrustedVaultPassphraseRecovery)) {
749 return;
750 }
751
752 trusted_vault_client_->GetIsRecoverabilityDegraded(
753 state_.account_info,
754 base::BindOnce(&SyncServiceCrypto::GetIsRecoverabilityDegradedCompleted,
755 weak_factory_.GetWeakPtr()));
756 }
757
GetIsRecoverabilityDegradedCompleted(bool is_recoverability_degraded)758 void SyncServiceCrypto::GetIsRecoverabilityDegradedCompleted(
759 bool is_recoverability_degraded) {
760 // The passphrase type could have changed.
761 if (state_.cached_passphrase_type !=
762 PassphraseType::kTrustedVaultPassphrase) {
763 DCHECK_NE(state_.required_user_action,
764 RequiredUserAction::kTrustedVaultRecoverabilityDegraded);
765 return;
766 }
767
768 // Transition from non-degraded to degraded recoverability.
769 if (is_recoverability_degraded &&
770 state_.required_user_action == RequiredUserAction::kNone) {
771 UpdateRequiredUserActionAndNotify(
772 RequiredUserAction::kTrustedVaultRecoverabilityDegraded);
773 notify_observers_.Run();
774 }
775
776 // Transition from degraded to non-degraded recoverability.
777 if (!is_recoverability_degraded &&
778 state_.required_user_action ==
779 RequiredUserAction::kTrustedVaultRecoverabilityDegraded) {
780 UpdateRequiredUserActionAndNotify(RequiredUserAction::kNone);
781 notify_observers_.Run();
782 }
783 }
784
785 } // namespace syncer
786