// Copyright 2014 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 <stdint.h>

#include <string>
#include <vector>

#include "base/base64url.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/path_service.h"
#include "base/stl_util.h"
#include "build/build_config.h"
#include "extensions/browser/content_verifier/content_verifier_utils.h"
#include "extensions/browser/verified_contents.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_paths.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace extensions {

namespace {

const char kContentVerifierDirectory[] = "content_verifier/";
const char kPublicKeyPem[] = "public_key.pem";

constexpr bool kIsFileAccessCaseInsensitive =
    !content_verifier_utils::IsFileAccessCaseSensitive();
constexpr bool kIsDotSpaceSuffixIgnored =
    content_verifier_utils::IsDotSpaceFilenameSuffixIgnored();

std::string DecodeBase64Url(const std::string& encoded) {
  std::string decoded;
  if (!base::Base64UrlDecode(
          encoded, base::Base64UrlDecodePolicy::IGNORE_PADDING, &decoded))
    return std::string();

  return decoded;
}

bool GetPublicKey(const base::FilePath& path, std::string* public_key) {
  std::string public_key_pem;
  if (!base::ReadFileToString(path, &public_key_pem))
    return false;
  if (!Extension::ParsePEMKeyBytes(public_key_pem, public_key))
    return false;
  return true;
}

base::FilePath GetTestDir(const char* sub_dir) {
  base::FilePath path;
  base::PathService::Get(DIR_TEST_DATA, &path);
  return path.AppendASCII(kContentVerifierDirectory).AppendASCII(sub_dir);
}

// Loads verified_contents file from a sub directory under
// kContentVerifierDirectory.
std::unique_ptr<VerifiedContents> CreateTestVerifiedContents(
    const char* sub_dir,
    const char* verified_contents_filename) {
  // Figure out our test data directory.
  base::FilePath path = GetTestDir(sub_dir);

  // Initialize the VerifiedContents object.
  std::string public_key;
  if (!GetPublicKey(path.AppendASCII(kPublicKeyPem), &public_key))
    return nullptr;

  base::FilePath verified_contents_path =
      path.AppendASCII(verified_contents_filename);
  return VerifiedContents::Create(base::as_bytes(base::make_span(public_key)),
                                  verified_contents_path);
}

}  // namespace

TEST(VerifiedContents, Simple) {
  std::unique_ptr<VerifiedContents> verified_contents =
      CreateTestVerifiedContents("simple", "verified_contents.json");
  ASSERT_TRUE(verified_contents);
  const VerifiedContents& contents = *verified_contents;

  // Make sure we get expected values.
  EXPECT_EQ(contents.block_size(), 4096);
  EXPECT_EQ(contents.extension_id(), "abcdefghijklmnopabcdefghijklmnop");
  EXPECT_EQ("1.2.3", contents.version().GetString());

  EXPECT_TRUE(contents.TreeHashRootEquals(
      base::FilePath::FromUTF8Unsafe("manifest.json"),
      DecodeBase64Url("-vyyIIn7iSCzg7X3ICUI5wZa3tG7w7vyiCckxZdJGfs")));

  EXPECT_TRUE(contents.TreeHashRootEquals(
      base::FilePath::FromUTF8Unsafe("background.js"),
      DecodeBase64Url("txHiG5KQvNoPOSH5FbQo9Zb5gJ23j3oFB0Ru9DOnziw")));

  base::FilePath foo_bar_html =
      base::FilePath(FILE_PATH_LITERAL("foo")).AppendASCII("bar.html");
  EXPECT_FALSE(foo_bar_html.IsAbsolute());
  EXPECT_TRUE(contents.TreeHashRootEquals(
      foo_bar_html,
      DecodeBase64Url("L37LFbT_hmtxRL7AfGZN9YTpW6yoz_ZiQ1opLJn1NZU")));

  base::FilePath nonexistent = base::FilePath::FromUTF8Unsafe("nonexistent");
  EXPECT_FALSE(contents.HasTreeHashRoot(nonexistent));

  std::map<std::string, std::string> hashes = {
      {"lowercase.html", "HpLotLGCmmOdKYvGQmD3OkXMKGs458dbanY4WcfAZI0"},
      {"ALLCAPS.html", "bl-eV8ENowvtw6P14D4X1EP0mlcMoG-_aOx5o9C1364"},
      {"MixedCase.Html", "zEAO9FwciigMNy3NtU2XNb-dS5TQMmVNx0T9h7WvXbQ"},
      {"mIxedcAse.Html", "nKRqUcJg1_QZWAeCb4uFd5ouC0McuGavKp8TFDRqBgg"},
  };

  // Resource is "lowercase.html".
  EXPECT_TRUE(contents.TreeHashRootEquals(
      base::FilePath::FromUTF8Unsafe("lowercase.html"),
      DecodeBase64Url(hashes["lowercase.html"])));
  // Only case-insensitive systems should be able to get hashes with incorrect
  // case.
  EXPECT_EQ(kIsFileAccessCaseInsensitive,
            contents.TreeHashRootEquals(
                base::FilePath::FromUTF8Unsafe("Lowercase.Html"),
                DecodeBase64Url(hashes["lowercase.html"])));
  EXPECT_EQ(kIsFileAccessCaseInsensitive,
            contents.TreeHashRootEquals(
                base::FilePath::FromUTF8Unsafe("LOWERCASE.HTML"),
                DecodeBase64Url(hashes["lowercase.html"])));

  // Resource is "ALLCAPS.HTML"
  EXPECT_TRUE(contents.TreeHashRootEquals(
      base::FilePath::FromUTF8Unsafe("ALLCAPS.HTML"),
      DecodeBase64Url(hashes["ALLCAPS.html"])));
  // Only case-insensitive systems should be able to get hashes with incorrect
  // case.
  EXPECT_EQ(kIsFileAccessCaseInsensitive,
            contents.TreeHashRootEquals(
                base::FilePath::FromUTF8Unsafe("AllCaps.Html"),
                DecodeBase64Url(hashes["ALLCAPS.html"])));
  EXPECT_EQ(kIsFileAccessCaseInsensitive,
            contents.TreeHashRootEquals(
                base::FilePath::FromUTF8Unsafe("allcaps.html"),
                DecodeBase64Url(hashes["ALLCAPS.html"])));

  // Resources are "MixedCase.Html", "mIxedcAse.Html".
  EXPECT_TRUE(contents.TreeHashRootEquals(
      base::FilePath::FromUTF8Unsafe("MixedCase.Html"),
      DecodeBase64Url(hashes["MixedCase.Html"])));
  EXPECT_TRUE(contents.TreeHashRootEquals(
      base::FilePath::FromUTF8Unsafe("mIxedcAse.Html"),
      DecodeBase64Url(hashes["mIxedcAse.Html"])));
  // In case-sensitive systems, swapping hashes within MixedCase.Html and
  // mIxedcAse.Html always would mismatch hash, but it matches for
  // case-insensitive systems.
  // TODO(https:://crbug.com/1040702): Fix if this becomes a problem.
  EXPECT_EQ(kIsFileAccessCaseInsensitive,
            contents.TreeHashRootEquals(
                base::FilePath::FromUTF8Unsafe("mIxedcAse.Html"),
                DecodeBase64Url(hashes["MixedCase.Html"])));
  EXPECT_EQ(kIsFileAccessCaseInsensitive,
            contents.TreeHashRootEquals(
                base::FilePath::FromUTF8Unsafe("MixedCase.Html"),
                DecodeBase64Url(hashes["mIxedcAse.Html"])));
  // Continuing from above, in case-insensitive systems, there is non
  // deterministic behavior here, e.g. MIXEDCASE.HTML will match both hashes of
  // MixedCase.Html and mIxedcAse.Html.
  EXPECT_EQ(kIsFileAccessCaseInsensitive,
            contents.TreeHashRootEquals(
                base::FilePath::FromUTF8Unsafe("MIXEDCASE.HTML"),
                DecodeBase64Url(hashes["MixedCase.Html"])));
  EXPECT_EQ(kIsFileAccessCaseInsensitive,
            contents.TreeHashRootEquals(
                base::FilePath::FromUTF8Unsafe("MIXEDCASE.HTML"),
                DecodeBase64Url(hashes["mIxedcAse.Html"])));
  EXPECT_EQ(kIsFileAccessCaseInsensitive,
            contents.TreeHashRootEquals(
                base::FilePath::FromUTF8Unsafe("mixedcase.html"),
                DecodeBase64Url(hashes["MixedCase.Html"])));
  EXPECT_EQ(kIsFileAccessCaseInsensitive,
            contents.TreeHashRootEquals(
                base::FilePath::FromUTF8Unsafe("mixedcase.html"),
                DecodeBase64Url(hashes["mIxedcAse.Html"])));

  // Regression test for https://crbug.com/776609.
  EXPECT_FALSE(contents.TreeHashRootEquals(
      base::FilePath::FromUTF8Unsafe("allcaps.html"),
      // This is the hash of "mixedcase.html".
      DecodeBase64Url("zEAO9FwciigMNy3NtU2XNb-dS5TQMmVNx0T9h7WvXbQ")));
}

TEST(VerifiedContents, FailsOnBase64) {
  // Accepting base64-encoded input where base64url-encoded input is expected
  // will be considered to be invalid data. Verify that it gets rejected.
  ASSERT_FALSE(
      CreateTestVerifiedContents("simple", "verified_contents_base64.json"));
}

// Tests behavior of verified contents with filenames that have "." and " "
// suffixes appened to them.
// Regression test for https://crbug.com/696208.
TEST(VerifiedContents, DotSpaceSuffixedFiles) {
  std::unique_ptr<VerifiedContents> contents =
      CreateTestVerifiedContents("dot_space_suffix", "verified_contents.json");
  ASSERT_TRUE(contents);

  // Make sure we get expected values.
  EXPECT_EQ(contents->block_size(), 4096);
  EXPECT_EQ(contents->extension_id(), "abcdabcdabcdabcdabcdabcdabcdabcd");
  EXPECT_EQ("1.2.3.4", contents->version().GetString());

  auto has_tree_hash_root = [&contents](const std::string& file_path_str) {
    return contents->HasTreeHashRoot(
        base::FilePath::FromUTF8Unsafe(file_path_str));
  };
  auto tree_hash_root_equals = [&contents](const std::string& file_path_str,
                                           const char* expected_hash) {
    return contents->TreeHashRootEquals(
        base::FilePath::FromUTF8Unsafe(file_path_str),
        DecodeBase64Url(expected_hash));
  };

  // Non-existent files won't be found in tree hash.
  EXPECT_FALSE(has_tree_hash_root("non-existent.js"));
  EXPECT_FALSE(has_tree_hash_root(""));

  struct TestFileInfo {
    const char* filename;
    const char* root_hashes;
  };
  std::vector<TestFileInfo> info_list{
      {
          "manifest.json", "ysCDJuQ1s7vWF4yUZTRB2_XDE6vfFyQcIPSmyvNvqEw",
      },
      {
          "background.js", "uYeF7eHzVgKpiBg5fikv2NTctmJnxCfX1UhhlrizvNE",
      },
      {
          "mixedcase.html", "S1lnRa4Yu1CM2dCwJoFYKfAqRkFC7SSI4tzyIOzO7hA",
      },
      {
          "mixedCase.html", "FVncNmt1wBfFn3aZVTnMB9CFRTRIl0Z4YFqm14Wmrhs",
      },
      {
          "doT.html.", "jEsJEk-0azFYx7G91rSUPuzPBXp95863lG4MDwZcSog",
      },
  };

  std::vector<std::string> kSuffixes{
      // Only spaces.
      " ", "  ", "   ",
      // Only dots.
      ".", "..", "...",
      // Mix of dots and spaces.
      ". ", ".  ", ".. ", "... ", " .", "  .", "   .", " . ", " ..", " ...",
      " .. ",
  };

  for (const TestFileInfo& info : info_list) {
    // The original filenames' hashes must exist.
    EXPECT_TRUE(has_tree_hash_root(info.filename));
    EXPECT_TRUE(tree_hash_root_equals(info.filename, info.root_hashes));

    // Verify that the discovery of tree hashes is also correct when the
    // filenames are appended with dot and space characters:
    //   - they should still succeed on windows (kIsDotSpaceSuffixIgnored
    //     = true).
    //   - they should fail otherwise (kIsDotSpaceSuffixIgnored = false).
    for (const std::string& suffix : kSuffixes) {
      std::string path_with_suffix = std::string(info.filename).append(suffix);
      EXPECT_EQ(kIsDotSpaceSuffixIgnored, has_tree_hash_root(path_with_suffix));
    }
  }

  // For background.js, additionally verify that reading the file with and
  // without the suffixes described above matches our expectations, taking
  // kIsDotSpaceSuffixIgnored into account.
  const char* kBackgroundJSFilename = "background.js";
  const char* kBackgroundJSContents = "console.log('hello');\n";
  base::FilePath test_dir = GetTestDir("dot_space_suffix");
  {
    // Case 1/2: background.js without suffix.
    base::FilePath background_js_path =
        test_dir.AppendASCII(kBackgroundJSFilename);
    EXPECT_TRUE(base::PathExists(background_js_path));
    std::string background_js_contents;
    EXPECT_TRUE(
        base::ReadFileToString(background_js_path, &background_js_contents));
    EXPECT_EQ(kBackgroundJSContents, background_js_contents);
  }
  {
    // Case 2/2: background.js with dot/space suffixes.
    for (const std::string& suffix : kSuffixes) {
      base::FilePath background_js_suffix_path = test_dir.AppendASCII(
          std::string(kBackgroundJSFilename).append(suffix));
      EXPECT_EQ(kIsDotSpaceSuffixIgnored,
                base::PathExists(background_js_suffix_path));
      if (kIsDotSpaceSuffixIgnored) {
        std::string background_js_suffix_contents;
        EXPECT_TRUE(base::ReadFileToString(background_js_suffix_path,
                                           &background_js_suffix_contents));
        EXPECT_EQ(kBackgroundJSContents, background_js_suffix_contents);
      }
    }
  }
}

// Tests behavior of verified_contents.json file containing keys already with
// "." suffix.
// Regression test for https://crbug.com/696208.
TEST(VerifiedContents, VerifiedContentsFileContainsDotSuffixedFilename) {
  std::unique_ptr<VerifiedContents> contents =
      CreateTestVerifiedContents("dot_space_suffix", "verified_contents.json");
  ASSERT_TRUE(contents);

  // Make sure we get expected values.
  EXPECT_EQ(contents->block_size(), 4096);
  EXPECT_EQ(contents->extension_id(), "abcdabcdabcdabcdabcdabcdabcdabcd");
  EXPECT_EQ("1.2.3.4", contents->version().GetString());

  auto has_tree_hash_root = [&contents](const std::string& file_path_str) {
    return contents->HasTreeHashRoot(
        base::FilePath::FromUTF8Unsafe(file_path_str));
  };
  auto tree_hash_root_equals = [&contents](const std::string& file_path_str,
                                           const char* expected_hash) {
    return contents->TreeHashRootEquals(
        base::FilePath::FromUTF8Unsafe(file_path_str),
        DecodeBase64Url(expected_hash));
  };

  // The original key "doT.html." should always succeed.
  EXPECT_TRUE(has_tree_hash_root("doT.html."));
  EXPECT_TRUE(tree_hash_root_equals(
      "doT.html.", "jEsJEk-0azFYx7G91rSUPuzPBXp95863lG4MDwZcSog"));
  // Its case variants would only succeed for case-insensitive system.
  EXPECT_EQ(kIsFileAccessCaseInsensitive, has_tree_hash_root("dot.html."));
  EXPECT_EQ(kIsFileAccessCaseInsensitive,
            tree_hash_root_equals(
                "dot.html.", "jEsJEk-0azFYx7G91rSUPuzPBXp95863lG4MDwZcSog"));

  // Keys with dot stripped succeeds if kIsDotSpaceSuffixIgnored is true.
  {
    const char* kKey = "dot.html";
    EXPECT_EQ(kIsDotSpaceSuffixIgnored, has_tree_hash_root(kKey));
    EXPECT_EQ(kIsDotSpaceSuffixIgnored,
              tree_hash_root_equals(
                  kKey, "jEsJEk-0azFYx7G91rSUPuzPBXp95863lG4MDwZcSog"));
  }

  // Also, adding (.| )+ suffix would succeed if kIsDotSpaceSuffixIgnored is
  // true. This is already part of VerifiedContents.DotSpaceSuffixedFiles test.
}

}  // namespace extensions
