1 // Copyright 2018 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 "build/build_config.h"
6 #include "chrome/browser/sync/test/integration/bookmarks_helper.h"
7 #include "chrome/browser/sync/test/integration/encryption_helper.h"
8 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
9 #include "chrome/browser/sync/test/integration/sync_integration_test_util.h"
10 #include "chrome/browser/sync/test/integration/sync_test.h"
11 #include "chrome/browser/sync/test/integration/updated_progress_marker_checker.h"
12 #include "components/sync/base/sync_base_switches.h"
13 #include "components/sync/engine/sync_engine_switches.h"
14 #include "components/sync/nigori/nigori_test_utils.h"
15 #include "content/public/test/browser_test.h"
16 #include "content/public/test/test_launcher.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 
19 namespace {
20 
21 static const int kEncryptingClientId = 0;
22 static const int kDecryptingClientId = 1;
23 
24 using bookmarks_helper::AddURL;
25 using bookmarks_helper::AllModelsMatchVerifier;
26 using bookmarks_helper::BookmarksMatchVerifierChecker;
27 
28 // These tests consider the client as a black-box; they are not concerned with
29 // whether the data is committed to the server correctly encrypted. Rather, they
30 // test the end-to-end behavior of two clients when a custom passphrase is set,
31 // i.e. whether the second client can see data that was committed by the first
32 // client. To test proper encryption behavior, a separate single-client test is
33 // used.
34 class TwoClientCustomPassphraseSyncTest : public SyncTest {
35  public:
TwoClientCustomPassphraseSyncTest()36   TwoClientCustomPassphraseSyncTest() : SyncTest(TWO_CLIENT) {}
37   ~TwoClientCustomPassphraseSyncTest() override = default;
38 
UseVerifier()39   bool UseVerifier() override {
40     // TODO(crbug.com/1137720): rewrite test to not use verifier (currently
41     // needed because of WaitForBookmarksToMatchVerifier()).
42     return true;
43   }
44 
WaitForBookmarksToMatchVerifier()45   bool WaitForBookmarksToMatchVerifier() {
46     return BookmarksMatchVerifierChecker().Wait();
47   }
48 
WaitForPassphraseRequiredState(int index,bool desired_state)49   bool WaitForPassphraseRequiredState(int index, bool desired_state) {
50     return PassphraseRequiredStateChecker(GetSyncService(index), desired_state)
51         .Wait();
52   }
53 
AddTestBookmarksToClient(int index)54   void AddTestBookmarksToClient(int index) {
55     ASSERT_TRUE(AddURL(index, 0, "What are you syncing about?",
56                        GURL("https://google.com/synced-bookmark-1")));
57     ASSERT_TRUE(AddURL(index, 1, "Test bookmark",
58                        GURL("https://google.com/synced-bookmark-2")));
59   }
60 };
61 
62 class TwoClientCustomPassphraseSyncTestScryptEnabledInPreTest
63     : public TwoClientCustomPassphraseSyncTest {
64  public:
TwoClientCustomPassphraseSyncTestScryptEnabledInPreTest()65   TwoClientCustomPassphraseSyncTestScryptEnabledInPreTest() {
66     if (content::IsPreTest()) {
67       override_features_.InitWithFeatures(
68           /*enabled_features=*/{switches::
69                                     kSyncUseScryptForNewCustomPassphrases},
70           /*disabled_features=*/{
71               switches::kSyncForceDisableScryptForCustomPassphrase});
72     } else {
73       override_features_.InitWithFeatures(
74           /*enabled_features=*/{},
75           /*disabled_features=*/{
76               switches::kSyncUseScryptForNewCustomPassphrases,
77               switches::kSyncForceDisableScryptForCustomPassphrase});
78     }
79   }
80 
81   ~TwoClientCustomPassphraseSyncTestScryptEnabledInPreTest() override = default;
82 
83  private:
84   base::test::ScopedFeatureList override_features_;
85 
86   DISALLOW_COPY_AND_ASSIGN(
87       TwoClientCustomPassphraseSyncTestScryptEnabledInPreTest);
88 };
89 
IN_PROC_BROWSER_TEST_F(TwoClientCustomPassphraseSyncTest,DecryptionFailsWhenIncorrectPassphraseProvided)90 IN_PROC_BROWSER_TEST_F(TwoClientCustomPassphraseSyncTest,
91                        DecryptionFailsWhenIncorrectPassphraseProvided) {
92   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
93   ASSERT_TRUE(AllModelsMatchVerifier());
94 
95   GetSyncService(kEncryptingClientId)
96       ->GetUserSettings()
97       ->SetEncryptionPassphrase("hunter2");
98   ASSERT_TRUE(WaitForPassphraseRequiredState(kDecryptingClientId,
99                                              /*desired_state=*/true));
100   EXPECT_FALSE(GetSyncService(kDecryptingClientId)
101                    ->GetUserSettings()
102                    ->SetDecryptionPassphrase("incorrect passphrase"));
103   EXPECT_TRUE(GetSyncService(kDecryptingClientId)
104                   ->GetUserSettings()
105                   ->IsPassphraseRequiredForPreferredDataTypes());
106 }
107 
IN_PROC_BROWSER_TEST_F(TwoClientCustomPassphraseSyncTest,ClientsCanSyncData)108 IN_PROC_BROWSER_TEST_F(TwoClientCustomPassphraseSyncTest, ClientsCanSyncData) {
109   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
110   ASSERT_TRUE(AllModelsMatchVerifier());
111 
112   GetSyncService(kEncryptingClientId)
113       ->GetUserSettings()
114       ->SetEncryptionPassphrase("hunter2");
115   ASSERT_TRUE(WaitForPassphraseRequiredState(kDecryptingClientId,
116                                              /*desired_state=*/true));
117   EXPECT_TRUE(GetSyncService(kDecryptingClientId)
118                   ->GetUserSettings()
119                   ->SetDecryptionPassphrase("hunter2"));
120   EXPECT_TRUE(WaitForPassphraseRequiredState(kDecryptingClientId,
121                                              /*desired_state=*/false));
122   AddTestBookmarksToClient(kEncryptingClientId);
123 
124   ASSERT_TRUE(
125       GetClient(kEncryptingClientId)
126           ->AwaitMutualSyncCycleCompletion(GetClient(kDecryptingClientId)));
127   EXPECT_TRUE(WaitForBookmarksToMatchVerifier());
128 }
129 
IN_PROC_BROWSER_TEST_F(TwoClientCustomPassphraseSyncTest,SetPassphraseAndThenSetupSync)130 IN_PROC_BROWSER_TEST_F(TwoClientCustomPassphraseSyncTest,
131                        SetPassphraseAndThenSetupSync) {
132   ASSERT_TRUE(SetupClients());
133   ASSERT_TRUE(GetClient(kEncryptingClientId)->SetupSync());
134 
135   // Set up a sync client with custom passphrase and one bookmark.
136   GetSyncService(kEncryptingClientId)
137       ->GetUserSettings()
138       ->SetEncryptionPassphrase("hunter2");
139   ASSERT_TRUE(
140       PassphraseAcceptedChecker(GetSyncService(kEncryptingClientId)).Wait());
141   AddTestBookmarksToClient(kEncryptingClientId);
142   // Wait for the client to commit the update.
143   ASSERT_TRUE(
144       UpdatedProgressMarkerChecker(GetSyncService(kEncryptingClientId)).Wait());
145 
146   // Set up a new sync client.
147   ASSERT_TRUE(GetClient(kDecryptingClientId)
148                   ->SetupSyncNoWaitForCompletion(
149                       GetRegisteredSelectableTypes(kDecryptingClientId)));
150   ASSERT_TRUE(
151       PassphraseRequiredChecker(GetSyncService(kDecryptingClientId)).Wait());
152 
153   // Get client |kDecryptingClientId| out of the passphrase required state.
154   ASSERT_TRUE(GetSyncService(kDecryptingClientId)
155                   ->GetUserSettings()
156                   ->SetDecryptionPassphrase("hunter2"));
157   ASSERT_TRUE(
158       PassphraseAcceptedChecker(GetSyncService(kDecryptingClientId)).Wait());
159   GetClient(kDecryptingClientId)->FinishSyncSetup();
160 
161   // Wait for bookmarks to converge.
162   EXPECT_TRUE(WaitForBookmarksToMatchVerifier());
163 }
164 
165 class TwoClientCustomPassphraseSyncTestWithScryptEncryptionNotEnabled
166     : public TwoClientCustomPassphraseSyncTest {
167  public:
TwoClientCustomPassphraseSyncTestWithScryptEncryptionNotEnabled()168   TwoClientCustomPassphraseSyncTestWithScryptEncryptionNotEnabled()
169       : toggler_(/*force_disabled=*/false,
170                  /*use_for_new_passphrases=*/false) {}
~TwoClientCustomPassphraseSyncTestWithScryptEncryptionNotEnabled()171   ~TwoClientCustomPassphraseSyncTestWithScryptEncryptionNotEnabled() override {}
172 
173  private:
174   ScopedScryptFeatureToggler toggler_;
175   DISALLOW_COPY_AND_ASSIGN(
176       TwoClientCustomPassphraseSyncTestWithScryptEncryptionNotEnabled);
177 };
178 
IN_PROC_BROWSER_TEST_F(TwoClientCustomPassphraseSyncTestWithScryptEncryptionNotEnabled,ClientsCanSyncData)179 IN_PROC_BROWSER_TEST_F(
180     TwoClientCustomPassphraseSyncTestWithScryptEncryptionNotEnabled,
181     ClientsCanSyncData) {
182   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
183   ASSERT_TRUE(AllModelsMatchVerifier());
184 
185   GetSyncService(kEncryptingClientId)
186       ->GetUserSettings()
187       ->SetEncryptionPassphrase("hunter2");
188   ASSERT_TRUE(WaitForPassphraseRequiredState(kDecryptingClientId,
189                                              /*desired_state=*/true));
190   EXPECT_TRUE(GetSyncService(kDecryptingClientId)
191                   ->GetUserSettings()
192                   ->SetDecryptionPassphrase("hunter2"));
193   EXPECT_TRUE(WaitForPassphraseRequiredState(kDecryptingClientId,
194                                              /*desired_state=*/false));
195   AddTestBookmarksToClient(kEncryptingClientId);
196 
197   ASSERT_TRUE(
198       GetClient(kEncryptingClientId)
199           ->AwaitMutualSyncCycleCompletion(GetClient(kDecryptingClientId)));
200   EXPECT_TRUE(WaitForBookmarksToMatchVerifier());
201 }
202 
203 class TwoClientCustomPassphraseSyncTestWithScryptEncryptionEnabled
204     : public TwoClientCustomPassphraseSyncTest {
205  public:
TwoClientCustomPassphraseSyncTestWithScryptEncryptionEnabled()206   TwoClientCustomPassphraseSyncTestWithScryptEncryptionEnabled()
207       : toggler_(/*force_disabled=*/false,
208                  /*use_for_new_passphrases=*/true) {}
~TwoClientCustomPassphraseSyncTestWithScryptEncryptionEnabled()209   ~TwoClientCustomPassphraseSyncTestWithScryptEncryptionEnabled() override {}
210 
211  private:
212   ScopedScryptFeatureToggler toggler_;
213   DISALLOW_COPY_AND_ASSIGN(
214       TwoClientCustomPassphraseSyncTestWithScryptEncryptionEnabled);
215 };
216 
IN_PROC_BROWSER_TEST_F(TwoClientCustomPassphraseSyncTestWithScryptEncryptionEnabled,ClientsCanSyncData)217 IN_PROC_BROWSER_TEST_F(
218     TwoClientCustomPassphraseSyncTestWithScryptEncryptionEnabled,
219     ClientsCanSyncData) {
220   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
221   ASSERT_TRUE(AllModelsMatchVerifier());
222 
223   GetSyncService(kEncryptingClientId)
224       ->GetUserSettings()
225       ->SetEncryptionPassphrase("hunter2");
226   ASSERT_TRUE(WaitForPassphraseRequiredState(kDecryptingClientId,
227                                              /*desired_state=*/true));
228   EXPECT_TRUE(GetSyncService(kDecryptingClientId)
229                   ->GetUserSettings()
230                   ->SetDecryptionPassphrase("hunter2"));
231   EXPECT_TRUE(WaitForPassphraseRequiredState(kDecryptingClientId,
232                                              /*desired_state=*/false));
233   AddTestBookmarksToClient(kEncryptingClientId);
234 
235   ASSERT_TRUE(
236       GetClient(kEncryptingClientId)
237           ->AwaitMutualSyncCycleCompletion(GetClient(kDecryptingClientId)));
238   EXPECT_TRUE(WaitForBookmarksToMatchVerifier());
239 }
240 
IN_PROC_BROWSER_TEST_F(TwoClientCustomPassphraseSyncTestScryptEnabledInPreTest,PRE_ClientsCanSyncDataWhenScryptEncryptionEnabledInOne)241 IN_PROC_BROWSER_TEST_F(TwoClientCustomPassphraseSyncTestScryptEnabledInPreTest,
242                        PRE_ClientsCanSyncDataWhenScryptEncryptionEnabledInOne) {
243   ASSERT_TRUE(SetupSync());
244   ASSERT_TRUE(AllModelsMatchVerifier());
245 
246   GetSyncService(kEncryptingClientId)
247       ->GetUserSettings()
248       ->SetEncryptionPassphrase("hunter2");
249   ASSERT_TRUE(ServerNigoriChecker(GetSyncService(kEncryptingClientId),
250                                   GetFakeServer(),
251                                   syncer::PassphraseType::kCustomPassphrase)
252                   .Wait());
253 }
254 
IN_PROC_BROWSER_TEST_F(TwoClientCustomPassphraseSyncTestScryptEnabledInPreTest,ClientsCanSyncDataWhenScryptEncryptionEnabledInOne)255 IN_PROC_BROWSER_TEST_F(TwoClientCustomPassphraseSyncTestScryptEnabledInPreTest,
256                        ClientsCanSyncDataWhenScryptEncryptionEnabledInOne) {
257   ASSERT_TRUE(SetupClients());
258   ASSERT_TRUE(AllModelsMatchVerifier());
259 
260   // WaitForPassphraseRequiredState() doesn't guarantee, that sync engine will
261   // be initialized, but SetDecryptionPassphrase() requires it, so explicitly
262   // wait for engine initialization.
263   ASSERT_TRUE(GetClient(kDecryptingClientId)->AwaitEngineInitialization());
264   ASSERT_TRUE(WaitForPassphraseRequiredState(kDecryptingClientId,
265                                              /*desired_state=*/true));
266   EXPECT_TRUE(GetSyncService(kDecryptingClientId)
267                   ->GetUserSettings()
268                   ->SetDecryptionPassphrase("hunter2"));
269   EXPECT_TRUE(WaitForPassphraseRequiredState(kDecryptingClientId,
270                                              /*desired_state=*/false));
271   AddTestBookmarksToClient(kEncryptingClientId);
272 
273   ASSERT_TRUE(
274       GetClient(kEncryptingClientId)
275           ->AwaitMutualSyncCycleCompletion(GetClient(kDecryptingClientId)));
276   EXPECT_TRUE(WaitForBookmarksToMatchVerifier());
277 }
278 
279 }  // namespace
280