#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_trust_checker.h"
#include <memory>
#include "base/check_deref.h"
#include "base/containers/span.h"
#include "base/feature_list.h"
#include "base/strings/strcat.h"
#include "base/test/scoped_feature_list.h"
#include "base/types/cxx23_to_underlying.h"
#include "chrome/browser/policy/developer_tools_policy_handler.h"
#include "chrome/browser/web_applications/test/web_app_test.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "components/prefs/pref_service.h"
#include "components/web_package/mojom/web_bundle_parser.mojom.h"
#include "components/web_package/signed_web_bundles/ed25519_public_key.h"
#include "components/web_package/signed_web_bundles/signed_web_bundle_id.h"
#include "components/web_package/signed_web_bundles/signed_web_bundle_integrity_block.h"
#include "content/public/common/content_features.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#include "url/url_constants.h"
#if BUILDFLAG(IS_CHROMEOS)
#include "base/values.h"
#include "chrome/browser/web_applications/isolated_web_apps/policy/isolated_web_app_policy_constants.h"
#endif
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "ash/constants/ash_features.h"
#include "chrome/common/chromeos/extensions/chromeos_system_extension_info.h"
#include "chromeos/ash/components/browser_context_helper/browser_context_types.h"
#endif
namespace web_app {
namespace {
constexpr std::array<uint8_t, 32> kPublicKeyBytes1 = …;
constexpr std::array<uint8_t, 32> kPublicKeyBytes2 = …;
#if BUILDFLAG(IS_CHROMEOS_ASH)
constexpr std::array<uint8_t, 32> kShimless3pDiagnosticsDevPublicKeyBytes = {
0x7c, 0xf4, 0x9c, 0x48, 0x1f, 0xc5, 0x37, 0xaf, 0x33, 0x42, 0x0d,
0x3a, 0xc1, 0x13, 0x91, 0x88, 0x13, 0x53, 0x50, 0x06, 0x8b, 0x9b,
0x19, 0x42, 0xcd, 0xe8, 0xce, 0x10, 0x45, 0x12, 0xf1, 0x00};
#endif
}
class IsolatedWebAppTrustCheckerTest : public WebAppTest { … };
TEST_F(IsolatedWebAppTrustCheckerTest, DevWebBundleId) { … }
TEST_F(IsolatedWebAppTrustCheckerTest, UntrustedByDefault) { … }
#if BUILDFLAG(IS_CHROMEOS)
TEST_F(IsolatedWebAppTrustCheckerTest, TrustedViaPolicy) {
base::Value::List force_install_list;
{
base::Value::Dict force_install_entry;
force_install_entry.Set(kPolicyWebBundleIdKey, "not a web bundle id");
force_install_entry.Set(kPolicyUpdateManifestUrlKey,
"https://example.com/update-manifest.json");
force_install_list.Append(std::move(force_install_entry));
}
{
base::Value::Dict force_install_entry;
force_install_entry.Set(kPolicyWebBundleIdKey, kWebBundleId1.id());
force_install_entry.Set(kPolicyUpdateManifestUrlKey,
"https://example.com/update-manifest.json");
force_install_list.Append(std::move(force_install_entry));
}
pref_service().SetList(prefs::kIsolatedWebAppInstallForceList,
std::move(force_install_list));
{
IsolatedWebAppTrustChecker::Result result =
trust_checker().IsTrusted(kWebBundleId1,
false);
EXPECT_EQ(result.status,
IsolatedWebAppTrustChecker::Result::Status::kTrusted);
}
{
IsolatedWebAppTrustChecker::Result result =
trust_checker().IsTrusted(kWebBundleId2,
false);
EXPECT_EQ(
result.status,
IsolatedWebAppTrustChecker::Result::Status::kErrorPublicKeysNotTrusted);
}
}
#endif
TEST_F(IsolatedWebAppTrustCheckerTest,
DevModeDoesNotAutomaticallyTrustAllApps) { … }
TEST_F(IsolatedWebAppTrustCheckerTest, TrustedViaDevMode) { … }
TEST_F(IsolatedWebAppTrustCheckerTest, TrustedWebBundleIDsForTesting) { … }
#if BUILDFLAG(IS_CHROMEOS_ASH)
class ShimlessProfileIsolatedWebAppTrustCheckerTest : public ::testing::Test {
public:
void SetUp() override {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
TestingProfile::Builder profile_builder;
profile_builder.SetPath(temp_dir_.GetPath().AppendASCII(
ash::kShimlessRmaAppBrowserContextBaseName));
shimless_profile_ = profile_builder.Build();
isolated_web_app_trust_checker_ =
std::make_unique<IsolatedWebAppTrustChecker>(*shimless_profile_.get());
}
void TearDown() override { isolated_web_app_trust_checker_.reset(); }
IsolatedWebAppTrustChecker& trust_checker() {
return *isolated_web_app_trust_checker_;
}
const web_package::Ed25519PublicKey k3pDiagnosticsDevPublicKey =
web_package::Ed25519PublicKey::Create(
base::make_span(kShimless3pDiagnosticsDevPublicKeyBytes));
const web_package::SignedWebBundleId k3pDiagnosticsDevWebBundleId =
web_package::SignedWebBundleId::CreateForPublicKey(
k3pDiagnosticsDevPublicKey);
private:
content::BrowserTaskEnvironment task_environment_;
base::test::ScopedFeatureList scoped_feature_list_;
std::unique_ptr<IsolatedWebAppTrustChecker> isolated_web_app_trust_checker_;
std::unique_ptr<TestingProfile> shimless_profile_;
base::ScopedTempDir temp_dir_;
content::RenderViewHostTestEnabler rvh_test_enabler_;
};
TEST_F(ShimlessProfileIsolatedWebAppTrustCheckerTest,
TrustedVia3pDiagnosticsApp) {
auto scoped_info =
chromeos::ScopedChromeOSSystemExtensionInfo::CreateForTesting();
base::test::ScopedFeatureList feature_list;
feature_list.InitWithFeatureStates({});
scoped_info->ApplyCommandLineSwitchesForTesting();
{
IsolatedWebAppTrustChecker::Result result =
trust_checker().IsTrusted(k3pDiagnosticsDevWebBundleId,
false);
EXPECT_EQ(
result.status,
IsolatedWebAppTrustChecker::Result::Status::kErrorPublicKeysNotTrusted);
}
feature_list.Reset();
feature_list.InitWithFeatureStates(
{{ash::features::kShimlessRMA3pDiagnosticsDevMode, true}});
scoped_info->ApplyCommandLineSwitchesForTesting();
{
IsolatedWebAppTrustChecker::Result result =
trust_checker().IsTrusted(k3pDiagnosticsDevWebBundleId,
false);
EXPECT_EQ(result.status,
IsolatedWebAppTrustChecker::Result::Status::kTrusted);
}
}
#endif
}