Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Side by Side Diff: chrome/browser/sync/util/cryptographer_unittest.cc

Issue 9699057: [Sync] Move 'sync' target to sync/ (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address Tim's comments Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/sync/util/cryptographer.cc ('k') | chrome/browser/sync/util/data_encryption.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/sync/util/cryptographer.h"
6
7 #include <string>
8
9 #include "base/memory/scoped_ptr.h"
10 #include "base/string_util.h"
11 #include "chrome/browser/sync/syncable/model_type_test_util.h"
12 #include "chrome/browser/sync/test/fake_encryptor.h"
13 #include "sync/protocol/nigori_specifics.pb.h"
14 #include "sync/protocol/password_specifics.pb.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 namespace browser_sync {
19
20 namespace {
21
22 using ::testing::_;
23 using ::testing::Mock;
24 using ::testing::StrictMock;
25 using syncable::ModelTypeSet;
26
27 class MockObserver : public Cryptographer::Observer {
28 public:
29 MOCK_METHOD2(OnEncryptedTypesChanged,
30 void(syncable::ModelTypeSet, bool));
31 };
32
33 } // namespace
34
35 class SyncCryptographerTest : public ::testing::Test {
36 protected:
37 SyncCryptographerTest() : cryptographer_(&encryptor_) {}
38
39 FakeEncryptor encryptor_;
40 Cryptographer cryptographer_;
41 };
42
43 TEST_F(SyncCryptographerTest, EmptyCantDecrypt) {
44 EXPECT_FALSE(cryptographer_.is_ready());
45
46 sync_pb::EncryptedData encrypted;
47 encrypted.set_key_name("foo");
48 encrypted.set_blob("bar");
49
50 EXPECT_FALSE(cryptographer_.CanDecrypt(encrypted));
51 }
52
53 TEST_F(SyncCryptographerTest, EmptyCantEncrypt) {
54 EXPECT_FALSE(cryptographer_.is_ready());
55
56 sync_pb::EncryptedData encrypted;
57 sync_pb::PasswordSpecificsData original;
58 EXPECT_FALSE(cryptographer_.Encrypt(original, &encrypted));
59 }
60
61 TEST_F(SyncCryptographerTest, MissingCantDecrypt) {
62 KeyParams params = {"localhost", "dummy", "dummy"};
63 cryptographer_.AddKey(params);
64 EXPECT_TRUE(cryptographer_.is_ready());
65
66 sync_pb::EncryptedData encrypted;
67 encrypted.set_key_name("foo");
68 encrypted.set_blob("bar");
69
70 EXPECT_FALSE(cryptographer_.CanDecrypt(encrypted));
71 }
72
73 TEST_F(SyncCryptographerTest, CanEncryptAndDecrypt) {
74 KeyParams params = {"localhost", "dummy", "dummy"};
75 EXPECT_TRUE(cryptographer_.AddKey(params));
76 EXPECT_TRUE(cryptographer_.is_ready());
77
78 sync_pb::PasswordSpecificsData original;
79 original.set_origin("http://example.com");
80 original.set_username_value("azure");
81 original.set_password_value("hunter2");
82
83 sync_pb::EncryptedData encrypted;
84 EXPECT_TRUE(cryptographer_.Encrypt(original, &encrypted));
85
86 sync_pb::PasswordSpecificsData decrypted;
87 EXPECT_TRUE(cryptographer_.Decrypt(encrypted, &decrypted));
88
89 EXPECT_EQ(original.SerializeAsString(), decrypted.SerializeAsString());
90 }
91
92 TEST_F(SyncCryptographerTest, EncryptOnlyIfDifferent) {
93 KeyParams params = {"localhost", "dummy", "dummy"};
94 EXPECT_TRUE(cryptographer_.AddKey(params));
95 EXPECT_TRUE(cryptographer_.is_ready());
96
97 sync_pb::PasswordSpecificsData original;
98 original.set_origin("http://example.com");
99 original.set_username_value("azure");
100 original.set_password_value("hunter2");
101
102 sync_pb::EncryptedData encrypted;
103 EXPECT_TRUE(cryptographer_.Encrypt(original, &encrypted));
104
105 sync_pb::EncryptedData encrypted2, encrypted3;
106 encrypted2.CopyFrom(encrypted);
107 encrypted3.CopyFrom(encrypted);
108 EXPECT_TRUE(cryptographer_.Encrypt(original, &encrypted2));
109
110 // Now encrypt with a new default key. Should overwrite the old data.
111 KeyParams params_new = {"localhost", "dummy", "dummy2"};
112 cryptographer_.AddKey(params_new);
113 EXPECT_TRUE(cryptographer_.Encrypt(original, &encrypted3));
114
115 sync_pb::PasswordSpecificsData decrypted;
116 EXPECT_TRUE(cryptographer_.Decrypt(encrypted2, &decrypted));
117 // encrypted2 should match encrypted, encrypted3 should not (due to salting).
118 EXPECT_EQ(encrypted.SerializeAsString(), encrypted2.SerializeAsString());
119 EXPECT_NE(encrypted.SerializeAsString(), encrypted3.SerializeAsString());
120 EXPECT_EQ(original.SerializeAsString(), decrypted.SerializeAsString());
121 }
122
123 TEST_F(SyncCryptographerTest, AddKeySetsDefault) {
124 KeyParams params1 = {"localhost", "dummy", "dummy1"};
125 EXPECT_TRUE(cryptographer_.AddKey(params1));
126 EXPECT_TRUE(cryptographer_.is_ready());
127
128 sync_pb::PasswordSpecificsData original;
129 original.set_origin("http://example.com");
130 original.set_username_value("azure");
131 original.set_password_value("hunter2");
132
133 sync_pb::EncryptedData encrypted1;
134 EXPECT_TRUE(cryptographer_.Encrypt(original, &encrypted1));
135 sync_pb::EncryptedData encrypted2;
136 EXPECT_TRUE(cryptographer_.Encrypt(original, &encrypted2));
137
138 KeyParams params2 = {"localhost", "dummy", "dummy2"};
139 EXPECT_TRUE(cryptographer_.AddKey(params2));
140 EXPECT_TRUE(cryptographer_.is_ready());
141
142 sync_pb::EncryptedData encrypted3;
143 EXPECT_TRUE(cryptographer_.Encrypt(original, &encrypted3));
144 sync_pb::EncryptedData encrypted4;
145 EXPECT_TRUE(cryptographer_.Encrypt(original, &encrypted4));
146
147 EXPECT_EQ(encrypted1.key_name(), encrypted2.key_name());
148 EXPECT_NE(encrypted1.key_name(), encrypted3.key_name());
149 EXPECT_EQ(encrypted3.key_name(), encrypted4.key_name());
150 }
151
152 // Crashes, Bug 55178.
153 #if defined(OS_WIN)
154 #define MAYBE_EncryptExportDecrypt DISABLED_EncryptExportDecrypt
155 #else
156 #define MAYBE_EncryptExportDecrypt EncryptExportDecrypt
157 #endif
158 TEST_F(SyncCryptographerTest, MAYBE_EncryptExportDecrypt) {
159 sync_pb::EncryptedData nigori;
160 sync_pb::EncryptedData encrypted;
161
162 sync_pb::PasswordSpecificsData original;
163 original.set_origin("http://example.com");
164 original.set_username_value("azure");
165 original.set_password_value("hunter2");
166
167 {
168 Cryptographer cryptographer(&encryptor_);
169
170 KeyParams params = {"localhost", "dummy", "dummy"};
171 cryptographer.AddKey(params);
172 EXPECT_TRUE(cryptographer.is_ready());
173
174 EXPECT_TRUE(cryptographer.Encrypt(original, &encrypted));
175 EXPECT_TRUE(cryptographer.GetKeys(&nigori));
176 }
177
178 {
179 Cryptographer cryptographer(&encryptor_);
180 EXPECT_FALSE(cryptographer.CanDecrypt(nigori));
181
182 cryptographer.SetPendingKeys(nigori);
183 EXPECT_FALSE(cryptographer.is_ready());
184 EXPECT_TRUE(cryptographer.has_pending_keys());
185
186 KeyParams params = {"localhost", "dummy", "dummy"};
187 EXPECT_TRUE(cryptographer.DecryptPendingKeys(params));
188 EXPECT_TRUE(cryptographer.is_ready());
189 EXPECT_FALSE(cryptographer.has_pending_keys());
190
191 sync_pb::PasswordSpecificsData decrypted;
192 EXPECT_TRUE(cryptographer.Decrypt(encrypted, &decrypted));
193 EXPECT_EQ(original.SerializeAsString(), decrypted.SerializeAsString());
194 }
195 }
196
197 // Crashes, Bug 55178.
198 #if defined(OS_WIN)
199 #define MAYBE_PackUnpack DISABLED_PackUnpack
200 #else
201 #define MAYBE_PackUnpack PackUnpack
202 #endif
203 TEST_F(SyncCryptographerTest, MAYBE_PackUnpack) {
204 Nigori nigori;
205 ASSERT_TRUE(nigori.InitByDerivation("example.com", "username", "password"));
206 std::string expected_user, expected_encryption, expected_mac;
207 ASSERT_TRUE(nigori.ExportKeys(&expected_user, &expected_encryption,
208 &expected_mac));
209
210 std::string token;
211 EXPECT_TRUE(cryptographer_.PackBootstrapToken(&nigori, &token));
212 EXPECT_TRUE(IsStringUTF8(token));
213
214 scoped_ptr<Nigori> unpacked(cryptographer_.UnpackBootstrapToken(token));
215 EXPECT_NE(static_cast<Nigori*>(NULL), unpacked.get());
216
217 std::string user_key, encryption_key, mac_key;
218 ASSERT_TRUE(unpacked->ExportKeys(&user_key, &encryption_key, &mac_key));
219
220 EXPECT_EQ(expected_user, user_key);
221 EXPECT_EQ(expected_encryption, encryption_key);
222 EXPECT_EQ(expected_mac, mac_key);
223 }
224
225 TEST_F(SyncCryptographerTest, NigoriEncryptionTypes) {
226 Cryptographer cryptographer2(&encryptor_);
227 sync_pb::NigoriSpecifics nigori;
228
229 StrictMock<MockObserver> observer;
230 cryptographer_.AddObserver(&observer);
231 StrictMock<MockObserver> observer2;
232 cryptographer2.AddObserver(&observer2);
233
234 // Just set the sensitive types (shouldn't trigger any
235 // notifications).
236 ModelTypeSet encrypted_types(Cryptographer::SensitiveTypes());
237 cryptographer_.MergeEncryptedTypesForTest(encrypted_types);
238 cryptographer_.UpdateNigoriFromEncryptedTypes(&nigori);
239 cryptographer2.UpdateEncryptedTypesFromNigori(nigori);
240 EXPECT_TRUE(encrypted_types.Equals(cryptographer_.GetEncryptedTypes()));
241 EXPECT_TRUE(encrypted_types.Equals(cryptographer2.GetEncryptedTypes()));
242
243 Mock::VerifyAndClearExpectations(&observer);
244 Mock::VerifyAndClearExpectations(&observer2);
245
246 EXPECT_CALL(observer,
247 OnEncryptedTypesChanged(
248 HasModelTypes(syncable::ModelTypeSet::All()),
249 false));
250 EXPECT_CALL(observer2,
251 OnEncryptedTypesChanged(
252 HasModelTypes(syncable::ModelTypeSet::All()),
253 false));
254
255 // Set all encrypted types
256 encrypted_types = syncable::ModelTypeSet::All();
257 cryptographer_.MergeEncryptedTypesForTest(encrypted_types);
258 cryptographer_.UpdateNigoriFromEncryptedTypes(&nigori);
259 cryptographer2.UpdateEncryptedTypesFromNigori(nigori);
260 EXPECT_TRUE(encrypted_types.Equals(cryptographer_.GetEncryptedTypes()));
261 EXPECT_TRUE(encrypted_types.Equals(cryptographer2.GetEncryptedTypes()));
262
263 // Receiving an empty nigori should not reset any encrypted types or trigger
264 // an observer notification.
265 Mock::VerifyAndClearExpectations(&observer);
266 nigori = sync_pb::NigoriSpecifics();
267 cryptographer_.UpdateEncryptedTypesFromNigori(nigori);
268 EXPECT_TRUE(encrypted_types.Equals(cryptographer_.GetEncryptedTypes()));
269 }
270
271 TEST_F(SyncCryptographerTest, EncryptEverythingExplicit) {
272 ModelTypeSet real_types = syncable::ModelTypeSet::All();
273 sync_pb::NigoriSpecifics specifics;
274 specifics.set_encrypt_everything(true);
275
276 StrictMock<MockObserver> observer;
277 cryptographer_.AddObserver(&observer);
278
279 EXPECT_CALL(observer,
280 OnEncryptedTypesChanged(
281 HasModelTypes(syncable::ModelTypeSet::All()), true));
282
283 EXPECT_FALSE(cryptographer_.encrypt_everything());
284 ModelTypeSet encrypted_types = cryptographer_.GetEncryptedTypes();
285 for (ModelTypeSet::Iterator iter = real_types.First();
286 iter.Good(); iter.Inc()) {
287 if (iter.Get() == syncable::PASSWORDS || iter.Get() == syncable::NIGORI)
288 EXPECT_TRUE(encrypted_types.Has(iter.Get()));
289 else
290 EXPECT_FALSE(encrypted_types.Has(iter.Get()));
291 }
292
293 cryptographer_.UpdateEncryptedTypesFromNigori(specifics);
294
295 EXPECT_TRUE(cryptographer_.encrypt_everything());
296 encrypted_types = cryptographer_.GetEncryptedTypes();
297 for (ModelTypeSet::Iterator iter = real_types.First();
298 iter.Good(); iter.Inc()) {
299 EXPECT_TRUE(encrypted_types.Has(iter.Get()));
300 }
301
302 // Shouldn't trigger another notification.
303 specifics.set_encrypt_everything(true);
304
305 cryptographer_.RemoveObserver(&observer);
306 }
307
308 TEST_F(SyncCryptographerTest, EncryptEverythingImplicit) {
309 ModelTypeSet real_types = syncable::ModelTypeSet::All();
310 sync_pb::NigoriSpecifics specifics;
311 specifics.set_encrypt_bookmarks(true); // Non-passwords = encrypt everything
312
313 StrictMock<MockObserver> observer;
314 cryptographer_.AddObserver(&observer);
315
316 EXPECT_CALL(observer,
317 OnEncryptedTypesChanged(
318 HasModelTypes(syncable::ModelTypeSet::All()), true));
319
320 EXPECT_FALSE(cryptographer_.encrypt_everything());
321 ModelTypeSet encrypted_types = cryptographer_.GetEncryptedTypes();
322 for (ModelTypeSet::Iterator iter = real_types.First();
323 iter.Good(); iter.Inc()) {
324 if (iter.Get() == syncable::PASSWORDS || iter.Get() == syncable::NIGORI)
325 EXPECT_TRUE(encrypted_types.Has(iter.Get()));
326 else
327 EXPECT_FALSE(encrypted_types.Has(iter.Get()));
328 }
329
330 cryptographer_.UpdateEncryptedTypesFromNigori(specifics);
331
332 EXPECT_TRUE(cryptographer_.encrypt_everything());
333 encrypted_types = cryptographer_.GetEncryptedTypes();
334 for (ModelTypeSet::Iterator iter = real_types.First();
335 iter.Good(); iter.Inc()) {
336 EXPECT_TRUE(encrypted_types.Has(iter.Get()));
337 }
338
339 // Shouldn't trigger another notification.
340 specifics.set_encrypt_everything(true);
341
342 cryptographer_.RemoveObserver(&observer);
343 }
344
345 TEST_F(SyncCryptographerTest, UnknownSensitiveTypes) {
346 ModelTypeSet real_types = syncable::ModelTypeSet::All();
347 sync_pb::NigoriSpecifics specifics;
348 // Explicitly setting encrypt everything should override logic for implicit
349 // encrypt everything.
350 specifics.set_encrypt_everything(false);
351 specifics.set_encrypt_bookmarks(true);
352
353 StrictMock<MockObserver> observer;
354 cryptographer_.AddObserver(&observer);
355
356 syncable::ModelTypeSet expected_encrypted_types =
357 Cryptographer::SensitiveTypes();
358 expected_encrypted_types.Put(syncable::BOOKMARKS);
359
360 EXPECT_CALL(observer,
361 OnEncryptedTypesChanged(
362 HasModelTypes(expected_encrypted_types), false));
363
364 EXPECT_FALSE(cryptographer_.encrypt_everything());
365 ModelTypeSet encrypted_types = cryptographer_.GetEncryptedTypes();
366 for (ModelTypeSet::Iterator iter = real_types.First();
367 iter.Good(); iter.Inc()) {
368 if (iter.Get() == syncable::PASSWORDS || iter.Get() == syncable::NIGORI)
369 EXPECT_TRUE(encrypted_types.Has(iter.Get()));
370 else
371 EXPECT_FALSE(encrypted_types.Has(iter.Get()));
372 }
373
374 cryptographer_.UpdateEncryptedTypesFromNigori(specifics);
375
376 EXPECT_FALSE(cryptographer_.encrypt_everything());
377 encrypted_types = cryptographer_.GetEncryptedTypes();
378 for (ModelTypeSet::Iterator iter = real_types.First();
379 iter.Good(); iter.Inc()) {
380 if (iter.Get() == syncable::PASSWORDS ||
381 iter.Get() == syncable::NIGORI ||
382 iter.Get() == syncable::BOOKMARKS)
383 EXPECT_TRUE(encrypted_types.Has(iter.Get()));
384 else
385 EXPECT_FALSE(encrypted_types.Has(iter.Get()));
386 }
387
388 cryptographer_.RemoveObserver(&observer);
389 }
390
391 } // namespace browser_sync
OLDNEW
« no previous file with comments | « chrome/browser/sync/util/cryptographer.cc ('k') | chrome/browser/sync/util/data_encryption.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698