// Copyright 2015 The Chromium Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "parse_certificate.h"

#include <optional>
#include <utility>

#include <openssl/base.h>
#include <openssl/bytestring.h>

#include "cert_error_params.h"
#include "cert_errors.h"
#include "general_names.h"
#include "input.h"
#include "parse_values.h"
#include "parser.h"
#include "string_util.h"

BSSL_NAMESPACE_BEGIN

namespace {

DEFINE_CERT_ERROR_ID(kCertificateNotSequence,
                     "Failed parsing Certificate SEQUENCE");
DEFINE_CERT_ERROR_ID(kUnconsumedDataInsideCertificateSequence,
                     "Unconsumed data inside Certificate SEQUENCE");
DEFINE_CERT_ERROR_ID(kUnconsumedDataAfterCertificateSequence,
                     "Unconsumed data after Certificate SEQUENCE");
DEFINE_CERT_ERROR_ID(kTbsCertificateNotSequence,
                     "Couldn't read tbsCertificate as SEQUENCE");
DEFINE_CERT_ERROR_ID(
    kSignatureAlgorithmNotSequence,
    "Couldn't read Certificate.signatureAlgorithm as SEQUENCE");
DEFINE_CERT_ERROR_ID(kSignatureValueNotBitString,
                     "Couldn't read Certificate.signatureValue as BIT STRING");
DEFINE_CERT_ERROR_ID(kUnconsumedDataInsideTbsCertificateSequence,
                     "Unconsumed data inside TBSCertificate");
DEFINE_CERT_ERROR_ID(kTbsNotSequence, "Failed parsing TBSCertificate SEQUENCE");
DEFINE_CERT_ERROR_ID(kFailedReadingVersion, "Failed reading version");
DEFINE_CERT_ERROR_ID(kFailedParsingVersion, "Failed parsing version");
DEFINE_CERT_ERROR_ID(kVersionExplicitlyV1,
                     "Version explicitly V1 (should be omitted)");
DEFINE_CERT_ERROR_ID(kFailedReadingSerialNumber, "Failed reading serialNumber");
DEFINE_CERT_ERROR_ID(kFailedReadingSignatureValue, "Failed reading signature");
DEFINE_CERT_ERROR_ID(kFailedReadingIssuer, "Failed reading issuer");
DEFINE_CERT_ERROR_ID(kFailedReadingValidity, "Failed reading validity");
DEFINE_CERT_ERROR_ID(kFailedParsingValidity, "Failed parsing validity");
DEFINE_CERT_ERROR_ID(kFailedReadingSubject, "Failed reading subject");
DEFINE_CERT_ERROR_ID(kFailedReadingSpki, "Failed reading subjectPublicKeyInfo");
DEFINE_CERT_ERROR_ID(kFailedReadingIssuerUniqueId,
                     "Failed reading issuerUniqueId");
DEFINE_CERT_ERROR_ID(kFailedParsingIssuerUniqueId,
                     "Failed parsing issuerUniqueId");
DEFINE_CERT_ERROR_ID(
    kIssuerUniqueIdNotExpected,
    "Unexpected issuerUniqueId (must be V2 or V3 certificate)");
DEFINE_CERT_ERROR_ID(kFailedReadingSubjectUniqueId,
                     "Failed reading subjectUniqueId");
DEFINE_CERT_ERROR_ID(kFailedParsingSubjectUniqueId,
                     "Failed parsing subjectUniqueId");
DEFINE_CERT_ERROR_ID(
    kSubjectUniqueIdNotExpected,
    "Unexpected subjectUniqueId (must be V2 or V3 certificate)");
DEFINE_CERT_ERROR_ID(kFailedReadingExtensions,
                     "Failed reading extensions SEQUENCE");
DEFINE_CERT_ERROR_ID(kUnexpectedExtensions,
                     "Unexpected extensions (must be V3 certificate)");
DEFINE_CERT_ERROR_ID(kSerialNumberIsNegative, "Serial number is negative");
DEFINE_CERT_ERROR_ID(kSerialNumberIsZero, "Serial number is zero");
DEFINE_CERT_ERROR_ID(kSerialNumberLengthOver20,
                     "Serial number is longer than 20 octets");
DEFINE_CERT_ERROR_ID(kSerialNumberNotValidInteger,
                     "Serial number is not a valid INTEGER");

// Returns true if `input` is a SEQUENCE and nothing else.
[[nodiscard]] bool IsSequenceTLV(der::Input input) {
  der::Parser parser(input);
  der::Parser unused_sequence_parser;
  if (!parser.ReadSequence(&unused_sequence_parser)) {
    return false;
  }
  // Should by a single SEQUENCE by definition of the function.
  return !parser.HasMore();
}

// Reads a SEQUENCE from `parser` and writes the full tag-length-value into
// `out`. On failure `parser` may or may not have been advanced.
[[nodiscard]] bool ReadSequenceTLV(der::Parser *parser, der::Input *out) {
  return parser->ReadRawTLV(out) && IsSequenceTLV(*out);
}

// Parses a Version according to RFC 5280:
//
//     Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
//
// No value other that v1, v2, or v3 is allowed (and if given will fail). RFC
// 5280 minimally requires the handling of v3 (and overwhelmingly these are the
// certificate versions in use today):
//
//     Implementations SHOULD be prepared to accept any version certificate.
//     At a minimum, conforming implementations MUST recognize version 3
//     certificates.
[[nodiscard]] bool ParseVersion(der::Input in, CertificateVersion *version) {
  der::Parser parser(in);
  uint64_t version64;
  if (!parser.ReadUint64(&version64)) {
    return false;
  }

  switch (version64) {
    case 0:
      *version = CertificateVersion::V1;
      break;
    case 1:
      *version = CertificateVersion::V2;
      break;
    case 2:
      *version = CertificateVersion::V3;
      break;
    default:
      // Don't allow any other version identifier.
      return false;
  }

  // By definition the input to this function was a single INTEGER, so there
  // shouldn't be anything else after it.
  return !parser.HasMore();
}

// Returns true if every bit in `bits` is zero (including empty).
[[nodiscard]] bool BitStringIsAllZeros(const der::BitString &bits) {
  // Note that it is OK to read from the unused bits, since BitString parsing
  // guarantees they are all zero.
  for (uint8_t b : bits.bytes()) {
    if (b != 0) {
      return false;
    }
  }
  return true;
}

// Parses a DistributionPointName.
//
// From RFC 5280:
//
//    DistributionPointName ::= CHOICE {
//      fullName                [0]     GeneralNames,
//      nameRelativeToCRLIssuer [1]     RelativeDistinguishedName }
bool ParseDistributionPointName(der::Input dp_name,
                                ParsedDistributionPoint *distribution_point) {
  der::Parser parser(dp_name);
  std::optional<der::Input> der_full_name;
  if (!parser.ReadOptionalTag(
          CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0,
          &der_full_name)) {
    return false;
  }
  if (der_full_name) {
    // TODO(mattm): surface the CertErrors.
    CertErrors errors;
    distribution_point->distribution_point_fullname =
        GeneralNames::CreateFromValue(*der_full_name, &errors);
    if (!distribution_point->distribution_point_fullname) {
      return false;
    }
    return !parser.HasMore();
  }

  if (!parser.ReadOptionalTag(
          CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1,
          &distribution_point
               ->distribution_point_name_relative_to_crl_issuer)) {
    return false;
  }
  if (distribution_point->distribution_point_name_relative_to_crl_issuer) {
    return !parser.HasMore();
  }

  // The CHOICE must contain either fullName or nameRelativeToCRLIssuer.
  return false;
}

// RFC 5280, section 4.2.1.13.
//
// DistributionPoint ::= SEQUENCE {
//  distributionPoint       [0]     DistributionPointName OPTIONAL,
//  reasons                 [1]     ReasonFlags OPTIONAL,
//  cRLIssuer               [2]     GeneralNames OPTIONAL }
bool ParseAndAddDistributionPoint(
    der::Parser *parser,
    std::vector<ParsedDistributionPoint> *distribution_points) {
  ParsedDistributionPoint distribution_point;

  // DistributionPoint ::= SEQUENCE {
  der::Parser distrib_point_parser;
  if (!parser->ReadSequence(&distrib_point_parser)) {
    return false;
  }

  //  distributionPoint       [0]     DistributionPointName OPTIONAL,
  std::optional<der::Input> distribution_point_name;
  if (!distrib_point_parser.ReadOptionalTag(
          CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0,
          &distribution_point_name)) {
    return false;
  }

  if (distribution_point_name &&
      !ParseDistributionPointName(*distribution_point_name,
                                  &distribution_point)) {
    return false;
  }

  //  reasons                 [1]     ReasonFlags OPTIONAL,
  if (!distrib_point_parser.ReadOptionalTag(CBS_ASN1_CONTEXT_SPECIFIC | 1,
                                            &distribution_point.reasons)) {
    return false;
  }

  //  cRLIssuer               [2]     GeneralNames OPTIONAL }
  if (!distrib_point_parser.ReadOptionalTag(
          CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 2,
          &distribution_point.crl_issuer)) {
    return false;
  }
  // TODO(eroman): Parse "cRLIssuer"?

  // RFC 5280, section 4.2.1.13:
  // either distributionPoint or cRLIssuer MUST be present.
  if (!distribution_point_name && !distribution_point.crl_issuer) {
    return false;
  }

  if (distrib_point_parser.HasMore()) {
    return false;
  }

  distribution_points->push_back(std::move(distribution_point));
  return true;
}

}  // namespace

