// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef BSSL_PKI_TEST_HELPERS_H_
#define BSSL_PKI_TEST_HELPERS_H_

#include <stddef.h>

#include <ostream>
#include <string>
#include <string_view>
#include <vector>

#include <gtest/gtest.h>
#include "input.h"
#include "parsed_certificate.h"
#include "simple_path_builder_delegate.h"
#include "trust_store.h"
#include "verify_certificate_chain.h"

namespace bssl {

namespace der {

// This function is used by GTest to support EXPECT_EQ() for der::Input.
void PrintTo(Input data, ::std::ostream *os);

}  // namespace der

// Parses |s| as a DER SEQUENCE TLV and returns a der::Input corresponding to
// the value portion. On error returns an empty der::Input and adds a gtest
// failure.
//
// The returned der::Input() is only valid so long as the input string is alive
// and is not mutated.
der::Input SequenceValueFromString(std::string_view s);

// Helper structure that maps a PEM block header (for instance "CERTIFICATE") to
// the destination where the value for that block should be written.
struct PemBlockMapping {
  // The name of the PEM header. Example "CERTIFICATE".
  const char *block_name;

  // The destination where the read value should be written to.
  std::string *value;

  // True to indicate that the block is not required to be present. If the
  // block is optional and is not present, then |value| will not be modified.
  bool optional = false;
};

// ReadTestDataFromPemFile() is a helper function that reads a PEM test file
// rooted in the "src/" directory.
//
//   * file_path_ascii:
//       The path to the PEM file, relative to src. For instance
//       "testdata/verify_signed_data_unittest/foopy.pem"
//
//   * mappings:
//       An array of length |mappings_length| which maps the expected PEM
//       headers to the destination to write its data.
//
// The function ensures that each of the chosen mappings is satisfied exactly
// once. In other words, the header must be present (unless marked as
// optional=true), have valid data, and appear no more than once.
::testing::AssertionResult ReadTestDataFromPemFile(
    const std::string &file_path_ascii, const PemBlockMapping *mappings,
    size_t mappings_length);

// This is the same as the variant above, however it uses template magic so an
// mappings array can be passed in directly (and the correct length is
// inferred).
template <size_t N>
::testing::AssertionResult ReadTestDataFromPemFile(
    const std::string &file_path_ascii, const PemBlockMapping (&mappings)[N]) {
  return ReadTestDataFromPemFile(file_path_ascii, mappings, N);
}

// Test cases are comprised of all the parameters to certificate
// verification, as well as the expected outputs.
struct VerifyCertChainTest {
  VerifyCertChainTest();
  ~VerifyCertChainTest();

  // The chain of certificates (with the zero-th being the target).
  ParsedCertificateList chain;

  // Details on the trustedness of the last certificate.
  CertificateTrust last_cert_trust;

  // The time to use when verifying the chain.
  der::GeneralizedTime time;

  // The Key Purpose to use when verifying the chain.
  KeyPurpose key_purpose = KeyPurpose::ANY_EKU;

  InitialExplicitPolicy initial_explicit_policy = InitialExplicitPolicy::kFalse;

  std::set<der::Input> user_initial_policy_set;

  InitialPolicyMappingInhibit initial_policy_mapping_inhibit =
      InitialPolicyMappingInhibit::kFalse;

  InitialAnyPolicyInhibit initial_any_policy_inhibit =
      InitialAnyPolicyInhibit::kFalse;

  // The expected errors/warnings from verification (as a string).
  std::string expected_errors;

  // Expected user_constrained_policy_set, as a set of numeric OID strings.
  std::set<std::string> expected_user_constrained_policy_set;

  SimplePathBuilderDelegate::DigestPolicy digest_policy =
      SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1;

  // Returns true if |expected_errors| contains any high severity errors (a
  // non-empty expected_errors doesn't necessarily mean verification is
  // expected to fail, as it may have contained warnings).
  bool HasHighSeverityErrors() const;
};

// Reads a test case from |file_path_ascii| (which is relative to //src).
// Generally |file_path_ascii| will start with:
//   net/data/verify_certificate_chain_unittest/
bool ReadVerifyCertChainTestFromFile(const std::string &file_path_ascii,
                                     VerifyCertChainTest *test);

// Reads a certificate chain from |file_path_ascii|
bool ReadCertChainFromFile(const std::string &file_path_ascii,
                           ParsedCertificateList *chain);

// Reads a certificate from |file_path_ascii|. Returns nullptr if the file
// contained more that one certificate.
std::shared_ptr<const ParsedCertificate> ReadCertFromFile(
    const std::string &file_path_ascii);

// Reads a data file relative to the src root directory.
std::string ReadTestFileToString(const std::string &file_path_ascii);

// Asserts that |actual_errors| matches |expected_errors_str|.
//
// This is a helper function to simplify rebasing the error expectations when
// they originate from a test file.
void VerifyCertPathErrors(const std::string &expected_errors_str,
                          const CertPathErrors &actual_errors,
                          const ParsedCertificateList &chain,
                          const std::string &errors_file_path);

// Asserts that |actual_errors| matches |expected_errors_str|.
//
// This is a helper function to simplify rebasing the error expectations when
// they originate from a test file.
void VerifyCertErrors(const std::string &expected_errors_str,
                      const CertErrors &actual_errors,
                      const std::string &errors_file_path);

// Asserts that |actual_user_constrained_policy_set| matches
// |expected_user_constrained_policy_set|.
void VerifyUserConstrainedPolicySet(
    const std::set<std::string> &expected_user_constrained_policy_str_set,
    const std::set<der::Input> &actual_user_constrained_policy_set,
    const std::string &errors_file_path);

}  // namespace bssl

#endif  // BSSL_PKI_TEST_HELPERS_H_
