diff options
Diffstat (limited to 'chromium/net/ssl/ssl_config_service.cc')
-rw-r--r-- | chromium/net/ssl/ssl_config_service.cc | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/chromium/net/ssl/ssl_config_service.cc b/chromium/net/ssl/ssl_config_service.cc new file mode 100644 index 00000000000..a2c34a26852 --- /dev/null +++ b/chromium/net/ssl/ssl_config_service.cc @@ -0,0 +1,183 @@ +// 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/memory/ref_counted.h" +#include "base/synchronization/lock.h" +#include "net/cert/crl_set.h" +#include "net/ssl/ssl_config_service_defaults.h" + +#if defined(USE_OPENSSL) +#include <openssl/ssl.h> +#endif + +namespace net { + +static uint16 g_default_version_min = SSL_PROTOCOL_VERSION_SSL3; + +static uint16 g_default_version_max = +#if defined(USE_OPENSSL) +#if defined(SSL_OP_NO_TLSv1_2) + SSL_PROTOCOL_VERSION_TLS1_2; +#elif defined(SSL_OP_NO_TLSv1_1) + SSL_PROTOCOL_VERSION_TLS1_1; +#else + SSL_PROTOCOL_VERSION_TLS1; +#endif +#else + SSL_PROTOCOL_VERSION_TLS1_2; +#endif + +SSLConfig::CertAndStatus::CertAndStatus() : cert_status(0) {} + +SSLConfig::CertAndStatus::~CertAndStatus() {} + +SSLConfig::SSLConfig() + : rev_checking_enabled(false), + rev_checking_required_local_anchors(false), + version_min(g_default_version_min), + version_max(g_default_version_max), + cached_info_enabled(false), + channel_id_enabled(true), + false_start_enabled(true), + unrestricted_ssl3_fallback_enabled(false), + send_client_cert(false), + verify_ev_cert(false), + version_fallback(false), + cert_io_enabled(true) { +} + +SSLConfig::~SSLConfig() { +} + +bool SSLConfig::IsAllowedBadCert(X509Certificate* cert, + CertStatus* cert_status) const { + std::string der_cert; + if (!X509Certificate::GetDEREncoded(cert->os_cert_handle(), &der_cert)) + return false; + return IsAllowedBadCert(der_cert, cert_status); +} + +bool SSLConfig::IsAllowedBadCert(const base::StringPiece& der_cert, + CertStatus* cert_status) const { + for (size_t i = 0; i < allowed_bad_certs.size(); ++i) { + if (der_cert == allowed_bad_certs[i].der_cert) { + if (cert_status) + *cert_status = allowed_bad_certs[i].cert_status; + return true; + } + } + return false; +} + +SSLConfigService::SSLConfigService() + : observer_list_(ObserverList<Observer>::NOTIFY_EXISTING_ONLY) { +} + +static bool g_cached_info_enabled = false; + +// GlobalCRLSet holds a reference to the global CRLSet. It simply wraps a lock +// around a scoped_refptr so that getting a reference doesn't race with +// updating the CRLSet. +class GlobalCRLSet { + public: + void Set(const scoped_refptr<CRLSet>& new_crl_set) { + base::AutoLock locked(lock_); + crl_set_ = new_crl_set; + } + + scoped_refptr<CRLSet> Get() const { + base::AutoLock locked(lock_); + return crl_set_; + } + + private: + scoped_refptr<CRLSet> crl_set_; + mutable base::Lock lock_; +}; + +base::LazyInstance<GlobalCRLSet>::Leaky g_crl_set = 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(); +} + +void SSLConfigService::EnableCachedInfo() { + g_cached_info_enabled = true; +} + +// static +bool SSLConfigService::cached_info_enabled() { + return g_cached_info_enabled; +} + +// static +uint16 SSLConfigService::default_version_min() { + return g_default_version_min; +} + +// static +uint16 SSLConfigService::default_version_max() { + return g_default_version_max; +} + +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() { +} + +// static +void SSLConfigService::SetSSLConfigFlags(SSLConfig* ssl_config) { + ssl_config->cached_info_enabled = g_cached_info_enabled; +} + +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.unrestricted_ssl3_fallback_enabled != + new_config.unrestricted_ssl3_fallback_enabled); + + if (config_changed) + NotifySSLConfigChange(); +} + +// static +bool SSLConfigService::IsSNIAvailable(SSLConfigService* service) { + if (!service) + return false; + + SSLConfig ssl_config; + service->GetSSLConfig(&ssl_config); + return ssl_config.version_max >= SSL_PROTOCOL_VERSION_TLS1; +} + +} // namespace net |