// 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.

#ifndef NET_CERT_INTERNAL_PARSED_CERTIFICATE_H_
#define NET_CERT_INTERNAL_PARSED_CERTIFICATE_H_

#include <map>
#include <memory>
#include <vector>

#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "net/base/net_export.h"
#include "net/cert/internal/certificate_policies.h"
#include "net/cert/internal/parse_certificate.h"
#include "net/der/input.h"
#include "third_party/boringssl/src/include/openssl/base.h"

namespace net {

struct GeneralNames;
class NameConstraints;
class ParsedCertificate;
class SignatureAlgorithm;
class CertErrors;

using ParsedCertificateList = std::vector<scoped_refptr<ParsedCertificate>>;

// Represents an X.509 certificate, including Certificate, TBSCertificate, and
// standard extensions.
// Creating a ParsedCertificate does not completely parse and validate the
// certificate data. Presence of a member in this class implies the DER was
// parsed successfully to that level, but does not imply the contents of that
// member are valid, unless otherwise specified. See the documentation for each
// member or the documentation of the type it returns.
class NET_EXPORT ParsedCertificate
    : public base::RefCountedThreadSafe<ParsedCertificate> {
 public:
  // Map from OID to ParsedExtension.
  using ExtensionsMap = std::map<der::Input, ParsedExtension>;

  // Creates a ParsedCertificate given a DER-encoded Certificate. Returns
  // nullptr on failure. Failure will occur if the standard certificate fields
  // and supported extensions cannot be parsed.
  // On either success or failure, if |errors| is non-null it may have error
  // information added to it.
  static scoped_refptr<ParsedCertificate> Create(
      bssl::UniquePtr<CRYPTO_BUFFER> cert_data,
      const ParseCertificateOptions& options,
      CertErrors* errors);

  // Creates a ParsedCertificate by copying the provided |data|, and appends it
  // to |chain|. Returns true if the certificate was successfully parsed and
  // added. If false is return, |chain| is unmodified.
  //
  // On either success or failure, if |errors| is non-null it may have error
  // information added to it.
  static bool CreateAndAddToVector(
      bssl::UniquePtr<CRYPTO_BUFFER> cert_data,
      const ParseCertificateOptions& options,
      std::vector<scoped_refptr<net::ParsedCertificate>>* chain,
      CertErrors* errors);

  // Like Create() this builds a ParsedCertificate given a DER-encoded
  // Certificate and returns nullptr on failure.
  //
  // However a copy of |data| is NOT made.
  //
  // This is a dangerous way to create as ParsedCertificate and should only be
  // used with care when saving a copy is really worth it, or the data is known
  // to come from static storage (and hence remain valid for entire life of
  // process).
  //
  // ParsedCertificate is reference counted, so it is easy to extend the life
  // and and end up with a ParsedCertificate referencing feed memory.
  //
  // On either success or failure, if |errors| is non-null it may have error
  // information added to it.
  static scoped_refptr<ParsedCertificate> CreateWithoutCopyingUnsafe(
      const uint8_t* data,
      size_t length,
      const ParseCertificateOptions& options,
      CertErrors* errors);

  // Returns the DER-encoded certificate data for this cert.
  const der::Input& der_cert() const { return cert_; }

  // Accessors for raw fields of the Certificate.
  const der::Input& tbs_certificate_tlv() const { return tbs_certificate_tlv_; }

  const der::Input& signature_algorithm_tlv() const {
    return signature_algorithm_tlv_;
  }

  const der::BitString& signature_value() const { return signature_value_; }

  // Accessor for struct containing raw fields of the TbsCertificate.
  const ParsedTbsCertificate& tbs() const { return tbs_; }

  // Returns the signatureAlgorithm of the Certificate (not the tbsCertificate).
  const SignatureAlgorithm& signature_algorithm() const {
    DCHECK(signature_algorithm_);
    return *signature_algorithm_;
  }

  // Returns the DER-encoded normalized subject value (not including outer
  // Sequence tag). This is gauranteed to be valid DER, though the contents of
  // unhandled string types are treated as raw bytes.
  der::Input normalized_subject() const {
    return der::Input(&normalized_subject_);
  }
  // Returns the DER-encoded normalized issuer value (not including outer
  // Sequence tag). This is gauranteed to be valid DER, though the contents of
  // unhandled string types are treated as raw bytes.
  der::Input normalized_issuer() const {
    return der::Input(&normalized_issuer_);
  }

  // Returns true if the certificate has a BasicConstraints extension.
  bool has_basic_constraints() const { return has_basic_constraints_; }

  // Returns the ParsedBasicConstraints struct. Caller must check
  // has_basic_constraints() before accessing this.
  const ParsedBasicConstraints& basic_constraints() const {
    DCHECK(has_basic_constraints_);
    return basic_constraints_;
  }

  // Returns true if the certificate has a KeyUsage extension.
  bool has_key_usage() const { return has_key_usage_; }

  // Returns the KeyUsage BitString. Caller must check
  // has_key_usage() before accessing this.
  const der::BitString& key_usage() const {
    DCHECK(has_key_usage_);
    return key_usage_;
  }

  // Returns true if the certificate has a ExtendedKeyUsage extension.
  bool has_extended_key_usage() const { return has_extended_key_usage_; }

  // Returns the ExtendedKeyUsage key purpose OIDs. Caller must check
  // has_extended_key_usage() before accessing this.
  const std::vector<der::Input>& extended_key_usage() const {
    DCHECK(has_extended_key_usage_);
    return extended_key_usage_;
  }

  // Returns true if the certificate has a SubjectAltName extension.
  bool has_subject_alt_names() const { return subject_alt_names_ != nullptr; }

  // Returns the ParsedExtension struct for the SubjectAltName extension.
  // If the cert did not have a SubjectAltName extension, this will be a
  // default-initialized ParsedExtension struct.
  const ParsedExtension& subject_alt_names_extension() const {
    return subject_alt_names_extension_;
  }

  // Returns the GeneralNames class parsed from SubjectAltName extension, or
  // nullptr if no SubjectAltName extension was present.
  const GeneralNames* subject_alt_names() const {
    return subject_alt_names_.get();
  }

  // Returns true if the certificate has a NameConstraints extension.
  bool has_name_constraints() const { return name_constraints_ != nullptr; }

  // Returns the parsed NameConstraints extension. Must not be called if
  // has_name_constraints() is false.
  const NameConstraints& name_constraints() const {
    DCHECK(name_constraints_);
    return *name_constraints_;
  }

  // Returns true if the certificate has an AuthorityInfoAccess extension.
  bool has_authority_info_access() const { return has_authority_info_access_; }

  // Returns the ParsedExtension struct for the AuthorityInfoAccess extension.
  const ParsedExtension& authority_info_access_extension() const {
    return authority_info_access_extension_;
  }

  // Returns any caIssuers URIs from the AuthorityInfoAccess extension.
  const std::vector<base::StringPiece>& ca_issuers_uris() const {
    return ca_issuers_uris_;
  }

  // Returns any OCSP URIs from the AuthorityInfoAccess extension.
  const std::vector<base::StringPiece>& ocsp_uris() const { return ocsp_uris_; }

  // Returns true if the certificate has a Policies extension.
  bool has_policy_oids() const { return has_policy_oids_; }

  // Returns the policy OIDs. Caller must check has_policy_oids() before
  // accessing this.
  const std::vector<der::Input>& policy_oids() const {
    DCHECK(has_policy_oids());
    return policy_oids_;
  }

  // Returns true if the certificate has a PolicyConstraints extension.
  bool has_policy_constraints() const { return has_policy_constraints_; }

  // Returns the ParsedPolicyConstraints struct. Caller must check
  // has_policy_constraints() before accessing this.
  const ParsedPolicyConstraints& policy_constraints() const {
    DCHECK(has_policy_constraints_);
    return policy_constraints_;
  }

  // Returns true if the certificate has a PolicyMappings extension.
  bool has_policy_mappings() const { return has_policy_mappings_; }

  // Returns the PolicyMappings extension. Caller must check
  // has_policy_mappings() before accessing this.
  const std::vector<ParsedPolicyMapping>& policy_mappings() const {
    DCHECK(has_policy_mappings_);
    return policy_mappings_;
  }

  // Returns true if the certificate has a InhibitAnyPolicy extension.
  bool has_inhibit_any_policy() const { return has_inhibit_any_policy_; }

  // Returns the Inhibit Any Policy extension. Caller must check
  // has_inhibit_any_policy() before accessing this.
  uint8_t inhibit_any_policy() const {
    DCHECK(has_inhibit_any_policy_);
    return inhibit_any_policy_;
  }

  // Returns a map of all the extensions in the certificate.
  const ExtensionsMap& extensions() const { return extensions_; }

  // Gets the value for extension matching |extension_oid|. Returns false if the
  // extension is not present.
  bool GetExtension(const der::Input& extension_oid,
                    ParsedExtension* parsed_extension) const;

 private:
  friend class base::RefCountedThreadSafe<ParsedCertificate>;
  ParsedCertificate();
  ~ParsedCertificate();

  // Creates a ParsedCertificate.  If |backing_data| is non-null, the
  // certificate's DER-encoded data will be referenced from here. Otherwise the
  // certificate's data will be |static_data|, and the pointer MUST remain
  // valid and its data unmodified for the entirety of the program.
  static scoped_refptr<ParsedCertificate> CreateInternal(
      bssl::UniquePtr<CRYPTO_BUFFER> backing_data,
      der::Input static_data,
      const ParseCertificateOptions& options,
      CertErrors* errors);

  // The backing store for the certificate data. May be null if created by
  // CreateWithoutCopyingUnsafe.
  bssl::UniquePtr<CRYPTO_BUFFER> cert_data_;

  // Points to the raw certificate DER.
  der::Input cert_;

  der::Input tbs_certificate_tlv_;
  der::Input signature_algorithm_tlv_;
  der::BitString signature_value_;
  ParsedTbsCertificate tbs_;

  // The signatureAlgorithm from the Certificate.
  std::unique_ptr<SignatureAlgorithm> signature_algorithm_;

  // Normalized DER-encoded Subject (not including outer Sequence tag).
  std::string normalized_subject_;
  // Normalized DER-encoded Issuer (not including outer Sequence tag).
  std::string normalized_issuer_;

  // BasicConstraints extension.
  bool has_basic_constraints_ = false;
  ParsedBasicConstraints basic_constraints_;

  // KeyUsage extension.
  bool has_key_usage_ = false;
  der::BitString key_usage_;

  // ExtendedKeyUsage extension.
  bool has_extended_key_usage_ = false;
  std::vector<der::Input> extended_key_usage_;

  // Raw SubjectAltName extension.
  ParsedExtension subject_alt_names_extension_;
  // Parsed SubjectAltName extension.
  std::unique_ptr<GeneralNames> subject_alt_names_;

  // NameConstraints extension.
  std::unique_ptr<NameConstraints> name_constraints_;

  // AuthorityInfoAccess extension.
  bool has_authority_info_access_ = false;
  ParsedExtension authority_info_access_extension_;
  // CaIssuers and Ocsp URIs parsed from the AuthorityInfoAccess extension. Note
  // that the AuthorityInfoAccess may have contained other AccessDescriptions
  // which are not represented here.
  std::vector<base::StringPiece> ca_issuers_uris_;
  std::vector<base::StringPiece> ocsp_uris_;

  // Policies extension.
  bool has_policy_oids_ = false;
  std::vector<der::Input> policy_oids_;

  // Policy constraints extension.
  bool has_policy_constraints_ = false;
  ParsedPolicyConstraints policy_constraints_;

  // Policy mappings extension.
  bool has_policy_mappings_ = false;
  std::vector<ParsedPolicyMapping> policy_mappings_;

  // Inhibit Any Policy extension.
  bool has_inhibit_any_policy_ = false;
  uint8_t inhibit_any_policy_;

  // All of the extensions.
  ExtensionsMap extensions_;

  DISALLOW_COPY_AND_ASSIGN(ParsedCertificate);
};

}  // namespace net

#endif  // NET_CERT_INTERNAL_PARSED_CERTIFICATE_H_
