blob: c70053139dfc88c926024644f1dcef368920a995 [file] [log] [blame]
// Copyright 2021 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/client_side_phishing_component_installer.h"
#include "base/bind.h"
#include "base/callback_forward.h"
#include "base/feature_list.h"
#include "base/files/file_util.h"
#include "base/location.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "components/safe_browsing/content/browser/client_side_phishing_model.h"
#include "components/safe_browsing/core/common/features.h"
#include "components/variations/variations_associated_data.h"
using component_updater::ComponentUpdateService;
namespace {
const base::FilePath::CharType kClientModelBinaryPbFileName[] =
FILE_PATH_LITERAL("client_model.pb");
const base::FilePath::CharType kVisualTfLiteModelFileName[] =
FILE_PATH_LITERAL("visual_model.tflite");
// The SHA256 of the SubjectPublicKeyInfo used to sign the extension.
// The extension id is: imefjhfbkmcmebodilednhmaccmincoa
const uint8_t kClientSidePhishingPublicKeySHA256[32] = {
0x8c, 0x45, 0x97, 0x51, 0xac, 0x2c, 0x41, 0xe3, 0x8b, 0x43, 0xd7,
0xc0, 0x22, 0xc8, 0xd2, 0xe0, 0xe3, 0xe2, 0x33, 0x88, 0x1f, 0x09,
0x6d, 0xde, 0x65, 0x6a, 0x83, 0x32, 0x71, 0x52, 0x6e, 0x77};
const char kClientSidePhishingManifestName[] = "Client Side Phishing Detection";
void LoadFromDisk(const base::FilePath& pb_path,
const base::FilePath& visual_tflite_model_path) {
if (pb_path.empty())
return;
std::string binary_pb;
if (!base::ReadFileToString(pb_path, &binary_pb))
binary_pb.clear();
base::File visual_tflite_model(visual_tflite_model_path,
base::File::FLAG_OPEN | base::File::FLAG_READ);
// The ClientSidePhishingModel singleton will react appropriately if the
// |binary_pb| is empty or |visual_tflite_model| is invalid.
safe_browsing::ClientSidePhishingModel::GetInstance()
->PopulateFromDynamicUpdate(binary_pb, std::move(visual_tflite_model));
}
base::FilePath GetInstalledProtoPath(const base::FilePath& base) {
return base.Append(kClientModelBinaryPbFileName);
}
base::FilePath GetInstalledTfLitePath(const base::FilePath& base) {
return base.Append(kVisualTfLiteModelFileName);
}
} // namespace
namespace component_updater {
bool ClientSidePhishingComponentInstallerPolicy::
SupportsGroupPolicyEnabledComponentUpdates() const {
return false;
}
bool ClientSidePhishingComponentInstallerPolicy::RequiresNetworkEncryption()
const {
return false;
}
update_client::CrxInstaller::Result
ClientSidePhishingComponentInstallerPolicy::OnCustomInstall(
const base::DictionaryValue& manifest,
const base::FilePath& install_dir) {
return update_client::CrxInstaller::Result(0); // Nothing custom here.
}
void ClientSidePhishingComponentInstallerPolicy::OnCustomUninstall() {}
void ClientSidePhishingComponentInstallerPolicy::ComponentReady(
const base::Version& version,
const base::FilePath& install_dir,
std::unique_ptr<base::DictionaryValue> manifest) {
base::ThreadPool::PostTask(
FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
base::BindOnce(&LoadFromDisk, GetInstalledProtoPath(install_dir),
GetInstalledTfLitePath(install_dir)));
}
// Called during startup and installation before ComponentReady().
bool ClientSidePhishingComponentInstallerPolicy::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(GetInstalledProtoPath(install_dir)) ||
base::PathExists(GetInstalledTfLitePath(install_dir));
}
base::FilePath
ClientSidePhishingComponentInstallerPolicy::GetRelativeInstallDir() const {
return base::FilePath(FILE_PATH_LITERAL("ClientSidePhishing"));
}
void ClientSidePhishingComponentInstallerPolicy::GetHash(
std::vector<uint8_t>* hash) const {
hash->assign(kClientSidePhishingPublicKeySHA256,
kClientSidePhishingPublicKeySHA256 +
base::size(kClientSidePhishingPublicKeySHA256));
}
std::string ClientSidePhishingComponentInstallerPolicy::GetName() const {
return kClientSidePhishingManifestName;
}
update_client::InstallerAttributes
ClientSidePhishingComponentInstallerPolicy::GetInstallerAttributes() const {
update_client::InstallerAttributes attributes;
// Pass the tag parameter to the installer as the "tag" attribute; it will
// be used to choose which binary is downloaded.
attributes["tag"] = safe_browsing::GetClientSideDetectionTag();
return attributes;
}
void RegisterClientSidePhishingComponent(ComponentUpdateService* cus) {
auto installer = base::MakeRefCounted<ComponentInstaller>(
std::make_unique<ClientSidePhishingComponentInstallerPolicy>());
installer->Register(cus, base::OnceClosure());
}
} // namespace component_updater