// 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/bind.h"
#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_SUITE_P(FetchBehaviorTests,
                         ContentVerifierHashTest,
                         testing::Values(kEnforce, kEnforceStrict));

}  // namespace extensions
