Home | History | Annotate | Download | only in browsing_data
      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 "chrome/browser/browsing_data/browsing_data_server_bound_cert_helper.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/logging.h"
      9 #include "base/memory/scoped_ptr.h"
     10 #include "base/message_loop/message_loop.h"
     11 #include "chrome/browser/profiles/profile.h"
     12 #include "content/public/browser/browser_thread.h"
     13 #include "net/ssl/server_bound_cert_service.h"
     14 #include "net/url_request/url_request_context.h"
     15 #include "net/url_request/url_request_context_getter.h"
     16 
     17 namespace {
     18 
     19 class BrowsingDataServerBoundCertHelperImpl
     20     : public BrowsingDataServerBoundCertHelper {
     21  public:
     22   explicit BrowsingDataServerBoundCertHelperImpl(Profile* profile);
     23 
     24   // BrowsingDataServerBoundCertHelper methods.
     25   virtual void StartFetching(const FetchResultCallback& callback) OVERRIDE;
     26   virtual void DeleteServerBoundCert(const std::string& server_id) OVERRIDE;
     27 
     28  private:
     29   virtual ~BrowsingDataServerBoundCertHelperImpl();
     30 
     31   // Fetch the certs. This must be called in the IO thread.
     32   void FetchOnIOThread();
     33 
     34   void OnFetchComplete(
     35       const net::ServerBoundCertStore::ServerBoundCertList& cert_list);
     36 
     37   // Notifies the completion callback. This must be called in the UI thread.
     38   void NotifyInUIThread(
     39       const net::ServerBoundCertStore::ServerBoundCertList& cert_list);
     40 
     41   // Delete a single cert. This must be called in IO thread.
     42   void DeleteOnIOThread(const std::string& server_id);
     43 
     44   // Called when deletion is done.
     45   void DeleteCallback();
     46 
     47   // Indicates whether or not we're currently fetching information:
     48   // it's true when StartFetching() is called in the UI thread, and it's reset
     49   // after we notify the callback in the UI thread.
     50   // This only mutates on the UI thread.
     51   bool is_fetching_;
     52 
     53   scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
     54 
     55   // This only mutates on the UI thread.
     56   FetchResultCallback completion_callback_;
     57 
     58   DISALLOW_COPY_AND_ASSIGN(BrowsingDataServerBoundCertHelperImpl);
     59 };
     60 
     61 BrowsingDataServerBoundCertHelperImpl::
     62 BrowsingDataServerBoundCertHelperImpl(Profile* profile)
     63     : is_fetching_(false),
     64       request_context_getter_(profile->GetRequestContext()) {
     65   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
     66 }
     67 
     68 BrowsingDataServerBoundCertHelperImpl::
     69 ~BrowsingDataServerBoundCertHelperImpl() {
     70 }
     71 
     72 void BrowsingDataServerBoundCertHelperImpl::StartFetching(
     73     const FetchResultCallback& callback) {
     74   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
     75   DCHECK(!is_fetching_);
     76   DCHECK(!callback.is_null());
     77   DCHECK(completion_callback_.is_null());
     78   is_fetching_ = true;
     79   completion_callback_ = callback;
     80   content::BrowserThread::PostTask(
     81       content::BrowserThread::IO, FROM_HERE,
     82       base::Bind(&BrowsingDataServerBoundCertHelperImpl::FetchOnIOThread,
     83                  this));
     84 }
     85 
     86 void BrowsingDataServerBoundCertHelperImpl::DeleteServerBoundCert(
     87     const std::string& server_id) {
     88   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
     89   content::BrowserThread::PostTask(
     90       content::BrowserThread::IO, FROM_HERE,
     91       base::Bind(&BrowsingDataServerBoundCertHelperImpl::DeleteOnIOThread,
     92                  this, server_id));
     93 }
     94 
     95 void BrowsingDataServerBoundCertHelperImpl::FetchOnIOThread() {
     96   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
     97   net::ServerBoundCertStore* cert_store =
     98       request_context_getter_->GetURLRequestContext()->
     99       server_bound_cert_service()->GetCertStore();
    100   if (cert_store) {
    101     cert_store->GetAllServerBoundCerts(base::Bind(
    102         &BrowsingDataServerBoundCertHelperImpl::OnFetchComplete, this));
    103   } else {
    104     OnFetchComplete(net::ServerBoundCertStore::ServerBoundCertList());
    105   }
    106 }
    107 
    108 void BrowsingDataServerBoundCertHelperImpl::OnFetchComplete(
    109     const net::ServerBoundCertStore::ServerBoundCertList& cert_list) {
    110   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
    111   content::BrowserThread::PostTask(
    112       content::BrowserThread::UI, FROM_HERE,
    113       base::Bind(&BrowsingDataServerBoundCertHelperImpl::NotifyInUIThread,
    114                  this, cert_list));
    115 }
    116 
    117 void BrowsingDataServerBoundCertHelperImpl::NotifyInUIThread(
    118     const net::ServerBoundCertStore::ServerBoundCertList& cert_list) {
    119   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
    120   DCHECK(is_fetching_);
    121   is_fetching_ = false;
    122   completion_callback_.Run(cert_list);
    123   completion_callback_.Reset();
    124 }
    125 
    126 void BrowsingDataServerBoundCertHelperImpl::DeleteOnIOThread(
    127     const std::string& server_id) {
    128   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
    129   net::ServerBoundCertStore* cert_store =
    130       request_context_getter_->GetURLRequestContext()->
    131       server_bound_cert_service()->GetCertStore();
    132   if (cert_store) {
    133     cert_store->DeleteServerBoundCert(
    134         server_id,
    135         base::Bind(&BrowsingDataServerBoundCertHelperImpl::DeleteCallback,
    136                    this));
    137   }
    138 }
    139 
    140 void BrowsingDataServerBoundCertHelperImpl::DeleteCallback() {
    141   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
    142   // Need to close open SSL connections which may be using the channel ids we
    143   // are deleting.
    144   // TODO(mattm): http://crbug.com/166069 Make the server bound cert
    145   // service/store have observers that can notify relevant things directly.
    146   request_context_getter_->GetURLRequestContext()->ssl_config_service()->
    147       NotifySSLConfigChange();
    148 }
    149 
    150 }  // namespace
    151 
    152 // static
    153 BrowsingDataServerBoundCertHelper*
    154 BrowsingDataServerBoundCertHelper::Create(Profile* profile) {
    155   return new BrowsingDataServerBoundCertHelperImpl(profile);
    156 }
    157 
    158 CannedBrowsingDataServerBoundCertHelper::
    159 CannedBrowsingDataServerBoundCertHelper() {}
    160 
    161 CannedBrowsingDataServerBoundCertHelper::
    162 ~CannedBrowsingDataServerBoundCertHelper() {}
    163 
    164 CannedBrowsingDataServerBoundCertHelper*
    165 CannedBrowsingDataServerBoundCertHelper::Clone() {
    166   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
    167   CannedBrowsingDataServerBoundCertHelper* clone =
    168       new CannedBrowsingDataServerBoundCertHelper();
    169 
    170   clone->server_bound_cert_map_ = server_bound_cert_map_;
    171   return clone;
    172 }
    173 
    174 void CannedBrowsingDataServerBoundCertHelper::AddServerBoundCert(
    175     const net::ServerBoundCertStore::ServerBoundCert& server_bound_cert) {
    176   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
    177   server_bound_cert_map_[server_bound_cert.server_identifier()] =
    178       server_bound_cert;
    179 }
    180 
    181 void CannedBrowsingDataServerBoundCertHelper::Reset() {
    182   server_bound_cert_map_.clear();
    183 }
    184 
    185 bool CannedBrowsingDataServerBoundCertHelper::empty() const {
    186   return server_bound_cert_map_.empty();
    187 }
    188 
    189 size_t CannedBrowsingDataServerBoundCertHelper::GetCertCount() const {
    190   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
    191   return server_bound_cert_map_.size();
    192 }
    193 
    194 void CannedBrowsingDataServerBoundCertHelper::StartFetching(
    195     const FetchResultCallback& callback) {
    196   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
    197   if (callback.is_null())
    198     return;
    199   // We post a task to emulate async fetching behavior.
    200   completion_callback_ = callback;
    201   base::MessageLoop::current()->PostTask(
    202       FROM_HERE,
    203       base::Bind(&CannedBrowsingDataServerBoundCertHelper::FinishFetching,
    204                  this));
    205 }
    206 
    207 void CannedBrowsingDataServerBoundCertHelper::FinishFetching() {
    208   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
    209   net::ServerBoundCertStore::ServerBoundCertList cert_list;
    210   for (ServerBoundCertMap::iterator i = server_bound_cert_map_.begin();
    211        i != server_bound_cert_map_.end(); ++i)
    212     cert_list.push_back(i->second);
    213   completion_callback_.Run(cert_list);
    214 }
    215 
    216 void CannedBrowsingDataServerBoundCertHelper::DeleteServerBoundCert(
    217     const std::string& server_id) {
    218   NOTREACHED();
    219 }
    220