ParsedTbsCertificate::ParsedTbsCertificate() = default;

ParsedTbsCertificate::ParsedTbsCertificate(ParsedTbsCertificate &&other) =
    default;

ParsedTbsCertificate::~ParsedTbsCertificate() = default;

bool VerifySerialNumber(der::Input value, bool warnings_only,
                        CertErrors *errors) {
  // If `warnings_only` was set to true, the exact same errors will be logged,
  // only they will be logged with a lower severity (warning rather than error).
  //
  // TODO(crbug.com/533048005): Remove this option. It now only controls serials
  // that aren't even valid integers. Historically, people needed to set it to
  // tolerate length over 20, but this is now always enabled.
  CertError::Severity error_severity =
      warnings_only ? CertError::SEVERITY_WARNING : CertError::SEVERITY_HIGH;

  bool negative;
  if (!der::IsValidInteger(value, &negative)) {
    errors->Add(error_severity, kSerialNumberNotValidInteger, nullptr);
    return false;
  }

  // RFC 5280 section 4.1.2.2:
  //
  //    Note: Non-conforming CAs may issue certificates with serial numbers
  //    that are negative or zero.  Certificate users SHOULD be prepared to
  //    gracefully handle such certificates.
  if (negative) {
    errors->AddWarning(kSerialNumberIsNegative);
  }
  if (value.size() == 1 && value[0] == 0) {
    errors->AddWarning(kSerialNumberIsZero);
  }

  // RFC 5280 section 4.1.2.2:
  //
  //    Certificate users MUST be able to handle serialNumber values up to 20
  //    octets. Conforming CAs MUST NOT use serialNumber values longer than 20
  //    octets.
  //
  // We do not attempt to enforce this as an error. In practice, it is common
  // for serials to be off, e.g. with 21 octets due to the extra byte needed to
  // keep values positive.
  if (value.size() > 20) {
    errors->AddWarning(kSerialNumberLengthOver20,
                       CreateCertErrorParams1SizeT("length", value.size()));
  }

  return true;
}

