Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / sync / util / cryptographer_unittest.cc
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 "sync/util/cryptographer.h"
6
7 #include <string>
8
9 #include "base/memory/scoped_ptr.h"
10 #include "base/strings/string_util.h"
11 #include "sync/protocol/password_specifics.pb.h"
12 #include "sync/test/fake_encryptor.h"
13 #include "testing/gmock/include/gmock/gmock.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 namespace syncer {
17
18 namespace {
19
20 using ::testing::_;
21
22 }  // namespace
23
24 class CryptographerTest : public ::testing::Test {
25  protected:
26   CryptographerTest() : cryptographer_(&encryptor_) {}
27
28   FakeEncryptor encryptor_;
29   Cryptographer cryptographer_;
30 };
31
32 TEST_F(CryptographerTest, EmptyCantDecrypt) {
33   EXPECT_FALSE(cryptographer_.is_ready());
34
35   sync_pb::EncryptedData encrypted;
36   encrypted.set_key_name("foo");
37   encrypted.set_blob("bar");
38
39   EXPECT_FALSE(cryptographer_.CanDecrypt(encrypted));
40 }
41
42 TEST_F(CryptographerTest, EmptyCantEncrypt) {
43   EXPECT_FALSE(cryptographer_.is_ready());
44
45   sync_pb::EncryptedData encrypted;
46   sync_pb::PasswordSpecificsData original;
47   EXPECT_FALSE(cryptographer_.Encrypt(original, &encrypted));
48 }
49
50 TEST_F(CryptographerTest, MissingCantDecrypt) {
51   KeyParams params = {"localhost", "dummy", "dummy"};
52   cryptographer_.AddKey(params);
53   EXPECT_TRUE(cryptographer_.is_ready());
54
55   sync_pb::EncryptedData encrypted;
56   encrypted.set_key_name("foo");
57   encrypted.set_blob("bar");
58
59   EXPECT_FALSE(cryptographer_.CanDecrypt(encrypted));
60 }
61
62 TEST_F(CryptographerTest, CanEncryptAndDecrypt) {
63   KeyParams params = {"localhost", "dummy", "dummy"};
64   EXPECT_TRUE(cryptographer_.AddKey(params));
65   EXPECT_TRUE(cryptographer_.is_ready());
66
67   sync_pb::PasswordSpecificsData original;
68   original.set_origin("http://example.com");
69   original.set_username_value("azure");
70   original.set_password_value("hunter2");
71
72   sync_pb::EncryptedData encrypted;
73   EXPECT_TRUE(cryptographer_.Encrypt(original, &encrypted));
74
75   sync_pb::PasswordSpecificsData decrypted;
76   EXPECT_TRUE(cryptographer_.Decrypt(encrypted, &decrypted));
77
78   EXPECT_EQ(original.SerializeAsString(), decrypted.SerializeAsString());
79 }
80
81 TEST_F(CryptographerTest, EncryptOnlyIfDifferent) {
82   KeyParams params = {"localhost", "dummy", "dummy"};
83   EXPECT_TRUE(cryptographer_.AddKey(params));
84   EXPECT_TRUE(cryptographer_.is_ready());
85
86   sync_pb::PasswordSpecificsData original;
87   original.set_origin("http://example.com");
88   original.set_username_value("azure");
89   original.set_password_value("hunter2");
90
91   sync_pb::EncryptedData encrypted;
92   EXPECT_TRUE(cryptographer_.Encrypt(original, &encrypted));
93
94   sync_pb::EncryptedData encrypted2, encrypted3;
95   encrypted2.CopyFrom(encrypted);
96   encrypted3.CopyFrom(encrypted);
97   EXPECT_TRUE(cryptographer_.Encrypt(original, &encrypted2));
98
99   // Now encrypt with a new default key. Should overwrite the old data.
100   KeyParams params_new = {"localhost", "dummy", "dummy2"};
101   cryptographer_.AddKey(params_new);
102   EXPECT_TRUE(cryptographer_.Encrypt(original, &encrypted3));
103
104   sync_pb::PasswordSpecificsData decrypted;
105   EXPECT_TRUE(cryptographer_.Decrypt(encrypted2, &decrypted));
106   // encrypted2 should match encrypted, encrypted3 should not (due to salting).
107   EXPECT_EQ(encrypted.SerializeAsString(), encrypted2.SerializeAsString());
108   EXPECT_NE(encrypted.SerializeAsString(), encrypted3.SerializeAsString());
109   EXPECT_EQ(original.SerializeAsString(), decrypted.SerializeAsString());
110 }
111
112 TEST_F(CryptographerTest, AddKeySetsDefault) {
113   KeyParams params1 = {"localhost", "dummy", "dummy1"};
114   EXPECT_TRUE(cryptographer_.AddKey(params1));
115   EXPECT_TRUE(cryptographer_.is_ready());
116
117   sync_pb::PasswordSpecificsData original;
118   original.set_origin("http://example.com");
119   original.set_username_value("azure");
120   original.set_password_value("hunter2");
121
122   sync_pb::EncryptedData encrypted1;
123   EXPECT_TRUE(cryptographer_.Encrypt(original, &encrypted1));
124   sync_pb::EncryptedData encrypted2;
125   EXPECT_TRUE(cryptographer_.Encrypt(original, &encrypted2));
126
127   KeyParams params2 = {"localhost", "dummy", "dummy2"};
128   EXPECT_TRUE(cryptographer_.AddKey(params2));
129   EXPECT_TRUE(cryptographer_.is_ready());
130
131   sync_pb::EncryptedData encrypted3;
132   EXPECT_TRUE(cryptographer_.Encrypt(original, &encrypted3));
133   sync_pb::EncryptedData encrypted4;
134   EXPECT_TRUE(cryptographer_.Encrypt(original, &encrypted4));
135
136   EXPECT_EQ(encrypted1.key_name(), encrypted2.key_name());
137   EXPECT_NE(encrypted1.key_name(), encrypted3.key_name());
138   EXPECT_EQ(encrypted3.key_name(), encrypted4.key_name());
139 }
140
141 // Crashes, Bug 55178.
142 #if defined(OS_WIN)
143 #define MAYBE_EncryptExportDecrypt DISABLED_EncryptExportDecrypt
144 #else
145 #define MAYBE_EncryptExportDecrypt EncryptExportDecrypt
146 #endif
147 TEST_F(CryptographerTest, MAYBE_EncryptExportDecrypt) {
148   sync_pb::EncryptedData nigori;
149   sync_pb::EncryptedData encrypted;
150
151   sync_pb::PasswordSpecificsData original;
152   original.set_origin("http://example.com");
153   original.set_username_value("azure");
154   original.set_password_value("hunter2");
155
156   {
157     Cryptographer cryptographer(&encryptor_);
158
159     KeyParams params = {"localhost", "dummy", "dummy"};
160     cryptographer.AddKey(params);
161     EXPECT_TRUE(cryptographer.is_ready());
162
163     EXPECT_TRUE(cryptographer.Encrypt(original, &encrypted));
164     EXPECT_TRUE(cryptographer.GetKeys(&nigori));
165   }
166
167   {
168     Cryptographer cryptographer(&encryptor_);
169     EXPECT_FALSE(cryptographer.CanDecrypt(nigori));
170
171     cryptographer.SetPendingKeys(nigori);
172     EXPECT_FALSE(cryptographer.is_ready());
173     EXPECT_TRUE(cryptographer.has_pending_keys());
174
175     KeyParams params = {"localhost", "dummy", "dummy"};
176     EXPECT_TRUE(cryptographer.DecryptPendingKeys(params));
177     EXPECT_TRUE(cryptographer.is_ready());
178     EXPECT_FALSE(cryptographer.has_pending_keys());
179
180     sync_pb::PasswordSpecificsData decrypted;
181     EXPECT_TRUE(cryptographer.Decrypt(encrypted, &decrypted));
182     EXPECT_EQ(original.SerializeAsString(), decrypted.SerializeAsString());
183   }
184 }
185
186 TEST_F(CryptographerTest, Bootstrap) {
187   KeyParams params = {"localhost", "dummy", "dummy"};
188   cryptographer_.AddKey(params);
189
190   std::string token;
191   EXPECT_TRUE(cryptographer_.GetBootstrapToken(&token));
192   EXPECT_TRUE(base::IsStringUTF8(token));
193
194   Cryptographer other_cryptographer(&encryptor_);
195   other_cryptographer.Bootstrap(token);
196   EXPECT_TRUE(other_cryptographer.is_ready());
197
198   const char secret[] = "secret";
199   sync_pb::EncryptedData encrypted;
200   EXPECT_TRUE(other_cryptographer.EncryptString(secret, &encrypted));
201   EXPECT_TRUE(cryptographer_.CanDecryptUsingDefaultKey(encrypted));
202 }
203
204 // Verifies that copied cryptographers are just as good as the original.
205 //
206 // Encrypt an item using the original cryptographer and two different sets of
207 // keys.  Verify that it can decrypt them.
208 //
209 // Then copy the original cryptographer and ensure it can also decrypt these
210 // items and encrypt them with the most recent key.
211 TEST_F(CryptographerTest, CopyConstructor) {
212   sync_pb::PasswordSpecificsData original;
213   original.set_origin("http://example.com");
214   original.set_username_value("luser");
215   original.set_password_value("p4ssw0rd");
216
217   // Start by testing the original cryptogprapher.
218   KeyParams params1 = {"localhost", "dummy", "dummy"};
219   EXPECT_TRUE(cryptographer_.AddKey(params1));
220   EXPECT_TRUE(cryptographer_.is_ready());
221
222   sync_pb::EncryptedData encrypted_k1;
223   EXPECT_TRUE(cryptographer_.Encrypt(original, &encrypted_k1));
224
225   KeyParams params2 = {"localhost", "fatuous", "fatuous"};
226   EXPECT_TRUE(cryptographer_.AddKey(params2));
227   EXPECT_TRUE(cryptographer_.is_ready());
228
229   sync_pb::EncryptedData encrypted_k2;
230   EXPECT_TRUE(cryptographer_.Encrypt(original, &encrypted_k2));
231
232   sync_pb::PasswordSpecificsData decrypted_k1;
233   sync_pb::PasswordSpecificsData decrypted_k2;
234   EXPECT_TRUE(cryptographer_.Decrypt(encrypted_k1, &decrypted_k1));
235   EXPECT_TRUE(cryptographer_.Decrypt(encrypted_k2, &decrypted_k2));
236
237   EXPECT_EQ(original.SerializeAsString(), decrypted_k1.SerializeAsString());
238   EXPECT_EQ(original.SerializeAsString(), decrypted_k2.SerializeAsString());
239
240   // Clone the cryptographer and test that it behaves the same.
241   Cryptographer cryptographer_clone(cryptographer_);
242
243   // The clone should be able to decrypt with old and new keys.
244   sync_pb::PasswordSpecificsData decrypted_k1_clone;
245   sync_pb::PasswordSpecificsData decrypted_k2_clone;
246   EXPECT_TRUE(cryptographer_clone.Decrypt(encrypted_k1, &decrypted_k1_clone));
247   EXPECT_TRUE(cryptographer_clone.Decrypt(encrypted_k2, &decrypted_k2_clone));
248
249   EXPECT_EQ(original.SerializeAsString(),
250             decrypted_k1_clone.SerializeAsString());
251   EXPECT_EQ(original.SerializeAsString(),
252             decrypted_k2_clone.SerializeAsString());
253
254   // The old cryptographer should be able to decrypt things encrypted by the
255   // new.
256   sync_pb::EncryptedData encrypted_c;
257   EXPECT_TRUE(cryptographer_clone.Encrypt(original, &encrypted_c));
258
259   sync_pb::PasswordSpecificsData decrypted_c;
260   EXPECT_TRUE(cryptographer_.Decrypt(encrypted_c, &decrypted_c));
261   EXPECT_EQ(original.SerializeAsString(), decrypted_c.SerializeAsString());
262
263   // The cloned cryptographer should be using the latest key.
264   EXPECT_EQ(encrypted_c.key_name(), encrypted_k2.key_name());
265 }
266
267 }  // namespace syncer