diff options
author | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-28 21:52:15 +0000 |
---|---|---|
committer | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-28 21:52:15 +0000 |
commit | 708f3b3ad64ea2f445ac975d9301db9304214d54 (patch) | |
tree | 052c9bd9641ccb7d665ac88ac0178ac2f095a583 | |
parent | cb5ecc0936ab4862807442dd08486f1d434b8596 (diff) | |
download | chromium_src-708f3b3ad64ea2f445ac975d9301db9304214d54.zip chromium_src-708f3b3ad64ea2f445ac975d9301db9304214d54.tar.gz chromium_src-708f3b3ad64ea2f445ac975d9301db9304214d54.tar.bz2 |
Revert 94553 - Provides in memory and persistent storage for origin bound certificates, which are
specified at http://balfanz.github.com/tls-obc-spec/draft-balfanz-tls-obc-00.html.
The code is based on cookie_monster.{cc,h} and sqlite_persistent_cookie_store.{cc,h}.
BUG=88782
TEST=None
Review URL: http://codereview.chromium.org/7342021
TBR=rkn@chromium.org
Review URL: http://codereview.chromium.org/7523039
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@94555 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/net/sqlite_origin_bound_cert_store.cc | 404 | ||||
-rw-r--r-- | chrome/browser/net/sqlite_origin_bound_cert_store.h | 44 | ||||
-rw-r--r-- | chrome/browser/net/sqlite_origin_bound_cert_store_unittest.cc | 175 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 2 | ||||
-rw-r--r-- | chrome/chrome_tests.gypi | 1 | ||||
-rw-r--r-- | chrome/common/chrome_constants.cc | 1 | ||||
-rw-r--r-- | chrome/common/chrome_constants.h | 1 | ||||
-rw-r--r-- | net/base/default_origin_bound_cert_store.cc | 137 | ||||
-rw-r--r-- | net/base/default_origin_bound_cert_store.h | 163 | ||||
-rw-r--r-- | net/base/default_origin_bound_cert_store_unittest.cc | 112 | ||||
-rw-r--r-- | net/base/origin_bound_cert_service.cc | 29 | ||||
-rw-r--r-- | net/base/origin_bound_cert_service.h | 23 | ||||
-rw-r--r-- | net/base/origin_bound_cert_service_unittest.cc | 68 | ||||
-rw-r--r-- | net/base/origin_bound_cert_store.h | 25 | ||||
-rw-r--r-- | net/net.gyp | 4 |
15 files changed, 25 insertions, 1164 deletions
diff --git a/chrome/browser/net/sqlite_origin_bound_cert_store.cc b/chrome/browser/net/sqlite_origin_bound_cert_store.cc deleted file mode 100644 index 9e77277..0000000 --- a/chrome/browser/net/sqlite_origin_bound_cert_store.cc +++ /dev/null @@ -1,404 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/net/sqlite_origin_bound_cert_store.h" - -#include <list> - -#include "base/basictypes.h" -#include "base/file_path.h" -#include "base/file_util.h" -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/string_util.h" -#include "base/threading/thread.h" -#include "base/threading/thread_restrictions.h" -#include "chrome/browser/diagnostics/sqlite_diagnostics.h" -#include "content/browser/browser_thread.h" -#include "sql/meta_table.h" -#include "sql/statement.h" -#include "sql/transaction.h" - -// This class is designed to be shared between any calling threads and the -// database thread. It batches operations and commits them on a timer. -class SQLiteOriginBoundCertStore::Backend - : public base::RefCountedThreadSafe<SQLiteOriginBoundCertStore::Backend> { - public: - explicit Backend(const FilePath& path) - : path_(path), - db_(NULL), - num_pending_(0), - clear_local_state_on_exit_(false) { - } - - // Creates or load the SQLite database. - bool Load( - std::vector<net::DefaultOriginBoundCertStore::OriginBoundCert*>* certs); - - // Batch an origin bound cert addition. - void AddOriginBoundCert( - const net::DefaultOriginBoundCertStore::OriginBoundCert& cert); - - // Batch an origin bound cert deletion. - void DeleteOriginBoundCert( - const net::DefaultOriginBoundCertStore::OriginBoundCert& cert); - - // Commit pending operations as soon as possible. - void Flush(Task* completion_task); - - // Commit any pending operations and close the database. This must be called - // before the object is destructed. - void Close(); - - void SetClearLocalStateOnExit(bool clear_local_state); - - private: - friend class base::RefCountedThreadSafe<SQLiteOriginBoundCertStore::Backend>; - - // You should call Close() before destructing this object. - ~Backend() { - DCHECK(!db_.get()) << "Close should have already been called."; - DCHECK(num_pending_ == 0 && pending_.empty()); - } - - // Database upgrade statements. - bool EnsureDatabaseVersion(); - - class PendingOperation { - public: - typedef enum { - CERT_ADD, - CERT_DELETE - } OperationType; - - PendingOperation( - OperationType op, - const net::DefaultOriginBoundCertStore::OriginBoundCert& cert) - : op_(op), cert_(cert) {} - - OperationType op() const { return op_; } - const net::DefaultOriginBoundCertStore::OriginBoundCert& cert() const { - return cert_; - } - - private: - OperationType op_; - net::DefaultOriginBoundCertStore::OriginBoundCert cert_; - }; - - private: - // Batch an origin bound cert operation (add or delete) - void BatchOperation( - PendingOperation::OperationType op, - const net::DefaultOriginBoundCertStore::OriginBoundCert& cert); - // Commit our pending operations to the database. - void Commit(); - // Close() executed on the background thread. - void InternalBackgroundClose(); - - FilePath path_; - scoped_ptr<sql::Connection> db_; - sql::MetaTable meta_table_; - - typedef std::list<PendingOperation*> PendingOperationsList; - PendingOperationsList pending_; - PendingOperationsList::size_type num_pending_; - // True if the persistent store should be deleted upon destruction. - bool clear_local_state_on_exit_; - // Guard |pending_|, |num_pending_| and |clear_local_state_on_exit_|. - base::Lock lock_; - - DISALLOW_COPY_AND_ASSIGN(Backend); -}; - -// Version number of the database. -static const int kCurrentVersionNumber = 1; -static const int kCompatibleVersionNumber = 1; - -namespace { - -// Initializes the certs table, returning true on success. -bool InitTable(sql::Connection* db) { - if (!db->DoesTableExist("origin_bound_certs")) { - if (!db->Execute("CREATE TABLE origin_bound_certs (" - "origin TEXT NOT NULL UNIQUE PRIMARY KEY," - "private_key BLOB NOT NULL," - "cert BLOB NOT NULL)")) - return false; - } - - return true; -} - -} // namespace - -bool SQLiteOriginBoundCertStore::Backend::Load( - std::vector<net::DefaultOriginBoundCertStore::OriginBoundCert*>* certs) { - // This function should be called only once per instance. - DCHECK(!db_.get()); - - // Ensure the parent directory for storing certs is created before reading - // from it. We make an exception to allow IO on the UI thread here because - // we are going to disk anyway in db_->Open. (This code will be moved to the - // DB thread as part of http://crbug.com/52909.) - { - base::ThreadRestrictions::ScopedAllowIO allow_io; - const FilePath dir = path_.DirName(); - if (!file_util::PathExists(dir) && !file_util::CreateDirectory(dir)) - return false; - } - - db_.reset(new sql::Connection); - if (!db_->Open(path_)) { - NOTREACHED() << "Unable to open cert DB."; - db_.reset(); - return false; - } - - if (!EnsureDatabaseVersion() || !InitTable(db_.get())) { - NOTREACHED() << "Unable to open cert DB."; - db_.reset(); - return false; - } - - db_->Preload(); - - // Slurp all the certs into the out-vector. - sql::Statement smt(db_->GetUniqueStatement( - "SELECT origin, private_key, cert FROM origin_bound_certs")); - if (!smt) { - NOTREACHED() << "select statement prep failed"; - db_.reset(); - return false; - } - - while (smt.Step()) { - std::string private_key_from_db, cert_from_db; - smt.ColumnBlobAsString(1, &private_key_from_db); - smt.ColumnBlobAsString(2, &cert_from_db); - scoped_ptr<net::DefaultOriginBoundCertStore::OriginBoundCert> cert( - new net::DefaultOriginBoundCertStore::OriginBoundCert( - smt.ColumnString(0), // origin - private_key_from_db, - cert_from_db)); - certs->push_back(cert.release()); - } - - return true; -} - -bool SQLiteOriginBoundCertStore::Backend::EnsureDatabaseVersion() { - // Version check. - if (!meta_table_.Init( - db_.get(), kCurrentVersionNumber, kCompatibleVersionNumber)) { - return false; - } - - if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) { - LOG(WARNING) << "Origin bound cert database is too new."; - return false; - } - - int cur_version = meta_table_.GetVersionNumber(); - - // Put future migration cases here. - - // When the version is too old, we just try to continue anyway, there should - // not be a released product that makes a database too old for us to handle. - LOG_IF(WARNING, cur_version < kCurrentVersionNumber) << - "Origin bound cert database version " << cur_version << - " is too old to handle."; - - return true; -} - -void SQLiteOriginBoundCertStore::Backend::AddOriginBoundCert( - const net::DefaultOriginBoundCertStore::OriginBoundCert& cert) { - BatchOperation(PendingOperation::CERT_ADD, cert); -} - -void SQLiteOriginBoundCertStore::Backend::DeleteOriginBoundCert( - const net::DefaultOriginBoundCertStore::OriginBoundCert& cert) { - BatchOperation(PendingOperation::CERT_DELETE, cert); -} - -void SQLiteOriginBoundCertStore::Backend::BatchOperation( - PendingOperation::OperationType op, - const net::DefaultOriginBoundCertStore::OriginBoundCert& cert) { - // Commit every 30 seconds. - static const int kCommitIntervalMs = 30 * 1000; - // Commit right away if we have more than 512 outstanding operations. - static const size_t kCommitAfterBatchSize = 512; - DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::DB)); - - // We do a full copy of the cert here, and hopefully just here. - scoped_ptr<PendingOperation> po(new PendingOperation(op, cert)); - - PendingOperationsList::size_type num_pending; - { - base::AutoLock locked(lock_); - pending_.push_back(po.release()); - num_pending = ++num_pending_; - } - - if (num_pending == 1) { - // We've gotten our first entry for this batch, fire off the timer. - BrowserThread::PostDelayedTask( - BrowserThread::DB, FROM_HERE, - NewRunnableMethod(this, &Backend::Commit), kCommitIntervalMs); - } else if (num_pending == kCommitAfterBatchSize) { - // We've reached a big enough batch, fire off a commit now. - BrowserThread::PostTask( - BrowserThread::DB, FROM_HERE, - NewRunnableMethod(this, &Backend::Commit)); - } -} - -void SQLiteOriginBoundCertStore::Backend::Commit() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); - - PendingOperationsList ops; - { - base::AutoLock locked(lock_); - pending_.swap(ops); - num_pending_ = 0; - } - - // Maybe an old timer fired or we are already Close()'ed. - if (!db_.get() || ops.empty()) - return; - - sql::Statement add_smt(db_->GetCachedStatement(SQL_FROM_HERE, - "INSERT INTO origin_bound_certs (origin, private_key, cert) " - "VALUES (?,?,?)")); - if (!add_smt) { - NOTREACHED(); - return; - } - - sql::Statement del_smt(db_->GetCachedStatement(SQL_FROM_HERE, - "DELETE FROM origin_bound_certs WHERE origin=?")); - if (!del_smt) { - NOTREACHED(); - return; - } - - sql::Transaction transaction(db_.get()); - if (!transaction.Begin()) { - NOTREACHED(); - return; - } - for (PendingOperationsList::iterator it = ops.begin(); - it != ops.end(); ++it) { - // Free the certs as we commit them to the database. - scoped_ptr<PendingOperation> po(*it); - switch (po->op()) { - case PendingOperation::CERT_ADD: { - add_smt.Reset(); - add_smt.BindString(0, po->cert().origin()); - const std::string& private_key = po->cert().private_key(); - add_smt.BindBlob(1, private_key.data(), private_key.size()); - const std::string& cert = po->cert().cert(); - add_smt.BindBlob(2, cert.data(), cert.size()); - if (!add_smt.Run()) - NOTREACHED() << "Could not add an origin bound cert to the DB."; - break; - } - case PendingOperation::CERT_DELETE: - del_smt.Reset(); - del_smt.BindString(0, po->cert().origin()); - if (!del_smt.Run()) - NOTREACHED() << "Could not delete an origin bound cert from the DB."; - break; - - default: - NOTREACHED(); - break; - } - } - transaction.Commit(); -} - -void SQLiteOriginBoundCertStore::Backend::Flush(Task* completion_task) { - DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::DB)); - BrowserThread::PostTask( - BrowserThread::DB, FROM_HERE, NewRunnableMethod(this, &Backend::Commit)); - if (completion_task) { - // We want the completion task to run immediately after Commit() returns. - // Posting it from here means there is less chance of another task getting - // onto the message queue first, than if we posted it from Commit() itself. - BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, completion_task); - } -} - -// Fire off a close message to the background thread. We could still have a -// pending commit timer that will be holding a reference on us, but if/when -// this fires we will already have been cleaned up and it will be ignored. -void SQLiteOriginBoundCertStore::Backend::Close() { - DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::DB)); - // Must close the backend on the background thread. - BrowserThread::PostTask( - BrowserThread::DB, FROM_HERE, - NewRunnableMethod(this, &Backend::InternalBackgroundClose)); -} - -void SQLiteOriginBoundCertStore::Backend::InternalBackgroundClose() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); - // Commit any pending operations - Commit(); - - db_.reset(); - - if (clear_local_state_on_exit_) - file_util::Delete(path_, false); -} - -void SQLiteOriginBoundCertStore::Backend::SetClearLocalStateOnExit( - bool clear_local_state) { - base::AutoLock locked(lock_); - clear_local_state_on_exit_ = clear_local_state; -} - -SQLiteOriginBoundCertStore::SQLiteOriginBoundCertStore(const FilePath& path) - : backend_(new Backend(path)) { -} - -SQLiteOriginBoundCertStore::~SQLiteOriginBoundCertStore() { - if (backend_.get()) { - backend_->Close(); - // Release our reference, it will probably still have a reference if the - // background thread has not run Close() yet. - backend_ = NULL; - } -} - -bool SQLiteOriginBoundCertStore::Load( - std::vector<net::DefaultOriginBoundCertStore::OriginBoundCert*>* certs) { - return backend_->Load(certs); -} - -void SQLiteOriginBoundCertStore::AddOriginBoundCert( - const net::DefaultOriginBoundCertStore::OriginBoundCert& cert) { - if (backend_.get()) - backend_->AddOriginBoundCert(cert); -} - -void SQLiteOriginBoundCertStore::DeleteOriginBoundCert( - const net::DefaultOriginBoundCertStore::OriginBoundCert& cert) { - if (backend_.get()) - backend_->DeleteOriginBoundCert(cert); -} - -void SQLiteOriginBoundCertStore::SetClearLocalStateOnExit( - bool clear_local_state) { - if (backend_.get()) - backend_->SetClearLocalStateOnExit(clear_local_state); -} - -void SQLiteOriginBoundCertStore::Flush(Task* completion_task) { - if (backend_.get()) - backend_->Flush(completion_task); - else if (completion_task) - MessageLoop::current()->PostTask(FROM_HERE, completion_task); -} diff --git a/chrome/browser/net/sqlite_origin_bound_cert_store.h b/chrome/browser/net/sqlite_origin_bound_cert_store.h deleted file mode 100644 index f112ad8..0000000 --- a/chrome/browser/net/sqlite_origin_bound_cert_store.h +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_NET_SQLITE_ORIGIN_BOUND_CERT_STORE_H_ -#define CHROME_BROWSER_NET_SQLITE_ORIGIN_BOUND_CERT_STORE_H_ -#pragma once - -#include "base/compiler_specific.h" -#include "base/memory/ref_counted.h" -#include "net/base/default_origin_bound_cert_store.h" - -class FilePath; - -// Implements the net::DefaultOriginBoundCertStore::PersistentStore interface -// in terms of a SQLite database. For documentation about the actual member -// functions consult the documentation of the parent class -// |net::DefaultOriginBoundCertStore::PersistentCertStore|. -class SQLiteOriginBoundCertStore - : public net::DefaultOriginBoundCertStore::PersistentStore { - public: - explicit SQLiteOriginBoundCertStore(const FilePath& path); - virtual ~SQLiteOriginBoundCertStore(); - - // net::DefaultOriginBoundCertStore::PersistentStore implementation. - virtual bool Load( - std::vector<net::DefaultOriginBoundCertStore::OriginBoundCert*>* certs) - OVERRIDE; - virtual void AddOriginBoundCert( - const net::DefaultOriginBoundCertStore::OriginBoundCert& cert) OVERRIDE; - virtual void DeleteOriginBoundCert( - const net::DefaultOriginBoundCertStore::OriginBoundCert& cert) OVERRIDE; - virtual void SetClearLocalStateOnExit(bool clear_local_state) OVERRIDE; - virtual void Flush(Task* completion_task) OVERRIDE; - - private: - class Backend; - - scoped_refptr<Backend> backend_; - - DISALLOW_COPY_AND_ASSIGN(SQLiteOriginBoundCertStore); -}; - -#endif // CHROME_BROWSER_NET_SQLITE_ORIGIN_BOUND_CERT_STORE_H_ diff --git a/chrome/browser/net/sqlite_origin_bound_cert_store_unittest.cc b/chrome/browser/net/sqlite_origin_bound_cert_store_unittest.cc deleted file mode 100644 index aae87a9..0000000 --- a/chrome/browser/net/sqlite_origin_bound_cert_store_unittest.cc +++ /dev/null @@ -1,175 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/file_util.h" -#include "base/memory/ref_counted.h" -#include "base/message_loop.h" -#include "base/scoped_temp_dir.h" -#include "base/stl_util.h" -#include "base/test/thread_test_helper.h" -#include "chrome/browser/net/sqlite_origin_bound_cert_store.h" -#include "chrome/common/chrome_constants.h" -#include "content/browser/browser_thread.h" -#include "testing/gtest/include/gtest/gtest.h" - -class SQLiteOriginBoundCertStoreTest : public testing::Test { - public: - SQLiteOriginBoundCertStoreTest() - : db_thread_(BrowserThread::DB) { - } - - protected: - virtual void SetUp() { - db_thread_.Start(); - ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - store_ = new SQLiteOriginBoundCertStore( - temp_dir_.path().Append(chrome::kOBCertFilename)); - std::vector<net::DefaultOriginBoundCertStore::OriginBoundCert*> certs; - ASSERT_TRUE(store_->Load(&certs)); - ASSERT_EQ(0u, certs.size()); - // Make sure the store gets written at least once. - store_->AddOriginBoundCert( - net::DefaultOriginBoundCertStore::OriginBoundCert( - "https://encrypted.google.com:8443", "a", "b")); - } - - BrowserThread db_thread_; - ScopedTempDir temp_dir_; - scoped_refptr<SQLiteOriginBoundCertStore> store_; -}; - -TEST_F(SQLiteOriginBoundCertStoreTest, KeepOnDestruction) { - store_->SetClearLocalStateOnExit(false); - store_ = NULL; - // Make sure we wait until the destructor has run. - scoped_refptr<base::ThreadTestHelper> helper( - new base::ThreadTestHelper( - BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); - ASSERT_TRUE(helper->Run()); - - ASSERT_TRUE(file_util::PathExists( - temp_dir_.path().Append(chrome::kOBCertFilename))); - ASSERT_TRUE(file_util::Delete( - temp_dir_.path().Append(chrome::kOBCertFilename), false)); -} - -TEST_F(SQLiteOriginBoundCertStoreTest, RemoveOnDestruction) { - store_->SetClearLocalStateOnExit(true); - // Replace the store effectively destroying the current one and forcing it - // to write it's data to disk. Then we can see if after loading it again it - // is still there. - store_ = NULL; - // Make sure we wait until the destructor has run. - scoped_refptr<base::ThreadTestHelper> helper( - new base::ThreadTestHelper( - BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); - ASSERT_TRUE(helper->Run()); - - ASSERT_FALSE(file_util::PathExists( - temp_dir_.path().Append(chrome::kOBCertFilename))); -} - -// Test if data is stored as expected in the SQLite database. -TEST_F(SQLiteOriginBoundCertStoreTest, TestPersistence) { - std::vector<net::DefaultOriginBoundCertStore::OriginBoundCert*> certs; - // Replace the store effectively destroying the current one and forcing it - // to write it's data to disk. Then we can see if after loading it again it - // is still there. - store_ = NULL; - scoped_refptr<base::ThreadTestHelper> helper( - new base::ThreadTestHelper( - BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); - // Make sure we wait until the destructor has run. - ASSERT_TRUE(helper->Run()); - store_ = new SQLiteOriginBoundCertStore( - temp_dir_.path().Append(chrome::kOBCertFilename)); - - // Reload and test for persistence - ASSERT_TRUE(store_->Load(&certs)); - ASSERT_EQ(1U, certs.size()); - ASSERT_STREQ("https://encrypted.google.com:8443", certs[0]->origin().c_str()); - ASSERT_STREQ("a", certs[0]->private_key().c_str()); - ASSERT_STREQ("b", certs[0]->cert().c_str()); - - // Now delete the cert and check persistence again. - store_->DeleteOriginBoundCert(*certs[0]); - store_ = NULL; - // Make sure we wait until the destructor has run. - ASSERT_TRUE(helper->Run()); - STLDeleteContainerPointers(certs.begin(), certs.end()); - certs.clear(); - store_ = new SQLiteOriginBoundCertStore( - temp_dir_.path().Append(chrome::kOBCertFilename)); - - // Reload and check if the cert has been removed. - ASSERT_TRUE(store_->Load(&certs)); - ASSERT_EQ(0U, certs.size()); -} - -// Test that we can force the database to be written by calling Flush(). -TEST_F(SQLiteOriginBoundCertStoreTest, TestFlush) { - // File timestamps don't work well on all platforms, so we'll determine - // whether the DB file has been modified by checking its size. - FilePath path = temp_dir_.path().Append(chrome::kOBCertFilename); - base::PlatformFileInfo info; - ASSERT_TRUE(file_util::GetFileInfo(path, &info)); - int64 base_size = info.size; - - // Write some certs, so the DB will have to expand by several KB. - for (char c = 'a'; c < 'z'; ++c) { - std::string origin(1, c); - std::string private_key(1000, c); - std::string cert(1000, c); - store_->AddOriginBoundCert( - net::DefaultOriginBoundCertStore::OriginBoundCert(origin, - private_key, - cert)); - } - - // Call Flush() and wait until the DB thread is idle. - store_->Flush(NULL); - scoped_refptr<base::ThreadTestHelper> helper( - new base::ThreadTestHelper( - BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); - ASSERT_TRUE(helper->Run()); - - // We forced a write, so now the file will be bigger. - ASSERT_TRUE(file_util::GetFileInfo(path, &info)); - ASSERT_GT(info.size, base_size); -} - -// Counts the number of times Callback() has been run. -class CallbackCounter : public base::RefCountedThreadSafe<CallbackCounter> { - public: - CallbackCounter() : callback_count_(0) {} - - void Callback() { - ++callback_count_; - } - - int callback_count() { - return callback_count_; - } - - private: - friend class base::RefCountedThreadSafe<CallbackCounter>; - volatile int callback_count_; -}; - -// Test that we can get a completion callback after a Flush(). -TEST_F(SQLiteOriginBoundCertStoreTest, TestFlushCompletionCallback) { - scoped_refptr<CallbackCounter> counter(new CallbackCounter()); - - // Callback shouldn't be invoked until we call Flush(). - ASSERT_EQ(0, counter->callback_count()); - - store_->Flush(NewRunnableMethod(counter.get(), &CallbackCounter::Callback)); - - scoped_refptr<base::ThreadTestHelper> helper( - new base::ThreadTestHelper( - BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); - ASSERT_TRUE(helper->Run()); - - ASSERT_EQ(1, counter->callback_count()); -} diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 540017b..08f6128 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1472,8 +1472,6 @@ 'browser/net/sdch_dictionary_fetcher.h', 'browser/net/service_providers_win.cc', 'browser/net/service_providers_win.h', - 'browser/net/sqlite_origin_bound_cert_store.cc', - 'browser/net/sqlite_origin_bound_cert_store.h', 'browser/net/sqlite_persistent_cookie_store.cc', 'browser/net/sqlite_persistent_cookie_store.h', 'browser/net/ssl_config_service_manager.h', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index f872890..cbf6f88 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1501,7 +1501,6 @@ 'browser/net/predictor_unittest.cc', 'browser/net/pref_proxy_config_service_unittest.cc', 'browser/net/quoted_printable_unittest.cc', - 'browser/net/sqlite_origin_bound_cert_store_unittest.cc', 'browser/net/sqlite_persistent_cookie_store_unittest.cc', 'browser/net/ssl_config_service_manager_pref_unittest.cc', 'browser/net/url_fixer_upper_unittest.cc', diff --git a/chrome/common/chrome_constants.cc b/chrome/common/chrome_constants.cc index 2d241ad..f1af5b6 100644 --- a/chrome/common/chrome_constants.cc +++ b/chrome/common/chrome_constants.cc @@ -126,7 +126,6 @@ const FilePath::CharType kOffTheRecordMediaCacheDirname[] = const FilePath::CharType kAppCacheDirname[] = FPL("Application Cache"); const FilePath::CharType kThemePackFilename[] = FPL("Cached Theme.pak"); const FilePath::CharType kCookieFilename[] = FPL("Cookies"); -const FilePath::CharType kOBCertFilename[] = FPL("Origin Bound Certs"); const FilePath::CharType kExtensionsCookieFilename[] = FPL("Extension Cookies"); const FilePath::CharType kIsolatedAppStateDirname[] = FPL("Isolated Apps"); const FilePath::CharType kFaviconsFilename[] = FPL("Favicons"); diff --git a/chrome/common/chrome_constants.h b/chrome/common/chrome_constants.h index 6cd6e45..ac5129d 100644 --- a/chrome/common/chrome_constants.h +++ b/chrome/common/chrome_constants.h @@ -50,7 +50,6 @@ extern const FilePath::CharType kOffTheRecordMediaCacheDirname[]; extern const FilePath::CharType kAppCacheDirname[]; extern const FilePath::CharType kThemePackFilename[]; extern const FilePath::CharType kCookieFilename[]; -extern const FilePath::CharType kOBCertFilename[]; extern const FilePath::CharType kExtensionsCookieFilename[]; extern const FilePath::CharType kIsolatedAppStateDirname[]; extern const FilePath::CharType kFaviconsFilename[]; diff --git a/net/base/default_origin_bound_cert_store.cc b/net/base/default_origin_bound_cert_store.cc deleted file mode 100644 index e047af8..0000000 --- a/net/base/default_origin_bound_cert_store.cc +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/default_origin_bound_cert_store.h" - -#include "base/message_loop.h" - -namespace net { - -// static -const size_t DefaultOriginBoundCertStore::kMaxCerts = 3300; - -DefaultOriginBoundCertStore::DefaultOriginBoundCertStore( - PersistentStore* store) - : initialized_(false), - store_(store) {} - -void DefaultOriginBoundCertStore::FlushStore(Task* completion_task) { - base::AutoLock autolock(lock_); - - if (initialized_ && store_) - store_->Flush(completion_task); - else if (completion_task) - MessageLoop::current()->PostTask(FROM_HERE, completion_task); -} - -bool DefaultOriginBoundCertStore::GetOriginBoundCert( - const std::string& origin, - std::string* private_key_result, - std::string* cert_result) { - base::AutoLock autolock(lock_); - InitIfNecessary(); - - OriginBoundCertMap::iterator it = origin_bound_certs_.find(origin); - - if (it == origin_bound_certs_.end()) - return false; - - OriginBoundCert* cert = it->second; - *private_key_result = cert->private_key(); - *cert_result = cert->cert(); - - return true; -} - -bool DefaultOriginBoundCertStore::SetOriginBoundCert( - const std::string& origin, - const std::string& private_key, - const std::string& cert) { - base::AutoLock autolock(lock_); - InitIfNecessary(); - - InternalDeleteOriginBoundCert(origin); - InternalInsertOriginBoundCert(origin, - new OriginBoundCert(origin, private_key, cert)); - - return true; -} - -int DefaultOriginBoundCertStore::GetCertCount() { - base::AutoLock autolock(lock_); - InitIfNecessary(); - - return origin_bound_certs_.size(); -} - -DefaultOriginBoundCertStore::~DefaultOriginBoundCertStore() { - DeleteAll(); -} - -void DefaultOriginBoundCertStore::DeleteAll() { - base::AutoLock autolock(lock_); - - for (OriginBoundCertMap::iterator it = origin_bound_certs_.begin(); - it != origin_bound_certs_.end(); it++) { - delete it->second; - } - origin_bound_certs_.clear(); -} - -void DefaultOriginBoundCertStore::InitStore() { - lock_.AssertAcquired(); - - DCHECK(store_) << "Store must exist to initialize"; - - // Initialize the store and sync in any saved persistent certs. - std::vector<OriginBoundCert*> certs; - // Reserve space for the maximum amount of certs a database should have. - // This prevents multiple vector growth / copies as we append certs. - certs.reserve(kMaxCerts); - store_->Load(&certs); - - for (std::vector<OriginBoundCert*>::const_iterator it = certs.begin(); - it != certs.end(); ++it) { - origin_bound_certs_[(*it)->origin()] = *it; - } -} - -void DefaultOriginBoundCertStore::InternalDeleteOriginBoundCert( - const std::string& origin) { - lock_.AssertAcquired(); - - OriginBoundCertMap::iterator it = origin_bound_certs_.find(origin); - if (it == origin_bound_certs_.end()) - return; // There is nothing to delete. - - OriginBoundCert* cert = it->second; - if (store_) - store_->DeleteOriginBoundCert(*cert); - origin_bound_certs_.erase(it); - delete cert; -} - -void DefaultOriginBoundCertStore::InternalInsertOriginBoundCert( - const std::string& origin, - OriginBoundCert* cert) { - lock_.AssertAcquired(); - - if (store_) - store_->AddOriginBoundCert(*cert); - origin_bound_certs_[origin] = cert; -} - -DefaultOriginBoundCertStore::OriginBoundCert::OriginBoundCert() {} - -DefaultOriginBoundCertStore::OriginBoundCert::OriginBoundCert( - const std::string& origin, - const std::string& private_key, - const std::string& cert) - : origin_(origin), - private_key_(private_key), - cert_(cert) {} - -DefaultOriginBoundCertStore::PersistentStore::PersistentStore() {} - -} // namespace net diff --git a/net/base/default_origin_bound_cert_store.h b/net/base/default_origin_bound_cert_store.h deleted file mode 100644 index 4b8b8a9..0000000 --- a/net/base/default_origin_bound_cert_store.h +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_DEFAULT_ORIGIN_BOUND_CERT_STORE_H_ -#define NET_BASE_DEFAULT_ORIGIN_BOUND_CERT_STORE_H_ -#pragma once - -#include <map> -#include <string> -#include <vector> - -#include "base/compiler_specific.h" -#include "base/memory/ref_counted.h" -#include "base/synchronization/lock.h" -#include "net/base/origin_bound_cert_store.h" - -class Task; - -namespace net { - -// This class is the system for storing and retrieving origin bound certs. -// Modelled after the CookieMonster class, it has an in-memory cert store, -// and synchronizes origin bound certs to an optional permanent storage that -// implements the PersistentStore interface. The use case is described in -// http://balfanz.github.com/tls-obc-spec/draft-balfanz-tls-obc-00.html -// -// This class can be accessed by multiple threads. For example, it can be used -// by IO and origin bound cert management UI. -class DefaultOriginBoundCertStore : public OriginBoundCertStore { - public: - class OriginBoundCert; - class PersistentStore; - - // The key for each OriginBoundCert* in OriginBoundCertMap is the - // corresponding origin. - typedef std::map<std::string, OriginBoundCert*> OriginBoundCertMap; - - // The store passed in should not have had Init() called on it yet. This - // class will take care of initializing it. The backing store is NOT owned by - // this class, but it must remain valid for the duration of the - // DefaultOriginBoundCertStore's existence. If |store| is NULL, then no - // backing store will be updated. - explicit DefaultOriginBoundCertStore(PersistentStore* store); - - virtual ~DefaultOriginBoundCertStore(); - - // Flush the backing store (if any) to disk and post the given task when done. - // WARNING: THE CALLBACK WILL RUN ON A RANDOM THREAD. IT MUST BE THREAD SAFE. - // It may be posted to the current thread, or it may run on the thread that - // actually does the flushing. Your Task should generally post a notification - // to the thread you actually want to be notified on. - void FlushStore(Task* completion_task); - - // OriginBoundCertStore implementation. - virtual bool GetOriginBoundCert(const std::string& origin, - std::string* private_key_result, - std::string* cert_result) OVERRIDE; - virtual bool SetOriginBoundCert(const std::string& origin, - const std::string& private_key, - const std::string& cert) OVERRIDE; - virtual int GetCertCount() OVERRIDE; - - private: - static const size_t kMaxCerts; - - // Deletes all of the certs. Does not delete them from |store_|. - void DeleteAll(); - - // Called by all non-static functions to ensure that the cert store has - // been initialized. This is not done during creating so it doesn't block - // the window showing. - // Note: this method should always be called with lock_ held. - void InitIfNecessary() { - if (!initialized_) { - if (store_) - InitStore(); - initialized_ = true; - } - } - - // Initializes the backing store and reads existing certs from it. - // Should only be called by InitIfNecessary(). - void InitStore(); - - // Deletes the cert for the specified origin, if such a cert exists, from the - // in-memory store. Deletes it from |store_| if |store_| is not NULL. - void InternalDeleteOriginBoundCert(const std::string& origin); - - // Takes ownership of *cert. - // Adds the cert for the specified origin to the in-memory store. Deletes it - // from |store_| if |store_| is not NULL. - void InternalInsertOriginBoundCert(const std::string& origin, - OriginBoundCert* cert); - - // Indicates whether the cert store has been initialized. This happens - // Lazily in InitStoreIfNecessary(). - bool initialized_; - - scoped_refptr<PersistentStore> store_; - - OriginBoundCertMap origin_bound_certs_; - - // Lock for thread-safety - base::Lock lock_; - - DISALLOW_COPY_AND_ASSIGN(DefaultOriginBoundCertStore); -}; - -// The OriginBoundCert class contains a private key in addition to the origin -// and the cert. -class DefaultOriginBoundCertStore::OriginBoundCert { - public: - OriginBoundCert(); - OriginBoundCert(const std::string& origin, - const std::string& privatekey, - const std::string& cert); - - const std::string& origin() const { return origin_; } - const std::string& private_key() const { return private_key_; } - const std::string& cert() const { return cert_; } - - private: - std::string origin_; - std::string private_key_; - std::string cert_; -}; - -typedef base::RefCountedThreadSafe<DefaultOriginBoundCertStore::PersistentStore> - RefcountedPersistentStore; - -class DefaultOriginBoundCertStore::PersistentStore - : public RefcountedPersistentStore { - public: - virtual ~PersistentStore() {} - - // Initializes the store and retrieves the existing certs. This will be - // called only once at startup. Note that the certs are individually allocated - // and that ownership is transferred to the caller upon return. - virtual bool Load( - std::vector<DefaultOriginBoundCertStore::OriginBoundCert*>* certs) = 0; - - virtual void AddOriginBoundCert(const OriginBoundCert& cert) = 0; - - virtual void DeleteOriginBoundCert(const OriginBoundCert& cert) = 0; - - // Sets the value of the user preference whether the persistent storage - // must be deleted upon destruction. - virtual void SetClearLocalStateOnExit(bool clear_local_state) = 0; - - // Flush the store and post the given Task when complete. - virtual void Flush(Task* completion_task) = 0; - - protected: - PersistentStore(); - - private: - DISALLOW_COPY_AND_ASSIGN(PersistentStore); -}; - -} // namespace net - -#endif // NET_DEFAULT_ORIGIN_BOUND_CERT_STORE_H_ diff --git a/net/base/default_origin_bound_cert_store_unittest.cc b/net/base/default_origin_bound_cert_store_unittest.cc deleted file mode 100644 index 5fe77ef..0000000 --- a/net/base/default_origin_bound_cert_store_unittest.cc +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/default_origin_bound_cert_store.h" - -#include <map> -#include <string> -#include <vector> - -#include "base/compiler_specific.h" -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace net { - -class MockPersistentStore - : public DefaultOriginBoundCertStore::PersistentStore { - public: - MockPersistentStore(); - virtual ~MockPersistentStore(); - - // DefaultOriginBoundCertStore::PersistentStore implementation. - virtual bool Load( - std::vector<DefaultOriginBoundCertStore::OriginBoundCert*>* certs) - OVERRIDE; - virtual void AddOriginBoundCert( - const DefaultOriginBoundCertStore::OriginBoundCert& cert) OVERRIDE; - virtual void DeleteOriginBoundCert( - const DefaultOriginBoundCertStore::OriginBoundCert& cert) OVERRIDE; - virtual void SetClearLocalStateOnExit(bool clear_local_state) OVERRIDE; - virtual void Flush(Task* completion_task) OVERRIDE; - - private: - typedef std::map<std::string, DefaultOriginBoundCertStore::OriginBoundCert> - OriginBoundCertMap; - - OriginBoundCertMap origin_certs_; -}; - -MockPersistentStore::MockPersistentStore() {} - -MockPersistentStore::~MockPersistentStore() {} - -bool MockPersistentStore::Load( - std::vector<DefaultOriginBoundCertStore::OriginBoundCert*>* certs) { - OriginBoundCertMap::iterator it; - - for (it = origin_certs_.begin(); it != origin_certs_.end(); ++it) { - certs->push_back( - new DefaultOriginBoundCertStore::OriginBoundCert(it->second)); - } - - return true; -} - -void MockPersistentStore::AddOriginBoundCert( - const DefaultOriginBoundCertStore::OriginBoundCert& cert) { - origin_certs_[cert.origin()] = cert; -} - -void MockPersistentStore::DeleteOriginBoundCert( - const DefaultOriginBoundCertStore::OriginBoundCert& cert) { - origin_certs_.erase(cert.origin()); -} - -void MockPersistentStore::SetClearLocalStateOnExit(bool clear_local_state) {} - -void MockPersistentStore::Flush(Task* completion_task) { - NOTREACHED(); -} - -TEST(DefaultOriginBoundCertStoreTest, TestLoading) { - scoped_refptr<MockPersistentStore> persistent_store(new MockPersistentStore); - - persistent_store->AddOriginBoundCert( - DefaultOriginBoundCertStore::OriginBoundCert( - "https://encrypted.google.com/", "a", "b")); - persistent_store->AddOriginBoundCert( - DefaultOriginBoundCertStore::OriginBoundCert( - "https://www.verisign.com/", "c", "d")); - - // Make sure certs load properly. - scoped_ptr<DefaultOriginBoundCertStore> store( - new DefaultOriginBoundCertStore(persistent_store)); - EXPECT_EQ(2, store->GetCertCount()); - EXPECT_TRUE(store->SetOriginBoundCert("https://www.verisign.com/", "e", "f")); - EXPECT_EQ(2, store->GetCertCount()); - EXPECT_TRUE(store->SetOriginBoundCert("https://www.twitter.com/", "g", "h")); - EXPECT_EQ(3, store->GetCertCount()); -} - -TEST(DefaultOriginBoundCertStoreTest, TestSettingAndGetting) { - scoped_ptr<DefaultOriginBoundCertStore> store( - new DefaultOriginBoundCertStore(NULL)); - std::string private_key, cert; - EXPECT_EQ(0, store->GetCertCount()); - EXPECT_FALSE(store->GetOriginBoundCert("https://www.verisign.com/", - &private_key, - &cert)); - EXPECT_TRUE(private_key.empty()); - EXPECT_TRUE(cert.empty()); - EXPECT_TRUE(store->SetOriginBoundCert("https://www.verisign.com/", "i", "j")); - EXPECT_TRUE(store->GetOriginBoundCert("https://www.verisign.com/", - &private_key, - &cert)); - EXPECT_EQ("i", private_key); - EXPECT_EQ("j", cert); -} - -} // namespace net diff --git a/net/base/origin_bound_cert_service.cc b/net/base/origin_bound_cert_service.cc index 61a80eb..0d706bc 100644 --- a/net/base/origin_bound_cert_service.cc +++ b/net/base/origin_bound_cert_service.cc @@ -11,6 +11,7 @@ #include "base/memory/scoped_ptr.h" #include "base/rand_util.h" #include "crypto/rsa_private_key.h" +#include "googleurl/src/gurl.h" #include "net/base/origin_bound_cert_store.h" #include "net/base/x509_certificate.h" @@ -23,23 +24,19 @@ const int kValidityPeriodInDays = 365; } // namespace -OriginBoundCertService::OriginBoundCertService( - OriginBoundCertStore* origin_bound_cert_store) - : origin_bound_cert_store_(origin_bound_cert_store) {} - -OriginBoundCertService::~OriginBoundCertService() {} - -bool OriginBoundCertService::GetOriginBoundCert(const std::string& origin, +bool OriginBoundCertService::GetOriginBoundCert(const GURL& url, std::string* private_key_result, std::string* cert_result) { // Check if origin bound cert already exists for this origin. - if (origin_bound_cert_store_->GetOriginBoundCert(origin, - private_key_result, - cert_result)) - return true; + if (origin_bound_cert_store_->HasOriginBoundCert(url)) { + return origin_bound_cert_store_->GetOriginBoundCert(url, + private_key_result, + cert_result); + } // No origin bound cert exists, we have to create one. - std::string subject = "CN=OBC"; + std::string origin = url.GetOrigin().spec(); + std::string subject = "CN=origin-bound certificate for " + origin; scoped_ptr<crypto::RSAPrivateKey> key( crypto::RSAPrivateKey::Create(kKeySizeInBits)); if (!key.get()) { @@ -71,9 +68,7 @@ bool OriginBoundCertService::GetOriginBoundCert(const std::string& origin, return false; } - if (!origin_bound_cert_store_->SetOriginBoundCert(origin, - key_out, - der_cert)) { + if (!origin_bound_cert_store_->SetOriginBoundCert(url, key_out, der_cert)) { LOG(WARNING) << "Unable to set origin bound certificate"; return false; } @@ -83,8 +78,4 @@ bool OriginBoundCertService::GetOriginBoundCert(const std::string& origin, return true; } -int OriginBoundCertService::GetCertCount() { - return origin_bound_cert_store_->GetCertCount(); -} - } // namespace net diff --git a/net/base/origin_bound_cert_service.h b/net/base/origin_bound_cert_service.h index 9f700b9..c1d65b9 100644 --- a/net/base/origin_bound_cert_service.h +++ b/net/base/origin_bound_cert_service.h @@ -8,39 +8,30 @@ #include <string> -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" +class GURL; namespace net { class OriginBoundCertStore; // A class for creating and fetching origin bound certs. -class OriginBoundCertService - : public base::RefCountedThreadSafe<OriginBoundCertService> { +class OriginBoundCertService { public: - // This object owns origin_bound_cert_store. - explicit OriginBoundCertService( - OriginBoundCertStore* origin_bound_cert_store); - - ~OriginBoundCertService(); + explicit OriginBoundCertService(OriginBoundCertStore* origin_bound_cert_store) + : origin_bound_cert_store_(origin_bound_cert_store) {} // TODO(rkn): Specify certificate type (RSA or DSA). // TODO(rkn): Key generation can be time consuming, so this should have an // asynchronous interface. // Fetches the origin bound cert for the specified origin if one exists // and creates one otherwise. On success, |private_key_result| stores a - // DER-encoded PrivateKeyInfo struct, and |cert_result| stores a DER-encoded - // certificate. - bool GetOriginBoundCert(const std::string& origin, + // PrivateKeyInfo struct, and |cert_result| stores a DER-encoded certificate. + bool GetOriginBoundCert(const GURL& url, std::string* private_key_result, std::string* cert_result); - // Public only for unit testing. - int GetCertCount(); - private: - scoped_ptr<OriginBoundCertStore> origin_bound_cert_store_; + OriginBoundCertStore* origin_bound_cert_store_; }; } // namespace net diff --git a/net/base/origin_bound_cert_service_unittest.cc b/net/base/origin_bound_cert_service_unittest.cc deleted file mode 100644 index 59be848..0000000 --- a/net/base/origin_bound_cert_service_unittest.cc +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/origin_bound_cert_service.h" - -#include <string> -#include <vector> - -#include "base/memory/ref_counted.h" -#include "crypto/rsa_private_key.h" -#include "net/base/default_origin_bound_cert_store.h" -#include "net/base/x509_certificate.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace net { - -TEST(OriginBoundCertServiceTest, DuplicateCertTest) { - scoped_refptr<OriginBoundCertService> service( - new OriginBoundCertService(new DefaultOriginBoundCertStore(NULL))); - std::string origin1("https://encrypted.google.com/"); - std::string origin2("https://www.verisign.com/"); - - // The store should start out empty and should increment appropriately. - std::string private_key_info_1a, der_cert_1a; - EXPECT_EQ(0, service->GetCertCount()); - EXPECT_TRUE(service->GetOriginBoundCert( - origin1, &private_key_info_1a, &der_cert_1a)); - EXPECT_EQ(1, service->GetCertCount()); - - // We should get the same cert and key for the same origin. - std::string private_key_info_1b, der_cert_1b; - EXPECT_TRUE(service->GetOriginBoundCert( - origin1, &private_key_info_1b, &der_cert_1b)); - EXPECT_EQ(1, service->GetCertCount()); - EXPECT_EQ(private_key_info_1a, private_key_info_1b); - EXPECT_EQ(der_cert_1a, der_cert_1b); - - // We should get a different cert and key for different origins. - std::string private_key_info_2, der_cert_2; - EXPECT_TRUE(service->GetOriginBoundCert( - origin2, &private_key_info_2, &der_cert_2)); - EXPECT_EQ(2, service->GetCertCount()); - EXPECT_NE(private_key_info_1a, private_key_info_2); - EXPECT_NE(der_cert_1a, der_cert_2); -} - -TEST(OriginBoundCertServiceTest, ExtractValuesFromBytes) { - scoped_refptr<OriginBoundCertService> service( - new OriginBoundCertService(new DefaultOriginBoundCertStore(NULL))); - std::string origin("https://encrypted.google.com/"); - std::string private_key_info, der_cert; - EXPECT_TRUE(service->GetOriginBoundCert( - origin, &private_key_info, &der_cert)); - std::vector<uint8> key_vec(private_key_info.begin(), private_key_info.end()); - - // Check that we can retrieve the key pair from the bytes. - scoped_ptr<crypto::RSAPrivateKey> private_key( - crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_vec)); - EXPECT_TRUE(private_key != NULL); - - // Check that we can retrieve the cert from the bytes. - scoped_refptr<X509Certificate> x509cert( - X509Certificate::CreateFromBytes(der_cert.data(), der_cert.size())); - EXPECT_TRUE(x509cert != NULL); -} - -} // namespace net diff --git a/net/base/origin_bound_cert_store.h b/net/base/origin_bound_cert_store.h index 63989f5..8529fbd 100644 --- a/net/base/origin_bound_cert_store.h +++ b/net/base/origin_bound_cert_store.h @@ -8,38 +8,29 @@ #include <string> +class GURL; + namespace net { // An interface for storing and retrieving origin bound certs. Origin bound // certificates are specified in // http://balfanz.github.com/tls-obc-spec/draft-balfanz-tls-obc-00.html. -// Owned only by a single OriginBoundCertService object, which is responsible -// for deleting it. - class OriginBoundCertStore { public: - virtual ~OriginBoundCertStore() {} + virtual bool HasOriginBoundCert(const GURL& url) = 0; // TODO(rkn): Specify certificate type (RSA or DSA). - // TODO(rkn): File I/O may be required, so this should have an asynchronous - // interface. - // Returns true on success. |private_key_result| stores a DER-encoded - // PrivateKeyInfo struct and |cert_result| stores a DER-encoded - // certificate. Returns false if no origin bound cert exists for the - // specified origin. - virtual bool GetOriginBoundCert(const std::string& origin, + // TODO(rkn): Key generation can be time consuming, so this should have an + // asynchronous interface. + // The output is stored in |private_key_result| and |cert_result|. + virtual bool GetOriginBoundCert(const GURL& url, std::string* private_key_result, std::string* cert_result) = 0; - // Adds an origin bound cert to the store. - virtual bool SetOriginBoundCert(const std::string& origin, + virtual bool SetOriginBoundCert(const GURL& url, const std::string& private_key, const std::string& cert) = 0; - - // Returns the number of certs in the store. - // Public only for unit testing. - virtual int GetCertCount() = 0; }; } // namespace net diff --git a/net/net.gyp b/net/net.gyp index de2b4df..4ae27c0 100644 --- a/net/net.gyp +++ b/net/net.gyp @@ -67,8 +67,6 @@ 'base/crypto_module_openssl.cc', 'base/data_url.cc', 'base/data_url.h', - 'base/default_origin_bound_cert_store.cc', - 'base/default_origin_bound_cert_store.h', 'base/directory_lister.cc', 'base/directory_lister.h', 'base/dns_reload_timer.cc', @@ -879,7 +877,6 @@ 'base/cookie_monster_unittest.cc', 'base/crl_filter_unittest.cc', 'base/data_url_unittest.cc', - 'base/default_origin_bound_cert_store_unittest.cc', 'base/directory_lister_unittest.cc', 'base/dnssec_unittest.cc', 'base/dns_util_unittest.cc', @@ -903,7 +900,6 @@ 'base/net_log_unittest.cc', 'base/net_log_unittest.h', 'base/net_util_unittest.cc', - 'base/origin_bound_cert_service_unittest.cc', 'base/pem_tokenizer_unittest.cc', 'base/registry_controlled_domain_unittest.cc', 'base/run_all_unittests.cc', |