bool ReadUTCOrGeneralizedTime(der::Parser *parser, der::GeneralizedTime *out) {
  der::Input value;
  CBS_ASN1_TAG tag;

  if (!parser->ReadTagAndValue(&tag, &value)) {
    return false;
  }

  if (tag == CBS_ASN1_UTCTIME) {
    return der::ParseUTCTime(value, out);
  }

  if (tag == CBS_ASN1_GENERALIZEDTIME) {
    return der::ParseGeneralizedTime(value, out);
  }

  // Unrecognized tag.
  return false;
}

bool ParseValidity(der::Input validity_tlv, der::GeneralizedTime *not_before,
                   der::GeneralizedTime *not_after) {
  der::Parser parser(validity_tlv);

  //     Validity ::= SEQUENCE {
  der::Parser validity_parser;
  if (!parser.ReadSequence(&validity_parser)) {
    return false;
  }

  //          notBefore      Time,
  if (!ReadUTCOrGeneralizedTime(&validity_parser, not_before)) {
    return false;
  }

  //          notAfter       Time }
  if (!ReadUTCOrGeneralizedTime(&validity_parser, not_after)) {
    return false;
  }

  // By definition the input was a single Validity sequence, so there shouldn't
  // be unconsumed data.
  if (parser.HasMore()) {
    return false;
  }

  // The Validity type does not have an extension point.
  if (validity_parser.HasMore()) {
    return false;
  }

  // Note that RFC 5280 doesn't require notBefore to be <=
  // notAfter, so that will not be considered a "parsing" error here. Instead it
  // will be considered an expired certificate later when testing against the
  // current timestamp.
  return true;
}

