sync_service_crypto_unittest.cc 56 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371
  1. // Copyright 2019 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. #include "components/sync/driver/sync_service_crypto.h"
  5. #include <list>
  6. #include <map>
  7. #include <utility>
  8. #include "base/base64.h"
  9. #include "base/callback_helpers.h"
  10. #include "base/containers/contains.h"
  11. #include "base/memory/raw_ptr.h"
  12. #include "base/observer_list.h"
  13. #include "base/run_loop.h"
  14. #include "base/test/metrics/histogram_tester.h"
  15. #include "base/test/mock_callback.h"
  16. #include "base/test/scoped_feature_list.h"
  17. #include "components/os_crypt/os_crypt.h"
  18. #include "components/os_crypt/os_crypt_mocker.h"
  19. #include "components/signin/public/identity_manager/account_info.h"
  20. #include "components/sync/base/features.h"
  21. #include "components/sync/base/sync_prefs.h"
  22. #include "components/sync/driver/trusted_vault_client.h"
  23. #include "components/sync/engine/nigori/key_derivation_params.h"
  24. #include "components/sync/engine/nigori/nigori.h"
  25. #include "components/sync/test/mock_sync_engine.h"
  26. #include "testing/gmock/include/gmock/gmock.h"
  27. #include "testing/gtest/include/gtest/gtest.h"
  28. #include "third_party/abseil-cpp/absl/types/optional.h"
  29. namespace syncer {
  30. namespace {
  31. using testing::_;
  32. using testing::Eq;
  33. using testing::IsEmpty;
  34. using testing::IsNull;
  35. using testing::Ne;
  36. using testing::Not;
  37. using testing::NotNull;
  38. using testing::Return;
  39. using testing::SaveArg;
  40. sync_pb::EncryptedData MakeEncryptedData(
  41. const std::string& passphrase,
  42. const KeyDerivationParams& derivation_params) {
  43. std::unique_ptr<Nigori> nigori =
  44. Nigori::CreateByDerivation(derivation_params, passphrase);
  45. std::string nigori_name;
  46. EXPECT_TRUE(
  47. nigori->Permute(Nigori::Type::Password, kNigoriKeyName, &nigori_name));
  48. const std::string unencrypted = "test";
  49. sync_pb::EncryptedData encrypted;
  50. encrypted.set_key_name(nigori_name);
  51. EXPECT_TRUE(nigori->Encrypt(unencrypted, encrypted.mutable_blob()));
  52. return encrypted;
  53. }
  54. CoreAccountInfo MakeAccountInfoWithGaia(const std::string& gaia) {
  55. CoreAccountInfo result;
  56. result.gaia = gaia;
  57. return result;
  58. }
  59. std::string CreateBootstrapToken(const std::string& passphrase,
  60. const KeyDerivationParams& derivation_params) {
  61. std::unique_ptr<Nigori> nigori =
  62. Nigori::CreateByDerivation(derivation_params, passphrase);
  63. sync_pb::NigoriKey proto;
  64. nigori->ExportKeys(proto.mutable_deprecated_user_key(),
  65. proto.mutable_encryption_key(), proto.mutable_mac_key());
  66. const std::string serialized_key = proto.SerializeAsString();
  67. EXPECT_FALSE(serialized_key.empty());
  68. std::string encrypted_key;
  69. EXPECT_TRUE(OSCrypt::EncryptString(serialized_key, &encrypted_key));
  70. std::string encoded_key;
  71. base::Base64Encode(encrypted_key, &encoded_key);
  72. return encoded_key;
  73. }
  74. MATCHER(IsScryptKeyDerivationParams, "") {
  75. const KeyDerivationParams& params = arg;
  76. return params.method() == KeyDerivationMethod::SCRYPT_8192_8_11 &&
  77. !params.scrypt_salt().empty();
  78. }
  79. MATCHER_P2(BootstrapTokenDerivedFrom,
  80. expected_passphrase,
  81. expected_derivation_params,
  82. "") {
  83. const std::string& given_bootstrap_token = arg;
  84. std::string decoded_key;
  85. if (!base::Base64Decode(given_bootstrap_token, &decoded_key)) {
  86. return false;
  87. }
  88. std::string decrypted_key;
  89. if (!OSCrypt::DecryptString(decoded_key, &decrypted_key)) {
  90. return false;
  91. }
  92. sync_pb::NigoriKey given_key;
  93. if (!given_key.ParseFromString(decrypted_key)) {
  94. return false;
  95. }
  96. std::unique_ptr<Nigori> expected_nigori = Nigori::CreateByDerivation(
  97. expected_derivation_params, expected_passphrase);
  98. sync_pb::NigoriKey expected_key;
  99. expected_nigori->ExportKeys(expected_key.mutable_deprecated_user_key(),
  100. expected_key.mutable_encryption_key(),
  101. expected_key.mutable_mac_key());
  102. return given_key.encryption_key() == expected_key.encryption_key() &&
  103. given_key.mac_key() == expected_key.mac_key();
  104. }
  105. class MockDelegate : public SyncServiceCrypto::Delegate {
  106. public:
  107. MockDelegate() = default;
  108. ~MockDelegate() override = default;
  109. MOCK_METHOD(void, CryptoStateChanged, (), (override));
  110. MOCK_METHOD(void, CryptoRequiredUserActionChanged, (), (override));
  111. MOCK_METHOD(void, ReconfigureDataTypesDueToCrypto, (), (override));
  112. MOCK_METHOD(void,
  113. SetEncryptionBootstrapToken,
  114. (const std::string&),
  115. (override));
  116. MOCK_METHOD(std::string, GetEncryptionBootstrapToken, (), (override));
  117. };
  118. // Object representing a server that contains the authoritative trusted vault
  119. // keys, and TestTrustedVaultClient reads from.
  120. class TestTrustedVaultServer {
  121. public:
  122. TestTrustedVaultServer() = default;
  123. ~TestTrustedVaultServer() = default;
  124. void StoreKeysOnServer(const std::string& gaia_id,
  125. const std::vector<std::vector<uint8_t>>& keys) {
  126. gaia_id_to_keys_[gaia_id] = keys;
  127. }
  128. // Mimics a user going through a key-retrieval flow (e.g. reauth) such that
  129. // keys are fetched from the server and cached in |client|.
  130. void MimicKeyRetrievalByUser(const std::string& gaia_id,
  131. TrustedVaultClient* client) {
  132. DCHECK(client);
  133. DCHECK_NE(0U, gaia_id_to_keys_.count(gaia_id))
  134. << "StoreKeysOnServer() should have been called for " << gaia_id;
  135. client->StoreKeys(gaia_id, gaia_id_to_keys_[gaia_id],
  136. /*last_key_version=*/
  137. static_cast<int>(gaia_id_to_keys_[gaia_id].size()) - 1);
  138. }
  139. // Mimics the server RPC endpoint that allows key rotation.
  140. std::vector<std::vector<uint8_t>> RequestRotatedKeysFromServer(
  141. const std::string& gaia_id,
  142. const std::vector<uint8_t>& key_known_by_client) const {
  143. auto it = gaia_id_to_keys_.find(gaia_id);
  144. if (it == gaia_id_to_keys_.end()) {
  145. return {};
  146. }
  147. const std::vector<std::vector<uint8_t>>& latest_keys = it->second;
  148. if (!base::Contains(latest_keys, key_known_by_client)) {
  149. // |key_known_by_client| is invalid or too old: cannot be used to follow
  150. // key rotation.
  151. return {};
  152. }
  153. return latest_keys;
  154. }
  155. private:
  156. std::map<std::string, std::vector<std::vector<uint8_t>>> gaia_id_to_keys_;
  157. };
  158. // Simple in-memory implementation of TrustedVaultClient.
  159. class TestTrustedVaultClient : public TrustedVaultClient {
  160. public:
  161. explicit TestTrustedVaultClient(const TestTrustedVaultServer* server)
  162. : server_(server) {}
  163. ~TestTrustedVaultClient() override = default;
  164. // Exposes the total number of calls to FetchKeys().
  165. int fetch_count() const { return fetch_count_; }
  166. // Exposes the total number of calls to MarkLocalKeysAsStale().
  167. bool keys_marked_as_stale_count() const {
  168. return keys_marked_as_stale_count_;
  169. }
  170. // Exposes the total number of calls to the server's RequestKeysFromServer().
  171. int server_request_count() const { return server_request_count_; }
  172. // Exposes the total number of calls to GetIsRecoverabilityDegraded().
  173. int get_is_recoverablity_degraded_call_count() const {
  174. return get_is_recoverablity_degraded_call_count_;
  175. }
  176. // Mimics the completion of the next (FIFO) FetchKeys() request.
  177. bool CompleteFetchKeysRequest() {
  178. if (pending_responses_.empty()) {
  179. return false;
  180. }
  181. base::OnceClosure cb = std::move(pending_responses_.front());
  182. pending_responses_.pop_front();
  183. std::move(cb).Run();
  184. return true;
  185. }
  186. void SetIsRecoverabilityDegraded(bool is_recoverability_degraded) {
  187. is_recoverability_degraded_ = is_recoverability_degraded;
  188. for (Observer& observer : observer_list_) {
  189. observer.OnTrustedVaultRecoverabilityChanged();
  190. }
  191. }
  192. // TrustedVaultClient implementation.
  193. void AddObserver(Observer* observer) override {
  194. observer_list_.AddObserver(observer);
  195. }
  196. void RemoveObserver(Observer* observer) override {
  197. observer_list_.RemoveObserver(observer);
  198. }
  199. void FetchKeys(
  200. const CoreAccountInfo& account_info,
  201. base::OnceCallback<void(const std::vector<std::vector<uint8_t>>&)> cb)
  202. override {
  203. const std::string& gaia_id = account_info.gaia;
  204. ++fetch_count_;
  205. CachedKeysPerUser& cached_keys = gaia_id_to_cached_keys_[gaia_id];
  206. // If there are no keys cached, the only way to bootstrap the client is by
  207. // going through a retrieval flow, see MimicKeyRetrievalByUser().
  208. if (cached_keys.keys.empty()) {
  209. pending_responses_.push_back(
  210. base::BindOnce(std::move(cb), std::vector<std::vector<uint8_t>>()));
  211. return;
  212. }
  213. // If the locally cached keys are not marked as stale, return them directly.
  214. if (!cached_keys.marked_as_stale) {
  215. pending_responses_.push_back(
  216. base::BindOnce(std::move(cb), cached_keys.keys));
  217. return;
  218. }
  219. // Fetch keys from the server and cache them.
  220. cached_keys.keys =
  221. server_->RequestRotatedKeysFromServer(gaia_id, cached_keys.keys.back());
  222. cached_keys.marked_as_stale = false;
  223. // Return the newly-cached keys.
  224. pending_responses_.push_back(
  225. base::BindOnce(std::move(cb), cached_keys.keys));
  226. }
  227. // Store keys in the client-side cache, usually retrieved from the server as
  228. // part of the key retrieval process, see MimicKeyRetrievalByUser().
  229. void StoreKeys(const std::string& gaia_id,
  230. const std::vector<std::vector<uint8_t>>& keys,
  231. int last_key_version) override {
  232. CachedKeysPerUser& cached_keys = gaia_id_to_cached_keys_[gaia_id];
  233. cached_keys.keys = keys;
  234. cached_keys.marked_as_stale = false;
  235. for (Observer& observer : observer_list_) {
  236. observer.OnTrustedVaultKeysChanged();
  237. }
  238. }
  239. void MarkLocalKeysAsStale(const CoreAccountInfo& account_info,
  240. base::OnceCallback<void(bool)> cb) override {
  241. const std::string& gaia_id = account_info.gaia;
  242. ++keys_marked_as_stale_count_;
  243. CachedKeysPerUser& cached_keys = gaia_id_to_cached_keys_[gaia_id];
  244. if (cached_keys.keys.empty() || cached_keys.marked_as_stale) {
  245. // Nothing changed so report |false|.
  246. std::move(cb).Run(false);
  247. return;
  248. }
  249. // The cache is stale and should be invalidated. Following calls to
  250. // FetchKeys() will read from the server.
  251. cached_keys.marked_as_stale = true;
  252. std::move(cb).Run(true);
  253. }
  254. void GetIsRecoverabilityDegraded(const CoreAccountInfo& account_info,
  255. base::OnceCallback<void(bool)> cb) override {
  256. ++get_is_recoverablity_degraded_call_count_;
  257. std::move(cb).Run(is_recoverability_degraded_);
  258. }
  259. void AddTrustedRecoveryMethod(const std::string& gaia_id,
  260. const std::vector<uint8_t>& public_key,
  261. int method_type_hint,
  262. base::OnceClosure cb) override {
  263. // Not relevant in these tests.
  264. std::move(cb).Run();
  265. }
  266. void ClearDataForAccount(const CoreAccountInfo& account_info) override {
  267. // Not relevant in these tests.
  268. }
  269. private:
  270. struct CachedKeysPerUser {
  271. bool marked_as_stale = false;
  272. std::vector<std::vector<uint8_t>> keys;
  273. };
  274. const raw_ptr<const TestTrustedVaultServer> server_;
  275. std::map<std::string, CachedKeysPerUser> gaia_id_to_cached_keys_;
  276. base::ObserverList<Observer> observer_list_;
  277. int fetch_count_ = 0;
  278. int keys_marked_as_stale_count_ = 0;
  279. int get_is_recoverablity_degraded_call_count_ = 0;
  280. int server_request_count_ = 0;
  281. std::list<base::OnceClosure> pending_responses_;
  282. bool is_recoverability_degraded_ = false;
  283. };
  284. class SyncServiceCryptoTest : public testing::Test {
  285. protected:
  286. // Account used in most tests.
  287. const CoreAccountInfo kSyncingAccount =
  288. MakeAccountInfoWithGaia("syncingaccount");
  289. // Initial trusted vault keys stored on the server |TestTrustedVaultServer|
  290. // for |kSyncingAccount|.
  291. const std::vector<std::vector<uint8_t>> kInitialTrustedVaultKeys = {
  292. {0, 1, 2, 3, 4}};
  293. SyncServiceCryptoTest()
  294. : trusted_vault_client_(&trusted_vault_server_),
  295. crypto_(&delegate_, &trusted_vault_client_) {
  296. trusted_vault_server_.StoreKeysOnServer(kSyncingAccount.gaia,
  297. kInitialTrustedVaultKeys);
  298. }
  299. ~SyncServiceCryptoTest() override = default;
  300. void SetUp() override { OSCryptMocker::SetUp(); }
  301. void TearDown() override { OSCryptMocker::TearDown(); }
  302. bool VerifyAndClearExpectations() {
  303. return testing::Mock::VerifyAndClearExpectations(&delegate_) &&
  304. testing::Mock::VerifyAndClearExpectations(&trusted_vault_client_) &&
  305. testing::Mock::VerifyAndClearExpectations(&engine_);
  306. }
  307. void MimicKeyRetrievalByUser() {
  308. trusted_vault_server_.MimicKeyRetrievalByUser(kSyncingAccount.gaia,
  309. &trusted_vault_client_);
  310. }
  311. testing::NiceMock<MockDelegate> delegate_;
  312. TestTrustedVaultServer trusted_vault_server_;
  313. TestTrustedVaultClient trusted_vault_client_;
  314. testing::NiceMock<MockSyncEngine> engine_;
  315. SyncServiceCrypto crypto_;
  316. };
  317. // Happy case where no user action is required upon startup.
  318. TEST_F(SyncServiceCryptoTest, ShouldRequireNoUserAction) {
  319. crypto_.SetSyncEngine(CoreAccountInfo(), &engine_);
  320. EXPECT_FALSE(crypto_.IsPassphraseRequired());
  321. EXPECT_FALSE(crypto_.IsTrustedVaultKeyRequired());
  322. EXPECT_TRUE(crypto_.IsTrustedVaultKeyRequiredStateKnown());
  323. EXPECT_FALSE(crypto_.IsTrustedVaultRecoverabilityDegraded());
  324. }
  325. TEST_F(SyncServiceCryptoTest, ShouldSetUpNewCustomPassphrase) {
  326. const std::string kTestPassphrase = "somepassphrase";
  327. crypto_.SetSyncEngine(CoreAccountInfo(), &engine_);
  328. ASSERT_FALSE(crypto_.IsPassphraseRequired());
  329. ASSERT_FALSE(crypto_.IsUsingExplicitPassphrase());
  330. ASSERT_FALSE(crypto_.IsEncryptEverythingEnabled());
  331. ASSERT_THAT(crypto_.GetPassphraseType(),
  332. Ne(PassphraseType::kCustomPassphrase));
  333. EXPECT_CALL(delegate_, SetEncryptionBootstrapToken(Not(IsEmpty())));
  334. EXPECT_CALL(engine_, SetEncryptionPassphrase(kTestPassphrase,
  335. IsScryptKeyDerivationParams()));
  336. crypto_.SetEncryptionPassphrase(kTestPassphrase);
  337. // Mimic completion of the procedure in the sync engine.
  338. EXPECT_CALL(delegate_, CryptoStateChanged());
  339. crypto_.OnPassphraseTypeChanged(PassphraseType::kCustomPassphrase,
  340. base::Time::Now());
  341. // The current implementation notifies observers again upon
  342. // crypto_.OnEncryptedTypesChanged(). This may change in the future.
  343. EXPECT_CALL(delegate_, CryptoStateChanged());
  344. crypto_.OnEncryptedTypesChanged(syncer::EncryptableUserTypes(),
  345. /*encrypt_everything=*/true);
  346. EXPECT_CALL(delegate_, ReconfigureDataTypesDueToCrypto());
  347. crypto_.OnPassphraseAccepted();
  348. EXPECT_FALSE(crypto_.IsPassphraseRequired());
  349. EXPECT_TRUE(crypto_.IsEncryptEverythingEnabled());
  350. ASSERT_THAT(crypto_.GetPassphraseType(),
  351. Eq(PassphraseType::kCustomPassphrase));
  352. EXPECT_TRUE(crypto_.IsUsingExplicitPassphrase());
  353. }
  354. TEST_F(SyncServiceCryptoTest, ShouldExposePassphraseRequired) {
  355. const std::string kTestPassphrase = "somepassphrase";
  356. crypto_.SetSyncEngine(CoreAccountInfo(), &engine_);
  357. ASSERT_FALSE(crypto_.IsPassphraseRequired());
  358. ASSERT_THAT(trusted_vault_client_.fetch_count(), Eq(0));
  359. // Mimic the engine determining that a passphrase is required.
  360. EXPECT_CALL(delegate_, ReconfigureDataTypesDueToCrypto());
  361. crypto_.OnPassphraseRequired(
  362. KeyDerivationParams::CreateForPbkdf2(),
  363. MakeEncryptedData(kTestPassphrase,
  364. KeyDerivationParams::CreateForPbkdf2()));
  365. EXPECT_TRUE(crypto_.IsPassphraseRequired());
  366. VerifyAndClearExpectations();
  367. // Entering the wrong passphrase should be rejected.
  368. EXPECT_CALL(delegate_, ReconfigureDataTypesDueToCrypto()).Times(0);
  369. EXPECT_CALL(engine_, SetExplicitPassphraseDecryptionKey).Times(0);
  370. EXPECT_FALSE(crypto_.SetDecryptionPassphrase("wrongpassphrase"));
  371. EXPECT_TRUE(crypto_.IsPassphraseRequired());
  372. // Entering the correct passphrase should be accepted.
  373. EXPECT_CALL(engine_, SetExplicitPassphraseDecryptionKey(NotNull()))
  374. .WillOnce(
  375. [&](std::unique_ptr<Nigori>) { crypto_.OnPassphraseAccepted(); });
  376. // The current implementation issues two reconfigurations: one immediately
  377. // after checking the passphrase in the UI thread and a second time later when
  378. // the engine confirms with OnPassphraseAccepted().
  379. EXPECT_CALL(delegate_, ReconfigureDataTypesDueToCrypto()).Times(2);
  380. EXPECT_CALL(delegate_,
  381. SetEncryptionBootstrapToken(BootstrapTokenDerivedFrom(
  382. kTestPassphrase, KeyDerivationParams::CreateForPbkdf2())));
  383. EXPECT_TRUE(crypto_.SetDecryptionPassphrase(kTestPassphrase));
  384. EXPECT_FALSE(crypto_.IsPassphraseRequired());
  385. }
  386. // Regression test for crbug.com/1306831.
  387. TEST_F(SyncServiceCryptoTest,
  388. ShouldStoreBootstrapTokenBeforeReconfiguringDataTypes) {
  389. const std::string kTestPassphrase = "somepassphrase";
  390. crypto_.SetSyncEngine(CoreAccountInfo(), &engine_);
  391. ASSERT_FALSE(crypto_.IsPassphraseRequired());
  392. crypto_.OnPassphraseRequired(
  393. KeyDerivationParams::CreateForPbkdf2(),
  394. MakeEncryptedData(kTestPassphrase,
  395. KeyDerivationParams::CreateForPbkdf2()));
  396. ASSERT_TRUE(crypto_.IsPassphraseRequired());
  397. // Entering the correct passphrase should be accepted.
  398. EXPECT_CALL(engine_, SetExplicitPassphraseDecryptionKey(NotNull()))
  399. .WillOnce(
  400. [&](std::unique_ptr<Nigori>) { crypto_.OnPassphraseAccepted(); });
  401. // Order of SetEncryptionBootstrapToken() and
  402. // ReconfigureDataTypesDueToCrypto() (assuming passphrase is not required upon
  403. // reconfiguration) is important as clients rely on this to detect whether
  404. // GetDecryptionNigoriKey() can be called.
  405. testing::InSequence seq;
  406. EXPECT_CALL(delegate_,
  407. SetEncryptionBootstrapToken(BootstrapTokenDerivedFrom(
  408. kTestPassphrase, KeyDerivationParams::CreateForPbkdf2())));
  409. // The current implementation issues two reconfigurations: one immediately
  410. // after checking the passphrase in the UI thread and a second time later when
  411. // the engine confirms with OnPassphraseAccepted().
  412. EXPECT_CALL(delegate_, ReconfigureDataTypesDueToCrypto()).Times(2);
  413. ASSERT_TRUE(crypto_.SetDecryptionPassphrase(kTestPassphrase));
  414. }
  415. TEST_F(SyncServiceCryptoTest, ShouldSetupDecryptionWithBootstrapToken) {
  416. const std::string kTestPassphrase = "somepassphrase";
  417. crypto_.SetSyncEngine(CoreAccountInfo(), &engine_);
  418. ASSERT_FALSE(crypto_.IsPassphraseRequired());
  419. // Mimic passphrase stored in bootstrap token.
  420. ON_CALL(delegate_, GetEncryptionBootstrapToken())
  421. .WillByDefault(Return(CreateBootstrapToken(
  422. kTestPassphrase, KeyDerivationParams::CreateForPbkdf2())));
  423. // Expect setting decryption key without waiting till user enters the
  424. // passphrase.
  425. EXPECT_CALL(engine_, SetExplicitPassphraseDecryptionKey(NotNull()))
  426. .WillOnce(
  427. [&](std::unique_ptr<Nigori>) { crypto_.OnPassphraseAccepted(); });
  428. // Mimic the engine determining that a passphrase is required.
  429. crypto_.OnPassphraseRequired(
  430. KeyDerivationParams::CreateForPbkdf2(),
  431. MakeEncryptedData(kTestPassphrase,
  432. KeyDerivationParams::CreateForPbkdf2()));
  433. // The passphrase-required state should have been automatically resolved via
  434. // the bootstrap token.
  435. EXPECT_FALSE(crypto_.IsPassphraseRequired());
  436. }
  437. TEST_F(SyncServiceCryptoTest,
  438. ShouldSetupDecryptionWithBootstrapTokenUponEngineInitialization) {
  439. const std::string kTestPassphrase = "somepassphrase";
  440. ASSERT_FALSE(crypto_.IsPassphraseRequired());
  441. // Mimic passphrase stored in bootstrap token.
  442. ON_CALL(delegate_, GetEncryptionBootstrapToken())
  443. .WillByDefault(Return(CreateBootstrapToken(
  444. kTestPassphrase, KeyDerivationParams::CreateForPbkdf2())));
  445. // Mimic the engine determining that a passphrase is required. Note that
  446. // |crypto_| isn't yet aware of engine initialization - this is a legitimate
  447. // scenario.
  448. crypto_.OnPassphraseRequired(
  449. KeyDerivationParams::CreateForPbkdf2(),
  450. MakeEncryptedData(kTestPassphrase,
  451. KeyDerivationParams::CreateForPbkdf2()));
  452. EXPECT_TRUE(crypto_.IsPassphraseRequired());
  453. // Expect setting decryption key without waiting till user enters the
  454. // passphrase.
  455. EXPECT_CALL(engine_, SetExplicitPassphraseDecryptionKey(NotNull()))
  456. .WillOnce(
  457. [&](std::unique_ptr<Nigori>) { crypto_.OnPassphraseAccepted(); });
  458. // Mimic completion of engine initialization, now decryption key from
  459. // bootstrap token should be populated to the engine.
  460. crypto_.SetSyncEngine(CoreAccountInfo(), &engine_);
  461. EXPECT_FALSE(crypto_.IsPassphraseRequired());
  462. }
  463. TEST_F(SyncServiceCryptoTest, ShouldIgnoreNotMatchingBootstrapToken) {
  464. const std::string kTestPassphrase = "somepassphrase";
  465. crypto_.SetSyncEngine(CoreAccountInfo(), &engine_);
  466. ASSERT_FALSE(crypto_.IsPassphraseRequired());
  467. // Mimic wrong passphrase stored in bootstrap token.
  468. ON_CALL(delegate_, GetEncryptionBootstrapToken())
  469. .WillByDefault(Return(CreateBootstrapToken(
  470. "wrongpassphrase", KeyDerivationParams::CreateForPbkdf2())));
  471. // Mimic the engine determining that a passphrase is required.
  472. EXPECT_CALL(delegate_, ReconfigureDataTypesDueToCrypto());
  473. // There should be no attempt to populate wrong key to the |engine_|.
  474. EXPECT_CALL(engine_, SetExplicitPassphraseDecryptionKey).Times(0);
  475. crypto_.OnPassphraseRequired(
  476. KeyDerivationParams::CreateForPbkdf2(),
  477. MakeEncryptedData(kTestPassphrase,
  478. KeyDerivationParams::CreateForPbkdf2()));
  479. EXPECT_TRUE(crypto_.IsPassphraseRequired());
  480. VerifyAndClearExpectations();
  481. // Entering the correct passphrase should be accepted.
  482. EXPECT_CALL(engine_, SetExplicitPassphraseDecryptionKey(NotNull()))
  483. .WillOnce(
  484. [&](std::unique_ptr<Nigori>) { crypto_.OnPassphraseAccepted(); });
  485. // The current implementation issues two reconfigurations: one immediately
  486. // after checking the passphrase in the UI thread and a second time later when
  487. // the engine confirms with OnPassphraseAccepted().
  488. EXPECT_CALL(delegate_, ReconfigureDataTypesDueToCrypto()).Times(2);
  489. EXPECT_TRUE(crypto_.SetDecryptionPassphrase(kTestPassphrase));
  490. EXPECT_FALSE(crypto_.IsPassphraseRequired());
  491. }
  492. TEST_F(SyncServiceCryptoTest, ShouldIgnoreCorruptedBootstrapToken) {
  493. const std::string kTestPassphrase = "somepassphrase";
  494. crypto_.SetSyncEngine(CoreAccountInfo(), &engine_);
  495. ASSERT_FALSE(crypto_.IsPassphraseRequired());
  496. // Mimic storing corrupted bootstrap token.
  497. ON_CALL(delegate_, GetEncryptionBootstrapToken())
  498. .WillByDefault(Return("corrupted_token"));
  499. // Mimic the engine determining that a passphrase is required.
  500. EXPECT_CALL(delegate_, ReconfigureDataTypesDueToCrypto());
  501. // There should be no attempt to populate wrong key to the |engine_|.
  502. EXPECT_CALL(engine_, SetExplicitPassphraseDecryptionKey).Times(0);
  503. crypto_.OnPassphraseRequired(
  504. KeyDerivationParams::CreateForPbkdf2(),
  505. MakeEncryptedData(kTestPassphrase,
  506. KeyDerivationParams::CreateForPbkdf2()));
  507. EXPECT_TRUE(crypto_.IsPassphraseRequired());
  508. VerifyAndClearExpectations();
  509. // Entering the correct passphrase should be accepted.
  510. EXPECT_CALL(engine_, SetExplicitPassphraseDecryptionKey(NotNull()))
  511. .WillOnce(
  512. [&](std::unique_ptr<Nigori>) { crypto_.OnPassphraseAccepted(); });
  513. // The current implementation issues two reconfigurations: one immediately
  514. // after checking the passphrase in the UI thread and a second time later when
  515. // the engine confirms with OnPassphraseAccepted().
  516. EXPECT_CALL(delegate_, ReconfigureDataTypesDueToCrypto()).Times(2);
  517. EXPECT_TRUE(crypto_.SetDecryptionPassphrase(kTestPassphrase));
  518. EXPECT_FALSE(crypto_.IsPassphraseRequired());
  519. }
  520. TEST_F(SyncServiceCryptoTest, ShouldDecryptWithNigoriKey) {
  521. const std::string kTestPassphrase = "somepassphrase";
  522. crypto_.SetSyncEngine(CoreAccountInfo(), &engine_);
  523. ASSERT_FALSE(crypto_.IsPassphraseRequired());
  524. // Mimic the engine determining that a passphrase is required.
  525. EXPECT_CALL(delegate_, ReconfigureDataTypesDueToCrypto());
  526. crypto_.OnPassphraseRequired(
  527. KeyDerivationParams::CreateForPbkdf2(),
  528. MakeEncryptedData(kTestPassphrase,
  529. KeyDerivationParams::CreateForPbkdf2()));
  530. EXPECT_TRUE(crypto_.IsPassphraseRequired());
  531. VerifyAndClearExpectations();
  532. // Passing wrong decryption key should be ignored.
  533. EXPECT_CALL(delegate_, ReconfigureDataTypesDueToCrypto()).Times(0);
  534. EXPECT_CALL(engine_, SetExplicitPassphraseDecryptionKey).Times(0);
  535. crypto_.SetDecryptionNigoriKey(Nigori::CreateByDerivation(
  536. KeyDerivationParams::CreateForPbkdf2(), "wrongpassphrase"));
  537. EXPECT_TRUE(crypto_.IsPassphraseRequired());
  538. VerifyAndClearExpectations();
  539. // Passing correct decryption key should be accepted.
  540. EXPECT_CALL(engine_, SetExplicitPassphraseDecryptionKey(NotNull()))
  541. .WillOnce(
  542. [&](std::unique_ptr<Nigori>) { crypto_.OnPassphraseAccepted(); });
  543. // The current implementation issues two reconfigurations: one immediately
  544. // after checking the passphrase in the UI thread and a second time later when
  545. // the engine confirms with OnPassphraseAccepted().
  546. EXPECT_CALL(delegate_, ReconfigureDataTypesDueToCrypto()).Times(2);
  547. EXPECT_CALL(delegate_,
  548. SetEncryptionBootstrapToken(BootstrapTokenDerivedFrom(
  549. kTestPassphrase, KeyDerivationParams::CreateForPbkdf2())));
  550. crypto_.SetDecryptionNigoriKey(Nigori::CreateByDerivation(
  551. KeyDerivationParams::CreateForPbkdf2(), kTestPassphrase));
  552. EXPECT_FALSE(crypto_.IsPassphraseRequired());
  553. }
  554. TEST_F(SyncServiceCryptoTest,
  555. ShouldIgnoreDecryptionWithNigoriKeyWhenPassphraseNotRequired) {
  556. crypto_.SetSyncEngine(CoreAccountInfo(), &engine_);
  557. ASSERT_FALSE(crypto_.IsPassphraseRequired());
  558. EXPECT_CALL(delegate_, ReconfigureDataTypesDueToCrypto()).Times(0);
  559. EXPECT_CALL(engine_, SetExplicitPassphraseDecryptionKey).Times(0);
  560. EXPECT_CALL(delegate_, SetEncryptionBootstrapToken).Times(0);
  561. crypto_.SetDecryptionNigoriKey(Nigori::CreateByDerivation(
  562. KeyDerivationParams::CreateForPbkdf2(), "unexpected_passphrase"));
  563. EXPECT_FALSE(crypto_.IsPassphraseRequired());
  564. }
  565. // Regression test for crbug.com/1322687: engine initialization may happen after
  566. // SetDecryptionNigoriKey() call, verify it doesn't crash and that decryption
  567. // key populated to the engine later, upon initialization.
  568. TEST_F(SyncServiceCryptoTest,
  569. ShouldDeferDecryptionWithNigoriKeyUntilEngineInitialization) {
  570. const std::string kTestPassphrase = "somepassphrase";
  571. ASSERT_FALSE(crypto_.IsPassphraseRequired());
  572. // Mimic the engine determining that a passphrase is required.
  573. EXPECT_CALL(delegate_, ReconfigureDataTypesDueToCrypto());
  574. crypto_.OnPassphraseRequired(
  575. KeyDerivationParams::CreateForPbkdf2(),
  576. MakeEncryptedData(kTestPassphrase,
  577. KeyDerivationParams::CreateForPbkdf2()));
  578. ASSERT_TRUE(crypto_.IsPassphraseRequired());
  579. VerifyAndClearExpectations();
  580. // Pass decryption nigori key, it should be stored in the bootstrap token, but
  581. // shouldn't cause other changes, since engine isn't initialized.
  582. std::string bootstrap_token;
  583. ON_CALL(delegate_, SetEncryptionBootstrapToken(_))
  584. .WillByDefault(SaveArg<0>(&bootstrap_token));
  585. ON_CALL(delegate_, GetEncryptionBootstrapToken())
  586. .WillByDefault([&bootstrap_token]() { return bootstrap_token; });
  587. crypto_.SetDecryptionNigoriKey(Nigori::CreateByDerivation(
  588. KeyDerivationParams::CreateForPbkdf2(), kTestPassphrase));
  589. EXPECT_TRUE(crypto_.IsPassphraseRequired());
  590. // Decryption key should be passed to the engine once it's initialized.
  591. EXPECT_CALL(engine_, SetExplicitPassphraseDecryptionKey(NotNull()))
  592. .WillOnce(
  593. [&](std::unique_ptr<Nigori>) { crypto_.OnPassphraseAccepted(); });
  594. // The current implementation issues two reconfigurations: one immediately
  595. // after checking the passphrase in the UI thread and a second time later when
  596. // the engine confirms with OnPassphraseAccepted().
  597. EXPECT_CALL(delegate_, ReconfigureDataTypesDueToCrypto()).Times(2);
  598. crypto_.SetSyncEngine(kSyncingAccount, &engine_);
  599. EXPECT_FALSE(crypto_.IsPassphraseRequired());
  600. }
  601. TEST_F(SyncServiceCryptoTest, ShouldGetDecryptionKeyFromBootstrapToken) {
  602. const std::string kTestPassphrase = "somepassphrase";
  603. // Mimic passphrase being stored in bootstrap token.
  604. ON_CALL(delegate_, GetEncryptionBootstrapToken)
  605. .WillByDefault(Return(CreateBootstrapToken(
  606. kTestPassphrase, KeyDerivationParams::CreateForPbkdf2())));
  607. std::unique_ptr<Nigori> expected_nigori = Nigori::CreateByDerivation(
  608. KeyDerivationParams::CreateForPbkdf2(), kTestPassphrase);
  609. ASSERT_THAT(expected_nigori, NotNull());
  610. std::string deprecated_user_key;
  611. std::string expected_encryption_key;
  612. std::string expected_mac_key;
  613. expected_nigori->ExportKeys(&deprecated_user_key, &expected_encryption_key,
  614. &expected_mac_key);
  615. // Verify that GetDecryptionNigoriKey() result equals to |expected_nigori|.
  616. std::unique_ptr<Nigori> stored_nigori = crypto_.GetDecryptionNigoriKey();
  617. ASSERT_THAT(stored_nigori, NotNull());
  618. std::string stored_encryption_key;
  619. std::string stored_mac_key;
  620. stored_nigori->ExportKeys(&deprecated_user_key, &stored_encryption_key,
  621. &stored_mac_key);
  622. EXPECT_THAT(stored_encryption_key, Eq(expected_encryption_key));
  623. EXPECT_THAT(stored_mac_key, Eq(expected_mac_key));
  624. }
  625. TEST_F(SyncServiceCryptoTest,
  626. ShouldGetNullDecryptionKeyFromEmptyBootstrapToken) {
  627. // GetEncryptionBootstrapToken() returns empty string by default.
  628. EXPECT_THAT(crypto_.GetDecryptionNigoriKey(), IsNull());
  629. }
  630. TEST_F(SyncServiceCryptoTest,
  631. ShouldGetNullDecryptionKeyFromCorruptedBootstrapToken) {
  632. // Mimic corrupted bootstrap token being stored.
  633. ON_CALL(delegate_, GetEncryptionBootstrapToken)
  634. .WillByDefault(Return("corrupted_token"));
  635. EXPECT_THAT(crypto_.GetDecryptionNigoriKey(), IsNull());
  636. }
  637. TEST_F(SyncServiceCryptoTest,
  638. ShouldReadValidTrustedVaultKeysFromClientBeforeInitialization) {
  639. // Cache |kInitialTrustedVaultKeys| into |trusted_vault_client_| prior to
  640. // engine initialization.
  641. MimicKeyRetrievalByUser();
  642. EXPECT_CALL(delegate_, ReconfigureDataTypesDueToCrypto()).Times(0);
  643. ASSERT_FALSE(crypto_.IsTrustedVaultKeyRequired());
  644. // OnTrustedVaultKeyRequired() called during initialization of the sync
  645. // engine (i.e. before SetSyncEngine()).
  646. crypto_.OnTrustedVaultKeyRequired();
  647. // Trusted vault keys should be fetched only after the engine initialization
  648. // is completed.
  649. ASSERT_THAT(trusted_vault_client_.fetch_count(), Eq(0));
  650. crypto_.SetSyncEngine(kSyncingAccount, &engine_);
  651. // While there is an ongoing fetch, there should be no user action required.
  652. EXPECT_THAT(trusted_vault_client_.fetch_count(), Eq(1));
  653. EXPECT_FALSE(crypto_.IsTrustedVaultKeyRequired());
  654. base::OnceClosure add_keys_cb;
  655. EXPECT_CALL(engine_,
  656. AddTrustedVaultDecryptionKeys(kInitialTrustedVaultKeys, _))
  657. .WillOnce(
  658. [&](const std::vector<std::vector<uint8_t>>& keys,
  659. base::OnceClosure done_cb) { add_keys_cb = std::move(done_cb); });
  660. // Mimic completion of the fetch.
  661. ASSERT_TRUE(trusted_vault_client_.CompleteFetchKeysRequest());
  662. ASSERT_TRUE(add_keys_cb);
  663. EXPECT_FALSE(crypto_.IsTrustedVaultKeyRequired());
  664. // Mimic completion of the engine.
  665. EXPECT_CALL(delegate_, ReconfigureDataTypesDueToCrypto());
  666. crypto_.OnTrustedVaultKeyAccepted();
  667. std::move(add_keys_cb).Run();
  668. EXPECT_FALSE(crypto_.IsTrustedVaultKeyRequired());
  669. EXPECT_THAT(trusted_vault_client_.fetch_count(), Eq(1));
  670. EXPECT_THAT(trusted_vault_client_.keys_marked_as_stale_count(), Eq(0));
  671. EXPECT_THAT(trusted_vault_client_.server_request_count(), Eq(0));
  672. }
  673. TEST_F(SyncServiceCryptoTest,
  674. ShouldReadValidTrustedVaultKeysFromClientAfterInitialization) {
  675. // Cache |kInitialTrustedVaultKeys| into |trusted_vault_client_| prior to
  676. // engine initialization.
  677. MimicKeyRetrievalByUser();
  678. EXPECT_CALL(delegate_, ReconfigureDataTypesDueToCrypto()).Times(0);
  679. ASSERT_FALSE(crypto_.IsTrustedVaultKeyRequired());
  680. // Mimic the initialization of the sync engine, without trusted vault keys
  681. // being required.
  682. crypto_.SetSyncEngine(kSyncingAccount, &engine_);
  683. ASSERT_THAT(trusted_vault_client_.fetch_count(), Eq(0));
  684. // Later on, mimic trusted vault keys being required (e.g. remote Nigori
  685. // update), which should trigger a fetch.
  686. crypto_.OnTrustedVaultKeyRequired();
  687. EXPECT_THAT(trusted_vault_client_.fetch_count(), Eq(1));
  688. // While there is an ongoing fetch, there should be no user action required.
  689. EXPECT_FALSE(crypto_.IsTrustedVaultKeyRequired());
  690. base::OnceClosure add_keys_cb;
  691. EXPECT_CALL(engine_,
  692. AddTrustedVaultDecryptionKeys(kInitialTrustedVaultKeys, _))
  693. .WillOnce(
  694. [&](const std::vector<std::vector<uint8_t>>& keys,
  695. base::OnceClosure done_cb) { add_keys_cb = std::move(done_cb); });
  696. // Mimic completion of the fetch.
  697. ASSERT_TRUE(trusted_vault_client_.CompleteFetchKeysRequest());
  698. ASSERT_TRUE(add_keys_cb);
  699. EXPECT_FALSE(crypto_.IsTrustedVaultKeyRequired());
  700. // Mimic completion of the engine.
  701. EXPECT_CALL(delegate_, ReconfigureDataTypesDueToCrypto());
  702. crypto_.OnTrustedVaultKeyAccepted();
  703. std::move(add_keys_cb).Run();
  704. EXPECT_FALSE(crypto_.IsTrustedVaultKeyRequired());
  705. EXPECT_THAT(trusted_vault_client_.fetch_count(), Eq(1));
  706. EXPECT_THAT(trusted_vault_client_.keys_marked_as_stale_count(), Eq(0));
  707. EXPECT_THAT(trusted_vault_client_.server_request_count(), Eq(0));
  708. }
  709. TEST_F(SyncServiceCryptoTest,
  710. ShouldReadNoTrustedVaultKeysFromClientAfterInitialization) {
  711. EXPECT_CALL(delegate_, ReconfigureDataTypesDueToCrypto()).Times(0);
  712. EXPECT_CALL(engine_, AddTrustedVaultDecryptionKeys).Times(0);
  713. ASSERT_FALSE(crypto_.IsTrustedVaultKeyRequired());
  714. // Mimic the initialization of the sync engine, without trusted vault keys
  715. // being required.
  716. crypto_.SetSyncEngine(kSyncingAccount, &engine_);
  717. ASSERT_THAT(trusted_vault_client_.fetch_count(), Eq(0));
  718. ASSERT_THAT(trusted_vault_client_.server_request_count(), Eq(0));
  719. // Later on, mimic trusted vault keys being required (e.g. remote Nigori
  720. // update), which should trigger a fetch.
  721. crypto_.OnTrustedVaultKeyRequired();
  722. EXPECT_THAT(trusted_vault_client_.fetch_count(), Eq(1));
  723. // While there is an ongoing fetch, there should be no user action required.
  724. ASSERT_FALSE(crypto_.IsTrustedVaultKeyRequired());
  725. // Mimic completion of the fetch, which should lead to a reconfiguration.
  726. EXPECT_CALL(delegate_, ReconfigureDataTypesDueToCrypto());
  727. ASSERT_TRUE(trusted_vault_client_.CompleteFetchKeysRequest());
  728. EXPECT_TRUE(crypto_.IsTrustedVaultKeyRequired());
  729. EXPECT_THAT(trusted_vault_client_.fetch_count(), Eq(1));
  730. EXPECT_THAT(trusted_vault_client_.server_request_count(), Eq(0));
  731. EXPECT_THAT(trusted_vault_client_.keys_marked_as_stale_count(), Eq(0));
  732. }
  733. TEST_F(SyncServiceCryptoTest, ShouldReadInvalidTrustedVaultKeysFromClient) {
  734. // Cache |kInitialTrustedVaultKeys| into |trusted_vault_client_| prior to
  735. // engine initialization. In this test, |kInitialTrustedVaultKeys| does not
  736. // match the Nigori keys (i.e. the engine continues to think trusted vault
  737. // keys are required).
  738. MimicKeyRetrievalByUser();
  739. base::OnceClosure add_keys_cb;
  740. ON_CALL(engine_, AddTrustedVaultDecryptionKeys)
  741. .WillByDefault(
  742. [&](const std::vector<std::vector<uint8_t>>& keys,
  743. base::OnceClosure done_cb) { add_keys_cb = std::move(done_cb); });
  744. ASSERT_FALSE(crypto_.IsTrustedVaultKeyRequired());
  745. // Mimic the initialization of the sync engine, without trusted vault keys
  746. // being required.
  747. crypto_.SetSyncEngine(kSyncingAccount, &engine_);
  748. ASSERT_THAT(trusted_vault_client_.fetch_count(), Eq(0));
  749. ASSERT_THAT(trusted_vault_client_.server_request_count(), Eq(0));
  750. // Later on, mimic trusted vault keys being required (e.g. remote Nigori
  751. // update), which should trigger a fetch.
  752. crypto_.OnTrustedVaultKeyRequired();
  753. EXPECT_THAT(trusted_vault_client_.fetch_count(), Eq(1));
  754. // While there is an ongoing fetch, there should be no user action required.
  755. EXPECT_FALSE(crypto_.IsTrustedVaultKeyRequired());
  756. // Mimic completion of the client.
  757. EXPECT_CALL(engine_,
  758. AddTrustedVaultDecryptionKeys(kInitialTrustedVaultKeys, _));
  759. ASSERT_TRUE(trusted_vault_client_.CompleteFetchKeysRequest());
  760. ASSERT_TRUE(add_keys_cb);
  761. EXPECT_FALSE(crypto_.IsTrustedVaultKeyRequired());
  762. // Mimic completion of the engine, without OnTrustedVaultKeyAccepted().
  763. std::move(add_keys_cb).Run();
  764. // The keys should be marked as stale, and a second fetch attempt started.
  765. EXPECT_FALSE(crypto_.IsTrustedVaultKeyRequired());
  766. EXPECT_THAT(trusted_vault_client_.keys_marked_as_stale_count(), Eq(1));
  767. EXPECT_THAT(trusted_vault_client_.fetch_count(), Eq(2));
  768. // Mimic completion of the client for the second pass.
  769. EXPECT_CALL(engine_,
  770. AddTrustedVaultDecryptionKeys(kInitialTrustedVaultKeys, _));
  771. ASSERT_TRUE(trusted_vault_client_.CompleteFetchKeysRequest());
  772. ASSERT_TRUE(add_keys_cb);
  773. // Mimic completion of the engine, without OnTrustedVaultKeyAccepted(), for
  774. // the second pass.
  775. EXPECT_CALL(delegate_, ReconfigureDataTypesDueToCrypto());
  776. std::move(add_keys_cb).Run();
  777. EXPECT_TRUE(crypto_.IsTrustedVaultKeyRequired());
  778. EXPECT_THAT(trusted_vault_client_.keys_marked_as_stale_count(), Eq(1));
  779. EXPECT_THAT(trusted_vault_client_.fetch_count(), Eq(2));
  780. }
  781. // Similar to ShouldReadInvalidTrustedVaultKeysFromClient but in this case the
  782. // client is able to follow a key rotation as part of the second fetch attempt.
  783. TEST_F(SyncServiceCryptoTest, ShouldFollowKeyRotationDueToSecondFetch) {
  784. const std::vector<std::vector<uint8_t>> kRotatedKeys = {
  785. kInitialTrustedVaultKeys[0], {2, 3, 4, 5}};
  786. // Cache |kInitialTrustedVaultKeys| into |trusted_vault_client_| prior to
  787. // engine initialization. In this test, |kInitialTrustedVaultKeys| does not
  788. // match the Nigori keys (i.e. the engine continues to think trusted vault
  789. // keys are required until |kRotatedKeys| are provided).
  790. MimicKeyRetrievalByUser();
  791. // Mimic server-side key rotation which the keys, in a way that the rotated
  792. // keys are a continuation of kInitialTrustedVaultKeys, such that
  793. // TestTrustedVaultServer will allow the client to silently follow key
  794. // rotation.
  795. trusted_vault_server_.StoreKeysOnServer(kSyncingAccount.gaia, kRotatedKeys);
  796. // The engine replies with OnTrustedVaultKeyAccepted() only if |kRotatedKeys|
  797. // are provided.
  798. ON_CALL(engine_, AddTrustedVaultDecryptionKeys)
  799. .WillByDefault([&](const std::vector<std::vector<uint8_t>>& keys,
  800. base::OnceClosure done_cb) {
  801. if (keys == kRotatedKeys) {
  802. crypto_.OnTrustedVaultKeyAccepted();
  803. }
  804. std::move(done_cb).Run();
  805. });
  806. // Mimic initialization of the engine where trusted vault keys are needed and
  807. // |kInitialTrustedVaultKeys| are fetched as part of the first fetch.
  808. crypto_.SetSyncEngine(kSyncingAccount, &engine_);
  809. crypto_.OnTrustedVaultKeyRequired();
  810. ASSERT_THAT(trusted_vault_client_.fetch_count(), Eq(1));
  811. // While there is an ongoing fetch (first attempt), there should be no user
  812. // action required.
  813. ASSERT_FALSE(crypto_.IsTrustedVaultKeyRequired());
  814. // The keys fetched in the first attempt (|kInitialTrustedVaultKeys|) are
  815. // insufficient and should be marked as stale. In addition, a second fetch
  816. // should be triggered.
  817. ASSERT_TRUE(trusted_vault_client_.CompleteFetchKeysRequest());
  818. ASSERT_THAT(trusted_vault_client_.keys_marked_as_stale_count(), Eq(1));
  819. ASSERT_THAT(trusted_vault_client_.fetch_count(), Eq(2));
  820. // While there is an ongoing fetch (second attempt), there should be no user
  821. // action required.
  822. ASSERT_FALSE(crypto_.IsTrustedVaultKeyRequired());
  823. // Because of |kRotatedKeys| is a continuation of |kInitialTrustedVaultKeys|,
  824. // TrustedVaultServer should successfully deliver the new keys |kRotatedKeys|
  825. // to the client.
  826. EXPECT_CALL(delegate_, ReconfigureDataTypesDueToCrypto());
  827. ASSERT_TRUE(trusted_vault_client_.CompleteFetchKeysRequest());
  828. EXPECT_FALSE(crypto_.IsTrustedVaultKeyRequired());
  829. ASSERT_THAT(trusted_vault_client_.keys_marked_as_stale_count(), Eq(1));
  830. }
  831. // Similar to ShouldReadInvalidTrustedVaultKeysFromClient: the vault
  832. // initially has no valid keys, leading to IsTrustedVaultKeyRequired().
  833. // Later, the vault gets populated with the keys, which should trigger
  834. // a fetch and eventually resolve the encryption issue.
  835. TEST_F(SyncServiceCryptoTest, ShouldRefetchTrustedVaultKeysWhenChangeObserved) {
  836. const std::vector<std::vector<uint8_t>> kNewKeys = {{2, 3, 4, 5}};
  837. // Cache |kInitialTrustedVaultKeys| into |trusted_vault_client_| prior to
  838. // engine initialization. In this test, |kInitialTrustedVaultKeys| does not
  839. // match the Nigori keys (i.e. the engine continues to think trusted vault
  840. // keys are required until |kNewKeys| are provided).
  841. MimicKeyRetrievalByUser();
  842. // The engine replies with OnTrustedVaultKeyAccepted() only if |kNewKeys| are
  843. // provided.
  844. ON_CALL(engine_, AddTrustedVaultDecryptionKeys)
  845. .WillByDefault([&](const std::vector<std::vector<uint8_t>>& keys,
  846. base::OnceClosure done_cb) {
  847. if (keys == kNewKeys) {
  848. crypto_.OnTrustedVaultKeyAccepted();
  849. }
  850. std::move(done_cb).Run();
  851. });
  852. // Mimic initialization of the engine where trusted vault keys are needed and
  853. // |kInitialTrustedVaultKeys| are fetched, which are insufficient, and hence
  854. // IsTrustedVaultKeyRequired() is exposed.
  855. crypto_.SetSyncEngine(kSyncingAccount, &engine_);
  856. crypto_.OnTrustedVaultKeyRequired();
  857. ASSERT_THAT(trusted_vault_client_.fetch_count(), Eq(1));
  858. ASSERT_TRUE(trusted_vault_client_.CompleteFetchKeysRequest());
  859. // Note that this initial attempt involves two fetches, where both return
  860. // |kInitialTrustedVaultKeys|.
  861. ASSERT_THAT(trusted_vault_client_.keys_marked_as_stale_count(), Eq(1));
  862. ASSERT_THAT(trusted_vault_client_.fetch_count(), Eq(2));
  863. ASSERT_TRUE(trusted_vault_client_.CompleteFetchKeysRequest());
  864. ASSERT_THAT(trusted_vault_client_.keys_marked_as_stale_count(), Eq(1));
  865. ASSERT_TRUE(crypto_.IsTrustedVaultKeyRequired());
  866. // Mimic server-side key reset and a new retrieval.
  867. trusted_vault_server_.StoreKeysOnServer(kSyncingAccount.gaia, kNewKeys);
  868. MimicKeyRetrievalByUser();
  869. // Key retrieval should have initiated a third fetch.
  870. EXPECT_THAT(trusted_vault_client_.fetch_count(), Eq(3));
  871. EXPECT_CALL(delegate_, ReconfigureDataTypesDueToCrypto());
  872. EXPECT_TRUE(trusted_vault_client_.CompleteFetchKeysRequest());
  873. EXPECT_FALSE(crypto_.IsTrustedVaultKeyRequired());
  874. EXPECT_THAT(trusted_vault_client_.keys_marked_as_stale_count(), Eq(1));
  875. }
  876. // Same as above but the new keys become available during an ongoing FetchKeys()
  877. // request.
  878. TEST_F(SyncServiceCryptoTest,
  879. ShouldDeferTrustedVaultKeyFetchingWhenChangeObservedWhileOngoingFetch) {
  880. const std::vector<std::vector<uint8_t>> kNewKeys = {{2, 3, 4, 5}};
  881. // Cache |kInitialTrustedVaultKeys| into |trusted_vault_client_| prior to
  882. // engine initialization. In this test, |kInitialTrustedVaultKeys| does not
  883. // match the Nigori keys (i.e. the engine continues to think trusted vault
  884. // keys are required until |kNewKeys| are provided).
  885. MimicKeyRetrievalByUser();
  886. // The engine replies with OnTrustedVaultKeyAccepted() only if |kNewKeys| are
  887. // provided.
  888. ON_CALL(engine_, AddTrustedVaultDecryptionKeys)
  889. .WillByDefault([&](const std::vector<std::vector<uint8_t>>& keys,
  890. base::OnceClosure done_cb) {
  891. if (keys == kNewKeys) {
  892. crypto_.OnTrustedVaultKeyAccepted();
  893. }
  894. std::move(done_cb).Run();
  895. });
  896. // Mimic initialization of the engine where trusted vault keys are needed and
  897. // |kInitialTrustedVaultKeys| are in the process of being fetched.
  898. crypto_.SetSyncEngine(kSyncingAccount, &engine_);
  899. crypto_.OnTrustedVaultKeyRequired();
  900. ASSERT_THAT(trusted_vault_client_.fetch_count(), Eq(1));
  901. ASSERT_FALSE(crypto_.IsTrustedVaultKeyRequired());
  902. // While there is an ongoing fetch, mimic server-side key reset and a new
  903. // retrieval.
  904. trusted_vault_server_.StoreKeysOnServer(kSyncingAccount.gaia, kNewKeys);
  905. MimicKeyRetrievalByUser();
  906. // Because there's already an ongoing fetch, a second one should not have been
  907. // triggered yet and should be deferred instead.
  908. EXPECT_THAT(trusted_vault_client_.fetch_count(), Eq(1));
  909. // As soon as the first fetch completes, the second one (deferred) should be
  910. // started.
  911. EXPECT_TRUE(trusted_vault_client_.CompleteFetchKeysRequest());
  912. EXPECT_THAT(trusted_vault_client_.fetch_count(), Eq(2));
  913. EXPECT_FALSE(crypto_.IsTrustedVaultKeyRequired());
  914. // The completion of the second fetch should resolve the encryption issue.
  915. EXPECT_CALL(delegate_, ReconfigureDataTypesDueToCrypto());
  916. EXPECT_TRUE(trusted_vault_client_.CompleteFetchKeysRequest());
  917. EXPECT_THAT(trusted_vault_client_.fetch_count(), Eq(2));
  918. EXPECT_FALSE(crypto_.IsTrustedVaultKeyRequired());
  919. }
  920. // The engine gets initialized and the vault initially has insufficient keys,
  921. // leading to IsTrustedVaultKeyRequired(). Later, keys are added to the vault
  922. // *twice*, where the later event should be handled as a deferred fetch.
  923. TEST_F(
  924. SyncServiceCryptoTest,
  925. ShouldDeferTrustedVaultKeyFetchingWhenChangeObservedWhileOngoingRefetch) {
  926. const std::vector<std::vector<uint8_t>> kLatestKeys = {{2, 2, 2, 2, 2}};
  927. // The engine replies with OnTrustedVaultKeyAccepted() only if |kLatestKeys|
  928. // are provided.
  929. ON_CALL(engine_, AddTrustedVaultDecryptionKeys)
  930. .WillByDefault([&](const std::vector<std::vector<uint8_t>>& keys,
  931. base::OnceClosure done_cb) {
  932. if (keys == kLatestKeys) {
  933. crypto_.OnTrustedVaultKeyAccepted();
  934. }
  935. std::move(done_cb).Run();
  936. });
  937. // Mimic initialization of the engine where trusted vault keys are needed and
  938. // no keys are fetched from the client, hence IsTrustedVaultKeyRequired() is
  939. // exposed.
  940. crypto_.SetSyncEngine(kSyncingAccount, &engine_);
  941. crypto_.OnTrustedVaultKeyRequired();
  942. ASSERT_THAT(trusted_vault_client_.fetch_count(), Eq(1));
  943. ASSERT_TRUE(trusted_vault_client_.CompleteFetchKeysRequest());
  944. ASSERT_THAT(trusted_vault_client_.fetch_count(), Eq(1));
  945. ASSERT_THAT(trusted_vault_client_.keys_marked_as_stale_count(), Eq(0));
  946. ASSERT_TRUE(crypto_.IsTrustedVaultKeyRequired());
  947. // Mimic retrieval of keys, leading to a second fetch that returns
  948. // |kInitialTrustedVaultKeys|, which are insufficient and should be marked as
  949. // stale as soon as the fetch completes (later below).
  950. MimicKeyRetrievalByUser();
  951. EXPECT_THAT(trusted_vault_client_.fetch_count(), Eq(2));
  952. // While the second fetch is ongoing, mimic additional keys being retrieved.
  953. // Because there's already an ongoing fetch, a third one should not have been
  954. // triggered yet and should be deferred instead.
  955. trusted_vault_server_.StoreKeysOnServer(kSyncingAccount.gaia, kLatestKeys);
  956. MimicKeyRetrievalByUser();
  957. EXPECT_THAT(trusted_vault_client_.fetch_count(), Eq(2));
  958. // As soon as the second fetch completes, the keys should be marked as stale
  959. // and a third fetch attempt triggered.
  960. EXPECT_TRUE(trusted_vault_client_.CompleteFetchKeysRequest());
  961. EXPECT_THAT(trusted_vault_client_.keys_marked_as_stale_count(), Eq(1));
  962. EXPECT_THAT(trusted_vault_client_.fetch_count(), Eq(3));
  963. // As soon as the third fetch completes, the fourth one (deferred) should be
  964. // started.
  965. EXPECT_TRUE(trusted_vault_client_.CompleteFetchKeysRequest());
  966. EXPECT_THAT(trusted_vault_client_.fetch_count(), Eq(3));
  967. }
  968. TEST_F(SyncServiceCryptoTest, ShouldNotGetRecoverabilityIfFeatureDisabled) {
  969. base::test::ScopedFeatureList override_features;
  970. override_features.InitAndDisableFeature(kSyncTrustedVaultPassphraseRecovery);
  971. trusted_vault_client_.SetIsRecoverabilityDegraded(true);
  972. crypto_.OnPassphraseTypeChanged(PassphraseType::kTrustedVaultPassphrase,
  973. base::Time::Now());
  974. crypto_.SetSyncEngine(CoreAccountInfo(), &engine_);
  975. ASSERT_THAT(crypto_.GetPassphraseType(),
  976. Eq(PassphraseType::kTrustedVaultPassphrase));
  977. ASSERT_TRUE(crypto_.IsTrustedVaultKeyRequiredStateKnown());
  978. ASSERT_FALSE(crypto_.IsTrustedVaultKeyRequired());
  979. EXPECT_THAT(trusted_vault_client_.get_is_recoverablity_degraded_call_count(),
  980. Eq(0));
  981. EXPECT_FALSE(crypto_.IsTrustedVaultRecoverabilityDegraded());
  982. }
  983. TEST_F(SyncServiceCryptoTest,
  984. ShouldNotGetRecoverabilityIfKeystorePassphraseUsed) {
  985. base::test::ScopedFeatureList override_features;
  986. override_features.InitAndEnableFeature(kSyncTrustedVaultPassphraseRecovery);
  987. trusted_vault_client_.SetIsRecoverabilityDegraded(true);
  988. crypto_.OnPassphraseTypeChanged(PassphraseType::kKeystorePassphrase,
  989. base::Time::Now());
  990. crypto_.SetSyncEngine(CoreAccountInfo(), &engine_);
  991. ASSERT_THAT(crypto_.GetPassphraseType(),
  992. Eq(PassphraseType::kKeystorePassphrase));
  993. ASSERT_TRUE(crypto_.IsTrustedVaultKeyRequiredStateKnown());
  994. ASSERT_FALSE(crypto_.IsTrustedVaultKeyRequired());
  995. EXPECT_THAT(trusted_vault_client_.get_is_recoverablity_degraded_call_count(),
  996. Eq(0));
  997. EXPECT_FALSE(crypto_.IsTrustedVaultRecoverabilityDegraded());
  998. }
  999. TEST_F(SyncServiceCryptoTest,
  1000. ShouldNotReportDegradedRecoverabilityUponInitialization) {
  1001. base::test::ScopedFeatureList override_features;
  1002. override_features.InitAndEnableFeature(kSyncTrustedVaultPassphraseRecovery);
  1003. base::HistogramTester histogram_tester;
  1004. trusted_vault_client_.SetIsRecoverabilityDegraded(false);
  1005. crypto_.OnPassphraseTypeChanged(PassphraseType::kTrustedVaultPassphrase,
  1006. base::Time::Now());
  1007. crypto_.SetSyncEngine(CoreAccountInfo(), &engine_);
  1008. ASSERT_THAT(crypto_.GetPassphraseType(),
  1009. Eq(PassphraseType::kTrustedVaultPassphrase));
  1010. ASSERT_TRUE(crypto_.IsTrustedVaultKeyRequiredStateKnown());
  1011. ASSERT_FALSE(crypto_.IsTrustedVaultKeyRequired());
  1012. EXPECT_FALSE(crypto_.IsTrustedVaultRecoverabilityDegraded());
  1013. histogram_tester.ExpectUniqueSample(
  1014. "Sync.TrustedVaultRecoverabilityDegradedOnStartup",
  1015. /*sample=*/false, /*expected_bucket_count=*/1);
  1016. }
  1017. TEST_F(SyncServiceCryptoTest,
  1018. ShouldReportDegradedRecoverabilityUponInitialization) {
  1019. base::test::ScopedFeatureList override_features;
  1020. override_features.InitAndEnableFeature(kSyncTrustedVaultPassphraseRecovery);
  1021. base::HistogramTester histogram_tester;
  1022. trusted_vault_client_.SetIsRecoverabilityDegraded(true);
  1023. crypto_.OnPassphraseTypeChanged(PassphraseType::kTrustedVaultPassphrase,
  1024. base::Time::Now());
  1025. crypto_.SetSyncEngine(CoreAccountInfo(), &engine_);
  1026. ASSERT_THAT(crypto_.GetPassphraseType(),
  1027. Eq(PassphraseType::kTrustedVaultPassphrase));
  1028. ASSERT_TRUE(crypto_.IsTrustedVaultKeyRequiredStateKnown());
  1029. ASSERT_FALSE(crypto_.IsTrustedVaultKeyRequired());
  1030. EXPECT_TRUE(crypto_.IsTrustedVaultRecoverabilityDegraded());
  1031. histogram_tester.ExpectUniqueSample(
  1032. "Sync.TrustedVaultRecoverabilityDegradedOnStartup",
  1033. /*sample=*/true, /*expected_bucket_count=*/1);
  1034. }
  1035. TEST_F(SyncServiceCryptoTest, ShouldReportDegradedRecoverabilityUponChange) {
  1036. base::test::ScopedFeatureList override_features;
  1037. override_features.InitAndEnableFeature(kSyncTrustedVaultPassphraseRecovery);
  1038. base::HistogramTester histogram_tester;
  1039. trusted_vault_client_.SetIsRecoverabilityDegraded(false);
  1040. crypto_.OnPassphraseTypeChanged(PassphraseType::kTrustedVaultPassphrase,
  1041. base::Time::Now());
  1042. crypto_.SetSyncEngine(CoreAccountInfo(), &engine_);
  1043. ASSERT_THAT(crypto_.GetPassphraseType(),
  1044. Eq(PassphraseType::kTrustedVaultPassphrase));
  1045. ASSERT_TRUE(crypto_.IsTrustedVaultKeyRequiredStateKnown());
  1046. ASSERT_FALSE(crypto_.IsTrustedVaultKeyRequired());
  1047. ASSERT_FALSE(crypto_.IsTrustedVaultRecoverabilityDegraded());
  1048. // Changing the state notifies observers and should lead to a change in
  1049. // IsTrustedVaultRecoverabilityDegraded().
  1050. EXPECT_CALL(delegate_, CryptoStateChanged());
  1051. trusted_vault_client_.SetIsRecoverabilityDegraded(true);
  1052. EXPECT_TRUE(crypto_.IsTrustedVaultRecoverabilityDegraded());
  1053. // For UMA purposes, only the initial value counts (false).
  1054. histogram_tester.ExpectUniqueSample(
  1055. "Sync.TrustedVaultRecoverabilityDegradedOnStartup",
  1056. /*sample=*/false, /*expected_bucket_count=*/1);
  1057. }
  1058. TEST_F(SyncServiceCryptoTest,
  1059. ShouldStopReportingDegradedRecoverabilityUponChange) {
  1060. base::test::ScopedFeatureList override_features;
  1061. override_features.InitAndEnableFeature(kSyncTrustedVaultPassphraseRecovery);
  1062. base::HistogramTester histogram_tester;
  1063. trusted_vault_client_.SetIsRecoverabilityDegraded(true);
  1064. crypto_.OnPassphraseTypeChanged(PassphraseType::kTrustedVaultPassphrase,
  1065. base::Time::Now());
  1066. crypto_.SetSyncEngine(CoreAccountInfo(), &engine_);
  1067. ASSERT_THAT(crypto_.GetPassphraseType(),
  1068. Eq(PassphraseType::kTrustedVaultPassphrase));
  1069. ASSERT_TRUE(crypto_.IsTrustedVaultKeyRequiredStateKnown());
  1070. ASSERT_FALSE(crypto_.IsTrustedVaultKeyRequired());
  1071. ASSERT_TRUE(crypto_.IsTrustedVaultRecoverabilityDegraded());
  1072. // Changing the state notifies observers and should lead to a change in
  1073. // IsTrustedVaultRecoverabilityDegraded().
  1074. EXPECT_CALL(delegate_, CryptoStateChanged());
  1075. trusted_vault_client_.SetIsRecoverabilityDegraded(false);
  1076. EXPECT_FALSE(crypto_.IsTrustedVaultRecoverabilityDegraded());
  1077. // For UMA purposes, only the initial value counts (true).
  1078. histogram_tester.ExpectUniqueSample(
  1079. "Sync.TrustedVaultRecoverabilityDegradedOnStartup",
  1080. /*sample=*/true, /*expected_bucket_count=*/1);
  1081. }
  1082. TEST_F(SyncServiceCryptoTest, ShouldReportDegradedRecoverabilityUponRetrieval) {
  1083. base::test::ScopedFeatureList override_features;
  1084. override_features.InitAndEnableFeature(kSyncTrustedVaultPassphraseRecovery);
  1085. base::HistogramTester histogram_tester;
  1086. trusted_vault_client_.SetIsRecoverabilityDegraded(true);
  1087. // Mimic startup with trusted vault keys being required.
  1088. crypto_.OnTrustedVaultKeyRequired();
  1089. crypto_.OnPassphraseTypeChanged(PassphraseType::kTrustedVaultPassphrase,
  1090. base::Time::Now());
  1091. crypto_.SetSyncEngine(kSyncingAccount, &engine_);
  1092. ASSERT_FALSE(crypto_.IsTrustedVaultKeyRequiredStateKnown());
  1093. ASSERT_FALSE(crypto_.IsTrustedVaultRecoverabilityDegraded());
  1094. // Complete the fetching of initial keys (no keys) from the client.
  1095. ASSERT_TRUE(trusted_vault_client_.CompleteFetchKeysRequest());
  1096. ASSERT_TRUE(crypto_.IsTrustedVaultKeyRequiredStateKnown());
  1097. ASSERT_TRUE(crypto_.IsTrustedVaultKeyRequired());
  1098. ASSERT_FALSE(crypto_.IsTrustedVaultRecoverabilityDegraded());
  1099. // Mimic a successful key retrieval.
  1100. ON_CALL(engine_, AddTrustedVaultDecryptionKeys)
  1101. .WillByDefault([&](const std::vector<std::vector<uint8_t>>& keys,
  1102. base::OnceClosure done_cb) {
  1103. crypto_.OnTrustedVaultKeyAccepted();
  1104. std::move(done_cb).Run();
  1105. });
  1106. MimicKeyRetrievalByUser();
  1107. ASSERT_TRUE(trusted_vault_client_.CompleteFetchKeysRequest());
  1108. ASSERT_TRUE(crypto_.IsTrustedVaultKeyRequiredStateKnown());
  1109. ASSERT_FALSE(crypto_.IsTrustedVaultKeyRequired());
  1110. // The recoverability state should be exposed.
  1111. EXPECT_TRUE(crypto_.IsTrustedVaultRecoverabilityDegraded());
  1112. histogram_tester.ExpectUniqueSample(
  1113. "Sync.TrustedVaultRecoverabilityDegradedOnStartup",
  1114. /*sample=*/true, /*expected_bucket_count=*/1);
  1115. }
  1116. TEST_F(SyncServiceCryptoTest,
  1117. ShouldClearDegradedRecoverabilityIfCustomPassphraseIsSet) {
  1118. const std::string kTestPassphrase = "somepassphrase";
  1119. base::test::ScopedFeatureList override_features;
  1120. override_features.InitAndEnableFeature(kSyncTrustedVaultPassphraseRecovery);
  1121. // Mimic a browser startup in |kTrustedVaultPassphrase| with no additional
  1122. // keys required and degraded recoverability state.
  1123. trusted_vault_client_.SetIsRecoverabilityDegraded(true);
  1124. crypto_.OnPassphraseTypeChanged(PassphraseType::kTrustedVaultPassphrase,
  1125. base::Time::Now());
  1126. crypto_.SetSyncEngine(CoreAccountInfo(), &engine_);
  1127. ASSERT_THAT(crypto_.GetPassphraseType(),
  1128. Eq(PassphraseType::kTrustedVaultPassphrase));
  1129. ASSERT_TRUE(crypto_.IsTrustedVaultKeyRequiredStateKnown());
  1130. ASSERT_FALSE(crypto_.IsTrustedVaultKeyRequired());
  1131. ASSERT_FALSE(crypto_.IsPassphraseRequired());
  1132. ASSERT_TRUE(crypto_.IsTrustedVaultRecoverabilityDegraded());
  1133. // Mimic the user setting up a new custom passphrase.
  1134. crypto_.SetEncryptionPassphrase(kTestPassphrase);
  1135. // Mimic completion of the procedure in the sync engine.
  1136. EXPECT_CALL(delegate_, ReconfigureDataTypesDueToCrypto());
  1137. EXPECT_CALL(delegate_, CryptoStateChanged());
  1138. crypto_.OnPassphraseTypeChanged(PassphraseType::kCustomPassphrase,
  1139. base::Time::Now());
  1140. crypto_.OnPassphraseAccepted();
  1141. ASSERT_THAT(crypto_.GetPassphraseType(),
  1142. Eq(PassphraseType::kCustomPassphrase));
  1143. // Recoverability should no longer be considered degraded.
  1144. EXPECT_FALSE(crypto_.IsTrustedVaultRecoverabilityDegraded());
  1145. }
  1146. } // namespace
  1147. } // namespace syncer