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

#include <algorithm>
#include <iterator>

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

#include "cert_errors.h"
#include "crl.h"
#include "input.h"
#include "parse_values.h"
#include "parser.h"
#include "revocation_util.h"
#include "signature_algorithm.h"
#include "verify_name_match.h"
#include "verify_signed_data.h"

namespace bssl {

namespace {

// id-ce-issuingDistributionPoint OBJECT IDENTIFIER ::= { id-ce 28 }
// In dotted notation: 2.5.29.28
inline constexpr uint8_t kIssuingDistributionPointOid[] = {0x55, 0x1d, 0x1c};

[[nodiscard]] bool NormalizeNameTLV(der::Input name_tlv,
                                    std::string *out_normalized_name) {
  der::Parser parser(name_tlv);
  der::Input name_rdn;
  bssl::CertErrors unused_errors;
  return parser.ReadTag(CBS_ASN1_SEQUENCE, &name_rdn) &&
         NormalizeName(name_rdn, out_normalized_name, &unused_errors) &&
         !parser.HasMore();
}

bool ContainsExactMatchingName(std::vector<std::string_view> a,
                               std::vector<std::string_view> b) {
  std::sort(a.begin(), a.end());
  std::sort(b.begin(), b.end());
  std::vector<std::string_view> names_in_common;
  std::set_intersection(a.begin(), a.end(), b.begin(), b.end(),
                        std::back_inserter(names_in_common));
  return !names_in_common.empty();
}

}  // namespace

bool ParseCrlCertificateList(der::Input crl_tlv,
                             der::Input *out_tbs_cert_list_tlv,
                             der::Input *out_signature_algorithm_tlv,
                             der::BitString *out_signature_value) {
  der::Parser parser(crl_tlv);

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

  //        tbsCertList          TBSCertList
  if (!certificate_list_parser.ReadRawTLV(out_tbs_cert_list_tlv)) {
    return false;
  }

  //        signatureAlgorithm   AlgorithmIdentifier,
  if (!certificate_list_parser.ReadRawTLV(out_signature_algorithm_tlv)) {
    return false;
  }

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

  // There isn't an extension point at the end of CertificateList.
  if (certificate_list_parser.HasMore()) {
    return false;
  }

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

  return true;
}

bool ParseCrlTbsCertList(der::Input tbs_tlv, ParsedCrlTbsCertList *out) {
  der::Parser parser(tbs_tlv);

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

  //         version                 Version OPTIONAL,
  //                                      -- if present, MUST be v2
  std::optional<der::Input> version_der;
  if (!tbs_parser.ReadOptionalTag(CBS_ASN1_INTEGER, &version_der)) {
    return false;
  }
  if (version_der.has_value()) {
    uint64_t version64;
    if (!der::ParseUint64(*version_der, &version64)) {
      return false;
    }
    // If version is present, it MUST be v2(1).
    if (version64 != 1) {
      return false;
    }
    out->version = CrlVersion::V2;
  } else {
    // Uh, RFC 5280 doesn't actually say it anywhere, but presumably if version
    // is not specified, it is V1.
    out->version = CrlVersion::V1;
  }

  //         signature               AlgorithmIdentifier,
  if (!tbs_parser.ReadRawTLV(&out->signature_algorithm_tlv)) {
    return false;
  }

  //         issuer                  Name,
  if (!tbs_parser.ReadRawTLV(&out->issuer_tlv)) {
    return false;
  }

  //         thisUpdate              Time,
  if (!ReadUTCOrGeneralizedTime(&tbs_parser, &out->this_update)) {
    return false;
  }

  //         nextUpdate              Time OPTIONAL,
  CBS_ASN1_TAG maybe_next_update_tag;
  der::Input unused_next_update_input;
  if (tbs_parser.PeekTagAndValue(&maybe_next_update_tag,
                                 &unused_next_update_input) &&
      (maybe_next_update_tag == CBS_ASN1_UTCTIME ||
       maybe_next_update_tag == CBS_ASN1_GENERALIZEDTIME)) {
    der::GeneralizedTime next_update_time;
    if (!ReadUTCOrGeneralizedTime(&tbs_parser, &next_update_time)) {
      return false;
    }
    out->next_update = next_update_time;
  } else {
    out->next_update = std::nullopt;
  }

  //         revokedCertificates     SEQUENCE OF SEQUENCE  { ... } OPTIONAL,
  der::Input unused_revoked_certificates;
  CBS_ASN1_TAG maybe_revoked_certifigates_tag;
  if (tbs_parser.PeekTagAndValue(&maybe_revoked_certifigates_tag,
                                 &unused_revoked_certificates) &&
      maybe_revoked_certifigates_tag == CBS_ASN1_SEQUENCE) {
    der::Input revoked_certificates_tlv;
    if (!tbs_parser.ReadRawTLV(&revoked_certificates_tlv)) {
      return false;
    }
    out->revoked_certificates_tlv = revoked_certificates_tlv;
  } else {
    out->revoked_certificates_tlv = std::nullopt;
  }

  //         crlExtensions           [0]  EXPLICIT Extensions OPTIONAL
  //                                       -- if present, version MUST be v2
  if (!tbs_parser.ReadOptionalTag(
          CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0,
          &out->crl_extensions_tlv)) {
    return false;
  }
  if (out->crl_extensions_tlv.has_value()) {
    if (out->version != CrlVersion::V2) {
      return false;
    }
  }

  if (tbs_parser.HasMore()) {
    // Invalid or extraneous elements.
    return false;
  }

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

  return true;
}

bool ParseIssuingDistributionPoint(
    der::Input extension_value,
    std::unique_ptr<GeneralNames> *out_distribution_point_names,
    ContainedCertsType *out_only_contains_cert_type) {
  der::Parser idp_extension_value_parser(extension_value);
  // IssuingDistributionPoint ::= SEQUENCE {
  der::Parser idp_parser;
  if (!idp_extension_value_parser.ReadSequence(&idp_parser)) {
    return false;
  }

  // 5.2.5.  Conforming CRLs issuers MUST NOT issue CRLs where the DER
  //    encoding of the issuing distribution point extension is an empty
  //    sequence.
  if (!idp_parser.HasMore()) {
    return false;
  }

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

  if (distribution_point.has_value()) {
    //   DistributionPointName ::= CHOICE {
    der::Parser dp_name_parser(*distribution_point);
    //        fullName                [0]     GeneralNames,
    //        nameRelativeToCRLIssuer [1]     RelativeDistinguishedName }
    std::optional<der::Input> der_full_name;
    if (!dp_name_parser.ReadOptionalTag(
            CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0,
            &der_full_name)) {
      return false;
    }
    if (!der_full_name) {
      // Only fullName is supported.
      return false;
    }
    CertErrors errors;
    *out_distribution_point_names =
        GeneralNames::CreateFromValue(*der_full_name, &errors);
    if (!*out_distribution_point_names) {
      return false;
    }

    if (dp_name_parser.HasMore()) {
      // CHOICE represents a single value.
      return false;
    }
  }

  *out_only_contains_cert_type = ContainedCertsType::ANY_CERTS;

  //  onlyContainsUserCerts      [1] BOOLEAN DEFAULT FALSE,
  std::optional<der::Input> only_contains_user_certs;
  if (!idp_parser.ReadOptionalTag(CBS_ASN1_CONTEXT_SPECIFIC | 1,
                                  &only_contains_user_certs)) {
    return false;
  }
  if (only_contains_user_certs.has_value()) {
    bool bool_value;
    if (!der::ParseBool(*only_contains_user_certs, &bool_value)) {
      return false;
    }
    if (!bool_value) {
      return false;  // DER-encoding requires DEFAULT values be omitted.
    }
    *out_only_contains_cert_type = ContainedCertsType::USER_CERTS;
  }

  //  onlyContainsCACerts        [2] BOOLEAN DEFAULT FALSE,
  std::optional<der::Input> only_contains_ca_certs;
  if (!idp_parser.ReadOptionalTag(CBS_ASN1_CONTEXT_SPECIFIC | 2,
                                  &only_contains_ca_certs)) {
    return false;
  }
  if (only_contains_ca_certs.has_value()) {
    bool bool_value;
    if (!der::ParseBool(*only_contains_ca_certs, &bool_value)) {
      return false;
    }
    if (!bool_value) {
      return false;  // DER-encoding requires DEFAULT values be omitted.
    }
    if (*out_only_contains_cert_type != ContainedCertsType::ANY_CERTS) {
      // 5.2.5.  at most one of onlyContainsUserCerts, onlyContainsCACerts,
      //         and onlyContainsAttributeCerts may be set to TRUE.
      return false;
    }
    *out_only_contains_cert_type = ContainedCertsType::CA_CERTS;
  }

  //  onlySomeReasons            [3] ReasonFlags OPTIONAL,
  //  indirectCRL                [4] BOOLEAN DEFAULT FALSE,
  //  onlyContainsAttributeCerts [5] BOOLEAN DEFAULT FALSE }
  // onlySomeReasons, indirectCRL, and onlyContainsAttributeCerts are not
  // supported, fail parsing if they are present.
  if (idp_parser.HasMore()) {
    return false;
  }

  return true;
}

CRLRevocationStatus GetCRLStatusForCert(
    der::Input cert_serial, CrlVersion crl_version,
    const std::optional<der::Input> &revoked_certificates_tlv) {
  if (!revoked_certificates_tlv.has_value()) {
    // RFC 5280 Section 5.1.2.6: "When there are no revoked certificates, the
    // revoked certificates list MUST be absent."
    // No covered certificates are revoked, therefore the cert is good.
    return CRLRevocationStatus::GOOD;
  }

  der::Parser parser(*revoked_certificates_tlv);

  //         revokedCertificates     SEQUENCE OF SEQUENCE  {
  der::Parser revoked_certificates_parser;
  if (!parser.ReadSequence(&revoked_certificates_parser)) {
    return CRLRevocationStatus::UNKNOWN;
  }

  // RFC 5280 Section 5.1.2.6: "When there are no revoked certificates, the
  // revoked certificates list MUST be absent."
  if (!revoked_certificates_parser.HasMore()) {
    return CRLRevocationStatus::UNKNOWN;
  }

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

  bool found_matching_serial = false;

  while (revoked_certificates_parser.HasMore()) {
    //         revokedCertificates     SEQUENCE OF SEQUENCE  {
    der::Parser crl_entry_parser;
    if (!revoked_certificates_parser.ReadSequence(&crl_entry_parser)) {
      return CRLRevocationStatus::UNKNOWN;
    }

    der::Input revoked_cert_serial_number;
    //              userCertificate         CertificateSerialNumber,
    if (!crl_entry_parser.ReadTag(CBS_ASN1_INTEGER,
                                  &revoked_cert_serial_number)) {
      return CRLRevocationStatus::UNKNOWN;
    }

    //              revocationDate          Time,
    der::GeneralizedTime unused_revocation_date;
    if (!ReadUTCOrGeneralizedTime(&crl_entry_parser, &unused_revocation_date)) {
      return CRLRevocationStatus::UNKNOWN;
    }

    //              crlEntryExtensions      Extensions OPTIONAL
    if (crl_entry_parser.HasMore()) {
      //                                       -- if present, version MUST be v2
      if (crl_version != CrlVersion::V2) {
        return CRLRevocationStatus::UNKNOWN;
      }

      der::Input crl_entry_extensions_tlv;
      if (!crl_entry_parser.ReadRawTLV(&crl_entry_extensions_tlv)) {
        return CRLRevocationStatus::UNKNOWN;
      }

      std::map<der::Input, ParsedExtension> extensions;
      if (!ParseExtensions(crl_entry_extensions_tlv, &extensions)) {
        return CRLRevocationStatus::UNKNOWN;
      }

      // RFC 5280 Section 5.3: "If a CRL contains a critical CRL entry
      // extension that the application cannot process, then the application
      // MUST NOT use that CRL to determine the status of any certificates."
      for (const auto &ext : extensions) {
        if (ext.second.critical) {
          return CRLRevocationStatus::UNKNOWN;
        }
      }
    }

    if (crl_entry_parser.HasMore()) {
      return CRLRevocationStatus::UNKNOWN;
    }

    if (revoked_cert_serial_number == cert_serial) {
      // Cert is revoked, but can't return yet since there might be critical
      // extensions on later entries that would prevent use of this CRL.
      found_matching_serial = true;
    }
  }

  if (found_matching_serial) {
    return CRLRevocationStatus::REVOKED;
  }

  // |cert| is not present in the revokedCertificates list.
  return CRLRevocationStatus::GOOD;
}

ParsedCrlTbsCertList::ParsedCrlTbsCertList() = default;
ParsedCrlTbsCertList::~ParsedCrlTbsCertList() = default;

CRLRevocationStatus CheckCRL(std::string_view raw_crl,
                             const ParsedCertificateList &valid_chain,
                             size_t target_cert_index,
                             const ParsedDistributionPoint &cert_dp,
                             int64_t verify_time_epoch_seconds,
                             std::optional<int64_t> max_age_seconds) {
  BSSL_CHECK(target_cert_index < valid_chain.size());

  if (cert_dp.reasons) {
    // Reason codes are not supported. If the distribution point contains a
    // subset of reasons then skip it. We aren't interested in subsets of CRLs
    // and the RFC states that there MUST be a CRL that covers all reasons.
    return CRLRevocationStatus::UNKNOWN;
  }
  if (cert_dp.crl_issuer) {
    // Indirect CRLs are not supported.
    return CRLRevocationStatus::UNKNOWN;
  }

  const ParsedCertificate *target_cert = valid_chain[target_cert_index].get();

  // 6.3.3 (a) Update the local CRL cache by obtaining a complete CRL, a
  //           delta CRL, or both, as required.
  //
  // This implementation only supports complete CRLs and takes the CRL as
  // input, it is up to the caller to provide an up to date CRL.

  der::Input tbs_cert_list_tlv;
  der::Input signature_algorithm_tlv;
  der::BitString signature_value;
  if (!ParseCrlCertificateList(der::Input(raw_crl), &tbs_cert_list_tlv,
                               &signature_algorithm_tlv, &signature_value)) {
    return CRLRevocationStatus::UNKNOWN;
  }

  ParsedCrlTbsCertList tbs_cert_list;
  if (!ParseCrlTbsCertList(tbs_cert_list_tlv, &tbs_cert_list)) {
    return CRLRevocationStatus::UNKNOWN;
  }

  // 5.1.1.2  signatureAlgorithm
  //
  // TODO(https://crbug.com/749276): Check the signature algorithm against
  // policy.
  std::optional<SignatureAlgorithm> signature_algorithm =
      ParseSignatureAlgorithm(signature_algorithm_tlv);
  if (!signature_algorithm) {
    return CRLRevocationStatus::UNKNOWN;
  }

  //    This field MUST contain the same algorithm identifier as the
  //    signature field in the sequence tbsCertList (Section 5.1.2.2).
  std::optional<SignatureAlgorithm> tbs_alg =
      ParseSignatureAlgorithm(tbs_cert_list.signature_algorithm_tlv);
  if (!tbs_alg || *signature_algorithm != *tbs_alg) {
    return CRLRevocationStatus::UNKNOWN;
  }

  // Check CRL dates. Roughly corresponds to 6.3.3 (a) (1) but does not attempt
  // to update the CRL if it is out of date.
  if (!CheckRevocationDateValid(tbs_cert_list.this_update,
                                tbs_cert_list.next_update.has_value()
                                    ? &tbs_cert_list.next_update.value()
                                    : nullptr,
                                verify_time_epoch_seconds, max_age_seconds)) {
    return CRLRevocationStatus::UNKNOWN;
  }

  // 6.3.3 (a) (2) is skipped: This implementation does not support delta CRLs.

  // 6.3.3 (b) Verify the issuer and scope of the complete CRL as follows:
  // 6.3.3 (b) (1) If the DP includes cRLIssuer, then verify that the issuer
  //               field in the complete CRL matches cRLIssuer in the DP and
  //               that the complete CRL contains an issuing distribution
  //               point extension with the indirectCRL boolean asserted.
  //
  // Nothing is done here since distribution points with crlIssuer were skipped
  // above.

  // 6.3.3 (b) (1) Otherwise, verify that the CRL issuer matches the
  //               certificate issuer.
  //
  // Normalization for the name comparison is used although the RFC is not
  // clear on this. There are several places that explicitly are called out as
  // requiring identical encodings:
  //
  // 4.2.1.13.  CRL Distribution Points (cert extension) says the DP cRLIssuer
  //    field MUST be exactly the same as the encoding in issuer field of the
  //    CRL.
  //
  // 5.2.5.  Issuing Distribution Point (crl extension)
  //    The identical encoding MUST be used in the distributionPoint fields
  //    of the certificate and the CRL.
  //
  // 5.3.3.  Certificate Issuer (crl entry extension) also says "The encoding of
  //    the DN MUST be identical to the encoding used in the certificate"
  //
  // But 6.3.3 (b) (1) just says "matches". Also NIST PKITS includes at least
  // one test that requires normalization here.
  // TODO(https://crbug.com/749276): could do exact comparison first and only
  // fall back to normalizing if that fails.
  std::string normalized_crl_issuer;
  if (!NormalizeNameTLV(tbs_cert_list.issuer_tlv, &normalized_crl_issuer)) {
    return CRLRevocationStatus::UNKNOWN;
  }
  if (der::Input(normalized_crl_issuer) != target_cert->normalized_issuer()) {
    return CRLRevocationStatus::UNKNOWN;
  }

  if (tbs_cert_list.crl_extensions_tlv.has_value()) {
    std::map<der::Input, ParsedExtension> extensions;
    if (!ParseExtensions(*tbs_cert_list.crl_extensions_tlv, &extensions)) {
      return CRLRevocationStatus::UNKNOWN;
    }

    // 6.3.3 (b) (2) If the complete CRL includes an issuing distribution point
    //               (IDP) CRL extension, check the following:
    ParsedExtension idp_extension;
    if (ConsumeExtension(der::Input(kIssuingDistributionPointOid), &extensions,
                         &idp_extension)) {
      std::unique_ptr<GeneralNames> distribution_point_names;
      ContainedCertsType only_contains_cert_type;
      if (!ParseIssuingDistributionPoint(idp_extension.value,
                                         &distribution_point_names,
                                         &only_contains_cert_type)) {
        return CRLRevocationStatus::UNKNOWN;
      }

      if (distribution_point_names) {
        // 6.3.3. (b) (2) (i) If the distribution point name is present in the
        //                    IDP CRL extension and the distribution field is
        //                    present in the DP, then verify that one of the
        //                    names in the IDP matches one of the names in the
        //                    DP.
        // 5.2.5.  The identical encoding MUST be used in the distributionPoint
        //         fields of the certificate and the CRL.
        // TODO(https://crbug.com/749276): Check other name types?
        if (!cert_dp.distribution_point_fullname ||
            !ContainsExactMatchingName(
                cert_dp.distribution_point_fullname
                    ->uniform_resource_identifiers,
                distribution_point_names->uniform_resource_identifiers)) {
          return CRLRevocationStatus::UNKNOWN;
        }

        // 6.3.3. (b) (2) (i) If the distribution point name is present in the
        //                    IDP CRL extension and the distribution field is
        //                    omitted from the DP, then verify that one of the
        //                    names in the IDP matches one of the names in the
        //                    cRLIssuer field of the DP.
        // Indirect CRLs are not supported, if indirectCRL was specified,
        // ParseIssuingDistributionPoint would already have failed.
      }

      switch (only_contains_cert_type) {
        case ContainedCertsType::USER_CERTS:
          // 6.3.3. (b) (2) (ii)  If the onlyContainsUserCerts boolean is
          //                      asserted in the IDP CRL extension, verify
          //                      that the certificate does not include the
          //                      basic constraints extension with the cA
          //                      boolean asserted.
          // 5.2.5.  If either onlyContainsUserCerts or onlyContainsCACerts is
          //         set to TRUE, then the scope of the CRL MUST NOT include any
          //         version 1 or version 2 certificates.
          if ((target_cert->has_basic_constraints() &&
               target_cert->basic_constraints().is_ca) ||
              target_cert->tbs().version == CertificateVersion::V1 ||
              target_cert->tbs().version == CertificateVersion::V2) {
            return CRLRevocationStatus::UNKNOWN;
          }
          break;

        case ContainedCertsType::CA_CERTS:
          // 6.3.3. (b) (2) (iii) If the onlyContainsCACerts boolean is asserted
          //                      in the IDP CRL extension, verify that the
          //                      certificate includes the basic constraints
          //                      extension with the cA boolean asserted.
          // The version check is not done here, as the basicConstraints
          // extension is required, and could not be present unless it is a V3
          // certificate.
          if (!target_cert->has_basic_constraints() ||
              !target_cert->basic_constraints().is_ca) {
            return CRLRevocationStatus::UNKNOWN;
          }
          break;

        case ContainedCertsType::ANY_CERTS:
          //                (iv)  Verify that the onlyContainsAttributeCerts
          //                      boolean is not asserted.
          // If onlyContainsAttributeCerts was present,
          // ParseIssuingDistributionPoint would already have failed.
          break;
      }
    }

    for (const auto &ext : extensions) {
      // Fail if any unhandled critical CRL extensions are present.
      if (ext.second.critical) {
        return CRLRevocationStatus::UNKNOWN;
      }
    }
  }

  // 6.3.3 (c-e) skipped: delta CRLs and reason codes are not supported.

  // This implementation only supports direct CRLs where the CRL was signed by
  // one of the certs in its validated issuer chain. This allows handling some
  // cases of key rollover without requiring additional CRL issuer cert
  // discovery & path building.
  // TODO(https://crbug.com/749276): should this loop start at
  // |target_cert_index|? There doesn't seem to be anything in the specs that
  // precludes a CRL signed by a self-issued cert from covering itself. On the
  // other hand it seems like a pretty weird thing to allow and causes NIST
  // PKITS 4.5.3 to pass when it seems like it would not be intended to (since
  // issuingDistributionPoint CRL extension is not handled).
  for (size_t i = target_cert_index + 1; i < valid_chain.size(); ++i) {
    const ParsedCertificate *issuer_cert = valid_chain[i].get();

    // 6.3.3 (f) Obtain and validate the certification path for the issuer of
    //           the complete CRL.  The trust anchor for the certification
    //           path MUST be the same as the trust anchor used to validate
    //           the target certificate.
    //
    // As the |issuer_cert| is from the already validated chain, it is already
    // known to chain to the same trust anchor as the target certificate.
    if (der::Input(normalized_crl_issuer) !=
        issuer_cert->normalized_subject()) {
      continue;
    }

    // 6.3.3 (f) If a key usage extension is present in the CRL issuer's
    //           certificate, verify that the cRLSign bit is set.
    if (issuer_cert->has_key_usage() &&
        !issuer_cert->key_usage().AssertsBit(KEY_USAGE_BIT_CRL_SIGN)) {
      continue;
    }

    // 6.3.3 (g) Validate the signature on the complete CRL using the public
    //           key validated in step (f).
    if (!VerifySignedData(*signature_algorithm, tbs_cert_list_tlv,
                          signature_value, issuer_cert->tbs().spki_tlv,
                          /*cache=*/nullptr)) {
      continue;
    }

    // 6.3.3 (h,i) skipped. This implementation does not support delta CRLs.

    // 6.3.3 (j) If (cert_status is UNREVOKED), then search for the
    //           certificate on the complete CRL.  If an entry is found that
    //           matches the certificate issuer and serial number as described
    //           in Section 5.3.3, then set the cert_status variable to the
    //           indicated reason as described in step (i).
    //
    // CRL is valid and covers |target_cert|, check if |target_cert| is present
    // in the revokedCertificates sequence.
    return GetCRLStatusForCert(target_cert->tbs().serial_number,
                               tbs_cert_list.version,
                               tbs_cert_list.revoked_certificates_tlv);

    // 6.3.3 (k,l) skipped. This implementation does not support reason codes.
  }

  // Did not find the issuer & signer of |raw_crl| in |valid_chain|.
  return CRLRevocationStatus::UNKNOWN;
}

}  // namespace bssl