bool ParseCertificate(der::Input certificate_tlv,
                      der::Input *out_tbs_certificate_tlv,
                      der::Input *out_signature_algorithm_tlv,
                      der::BitString *out_signature_value,
                      CertErrors *out_errors) {
  // `out_errors` is optional. But ensure it is non-null for the remainder of
  // this function.
  CertErrors unused_errors;
  if (!out_errors) {
    out_errors = &unused_errors;
  }

  der::Parser parser(certificate_tlv);

  //   Certificate  ::=  SEQUENCE  {
  der::Parser certificate_parser;
  if (!parser.ReadSequence(&certificate_parser)) {
    out_errors->AddError(kCertificateNotSequence);
    return false;
  }

  //        tbsCertificate       TBSCertificate,
  if (!ReadSequenceTLV(&certificate_parser, out_tbs_certificate_tlv)) {
    out_errors->AddError(kTbsCertificateNotSequence);
    return false;
  }

  //        signatureAlgorithm   AlgorithmIdentifier,
  if (!ReadSequenceTLV(&certificate_parser, out_signature_algorithm_tlv)) {
    out_errors->AddError(kSignatureAlgorithmNotSequence);
    return false;
  }

  //        signatureValue       BIT STRING  }
  std::optional<der::BitString> signature_value =
      certificate_parser.ReadBitString();
  if (!signature_value) {
    out_errors->AddError(kSignatureValueNotBitString);
    return false;
  }
  *out_signature_value = signature_value.value();

  // There isn't an extension point at the end of Certificate.
  if (certificate_parser.HasMore()) {
    out_errors->AddError(kUnconsumedDataInsideCertificateSequence);
    return false;
  }

  // By definition the input was a single Certificate, so there shouldn't be
  // unconsumed data.
  if (parser.HasMore()) {
    out_errors->AddError(kUnconsumedDataAfterCertificateSequence);
    return false;
  }

  return true;
}

