// Copyright 2016 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 <iostream>

#include "base/at_exit.h"
#include "base/callback_helpers.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string_split.h"
#include "base/synchronization/waitable_event.h"
#include "base/task/task_scheduler/task_scheduler.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "net/cert/cert_net_fetcher.h"
#include "net/cert/cert_verify_proc.h"
#include "net/cert/cert_verify_proc_builtin.h"
#include "net/cert/crl_set.h"
#include "net/cert_net/cert_net_fetcher_impl.h"
#include "net/tools/cert_verify_tool/cert_verify_tool_util.h"
#include "net/tools/cert_verify_tool/verify_using_cert_verify_proc.h"
#include "net/tools/cert_verify_tool/verify_using_path_builder.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_builder.h"
#include "net/url_request/url_request_context_getter.h"

#if defined(OS_LINUX)
#include "net/proxy_resolution/proxy_config.h"
#include "net/proxy_resolution/proxy_config_service_fixed.h"
#endif

#if defined(USE_NSS_CERTS)
#include "net/cert_net/nss_ocsp.h"
#endif

namespace {

std::string GetUserAgent() {
  return "cert_verify_tool/0.1";
}

void SetUpOnNetworkThread(std::unique_ptr<net::URLRequestContext>* context,
                          base::WaitableEvent* initialization_complete_event) {
  net::URLRequestContextBuilder url_request_context_builder;
  url_request_context_builder.set_user_agent(GetUserAgent());
#if defined(OS_LINUX)
  // On Linux, use a fixed ProxyConfigService, since the default one
  // depends on glib.
  //
  // TODO(akalin): Remove this once http://crbug.com/146421 is fixed.
  url_request_context_builder.set_proxy_config_service(
      std::make_unique<net::ProxyConfigServiceFixed>(
          net::ProxyConfigWithAnnotation()));
#endif
  *context = url_request_context_builder.Build();

#if defined(USE_NSS_CERTS)
  net::SetURLRequestContextForNSSHttpIO(context->get());
#endif
  net::SetGlobalCertNetFetcher(net::CreateCertNetFetcher(context->get()));
  initialization_complete_event->Signal();
}

void ShutdownOnNetworkThread(std::unique_ptr<net::URLRequestContext>* context) {
  net::ShutdownGlobalCertNetFetcher();
  context->reset();
}

// Base class to abstract running a particular implementation of certificate
// verification.
class CertVerifyImpl {
 public:
  virtual ~CertVerifyImpl() = default;

  virtual std::string GetName() const = 0;

  // Does certificate verification.
  //
  // Note that |hostname| may be empty to indicate that no name validation is
  // requested, and a null value of |verify_time| means to use the current time.
  virtual bool VerifyCert(const CertInput& target_der_cert,
                          const std::string& hostname,
                          const std::vector<CertInput>& intermediate_der_certs,
                          const std::vector<CertInput>& root_der_certs,
                          base::Time verify_time,
                          net::CRLSet* crl_set,
                          const base::FilePath& dump_prefix_path) = 0;
};

// Runs certificate verification using a particular CertVerifyProc.
class CertVerifyImplUsingProc : public CertVerifyImpl {
 public:
  CertVerifyImplUsingProc(const std::string& name,
                          scoped_refptr<net::CertVerifyProc> proc)
      : name_(name), proc_(std::move(proc)) {}

  std::string GetName() const override { return name_; }

  bool VerifyCert(const CertInput& target_der_cert,
                  const std::string& hostname,
                  const std::vector<CertInput>& intermediate_der_certs,
                  const std::vector<CertInput>& root_der_certs,
                  base::Time verify_time,
                  net::CRLSet* crl_set,
                  const base::FilePath& dump_prefix_path) override {
    if (!verify_time.is_null()) {
      std::cerr << "WARNING: --time is not supported by " << GetName()
                << ", will use current time.\n";
    }

    if (hostname.empty()) {
      std::cerr << "ERROR: --hostname is required for " << GetName()
                << ", skipping\n";
      return true;  // "skipping" is considered a successful return.
    }

    base::FilePath dump_path;
    if (!dump_prefix_path.empty()) {
      dump_path = dump_prefix_path.AddExtension(FILE_PATH_LITERAL(".pem"))
                      .InsertBeforeExtensionASCII("." + GetName());
    }

    return VerifyUsingCertVerifyProc(proc_.get(), target_der_cert, hostname,
                                     intermediate_der_certs, root_der_certs,
                                     crl_set, dump_path);
  }

 private:
  const std::string name_;
  scoped_refptr<net::CertVerifyProc> proc_;
};

// Runs certificate verification using CertPathBuilder.
class CertVerifyImplUsingPathBuilder : public CertVerifyImpl {
 public:
  std::string GetName() const override { return "CertPathBuilder"; }

