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

BSSL_NAMESPACE_BEGIN

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;
}

BSSL_NAMESPACE_END