// From RFC 5280 section 4.1:
//
//   TBSCertificate  ::=  SEQUENCE  {
//        version         [0]  EXPLICIT Version DEFAULT v1,
//        serialNumber         CertificateSerialNumber,
//        signature            AlgorithmIdentifier,
//        issuer               Name,
//        validity             Validity,
//        subject              Name,
//        subjectPublicKeyInfo SubjectPublicKeyInfo,
//        issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
//                             -- If present, version MUST be v2 or v3
//        subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
//                             -- If present, version MUST be v2 or v3
//        extensions      [3]  EXPLICIT Extensions OPTIONAL
//                             -- If present, version MUST be v3
//        }
bool ParseTbsCertificate(der::Input tbs_tlv,
                         const ParseCertificateOptions &options,
                         ParsedTbsCertificate *out, CertErrors *errors) {
  // The rest of this function assumes that `errors` is non-null.
  CertErrors unused_errors;
  if (!errors) {
    errors = &unused_errors;
  }

  // TODO(crbug.com/634443): Add useful error information to `errors`.

  der::Parser parser(tbs_tlv);

  //   TBSCertificate  ::=  SEQUENCE  {
  der::Parser tbs_parser;
  if (!parser.ReadSequence(&tbs_parser)) {
    errors->AddError(kTbsNotSequence);
    return false;
  }

  //        version         [0]  EXPLICIT Version DEFAULT v1,
  std::optional<der::Input> version;
  if (!tbs_parser.ReadOptionalTag(
          CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0, &version)) {
    errors->AddError(kFailedReadingVersion);
    return false;
  }
  if (version) {
    if (!ParseVersion(version.value(), &out->version)) {
      errors->AddError(kFailedParsingVersion);
      return false;
    }
    if (out->version == CertificateVersion::V1) {
      errors->AddError(kVersionExplicitlyV1);
      // The correct way to specify v1 is to omit the version field since v1 is
      // the DEFAULT.
      return false;
    }
  } else {
    out->version = CertificateVersion::V1;
  }

  //        serialNumber         CertificateSerialNumber,
  if (!tbs_parser.ReadTag(CBS_ASN1_INTEGER, &out->serial_number)) {
    errors->AddError(kFailedReadingSerialNumber);
    return false;
  }
  if (!VerifySerialNumber(out->serial_number,
                          options.allow_invalid_serial_numbers, errors)) {
    // Invalid serial numbers are only considered fatal failures if
    // |!allow_invalid_serial_numbers|.
    if (!options.allow_invalid_serial_numbers) {
      return false;
    }
  }

  //        signature            AlgorithmIdentifier,
  if (!ReadSequenceTLV(&tbs_parser, &out->signature_algorithm_tlv)) {
    errors->AddError(kFailedReadingSignatureValue);
    return false;
  }

  //        issuer               Name,
  if (!ReadSequenceTLV(&tbs_parser, &out->issuer_tlv)) {
    errors->AddError(kFailedReadingIssuer);
    return false;
  }

  //        validity             Validity,
  if (!tbs_parser.ReadRawTLV(&out->validity_tlv)) {
    errors->AddError(kFailedReadingValidity);
    return false;
  }
  if (!ParseValidity(out->validity_tlv, &out->validity_not_before,
                     &out->validity_not_after)) {
    errors->AddError(kFailedParsingValidity);
    return false;
  }

  //        subject              Name,
  if (!ReadSequenceTLV(&tbs_parser, &out->subject_tlv)) {
    errors->AddError(kFailedReadingSubject);
    return false;
  }

  //        subjectPublicKeyInfo SubjectPublicKeyInfo,
  if (!ReadSequenceTLV(&tbs_parser, &out->spki_tlv)) {
    errors->AddError(kFailedReadingSpki);
    return false;
  }

  out->bytes_after_spki = tbs_parser.RemainingBytes();

  //        issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
  //                             -- If present, version MUST be v2 or v3
  std::optional<der::Input> issuer_unique_id;
  if (!tbs_parser.ReadOptionalTag(CBS_ASN1_CONTEXT_SPECIFIC | 1,
                                  &issuer_unique_id)) {
    errors->AddError(kFailedReadingIssuerUniqueId);
    return false;
  }
  if (issuer_unique_id) {
    out->issuer_unique_id = der::ParseBitString(issuer_unique_id.value());
    if (!out->issuer_unique_id) {
      errors->AddError(kFailedParsingIssuerUniqueId);
      return false;
    }
    if (out->version != CertificateVersion::V2 &&
        out->version != CertificateVersion::V3) {
      errors->AddError(kIssuerUniqueIdNotExpected);
      return false;
    }
  }

  //        subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
  //                             -- If present, version MUST be v2 or v3
  std::optional<der::Input> subject_unique_id;
  if (!tbs_parser.ReadOptionalTag(CBS_ASN1_CONTEXT_SPECIFIC | 2,
                                  &subject_unique_id)) {
    errors->AddError(kFailedReadingSubjectUniqueId);
    return false;
  }
  if (subject_unique_id) {
    out->subject_unique_id = der::ParseBitString(subject_unique_id.value());
    if (!out->subject_unique_id) {
      errors->AddError(kFailedParsingSubjectUniqueId);
      return false;
    }
    if (out->version != CertificateVersion::V2 &&
        out->version != CertificateVersion::V3) {
      errors->AddError(kSubjectUniqueIdNotExpected);
      return false;
    }
  }

  //        extensions      [3]  EXPLICIT Extensions OPTIONAL
  //                             -- If present, version MUST be v3
  if (!tbs_parser.ReadOptionalTag(
          CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 3,
          &out->extensions_tlv)) {
    errors->AddError(kFailedReadingExtensions);
    return false;
  }
  if (out->extensions_tlv) {
    // extensions_tlv must be a single element. Also check that it is a
    // SEQUENCE.
    if (!IsSequenceTLV(out->extensions_tlv.value())) {
      errors->AddError(kFailedReadingExtensions);
      return false;
    }
    if (out->version != CertificateVersion::V3) {
      errors->AddError(kUnexpectedExtensions);
      return false;
    }
  }

  // Note that there IS an extension point at the end of TBSCertificate
  // (according to RFC 5912), so from that interpretation, unconsumed data would
  // be allowed in `tbs_parser`.
  //
  // However because only v1, v2, and v3 certificates are supported by the
  // parsing, there shouldn't be any subsequent data in those versions, so
  // reject.
  if (tbs_parser.HasMore()) {
    errors->AddError(kUnconsumedDataInsideTbsCertificateSequence);
    return false;
  }

  // By definition the input was a single TBSCertificate, so there shouldn't be
  // unconsumed data.
  if (parser.HasMore()) {
    return false;
  }

  return true;
}

