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/nigori.h"
6
7#include <string>
8
9#include "base/memory/scoped_ptr.h"
10#include "base/strings/string_util.h"
11#include "testing/gtest/include/gtest/gtest.h"
12
13namespace syncer {
14namespace {
15
16TEST(SyncNigoriTest, Permute) {
17  Nigori nigori;
18  EXPECT_TRUE(nigori.InitByDerivation("example.com", "username", "password"));
19
20  std::string permuted;
21  EXPECT_TRUE(nigori.Permute(Nigori::Password, "test name",
22                             &permuted));
23
24  std::string expected =
25      "prewwdJj2PrGDczvmsHJEE5ndcCyVze8sY9kD5hjY/Tm"
26      "c5kOjXFK7zB3Ss4LlHjEDirMu+vh85JwHOnGrMVe+g==";
27  EXPECT_EQ(expected, permuted);
28}
29
30TEST(SyncNigoriTest, PermuteIsConstant) {
31  Nigori nigori1;
32  EXPECT_TRUE(nigori1.InitByDerivation("example.com", "username", "password"));
33
34  std::string permuted1;
35  EXPECT_TRUE(nigori1.Permute(Nigori::Password,
36                              "name",
37                              &permuted1));
38
39  Nigori nigori2;
40  EXPECT_TRUE(nigori2.InitByDerivation("example.com", "username", "password"));
41
42  std::string permuted2;
43  EXPECT_TRUE(nigori2.Permute(Nigori::Password,
44                              "name",
45                              &permuted2));
46
47  EXPECT_LT(0U, permuted1.size());
48  EXPECT_EQ(permuted1, permuted2);
49}
50
51TEST(SyncNigoriTest, EncryptDifferentIv) {
52  Nigori nigori;
53  EXPECT_TRUE(nigori.InitByDerivation("example.com", "username", "password"));
54
55  std::string plaintext("value");
56
57  std::string encrypted1;
58  EXPECT_TRUE(nigori.Encrypt(plaintext, &encrypted1));
59
60  std::string encrypted2;
61  EXPECT_TRUE(nigori.Encrypt(plaintext, &encrypted2));
62
63  EXPECT_NE(encrypted1, encrypted2);
64}
65
66TEST(SyncNigoriTest, Decrypt) {
67  Nigori nigori;
68  EXPECT_TRUE(nigori.InitByDerivation("example.com", "username", "password"));
69
70  std::string encrypted =
71      "e7+JyS6ibj6F5qqvpseukNRTZ+oBpu5iuv2VYjOfrH1dNiFLNf7Ov0"
72      "kx/zicKFn0lJcbG1UmkNWqIuR4x+quDNVuLaZGbrJPhrJuj7cokCM=";
73
74  std::string plaintext;
75  EXPECT_TRUE(nigori.Decrypt(encrypted, &plaintext));
76
77  std::string expected("test, test, 1, 2, 3");
78  EXPECT_EQ(expected, plaintext);
79}
80
81TEST(SyncNigoriTest, EncryptDecrypt) {
82  Nigori nigori;
83  EXPECT_TRUE(nigori.InitByDerivation("example.com", "username", "password"));
84
85  std::string plaintext("value");
86
87  std::string encrypted;
88  EXPECT_TRUE(nigori.Encrypt(plaintext, &encrypted));
89
90  std::string decrypted;
91  EXPECT_TRUE(nigori.Decrypt(encrypted, &decrypted));
92
93  EXPECT_EQ(plaintext, decrypted);
94}
95
96TEST(SyncNigoriTest, CorruptedIv) {
97  Nigori nigori;
98  EXPECT_TRUE(nigori.InitByDerivation("example.com", "username", "password"));
99
100  std::string plaintext("test");
101
102  std::string encrypted;
103  EXPECT_TRUE(nigori.Encrypt(plaintext, &encrypted));
104
105  // Corrupt the IV by changing one of its byte.
106  encrypted[0] = (encrypted[0] == 'a' ? 'b' : 'a');
107
108  std::string decrypted;
109  EXPECT_TRUE(nigori.Decrypt(encrypted, &decrypted));
110
111  EXPECT_NE(plaintext, decrypted);
112}
113
114TEST(SyncNigoriTest, CorruptedCiphertext) {
115  Nigori nigori;
116  EXPECT_TRUE(nigori.InitByDerivation("example.com", "username", "password"));
117
118  std::string plaintext("test");
119
120  std::string encrypted;
121  EXPECT_TRUE(nigori.Encrypt(plaintext, &encrypted));
122
123  // Corrput the ciphertext by changing one of its bytes.
124  encrypted[Nigori::kIvSize + 10] =
125      (encrypted[Nigori::kIvSize + 10] == 'a' ? 'b' : 'a');
126
127  std::string decrypted;
128  EXPECT_FALSE(nigori.Decrypt(encrypted, &decrypted));
129
130  EXPECT_NE(plaintext, decrypted);
131}
132
133// Crashes, Bug 55180.
134#if defined(OS_WIN)
135#define MAYBE_ExportImport DISABLED_ExportImport
136#else
137#define MAYBE_ExportImport ExportImport
138#endif
139TEST(SyncNigoriTest, MAYBE_ExportImport) {
140  Nigori nigori1;
141  EXPECT_TRUE(nigori1.InitByDerivation("example.com", "username", "password"));
142
143  std::string user_key;
144  std::string encryption_key;
145  std::string mac_key;
146  EXPECT_TRUE(nigori1.ExportKeys(&user_key, &encryption_key, &mac_key));
147
148  Nigori nigori2;
149  EXPECT_TRUE(nigori2.InitByImport(user_key, encryption_key, mac_key));
150
151  std::string original("test");
152  std::string plaintext;
153  std::string ciphertext;
154
155  EXPECT_TRUE(nigori1.Encrypt(original, &ciphertext));
156  EXPECT_TRUE(nigori2.Decrypt(ciphertext, &plaintext));
157  EXPECT_EQ(original, plaintext);
158
159  EXPECT_TRUE(nigori2.Encrypt(original, &ciphertext));
160  EXPECT_TRUE(nigori1.Decrypt(ciphertext, &plaintext));
161  EXPECT_EQ(original, plaintext);
162
163  std::string permuted1, permuted2;
164  EXPECT_TRUE(nigori1.Permute(Nigori::Password, original, &permuted1));
165  EXPECT_TRUE(nigori2.Permute(Nigori::Password, original, &permuted2));
166  EXPECT_EQ(permuted1, permuted2);
167}
168
169}  // anonymous namespace
170}  // namespace syncer
171