Commit f4b33f38 authored by Joshua Pawlicki's avatar Joshua Pawlicki Committed by Commit Bot

Require CRX3s with publisher proofs for all component updates.

Extension updates are unaffected by this CL.

Bug: 740715
Change-Id: Ib1a563f62ed923ecc06300d171a83935ef18a1ef
Reviewed-on: https://chromium-review.googlesource.com/1167987
Commit-Queue: Joshua Pawlicki <waffles@chromium.org>
Reviewed-by: default avatarDevlin <rdevlin.cronin@chromium.org>
Reviewed-by: default avatarSorin Jianu <sorin@chromium.org>
Reviewed-by: default avatarMinh Nguyen <mxnguyen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#584114}
parent 697f4d6f
......@@ -34,6 +34,7 @@
#include "components/component_updater/component_updater_paths.h"
#include "components/component_updater/component_updater_service.h"
#include "components/component_updater/pref_names.h"
#include "components/crx_file/crx_verifier.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/update_client/update_client.h"
......@@ -302,6 +303,8 @@ void RecoveryRegisterHelper(ComponentUpdateService* cus, PrefService* prefs) {
&kRecoverySha2Hash[sizeof(kRecoverySha2Hash)]);
recovery.supports_group_policy_enable_component_updates = true;
recovery.requires_network_encryption = false;
recovery.crx_format_requirement =
crx_file::VerifierFormat::CRX3_WITH_PUBLISHER_PROOF;
if (!cus->RegisterComponent(recovery)) {
NOTREACHED() << "Recovery component registration failed.";
}
......
......@@ -30,6 +30,7 @@ static_library("component_updater") {
deps = [
"//base",
"//components/crx_file",
"//components/update_client",
"//components/version_info",
"//third_party/boringssl:boringssl",
......@@ -76,6 +77,7 @@ source_set("unit_tests") {
":component_updater",
"//base",
"//base/test:test_support",
"//components/crx_file",
"//components/update_client:test_support",
"//services/service_manager/public/cpp",
"//testing/gmock",
......
include_rules = [
"+components/crx_file",
"+components/update_client",
"+components/version_info",
"+services/service_manager/public",
......
......@@ -24,6 +24,7 @@
#include "build/build_config.h"
#include "components/component_updater/component_updater_paths.h"
#include "components/component_updater/component_updater_service.h"
#include "components/crx_file/crx_verifier.h"
#include "components/update_client/component_unpacker.h"
#include "components/update_client/update_client.h"
#include "components/update_client/update_client_errors.h"
......@@ -409,6 +410,8 @@ void ComponentInstaller::FinishRegistration(
crx.installer_attributes = installer_policy_->GetInstallerAttributes();
crx.requires_network_encryption =
installer_policy_->RequiresNetworkEncryption();
crx.crx_format_requirement =
crx_file::VerifierFormat::CRX3_WITH_PUBLISHER_PROOF;
crx.handled_mime_types = installer_policy_->GetMimeTypes();
crx.supports_group_policy_enable_component_updates =
installer_policy_->SupportsGroupPolicyEnabledComponentUpdates();
......
......@@ -25,6 +25,7 @@
#include "components/component_updater/component_updater_paths.h"
#include "components/component_updater/component_updater_service.h"
#include "components/component_updater/component_updater_service_internal.h"
#include "components/crx_file/crx_verifier.h"
#include "components/update_client/component_unpacker.h"
#include "components/update_client/crx_update_item.h"
#include "components/update_client/test_configurator.h"
......@@ -241,7 +242,8 @@ void ComponentInstallerTest::Unpack(const base::FilePath& crx_path) {
auto config = base::MakeRefCounted<TestConfigurator>();
auto component_unpacker = base::MakeRefCounted<ComponentUnpacker>(
std::vector<uint8_t>(std::begin(kSha256Hash), std::end(kSha256Hash)),
crx_path, nullptr, config->CreateServiceManagerConnector());
crx_path, nullptr, config->CreateServiceManagerConnector(),
crx_file::VerifierFormat::CRX2_OR_CRX3);
component_unpacker->Unpack(base::BindOnce(
&ComponentInstallerTest::UnpackComplete, base::Unretained(this)));
RunThreads();
......
......@@ -14,6 +14,7 @@
#include "base/logging.h"
#include "base/task/post_task.h"
#include "build/build_config.h"
#include "components/crx_file/crx_verifier.h"
#include "components/update_client/component.h"
#include "components/update_client/configurator.h"
#include "components/update_client/task_traits.h"
......@@ -52,7 +53,8 @@ void ActionRunner::Unpack(
// Contains the key hash of the CRX this object is allowed to run.
const auto key_hash = component_.config()->GetRunActionKeyHash();
auto unpacker = base::MakeRefCounted<ComponentUnpacker>(
key_hash, file_path, installer, std::move(connector));
key_hash, file_path, installer, std::move(connector),
component_.crx_component()->crx_format_requirement);
unpacker->Unpack(
base::BindOnce(&ActionRunner::UnpackComplete, base::Unretained(this)));
}
......
......@@ -149,9 +149,10 @@ void StartInstallOnBlockingTaskRunner(
const std::string& fingerprint,
scoped_refptr<CrxInstaller> installer,
std::unique_ptr<service_manager::Connector> connector,
crx_file::VerifierFormat crx_format,
InstallOnBlockingTaskRunnerCompleteCallback callback) {
auto unpacker = base::MakeRefCounted<ComponentUnpacker>(
pk_hash, crx_path, installer, std::move(connector));
pk_hash, crx_path, installer, std::move(connector), crx_format);
unpacker->Unpack(base::BindOnce(&UnpackCompleteOnBlockingTaskRunner,
main_task_runner, crx_path, fingerprint,
......@@ -658,6 +659,7 @@ void Component::StateUpdatingDiff::DoHandle() {
component.crx_component()->pk_hash, component.crx_path_,
component.next_fp_, component.crx_component()->installer,
std::move(connector),
component.crx_component()->crx_format_requirement,
base::BindOnce(&Component::StateUpdatingDiff::InstallComplete,
base::Unretained(this))));
}
......@@ -721,6 +723,7 @@ void Component::StateUpdating::DoHandle() {
component.crx_component()->pk_hash, component.crx_path_,
component.next_fp_, component.crx_component()->installer,
std::move(connector),
component.crx_component()->crx_format_requirement,
base::BindOnce(&Component::StateUpdating::InstallComplete,
base::Unretained(this))));
}
......
......@@ -34,12 +34,14 @@ ComponentUnpacker::ComponentUnpacker(
const std::vector<uint8_t>& pk_hash,
const base::FilePath& path,
scoped_refptr<CrxInstaller> installer,
std::unique_ptr<service_manager::Connector> connector)
std::unique_ptr<service_manager::Connector> connector,
crx_file::VerifierFormat crx_format)
: pk_hash_(pk_hash),
path_(path),
is_delta_(false),
installer_(installer),
connector_(std::move(connector)),
crx_format_(crx_format),
error_(UnpackerError::kNone),
extended_error_(0) {}
......@@ -58,9 +60,9 @@ bool ComponentUnpacker::Verify() {
return false;
}
const std::vector<std::vector<uint8_t>> required_keys = {pk_hash_};
const crx_file::VerifierResult result = crx_file::Verify(
path_, crx_file::VerifierFormat::CRX2_OR_CRX3, required_keys,
std::vector<uint8_t>(), &public_key_, nullptr);
const crx_file::VerifierResult result =
crx_file::Verify(path_, crx_format_, required_keys,
std::vector<uint8_t>(), &public_key_, nullptr);
if (result != crx_file::VerifierResult::OK_FULL &&
result != crx_file::VerifierResult::OK_DELTA) {
error_ = UnpackerError::kInvalidFile;
......
......@@ -18,6 +18,10 @@
#include "components/update_client/update_client_errors.h"
#include "services/service_manager/public/cpp/connector.h"
namespace crx_file {
enum class VerifierFormat;
}
namespace update_client {
class CrxInstaller;
......@@ -84,7 +88,8 @@ class ComponentUnpacker : public base::RefCountedThreadSafe<ComponentUnpacker> {
ComponentUnpacker(const std::vector<uint8_t>& pk_hash,
const base::FilePath& path,
scoped_refptr<CrxInstaller> installer,
std::unique_ptr<service_manager::Connector> connector);
std::unique_ptr<service_manager::Connector> connector,
crx_file::VerifierFormat crx_format);
// Begins the actual unpacking of the files. May invoke a patcher and the
// component installer if the package is a differential update.
......@@ -127,6 +132,7 @@ class ComponentUnpacker : public base::RefCountedThreadSafe<ComponentUnpacker> {
scoped_refptr<CrxInstaller> installer_;
Callback callback_;
std::unique_ptr<service_manager::Connector> connector_;
crx_file::VerifierFormat crx_format_;
UnpackerError error_;
int extended_error_;
std::string public_key_;
......
......@@ -105,7 +105,8 @@ TEST_F(ComponentUnpackerTest, UnpackFullCrx) {
base::MakeRefCounted<ComponentUnpacker>(
std::vector<uint8_t>(std::begin(jebg_hash), std::end(jebg_hash)),
test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"), nullptr,
config->CreateServiceManagerConnector());
config->CreateServiceManagerConnector(),
crx_file::VerifierFormat::CRX2_OR_CRX3);
component_unpacker->Unpack(base::BindOnce(
&ComponentUnpackerTest::UnpackComplete, base::Unretained(this)));
RunThreads();
......@@ -136,7 +137,8 @@ TEST_F(ComponentUnpackerTest, UnpackFileNotFound) {
scoped_refptr<ComponentUnpacker> component_unpacker =
base::MakeRefCounted<ComponentUnpacker>(
std::vector<uint8_t>(std::begin(jebg_hash), std::end(jebg_hash)),
test_file("file-not-found.crx"), nullptr, nullptr);
test_file("file-not-found.crx"), nullptr, nullptr,
crx_file::VerifierFormat::CRX2_OR_CRX3);
component_unpacker->Unpack(base::BindOnce(
&ComponentUnpackerTest::UnpackComplete, base::Unretained(this)));
RunThreads();
......@@ -153,7 +155,8 @@ TEST_F(ComponentUnpackerTest, UnpackFileHashMismatch) {
scoped_refptr<ComponentUnpacker> component_unpacker =
base::MakeRefCounted<ComponentUnpacker>(
std::vector<uint8_t>(std::begin(abag_hash), std::end(abag_hash)),
test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"), nullptr, nullptr);
test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"), nullptr, nullptr,
crx_file::VerifierFormat::CRX2_OR_CRX3);
component_unpacker->Unpack(base::BindOnce(
&ComponentUnpackerTest::UnpackComplete, base::Unretained(this)));
RunThreads();
......
......@@ -19,6 +19,7 @@
#include "base/stl_util.h"
#include "base/threading/thread_checker.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/crx_file/crx_verifier.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/update_client/configurator.h"
#include "components/update_client/crx_update_item.h"
......@@ -43,6 +44,8 @@ CrxUpdateItem::CrxUpdateItem(const CrxUpdateItem& other) = default;
CrxComponent::CrxComponent()
: allows_background_download(true),
requires_network_encryption(true),
crx_format_requirement(
crx_file::VerifierFormat::CRX3_WITH_PUBLISHER_PROOF),
supports_group_policy_enable_component_updates(false) {}
CrxComponent::CrxComponent(const CrxComponent& other) = default;
CrxComponent::~CrxComponent() = default;
......
......@@ -136,6 +136,10 @@ namespace base {
class FilePath;
}
namespace crx_file {
enum class VerifierFormat;
}
namespace update_client {
class Configurator;
......@@ -244,6 +248,9 @@ struct CrxComponent {
// which only returns secure download URLs in this case.
bool requires_network_encryption;
// Specifies the strength of package validation required for the item.
crx_file::VerifierFormat crx_format_requirement;
// True if the component allows enabling or disabling updates by group policy.
// This member should be set to |false| for data, non-binary components, such
// as CRLSet, Supervised User Whitelists, STH Set, Origin Trials, and File
......
......@@ -23,6 +23,7 @@
#include "base/values.h"
#include "base/version.h"
#include "build/build_config.h"
#include "components/crx_file/crx_verifier.h"
#include "components/prefs/testing_pref_service.h"
#include "components/update_client/component_unpacker.h"
#include "components/update_client/crx_update_item.h"
......@@ -222,6 +223,7 @@ TEST_F(UpdateClientTest, OneCrxNoUpdate) {
crx.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
crx.version = base::Version("0.9");
crx.installer = base::MakeRefCounted<TestInstaller>();
crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
std::vector<base::Optional<CrxComponent>> component = {crx};
return component;
}
......@@ -332,12 +334,14 @@ TEST_F(UpdateClientTest, TwoCrxUpdateNoUpdate) {
crx1.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
crx1.version = base::Version("0.9");
crx1.installer = base::MakeRefCounted<TestInstaller>();
crx1.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
CrxComponent crx2;
crx2.name = "test_abag";
crx2.pk_hash.assign(abag_hash, abag_hash + base::size(abag_hash));
crx2.version = base::Version("2.2");
crx2.installer = base::MakeRefCounted<TestInstaller>();
crx2.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
return {crx1, crx2};
}
......@@ -548,12 +552,14 @@ TEST_F(UpdateClientTest, TwoCrxUpdateFirstServerIgnoresSecond) {
crx1.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
crx1.version = base::Version("0.9");
crx1.installer = base::MakeRefCounted<TestInstaller>();
crx1.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
CrxComponent crx2;
crx2.name = "test_abag";
crx2.pk_hash.assign(abag_hash, abag_hash + base::size(abag_hash));
crx2.version = base::Version("2.2");
crx2.installer = base::MakeRefCounted<TestInstaller>();
crx2.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
return {crx1, crx2};
}
......@@ -763,6 +769,7 @@ TEST_F(UpdateClientTest, TwoCrxUpdateNoCrxComponentData) {
crx.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
crx.version = base::Version("0.9");
crx.installer = base::MakeRefCounted<TestInstaller>();
crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
return {crx, base::nullopt};
}
};
......@@ -1050,12 +1057,14 @@ TEST_F(UpdateClientTest, TwoCrxUpdateDownloadTimeout) {
crx1.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
crx1.version = base::Version("0.9");
crx1.installer = base::MakeRefCounted<TestInstaller>();
crx1.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
CrxComponent crx2;
crx2.name = "test_ihfo";
crx2.pk_hash.assign(ihfo_hash, ihfo_hash + base::size(ihfo_hash));
crx2.version = base::Version("0.8");
crx2.installer = base::MakeRefCounted<TestInstaller>();
crx2.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
return {crx1, crx2};
}
......@@ -1326,6 +1335,7 @@ TEST_F(UpdateClientTest, OneCrxDiffUpdate) {
crx.name = "test_ihfo";
crx.pk_hash.assign(ihfo_hash, ihfo_hash + base::size(ihfo_hash));
crx.installer = installer;
crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
if (num_calls == 1) {
crx.version = base::Version("0.8");
} else if (num_calls == 2) {
......@@ -1664,6 +1674,7 @@ TEST_F(UpdateClientTest, OneCrxInstallError) {
crx.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
crx.version = base::Version("0.9");
crx.installer = installer;
crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
return {crx};
}
......@@ -1849,6 +1860,7 @@ TEST_F(UpdateClientTest, OneCrxDiffUpdateFailsFullUpdateSucceeds) {
crx.name = "test_ihfo";
crx.pk_hash.assign(ihfo_hash, ihfo_hash + base::size(ihfo_hash));
crx.installer = installer;
crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
if (num_calls == 1) {
crx.version = base::Version("0.8");
} else if (num_calls == 2) {
......@@ -2157,6 +2169,7 @@ TEST_F(UpdateClientTest, OneCrxNoUpdateQueuedCall) {
crx.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
crx.version = base::Version("0.9");
crx.installer = base::MakeRefCounted<TestInstaller>();
crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
return {crx};
}
};
......@@ -2276,6 +2289,7 @@ TEST_F(UpdateClientTest, OneCrxInstall) {
crx.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
crx.version = base::Version("0.0");
crx.installer = base::MakeRefCounted<TestInstaller>();
crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
return {crx};
}
};
......@@ -2558,6 +2572,7 @@ TEST_F(UpdateClientTest, ConcurrentInstallSameCRX) {
crx.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
crx.version = base::Version("0.0");
crx.installer = base::MakeRefCounted<TestInstaller>();
crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
return {crx};
}
};
......@@ -2822,6 +2837,7 @@ TEST_F(UpdateClientTest, RetryAfter) {
crx.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
crx.version = base::Version("0.9");
crx.installer = base::MakeRefCounted<TestInstaller>();
crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
return {crx};
}
};
......@@ -3014,6 +3030,7 @@ TEST_F(UpdateClientTest, TwoCrxUpdateOneUpdateDisabled) {
crx1.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
crx1.version = base::Version("0.9");
crx1.installer = base::MakeRefCounted<TestInstaller>();
crx1.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
crx1.supports_group_policy_enable_component_updates = true;
CrxComponent crx2;
......@@ -3021,6 +3038,7 @@ TEST_F(UpdateClientTest, TwoCrxUpdateOneUpdateDisabled) {
crx2.pk_hash.assign(ihfo_hash, ihfo_hash + base::size(ihfo_hash));
crx2.version = base::Version("0.8");
crx2.installer = base::MakeRefCounted<TestInstaller>();
crx2.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
return {crx1, crx2};
}
......@@ -3269,6 +3287,7 @@ TEST_F(UpdateClientTest, OneCrxUpdateCheckFails) {
crx.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
crx.version = base::Version("0.9");
crx.installer = base::MakeRefCounted<TestInstaller>();
crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
return {crx};
}
};
......@@ -3379,6 +3398,7 @@ TEST_F(UpdateClientTest, OneCrxErrorUnknownApp) {
crx.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
crx.version = base::Version("0.9");
crx.installer = base::MakeRefCounted<TestInstaller>();
crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
component.push_back(crx);
}
{
......@@ -3387,6 +3407,7 @@ TEST_F(UpdateClientTest, OneCrxErrorUnknownApp) {
crx.pk_hash.assign(abag_hash, abag_hash + base::size(abag_hash));
crx.version = base::Version("0.1");
crx.installer = base::MakeRefCounted<TestInstaller>();
crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
component.push_back(crx);
}
{
......@@ -3395,6 +3416,7 @@ TEST_F(UpdateClientTest, OneCrxErrorUnknownApp) {
crx.pk_hash.assign(ihfo_hash, ihfo_hash + base::size(ihfo_hash));
crx.version = base::Version("0.2");
crx.installer = base::MakeRefCounted<TestInstaller>();
crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
component.push_back(crx);
}
{
......@@ -3403,6 +3425,7 @@ TEST_F(UpdateClientTest, OneCrxErrorUnknownApp) {
crx.pk_hash.assign(gjpm_hash, gjpm_hash + base::size(gjpm_hash));
crx.version = base::Version("0.3");
crx.installer = base::MakeRefCounted<TestInstaller>();
crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
component.push_back(crx);
}
return component;
......@@ -3724,6 +3747,7 @@ TEST_F(UpdateClientTest, ActionRun_Install) {
crx.pk_hash.assign(gjpm_hash, gjpm_hash + base::size(gjpm_hash));
crx.version = base::Version("0.0");
crx.installer = base::MakeRefCounted<VersionedTestInstaller>();
crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
return std::vector<base::Optional<CrxComponent>>{crx};
}),
base::BindOnce(
......@@ -3828,7 +3852,8 @@ TEST_F(UpdateClientTest, ActionRun_NoUpdate) {
auto component_unpacker = base::MakeRefCounted<ComponentUnpacker>(
std::vector<uint8_t>(std::begin(gjpm_hash), std::end(gjpm_hash)),
TestFilePath("runaction_test_win.crx3"), nullptr,
config->CreateServiceManagerConnector());
config->CreateServiceManagerConnector(),
crx_file::VerifierFormat::CRX2_OR_CRX3);
component_unpacker->Unpack(base::BindOnce(
[](base::FilePath* unpack_path, base::OnceClosure quit_closure,
......@@ -3871,6 +3896,7 @@ TEST_F(UpdateClientTest, ActionRun_NoUpdate) {
crx.version = base::Version("1.0");
crx.installer =
base::MakeRefCounted<ReadOnlyTestInstaller>(unpack_path);
crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
return std::vector<base::Optional<CrxComponent>>{crx};
},
unpack_path),
......
......@@ -13,6 +13,7 @@
#include "base/optional.h"
#include "base/strings/string_util.h"
#include "base/task/post_task.h"
#include "components/crx_file/crx_verifier.h"
#include "components/update_client/utils.h"
#include "content/public/browser/browser_thread.h"
#include "crypto/sha2.h"
......@@ -101,6 +102,8 @@ UpdateDataProvider::GetData(bool install_immediately,
: extension->version();
crx_component->allows_background_download = false;
crx_component->requires_network_encryption = true;
crx_component->crx_format_requirement =
crx_file::VerifierFormat::CRX2_OR_CRX3;
crx_component->installer = base::MakeRefCounted<ExtensionInstaller>(
id, extension->path(), install_immediately,
base::BindOnce(&UpdateDataProvider::RunInstallCallback, this));
......
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