// From RFC 5280:
//
//    Extension  ::=  SEQUENCE  {
//            extnID      OBJECT IDENTIFIER,
//            critical    BOOLEAN DEFAULT FALSE,
//            extnValue   OCTET STRING
//                        -- contains the DER encoding of an ASN.1 value
//                        -- corresponding to the extension type identified
//                        -- by extnID
//            }
bool ParseExtension(der::Input extension_tlv, ParsedExtension *out) {
  der::Parser parser(extension_tlv);

  //    Extension  ::=  SEQUENCE  {
  der::Parser extension_parser;
  if (!parser.ReadSequence(&extension_parser)) {
    return false;
  }

  //            extnID      OBJECT IDENTIFIER,
  if (!extension_parser.ReadTag(CBS_ASN1_OBJECT, &out->oid)) {
    return false;
  }

  //            critical    BOOLEAN DEFAULT FALSE,
  out->critical = false;
  bool has_critical;
  der::Input critical;
  if (!extension_parser.ReadOptionalTag(CBS_ASN1_BOOLEAN, &critical,
                                        &has_critical)) {
    return false;
  }
  if (has_critical) {
    if (!der::ParseBool(critical, &out->critical)) {
      return false;
    }
    if (!out->critical) {
      return false;  // DER-encoding requires DEFAULT values be omitted.
    }
  }

  //            extnValue   OCTET STRING
  if (!extension_parser.ReadTag(CBS_ASN1_OCTETSTRING, &out->value)) {
    return false;
  }

  // The Extension type does not have an extension point (everything goes in
  // extnValue).
  if (extension_parser.HasMore()) {
    return false;
  }

  // By definition the input was a single Extension sequence, so there shouldn't
  // be unconsumed data.
  if (parser.HasMore()) {
    return false;
  }

  return true;
}

OPENSSL_EXPORT bool ParseExtensions(
    der::Input extensions_tlv,
    std::map<der::Input, ParsedExtension> *extensions) {
  der::Parser parser(extensions_tlv);

  //    Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
  der::Parser extensions_parser;
  if (!parser.ReadSequence(&extensions_parser)) {
    return false;
  }

  // The Extensions SEQUENCE must contains at least 1 element (otherwise it
  // should have been omitted).
  if (!extensions_parser.HasMore()) {
    return false;
  }

  extensions->clear();

  while (extensions_parser.HasMore()) {
    ParsedExtension extension;

    der::Input extension_tlv;
    if (!extensions_parser.ReadRawTLV(&extension_tlv)) {
      return false;
    }

    if (!ParseExtension(extension_tlv, &extension)) {
      return false;
    }

    bool is_duplicate =
        !extensions->insert(std::make_pair(extension.oid, extension)).second;

    // RFC 5280 says that an extension should not appear more than once.
    if (is_duplicate) {
      return false;
    }
  }

  // By definition the input was a single Extensions sequence, so there
  // shouldn't be unconsumed data.
  if (parser.HasMore()) {
    return false;
  }

  return true;
}

OPENSSL_EXPORT bool ConsumeExtension(
    der::Input oid,
    std::map<der::Input, ParsedExtension> *unconsumed_extensions,
    ParsedExtension *extension) {
  auto it = unconsumed_extensions->find(oid);
  if (it == unconsumed_extensions->end()) {
    return false;
  }

  *extension = it->second;
  unconsumed_extensions->erase(it);
  return true;
}

bool ParseBasicConstraints(der::Input basic_constraints_tlv,
                           ParsedBasicConstraints *out) {
  der::Parser parser(basic_constraints_tlv);

  //    BasicConstraints ::= SEQUENCE {
  der::Parser sequence_parser;
  if (!parser.ReadSequence(&sequence_parser)) {
    return false;
  }

  //         cA                      BOOLEAN DEFAULT FALSE,
  out->is_ca = false;
  bool has_ca;
  der::Input ca;
  if (!sequence_parser.ReadOptionalTag(CBS_ASN1_BOOLEAN, &ca, &has_ca)) {
    return false;
  }
  if (has_ca) {
    if (!der::ParseBool(ca, &out->is_ca)) {
      return false;
    }
    // TODO(eroman): Should reject if CA was set to false, since
    // DER-encoding requires DEFAULT values be omitted. In
    // practice however there are a lot of certificates that use
    // the broken encoding.
  }

  //         pathLenConstraint       INTEGER (0..MAX) OPTIONAL }
  der::Input encoded_path_len;
  if (!sequence_parser.ReadOptionalTag(CBS_ASN1_INTEGER, &encoded_path_len,
                                       &out->has_path_len)) {
    return false;
  }
  if (out->has_path_len) {
    // TODO(eroman): Surface reason for failure if length was longer than uint8.
    if (!der::ParseUint8(encoded_path_len, &out->path_len)) {
      return false;
    }
  } else {
    // Default initialize to 0 as a precaution.
    out->path_len = 0;
  }

  // There shouldn't be any unconsumed data in the extension.
  if (sequence_parser.HasMore()) {
    return false;
  }

  // By definition the input was a single BasicConstraints sequence, so there
  // shouldn't be unconsumed data.
  if (parser.HasMore()) {
    return false;
  }

  return true;
}

