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 } // namespace syncer 205