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