// TODO(crbug.com/1314019): return std::optional<BitString> when converting
// has_key_usage_ and key_usage_ into single std::optional field.
bool ParseKeyUsage(der::Input key_usage_tlv, der::BitString *key_usage) {
  der::Parser parser(key_usage_tlv);
  std::optional<der::BitString> key_usage_internal = parser.ReadBitString();
  if (!key_usage_internal) {
    return false;
  }

  // By definition the input was a single BIT STRING.
  if (parser.HasMore()) {
    return false;
  }

  // RFC 5280 section 4.2.1.3:
  //
  //     When the keyUsage extension appears in a certificate, at least
  //     one of the bits MUST be set to 1.
  if (BitStringIsAllZeros(key_usage_internal.value())) {
    return false;
  }

  *key_usage = key_usage_internal.value();
  return true;
}

bool ParseAuthorityInfoAccess(
    der::Input authority_info_access_tlv,
    std::vector<AuthorityInfoAccessDescription> *out_access_descriptions) {
  der::Parser parser(authority_info_access_tlv);

  out_access_descriptions->clear();

  //    AuthorityInfoAccessSyntax  ::=
  //            SEQUENCE SIZE (1..MAX) OF AccessDescription
  der::Parser sequence_parser;
  if (!parser.ReadSequence(&sequence_parser)) {
    return false;
  }
  if (!sequence_parser.HasMore()) {
    return false;
  }

  while (sequence_parser.HasMore()) {
    AuthorityInfoAccessDescription access_description;

    //    AccessDescription  ::=  SEQUENCE {
    der::Parser access_description_sequence_parser;
    if (!sequence_parser.ReadSequence(&access_description_sequence_parser)) {
      return false;
    }

    //            accessMethod          OBJECT IDENTIFIER,
    if (!access_description_sequence_parser.ReadTag(
            CBS_ASN1_OBJECT, &access_description.access_method_oid)) {
      return false;
    }

    //            accessLocation        GeneralName  }
    if (!access_description_sequence_parser.ReadRawTLV(
            &access_description.access_location)) {
      return false;
    }

    if (access_description_sequence_parser.HasMore()) {
      return false;
    }

    out_access_descriptions->push_back(access_description);
  }

  return true;
}

bool ParseAuthorityInfoAccessURIs(
    der::Input authority_info_access_tlv,
    std::vector<std::string_view> *out_ca_issuers_uris,
    std::vector<std::string_view> *out_ocsp_uris) {
  std::vector<AuthorityInfoAccessDescription> access_descriptions;
  if (!ParseAuthorityInfoAccess(authority_info_access_tlv,
                                &access_descriptions)) {
    return false;
  }

  for (const auto &access_description : access_descriptions) {
    der::Parser access_location_parser(access_description.access_location);
    CBS_ASN1_TAG access_location_tag;
    der::Input access_location_value;
    if (!access_location_parser.ReadTagAndValue(&access_location_tag,
                                                &access_location_value)) {
      return false;
    }

    // GeneralName ::= CHOICE {
    if (access_location_tag == (CBS_ASN1_CONTEXT_SPECIFIC | 6)) {
      // uniformResourceIdentifier       [6]     IA5String,
      std::string_view uri = BytesAsStringView(access_location_value);
      if (!bssl::string_util::IsAscii(uri)) {
        return false;
      }

      if (access_description.access_method_oid == der::Input(kAdCaIssuersOid)) {
        out_ca_issuers_uris->push_back(uri);
      } else if (access_description.access_method_oid ==
                 der::Input(kAdOcspOid)) {
        out_ocsp_uris->push_back(uri);
      }
    }
  }
  return true;
}

