Add support for loading certificate revocation lists (issue #2213)

This commit is contained in:
Marshall Greenblatt 2017-07-11 15:02:44 -04:00
parent b216f427f6
commit 700123d3eb
9 changed files with 127 additions and 3 deletions

View File

@ -422,6 +422,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",

View File

@ -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

View File

@ -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_

View File

@ -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<net::CRLSet> crl_set) {
CEF_REQUIRE_IOT();
scoped_refptr<net::CRLSet> 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<net::CRLSet> 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));
}

View File

@ -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

View File

@ -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<CefGetGeolocationCallback> callback) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

View File

@ -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:

View File

@ -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

View File

@ -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