// Copyright 2015 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 "net/cert/internal/test_helpers.h"

#include "base/base64.h"
#include "base/base_paths.h"
#include "base/files/file_util.h"
#include "base/path_service.h"
#include "base/strings/string_split.h"
#include "net/cert/internal/cert_error_params.h"
#include "net/cert/internal/cert_errors.h"
#include "net/cert/pem_tokenizer.h"
#include "net/der/parser.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/boringssl/src/include/openssl/pool.h"

namespace net {

namespace {

bool GetValue(base::StringPiece prefix,
              base::StringPiece line,
              std::string* value,
              bool* has_value) {
  if (!line.starts_with(prefix))
    return false;

  if (*has_value) {
    ADD_FAILURE() << "Duplicated " << prefix;
    return false;
  }

  *has_value = true;
  *value = line.substr(prefix.size()).as_string();
  return true;
}

}  // namespace

namespace der {

void PrintTo(const Input& data, ::std::ostream* os) {
  std::string b64;
  base::Base64Encode(
      base::StringPiece(reinterpret_cast<const char*>(data.UnsafeData()),
                        data.Length()),
      &b64);

  *os << "[" << b64 << "]";
}

}  // namespace der

der::Input SequenceValueFromString(const std::string* s) {
  der::Parser parser((der::Input(s)));
  der::Input data;
  if (!parser.ReadTag(der::kSequence, &data)) {
    ADD_FAILURE();
    return der::Input();
  }
  if (parser.HasMore()) {
    ADD_FAILURE();
    return der::Input();
  }
  return data;
}

::testing::AssertionResult ReadTestDataFromPemFile(
    const std::string& file_path_ascii,
    const PemBlockMapping* mappings,
    size_t mappings_length) {
  // Compute the full path, relative to the src/ directory.
  base::FilePath src_root;
  base::PathService::Get(base::DIR_TEST_DATA, &src_root);
  base::FilePath filepath = src_root.AppendASCII(file_path_ascii);

  // Read the full contents of the PEM file.
  std::string file_data;
  if (!base::ReadFileToString(filepath, &file_data)) {
    return ::testing::AssertionFailure()
           << "Couldn't read file: " << filepath.value();
  }

  // mappings_copy is used to keep track of which mappings have already been
  // satisfied (by nulling the |value| field). This is used to track when
  // blocks are mulitply defined.
  std::vector<PemBlockMapping> mappings_copy(mappings,
                                             mappings + mappings_length);

  // Build the |pem_headers| vector needed for PEMTokenzier.
  std::vector<std::string> pem_headers;
  for (const auto& mapping : mappings_copy) {
    pem_headers.push_back(mapping.block_name);
  }

  PEMTokenizer pem_tokenizer(file_data, pem_headers);
  while (pem_tokenizer.GetNext()) {
    for (auto& mapping : mappings_copy) {
      // Find the mapping for this block type.
      if (pem_tokenizer.block_type() == mapping.block_name) {
        if (!mapping.value) {
          return ::testing::AssertionFailure()
                 << "PEM block defined multiple times: " << mapping.block_name;
        }

        // Copy the data to the result.
        mapping.value->assign(pem_tokenizer.data());

        // Mark the mapping as having been satisfied.
        mapping.value = nullptr;
      }
    }
  }

  // Ensure that all specified blocks were found.
  for (const auto& mapping : mappings_copy) {
    if (mapping.value && !mapping.optional) {
      return ::testing::AssertionFailure()
             << "PEM block missing: " << mapping.block_name;
    }
  }

  return ::testing::AssertionSuccess();
}

VerifyCertChainTest::VerifyCertChainTest()
    : user_initial_policy_set{AnyPolicy()} {}
VerifyCertChainTest::~VerifyCertChainTest() = default;

bool VerifyCertChainTest::HasHighSeverityErrors() const {
  // This function assumes that high severity warnings are prefixed with
  // "ERROR: " and warnings are prefixed with "WARNING: ". This is an
  // implementation detail of CertError::ToDebugString).
  //
  // Do a quick sanity-check to confirm this.
  CertError error(CertError::SEVERITY_HIGH, "unused", nullptr);
  EXPECT_EQ("ERROR: unused\n", error.ToDebugString());
  CertError warning(CertError::SEVERITY_WARNING, "unused", nullptr);
  EXPECT_EQ("WARNING: unused\n", warning.ToDebugString());

  // Do a simple substring test (not perfect, but good enough for our test
  // corpus).
  return expected_errors.find("ERROR: ") != std::string::npos;
}

bool ReadCertChainFromFile(const std::string& file_path_ascii,
                           ParsedCertificateList* chain) {
  // Reset all the out parameters to their defaults.
  *chain = ParsedCertificateList();

  std::string file_data = ReadTestFileToString(file_path_ascii);
  if (file_data.empty())
    return false;

  std::vector<std::string> pem_headers = {"CERTIFICATE"};

  PEMTokenizer pem_tokenizer(file_data, pem_headers);
  while (pem_tokenizer.GetNext()) {
    const std::string& block_data = pem_tokenizer.data();

    CertErrors errors;
    if (!ParsedCertificate::CreateAndAddToVector(
            bssl::UniquePtr<CRYPTO_BUFFER>(CRYPTO_BUFFER_new(
                reinterpret_cast<const uint8_t*>(block_data.data()),
                block_data.size(), nullptr)),
            {}, chain, &errors)) {
      ADD_FAILURE() << errors.ToDebugString();
      return false;
    }
  }

  return true;
}

bool ReadVerifyCertChainTestFromFile(const std::string& file_path_ascii,
                                     VerifyCertChainTest* test) {
  // Reset all the out parameters to their defaults.
  *test = {};

  std::string file_data = ReadTestFileToString(file_path_ascii);
  if (file_data.empty())
    return false;

  std::vector<std::string> lines = base::SplitString(
      file_data, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);

  bool has_chain = false;
  bool has_trust = false;
  bool has_time = false;
  bool has_errors = false;
  bool has_key_purpose = false;

  base::StringPiece kExpectedErrors = "expected_errors:";

  for (const std::string& line : lines) {
    base::StringPiece line_piece(line);

    std::string value;

    // For details on the file format refer to:
    // net/data/verify_certificate_chain_unittest/README.
    if (GetValue("chain: ", line_piece, &value, &has_chain)) {
      // Interpret the |chain| path as being relative to the .test file.
      size_t slash = file_path_ascii.rfind('/');
      if (slash == std::string::npos) {
        ADD_FAILURE() << "Bad path - expecting slashes";
        return false;
      }
      std::string chain_path = file_path_ascii.substr(0, slash) + "/" + value;

      ReadCertChainFromFile(chain_path, &test->chain);
    } else if (GetValue("utc_time: ", line_piece, &value, &has_time)) {
      if (value == "DEFAULT") {
        value = "180510120000Z";
      }
      if (!der::ParseUTCTime(der::Input(&value), &test->time)) {
        ADD_FAILURE() << "Failed parsing UTC time";
        return false;
      }
    } else if (GetValue("key_purpose: ", line_piece, &value,
                        &has_key_purpose)) {
      if (value == "ANY_EKU") {
        test->key_purpose = KeyPurpose::ANY_EKU;
      } else if (value == "SERVER_AUTH") {
        test->key_purpose = KeyPurpose::SERVER_AUTH;
      } else if (value == "CLIENT_AUTH") {
        test->key_purpose = KeyPurpose::CLIENT_AUTH;
      } else {
        ADD_FAILURE() << "Unrecognized key_purpose: " << value;
        return false;
      }
    } else if (GetValue("last_cert_trust: ", line_piece, &value, &has_trust)) {
      if (value == "TRUSTED_ANCHOR") {
        test->last_cert_trust = CertificateTrust::ForTrustAnchor();
      } else if (value == "TRUSTED_ANCHOR_WITH_CONSTRAINTS") {
        test->last_cert_trust =
            CertificateTrust::ForTrustAnchorEnforcingConstraints();
      } else if (value == "DISTRUSTED") {
        test->last_cert_trust = CertificateTrust::ForDistrusted();
      } else if (value == "UNSPECIFIED") {
        test->last_cert_trust = CertificateTrust::ForUnspecified();
      } else {
        ADD_FAILURE() << "Unrecognized last_cert_trust: " << value;
        return false;
      }
    } else if (line_piece.starts_with("#")) {
      // Skip comments.
      continue;
    } else if (line_piece == kExpectedErrors) {
      has_errors = true;
      // The errors start on the next line, and extend until the end of the
      // file.
      std::string prefix =
          std::string("\n") + kExpectedErrors.as_string() + std::string("\n");
      size_t errors_start = file_data.find(prefix);
      if (errors_start == std::string::npos) {
        ADD_FAILURE() << "expected_errors not found";
        return false;
      }
      test->expected_errors = file_data.substr(errors_start + prefix.size());
      break;
    } else {
      ADD_FAILURE() << "Unknown line: " << line_piece;
      return false;
    }
  }

  if (!has_chain) {
    ADD_FAILURE() << "Missing chain: ";
    return false;
  }

  if (!has_trust) {
    ADD_FAILURE() << "Missing last_cert_trust: ";
    return false;
  }

  if (!has_time) {
    ADD_FAILURE() << "Missing time: ";
    return false;
  }

  if (!has_key_purpose) {
    ADD_FAILURE() << "Missing key_purpose: ";
    return false;
  }

  if (!has_errors) {
    ADD_FAILURE() << "Missing errors:";
    return false;
  }

  return true;
}

std::string ReadTestFileToString(const std::string& file_path_ascii) {
  // Compute the full path, relative to the src/ directory.
  base::FilePath src_root;
  base::PathService::Get(base::DIR_TEST_DATA, &src_root);
  base::FilePath filepath = src_root.AppendASCII(file_path_ascii);

  // Read the full contents of the file.
  std::string file_data;
  if (!base::ReadFileToString(filepath, &file_data)) {
    ADD_FAILURE() << "Couldn't read file: " << filepath.value();
    return std::string();
  }

  return file_data;
}

void VerifyCertPathErrors(const std::string& expected_errors_str,
                          const CertPathErrors& actual_errors,
                          const ParsedCertificateList& chain,
                          const std::string& errors_file_path) {
  std::string actual_errors_str = actual_errors.ToDebugString(chain);

  if (expected_errors_str != actual_errors_str) {
    ADD_FAILURE() << "Cert path errors don't match expectations ("
                  << errors_file_path << ")\n\n"
                  << "EXPECTED:\n\n"
                  << expected_errors_str << "\n"
                  << "ACTUAL:\n\n"
                  << actual_errors_str << "\n"
                  << "===> Use "
                     "net/data/verify_certificate_chain_unittest/"
                     "rebase-errors.py to rebaseline.\n";
  }
}

void VerifyCertErrors(const std::string& expected_errors_str,
                      const CertErrors& actual_errors,
                      const std::string& errors_file_path) {
  std::string actual_errors_str = actual_errors.ToDebugString();

  if (expected_errors_str != actual_errors_str) {
    ADD_FAILURE() << "Cert errors don't match expectations ("
                  << errors_file_path << ")\n\n"
                  << "EXPECTED:\n\n"
                  << expected_errors_str << "\n"
                  << "ACTUAL:\n\n"
                  << actual_errors_str << "\n"
                  << "===> Use "
                     "net/data/parse_certificate_unittest/"
                     "rebase-errors.py to rebaseline.\n";
  }
}

}  // namespace net
