diff --git a/BUILD.gn b/BUILD.gn index 021aec508..0b3e96910 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -348,6 +348,7 @@ static_library("libcef_static") { "libcef/browser/net/chrome_scheme_handler.h", "libcef/browser/net/cookie_store_proxy.cc", "libcef/browser/net/cookie_store_proxy.h", + "libcef/browser/net/crlset_file_util_impl.cc", "libcef/browser/net/devtools_scheme_handler.cc", "libcef/browser/net/devtools_scheme_handler.h", "libcef/browser/net/internal_scheme_handler.cc", diff --git a/include/capi/cef_file_util_capi.h b/include/capi/cef_file_util_capi.h index 4602492fb..a7e38e5ee 100644 --- a/include/capi/cef_file_util_capi.h +++ b/include/capi/cef_file_util_capi.h @@ -33,7 +33,7 @@ // by hand. See the translator.README.txt file in the tools directory for // more information. // -// $hash=4601edefadfafea031f2c5df498262fc2142252b$ +// $hash=1c02b57893a3f78c436bc2ab66c63753edfb174a$ // #ifndef CEF_INCLUDE_CAPI_CEF_FILE_UTIL_CAPI_H_ @@ -114,6 +114,16 @@ CEF_EXPORT int cef_zip_directory(const cef_string_t* src_dir, const cef_string_t* dest_file, int include_hidden_files); +/// +// Loads the existing "Certificate Revocation Lists" file that is managed by +// Google Chrome. This file can generally be found in Chrome's User Data +// directory (e.g. "C:\Users\[User]\AppData\Local\Google\Chrome\User Data\" on +// Windows) and is updated periodically by Chrome's component updater service. +// Must be called in the browser process after the context has been initialized. +// See https://dev.chromium.org/Home/chromium-security/crlsets for background. +/// +CEF_EXPORT void cef_load_crlsets_file(const cef_string_t* path); + #ifdef __cplusplus } #endif diff --git a/include/cef_file_util.h b/include/cef_file_util.h index d18f886ca..8dd1ff644 100644 --- a/include/cef_file_util.h +++ b/include/cef_file_util.h @@ -115,4 +115,15 @@ bool CefZipDirectory(const CefString& src_dir, const CefString& dest_file, bool include_hidden_files); +/// +// Loads the existing "Certificate Revocation Lists" file that is managed by +// Google Chrome. This file can generally be found in Chrome's User Data +// directory (e.g. "C:\Users\[User]\AppData\Local\Google\Chrome\User Data\" on +// Windows) and is updated periodically by Chrome's component updater service. +// Must be called in the browser process after the context has been initialized. +// See https://dev.chromium.org/Home/chromium-security/crlsets for background. +/// +/*--cef()--*/ +void CefLoadCRLSetsFile(const CefString& path); + #endif // CEF_INCLUDE_CEF_FILE_UTIL_H_ diff --git a/libcef/browser/net/crlset_file_util_impl.cc b/libcef/browser/net/crlset_file_util_impl.cc new file mode 100644 index 000000000..442a44e9f --- /dev/null +++ b/libcef/browser/net/crlset_file_util_impl.cc @@ -0,0 +1,65 @@ +// Copyright 2017 The Chromium Embedded Framework 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 "include/cef_file_util.h" + +#include "libcef/browser/context.h" +#include "libcef/browser/thread_util.h" + +#include "base/files/file_util.h" +#include "base/logging.h" +#include "base/task_scheduler/post_task.h" +#include "base/threading/thread_restrictions.h" +#include "net/cert/crl_set.h" +#include "net/cert/crl_set_storage.h" +#include "net/ssl/ssl_config_service.h" + +namespace { + +// Based on chrome/browser/net/crl_set_fetcher.cc. + +void SetCRLSetIfNewer(scoped_refptr crl_set) { + CEF_REQUIRE_IOT(); + + scoped_refptr old_crl_set(net::SSLConfigService::GetCRLSet()); + if (old_crl_set.get() && old_crl_set->sequence() > crl_set->sequence()) { + LOG(WARNING) << "Refusing to downgrade CRL set from #" + << old_crl_set->sequence() << "to #" << crl_set->sequence(); + } else { + net::SSLConfigService::SetCRLSet(crl_set); + VLOG(1) << "Installed CRL set #" << crl_set->sequence(); + } +} + +void LoadFromDisk(const base::FilePath& path) { + base::ThreadRestrictions::AssertIOAllowed(); + + std::string crl_set_bytes; + if (!base::ReadFileToString(path, &crl_set_bytes)) { + LOG(WARNING) << "Failed to read CRL set from " << path.MaybeAsASCII(); + return; + } + + scoped_refptr crl_set; + if (!net::CRLSetStorage::Parse(crl_set_bytes, &crl_set)) { + LOG(WARNING) << "Failed to parse CRL set from " << path.MaybeAsASCII(); + return; + } + + VLOG(1) << "Loaded " << crl_set_bytes.size() << " bytes of CRL set from disk"; + CEF_POST_TASK(CEF_IOT, base::BindOnce(&SetCRLSetIfNewer, crl_set)); +} + +} // namespace + +void CefLoadCRLSetsFile(const CefString& path) { + if (!CONTEXT_STATE_VALID()) { + NOTREACHED() << "context not valid"; + return; + } + + base::PostTaskWithTraits(FROM_HERE, + {base::TaskPriority::BACKGROUND, base::MayBlock()}, + base::BindOnce(&LoadFromDisk, path)); +} diff --git a/libcef_dll/libcef_dll.cc b/libcef_dll/libcef_dll.cc index 38e1c0e39..b828d0856 100644 --- a/libcef_dll/libcef_dll.cc +++ b/libcef_dll/libcef_dll.cc @@ -9,7 +9,7 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=2ff7a51013987b111a12b700a0e018eb0bb08edc$ +// $hash=45f1ced8a482b44d73c8538fbbdbc27e73003d6f$ // #include "include/capi/cef_app_capi.h" @@ -584,6 +584,18 @@ CEF_EXPORT int cef_zip_directory(const cef_string_t* src_dir, return _retval; } +CEF_EXPORT void cef_load_crlsets_file(const cef_string_t* path) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Verify param: path; type: string_byref_const + DCHECK(path); + if (!path) + return; + + // Execute + CefLoadCRLSetsFile(CefString(path)); +} + CEF_EXPORT int cef_get_geolocation( struct _cef_get_geolocation_callback_t* callback) { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING diff --git a/libcef_dll/wrapper/libcef_dll_wrapper.cc b/libcef_dll/wrapper/libcef_dll_wrapper.cc index 07e8a4190..14c2ef4e2 100644 --- a/libcef_dll/wrapper/libcef_dll_wrapper.cc +++ b/libcef_dll/wrapper/libcef_dll_wrapper.cc @@ -9,7 +9,7 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=da690070ed610a81d9f5dcab623ca7822dbd0ac1$ +// $hash=5adfe7f61a476b5b7dac0365f481efc213b3c579$ // #include "include/capi/cef_app_capi.h" @@ -553,6 +553,18 @@ CEF_GLOBAL bool CefZipDirectory(const CefString& src_dir, return _retval ? true : false; } +CEF_GLOBAL void CefLoadCRLSetsFile(const CefString& path) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Verify param: path; type: string_byref_const + DCHECK(!path.empty()); + if (path.empty()) + return; + + // Execute + cef_load_crlsets_file(path.GetStruct()); +} + CEF_GLOBAL bool CefGetGeolocation( CefRefPtr callback) { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING diff --git a/tests/cefclient/browser/client_browser.cc b/tests/cefclient/browser/client_browser.cc index f446dc83e..008c85444 100644 --- a/tests/cefclient/browser/client_browser.cc +++ b/tests/cefclient/browser/client_browser.cc @@ -4,7 +4,10 @@ #include "tests/cefclient/browser/client_browser.h" +#include "include/cef_command_line.h" #include "include/cef_crash_util.h" +#include "include/cef_file_util.h" +#include "tests/shared/common/client_switches.h" namespace client { namespace browser { @@ -23,6 +26,14 @@ class ClientBrowserDelegate : public ClientAppBrowser::Delegate { CefSetCrashKeyValue("testkey2", "value2_browser"); CefSetCrashKeyValue("testkey3", "value3_browser"); } + + const std::string& crl_sets_path = + CefCommandLine::GetGlobalCommandLine()->GetSwitchValue( + switches::kCRLSetsPath); + if (!crl_sets_path.empty()) { + // Load the CRLSets file from the specified path. + CefLoadCRLSetsFile(crl_sets_path); + } } private: diff --git a/tests/shared/common/client_switches.cc b/tests/shared/common/client_switches.cc index 910eaadda..101a84574 100644 --- a/tests/shared/common/client_switches.cc +++ b/tests/shared/common/client_switches.cc @@ -37,6 +37,7 @@ const char kHideControls[] = "hide-controls"; const char kHideTopMenu[] = "hide-top-menu"; const char kWidevineCdmPath[] = "widevine-cdm-path"; const char kSslClientCertificate[] = "ssl-client-certificate"; +const char kCRLSetsPath[] = "crl-sets-path"; } // namespace switches } // namespace client diff --git a/tests/shared/common/client_switches.h b/tests/shared/common/client_switches.h index 7c656d9d4..65e02cfd8 100644 --- a/tests/shared/common/client_switches.h +++ b/tests/shared/common/client_switches.h @@ -31,6 +31,7 @@ extern const char kHideControls[]; extern const char kHideTopMenu[]; extern const char kWidevineCdmPath[]; extern const char kSslClientCertificate[]; +extern const char kCRLSetsPath[]; } // namespace switches } // namespace client