diff options
author | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-30 15:19:11 +0000 |
---|---|---|
committer | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-30 15:19:11 +0000 |
commit | ca167a3703b1b32a265547a11833f2954fedef9c (patch) | |
tree | a53092895dcaffeacd40f6e3a55f0f9fca72f641 | |
parent | 505cbbc4fc113adb474d0c21b4d1c909387224f0 (diff) | |
download | chromium_src-ca167a3703b1b32a265547a11833f2954fedef9c.zip chromium_src-ca167a3703b1b32a265547a11833f2954fedef9c.tar.gz chromium_src-ca167a3703b1b32a265547a11833f2954fedef9c.tar.bz2 |
Add CRL set updater.
This is just a dormant component updater for CRL sets. Since the call to start
the initial load is commented out it's actually inactive, but it helps to split
the CRL set change into parts to make it more easily reviewable.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/8056013
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@103466 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/browser_process.h | 3 | ||||
-rw-r--r-- | chrome/browser/browser_process_impl.cc | 14 | ||||
-rw-r--r-- | chrome/browser/browser_process_impl.h | 4 | ||||
-rw-r--r-- | chrome/browser/net/crl_set_fetcher.cc | 168 | ||||
-rw-r--r-- | chrome/browser/net/crl_set_fetcher.h | 71 | ||||
-rw-r--r-- | chrome/browser/ui/browser_init.cc | 7 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 2 | ||||
-rw-r--r-- | chrome/common/chrome_constants.cc | 2 | ||||
-rw-r--r-- | chrome/common/chrome_constants.h | 1 | ||||
-rw-r--r-- | chrome/test/base/testing_browser_process.cc | 4 | ||||
-rw-r--r-- | chrome/test/base/testing_browser_process.h | 2 | ||||
-rw-r--r-- | net/base/crl_set.h | 2 | ||||
-rw-r--r-- | net/base/ssl_config_service.cc | 10 | ||||
-rw-r--r-- | net/base/ssl_config_service.h | 8 |
14 files changed, 297 insertions, 1 deletions
diff --git a/chrome/browser/browser_process.h b/chrome/browser/browser_process.h index 0a7dd39..d61209d 100644 --- a/chrome/browser/browser_process.h +++ b/chrome/browser/browser_process.h @@ -21,6 +21,7 @@ class AutomationProviderList; class BackgroundModeManager; class ChromeNetLog; +class CRLSetFetcher; class ComponentUpdateService; class DevToolsManager; class DownloadRequestLimiter; @@ -244,6 +245,8 @@ class BrowserProcess { virtual ComponentUpdateService* component_updater() = 0; + virtual CRLSetFetcher* crl_set_fetcher() = 0; + private: DISALLOW_COPY_AND_ASSIGN(BrowserProcess); }; diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc index 84f1a34..e3087a3 100644 --- a/chrome/browser/browser_process_impl.cc +++ b/chrome/browser/browser_process_impl.cc @@ -36,6 +36,7 @@ #include "chrome/browser/metrics/metrics_service.h" #include "chrome/browser/metrics/thread_watcher.h" #include "chrome/browser/net/chrome_net_log.h" +#include "chrome/browser/net/crl_set_fetcher.h" #include "chrome/browser/net/sdch_dictionary_fetcher.h" #include "chrome/browser/notifications/notification_ui_manager.h" #include "chrome/browser/policy/browser_policy_connector.h" @@ -740,6 +741,19 @@ ComponentUpdateService* BrowserProcessImpl::component_updater() { #endif } +CRLSetFetcher* BrowserProcessImpl::crl_set_fetcher() { +#if defined(OS_CHROMEOS) + // There's no component updater on ChromeOS so there can't be a CRLSetFetcher + // either. + return NULL; +#else + if (!crl_set_fetcher_.get()) { + crl_set_fetcher_ = new CRLSetFetcher(); + } + return crl_set_fetcher_.get(); +#endif +} + void BrowserProcessImpl::CreateResourceDispatcherHost() { DCHECK(!created_resource_dispatcher_host_ && resource_dispatcher_host_.get() == NULL); diff --git a/chrome/browser/browser_process_impl.h b/chrome/browser/browser_process_impl.h index 8e0a00c..dcfb7fa 100644 --- a/chrome/browser/browser_process_impl.h +++ b/chrome/browser/browser_process_impl.h @@ -130,6 +130,8 @@ class BrowserProcessImpl : public BrowserProcess, virtual ComponentUpdateService* component_updater() OVERRIDE; + virtual CRLSetFetcher* crl_set_fetcher(); + private: void CreateResourceDispatcherHost(); void CreateMetricsService(); @@ -318,6 +320,8 @@ class BrowserProcessImpl : public BrowserProcess, #if !defined(OS_CHROMEOS) scoped_ptr<ComponentUpdateService> component_updater_; + + scoped_refptr<CRLSetFetcher> crl_set_fetcher_; #endif DISALLOW_COPY_AND_ASSIGN(BrowserProcessImpl); diff --git a/chrome/browser/net/crl_set_fetcher.cc b/chrome/browser/net/crl_set_fetcher.cc new file mode 100644 index 0000000..ef3558a --- /dev/null +++ b/chrome/browser/net/crl_set_fetcher.cc @@ -0,0 +1,168 @@ +// 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/crl_set_fetcher.h" + +#include "base/file_util.h" +#include "base/path_service.h" +#include "base/rand_util.h" +#include "base/time.h" +#include "base/string_number_conversions.h" +#include "chrome/browser/component_updater/component_updater_service.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/common/chrome_constants.h" +#include "chrome/common/chrome_paths.h" +#include "content/browser/browser_thread.h" +#include "net/base/crl_set.h" +#include "net/base/ssl_config_service.h" + +CRLSetFetcher::CRLSetFetcher() { +} + +CRLSetFetcher::~CRLSetFetcher() { +} + +bool CRLSetFetcher::GetCRLSetFilePath(FilePath* path) const { + bool ok = PathService::Get(chrome::DIR_USER_DATA, path); + if (!ok) { + NOTREACHED(); + return false; + } + *path = path->Append(chrome::kCRLSetFilename); + return true; +} + +void CRLSetFetcher::StartInitialLoad(ComponentUpdateService* cus) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + cus_ = cus; + + if (!BrowserThread::PostTask( + BrowserThread::FILE, FROM_HERE, + NewRunnableMethod( + this, + &CRLSetFetcher::DoInitialLoadFromDisk))) { + NOTREACHED(); + } +} + +void CRLSetFetcher::DoInitialLoadFromDisk() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + + FilePath crl_set_file_path; + if (!GetCRLSetFilePath(&crl_set_file_path)) + return; + + scoped_refptr<net::CRLSet> crl_set; + LoadFromDisk(crl_set_file_path, + FilePath() /* don't copy the data anywhere */, + &crl_set); + + uint32 sequence_of_loaded_crl = 0; + if (crl_set.get()) + sequence_of_loaded_crl = crl_set->sequence(); + + // Get updates, advertising the sequence number of the CRL set that we just + // loaded, if any. + if (!BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + NewRunnableMethod( + this, + &CRLSetFetcher::RegisterComponent, + sequence_of_loaded_crl))) { + NOTREACHED(); + } +} + +void CRLSetFetcher::LoadFromDisk(FilePath path, + FilePath save_to, + scoped_refptr<net::CRLSet>* out_crl_set) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + + std::string crl_set_bytes; + if (!file_util::ReadFileToString(path, &crl_set_bytes)) + return; + + scoped_refptr<net::CRLSet> crl_set; + if (!net::CRLSet::Parse(crl_set_bytes, &crl_set)) { + LOG(WARNING) << "Failed to parse CRL set from " << path.MaybeAsASCII(); + return; + } + + if (out_crl_set) + *out_crl_set = crl_set; + + if (!save_to.empty()) + file_util::WriteFile(save_to, crl_set_bytes.data(), crl_set_bytes.size()); + + VLOG(1) << "Loaded " << crl_set_bytes.size() << " bytes of CRL set from disk"; + + if (!BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + this, &CRLSetFetcher::SetCRLSetIfNewer, crl_set))) { + NOTREACHED(); + } +} + +void CRLSetFetcher::SetCRLSetIfNewer( + scoped_refptr<net::CRLSet> crl_set) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + scoped_refptr<net::CRLSet> old_crl_set(net::SSLConfigService::GetCRLSet()); + if (old_crl_set.get() && old_crl_set->sequence() > crl_set->sequence()) { + LOG(WARNING) << "Refusing to downgrade CRL set from #" + << old_crl_set->sequence() + << "to #" + << crl_set->sequence(); + } else { + net::SSLConfigService::SetCRLSet(crl_set); + VLOG(1) << "Installed CRL set #" << crl_set->sequence(); + } +} + +// TODO(agl): this is a key for testing only. Replace with a real key. +static const uint8 kPublicKeySHA256[32] = { + 0x0f, 0x0e, 0xa7, 0x94, 0x37, 0x6b, 0x60, 0x9a, + 0x90, 0x09, 0x3e, 0xbb, 0xce, 0xe8, 0xd7, 0x4b, + 0xc2, 0x78, 0x17, 0x43, 0x63, 0xd5, 0xb4, 0x43, + 0xc1, 0x49, 0xc6, 0x44, 0x40, 0x43, 0xae, 0x2a, +}; + +void CRLSetFetcher::RegisterComponent(uint32 sequence_of_loaded_crl) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + CrxComponent component; + component.pk_hash.assign(&kPublicKeySHA256[0], + &kPublicKeySHA256[0] + sizeof(kPublicKeySHA256)); + component.installer = this; + component.name = "CRLSet"; + component.version = Version(base::UintToString(sequence_of_loaded_crl)); + if (!component.version.IsValid()) { + NOTREACHED(); + component.version = Version("0"); + } + + if (cus_->RegisterComponent(component) != + ComponentUpdateService::kOk) { + NOTREACHED() << "RegisterComponent returned error"; + } +} + +void CRLSetFetcher::OnUpdateError(int error) { + LOG(WARNING) << "CRLSetFetcher got error " << error + << " from component installer"; +} + +bool CRLSetFetcher::Install(base::DictionaryValue* manifest, + const FilePath& unpack_path) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + + FilePath crl_set_file_path = unpack_path.Append(FILE_PATH_LITERAL("crl-set")); + FilePath save_to; + if (!GetCRLSetFilePath(&save_to)) + return true; + LoadFromDisk(crl_set_file_path, save_to, NULL); + return true; +} diff --git a/chrome/browser/net/crl_set_fetcher.h b/chrome/browser/net/crl_set_fetcher.h new file mode 100644 index 0000000..6725500 --- /dev/null +++ b/chrome/browser/net/crl_set_fetcher.h @@ -0,0 +1,71 @@ +// 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_CRL_SET_FETCHER_H_ +#define CHROME_BROWSER_NET_CRL_SET_FETCHER_H_ +#pragma once + +#include <string> + +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "base/task.h" +#include "base/time.h" +#include "chrome/browser/component_updater/component_updater_service.h" + +class FilePath; + +namespace base { +class DictionaryValue; +} + +namespace net { +class CRLSet; +} + +class ComponentUpdateService; + +class CRLSetFetcher : public ComponentInstaller, + public base::RefCountedThreadSafe<CRLSetFetcher> { + public: + CRLSetFetcher(); + virtual ~CRLSetFetcher(); + + void StartInitialLoad(ComponentUpdateService* cus); + + // ComponentInstaller interface + virtual void OnUpdateError(int error) OVERRIDE; + virtual bool Install(base::DictionaryValue* manifest, + const FilePath& unpack_path) OVERRIDE; + + private: + // GetCRLSetFilePath gets the path of the CRL set file in the user data + // dir. + bool GetCRLSetFilePath(FilePath* path) const; + + // DoInitialLoadFromDisk runs on the FILE thread and attempts to load a CRL + // set from the user-data dir. It then registers this object as a component + // in order to get updates. + void DoInitialLoadFromDisk(); + + // LoadFromDisk runs on the FILE thread and attempts to load a CRL set + // from |load_from|. If successful, it saves a copy of the CRLSet to + // |save_to|, unless |save_to| is empty. + void LoadFromDisk(FilePath load_from, + FilePath save_to, + scoped_refptr<net::CRLSet>* maybe_out_crl_set); + + // SetCRLSetIfNewer runs on the IO thread and installs a CRL set + // as the global CRL set if it's newer than the existing one. + void SetCRLSetIfNewer(scoped_refptr<net::CRLSet> crl_set); + + // RegisterComponent registers this object as a component updater. + void RegisterComponent(uint32 sequence_of_loaded_crl); + + ComponentUpdateService* cus_; + + DISALLOW_COPY_AND_ASSIGN(CRLSetFetcher); +}; + +#endif // CHROME_BROWSER_NET_CRL_SET_FETCHER_H_ diff --git a/chrome/browser/ui/browser_init.cc b/chrome/browser/ui/browser_init.cc index 55264ac..237de73 100644 --- a/chrome/browser/ui/browser_init.cc +++ b/chrome/browser/ui/browser_init.cc @@ -30,6 +30,7 @@ #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/pack_extension_job.h" #include "chrome/browser/first_run/first_run.h" +#include "chrome/browser/net/crl_set_fetcher.h" #include "chrome/browser/infobars/infobar_tab_helper.h" #include "chrome/browser/net/predictor.h" #include "chrome/browser/net/url_fixer_upper.h" @@ -529,6 +530,12 @@ void RegisterComponentsForUpdate() { // a task to the UI thread to do registration once you done the necessary // file IO to know your current version. RegisterPepperFlashComponent(cus); + + // CRLSetFetcher attempts to load a CRL set from either the local disk + // or network. + // TODO(agl): this is disabled for now while it's plumbed in. + // g_browser_process->crl_set_fetcher()->StartInitialLoad(cus); + cus->Start(); } diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 38e8ef9..3756663 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1540,6 +1540,8 @@ 'browser/net/connect_interceptor.h', 'browser/net/connection_tester.cc', 'browser/net/connection_tester.h', + 'browser/net/crl_set_fetcher.cc', + 'browser/net/crl_set_fetcher.h', 'browser/net/gaia/gaia_oauth_consumer.h', 'browser/net/gaia/gaia_oauth_fetcher.cc', 'browser/net/gaia/gaia_oauth_fetcher.h', diff --git a/chrome/common/chrome_constants.cc b/chrome/common/chrome_constants.cc index 447b7bc..33493e6 100644 --- a/chrome/common/chrome_constants.cc +++ b/chrome/common/chrome_constants.cc @@ -124,6 +124,8 @@ const FilePath::CharType kExtensionKeyFileExtension[] = FPL(".pem"); // filenames const FilePath::CharType kArchivedHistoryFilename[] = FPL("Archived History"); const FilePath::CharType kCacheDirname[] = FPL("Cache"); +const FilePath::CharType kCRLSetFilename[] = + FPL("Certificate Revocation Lists"); const FilePath::CharType kMediaCacheDirname[] = FPL("Media Cache"); const FilePath::CharType kOffTheRecordMediaCacheDirname[] = FPL("Incognito Media Cache"); diff --git a/chrome/common/chrome_constants.h b/chrome/common/chrome_constants.h index 7f196a3..56649e2 100644 --- a/chrome/common/chrome_constants.h +++ b/chrome/common/chrome_constants.h @@ -54,6 +54,7 @@ extern const FilePath::CharType kExtensionKeyFileExtension[]; // filenames extern const FilePath::CharType kArchivedHistoryFilename[]; extern const FilePath::CharType kCacheDirname[]; +extern const FilePath::CharType kCRLSetFilename[]; extern const FilePath::CharType kMediaCacheDirname[]; extern const FilePath::CharType kOffTheRecordMediaCacheDirname[]; extern const FilePath::CharType kAppCacheDirname[]; diff --git a/chrome/test/base/testing_browser_process.cc b/chrome/test/base/testing_browser_process.cc index f1cf45a..6f24fdc 100644 --- a/chrome/test/base/testing_browser_process.cc +++ b/chrome/test/base/testing_browser_process.cc @@ -257,6 +257,10 @@ ComponentUpdateService* TestingBrowserProcess::component_updater() { return NULL; } +CRLSetFetcher* TestingBrowserProcess::crl_set_fetcher() { + return NULL; +} + void TestingBrowserProcess::SetLocalState(PrefService* local_state) { if (!local_state && notification_ui_manager_.get()) notification_ui_manager_.reset(); // Used local_state_. diff --git a/chrome/test/base/testing_browser_process.h b/chrome/test/base/testing_browser_process.h index 58cfdc9..9f8b4b9 100644 --- a/chrome/test/base/testing_browser_process.h +++ b/chrome/test/base/testing_browser_process.h @@ -19,6 +19,7 @@ #include "content/common/notification_service.h" class BackgroundModeManager; +class CRLSetFetcher; class IOThread; class GoogleURLTracker; class MHTMLGenerationManager; @@ -122,6 +123,7 @@ class TestingBrowserProcess : public BrowserProcess { virtual MHTMLGenerationManager* mhtml_generation_manager() OVERRIDE; virtual GpuBlacklistUpdater* gpu_blacklist_updater() OVERRIDE; virtual ComponentUpdateService* component_updater() OVERRIDE; + virtual CRLSetFetcher* crl_set_fetcher() OVERRIDE; // Set the local state for tests. Consumer is responsible for cleaning it up // afterwards (using ScopedTestingLocalState, for example). diff --git a/net/base/crl_set.h b/net/base/crl_set.h index 8a7440a..1f5f143 100644 --- a/net/base/crl_set.h +++ b/net/base/crl_set.h @@ -22,7 +22,7 @@ namespace net { // A CRLSet is a structure that lists the serial numbers of revoked // certificates from a number of issuers where issuers are identified by the // SHA256 of their SubjectPublicKeyInfo. -class NET_EXPORT_PRIVATE CRLSet : public base::RefCounted<CRLSet> { +class NET_EXPORT CRLSet : public base::RefCountedThreadSafe<CRLSet> { public: enum Result { REVOKED, // the certificate should be rejected. diff --git a/net/base/ssl_config_service.cc b/net/base/ssl_config_service.cc index 8631bc9..6240ea0 100644 --- a/net/base/ssl_config_service.cc +++ b/net/base/ssl_config_service.cc @@ -59,6 +59,7 @@ static bool g_cached_info_enabled = false; static bool g_origin_bound_certs_enabled = false; static bool g_false_start_enabled = true; static bool g_dns_cert_provenance_checking = false; +static scoped_refptr<CRLSet> g_crl_set = NULL; // static void SSLConfigService::DisableFalseStart() { @@ -81,6 +82,15 @@ bool SSLConfigService::dns_cert_provenance_checking_enabled() { } // static +void SSLConfigService::SetCRLSet(scoped_refptr<CRLSet> crl_set) { + g_crl_set = crl_set; +} + +// static +scoped_refptr<CRLSet> SSLConfigService::GetCRLSet() { + return g_crl_set; +} + void SSLConfigService::EnableCachedInfo() { g_cached_info_enabled = true; } diff --git a/net/base/ssl_config_service.h b/net/base/ssl_config_service.h index 3e32587..8f2e9d2 100644 --- a/net/base/ssl_config_service.h +++ b/net/base/ssl_config_service.h @@ -13,6 +13,7 @@ #include "base/observer_list.h" #include "base/string_piece.h" #include "net/base/cert_status_flags.h" +#include "net/base/crl_set.h" #include "net/base/net_export.h" #include "net/base/x509_certificate.h" @@ -104,6 +105,8 @@ struct NET_EXPORT SSLConfig { std::string next_protos; scoped_refptr<X509Certificate> client_cert; + + scoped_refptr<CRLSet> crl_set; }; // The interface for retrieving the SSL configuration. This interface @@ -154,6 +157,11 @@ class NET_EXPORT SSLConfigService static void EnableDNSCertProvenanceChecking(); static bool dns_cert_provenance_checking_enabled(); + // Sets and gets the current, global CRL set. + // TODO(agl): currently unused. + static void SetCRLSet(scoped_refptr<CRLSet> crl_set); + static scoped_refptr<CRLSet> GetCRLSet(); + // Enables the TLS cached info extension, which allows the server to send // just a digest of its certificate chain. static void EnableCachedInfo(); |