1// Copyright (c) 2011 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/password_manager/encryptor.h"
12#include "chrome/browser/sync/protocol/password_specifics.pb.h"
13#include "testing/gtest/include/gtest/gtest.h"
14
15namespace browser_sync {
16
17TEST(CryptographerTest, EmptyCantDecrypt) {
18  Cryptographer cryptographer;
19  EXPECT_FALSE(cryptographer.is_ready());
20
21  sync_pb::EncryptedData encrypted;
22  encrypted.set_key_name("foo");
23  encrypted.set_blob("bar");
24
25  EXPECT_FALSE(cryptographer.CanDecrypt(encrypted));
26}
27
28TEST(CryptographerTest, MissingCantDecrypt) {
29  Cryptographer cryptographer;
30
31  KeyParams params = {"localhost", "dummy", "dummy"};
32  cryptographer.AddKey(params);
33  EXPECT_TRUE(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
42TEST(CryptographerTest, CanEncryptAndDecrypt) {
43  Cryptographer cryptographer;
44
45  KeyParams params = {"localhost", "dummy", "dummy"};
46  EXPECT_TRUE(cryptographer.AddKey(params));
47  EXPECT_TRUE(cryptographer.is_ready());
48
49  sync_pb::PasswordSpecificsData original;
50  original.set_origin("http://example.com");
51  original.set_username_value("azure");
52  original.set_password_value("hunter2");
53
54  sync_pb::EncryptedData encrypted;
55  EXPECT_TRUE(cryptographer.Encrypt(original, &encrypted));
56
57  sync_pb::PasswordSpecificsData decrypted;
58  EXPECT_TRUE(cryptographer.Decrypt(encrypted, &decrypted));
59
60  EXPECT_EQ(original.SerializeAsString(), decrypted.SerializeAsString());
61}
62
63TEST(CryptographerTest, AddKeySetsDefault) {
64  Cryptographer cryptographer;
65
66  KeyParams params1 = {"localhost", "dummy", "dummy1"};
67  EXPECT_TRUE(cryptographer.AddKey(params1));
68  EXPECT_TRUE(cryptographer.is_ready());
69
70  sync_pb::PasswordSpecificsData original;
71  original.set_origin("http://example.com");
72  original.set_username_value("azure");
73  original.set_password_value("hunter2");
74
75  sync_pb::EncryptedData encrypted1;
76  EXPECT_TRUE(cryptographer.Encrypt(original, &encrypted1));
77  sync_pb::EncryptedData encrypted2;
78  EXPECT_TRUE(cryptographer.Encrypt(original, &encrypted2));
79
80  KeyParams params2 = {"localhost", "dummy", "dummy2"};
81  EXPECT_TRUE(cryptographer.AddKey(params2));
82  EXPECT_TRUE(cryptographer.is_ready());
83
84  sync_pb::EncryptedData encrypted3;
85  EXPECT_TRUE(cryptographer.Encrypt(original, &encrypted3));
86  sync_pb::EncryptedData encrypted4;
87  EXPECT_TRUE(cryptographer.Encrypt(original, &encrypted4));
88
89  EXPECT_EQ(encrypted1.key_name(), encrypted2.key_name());
90  EXPECT_NE(encrypted1.key_name(), encrypted3.key_name());
91  EXPECT_EQ(encrypted3.key_name(), encrypted4.key_name());
92}
93
94// Crashes, Bug 55178.
95#if defined(OS_WIN)
96#define MAYBE_EncryptExportDecrypt DISABLED_EncryptExportDecrypt
97#else
98#define MAYBE_EncryptExportDecrypt EncryptExportDecrypt
99#endif
100TEST(CryptographerTest, MAYBE_EncryptExportDecrypt) {
101  sync_pb::EncryptedData nigori;
102  sync_pb::EncryptedData encrypted;
103
104  sync_pb::PasswordSpecificsData original;
105  original.set_origin("http://example.com");
106  original.set_username_value("azure");
107  original.set_password_value("hunter2");
108
109  {
110    Cryptographer cryptographer;
111
112    KeyParams params = {"localhost", "dummy", "dummy"};
113    cryptographer.AddKey(params);
114    EXPECT_TRUE(cryptographer.is_ready());
115
116    EXPECT_TRUE(cryptographer.Encrypt(original, &encrypted));
117    EXPECT_TRUE(cryptographer.GetKeys(&nigori));
118  }
119
120  {
121    Cryptographer cryptographer;
122    EXPECT_FALSE(cryptographer.CanDecrypt(nigori));
123
124    cryptographer.SetPendingKeys(nigori);
125    EXPECT_FALSE(cryptographer.is_ready());
126    EXPECT_TRUE(cryptographer.has_pending_keys());
127
128    KeyParams params = {"localhost", "dummy", "dummy"};
129    EXPECT_TRUE(cryptographer.DecryptPendingKeys(params));
130    EXPECT_TRUE(cryptographer.is_ready());
131    EXPECT_FALSE(cryptographer.has_pending_keys());
132
133    sync_pb::PasswordSpecificsData decrypted;
134    EXPECT_TRUE(cryptographer.Decrypt(encrypted, &decrypted));
135    EXPECT_EQ(original.SerializeAsString(), decrypted.SerializeAsString());
136  }
137}
138
139// Crashes, Bug 55178.
140#if defined(OS_WIN)
141#define MAYBE_PackUnpack DISABLED_PackUnpack
142#else
143#define MAYBE_PackUnpack PackUnpack
144#endif
145TEST(CryptographerTest, MAYBE_PackUnpack) {
146#if defined(OS_MACOSX)
147  Encryptor::UseMockKeychain(true);
148#endif
149
150  Nigori nigori;
151  ASSERT_TRUE(nigori.InitByDerivation("example.com", "username", "password"));
152  std::string expected_user, expected_encryption, expected_mac;
153  ASSERT_TRUE(nigori.ExportKeys(&expected_user, &expected_encryption,
154                                &expected_mac));
155
156  Cryptographer cryptographer;
157  std::string token;
158  EXPECT_TRUE(cryptographer.PackBootstrapToken(&nigori, &token));
159  EXPECT_TRUE(IsStringUTF8(token));
160
161  scoped_ptr<Nigori> unpacked(cryptographer.UnpackBootstrapToken(token));
162  EXPECT_NE(static_cast<Nigori*>(NULL), unpacked.get());
163
164  std::string user_key, encryption_key, mac_key;
165  ASSERT_TRUE(unpacked->ExportKeys(&user_key, &encryption_key, &mac_key));
166
167  EXPECT_EQ(expected_user, user_key);
168  EXPECT_EQ(expected_encryption, encryption_key);
169  EXPECT_EQ(expected_mac, mac_key);
170}
171
172}  // namespace browser_sync
173