Home | History | Annotate | Download | only in util
      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