  bool VerifyCert(const CertInput& target_der_cert,
                  const std::string& hostname,
                  const std::vector<CertInput>& intermediate_der_certs,
                  const std::vector<CertInput>& root_der_certs,
                  base::Time verify_time,
                  net::CRLSet* crl_set,
                  const base::FilePath& dump_prefix_path) override {
    if (!hostname.empty()) {
      std::cerr << "WARNING: --hostname is not verified with CertPathBuilder\n";
    }

    if (verify_time.is_null()) {
      verify_time = base::Time::Now();
    }

    return VerifyUsingPathBuilder(target_der_cert, intermediate_der_certs,
                                  root_der_certs, verify_time,
                                  dump_prefix_path);
  }
};

// Creates an subclass of CertVerifyImpl based on its name, or returns nullptr.
std::unique_ptr<CertVerifyImpl> CreateCertVerifyImplFromName(
    base::StringPiece impl_name) {
  if (impl_name == "platform")
    return std::make_unique<CertVerifyImplUsingProc>(
        "CertVerifyProc (default)", net::CertVerifyProc::CreateDefault());

  if (impl_name == "builtin") {
    return std::make_unique<CertVerifyImplUsingProc>(
        "CertVerifyProcBuiltin", net::CreateCertVerifyProcBuiltin());
  }

  if (impl_name == "pathbuilder")
    return std::make_unique<CertVerifyImplUsingPathBuilder>();

  std::cerr << "WARNING: Unrecognized impl: " << impl_name << "\n";
  return nullptr;
}

const char kUsage[] =
    " [flags] <target/chain>\n"
    "\n"
    " <target/chain> is a file containing certificates [1]. Minimally it\n"
    " contains the target certificate. Optionally it may subsequently list\n"
    " additional certificates needed to build a chain (this is equivalent to\n"
    " specifying them through --intermediates)\n"
    "\n"
    "Flags:\n"
    "\n"
    " --hostname=<hostname>\n"
    "      The hostname required to match the end-entity certificate.\n"
    "      Required for the CertVerifyProc implementation.\n"
    "\n"
    " --roots=<certs path>\n"
    "      <certs path> is a file containing certificates [1] to interpret as\n"
    "      trust anchors (without any anchor constraints).\n"
    "\n"
    " --intermediates=<certs path>\n"
    "      <certs path> is a file containing certificates [1] for use when\n"
    "      path building is looking for intermediates.\n"
    "\n"
    " --impls=<ordered list of implementations>\n"
    "      Ordered list of the verifier implementations to run. If omitted,\n"
    "      will default to: \"platform,builtin,pathbuilder\".\n"
    "      Changing this can lead to different results in cases where the\n"
    "      platform verifier affects global caches (as in the case of NSS).\n"
    "\n"
    " --trust-last-cert\n"
    "      Removes the final intermediate from the chain and instead adds it\n"
    "      as a root. This is useful when providing a <target/chain>\n"
    "      parameter whose final certificate is a trust anchor.\n"
    "\n"
    " --time=<time>\n"
    "      Use <time> instead of the current system time. <time> is\n"
    "      interpreted in local time if a timezone is not specified.\n"
    "      Many common formats are supported, including:\n"
    "        1994-11-15 12:45:26 GMT\n"
    "        Tue, 15 Nov 1994 12:45:26 GMT\n"
    "        Nov 15 12:45:26 1994 GMT\n"
    "\n"
    " --crlset=<crlset path>\n"
    "      <crlset path> is a file containing a serialized CRLSet to use\n"
    "      during revocation checking. For example:\n"
    "        <chrome data dir>/CertificateRevocation/<number>/crl-set\n"
    "\n"
    " --dump=<file prefix>\n"
    "      Dumps the verified chain to PEM files starting with\n"
    "      <file prefix>.\n"
    "\n"
    "\n"
    "[1] A \"file containing certificates\" means a path to a file that can\n"
    "    either be:\n"
    "    * A binary file containing a single DER-encoded RFC 5280 Certificate\n"
    "    * A PEM file containing one or more CERTIFICATE blocks (DER-encoded\n"
    "      RFC 5280 Certificate)\n";

void PrintUsage(const char* argv0) {
  std::cerr << "Usage: " << argv0 << kUsage;

  // TODO(mattm): allow <certs path> to be a directory containing DER/PEM files?
  // TODO(mattm): allow target to specify an HTTPS URL to check the cert of?
  // TODO(mattm): allow target to be a verify_certificate_chain_unittest .test
  // file?
}

}  // namespace

