Commit a39bb456 authored by Christopher Thompson's avatar Christopher Thompson Committed by Commit Bot

TLS deprecation config component

Add component installer, configuration API, and the various plumbing to
add it to Chrome.

The installer and configuration is largely based on the existing Safety
Tips component (i.e., safety_tips_component_installer.h/cc and
safety_tips_config.h/cc).

Bug: 989607
Change-Id: If48016acc8032eacf2eb0393795fc5e66dcc892c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1769634
Commit-Queue: Christopher Thompson <cthomp@chromium.org>
Reviewed-by: default avatarLei Zhang <thestig@chromium.org>
Reviewed-by: default avatarJoshua Pawlicki <waffles@chromium.org>
Reviewed-by: default avatarEmily Stark <estark@chromium.org>
Cr-Commit-Position: refs/heads/master@{#699486}
parent b615313f
...@@ -1727,6 +1727,8 @@ jumbo_split_static_library("browser") { ...@@ -1727,6 +1727,8 @@ jumbo_split_static_library("browser") {
"ssl/ssl_error_handler.h", "ssl/ssl_error_handler.h",
"ssl/ssl_error_navigation_throttle.cc", "ssl/ssl_error_navigation_throttle.cc",
"ssl/ssl_error_navigation_throttle.h", "ssl/ssl_error_navigation_throttle.h",
"ssl/tls_deprecation_config.cc",
"ssl/tls_deprecation_config.h",
"ssl/typed_navigation_timing_throttle.cc", "ssl/typed_navigation_timing_throttle.cc",
"ssl/typed_navigation_timing_throttle.h", "ssl/typed_navigation_timing_throttle.h",
"startup_data.cc", "startup_data.cc",
...@@ -3013,6 +3015,8 @@ jumbo_split_static_library("browser") { ...@@ -3013,6 +3015,8 @@ jumbo_split_static_library("browser") {
"chrome_process_singleton.h", "chrome_process_singleton.h",
"component_updater/intervention_policy_database_component_installer.cc", "component_updater/intervention_policy_database_component_installer.cc",
"component_updater/intervention_policy_database_component_installer.h", "component_updater/intervention_policy_database_component_installer.h",
"component_updater/tls_deprecation_config_component_installer.cc",
"component_updater/tls_deprecation_config_component_installer.h",
"custom_handlers/register_protocol_handler_permission_request.cc", "custom_handlers/register_protocol_handler_permission_request.cc",
"custom_handlers/register_protocol_handler_permission_request.h", "custom_handlers/register_protocol_handler_permission_request.h",
"diagnostics/diagnostics_controller.cc", "diagnostics/diagnostics_controller.cc",
......
...@@ -330,6 +330,7 @@ ...@@ -330,6 +330,7 @@
#if !defined(OS_ANDROID) #if !defined(OS_ANDROID)
#include "chrome/browser/component_updater/intervention_policy_database_component_installer.h" #include "chrome/browser/component_updater/intervention_policy_database_component_installer.h"
#include "chrome/browser/component_updater/tls_deprecation_config_component_installer.h"
#include "chrome/browser/resource_coordinator/tab_manager.h" #include "chrome/browser/resource_coordinator/tab_manager.h"
#endif #endif
...@@ -536,6 +537,7 @@ void RegisterComponentsForUpdate(PrefService* profile_prefs) { ...@@ -536,6 +537,7 @@ void RegisterComponentsForUpdate(PrefService* profile_prefs) {
#if !defined(OS_ANDROID) #if !defined(OS_ANDROID)
RegisterInterventionPolicyDatabaseComponent( RegisterInterventionPolicyDatabaseComponent(
cus, g_browser_process->GetTabManager()->intervention_policy_database()); cus, g_browser_process->GetTabManager()->intervention_policy_database());
RegisterTLSDeprecationConfigComponent(cus, path);
#endif #endif
#if BUILDFLAG(ENABLE_VR) #if BUILDFLAG(ENABLE_VR)
......
// Copyright 2019 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 "chrome/browser/component_updater/tls_deprecation_config_component_installer.h"
#include <memory>
#include <utility>
#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/stl_util.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
#include "chrome/browser/ssl/tls_deprecation_config.h"
#include "chrome/browser/ssl/tls_deprecation_config.pb.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
using component_updater::ComponentUpdateService;
namespace {
const base::FilePath::CharType kTLSDeprecationConfigBinaryPbFileName[] =
FILE_PATH_LITERAL("tls_deprecation_config.pb");
// The SHA256 of the SubjectPublicKeyInfo used to sign the extension.
// The extension id is: bklopemakmnopmghhmccadeonafabnal
const uint8_t kTLSDeprecationConfigPublicKeySHA256[32] = {
0x1a, 0xbe, 0xf4, 0xc0, 0xac, 0xde, 0xfc, 0x67, 0x7c, 0x22, 0x03,
0x4e, 0xd0, 0x50, 0x1d, 0x0b, 0xed, 0x45, 0x0f, 0xcb, 0x0b, 0x7f,
0xad, 0x4f, 0xb6, 0x7b, 0x7c, 0x8f, 0xbf, 0xda, 0xa8, 0xe3};
std::unique_ptr<chrome_browser_ssl::LegacyTLSExperimentConfig>
LoadTLSDeprecationConfigProtoFromDisk(const base::FilePath& pb_path) {
std::string binary_pb;
if (!base::ReadFileToString(pb_path, &binary_pb)) {
// The file won't exist on new installations, so this is not always an
// error.
DVLOG(1) << "Failed reading from " << pb_path.value();
return nullptr;
}
auto proto =
std::make_unique<chrome_browser_ssl::LegacyTLSExperimentConfig>();
if (!proto->ParseFromString(binary_pb)) {
DVLOG(1) << "Failed parsing proto " << pb_path.value();
return nullptr;
}
return proto;
}
base::FilePath GetInstalledPath(const base::FilePath& base) {
return base.Append(kTLSDeprecationConfigBinaryPbFileName);
}
} // namespace
namespace component_updater {
TLSDeprecationConfigComponentInstallerPolicy::
TLSDeprecationConfigComponentInstallerPolicy() = default;
TLSDeprecationConfigComponentInstallerPolicy::
~TLSDeprecationConfigComponentInstallerPolicy() = default;
bool TLSDeprecationConfigComponentInstallerPolicy::
SupportsGroupPolicyEnabledComponentUpdates() const {
return false;
}
bool TLSDeprecationConfigComponentInstallerPolicy::RequiresNetworkEncryption()
const {
return false;
}
update_client::CrxInstaller::Result
TLSDeprecationConfigComponentInstallerPolicy::OnCustomInstall(
const base::DictionaryValue& /* manifest */,
const base::FilePath& /* install_dir */) {
return update_client::CrxInstaller::Result(0); // Nothing custom here.
}
void TLSDeprecationConfigComponentInstallerPolicy::OnCustomUninstall() {}
void TLSDeprecationConfigComponentInstallerPolicy::ComponentReady(
const base::Version& version,
const base::FilePath& install_dir,
std::unique_ptr<base::DictionaryValue> manifest) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DVLOG(1) << "Component ready, version " << version.GetString() << " in "
<< install_dir.value();
const base::FilePath pb_path = GetInstalledPath(install_dir);
if (pb_path.empty())
return;
// The default proto will always be a placeholder since the updated versions
// are not checked into the repo. Simply load whatever the component updater
// gave us without checking the default proto from the resource bundle.
base::PostTaskAndReplyWithResult(
FROM_HERE,
{base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT},
base::BindOnce(&LoadTLSDeprecationConfigProtoFromDisk, pb_path),
base::BindOnce(&SetRemoteTLSDeprecationConfigProto));
}
// Called during startup and installation before ComponentReady().
bool TLSDeprecationConfigComponentInstallerPolicy::VerifyInstallation(
const base::DictionaryValue& /* manifest */,
const base::FilePath& install_dir) const {
// No need to actually validate the proto here, since we'll do the checking
// in PopulateFromDynamicUpdate().
return base::PathExists(GetInstalledPath(install_dir));
}
base::FilePath
TLSDeprecationConfigComponentInstallerPolicy::GetRelativeInstallDir() const {
return base::FilePath(FILE_PATH_LITERAL("TLSDeprecationConfig"));
}
void TLSDeprecationConfigComponentInstallerPolicy::GetHash(
std::vector<uint8_t>* hash) const {
hash->assign(kTLSDeprecationConfigPublicKeySHA256,
kTLSDeprecationConfigPublicKeySHA256 +
base::size(kTLSDeprecationConfigPublicKeySHA256));
}
std::string TLSDeprecationConfigComponentInstallerPolicy::GetName() const {
return "Legacy TLS Deprecation Configuration";
}
update_client::InstallerAttributes
TLSDeprecationConfigComponentInstallerPolicy::GetInstallerAttributes() const {
return update_client::InstallerAttributes();
}
std::vector<std::string>
TLSDeprecationConfigComponentInstallerPolicy::GetMimeTypes() const {
return std::vector<std::string>();
}
void RegisterTLSDeprecationConfigComponent(
ComponentUpdateService* cus,
const base::FilePath& user_data_dir) {
DVLOG(1) << "Registering TLS Deprecation Config component.";
auto installer = base::MakeRefCounted<ComponentInstaller>(
std::make_unique<TLSDeprecationConfigComponentInstallerPolicy>());
installer->Register(cus, base::OnceClosure());
}
} // namespace component_updater
// Copyright 2019 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.
#ifndef CHROME_BROWSER_COMPONENT_UPDATER_TLS_DEPRECATION_CONFIG_COMPONENT_INSTALLER_H_
#define CHROME_BROWSER_COMPONENT_UPDATER_TLS_DEPRECATION_CONFIG_COMPONENT_INSTALLER_H_
#include <memory>
#include <string>
#include <vector>
#include "base/macros.h"
#include "base/values.h"
#include "components/component_updater/component_installer.h"
namespace base {
class FilePath;
} // namespace base
namespace component_updater {
class TLSDeprecationConfigComponentInstallerPolicy
: public ComponentInstallerPolicy {
public:
TLSDeprecationConfigComponentInstallerPolicy();
~TLSDeprecationConfigComponentInstallerPolicy() override;
private:
// ComponentInstallerPolicy methods:
bool SupportsGroupPolicyEnabledComponentUpdates() const override;
bool RequiresNetworkEncryption() const override;
update_client::CrxInstaller::Result OnCustomInstall(
const base::DictionaryValue& manifest,
const base::FilePath& install_dir) override;
void OnCustomUninstall() override;
bool VerifyInstallation(const base::DictionaryValue& manifest,
const base::FilePath& install_dir) const override;
void ComponentReady(const base::Version& version,
const base::FilePath& install_dir,
std::unique_ptr<base::DictionaryValue> manifest) override;
base::FilePath GetRelativeInstallDir() const override;
void GetHash(std::vector<uint8_t>* hash) const override;
std::string GetName() const override;
update_client::InstallerAttributes GetInstallerAttributes() const override;
std::vector<std::string> GetMimeTypes() const override;
DISALLOW_COPY_AND_ASSIGN(TLSDeprecationConfigComponentInstallerPolicy);
};
void RegisterTLSDeprecationConfigComponent(ComponentUpdateService* cus,
const base::FilePath& user_data_dir);
} // namespace component_updater
#endif // CHROME_BROWSER_COMPONENT_UPDATER_TLS_DEPRECATION_CONFIG_COMPONENT_INSTALLER_H_
...@@ -8,5 +8,6 @@ proto_library("proto") { ...@@ -8,5 +8,6 @@ proto_library("proto") {
sources = [ sources = [
"cert_logger.proto", "cert_logger.proto",
"ssl_error_assistant.proto", "ssl_error_assistant.proto",
"tls_deprecation_config.proto",
] ]
} }
// Copyright 2019 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 "chrome/browser/ssl/tls_deprecation_config.h"
#include <algorithm>
#include <string>
#include <utility>
#include "base/no_destructor.h"
#include "base/strings/string_piece.h"
#include "chrome/browser/ssl/tls_deprecation_config.pb.h"
#include "crypto/sha2.h"
#include "url/gurl.h"
namespace {
class TLSDeprecationConfigSingleton {
public:
void SetProto(
std::unique_ptr<chrome_browser_ssl::LegacyTLSExperimentConfig> proto) {
proto_ = std::move(proto);
}
chrome_browser_ssl::LegacyTLSExperimentConfig* GetProto() const {
return proto_.get();
}
static TLSDeprecationConfigSingleton& GetInstance() {
static base::NoDestructor<TLSDeprecationConfigSingleton> instance;
return *instance;
}
private:
std::unique_ptr<chrome_browser_ssl::LegacyTLSExperimentConfig> proto_;
};
} // namespace
void SetRemoteTLSDeprecationConfigProto(
std::unique_ptr<chrome_browser_ssl::LegacyTLSExperimentConfig> proto) {
TLSDeprecationConfigSingleton::GetInstance().SetProto(std::move(proto));
}
bool IsTLSDeprecationConfigControlSite(const GURL& url) {
if (!url.has_host() || !url.SchemeIsCryptographic())
return false;
auto* proto = TLSDeprecationConfigSingleton::GetInstance().GetProto();
if (!proto)
return false;
std::string host_hash = crypto::SHA256HashString(url.host_piece());
const auto& control_site_hashes = proto->control_site_hashes();
// Perform binary search on the sorted list of control site hashes to check
// if the input URL's hostname is included.
auto lower = std::lower_bound(control_site_hashes.begin(),
control_site_hashes.end(), host_hash);
return lower != control_site_hashes.end() && *lower == host_hash;
}
// Copyright 2019 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.
#ifndef CHROME_BROWSER_SSL_TLS_DEPRECATION_CONFIG_H_
#define CHROME_BROWSER_SSL_TLS_DEPRECATION_CONFIG_H_
#include <memory>
class GURL;
namespace chrome_browser_ssl {
class LegacyTLSExperimentConfig;
} // namespace chrome_browser_ssl
void SetRemoteTLSDeprecationConfigProto(
std::unique_ptr<chrome_browser_ssl::LegacyTLSExperimentConfig> proto);
bool IsTLSDeprecationConfigControlSite(const GURL& url);
#endif // CHROME_BROWSER_SSL_TLS_DEPRECATION_CONFIG_H_
// Copyright 2019 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.
syntax = "proto2";
package chrome_browser_ssl;
option optimize_for = LITE_RUNTIME;
// The set of sites to be used as a control group for Legacy TLS experiments.
// Warning UI will not be shown on these sites.
message LegacyTLSExperimentConfig {
optional uint32 version_id = 1;
// SHA-256 hash of the hostname of sites in the control group (e.g., for
// "https://test.example.com/foo" the hostname is "test.example.com"). This
// list must be in sorted order (alphanumeric by hash value).
repeated string control_site_hashes = 2;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment