/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agree to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <string>
#include <vector>

#include <android-base/file.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <gtest/gtest.h>
#include <openssl/bn.h>
#include <openssl/ec.h>
#include <openssl/nid.h>
#include <ziparchive/zip_writer.h>

#include "common/test_constants.h"
#include "otautil/sysutil.h"
#include "package.h"
#include "verifier.h"

using namespace std::string_literals;

static void LoadKeyFromFile(const std::string& file_name, Certificate* cert) {
  std::string testkey_string;
  ASSERT_TRUE(android::base::ReadFileToString(file_name, &testkey_string));
  ASSERT_TRUE(LoadCertificateFromBuffer(
      std::vector<uint8_t>(testkey_string.begin(), testkey_string.end()), cert));
}

static void VerifyFile(const std::string& content, const std::vector<Certificate>& keys,
                       int expected) {
  auto package =
      Package::CreateMemoryPackage(std::vector<uint8_t>(content.begin(), content.end()), nullptr);
  ASSERT_NE(nullptr, package);

  ASSERT_EQ(expected, verify_file(package.get(), keys));
}

static void VerifyPackageWithCertificates(const std::string& name,
                                          const std::vector<Certificate>& certs) {
  std::string path = from_testdata_base(name);
  auto package = Package::CreateMemoryPackage(path, nullptr);
  ASSERT_NE(nullptr, package);

  ASSERT_EQ(VERIFY_SUCCESS, verify_file(package.get(), certs));
}

static void VerifyPackageWithSingleCertificate(const std::string& name, Certificate&& cert) {
  std::vector<Certificate> certs;
  certs.emplace_back(std::move(cert));
  VerifyPackageWithCertificates(name, certs);
}

static void BuildCertificateArchive(const std::vector<std::string>& file_names, int fd) {
  FILE* zip_file_ptr = fdopen(fd, "wb");
  ZipWriter zip_writer(zip_file_ptr);

  for (const auto& name : file_names) {
    std::string content;
    ASSERT_TRUE(android::base::ReadFileToString(name, &content));

    // Makes sure the zip entry name has the correct suffix.
    std::string entry_name = name;
    if (!android::base::EndsWith(entry_name, "x509.pem")) {
      entry_name += "x509.pem";
    }
    ASSERT_EQ(0, zip_writer.StartEntry(entry_name.c_str(), ZipWriter::kCompress));
    ASSERT_EQ(0, zip_writer.WriteBytes(content.data(), content.size()));
    ASSERT_EQ(0, zip_writer.FinishEntry());
  }

  ASSERT_EQ(0, zip_writer.Finish());
  ASSERT_EQ(0, fclose(zip_file_ptr));
}

TEST(VerifierTest, LoadCertificateFromBuffer_failure) {
  Certificate cert(0, Certificate::KEY_TYPE_RSA, nullptr, nullptr);
  std::string testkey_string;
  ASSERT_TRUE(
      android::base::ReadFileToString(from_testdata_base("testkey_v1.txt"), &testkey_string));
  ASSERT_FALSE(LoadCertificateFromBuffer(
      std::vector<uint8_t>(testkey_string.begin(), testkey_string.end()), &cert));
}

TEST(VerifierTest, LoadCertificateFromBuffer_sha1_exponent3) {
  Certificate cert(0, Certificate::KEY_TYPE_RSA, nullptr, nullptr);
  LoadKeyFromFile(from_testdata_base("testkey_v1.x509.pem"), &cert);

  ASSERT_EQ(SHA_DIGEST_LENGTH, cert.hash_len);
  ASSERT_EQ(Certificate::KEY_TYPE_RSA, cert.key_type);
  ASSERT_EQ(nullptr, cert.ec);

  VerifyPackageWithSingleCertificate("otasigned_v1.zip", std::move(cert));
}

TEST(VerifierTest, LoadCertificateFromBuffer_sha1_exponent65537) {
  Certificate cert(0, Certificate::KEY_TYPE_RSA, nullptr, nullptr);
  LoadKeyFromFile(from_testdata_base("testkey_v2.x509.pem"), &cert);

  ASSERT_EQ(SHA_DIGEST_LENGTH, cert.hash_len);
  ASSERT_EQ(Certificate::KEY_TYPE_RSA, cert.key_type);
  ASSERT_EQ(nullptr, cert.ec);

  VerifyPackageWithSingleCertificate("otasigned_v2.zip", std::move(cert));
}

TEST(VerifierTest, LoadCertificateFromBuffer_sha256_exponent3) {
  Certificate cert(0, Certificate::KEY_TYPE_RSA, nullptr, nullptr);
  LoadKeyFromFile(from_testdata_base("testkey_v3.x509.pem"), &cert);

  ASSERT_EQ(SHA256_DIGEST_LENGTH, cert.hash_len);
  ASSERT_EQ(Certificate::KEY_TYPE_RSA, cert.key_type);
  ASSERT_EQ(nullptr, cert.ec);

  VerifyPackageWithSingleCertificate("otasigned_v3.zip", std::move(cert));
}

TEST(VerifierTest, LoadCertificateFromBuffer_sha256_exponent65537) {
  Certificate cert(0, Certificate::KEY_TYPE_RSA, nullptr, nullptr);
  LoadKeyFromFile(from_testdata_base("testkey_v4.x509.pem"), &cert);

  ASSERT_EQ(SHA256_DIGEST_LENGTH, cert.hash_len);
  ASSERT_EQ(Certificate::KEY_TYPE_RSA, cert.key_type);
  ASSERT_EQ(nullptr, cert.ec);

  VerifyPackageWithSingleCertificate("otasigned_v4.zip", std::move(cert));
}

TEST(VerifierTest, LoadCertificateFromBuffer_sha256_ec256bits) {
  Certificate cert(0, Certificate::KEY_TYPE_RSA, nullptr, nullptr);
  LoadKeyFromFile(from_testdata_base("testkey_v5.x509.pem"), &cert);

  ASSERT_EQ(SHA256_DIGEST_LENGTH, cert.hash_len);
  ASSERT_EQ(Certificate::KEY_TYPE_EC, cert.key_type);
  ASSERT_EQ(nullptr, cert.rsa);

  VerifyPackageWithSingleCertificate("otasigned_v5.zip", std::move(cert));
}

TEST(VerifierTest, LoadCertificateFromBuffer_sha256_rsa4096_bits) {
  Certificate cert(0, Certificate::KEY_TYPE_RSA, nullptr, nullptr);
  LoadKeyFromFile(from_testdata_base("testkey_4096bits.x509.pem"), &cert);

  ASSERT_EQ(SHA256_DIGEST_LENGTH, cert.hash_len);
  ASSERT_EQ(Certificate::KEY_TYPE_RSA, cert.key_type);
  ASSERT_EQ(nullptr, cert.ec);

  VerifyPackageWithSingleCertificate("otasigned_4096bits.zip", std::move(cert));
}

TEST(VerifierTest, LoadCertificateFromBuffer_check_rsa_keys) {
  std::unique_ptr<RSA, RSADeleter> rsa(RSA_new());
  std::unique_ptr<BIGNUM, decltype(&BN_free)> exponent(BN_new(), BN_free);
  BN_set_word(exponent.get(), 3);
  RSA_generate_key_ex(rsa.get(), 2048, exponent.get(), nullptr);
  ASSERT_TRUE(CheckRSAKey(rsa));

  // Exponent is expected to be 3 or 65537
  BN_set_word(exponent.get(), 17);
  RSA_generate_key_ex(rsa.get(), 2048, exponent.get(), nullptr);
  ASSERT_FALSE(CheckRSAKey(rsa));

  // Modulus is expected to be 2048.
  BN_set_word(exponent.get(), 3);
  RSA_generate_key_ex(rsa.get(), 1024, exponent.get(), nullptr);
  ASSERT_FALSE(CheckRSAKey(rsa));
}

TEST(VerifierTest, LoadCertificateFromBuffer_check_ec_keys) {
  std::unique_ptr<EC_KEY, ECKEYDeleter> ec(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
  ASSERT_EQ(1, EC_KEY_generate_key(ec.get()));
  ASSERT_TRUE(CheckECKey(ec));

  // Expects 256-bit EC key with curve NIST P-256
  ec.reset(EC_KEY_new_by_curve_name(NID_secp224r1));
  ASSERT_EQ(1, EC_KEY_generate_key(ec.get()));
  ASSERT_FALSE(CheckECKey(ec));
}

TEST(VerifierTest, LoadKeysFromZipfile_empty_archive) {
  TemporaryFile otacerts;
  BuildCertificateArchive({}, otacerts.release());
  std::vector<Certificate> certs = LoadKeysFromZipfile(otacerts.path);
  ASSERT_TRUE(certs.empty());
}

TEST(VerifierTest, LoadKeysFromZipfile_single_key) {
  TemporaryFile otacerts;
  BuildCertificateArchive({ from_testdata_base("testkey_v1.x509.pem") }, otacerts.release());
  std::vector<Certificate> certs = LoadKeysFromZipfile(otacerts.path);
  ASSERT_EQ(1, certs.size());

  VerifyPackageWithCertificates("otasigned_v1.zip", certs);
}

TEST(VerifierTest, LoadKeysFromZipfile_corrupted_key) {
  TemporaryFile corrupted_key;
  std::string content;
  ASSERT_TRUE(android::base::ReadFileToString(from_testdata_base("testkey_v1.x509.pem"), &content));
  content = "random-contents" + content;
  ASSERT_TRUE(android::base::WriteStringToFd(content, corrupted_key.release()));

  TemporaryFile otacerts;
  BuildCertificateArchive({ from_testdata_base("testkey_v2.x509.pem"), corrupted_key.path },
                          otacerts.release());
  std::vector<Certificate> certs = LoadKeysFromZipfile(otacerts.path);
  ASSERT_EQ(0, certs.size());
}

TEST(VerifierTest, LoadKeysFromZipfile_multiple_key) {
  TemporaryFile otacerts;
  BuildCertificateArchive(
      {
          from_testdata_base("testkey_v3.x509.pem"),
          from_testdata_base("testkey_v4.x509.pem"),
          from_testdata_base("testkey_v5.x509.pem"),

      },
      otacerts.release());
  std::vector<Certificate> certs = LoadKeysFromZipfile(otacerts.path);
  ASSERT_EQ(3, certs.size());

  VerifyPackageWithCertificates("otasigned_v3.zip", certs);
  VerifyPackageWithCertificates("otasigned_v4.zip", certs);
  VerifyPackageWithCertificates("otasigned_v5.zip", certs);
}

class VerifierTest : public testing::TestWithParam<std::vector<std::string>> {
 protected:
  void SetUp() override {
    std::vector<std::string> args = GetParam();
    std::string path = from_testdata_base(args[0]);
    memory_package_ = Package::CreateMemoryPackage(path, nullptr);
    ASSERT_NE(nullptr, memory_package_);
    file_package_ = Package::CreateFilePackage(path, nullptr);
    ASSERT_NE(nullptr, file_package_);

    for (auto it = ++args.cbegin(); it != args.cend(); ++it) {
      std::string public_key_file = from_testdata_base("testkey_" + *it + ".x509.pem");
      certs_.emplace_back(0, Certificate::KEY_TYPE_RSA, nullptr, nullptr);
      LoadKeyFromFile(public_key_file, &certs_.back());
    }
  }

  std::unique_ptr<Package> memory_package_;
  std::unique_ptr<Package> file_package_;
  std::vector<Certificate> certs_;
};

class VerifierSuccessTest : public VerifierTest {
};

class VerifierFailureTest : public VerifierTest {
};

TEST(VerifierTest, BadPackage_AlteredFooter) {
  std::vector<Certificate> certs;
  certs.emplace_back(0, Certificate::KEY_TYPE_RSA, nullptr, nullptr);
  LoadKeyFromFile(from_testdata_base("testkey_v3.x509.pem"), &certs.back());

  std::string package;
  ASSERT_TRUE(android::base::ReadFileToString(from_testdata_base("otasigned_v3.zip"), &package));
  ASSERT_EQ(std::string("\xc0\x06\xff\xff\xd2\x06", 6), package.substr(package.size() - 6, 6));

  // Alter the footer.
  package[package.size() - 5] = '\x05';
  VerifyFile(package, certs, VERIFY_FAILURE);
}

TEST(VerifierTest, BadPackage_AlteredContent) {
  std::vector<Certificate> certs;
  certs.emplace_back(0, Certificate::KEY_TYPE_RSA, nullptr, nullptr);
  LoadKeyFromFile(from_testdata_base("testkey_v3.x509.pem"), &certs.back());

  std::string package;
  ASSERT_TRUE(android::base::ReadFileToString(from_testdata_base("otasigned_v3.zip"), &package));
  ASSERT_GT(package.size(), static_cast<size_t>(100));

  // Alter the content.
  std::string altered1(package);
  altered1[50] += 1;
  VerifyFile(altered1, certs, VERIFY_FAILURE);

  std::string altered2(package);
  altered2[10] += 1;
  VerifyFile(altered2, certs, VERIFY_FAILURE);
}

TEST(VerifierTest, BadPackage_SignatureStartOutOfBounds) {
  std::vector<Certificate> certs;
  certs.emplace_back(0, Certificate::KEY_TYPE_RSA, nullptr, nullptr);
  LoadKeyFromFile(from_testdata_base("testkey_v3.x509.pem"), &certs.back());

  // Signature start is 65535 (0xffff) while comment size is 0 (Bug: 31914369).
  std::string package = "\x50\x4b\x05\x06"s + std::string(12, '\0') + "\xff\xff\xff\xff\x00\x00"s;
  VerifyFile(package, certs, VERIFY_FAILURE);
}

TEST_P(VerifierSuccessTest, VerifySucceed) {
  ASSERT_EQ(VERIFY_SUCCESS, verify_file(memory_package_.get(), certs_));
  ASSERT_EQ(VERIFY_SUCCESS, verify_file(file_package_.get(), certs_));
}

TEST_P(VerifierFailureTest, VerifyFailure) {
  ASSERT_EQ(VERIFY_FAILURE, verify_file(memory_package_.get(), certs_));
  ASSERT_EQ(VERIFY_FAILURE, verify_file(file_package_.get(), certs_));
}

INSTANTIATE_TEST_CASE_P(SingleKeySuccess, VerifierSuccessTest,
    ::testing::Values(
      std::vector<std::string>({"otasigned_v1.zip", "v1"}),
      std::vector<std::string>({"otasigned_v2.zip", "v2"}),
      std::vector<std::string>({"otasigned_v3.zip", "v3"}),
      std::vector<std::string>({"otasigned_v4.zip", "v4"}),
      std::vector<std::string>({"otasigned_v5.zip", "v5"})));

INSTANTIATE_TEST_CASE_P(MultiKeySuccess, VerifierSuccessTest,
    ::testing::Values(
      std::vector<std::string>({"otasigned_v1.zip", "v1", "v2"}),
      std::vector<std::string>({"otasigned_v2.zip", "v5", "v2"}),
      std::vector<std::string>({"otasigned_v3.zip", "v5", "v1", "v3"}),
      std::vector<std::string>({"otasigned_v4.zip", "v5", "v1", "v4"}),
      std::vector<std::string>({"otasigned_v5.zip", "v4", "v1", "v5"})));

INSTANTIATE_TEST_CASE_P(WrongKey, VerifierFailureTest,
    ::testing::Values(
      std::vector<std::string>({"otasigned_v1.zip", "v2"}),
      std::vector<std::string>({"otasigned_v2.zip", "v1"}),
      std::vector<std::string>({"otasigned_v3.zip", "v5"}),
      std::vector<std::string>({"otasigned_v4.zip", "v5"}),
      std::vector<std::string>({"otasigned_v5.zip", "v3"})));

INSTANTIATE_TEST_CASE_P(WrongHash, VerifierFailureTest,
    ::testing::Values(
      std::vector<std::string>({"otasigned_v1.zip", "v3"}),
      std::vector<std::string>({"otasigned_v2.zip", "v4"}),
      std::vector<std::string>({"otasigned_v3.zip", "v1"}),
      std::vector<std::string>({"otasigned_v4.zip", "v2"})));

INSTANTIATE_TEST_CASE_P(BadPackage, VerifierFailureTest,
    ::testing::Values(
      std::vector<std::string>({"random.zip", "v1"}),
      std::vector<std::string>({"fake-eocd.zip", "v1"})));
