| // Copyright (c) 2012 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/ssl/ssl_config_service.h" | 
 |  | 
 | #include "base/lazy_instance.h" | 
 | #include "base/synchronization/lock.h" | 
 | #include "net/ssl/ssl_config_service_defaults.h" | 
 |  | 
 | namespace net { | 
 |  | 
 | SSLConfigService::SSLConfigService() | 
 |     : observer_list_(ObserverList<Observer>::NOTIFY_EXISTING_ONLY) { | 
 | } | 
 |  | 
 | // GlobalSSLObject holds a reference to a global SSL object, such as the | 
 | // CRLSet or the EVCertsWhitelist. It simply wraps a lock  around a | 
 | // scoped_refptr so that getting a reference doesn't race with | 
 | // updating the global object. | 
 | template <class T> | 
 | class GlobalSSLObject { | 
 |  public: | 
 |   void Set(const scoped_refptr<T>& new_ssl_object) { | 
 |     base::AutoLock locked(lock_); | 
 |     ssl_object_ = new_ssl_object; | 
 |   } | 
 |  | 
 |   scoped_refptr<T> Get() const { | 
 |     base::AutoLock locked(lock_); | 
 |     return ssl_object_; | 
 |   } | 
 |  | 
 |  private: | 
 |   scoped_refptr<T> ssl_object_; | 
 |   mutable base::Lock lock_; | 
 | }; | 
 |  | 
 | typedef GlobalSSLObject<CRLSet> GlobalCRLSet; | 
 | typedef GlobalSSLObject<ct::EVCertsWhitelist> GlobalEVCertsWhitelist; | 
 |  | 
 | base::LazyInstance<GlobalCRLSet>::Leaky g_crl_set = LAZY_INSTANCE_INITIALIZER; | 
 | base::LazyInstance<GlobalEVCertsWhitelist>::Leaky g_ev_whitelist = | 
 |     LAZY_INSTANCE_INITIALIZER; | 
 |  | 
 | // static | 
 | void SSLConfigService::SetCRLSet(scoped_refptr<CRLSet> crl_set) { | 
 |   // Note: this can be called concurently with GetCRLSet(). | 
 |   g_crl_set.Get().Set(crl_set); | 
 | } | 
 |  | 
 | // static | 
 | scoped_refptr<CRLSet> SSLConfigService::GetCRLSet() { | 
 |   return g_crl_set.Get().Get(); | 
 | } | 
 |  | 
 | // static | 
 | void SSLConfigService::SetEVCertsWhitelist( | 
 |     scoped_refptr<ct::EVCertsWhitelist> ev_whitelist) { | 
 |   g_ev_whitelist.Get().Set(ev_whitelist); | 
 | } | 
 |  | 
 | // static | 
 | scoped_refptr<ct::EVCertsWhitelist> SSLConfigService::GetEVCertsWhitelist() { | 
 |   return g_ev_whitelist.Get().Get(); | 
 | } | 
 |  | 
 | void SSLConfigService::AddObserver(Observer* observer) { | 
 |   observer_list_.AddObserver(observer); | 
 | } | 
 |  | 
 | void SSLConfigService::RemoveObserver(Observer* observer) { | 
 |   observer_list_.RemoveObserver(observer); | 
 | } | 
 |  | 
 | void SSLConfigService::NotifySSLConfigChange() { | 
 |   FOR_EACH_OBSERVER(Observer, observer_list_, OnSSLConfigChanged()); | 
 | } | 
 |  | 
 | SSLConfigService::~SSLConfigService() { | 
 | } | 
 |  | 
 | void SSLConfigService::ProcessConfigUpdate(const SSLConfig& orig_config, | 
 |                                            const SSLConfig& new_config) { | 
 |   bool config_changed = | 
 |       (orig_config.rev_checking_enabled != new_config.rev_checking_enabled) || | 
 |       (orig_config.rev_checking_required_local_anchors != | 
 |        new_config.rev_checking_required_local_anchors) || | 
 |       (orig_config.version_min != new_config.version_min) || | 
 |       (orig_config.version_max != new_config.version_max) || | 
 |       (orig_config.disabled_cipher_suites != | 
 |        new_config.disabled_cipher_suites) || | 
 |       (orig_config.channel_id_enabled != new_config.channel_id_enabled) || | 
 |       (orig_config.false_start_enabled != new_config.false_start_enabled) || | 
 |       (orig_config.require_forward_secrecy != | 
 |        new_config.require_forward_secrecy); | 
 |  | 
 |   if (config_changed) | 
 |     NotifySSLConfigChange(); | 
 | } | 
 |  | 
 | }  // namespace net |