|  | // 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_(base::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_ecdhe != new_config.require_ecdhe); | 
|  |  | 
|  | if (config_changed) | 
|  | NotifySSLConfigChange(); | 
|  | } | 
|  |  | 
|  | }  // namespace net |