ParsedDistributionPoint::ParsedDistributionPoint() = default;
ParsedDistributionPoint::ParsedDistributionPoint(
    ParsedDistributionPoint &&other) = default;
ParsedDistributionPoint::~ParsedDistributionPoint() = default;

bool ParseCrlDistributionPoints(
    der::Input extension_value,
    std::vector<ParsedDistributionPoint> *distribution_points) {
  distribution_points->clear();

  // RFC 5280, section 4.2.1.13.
  //
  // CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
  der::Parser extension_value_parser(extension_value);
  der::Parser distribution_points_parser;
  if (!extension_value_parser.ReadSequence(&distribution_points_parser)) {
    return false;
  }
  if (extension_value_parser.HasMore()) {
    return false;
  }

  // Sequence must have a minimum of 1 item.
  if (!distribution_points_parser.HasMore()) {
    return false;
  }

  while (distribution_points_parser.HasMore()) {
    if (!ParseAndAddDistributionPoint(&distribution_points_parser,
                                      distribution_points)) {
      return false;
    }
  }

  return true;
}

ParsedAuthorityKeyIdentifier::ParsedAuthorityKeyIdentifier() = default;
ParsedAuthorityKeyIdentifier::~ParsedAuthorityKeyIdentifier() = default;
ParsedAuthorityKeyIdentifier::ParsedAuthorityKeyIdentifier(
    ParsedAuthorityKeyIdentifier &&other) = default;
ParsedAuthorityKeyIdentifier &ParsedAuthorityKeyIdentifier::operator=(
    ParsedAuthorityKeyIdentifier &&other) = default;

bool ParseAuthorityKeyIdentifier(
    der::Input extension_value,
    ParsedAuthorityKeyIdentifier *authority_key_identifier) {
  // RFC 5280, section 4.2.1.1.
  //    AuthorityKeyIdentifier ::= SEQUENCE {
  //       keyIdentifier             [0] KeyIdentifier           OPTIONAL,
  //       authorityCertIssuer       [1] GeneralNames            OPTIONAL,
  //       authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL  }
  //
  //    KeyIdentifier ::= OCTET STRING

  der::Parser extension_value_parser(extension_value);
  der::Parser aki_parser;
  if (!extension_value_parser.ReadSequence(&aki_parser)) {
    return false;
  }
  if (extension_value_parser.HasMore()) {
    return false;
  }

  // TODO(mattm): Should having an empty AuthorityKeyIdentifier SEQUENCE be an
  // error? RFC 5280 doesn't explicitly say it.

  //       keyIdentifier             [0] KeyIdentifier           OPTIONAL,
  if (!aki_parser.ReadOptionalTag(CBS_ASN1_CONTEXT_SPECIFIC | 0,
                                  &authority_key_identifier->key_identifier)) {
    return false;
  }

  //       authorityCertIssuer       [1] GeneralNames            OPTIONAL,
  if (!aki_parser.ReadOptionalTag(
          CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1,
          &authority_key_identifier->authority_cert_issuer)) {
    return false;
  }

  //       authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL  }
  if (!aki_parser.ReadOptionalTag(
          CBS_ASN1_CONTEXT_SPECIFIC | 2,
          &authority_key_identifier->authority_cert_serial_number)) {
    return false;
  }

  //     -- authorityCertIssuer and authorityCertSerialNumber MUST both
  //     -- be present or both be absent
  if (authority_key_identifier->authority_cert_issuer.has_value() !=
      authority_key_identifier->authority_cert_serial_number.has_value()) {
    return false;
  }

  // There shouldn't be any unconsumed data in the AuthorityKeyIdentifier
  // SEQUENCE.
  if (aki_parser.HasMore()) {
    return false;
  }

  return true;
}

bool ParseSubjectKeyIdentifier(der::Input extension_value,
                               der::Input *subject_key_identifier) {
  //    SubjectKeyIdentifier ::= KeyIdentifier
  //
  //    KeyIdentifier ::= OCTET STRING
  der::Parser extension_value_parser(extension_value);
  if (!extension_value_parser.ReadTag(CBS_ASN1_OCTETSTRING,
                                      subject_key_identifier)) {
    return false;
  }

  // There shouldn't be any unconsumed data in the extension SEQUENCE.
  if (extension_value_parser.HasMore()) {
    return false;
  }

  return true;
}

BSSL_NAMESPACE_END
