diff --git a/atom/browser/atom_browser_context.cc b/atom/browser/atom_browser_context.cc index 63c8c81fb4df..e076fe85c176 100644 --- a/atom/browser/atom_browser_context.cc +++ b/atom/browser/atom_browser_context.cc @@ -12,6 +12,7 @@ #include "atom/browser/browser.h" #include "atom/browser/net/asar/asar_protocol_handler.h" #include "atom/browser/net/atom_cert_verifier.h" +#include "atom/browser/net/atom_ct_delegate.h" #include "atom/browser/net/atom_network_delegate.h" #include "atom/browser/net/atom_ssl_config_service.h" #include "atom/browser/net/atom_url_request_job_factory.h" @@ -67,10 +68,11 @@ std::string RemoveWhitespace(const std::string& str) { } // namespace -AtomBrowserContext::AtomBrowserContext( - const std::string& partition, bool in_memory, - const base::DictionaryValue& options) +AtomBrowserContext::AtomBrowserContext(const std::string& partition, + bool in_memory, + const base::DictionaryValue& options) : brightray::BrowserContext(partition, in_memory), + ct_delegate_(new AtomCTDelegate), network_delegate_(new AtomNetworkDelegate), cookie_delegate_(new AtomCookieDelegate) { // Construct user agent string. @@ -190,7 +192,7 @@ content::PermissionManager* AtomBrowserContext::GetPermissionManager() { } std::unique_ptr AtomBrowserContext::CreateCertVerifier() { - return base::WrapUnique(new AtomCertVerifier); + return base::WrapUnique(new AtomCertVerifier(ct_delegate_.get())); } net::SSLConfigService* AtomBrowserContext::CreateSSLConfigService() { @@ -205,6 +207,11 @@ std::vector AtomBrowserContext::GetCookieableSchemes() { return default_schemes; } +net::TransportSecurityState::RequireCTDelegate* +AtomBrowserContext::GetRequireCTDelegate() { + return ct_delegate_.get(); +} + void AtomBrowserContext::RegisterPrefs(PrefRegistrySimple* pref_registry) { pref_registry->RegisterFilePathPref(prefs::kSelectFileLastDirectory, base::FilePath()); diff --git a/atom/browser/atom_browser_context.h b/atom/browser/atom_browser_context.h index 0ff1cc6321ad..f149e62cb279 100644 --- a/atom/browser/atom_browser_context.h +++ b/atom/browser/atom_browser_context.h @@ -15,6 +15,7 @@ namespace atom { class AtomBlobReader; +class AtomCTDelegate; class AtomDownloadManagerDelegate; class AtomNetworkDelegate; class AtomPermissionManager; @@ -42,6 +43,8 @@ class AtomBrowserContext : public brightray::BrowserContext { std::unique_ptr CreateCertVerifier() override; net::SSLConfigService* CreateSSLConfigService() override; std::vector GetCookieableSchemes() override; + net::TransportSecurityState::RequireCTDelegate* GetRequireCTDelegate() + override; // content::BrowserContext: content::DownloadManagerDelegate* GetDownloadManagerDelegate() override; @@ -67,6 +70,7 @@ class AtomBrowserContext : public brightray::BrowserContext { std::unique_ptr guest_manager_; std::unique_ptr permission_manager_; std::unique_ptr blob_reader_; + std::unique_ptr ct_delegate_; std::string user_agent_; bool use_cache_; diff --git a/atom/browser/net/atom_cert_verifier.cc b/atom/browser/net/atom_cert_verifier.cc index 7fb2ce72297c..9892845cc83f 100644 --- a/atom/browser/net/atom_cert_verifier.cc +++ b/atom/browser/net/atom_cert_verifier.cc @@ -5,9 +5,11 @@ #include "atom/browser/net/atom_cert_verifier.h" #include "atom/browser/browser.h" +#include "atom/browser/net/atom_ct_delegate.h" #include "atom/common/native_mate_converters/net_converter.h" #include "content/public/browser/browser_thread.h" #include "net/base/net_errors.h" +#include "net/cert/cert_verify_result.h" #include "net/cert/crl_set.h" #include "net/cert/x509_certificate.h" @@ -28,12 +30,11 @@ void OnResult( } // namespace -AtomCertVerifier::AtomCertVerifier() - : default_cert_verifier_(net::CertVerifier::CreateDefault()) { -} +AtomCertVerifier::AtomCertVerifier(AtomCTDelegate* ct_delegate) + : default_cert_verifier_(net::CertVerifier::CreateDefault()), + ct_delegate_(ct_delegate) {} -AtomCertVerifier::~AtomCertVerifier() { -} +AtomCertVerifier::~AtomCertVerifier() {} void AtomCertVerifier::SetVerifyProc(const VerifyProc& proc) { verify_proc_ = proc; @@ -48,9 +49,15 @@ int AtomCertVerifier::Verify( const net::BoundNetLog& net_log) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - if (verify_proc_.is_null()) + if (verify_proc_.is_null()) { + ct_delegate_->ClearCTExcludedHostsList(); return default_cert_verifier_->Verify( params, crl_set, verify_result, callback, out_req, net_log); + } + + verify_result->Reset(); + verify_result->verified_cert = params.certificate(); + ct_delegate_->AddCTExcludedHost(params.hostname()); BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, diff --git a/atom/browser/net/atom_cert_verifier.h b/atom/browser/net/atom_cert_verifier.h index 74b8f2784c16..7582fae74f61 100644 --- a/atom/browser/net/atom_cert_verifier.h +++ b/atom/browser/net/atom_cert_verifier.h @@ -12,9 +12,11 @@ namespace atom { +class AtomCTDelegate; + class AtomCertVerifier : public net::CertVerifier { public: - AtomCertVerifier(); + explicit AtomCertVerifier(AtomCTDelegate* ct_delegate); virtual ~AtomCertVerifier(); using VerifyProc = @@ -37,6 +39,7 @@ class AtomCertVerifier : public net::CertVerifier { private: VerifyProc verify_proc_; std::unique_ptr default_cert_verifier_; + AtomCTDelegate* ct_delegate_; DISALLOW_COPY_AND_ASSIGN(AtomCertVerifier); }; diff --git a/atom/browser/net/atom_ct_delegate.cc b/atom/browser/net/atom_ct_delegate.cc new file mode 100644 index 000000000000..66d6c93adb35 --- /dev/null +++ b/atom/browser/net/atom_ct_delegate.cc @@ -0,0 +1,34 @@ +// Copyright (c) 2016 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/net/atom_ct_delegate.h" + +#include "content/public/browser/browser_thread.h" + +namespace atom { + +AtomCTDelegate::AtomCTDelegate() {} + +AtomCTDelegate::~AtomCTDelegate() {} + +void AtomCTDelegate::AddCTExcludedHost(const std::string& host) { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + ct_excluded_hosts_.insert(host); +} + +void AtomCTDelegate::ClearCTExcludedHostsList() { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + ct_excluded_hosts_.clear(); +} + +AtomCTDelegate::CTRequirementLevel AtomCTDelegate::IsCTRequiredForHost( + const std::string& host) { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + if (!ct_excluded_hosts_.empty() && + (ct_excluded_hosts_.find(host) != ct_excluded_hosts_.end())) + return CTRequirementLevel::NOT_REQUIRED; + return CTRequirementLevel::DEFAULT; +} + +} // namespace atom diff --git a/atom/browser/net/atom_ct_delegate.h b/atom/browser/net/atom_ct_delegate.h new file mode 100644 index 000000000000..680071eaa06c --- /dev/null +++ b/atom/browser/net/atom_ct_delegate.h @@ -0,0 +1,33 @@ +// Copyright (c) 2016 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_NET_ATOM_CT_DELEGATE_H_ +#define ATOM_BROWSER_NET_ATOM_CT_DELEGATE_H_ + +#include +#include + +#include "net/http/transport_security_state.h" + +namespace atom { + +class AtomCTDelegate : public net::TransportSecurityState::RequireCTDelegate { + public: + AtomCTDelegate(); + ~AtomCTDelegate() override; + + void AddCTExcludedHost(const std::string& host); + void ClearCTExcludedHostsList(); + + // net::TransportSecurityState::RequireCTDelegate: + CTRequirementLevel IsCTRequiredForHost(const std::string& host) override; + + private: + std::set ct_excluded_hosts_; + DISALLOW_COPY_AND_ASSIGN(AtomCTDelegate); +}; + +} // namespace atom + +#endif // ATOM_BROWSER_NET_ATOM_CT_DELEGATE_H_ diff --git a/filenames.gypi b/filenames.gypi index 9c4b42f622d5..f1ee8d069c34 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -227,6 +227,8 @@ 'atom/browser/net/asar/url_request_asar_job.h', 'atom/browser/net/atom_cert_verifier.cc', 'atom/browser/net/atom_cert_verifier.h', + 'atom/browser/net/atom_ct_delegate.cc', + 'atom/browser/net/atom_ct_delegate.h', 'atom/browser/net/atom_cookie_delegate.cc', 'atom/browser/net/atom_cookie_delegate.h', 'atom/browser/net/atom_network_delegate.cc',