// 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 "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 "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 "net/url_request/test_url_request_interceptor.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);
  }

  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);
    }

    if (interceptor_) {
      EXPECT_EQ(0, interceptor_->GetHitCount()) << "Interceptor should not "
                                                   "have seen any requests "
                                                   "before enabling extension.";
    }

    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;
  }

  bool AddInterceptor() {
    if (interceptor_) {
      ADD_FAILURE() << "Already created interceptor.";
      return false;
    }

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

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

    // Mock serving |copied_verified_contents_path| for content hash, so that
    // hash fetch succeeds.
    interceptor_ = std::make_unique<net::TestURLRequestInterceptor>(
        fetch_url.scheme(), fetch_url.host(),
        content::BrowserThread::GetTaskRunnerForThread(
            content::BrowserThread::IO),
        GetExtensionFileTaskRunner());
    interceptor_->SetResponse(fetch_url, copied_verified_contents_path);
    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);

    // Interceptor.
    if (!hash_fetching_disabled_ && !AddInterceptor())
      return testing::AssertionFailure() << "Failed to install interceptor.";

    return testing::AssertionSuccess();
  }

  std::unique_ptr<net::TestURLRequestInterceptor> interceptor_;
  base::ScopedTempDir temp_dir_;

  // 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