int main(int argc, char** argv) {
  base::AtExitManager at_exit_manager;
  if (!base::CommandLine::Init(argc, argv)) {
    std::cerr << "ERROR in CommandLine::Init\n";
    return 1;
  }
  base::TaskScheduler::CreateAndStartWithDefaultParams("cert_verify_tool");
  base::ScopedClosureRunner cleanup(
      base::BindOnce([] { base::TaskScheduler::GetInstance()->Shutdown(); }));
  base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
  logging::LoggingSettings settings;
  settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
  logging::InitLogging(settings);

  base::CommandLine::StringVector args = command_line.GetArgs();
  if (args.size() != 1U || command_line.HasSwitch("help")) {
    PrintUsage(argv[0]);
    return 1;
  }

  std::string hostname = command_line.GetSwitchValueASCII("hostname");

  base::Time verify_time;
  std::string time_flag = command_line.GetSwitchValueASCII("time");
  if (!time_flag.empty()) {
    if (!base::Time::FromString(time_flag.c_str(), &verify_time)) {
      std::cerr << "Error parsing --time flag\n";
      return 1;
    }
  }

  base::FilePath roots_path = command_line.GetSwitchValuePath("roots");
  base::FilePath intermediates_path =
      command_line.GetSwitchValuePath("intermediates");
  base::FilePath target_path = base::FilePath(args[0]);

  base::FilePath crlset_path = command_line.GetSwitchValuePath("crlset");
  scoped_refptr<net::CRLSet> crl_set;
  if (!crlset_path.empty()) {
    std::string crl_set_bytes;
    if (!ReadFromFile(crlset_path, &crl_set_bytes))
      return 1;
    if (!net::CRLSet::Parse(crl_set_bytes, &crl_set)) {
      std::cerr << "Error parsing CRLSet\n";
      return 1;
    }
  }

  base::FilePath dump_prefix_path = command_line.GetSwitchValuePath("dump");

  std::vector<CertInput> root_der_certs;
  std::vector<CertInput> intermediate_der_certs;
  CertInput target_der_cert;

  if (!roots_path.empty())
    ReadCertificatesFromFile(roots_path, &root_der_certs);
  if (!intermediates_path.empty())
    ReadCertificatesFromFile(intermediates_path, &intermediate_der_certs);

  if (!ReadChainFromFile(target_path, &target_der_cert,
                         &intermediate_der_certs)) {
    std::cerr << "ERROR: Couldn't read certificate chain\n";
    return 1;
  }

  if (target_der_cert.der_cert.empty()) {
    std::cerr << "ERROR: no target cert\n";
    return 1;
  }

  // If --trust-last-cert was specified, move the final intermediate to the
  // roots list.
  if (command_line.HasSwitch("trust-last-cert")) {
    if (intermediate_der_certs.empty()) {
      std::cerr << "ERROR: no intermediate certificates\n";
      return 1;
    }

    root_der_certs.push_back(intermediate_der_certs.back());
    intermediate_der_certs.pop_back();
  }

  // Create a network thread to be used for AIA fetches, and wait for a
  // CertNetFetcher to be constructed on that thread.
  base::Thread::Options options(base::MessageLoop::TYPE_IO, 0);
  base::Thread thread("network_thread");
  CHECK(thread.StartWithOptions(options));
  // Owned by this thread, but initialized, used, and shutdown on the network
  // thread.
  std::unique_ptr<net::URLRequestContext> context;
  base::WaitableEvent initialization_complete_event(
      base::WaitableEvent::ResetPolicy::MANUAL,
      base::WaitableEvent::InitialState::NOT_SIGNALED);
  thread.task_runner()->PostTask(
      FROM_HERE, base::BindOnce(&SetUpOnNetworkThread, &context,
                                &initialization_complete_event));
  initialization_complete_event.Wait();

  std::vector<std::unique_ptr<CertVerifyImpl>> impls;

  // Parse the ordered list of CertVerifyImpl passed via command line flags into
  // |impls|.
  std::string impls_str = command_line.GetSwitchValueASCII("impls");
  if (impls_str.empty())
    impls_str = "platform,builtin,pathbuilder";  // Default value.

  std::vector<std::string> impl_names = base::SplitString(
      impls_str, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);

  for (const std::string& impl_name : impl_names) {
    auto verify_impl = CreateCertVerifyImplFromName(impl_name);
    if (verify_impl)
      impls.push_back(std::move(verify_impl));
  }

  // Sequentially run the chain with each of the selected verifier
  // implementations.
  bool all_impls_success = true;

  for (size_t i = 0; i < impls.size(); ++i) {
    if (i != 0)
      std::cout << "\n";

    std::cout << impls[i]->GetName() << ":\n";
    if (!impls[i]->VerifyCert(target_der_cert, hostname, intermediate_der_certs,
                              root_der_certs, verify_time, crl_set.get(),
                              dump_prefix_path)) {
      all_impls_success = false;
    }
  }

  // Clean up on the network thread and stop it (which waits for the clean up
  // task to run).
  thread.task_runner()->PostTask(
      FROM_HERE, base::BindOnce(&ShutdownOnNetworkThread, &context));
  thread.Stop();

  return all_impls_success ? 0 : 1;
}
