// 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 #include "base/at_exit.h" #include "base/callback_helpers.h" #include "base/command_line.h" #include "base/logging.h" #include "base/task_scheduler/task_scheduler.h" #include "base/time/time.h" #include "net/cert/cert_verify_proc.h" #include "net/cert/cert_verify_proc_builtin.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" namespace { // 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& intermediate_der_certs, const std::vector& root_der_certs, base::Time verify_time, 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 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& intermediate_der_certs, const std::vector& root_der_certs, base::Time verify_time, 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. } return VerifyUsingCertVerifyProc(proc_.get(), target_der_cert, hostname, intermediate_der_certs, root_der_certs, dump_prefix_path); } private: const std::string name_; scoped_refptr 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& intermediate_der_certs, const std::vector& root_der_certs, base::Time verify_time, 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); } }; const char kUsage[] = " [flags] \n" "\n" " 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=\n" " The hostname required to match the end-entity certificate.\n" " Required for the CertVerifyProc implementation.\n" "\n" " --roots=\n" " is a file containing certificates [1] to interpret as\n" " trust anchors (without any anchor constraints).\n" "\n" " --intermediates=\n" " is a file containing certificates [1] for use when\n" " path building is looking for intermediates.\n" "\n" " --time=