Chromium Code Reviews| Index: content/browser/net/sqlite_persistent_cookie_store_unittest.cc |
| diff --git a/content/browser/net/sqlite_persistent_cookie_store_unittest.cc b/content/browser/net/sqlite_persistent_cookie_store_unittest.cc |
| index 4adb7906685e43301a6602d5091fd5f4de90ffef..97c2b10d3b33afbe9890a275f1a97049343cd23a 100644 |
| --- a/content/browser/net/sqlite_persistent_cookie_store_unittest.cc |
| +++ b/content/browser/net/sqlite_persistent_cookie_store_unittest.cc |
| @@ -19,6 +19,10 @@ |
| #include "base/test/sequenced_worker_pool_owner.h" |
| #include "base/threading/sequenced_worker_pool.h" |
| #include "base/time/time.h" |
| +#include "content/public/browser/cookie_crypto_delegate.h" |
| +#include "content/public/browser/cookie_store_factory.h" |
| +#include "crypto/encryptor.h" |
| +#include "crypto/symmetric_key.h" |
| #include "net/cookies/canonical_cookie.h" |
| #include "net/cookies/cookie_constants.h" |
| #include "sql/connection.h" |
| @@ -32,6 +36,36 @@ namespace { |
| const base::FilePath::CharType kCookieFilename[] = FILE_PATH_LITERAL("Cookies"); |
| +class CookieCryptor : public content::CookieCryptoDelegate { |
| + public: |
| + CookieCryptor(); |
| + virtual bool EncryptString(const std::string& plaintext, |
| + std::string* ciphertext) OVERRIDE; |
| + virtual bool DecryptString(const std::string& ciphertext, |
| + std::string* plaintext) OVERRIDE; |
| + |
| + private: |
| + scoped_ptr<crypto::SymmetricKey> key_; |
| + crypto::Encryptor encryptor_; |
| +}; |
| + |
| +CookieCryptor::CookieCryptor() : key_( |
| + crypto::SymmetricKey::DeriveKeyFromPassword( |
| + crypto::SymmetricKey::AES, "password", "saltiest", 1000, 256)) { |
| + std::string iv("the iv: 16 bytes"); |
| + encryptor_.Init(key_.get(), crypto::Encryptor::CBC, iv); |
| +} |
| + |
| +bool CookieCryptor::EncryptString(const std::string& plaintext, |
| + std::string* ciphertext) { |
| + return encryptor_.Encrypt(plaintext, ciphertext); |
| +} |
| + |
| +bool CookieCryptor::DecryptString(const std::string& ciphertext, |
| + std::string* plaintext) { |
| + return encryptor_.Decrypt(ciphertext, plaintext); |
| +} |
| + |
| } // namespace |
| typedef std::vector<net::CanonicalCookie*> CanonicalCookieVector; |
| @@ -90,20 +124,22 @@ class SQLitePersistentCookieStoreTest : public testing::Test { |
| pool_owner_.reset(new base::SequencedWorkerPoolOwner(3, "Background Pool")); |
| } |
| - void CreateAndLoad(bool restore_old_session_cookies, |
| + void CreateAndLoad(bool crypt_cookies, |
| + bool restore_old_session_cookies, |
| CanonicalCookieVector* cookies) { |
| store_ = new SQLitePersistentCookieStore( |
| temp_dir_.path().Append(kCookieFilename), |
| client_task_runner(), |
| background_task_runner(), |
| restore_old_session_cookies, |
| - NULL); |
| + NULL, |
| + crypt_cookies ? new CookieCryptor : NULL); |
| Load(cookies); |
| } |
| - void InitializeStore(bool restore_old_session_cookies) { |
| + void InitializeStore(bool crypt, bool restore_old_session_cookies) { |
|
Scott Hess - ex-Googler
2013/10/08 17:35:55
VERY easy to get your bools in the wrong order for
|
| CanonicalCookieVector cookies; |
| - CreateAndLoad(restore_old_session_cookies, &cookies); |
| + CreateAndLoad(crypt, restore_old_session_cookies, &cookies); |
| EXPECT_EQ(0U, cookies.size()); |
| } |
| @@ -146,13 +182,13 @@ class SQLitePersistentCookieStoreTest : public testing::Test { |
| }; |
| TEST_F(SQLitePersistentCookieStoreTest, TestInvalidMetaTableRecovery) { |
| - InitializeStore(false); |
| + InitializeStore(false, false); |
| AddCookie("A", "B", "foo.bar", "/", base::Time::Now()); |
| DestroyStore(); |
| // Load up the store and verify that it has good data in it. |
| CanonicalCookieVector cookies; |
| - CreateAndLoad(false, &cookies); |
| + CreateAndLoad(false, false, &cookies); |
| ASSERT_EQ(1U, cookies.size()); |
| ASSERT_STREQ("foo.bar", cookies[0]->Domain().c_str()); |
| ASSERT_STREQ("A", cookies[0]->Name().c_str()); |
| @@ -171,13 +207,13 @@ TEST_F(SQLitePersistentCookieStoreTest, TestInvalidMetaTableRecovery) { |
| } |
| // Upon loading, the database should be reset to a good, blank state. |
| - CreateAndLoad(false, &cookies); |
| + CreateAndLoad(false, false, &cookies); |
| ASSERT_EQ(0U, cookies.size()); |
| // Verify that, after, recovery, the database persists properly. |
| AddCookie("X", "Y", "foo.bar", "/", base::Time::Now()); |
| DestroyStore(); |
| - CreateAndLoad(false, &cookies); |
| + CreateAndLoad(false, false, &cookies); |
| ASSERT_EQ(1U, cookies.size()); |
| ASSERT_STREQ("foo.bar", cookies[0]->Domain().c_str()); |
| ASSERT_STREQ("X", cookies[0]->Name().c_str()); |
| @@ -187,7 +223,7 @@ TEST_F(SQLitePersistentCookieStoreTest, TestInvalidMetaTableRecovery) { |
| // Test if data is stored as expected in the SQLite database. |
| TEST_F(SQLitePersistentCookieStoreTest, TestPersistance) { |
| - InitializeStore(false); |
| + InitializeStore(false, false); |
| AddCookie("A", "B", "foo.bar", "/", base::Time::Now()); |
| // Replace the store effectively destroying the current one and forcing it |
| // to write its data to disk. Then we can see if after loading it again it |
| @@ -195,7 +231,7 @@ TEST_F(SQLitePersistentCookieStoreTest, TestPersistance) { |
| DestroyStore(); |
| // Reload and test for persistence |
| CanonicalCookieVector cookies; |
| - CreateAndLoad(false, &cookies); |
| + CreateAndLoad(false, false, &cookies); |
| ASSERT_EQ(1U, cookies.size()); |
| ASSERT_STREQ("foo.bar", cookies[0]->Domain().c_str()); |
| ASSERT_STREQ("A", cookies[0]->Name().c_str()); |
| @@ -207,14 +243,14 @@ TEST_F(SQLitePersistentCookieStoreTest, TestPersistance) { |
| STLDeleteElements(&cookies); |
| // Reload and check if the cookie has been removed. |
| - CreateAndLoad(false, &cookies); |
| + CreateAndLoad(false, false, &cookies); |
| ASSERT_EQ(0U, cookies.size()); |
| } |
| // Test that priority load of cookies for a specfic domain key could be |
| // completed before the entire store is loaded |
| TEST_F(SQLitePersistentCookieStoreTest, TestLoadCookiesForKey) { |
| - InitializeStore(false); |
| + InitializeStore(false, false); |
| base::Time t = base::Time::Now(); |
| AddCookie("A", "B", "foo.bar", "/", t); |
| t += base::TimeDelta::FromInternalValue(10); |
| @@ -229,7 +265,7 @@ TEST_F(SQLitePersistentCookieStoreTest, TestLoadCookiesForKey) { |
| temp_dir_.path().Append(kCookieFilename), |
| client_task_runner(), |
| background_task_runner(), |
| - false, NULL); |
| + false, NULL, NULL); |
| // Posting a blocking task to db_thread_ makes sure that the DB thread waits |
| // until both Load and LoadCookiesForKey have been posted to its task queue. |
| background_task_runner()->PostTask( |
| @@ -284,7 +320,7 @@ TEST_F(SQLitePersistentCookieStoreTest, TestLoadCookiesForKey) { |
| // Test that we can force the database to be written by calling Flush(). |
| TEST_F(SQLitePersistentCookieStoreTest, TestFlush) { |
| - InitializeStore(false); |
| + InitializeStore(false, false); |
| // File timestamps don't work well on all platforms, so we'll determine |
| // whether the DB file has been modified by checking its size. |
| base::FilePath path = temp_dir_.path().Append(kCookieFilename); |
| @@ -310,7 +346,7 @@ TEST_F(SQLitePersistentCookieStoreTest, TestFlush) { |
| // Test loading old session cookies from the disk. |
| TEST_F(SQLitePersistentCookieStoreTest, TestLoadOldSessionCookies) { |
| - InitializeStore(true); |
| + InitializeStore(false, true); |
| // Add a session cookie. |
| store_->AddCookie( |
| @@ -325,7 +361,7 @@ TEST_F(SQLitePersistentCookieStoreTest, TestLoadOldSessionCookies) { |
| // Create a store that loads session cookies and test that the session cookie |
| // was loaded. |
| CanonicalCookieVector cookies; |
| - CreateAndLoad(true, &cookies); |
| + CreateAndLoad(false, true, &cookies); |
| ASSERT_EQ(1U, cookies.size()); |
| ASSERT_STREQ("sessioncookie.com", cookies[0]->Domain().c_str()); |
| @@ -338,7 +374,7 @@ TEST_F(SQLitePersistentCookieStoreTest, TestLoadOldSessionCookies) { |
| // Test loading old session cookies from the disk. |
| TEST_F(SQLitePersistentCookieStoreTest, TestDontLoadOldSessionCookies) { |
| - InitializeStore(true); |
| + InitializeStore(false, true); |
| // Add a session cookie. |
| store_->AddCookie( |
| @@ -353,7 +389,7 @@ TEST_F(SQLitePersistentCookieStoreTest, TestDontLoadOldSessionCookies) { |
| // Create a store that doesn't load old session cookies and test that the |
| // session cookie was not loaded. |
| CanonicalCookieVector cookies; |
| - CreateAndLoad(false, &cookies); |
| + CreateAndLoad(false, false, &cookies); |
| ASSERT_EQ(0U, cookies.size()); |
| // The store should also delete the session cookie. Wait until that has been |
| @@ -362,12 +398,12 @@ TEST_F(SQLitePersistentCookieStoreTest, TestDontLoadOldSessionCookies) { |
| // Create a store that loads old session cookies and test that the session |
| // cookie is gone. |
| - CreateAndLoad(true, &cookies); |
| + CreateAndLoad(false, true, &cookies); |
| ASSERT_EQ(0U, cookies.size()); |
| } |
| TEST_F(SQLitePersistentCookieStoreTest, PersistIsPersistent) { |
| - InitializeStore(true); |
| + InitializeStore(false, true); |
| static const char kSessionName[] = "session"; |
| static const char kPersistentName[] = "persistent"; |
| @@ -392,7 +428,7 @@ TEST_F(SQLitePersistentCookieStoreTest, PersistIsPersistent) { |
| // Create a store that loads session cookie and test that the IsPersistent |
| // attribute is restored. |
| CanonicalCookieVector cookies; |
| - CreateAndLoad(true, &cookies); |
| + CreateAndLoad(false, true, &cookies); |
| ASSERT_EQ(2U, cookies.size()); |
| std::map<std::string, net::CanonicalCookie*> cookie_map; |
| @@ -422,7 +458,7 @@ TEST_F(SQLitePersistentCookieStoreTest, PriorityIsPersistent) { |
| static const char kCookieValue[] = "value"; |
| static const char kCookiePath[] = "/"; |
| - InitializeStore(true); |
| + InitializeStore(false, true); |
| // Add a low-priority persistent cookie. |
| store_->AddCookie( |
| @@ -457,7 +493,7 @@ TEST_F(SQLitePersistentCookieStoreTest, PriorityIsPersistent) { |
| // Create a store that loads session cookie and test that the priority |
| // attribute values are restored. |
| CanonicalCookieVector cookies; |
| - CreateAndLoad(true, &cookies); |
| + CreateAndLoad(false, true, &cookies); |
| ASSERT_EQ(3U, cookies.size()); |
| // Put the cookies into a map, by name, so we can easily find them. |
| @@ -485,4 +521,41 @@ TEST_F(SQLitePersistentCookieStoreTest, PriorityIsPersistent) { |
| STLDeleteElements(&cookies); |
| } |
| +TEST_F(SQLitePersistentCookieStoreTest, UpdateToEncryption) { |
| + CanonicalCookieVector cookies; |
| + |
| + // Create unencrypted cookie store and write something to it. |
| + InitializeStore(false, false); |
| + AddCookie("name", "value", "foo.bar", "/", base::Time::Now()); |
| + DestroyStore(); |
| + |
| + // Create encrypted cookie store and ensure old cookie still reads. |
| + STLDeleteElements(&cookies_); |
| + EXPECT_EQ(0U, cookies_.size()); |
| + CreateAndLoad(true, false, &cookies); |
| + EXPECT_EQ(1U, cookies_.size()); |
| + EXPECT_EQ("name", cookies_[0]->Name()); |
| + EXPECT_EQ("value", cookies_[0]->Value()); |
| + |
| + // Make sure we can update existing cookie and add new cookie as encrypted. |
| + store_->DeleteCookie(*(cookies_[0])); |
| + AddCookie("name", "encrypted_value", "foo.bar", "/", base::Time::Now()); |
| + AddCookie("other", "something", "foo.bar", "/", base::Time::Now()); |
| + DestroyStore(); |
| + STLDeleteElements(&cookies_); |
| + CreateAndLoad(true, false, &cookies); |
| + EXPECT_EQ(2U, cookies_.size()); |
| + net::CanonicalCookie* cookie_name = NULL; |
| + net::CanonicalCookie* cookie_other = NULL; |
| + if (cookies_[0]->Name() == "name") { |
| + cookie_name = cookies_[0]; |
| + cookie_other = cookies_[1]; |
| + } else { |
| + cookie_name = cookies_[1]; |
| + cookie_other = cookies_[0]; |
| + } |
| + EXPECT_EQ("encrypted_value", cookie_name->Value()); |
| + EXPECT_EQ("something", cookie_other->Value()); |
| +} |
| + |
| } // namespace content |