// Copyright 2018 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 <memory>
#include <string>

#include "base/macros.h"
#include "base/test/bind_test_util.h"
#include "chrome/browser/extensions/browsertest_util.h"
#include "chrome/browser/extensions/chrome_content_verifier_delegate.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/extensions/extension_service.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_utils.h"
#include "content/public/test/url_loader_interceptor.h"
#include "extensions/browser/computed_hashes.h"
#include "extensions/browser/content_verifier/test_utils.h"
#include "extensions/browser/extension_file_task_runner.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/test_extension_registry_observer.h"
#include "extensions/common/file_util.h"
#include "services/network/public/cpp/features.h"

namespace extensions {

namespace {

// Specifies the content verification mode.
enum ContentVerificationMode {
  // Uses ContentVerifierDelegate::ENFORCE mode.
  kEnforce,
  // Uses ContentVerifierDelegate::ENFORCE_STRICT mode.
  kEnforceStrict
};

}  // namespace

// Tests content verification's hash fetch behavior and its implication on
// verification failure in different verification modes (enforce and
// enforce_strict).
// TODO(lazyboy): Add assertions for checking verified_contents.json file's
// validity after running each test.
class ContentVerifierHashTest
    : public ExtensionBrowserTest,
      public testing::WithParamInterface<ContentVerificationMode> {
 public:
  ContentVerifierHashTest() = default;
  ~ContentVerifierHashTest() override {}

  enum TamperResourceType {
    kTamperRequestedResource,
    kTamperNotRequestedResource
  };

  // ExtensionBrowserTest:
  bool ShouldEnableContentVerification() override { return true; }

  void SetUp() override {
    // Override content verification mode before ExtensionSystemImpl initializes
    // ChromeContentVerifierDelegate.
    ChromeContentVerifierDelegate::SetDefaultModeForTesting(
        uses_enforce_strict_mode() ? ContentVerifierDelegate::ENFORCE_STRICT
                                   : ContentVerifierDelegate::ENFORCE);

    ExtensionBrowserTest::SetUp();
  }

  void TearDown() override {
    ExtensionBrowserTest::TearDown();
    ChromeContentVerifierDelegate::SetDefaultModeForTesting(base::nullopt);
  }

  void TearDownOnMainThread() override {
    url_loader_interceptor_.reset();
    ExtensionBrowserTest::TearDownOnMainThread();
  }

  bool uses_enforce_strict_mode() {
    return GetParam() == ContentVerificationMode::kEnforceStrict;
  }
  bool uses_enforce_mode() {
    return GetParam() == ContentVerificationMode::kEnforce;
  }

  void DisableHashFetching() { hash_fetching_disabled_ = true; }

  testing::AssertionResult InstallDefaultResourceExtension() {
    LOG(INFO) << "InstallDefaultResourceExtension";
    return InstallExtension(kHasDefaultResource);
  }
  testing::AssertionResult InstallNoDefaultResourceExtension() {
    LOG(INFO) << "InstallNoDefaultResourceExtension";
    return InstallExtension(kDoesNotHaveDefaultResource);
  }

  void DisableExtension() { ExtensionBrowserTest::DisableExtension(id()); }

  testing::AssertionResult DeleteVerifiedContents() {
    base::ScopedAllowBlockingForTesting allow_blocking;

    base::FilePath verified_contents_path =
        file_util::GetVerifiedContentsPath(info_->extension_root);
    if (!base::PathExists(verified_contents_path)) {
      return testing::AssertionFailure()
             << "Could not find verified_contents.json.";
    }

    // Delete verified_contents.json:
    if (!base::DeleteFile(verified_contents_path, false /* recursive */)) {
      return testing::AssertionFailure()
             << "Could not delete verified_contents.json.";
    }
    return testing::AssertionSuccess();
  }

  bool HasComputedHashes() {
    base::ScopedAllowBlockingForTesting allow_blocking;
    return base::PathExists(
        file_util::GetComputedHashesPath(info_->extension_root));
  }

  testing::AssertionResult DeleteComputedHashes() {
    LOG(INFO) << "Deleting computed_hashes.json";
    base::ScopedAllowBlockingForTesting allow_blocking;
    if (!HasComputedHashes()) {
      return testing::AssertionFailure()
             << "Could not find computed_hashes.json for deletion. "
             << "Make sure the previous steps created a "
             << "computed_hashes.json, otherwise tests might fail/flake";
    }
    base::FilePath computed_hashes_path =
        file_util::GetComputedHashesPath(info_->extension_root);
    if (!base::DeleteFile(computed_hashes_path, false /* recursive */)) {
      return testing::AssertionFailure()
             << "Error deleting computed_hashes.json.";
    }
    return testing::AssertionSuccess();
  }

  testing::AssertionResult TamperComputedHashes() {
    LOG(INFO) << "Tampering computed_hashes.json";
    base::ScopedAllowBlockingForTesting allow_blocking;
    if (!HasComputedHashes()) {
      return testing::AssertionFailure()
             << "Could not find computed_hashes.json for tampering.";
    }
    base::FilePath computed_hashes_path =
        file_util::GetComputedHashesPath(info_->extension_root);
    std::string extra = R"({hello:"world"})";
    if (!base::AppendToFile(computed_hashes_path, extra.data(), extra.size())) {
      return testing::AssertionFailure()
             << "Could not tamper computed_hashes.json";
    }
    return testing::AssertionSuccess();
  }

  testing::AssertionResult TamperResource(TamperResourceType type) {
    const std::string resource_to_tamper =
        type == kTamperRequestedResource ? "background.js" : "script.js";
    base::ScopedAllowBlockingForTesting allow_blocking;
    // Modify content of a resource if this test requested that, time the
    // extension loads, hash fetch will discover content verification failure
    // due to hash mismatch.
    std::string extra = "some_extra_function_call();";
    base::FilePath real_path =
        info_->extension_root.AppendASCII(resource_to_tamper);
    if (!base::AppendToFile(real_path, extra.data(), extra.size())) {
      return testing::AssertionFailure()
             << "Could not tamper " << resource_to_tamper << ".";
    }
    return testing::AssertionSuccess();
  }

  const ExtensionId& id() const { return info_->extension_id; }

  void EnableExtensionAndWaitForCompletion(bool expect_disabled) {
    LOG(INFO) << "EnableExtensionAndWaitForCompletion: expect_disabled = "
              << expect_disabled;
    // Only observe ContentVerifyJob when necessary. This is because
    // ContentVerifyJob's callback and ContentVerifyJob::OnExtensionLoad's
    // callbacks can be race-y.
    std::unique_ptr<TestContentVerifyJobObserver> job_observer;
    const bool needs_to_observe_content_verify_job =
        // If the test wouldn't disable the extension, extensions with
        // default resource(s) will always see at at least one ContentVerifyJob
        // to a default resource (background.js).
        info_->type == kHasDefaultResource && !expect_disabled;

    if (needs_to_observe_content_verify_job) {
      LOG(INFO) << "Observing ContentVerifyJob";
      job_observer = std::make_unique<TestContentVerifyJobObserver>();
      using Result = TestContentVerifyJobObserver::Result;
      job_observer->ExpectJobResult(
          id(), base::FilePath(FILE_PATH_LITERAL("background.js")),
          Result::SUCCESS);
    }

    TestExtensionRegistryObserver registry_observer(
        ExtensionRegistry::Get(profile()), id());
    VerifierObserver verifier_observer;
    {
      EnableExtension(id());
      registry_observer.WaitForExtensionLoaded();
    }
    if (!base::ContainsKey(verifier_observer.completed_fetches(), id()))
      verifier_observer.WaitForFetchComplete(id());
    LOG(INFO) << "Verifier observer has seen FetchComplete";

    if (job_observer) {
      LOG(INFO) << "ContentVerifyJobObserver, wait for expected job";
      job_observer->WaitForExpectedJobs();
      LOG(INFO) << "ContentVerifyJobObserver, completed expected job";
    }
  }

  bool ExtensionIsDisabledForCorruption() {
    const Extension* extension = extensions::ExtensionRegistry::Get(profile())
                                     ->disabled_extensions()
                                     .GetByID(id());
    if (!extension)
      return false;

    ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
    // Make sure the extension got disabled due to corruption (and only due to
    // corruption).
    int reasons = prefs->GetDisableReasons(id());
    return reasons == disable_reason::DISABLE_CORRUPTED;
  }

  bool ExtensionIsEnabled() {
    return extensions::ExtensionRegistry::Get(profile())
        ->enabled_extensions()
        .Contains(id());
  }

  bool HasValidComputedHashes() {
    base::ScopedAllowBlockingForTesting allow_blocking;
    ComputedHashes::Reader reader;
    return reader.InitFromFile(
        file_util::GetComputedHashesPath(info_->extension_root));
  }

  bool HasValidVerifiedContents() {
    base::ScopedAllowBlockingForTesting allow_blocking;
    base::FilePath verified_contents_path =
        file_util::GetVerifiedContentsPath(info_->extension_root);
    if (!base::PathExists(verified_contents_path)) {
      ADD_FAILURE() << "Could not find verified_contents.json.";
      return false;
    }
    std::string contents;
    if (!base::ReadFileToString(verified_contents_path, &contents)) {
      ADD_FAILURE() << "Could not read verified_contents.json.";
      return false;
    }
    return verified_contents_contents_ == contents;
  }

 private:
  enum ExtensionType {
    // An extension (has_default_resource.crx) that by default requests a
    // resource in it during ExtensionLoad.
    kHasDefaultResource,
    // An extension (no_default_resources.crx) that doesn't request any
    // resource during ExtensionLoad.
    kDoesNotHaveDefaultResource
  };

  struct ExtensionInfo {
    ExtensionId extension_id;
    base::FilePath extension_root;
    base::Version version;
    ExtensionType type;

    ExtensionInfo(const ExtensionId& extension_id,
                  const base::FilePath& extension_root,
                  const base::Version& version,
                  ExtensionType type)
        : extension_id(extension_id),
          extension_root(extension_root),
          version(version),
          type(type) {}
    ExtensionInfo(const Extension* extension, ExtensionType type)
        : ExtensionInfo(extension->id(),
                        extension->path(),
                        extension->version(),
                        type) {}
  };

  // Stores verified_contents.json into a temp file.
  bool CopyVerifiedContents(base::FilePath* out_path) {
    base::ScopedAllowBlockingForTesting allow_blocking;
    if (!temp_dir_.CreateUniqueTempDir()) {
      ADD_FAILURE() << "Could not create temp dir for test.";
      return false;
    }

    base::FilePath verified_contents_path =
        file_util::GetVerifiedContentsPath(info_->extension_root);
    if (!base::PathExists(verified_contents_path)) {
      ADD_FAILURE() << "Could not find verified_contents.json for copying.";
      return false;
    }
    base::FilePath destination = temp_dir_.GetPath();
    *out_path = destination.Append(FILE_PATH_LITERAL("copy.json"));
    if (!base::CopyFile(verified_contents_path, *out_path)) {
      ADD_FAILURE() << "Could not copy verified_contents.json to a temp dir.";
      return false;
    }
    if (!base::ReadFileToString(verified_contents_path,
                                &verified_contents_contents_)) {
      ADD_FAILURE() << "Could not read verified_contents.json.";
      return false;
    }
    return true;
  }

  // Installs test extension that is copied from the webstore with actual
  // signatures.
  testing::AssertionResult InstallExtension(ExtensionType type) {
    // This observer will make sure content hash read and computed_hashes.json
    // writing is complete before we proceed.
    VerifierObserver verifier_observer;

    const std::string crx_relative_path =
        type == kHasDefaultResource
            ? "content_verifier/has_default_resource.crx"
            : "content_verifier/no_default_resources.crx";
    // These test extension is copied from the webstore that has actual
    // signatures.
    const Extension* extension = InstallExtensionFromWebstore(
        test_data_dir_.AppendASCII(crx_relative_path), 1);
    if (!extension) {
      return testing::AssertionFailure()
             << "Could not install extension: " << crx_relative_path;
    }

    const ExtensionId& extension_id = extension->id();
    if (!base::ContainsKey(verifier_observer.completed_fetches(), extension_id))
      verifier_observer.WaitForFetchComplete(extension_id);

    info_ = std::make_unique<ExtensionInfo>(extension, type);

    // Set up the interceptor functor and data needed by it.
    if (!hash_fetching_disabled_ && !InstallInterceptor())
      return testing::AssertionFailure() << "Failed to install interceptor.";

    return testing::AssertionSuccess();
  }

  bool InstallInterceptor() {
    if (url_loader_interceptor_) {
      testing::AssertionFailure() << "Already created interceptor.";
      return false;
    }

    SetUpInterceptorData();

    auto interceptor_function =
        [](GURL* fetch_url, base::FilePath* file_path,
           content::URLLoaderInterceptor::RequestParams* params) {
          GURL url = params->url_request.url;
          if (url == *fetch_url) {
            base::ScopedAllowBlockingForTesting allow_io;
            std::string contents;
            CHECK(base::ReadFileToString(*file_path, &contents));

            content::URLLoaderInterceptor::WriteResponse(
                std::string(), contents, params->client.get());
            return true;
          }
          return false;
        };
    url_loader_interceptor_ = std::make_unique<content::URLLoaderInterceptor>(
        base::BindRepeating(interceptor_function, &fetch_url_,
                            &copied_verified_contents_path_));
    return true;
  }

  bool SetUpInterceptorData() {
    // Use stored copy of verified_contents.json as hash fetch response.
    if (!CopyVerifiedContents(&copied_verified_contents_path_)) {
      ADD_FAILURE() << "Could not copy verified_contents.json.";
      return false;
    }

    ExtensionSystem* system = ExtensionSystem::Get(profile());
    fetch_url_ = system->content_verifier()->GetSignatureFetchUrlForTest(
        id(), info_->version);

    return true;
  }

  std::unique_ptr<content::URLLoaderInterceptor> url_loader_interceptor_;
  base::ScopedTempDir temp_dir_;

  base::FilePath copied_verified_contents_path_;
  GURL fetch_url_;

  // Information about the loaded extension.
  std::unique_ptr<ExtensionInfo> info_;

  // Contents of verified_contents.json (if available).
  std::string verified_contents_contents_;

  bool hash_fetching_disabled_ = false;

  DISALLOW_COPY_AND_ASSIGN(ContentVerifierHashTest);
};

// Tests that corruption of a requested extension resource always disables the
// extension.
IN_PROC_BROWSER_TEST_P(ContentVerifierHashTest,
                       TamperRequestedResourceKeepComputedHashes) {
  ASSERT_TRUE(InstallDefaultResourceExtension());

  DisableExtension();

  // Delete verified_contents.json to force a hash fetch on next load.
  EXPECT_TRUE(DeleteVerifiedContents());

  // computed_hashes.json should remain valid.
  EXPECT_TRUE(HasComputedHashes());

  // Tamper an extension resource that will be requested on next load.
  EXPECT_TRUE(TamperResource(kTamperRequestedResource));

  TestExtensionRegistryObserver registry_observer(
      ExtensionRegistry::Get(profile()), id());
  // Since we tampered with the resource, content verification should
  // disable the extension, both in "enforce_strict" and "enforce" mode.
  EnableExtensionAndWaitForCompletion(true /* expect_disabled */);
  EXPECT_TRUE(registry_observer.WaitForExtensionUnloaded());

  EXPECT_TRUE(ExtensionIsDisabledForCorruption());

  // Expect a valid verified_contents.json file at the end.
  EXPECT_TRUE(HasValidVerifiedContents());
}

// Tests that tampering a resource that will be requested by the extension and
// deleting computed_hashes.json will always disable the extension.
IN_PROC_BROWSER_TEST_P(ContentVerifierHashTest,
                       TamperRequestedResourceDeleteComputedHashes) {
  ASSERT_TRUE(InstallDefaultResourceExtension());

  DisableExtension();

  // Delete verified_contents.json to force a hash fetch on next load.
  EXPECT_TRUE(DeleteVerifiedContents());

  // Delete computed_hashes.json.
  EXPECT_TRUE(DeleteComputedHashes());

  // Tamper an extension resource that will be requested on next load.
  EXPECT_TRUE(TamperResource(kTamperRequestedResource));

  TestExtensionRegistryObserver registry_observer(
      ExtensionRegistry::Get(profile()), id());
  // Since we tampered with the resource, content verification should
  // disable the extension, both in "enforce_strict" and "enforce" mode.
  EnableExtensionAndWaitForCompletion(true /* expect_disabled */);
  EXPECT_TRUE(registry_observer.WaitForExtensionUnloaded());

  EXPECT_TRUE(ExtensionIsDisabledForCorruption());

  // Expect a valid computed_hashes.json file at the end, the verification
  // failure must have used this file to detect corruption.
  EXPECT_TRUE(HasValidComputedHashes());

  // Expect a valid verified_contents.json file at the end.
  EXPECT_TRUE(HasValidVerifiedContents());
}

// Tests that tampering a resource that will be requested by the extension and
// tampering computed_hashes.json will always disable the extension.
IN_PROC_BROWSER_TEST_P(ContentVerifierHashTest,
                       TamperRequestedResourceTamperComputedHashes) {
  ASSERT_TRUE(InstallDefaultResourceExtension());

  DisableExtension();

  // Delete verified_contents.json to force a hash fetch on next load.
  EXPECT_TRUE(DeleteVerifiedContents());

  // Tamper computed_hashes.json.
  EXPECT_TRUE(TamperComputedHashes());

  // Tamper an extension resource that will be requested on next load.
  EXPECT_TRUE(TamperResource(kTamperRequestedResource));

  TestExtensionRegistryObserver registry_observer(
      ExtensionRegistry::Get(profile()), id());
  // Since we tampered with the resource, content verification should
  // disable the extension, both in "enforce_strict" and "enforce" mode.
  EnableExtensionAndWaitForCompletion(true /* expect_disabled */);
  EXPECT_TRUE(registry_observer.WaitForExtensionUnloaded());

  EXPECT_TRUE(ExtensionIsDisabledForCorruption());

  // Expect a valid computed_hashes.json file at the end, the verification
  // failure must have used this file to detect corruption.
  EXPECT_TRUE(HasValidComputedHashes());

  // Expect a valid verified_contents.json file at the end.
  EXPECT_TRUE(HasValidVerifiedContents());
}

// Tests hash fetch failure scenario with an extension that requests resource(s)
// by default.
IN_PROC_BROWSER_TEST_P(ContentVerifierHashTest,
                       FetchFailureWithDefaultResourceExtension) {
  // Do *not* install any hash fetch interceptor, so that hash fetch after
  // reload fails.
  DisableHashFetching();

  ASSERT_TRUE(InstallDefaultResourceExtension());

  DisableExtension();

  // Delete verified_contents.json to force a hash fetch on next load.
  EXPECT_TRUE(DeleteVerifiedContents());

  // computed_hashes.json and extension resource(s) aren't touched since they do
  // not matter as hash fetch will fail.

  // In "enforce_strict" mode, hash fetch failures will cause the extension to
  // be disabled. Implementation-wise, this happens because the requested
  // resource's ContentVerifyJob will result in failure, not because the hash
  // fetch failed. See https://crbug.com/819818 for details.
  //
  // In "enforce" mode, the extension won't be disabled. However, since we
  // request a resource (background.js), its corresponding ContentVerifyJob will
  // attempt to fetch hash and that job will also fail. In order to achieve
  // determinism in this case, also observe a ContentVerifyJob that will fail.
  const bool expect_disabled = uses_enforce_strict_mode();

  // Similar to EnableExtensionAndWaitForCompletion, but also forces a
  // ContentVerifyJob observer in "enforce" mode.
  // Instead of generalizing this oddball expectation into
  // EnableExtensionAndWaitForCompletion, provide the implementation right here
  // in the test body.
  {
    LOG(INFO) << "EnableExtensionAndWaitForCompletion: expect_disabled = "
              << expect_disabled;
    ExtensionId extension_id = id();

    // Only observe ContentVerifyJob when necessary. This is because
    // ContentVerifyJob's callback and ContentVerifyJob::OnExtensionLoad's
    // callbacks can be race-y.
    std::unique_ptr<TestContentVerifyJobObserver> job_observer;
    if (uses_enforce_mode()) {
      // In "enforce" mode, we expect to see a job completion (and its failure).
      job_observer = std::make_unique<TestContentVerifyJobObserver>();
      using Result = TestContentVerifyJobObserver::Result;
      job_observer->ExpectJobResult(
          extension_id,
          // This extension has default resource (background.js), so it must
          // request it.
          base::FilePath(FILE_PATH_LITERAL("background.js")), Result::FAILURE);
    }

    TestExtensionRegistryObserver registry_observer(
        ExtensionRegistry::Get(profile()), extension_id);
    VerifierObserver verifier_observer;
    {
      EnableExtension(extension_id);
      registry_observer.WaitForExtensionLoaded();
    }
    if (!base::ContainsKey(verifier_observer.completed_fetches(), extension_id))
      verifier_observer.WaitForFetchComplete(extension_id);
    LOG(INFO) << "Verifier observer has seen FetchComplete";

    if (job_observer) {
      LOG(INFO) << "ContentVerifyJobObserver, wait for expected job";
      job_observer->WaitForExpectedJobs();
      LOG(INFO) << "ContentVerifyJobObserver, completed expected job";
    }

    if (expect_disabled)
      EXPECT_TRUE(registry_observer.WaitForExtensionUnloaded());
  }

  EXPECT_TRUE(expect_disabled ? ExtensionIsDisabledForCorruption()
                              : ExtensionIsEnabled());
}

// Tests that hash fetch failure for loading an extension that doesn't request
// any resource by default will not be disabled.
IN_PROC_BROWSER_TEST_P(ContentVerifierHashTest,
                       FetchFailureWithNoDefaultResourceDoesNotDisable) {
  // Do *not* install any hash fetch interceptor, so that hash fetch after
  // reload fails.
  DisableHashFetching();

  ASSERT_TRUE(InstallNoDefaultResourceExtension());

  DisableExtension();

  // Delete verified_contents.json to force a hash fetch on next load.
  EXPECT_TRUE(DeleteVerifiedContents());

  // computed_hashes.json and extension resource(s) aren't touched since they do
  // not matter as hash fetch will fail.

  // If the extension didn't explicitly request any resources, then there will
  // not be any content verification failures.
  const bool expect_disabled = false;
  // TODO(lazyboy): https://crbug.com/819818: "enforce_strict" mode should
  // disable the extension.
  // const bool expect_disabled = uses_enforce_strict_mode();
  EnableExtensionAndWaitForCompletion(expect_disabled);

  EXPECT_TRUE(expect_disabled ? ExtensionIsDisabledForCorruption()
                              : ExtensionIsEnabled());
}

// Tests the behavior of tampering an extension resource that is not requested
// by default and without modifying computed_hashes.json.
IN_PROC_BROWSER_TEST_P(ContentVerifierHashTest,
                       TamperNotRequestedResourceKeepComputedHashes) {
  ASSERT_TRUE(InstallDefaultResourceExtension());

  DisableExtension();

  // Delete verified_contents.json to force a hash fetch on next load.
  EXPECT_TRUE(DeleteVerifiedContents());

  // computed_hashes.json should remain valid.
  EXPECT_TRUE(HasComputedHashes());

  // Tamper an extension resource that will *not* be requested on next load.
  EXPECT_TRUE(TamperResource(kTamperNotRequestedResource));

  // We tampered a resource that is not requested by the extension. Keeping
  // computed_hashes.json will not compute new compute computed_hashes.json, and
  // we will not discover the tampered hash. So the extension won't be disabled.
  //
  // TODO(lazyboy): http://crbug.com/819832: We fetched a new
  // verified_contents.json in this case. However, if we had recomputed
  // computed_hashes.json we would have discovered the tampered resource's hash
  // mismatch. Fix.
  const bool expect_disabled = false;
  EnableExtensionAndWaitForCompletion(expect_disabled);

  EXPECT_TRUE(ExtensionIsEnabled());

  // Expect a valid verified_contents.json file at the end.
  EXPECT_TRUE(HasValidVerifiedContents());
}

// Tests the behavior of loading an extension without any default resource
// request and deleting its computed_hashes.json before fetching hashes.
IN_PROC_BROWSER_TEST_P(ContentVerifierHashTest,
                       TamperNoResourceExtensionDeleteComputedHashes) {
  ASSERT_TRUE(InstallNoDefaultResourceExtension());

  DisableExtension();

  // Delete verified_contents.json to force a hash fetch on next load.
  EXPECT_TRUE(DeleteVerifiedContents());

  // Delete computed_hashes.json.
  EXPECT_TRUE(DeleteComputedHashes());

  // Tamper an extension resource that will *not* be requested on next load.
  EXPECT_TRUE(TamperResource(kTamperNotRequestedResource));

  TestExtensionRegistryObserver registry_observer(
      ExtensionRegistry::Get(profile()), id());
  // The deletion of computed_hashes.json forces its recomputation and disables
  // the extension.
  EnableExtensionAndWaitForCompletion(true /* expect_disabled */);
  EXPECT_TRUE(registry_observer.WaitForExtensionUnloaded());

  EXPECT_TRUE(ExtensionIsDisabledForCorruption());

  // Expect a valid computed_hashes.json file at the end, the verification
  // failure must have used this file to detect corruption.
  EXPECT_TRUE(HasValidComputedHashes());

  // Expect a valid verified_contents.json file at the end.
  EXPECT_TRUE(HasValidVerifiedContents());
}

// Tests the behavior of loading an extension without any default resource
// request and keeping its computed_hashes.json.
IN_PROC_BROWSER_TEST_P(ContentVerifierHashTest,
                       TamperNoResourceExtensionKeepComputedHashes) {
  ASSERT_TRUE(InstallNoDefaultResourceExtension());

  DisableExtension();

  // Delete verified_contents.json to force a hash fetch on next load.
  EXPECT_TRUE(DeleteVerifiedContents());

  // computed_hashes.json should remain valid.
  EXPECT_TRUE(HasComputedHashes());

  // Tamper an extension resource that will *not* be requested on next load.
  EXPECT_TRUE(TamperResource(kTamperNotRequestedResource));

  // Not modifying computed_hashes.json will not trigger any hash computation
  // at OnExtensionLoad, so we won't discover any hash mismatches.
  EnableExtensionAndWaitForCompletion(false /* expect_disabled */);

  EXPECT_TRUE(ExtensionIsEnabled());

  // Expect a valid verified_contents.json file at the end.
  EXPECT_TRUE(HasValidVerifiedContents());
}

// Tests the behavior of loading an extension without any default resource
// request and tampering its computed_hashes.json.
IN_PROC_BROWSER_TEST_P(ContentVerifierHashTest,
                       TamperNoResourceExtensionTamperComputedHashes) {
  ASSERT_TRUE(InstallNoDefaultResourceExtension());

  DisableExtension();

  // Delete verified_contents.json to force a hash fetch on next load.
  EXPECT_TRUE(DeleteVerifiedContents());

  // Tamper computed_hashes.json.
  EXPECT_TRUE(TamperComputedHashes());

  // Tamper an extension resource that will *not* be requested on next load.
  EXPECT_TRUE(TamperResource(kTamperNotRequestedResource));

  // Tampering computed_hashes.json will not trigger any hash computation
  // at OnExtensionLoad, so we won't discover any hash mismatches.
  // TODO(lazyboy): Consider fixing this, see http://crbug.com/819832 for
  // details.
  EnableExtensionAndWaitForCompletion(false /* expect_disabled */);

  EXPECT_TRUE(ExtensionIsEnabled());

  // Because we didn't do any hash computation, expect computed_hashes.json to
  // still remain invalid.
  EXPECT_FALSE(HasValidComputedHashes());

  // Expect a valid verified_contents.json file at the end.
  EXPECT_TRUE(HasValidVerifiedContents());
}

// Tests the behavior of loading a default resource extension with tampering
// an extension resource that is not requested by default and without modifying
// computed_hashes.json.
IN_PROC_BROWSER_TEST_P(
    ContentVerifierHashTest,
    DefaultRequestExtensionTamperNotRequestedResourceKeepComputedHashes) {
  ASSERT_TRUE(InstallDefaultResourceExtension());

  DisableExtension();

  // Delete verified_contents.json to force a hash fetch on next load.
  EXPECT_TRUE(DeleteVerifiedContents());

  // computed_hashes.json should remain valid.
  EXPECT_TRUE(HasComputedHashes());

  // Tamper an extension resource that will *not* be requested on next load.
  EXPECT_TRUE(TamperResource(kTamperNotRequestedResource));

  // TODO(lazyboy): Not modifying the computed_hashes.json file doesn't prompt
  // a hash recomputation and the requested (not-tampered) resource's
  // corresponding ContentVerifyJob succeeds because that resource's hash
  // remains fine. Therefore, the extension remains enabled. Consider disabling
  // the extension in this case: https://crbug.com/819832.
  EnableExtensionAndWaitForCompletion(false /* expect_disabled */);

  EXPECT_TRUE(ExtensionIsEnabled());

  // Expect a valid verified_contents.json file at the end.
  EXPECT_TRUE(HasValidVerifiedContents());
}

// Tests the behavior of loading a default resource extension with tampering
// an extension resource that is not requested by default and tampering
// computed_hashes.json.
IN_PROC_BROWSER_TEST_P(
    ContentVerifierHashTest,
    DefaultRequestExtensionTamperNotRequestedResourceTamperComputedHashes) {
  ASSERT_TRUE(InstallDefaultResourceExtension());

  DisableExtension();

  // Delete verified_contents.json to force a hash fetch on next load.
  EXPECT_TRUE(DeleteVerifiedContents());

  // Tamper computed_hashes.json.
  EXPECT_TRUE(TamperComputedHashes());

  // Tamper an extension resource that will *not* be requested on next load.
  EXPECT_TRUE(TamperResource(kTamperNotRequestedResource));

  TestExtensionRegistryObserver registry_observer(
      ExtensionRegistry::Get(profile()), id());
  // Subtle: tampering computed_hashes.json (by itself) will not trigger any
  // hash computation or failure during OnExtensionLoad. However, the default
  // resource request (that isn't tampered) will prompt a hash read that will
  // fail due to the tampered computed_hashes.json.
  EnableExtensionAndWaitForCompletion(true /* expect_disabled */);
  EXPECT_TRUE(registry_observer.WaitForExtensionUnloaded());

  EXPECT_TRUE(ExtensionIsDisabledForCorruption());

  // Expect a valid computed_hashes.json file at the end, the verification
  // failure must have used this file to detect corruption.
  EXPECT_TRUE(HasValidComputedHashes());

  // Expect a valid verified_contents.json file at the end.
  EXPECT_TRUE(HasValidVerifiedContents());
}

// Tests the behavior of loading a default resource extension with tampering
// an extension resource that is not requested by default and deleting
// computed_hashes.json.
IN_PROC_BROWSER_TEST_P(
    ContentVerifierHashTest,
    DefaultRequestExtensionTamperNotRequestedResourceDeleteComputedHashes) {
  ASSERT_TRUE(InstallDefaultResourceExtension());

  DisableExtension();

  // Delete verified_contents.json to force a hash fetch on next load.
  EXPECT_TRUE(DeleteVerifiedContents());

  // Delete computed_hashes.json.
  EXPECT_TRUE(DeleteComputedHashes());

  // Tamper an extension resource that will *not* be requested on next load.
  EXPECT_TRUE(TamperResource(kTamperNotRequestedResource));

  TestExtensionRegistryObserver registry_observer(
      ExtensionRegistry::Get(profile()), id());
  // The deletion of computed_hashes.json will trigger hash recomputation and
  // the file's regeneration. This will discover the resource tampering and
  // disable the extension.
  EnableExtensionAndWaitForCompletion(true /* expect_disabled */);
  EXPECT_TRUE(registry_observer.WaitForExtensionUnloaded());

  EXPECT_TRUE(ExtensionIsDisabledForCorruption());

  // Expect a valid computed_hashes.json file at the end, the verification
  // failure must have used this file to detect corruption.
  EXPECT_TRUE(HasValidComputedHashes());

  // Expect a valid verified_contents.json file at the end.
  EXPECT_TRUE(HasValidVerifiedContents());
}

INSTANTIATE_TEST_CASE_P(FetchBehaviorTests,
                        ContentVerifierHashTest,
                        testing::Values(kEnforce, kEnforceStrict));

}  // namespace extensions
