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

#include "parse_certificate.h"

#include <gtest/gtest.h>
#include <openssl/pool.h>
#include "cert_errors.h"
#include "general_names.h"
#include "input.h"
#include "parsed_certificate.h"
#include "test_helpers.h"

BSSL_NAMESPACE_BEGIN

namespace {

// Pretty-prints a GeneralizedTime as a human-readable string for use in test
// expectations (it is more readable to specify the expected results as a
// string).
std::string ToString(const der::GeneralizedTime &time) {
  std::ostringstream pretty_time;
  pretty_time << "year=" << int{time.year} << ", month=" << int{time.month}
              << ", day=" << int{time.day} << ", hours=" << int{time.hours}
              << ", minutes=" << int{time.minutes}
              << ", seconds=" << int{time.seconds};
  return pretty_time.str();
}

std::string GetFilePath(const std::string &file_name) {
  return std::string("testdata/parse_certificate_unittest/") + file_name;
}

// Loads certificate data and expectations from the PEM file |file_name|.
// Verifies that parsing the Certificate matches expectations:
//   * If expected to fail, emits the expected errors
//   * If expected to succeeds, the parsed fields match expectations
void RunCertificateTest(const std::string &file_name) {
  std::string data;
  std::string expected_errors;
  std::string expected_tbs_certificate;
  std::string expected_signature_algorithm;
  std::string expected_signature;

  // Read the certificate data and test expectations from a single PEM file.
  const PemBlockMapping mappings[] = {
      {"CERTIFICATE", &data},
      {"ERRORS", &expected_errors, true /*optional*/},
      {"SIGNATURE", &expected_signature, true /*optional*/},
      {"SIGNATURE ALGORITHM", &expected_signature_algorithm, true /*optional*/},
      {"TBS CERTIFICATE", &expected_tbs_certificate, true /*optional*/},
  };
  std::string test_file_path = GetFilePath(file_name);
  ASSERT_TRUE(ReadTestDataFromPemFile(test_file_path, mappings));

  // Note that empty expected_errors doesn't necessarily mean success.
  bool expected_result = !expected_tbs_certificate.empty();

  // Parsing the certificate.
  der::Input tbs_certificate_tlv;
  der::Input signature_algorithm_tlv;
  der::BitString signature_value;
  CertErrors errors;
  bool actual_result =
      ParseCertificate(der::Input(data), &tbs_certificate_tlv,
                       &signature_algorithm_tlv, &signature_value, &errors);

  EXPECT_EQ(expected_result, actual_result);
  VerifyCertErrors(expected_errors, errors, test_file_path);

  // Ensure that the parsed certificate matches expectations.
  if (expected_result && actual_result) {
    EXPECT_EQ(0, signature_value.unused_bits());
    EXPECT_EQ(der::Input(expected_signature), signature_value.bytes());
    EXPECT_EQ(der::Input(expected_signature_algorithm),
              signature_algorithm_tlv);
    EXPECT_EQ(der::Input(expected_tbs_certificate), tbs_certificate_tlv);
  }
}

// Tests parsing a Certificate.
TEST(ParseCertificateTest, Version3) {
  RunCertificateTest("cert_version3.pem");
}

// Tests parsing a simplified Certificate-like structure (the sub-fields for
// algorithm and tbsCertificate are not actually valid, but ParseCertificate()
// doesn't check them)
TEST(ParseCertificateTest, Skeleton) {
  RunCertificateTest("cert_skeleton.pem");
}

// Tests parsing a Certificate that is not a sequence fails.
TEST(ParseCertificateTest, NotSequence) {
  RunCertificateTest("cert_not_sequence.pem");
}

// Tests that uncomsumed data is not allowed after the main SEQUENCE.
TEST(ParseCertificateTest, DataAfterSignature) {
  RunCertificateTest("cert_data_after_signature.pem");
}

// Tests that parsing fails if the signature BIT STRING is missing.
TEST(ParseCertificateTest, MissingSignature) {
  RunCertificateTest("cert_missing_signature.pem");
}

// Tests that parsing fails if the signature is present but not a BIT STRING.
TEST(ParseCertificateTest, SignatureNotBitString) {
  RunCertificateTest("cert_signature_not_bit_string.pem");
}

// Tests that parsing fails if the main SEQUENCE is empty (missing all the
// fields).
TEST(ParseCertificateTest, EmptySequence) {
  RunCertificateTest("cert_empty_sequence.pem");
}

// Tests what happens when the signature algorithm is present, but has the wrong
// tag.
TEST(ParseCertificateTest, AlgorithmNotSequence) {
  RunCertificateTest("cert_algorithm_not_sequence.pem");
}

// Loads tbsCertificate data and expectations from the PEM file |file_name|.
// Verifies that parsing the TBSCertificate succeeds, and each parsed field
// matches the expectations.
//
// TODO(eroman): Get rid of the |expected_version| parameter -- this should be
// encoded in the test expectations file.
void RunTbsCertificateTestGivenVersion(const std::string &file_name,
                                       CertificateVersion expected_version) {
  std::string data;
  std::string expected_serial_number;
  std::string expected_signature_algorithm;
  std::string expected_issuer;
  std::string expected_validity_not_before;
  std::string expected_validity_not_after;
  std::string expected_subject;
  std::string expected_spki;
  std::string expected_issuer_unique_id;
  std::string expected_subject_unique_id;
  std::string expected_extensions;
  std::string expected_errors;

  // Read the certificate data and test expectations from a single PEM file.
  const PemBlockMapping mappings[] = {
      {"TBS CERTIFICATE", &data},
      {"SIGNATURE ALGORITHM", &expected_signature_algorithm, true},
      {"SERIAL NUMBER", &expected_serial_number, true},
      {"ISSUER", &expected_issuer, true},
      {"VALIDITY NOTBEFORE", &expected_validity_not_before, true},
      {"VALIDITY NOTAFTER", &expected_validity_not_after, true},
      {"SUBJECT", &expected_subject, true},
      {"SPKI", &expected_spki, true},
      {"ISSUER UNIQUE ID", &expected_issuer_unique_id, true},
      {"SUBJECT UNIQUE ID", &expected_subject_unique_id, true},
      {"EXTENSIONS", &expected_extensions, true},
      {"ERRORS", &expected_errors, true},
  };
  std::string test_file_path = GetFilePath(file_name);
  ASSERT_TRUE(ReadTestDataFromPemFile(test_file_path, mappings));

  bool expected_result = !expected_spki.empty();

  ParsedTbsCertificate parsed;
  CertErrors errors;
  bool actual_result =
      ParseTbsCertificate(der::Input(data), {}, &parsed, &errors);

  EXPECT_EQ(expected_result, actual_result);
  VerifyCertErrors(expected_errors, errors, test_file_path);

  if (!expected_result || !actual_result) {
    return;
  }

  // Ensure that the ParsedTbsCertificate matches expectations.
  EXPECT_EQ(expected_version, parsed.version);

  EXPECT_EQ(der::Input(expected_serial_number), parsed.serial_number);
  EXPECT_EQ(der::Input(expected_signature_algorithm),
            parsed.signature_algorithm_tlv);

  EXPECT_EQ(der::Input(expected_issuer), parsed.issuer_tlv);

  // In the test expectations PEM file, validity is described as a
  // textual string of the parsed value (rather than as DER).
  EXPECT_EQ(expected_validity_not_before, ToString(parsed.validity_not_before));
  EXPECT_EQ(expected_validity_not_after, ToString(parsed.validity_not_after));

  EXPECT_EQ(der::Input(expected_subject), parsed.subject_tlv);
  EXPECT_EQ(der::Input(expected_spki), parsed.spki_tlv);

  EXPECT_EQ(!expected_issuer_unique_id.empty(),
            parsed.issuer_unique_id.has_value());
  if (parsed.issuer_unique_id.has_value()) {
    EXPECT_EQ(der::Input(expected_issuer_unique_id),
              parsed.issuer_unique_id->bytes());
  }
  EXPECT_EQ(!expected_subject_unique_id.empty(),
            parsed.subject_unique_id.has_value());
  if (parsed.subject_unique_id.has_value()) {
    EXPECT_EQ(der::Input(expected_subject_unique_id),
              parsed.subject_unique_id->bytes());
  }

  EXPECT_EQ(!expected_extensions.empty(), parsed.extensions_tlv.has_value());
  if (parsed.extensions_tlv) {
    EXPECT_EQ(der::Input(expected_extensions), parsed.extensions_tlv.value());
  }
}

void RunTbsCertificateTest(const std::string &file_name) {
  RunTbsCertificateTestGivenVersion(file_name, CertificateVersion::V3);
}

// Tests parsing a TBSCertificate for v3 that contains no optional fields.
TEST(ParseTbsCertificateTest, Version3NoOptionals) {
  RunTbsCertificateTest("tbs_v3_no_optionals.pem");
}

// Tests parsing a TBSCertificate for v3 that contains extensions.
TEST(ParseTbsCertificateTest, Version3WithExtensions) {
  RunTbsCertificateTest("tbs_v3_extensions.pem");
}

// Tests parsing a TBSCertificate which lacks a version number (causing it to
// default to v1).
TEST(ParseTbsCertificateTest, Version1) {
  RunTbsCertificateTestGivenVersion("tbs_v1.pem", CertificateVersion::V1);
}

// The version was set to v1 explicitly rather than omitting the version field.
TEST(ParseTbsCertificateTest, ExplicitVersion1) {
  RunTbsCertificateTest("tbs_explicit_v1.pem");
}

// Extensions are not defined in version 1.
TEST(ParseTbsCertificateTest, Version1WithExtensions) {
  RunTbsCertificateTest("tbs_v1_extensions.pem");
}

// Extensions are not defined in version 2.
TEST(ParseTbsCertificateTest, Version2WithExtensions) {
  RunTbsCertificateTest("tbs_v2_extensions.pem");
}

// A boring version 2 certificate with none of the optional fields.
TEST(ParseTbsCertificateTest, Version2NoOptionals) {
  RunTbsCertificateTestGivenVersion("tbs_v2_no_optionals.pem",
                                    CertificateVersion::V2);
}

// A version 2 certificate with an issuer unique ID field.
TEST(ParseTbsCertificateTest, Version2IssuerUniqueId) {
  RunTbsCertificateTestGivenVersion("tbs_v2_issuer_unique_id.pem",
                                    CertificateVersion::V2);
}

// A version 2 certificate with both a issuer and subject unique ID field.
TEST(ParseTbsCertificateTest, Version2IssuerAndSubjectUniqueId) {
  RunTbsCertificateTestGivenVersion("tbs_v2_issuer_and_subject_unique_id.pem",
                                    CertificateVersion::V2);
}

// A version 3 certificate with all of the optional fields (issuer unique id,
// subject unique id, and extensions).
TEST(ParseTbsCertificateTest, Version3AllOptionals) {
  RunTbsCertificateTest("tbs_v3_all_optionals.pem");
}

// The version was set to v4, which is unrecognized.
TEST(ParseTbsCertificateTest, Version4) { RunTbsCertificateTest("tbs_v4.pem"); }

// Tests that extraneous data after extensions in a v3 is rejected.
TEST(ParseTbsCertificateTest, Version3DataAfterExtensions) {
  RunTbsCertificateTest("tbs_v3_data_after_extensions.pem");
}

// Tests using a real-world certificate (whereas the other tests are fabricated
// (and in fact invalid) data.
TEST(ParseTbsCertificateTest, Version3Real) {
  RunTbsCertificateTest("tbs_v3_real.pem");
}

// Parses a TBSCertificate whose "validity" field expresses both notBefore
// and notAfter using UTCTime.
TEST(ParseTbsCertificateTest, ValidityBothUtcTime) {
  RunTbsCertificateTest("tbs_validity_both_utc_time.pem");
}

// Parses a TBSCertificate whose "validity" field expresses both notBefore
// and notAfter using GeneralizedTime.
TEST(ParseTbsCertificateTest, ValidityBothGeneralizedTime) {
  RunTbsCertificateTest("tbs_validity_both_generalized_time.pem");
}

// Parses a TBSCertificate whose "validity" field expresses notBefore using
// UTCTime and notAfter using GeneralizedTime.
TEST(ParseTbsCertificateTest, ValidityUTCTimeAndGeneralizedTime) {
  RunTbsCertificateTest("tbs_validity_utc_time_and_generalized_time.pem");
}

// Parses a TBSCertificate whose validity" field expresses notBefore using
// GeneralizedTime and notAfter using UTCTime. Also of interest, notBefore >
// notAfter. Parsing will succeed, however no time can satisfy this constraint.
TEST(ParseTbsCertificateTest, ValidityGeneralizedTimeAndUTCTime) {
  RunTbsCertificateTest("tbs_validity_generalized_time_and_utc_time.pem");
}

// Parses a TBSCertificate whose "validity" field does not strictly follow
// the DER rules (and fails to be parsed).
TEST(ParseTbsCertificateTest, ValidityRelaxed) {
  RunTbsCertificateTest("tbs_validity_relaxed.pem");
}

// Parses a KeyUsage with a single 0 bit.
TEST(ParseKeyUsageTest, OneBitAllZeros) {
  const uint8_t der[] = {
      0x03, 0x02,  // BIT STRING
      0x07,        // Number of unused bits
      0x00,        // bits
  };

  der::BitString key_usage;
  ASSERT_FALSE(ParseKeyUsage(der::Input(der), &key_usage));
}

// Parses a KeyUsage with 32 bits that are all 0.
TEST(ParseKeyUsageTest, 32BitsAllZeros) {
  const uint8_t der[] = {
      0x03, 0x05,  // BIT STRING
      0x00,        // Number of unused bits
      0x00, 0x00, 0x00, 0x00,
  };

  der::BitString key_usage;
  ASSERT_FALSE(ParseKeyUsage(der::Input(der), &key_usage));
}

// Parses a KeyUsage with 32 bits, one of which is 1 (but not in recognized
// set).
TEST(ParseKeyUsageTest, 32BitsOneSet) {
  const uint8_t der[] = {
      0x03, 0x05,  // BIT STRING
      0x00,        // Number of unused bits
      0x00, 0x00, 0x00, 0x02,
  };

  der::BitString key_usage;
  ASSERT_TRUE(ParseKeyUsage(der::Input(der), &key_usage));

  EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_DIGITAL_SIGNATURE));
  EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_NON_REPUDIATION));
  EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_KEY_ENCIPHERMENT));
  EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_DATA_ENCIPHERMENT));
  EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_KEY_AGREEMENT));
  EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN));
  EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_CRL_SIGN));
  EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_ENCIPHER_ONLY));
  EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_DECIPHER_ONLY));
}

// Parses a KeyUsage containing bit string 101.
TEST(ParseKeyUsageTest, ThreeBits) {
  const uint8_t der[] = {
      0x03, 0x02,  // BIT STRING
      0x05,        // Number of unused bits
      0xA0,        // bits
  };

  der::BitString key_usage;
  ASSERT_TRUE(ParseKeyUsage(der::Input(der), &key_usage));

  EXPECT_TRUE(key_usage.AssertsBit(KEY_USAGE_BIT_DIGITAL_SIGNATURE));
  EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_NON_REPUDIATION));
  EXPECT_TRUE(key_usage.AssertsBit(KEY_USAGE_BIT_KEY_ENCIPHERMENT));
  EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_DATA_ENCIPHERMENT));
  EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_KEY_AGREEMENT));
  EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN));
  EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_CRL_SIGN));
  EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_ENCIPHER_ONLY));
  EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_DECIPHER_ONLY));
}

// Parses a KeyUsage containing DECIPHER_ONLY, which is the
// only bit that doesn't fit in the first byte.
TEST(ParseKeyUsageTest, DecipherOnly) {
  const uint8_t der[] = {
      0x03, 0x03,  // BIT STRING
      0x07,        // Number of unused bits
      0x00, 0x80,  // bits
  };

  der::BitString key_usage;
  ASSERT_TRUE(ParseKeyUsage(der::Input(der), &key_usage));

  EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_DIGITAL_SIGNATURE));
  EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_NON_REPUDIATION));
  EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_KEY_ENCIPHERMENT));
  EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_DATA_ENCIPHERMENT));
  EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_KEY_AGREEMENT));
  EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN));
  EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_CRL_SIGN));
  EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_ENCIPHER_ONLY));
  EXPECT_TRUE(key_usage.AssertsBit(KEY_USAGE_BIT_DECIPHER_ONLY));
}

// Parses an empty KeyUsage.
TEST(ParseKeyUsageTest, Empty) {
  const uint8_t der[] = {
      0x03, 0x01,  // BIT STRING
      0x00,        // Number of unused bits
  };

  der::BitString key_usage;
  ASSERT_FALSE(ParseKeyUsage(der::Input(der), &key_usage));
}

TEST(ParseAuthorityInfoAccess, BasicTests) {
  // SEQUENCE {
  //   SEQUENCE {
  //     # ocsp with directoryName
  //     OBJECT_IDENTIFIER { 1.3.6.1.5.5.7.48.1 }
  //     [4] {
  //       SEQUENCE {
  //         SET {
  //           SEQUENCE {
  //             # commonName
  //             OBJECT_IDENTIFIER { 2.5.4.3 }
  //             PrintableString { "ocsp" }
  //           }
  //         }
  //       }
  //     }
  //   }
  //   SEQUENCE {
  //     # caIssuers with directoryName
  //     OBJECT_IDENTIFIER { 1.3.6.1.5.5.7.48.2 }
  //     [4] {
  //       SEQUENCE {
  //         SET {
  //           SEQUENCE {
  //             # commonName
  //             OBJECT_IDENTIFIER { 2.5.4.3 }
  //             PrintableString { "ca issuer" }
  //           }
  //         }
  //       }
  //     }
  //   }
  //   SEQUENCE {
  //     # non-standard method with URI
  //     OBJECT_IDENTIFIER { 1.3.6.1.5.5.7.48.3 }
  //     [6 PRIMITIVE] { "http://nonstandard.example.com" }
  //   }
  //   SEQUENCE {
  //     # ocsp with URI
  //     OBJECT_IDENTIFIER { 1.3.6.1.5.5.7.48.1 }
  //     [6 PRIMITIVE] { "http://ocsp.example.com" }
  //   }
  //   SEQUENCE {
  //     # caIssuers with URI
  //     OBJECT_IDENTIFIER { 1.3.6.1.5.5.7.48.2 }
  //     [6 PRIMITIVE] { "http://www.example.com/issuer.crt" }
  //   }
  // }
  const uint8_t der[] = {
      0x30, 0x81, 0xc3, 0x30, 0x1d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
      0x07, 0x30, 0x01, 0xa4, 0x11, 0x30, 0x0f, 0x31, 0x0d, 0x30, 0x0b, 0x06,
      0x03, 0x55, 0x04, 0x03, 0x13, 0x04, 0x6f, 0x63, 0x73, 0x70, 0x30, 0x22,
      0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0xa4, 0x16,
      0x30, 0x14, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
      0x09, 0x63, 0x61, 0x20, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x30, 0x2a,
      0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x03, 0x86, 0x1e,
      0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x6f, 0x6e, 0x73, 0x74,
      0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70,
      0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x23, 0x06, 0x08, 0x2b, 0x06,
      0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x17, 0x68, 0x74, 0x74, 0x70,
      0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x65, 0x78, 0x61, 0x6d,
      0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x2d, 0x06, 0x08, 0x2b,
      0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x21, 0x68, 0x74, 0x74,
      0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x78, 0x61, 0x6d,
      0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x73, 0x73, 0x75,
      0x65, 0x72, 0x2e, 0x63, 0x72, 0x74};

  std::vector<AuthorityInfoAccessDescription> access_descriptions;
  ASSERT_TRUE(ParseAuthorityInfoAccess(der::Input(der), &access_descriptions));
  ASSERT_EQ(5u, access_descriptions.size());
  {
    const auto &desc = access_descriptions[0];
    EXPECT_EQ(der::Input(kAdOcspOid), desc.access_method_oid);
    const uint8_t location_der[] = {0xa4, 0x11, 0x30, 0x0f, 0x31, 0x0d, 0x30,
                                    0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
                                    0x04, 0x6f, 0x63, 0x73, 0x70};
    EXPECT_EQ(der::Input(location_der), desc.access_location);
  }
  {
    const auto &desc = access_descriptions[1];
    EXPECT_EQ(der::Input(kAdCaIssuersOid), desc.access_method_oid);
    const uint8_t location_der[] = {
        0xa4, 0x16, 0x30, 0x14, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
        0x03, 0x13, 0x09, 0x63, 0x61, 0x20, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72};
    EXPECT_EQ(der::Input(location_der), desc.access_location);
  }
  {
    const auto &desc = access_descriptions[2];
    const uint8_t method_oid[] = {0x2b, 0x06, 0x01, 0x05,
                                  0x05, 0x07, 0x30, 0x03};
    EXPECT_EQ(der::Input(method_oid), desc.access_method_oid);
    const uint8_t location_der[] = {
        0x86, 0x1e, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x6f,
        0x6e, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x2e, 0x65,
        0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d};
    EXPECT_EQ(der::Input(location_der), desc.access_location);
  }
  {
    const auto &desc = access_descriptions[3];
    EXPECT_EQ(der::Input(kAdOcspOid), desc.access_method_oid);
    const uint8_t location_der[] = {0x86, 0x17, 0x68, 0x74, 0x74, 0x70, 0x3a,
                                    0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e,
                                    0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
                                    0x2e, 0x63, 0x6f, 0x6d};
    EXPECT_EQ(der::Input(location_der), desc.access_location);
  }
  {
    const auto &desc = access_descriptions[4];
    EXPECT_EQ(der::Input(kAdCaIssuersOid), desc.access_method_oid);
    const uint8_t location_der[] = {
        0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77,
        0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
        0x2f, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x2e, 0x63, 0x72, 0x74};
    EXPECT_EQ(der::Input(location_der), desc.access_location);
  }

  std::vector<std::string_view> ca_issuers_uris, ocsp_uris;
  ASSERT_TRUE(ParseAuthorityInfoAccessURIs(der::Input(der), &ca_issuers_uris,
                                           &ocsp_uris));
  ASSERT_EQ(1u, ca_issuers_uris.size());
  EXPECT_EQ("http://www.example.com/issuer.crt", ca_issuers_uris.front());
  ASSERT_EQ(1u, ocsp_uris.size());
  EXPECT_EQ("http://ocsp.example.com", ocsp_uris.front());
}

TEST(ParseAuthorityInfoAccess, NoOcspOrCaIssuersURIs) {
  // SEQUENCE {
  //   SEQUENCE {
  //     # non-standard method with directoryName
  //     OBJECT_IDENTIFIER { 1.2.3 }
  //     [4] {
  //       SEQUENCE {
  //         SET {
  //           SEQUENCE {
  //             # commonName
  //             OBJECT_IDENTIFIER { 2.5.4.3 }
  //             PrintableString { "foo" }
  //           }
  //         }
  //       }
  //     }
  //   }
  // }
  const uint8_t der[] = {0x30, 0x18, 0x30, 0x16, 0x06, 0x02, 0x2a, 0x03, 0xa4,
                         0x10, 0x30, 0x0e, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03,
                         0x55, 0x04, 0x03, 0x13, 0x03, 0x66, 0x6f, 0x6f};

  std::vector<AuthorityInfoAccessDescription> access_descriptions;
  ASSERT_TRUE(ParseAuthorityInfoAccess(der::Input(der), &access_descriptions));
  ASSERT_EQ(1u, access_descriptions.size());
  const auto &desc = access_descriptions[0];
  const uint8_t method_oid[] = {0x2a, 0x03};
  EXPECT_EQ(der::Input(method_oid), desc.access_method_oid);
  const uint8_t location_der[] = {0xa4, 0x10, 0x30, 0x0e, 0x31, 0x0c,
                                  0x30, 0x0a, 0x06, 0x03, 0x55, 0x04,
                                  0x03, 0x13, 0x03, 0x66, 0x6f, 0x6f};
  EXPECT_EQ(der::Input(location_der), desc.access_location);

  std::vector<std::string_view> ca_issuers_uris, ocsp_uris;
  // ParseAuthorityInfoAccessURIs should still return success since it was a
  // valid AuthorityInfoAccess extension, even though it did not contain any
  // elements we care about, and both output vectors should be empty.
  ASSERT_TRUE(ParseAuthorityInfoAccessURIs(der::Input(der), &ca_issuers_uris,
                                           &ocsp_uris));
  EXPECT_EQ(0u, ca_issuers_uris.size());
  EXPECT_EQ(0u, ocsp_uris.size());
}

TEST(ParseAuthorityInfoAccess, IncompleteAccessDescription) {
  // SEQUENCE {
  //   # first entry is ok
  //   SEQUENCE {
  //     OBJECT_IDENTIFIER { 1.3.6.1.5.5.7.48.1 }
  //     [6 PRIMITIVE] { "http://ocsp.example.com" }
  //   }
  //   # second is missing accessLocation field
  //   SEQUENCE {
  //     OBJECT_IDENTIFIER { 1.3.6.1.5.5.7.48.2 }
  //   }
  // }
  const uint8_t der[] = {0x30, 0x31, 0x30, 0x23, 0x06, 0x08, 0x2b, 0x06, 0x01,
                         0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x17, 0x68, 0x74,
                         0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70,
                         0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e,
                         0x63, 0x6f, 0x6d, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06,
                         0x01, 0x05, 0x05, 0x07, 0x30, 0x02};

  std::vector<AuthorityInfoAccessDescription> access_descriptions;
  EXPECT_FALSE(ParseAuthorityInfoAccess(der::Input(der), &access_descriptions));

  std::vector<std::string_view> ca_issuers_uris, ocsp_uris;
  EXPECT_FALSE(ParseAuthorityInfoAccessURIs(der::Input(der), &ca_issuers_uris,
                                            &ocsp_uris));
}

TEST(ParseAuthorityInfoAccess, ExtraDataInAccessDescription) {
  // SEQUENCE {
  //   SEQUENCE {
  //     OBJECT_IDENTIFIER { 1.3.6.1.5.5.7.48.1 }
  //     [6 PRIMITIVE] { "http://ocsp.example.com" }
  //     # invalid, AccessDescription only has 2 fields
  //     PrintableString { "henlo" }
  //   }
  // }
  const uint8_t der[] = {
      0x30, 0x2c, 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
      0x30, 0x01, 0x86, 0x17, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f,
      0x63, 0x73, 0x70, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e,
      0x63, 0x6f, 0x6d, 0x13, 0x05, 0x68, 0x65, 0x6e, 0x6c, 0x6f};

  std::vector<AuthorityInfoAccessDescription> access_descriptions;
  EXPECT_FALSE(ParseAuthorityInfoAccess(der::Input(der), &access_descriptions));

  std::vector<std::string_view> ca_issuers_uris, ocsp_uris;
  EXPECT_FALSE(ParseAuthorityInfoAccessURIs(der::Input(der), &ca_issuers_uris,
                                            &ocsp_uris));
}

TEST(ParseAuthorityInfoAccess, EmptySequence) {
  // SEQUENCE { }
  const uint8_t der[] = {0x30, 0x00};

  std::vector<AuthorityInfoAccessDescription> access_descriptions;
  EXPECT_FALSE(ParseAuthorityInfoAccess(der::Input(der), &access_descriptions));

  std::vector<std::string_view> ca_issuers_uris, ocsp_uris;
  EXPECT_FALSE(ParseAuthorityInfoAccessURIs(der::Input(der), &ca_issuers_uris,
                                            &ocsp_uris));
}

// Test fixture for testing ParseCrlDistributionPoints.
//
// Test data is encoded in certificate files. This fixture is responsible for
// reading and parsing the certificates to get at the extension under test.
class ParseCrlDistributionPointsTest : public ::testing::Test {
 public:
 protected:
  bool GetCrlDps(const char *file_name,
                 std::vector<ParsedDistributionPoint> *dps) {
    std::string cert_bytes;
    // Read the test certificate file.
    const PemBlockMapping mappings[] = {
        {"CERTIFICATE", &cert_bytes},
    };
    std::string test_file_path = GetFilePath(file_name);
    EXPECT_TRUE(ReadTestDataFromPemFile(test_file_path, mappings));

    // Extract the CRLDP from the test Certificate.
    CertErrors errors;
    std::shared_ptr<const ParsedCertificate> cert = ParsedCertificate::Create(
        bssl::UniquePtr<CRYPTO_BUFFER>(CRYPTO_BUFFER_new(
            reinterpret_cast<const uint8_t *>(cert_bytes.data()),
            cert_bytes.size(), nullptr)),
        {}, &errors);

    if (!cert) {
      return false;
    }

    auto it = cert->extensions().find(der::Input(kCrlDistributionPointsOid));
    if (it == cert->extensions().end()) {
      return false;
    }

    der::Input crl_dp_tlv = it->second.value;

    // Keep the certificate data alive, since this function will return
    // der::Inputs that reference it. Run the function under test (for parsing
    //
    // TODO(eroman): The use of ParsedCertificate in this test should be removed
    // in lieu of lazy parsing.
    keep_alive_certs_.push_back(cert);

    return ParseCrlDistributionPoints(crl_dp_tlv, dps);
  }

 private:
  ParsedCertificateList keep_alive_certs_;
};

TEST_F(ParseCrlDistributionPointsTest, OneUriNoIssuer) {
  std::vector<ParsedDistributionPoint> dps;
  ASSERT_TRUE(GetCrlDps("crldp_1uri_noissuer.pem", &dps));

  ASSERT_EQ(1u, dps.size());
  const ParsedDistributionPoint &dp1 = dps.front();

  ASSERT_TRUE(dp1.distribution_point_fullname);
  const GeneralNames &fullname = *dp1.distribution_point_fullname;
  EXPECT_EQ(GENERAL_NAME_UNIFORM_RESOURCE_IDENTIFIER,
            fullname.present_name_types);
  ASSERT_EQ(1u, fullname.uniform_resource_identifiers.size());
  EXPECT_EQ(fullname.uniform_resource_identifiers.front(),
            std::string("http://www.example.com/foo.crl"));

  EXPECT_FALSE(dp1.distribution_point_name_relative_to_crl_issuer);
  EXPECT_FALSE(dp1.reasons);
  EXPECT_FALSE(dp1.crl_issuer);
}

TEST_F(ParseCrlDistributionPointsTest, ThreeUrisNoIssuer) {
  std::vector<ParsedDistributionPoint> dps;
  ASSERT_TRUE(GetCrlDps("crldp_3uri_noissuer.pem", &dps));

  ASSERT_EQ(1u, dps.size());
  const ParsedDistributionPoint &dp1 = dps.front();

  ASSERT_TRUE(dp1.distribution_point_fullname);
  const GeneralNames &fullname = *dp1.distribution_point_fullname;
  EXPECT_EQ(GENERAL_NAME_UNIFORM_RESOURCE_IDENTIFIER,
            fullname.present_name_types);
  ASSERT_EQ(3u, fullname.uniform_resource_identifiers.size());
  EXPECT_EQ(fullname.uniform_resource_identifiers[0],
            std::string("http://www.example.com/foo1.crl"));
  EXPECT_EQ(fullname.uniform_resource_identifiers[1],
            std::string("http://www.example.com/blah.crl"));
  EXPECT_EQ(fullname.uniform_resource_identifiers[2],
            std::string("not-even-a-url"));

  EXPECT_FALSE(dp1.distribution_point_name_relative_to_crl_issuer);
  EXPECT_FALSE(dp1.reasons);
  EXPECT_FALSE(dp1.crl_issuer);
}

TEST_F(ParseCrlDistributionPointsTest, CrlIssuerAsDirname) {
  std::vector<ParsedDistributionPoint> dps;
  ASSERT_TRUE(GetCrlDps("crldp_issuer_as_dirname.pem", &dps));

  ASSERT_EQ(1u, dps.size());
  const ParsedDistributionPoint &dp1 = dps.front();
  ASSERT_TRUE(dp1.distribution_point_fullname);
  const GeneralNames &fullname = *dp1.distribution_point_fullname;
  EXPECT_EQ(GENERAL_NAME_DIRECTORY_NAME, fullname.present_name_types);
  // Generated by `ascii2der | xxd -i` from the Name value in
  // crldp_issuer_as_dirname.pem.
  const uint8_t kExpectedName[] = {
      0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
      0x53, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x16,
      0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
      0x63, 0x61, 0x74, 0x65, 0x73, 0x20, 0x32, 0x30, 0x31, 0x31, 0x31, 0x22,
      0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x19, 0x69, 0x6e, 0x64,
      0x69, 0x72, 0x65, 0x63, 0x74, 0x43, 0x52, 0x4c, 0x20, 0x43, 0x41, 0x33,
      0x20, 0x63, 0x52, 0x4c, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x31, 0x29,
      0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x20, 0x69, 0x6e, 0x64,
      0x69, 0x72, 0x65, 0x63, 0x74, 0x20, 0x43, 0x52, 0x4c, 0x20, 0x66, 0x6f,
      0x72, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x43, 0x52,
      0x4c, 0x20, 0x43, 0x41, 0x33};
  ASSERT_EQ(1u, fullname.directory_names.size());
  EXPECT_EQ(der::Input(kExpectedName), fullname.directory_names[0]);

  EXPECT_FALSE(dp1.distribution_point_name_relative_to_crl_issuer);
  EXPECT_FALSE(dp1.reasons);

  ASSERT_TRUE(dp1.crl_issuer);
  // Generated by `ascii2der | xxd -i` from the cRLIssuer value in
  // crldp_issuer_as_dirname.pem.
  const uint8_t kExpectedCrlIssuer[] = {
      0xa4, 0x54, 0x30, 0x52, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
      0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x1f, 0x30, 0x1d, 0x06,
      0x03, 0x55, 0x04, 0x0a, 0x13, 0x16, 0x54, 0x65, 0x73, 0x74, 0x20,
      0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65,
      0x73, 0x20, 0x32, 0x30, 0x31, 0x31, 0x31, 0x22, 0x30, 0x20, 0x06,
      0x03, 0x55, 0x04, 0x0b, 0x13, 0x19, 0x69, 0x6e, 0x64, 0x69, 0x72,
      0x65, 0x63, 0x74, 0x43, 0x52, 0x4c, 0x20, 0x43, 0x41, 0x33, 0x20,
      0x63, 0x52, 0x4c, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72};
  EXPECT_EQ(der::Input(kExpectedCrlIssuer), dp1.crl_issuer);
}

TEST_F(ParseCrlDistributionPointsTest, FullnameAsDirname) {
  std::vector<ParsedDistributionPoint> dps;
  ASSERT_TRUE(GetCrlDps("crldp_full_name_as_dirname.pem", &dps));

  ASSERT_EQ(1u, dps.size());
  const ParsedDistributionPoint &dp1 = dps.front();

  ASSERT_TRUE(dp1.distribution_point_fullname);
  const GeneralNames &fullname = *dp1.distribution_point_fullname;
  EXPECT_EQ(GENERAL_NAME_DIRECTORY_NAME, fullname.present_name_types);
  // Generated by `ascii2der | xxd -i` from the Name value in
  // crldp_full_name_as_dirname.pem.
  const uint8_t kExpectedName[] = {
      0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
      0x53, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x16,
      0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
      0x63, 0x61, 0x74, 0x65, 0x73, 0x20, 0x32, 0x30, 0x31, 0x31, 0x31, 0x45,
      0x30, 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x53, 0x65, 0x6c,
      0x66, 0x2d, 0x49, 0x73, 0x73, 0x75, 0x65, 0x64, 0x20, 0x43, 0x65, 0x72,
      0x74, 0x20, 0x44, 0x50, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x42, 0x61, 0x73,
      0x69, 0x63, 0x20, 0x53, 0x65, 0x6c, 0x66, 0x2d, 0x49, 0x73, 0x73, 0x75,
      0x65, 0x64, 0x20, 0x43, 0x52, 0x4c, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69,
      0x6e, 0x67, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x43, 0x41};
  ASSERT_EQ(1u, fullname.directory_names.size());
  EXPECT_EQ(der::Input(kExpectedName), fullname.directory_names[0]);

  EXPECT_FALSE(dp1.distribution_point_name_relative_to_crl_issuer);
  EXPECT_FALSE(dp1.reasons);
  EXPECT_FALSE(dp1.crl_issuer);
}

TEST_F(ParseCrlDistributionPointsTest, RelativeNameAndReasonsAndMultipleDPs) {
  // SEQUENCE {
  //   SEQUENCE {
  //     # distributionPoint
  //     [0] {
  //       # nameRelativeToCRLIssuer
  //       [1] {
  //         SET {
  //           SEQUENCE {
  //             # commonName
  //             OBJECT_IDENTIFIER { 2.5.4.3 }
  //             PrintableString { "CRL1" }
  //           }
  //         }
  //       }
  //     }
  //     # reasons
  //     [1 PRIMITIVE] { b`011` }
  //   }
  //   SEQUENCE {
  //     # distributionPoint
  //     [0] {
  //       # fullName
  //       [0] {
  //         [4] {
  //           SEQUENCE {
  //             SET {
  //               SEQUENCE {
  //                 # commonName
  //                 OBJECT_IDENTIFIER { 2.5.4.3 }
  //                 PrintableString { "CRL2" }
  //               }
  //             }
  //           }
  //         }
  //       }
  //     }
  //     # reasons
  //     [1 PRIMITIVE] { b`100111111` }
  //   }
  // }
  const uint8_t kInputDer[] = {
      0x30, 0x37, 0x30, 0x17, 0xa0, 0x11, 0xa1, 0x0f, 0x31, 0x0d, 0x30, 0x0b,
      0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x04, 0x43, 0x52, 0x4c, 0x31, 0x81,
      0x02, 0x05, 0x60, 0x30, 0x1c, 0xa0, 0x15, 0xa0, 0x13, 0xa4, 0x11, 0x30,
      0x0f, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x04,
      0x43, 0x52, 0x4c, 0x32, 0x81, 0x03, 0x07, 0x9f, 0x80};

  std::vector<ParsedDistributionPoint> dps;
  ASSERT_TRUE(ParseCrlDistributionPoints(der::Input(kInputDer), &dps));
  ASSERT_EQ(2u, dps.size());
  {
    const ParsedDistributionPoint &dp = dps[0];
    EXPECT_FALSE(dp.distribution_point_fullname);

    ASSERT_TRUE(dp.distribution_point_name_relative_to_crl_issuer);
    // SET {
    //   SEQUENCE {
    //     # commonName
    //     OBJECT_IDENTIFIER { 2.5.4.3 }
    //     PrintableString { "CRL1" }
    //   }
    // }
    const uint8_t kExpectedRDN[] = {0x31, 0x0d, 0x30, 0x0b, 0x06,
                                    0x03, 0x55, 0x04, 0x03, 0x13,
                                    0x04, 0x43, 0x52, 0x4c, 0x31};
    EXPECT_EQ(der::Input(kExpectedRDN),
              *dp.distribution_point_name_relative_to_crl_issuer);

    ASSERT_TRUE(dp.reasons);
    const uint8_t kExpectedReasons[] = {0x05, 0x60};
    EXPECT_EQ(der::Input(kExpectedReasons), *dp.reasons);

    EXPECT_FALSE(dp.crl_issuer);
  }
  {
    const ParsedDistributionPoint &dp = dps[1];
    ASSERT_TRUE(dp.distribution_point_fullname);
    const GeneralNames &fullname = *dp.distribution_point_fullname;
    EXPECT_EQ(GENERAL_NAME_DIRECTORY_NAME, fullname.present_name_types);
    // SET {
    //   SEQUENCE {
    //     # commonName
    //     OBJECT_IDENTIFIER { 2.5.4.3 }
    //     PrintableString { "CRL2" }
    //   }
    // }
    const uint8_t kExpectedName[] = {0x31, 0x0d, 0x30, 0x0b, 0x06,
                                     0x03, 0x55, 0x04, 0x03, 0x13,
                                     0x04, 0x43, 0x52, 0x4c, 0x32};
    ASSERT_EQ(1u, fullname.directory_names.size());
    EXPECT_EQ(der::Input(kExpectedName), fullname.directory_names[0]);

    EXPECT_FALSE(dp.distribution_point_name_relative_to_crl_issuer);

    ASSERT_TRUE(dp.reasons);
    const uint8_t kExpectedReasons[] = {0x07, 0x9f, 0x80};
    EXPECT_EQ(der::Input(kExpectedReasons), *dp.reasons);

    EXPECT_FALSE(dp.crl_issuer);
  }
}

TEST_F(ParseCrlDistributionPointsTest, NoDistributionPointName) {
  // SEQUENCE {
  //   SEQUENCE {
  //     # cRLIssuer
  //     [2] {
  //       [4] {
  //         SEQUENCE {
  //           SET {
  //             SEQUENCE {
  //               # organizationUnitName
  //               OBJECT_IDENTIFIER { 2.5.4.11 }
  //               PrintableString { "crl issuer" }
  //             }
  //           }
  //         }
  //       }
  //     }
  //   }
  // }
  const uint8_t kInputDer[] = {0x30, 0x1d, 0x30, 0x1b, 0xa2, 0x19, 0xa4, 0x17,
                               0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
                               0x55, 0x04, 0x0b, 0x13, 0x0a, 0x63, 0x72, 0x6c,
                               0x20, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72};

  std::vector<ParsedDistributionPoint> dps;
  ASSERT_TRUE(ParseCrlDistributionPoints(der::Input(kInputDer), &dps));
  ASSERT_EQ(1u, dps.size());
  const ParsedDistributionPoint &dp = dps[0];
  EXPECT_FALSE(dp.distribution_point_fullname);

  EXPECT_FALSE(dp.distribution_point_name_relative_to_crl_issuer);

  EXPECT_FALSE(dp.reasons);

  ASSERT_TRUE(dp.crl_issuer);
  const uint8_t kExpectedDer[] = {0xa4, 0x17, 0x30, 0x15, 0x31, 0x13, 0x30,
                                  0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
                                  0x0a, 0x63, 0x72, 0x6c, 0x20, 0x69, 0x73,
                                  0x73, 0x75, 0x65, 0x72};
  EXPECT_EQ(der::Input(kExpectedDer), *dp.crl_issuer);
}

TEST_F(ParseCrlDistributionPointsTest, OnlyReasons) {
  // SEQUENCE {
  //   SEQUENCE {
  //     # reasons
  //     [1 PRIMITIVE] { b`011` }
  //   }
  // }
  const uint8_t kInputDer[] = {0x30, 0x06, 0x30, 0x04, 0x81, 0x02, 0x05, 0x60};

  std::vector<ParsedDistributionPoint> dps;
  EXPECT_FALSE(ParseCrlDistributionPoints(der::Input(kInputDer), &dps));
}

TEST_F(ParseCrlDistributionPointsTest, EmptyDistributionPoint) {
  // SEQUENCE {
  //   SEQUENCE {
  //   }
  // }
  const uint8_t kInputDer[] = {0x30, 0x02, 0x30, 0x00};

  std::vector<ParsedDistributionPoint> dps;
  EXPECT_FALSE(ParseCrlDistributionPoints(der::Input(kInputDer), &dps));
}

TEST_F(ParseCrlDistributionPointsTest, EmptyDistributionPoints) {
  // SEQUENCE { }
  const uint8_t kInputDer[] = {0x30, 0x00};

  std::vector<ParsedDistributionPoint> dps;
  EXPECT_FALSE(ParseCrlDistributionPoints(der::Input(kInputDer), &dps));
}

bool ParseAuthorityKeyIdentifierTestData(
    const char *file_name, std::string *backing_bytes,
    ParsedAuthorityKeyIdentifier *authority_key_identifier) {
  // Read the test file.
  const PemBlockMapping mappings[] = {
      {"AUTHORITY_KEY_IDENTIFIER", backing_bytes},
  };
  std::string test_file_path =
      std::string(
          "testdata/parse_certificate_unittest/authority_key_identifier/") +
      file_name;
  EXPECT_TRUE(ReadTestDataFromPemFile(test_file_path, mappings));

  return ParseAuthorityKeyIdentifier(der::Input(*backing_bytes),
                                     authority_key_identifier);
}

TEST(ParseAuthorityKeyIdentifierTest, EmptyInput) {
  ParsedAuthorityKeyIdentifier authority_key_identifier;
  EXPECT_FALSE(
      ParseAuthorityKeyIdentifier(der::Input(), &authority_key_identifier));
}

TEST(ParseAuthorityKeyIdentifierTest, EmptySequence) {
  std::string backing_bytes;
  ParsedAuthorityKeyIdentifier authority_key_identifier;
  // TODO(mattm): should this be an error? RFC 5280 doesn't explicitly say it.
  ASSERT_TRUE(ParseAuthorityKeyIdentifierTestData(
      "empty_sequence.pem", &backing_bytes, &authority_key_identifier));

  EXPECT_FALSE(authority_key_identifier.key_identifier);
  EXPECT_FALSE(authority_key_identifier.authority_cert_issuer);
  EXPECT_FALSE(authority_key_identifier.authority_cert_serial_number);
}

TEST(ParseAuthorityKeyIdentifierTest, KeyIdentifier) {
  std::string backing_bytes;
  ParsedAuthorityKeyIdentifier authority_key_identifier;
  ASSERT_TRUE(ParseAuthorityKeyIdentifierTestData(
      "key_identifier.pem", &backing_bytes, &authority_key_identifier));

  ASSERT_TRUE(authority_key_identifier.key_identifier);
  const uint8_t kExpectedValue[] = {0xDE, 0xAD, 0xB0, 0x0F};
  EXPECT_EQ(der::Input(kExpectedValue),
            authority_key_identifier.key_identifier);
}

TEST(ParseAuthorityKeyIdentifierTest, IssuerAndSerial) {
  std::string backing_bytes;
  ParsedAuthorityKeyIdentifier authority_key_identifier;
  ASSERT_TRUE(ParseAuthorityKeyIdentifierTestData(
      "issuer_and_serial.pem", &backing_bytes, &authority_key_identifier));

  EXPECT_FALSE(authority_key_identifier.key_identifier);

  ASSERT_TRUE(authority_key_identifier.authority_cert_issuer);
  const uint8_t kExpectedIssuer[] = {0xa4, 0x11, 0x30, 0x0f, 0x31, 0x0d, 0x30,
                                     0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
                                     0x04, 0x52, 0x6f, 0x6f, 0x74};
  EXPECT_EQ(der::Input(kExpectedIssuer),
            authority_key_identifier.authority_cert_issuer);

  ASSERT_TRUE(authority_key_identifier.authority_cert_serial_number);
  const uint8_t kExpectedSerial[] = {0x27, 0x4F};
  EXPECT_EQ(der::Input(kExpectedSerial),
            authority_key_identifier.authority_cert_serial_number);
}

TEST(ParseAuthorityKeyIdentifierTest, KeyIdentifierAndIssuerAndSerial) {
  std::string backing_bytes;
  ParsedAuthorityKeyIdentifier authority_key_identifier;
  ASSERT_TRUE(ParseAuthorityKeyIdentifierTestData(
      "key_identifier_and_issuer_and_serial.pem", &backing_bytes,
      &authority_key_identifier));

  ASSERT_TRUE(authority_key_identifier.key_identifier);
  const uint8_t kExpectedValue[] = {0xDE, 0xAD, 0xB0, 0x0F};
  EXPECT_EQ(der::Input(kExpectedValue),
            authority_key_identifier.key_identifier);

  ASSERT_TRUE(authority_key_identifier.authority_cert_issuer);
  const uint8_t kExpectedIssuer[] = {0xa4, 0x11, 0x30, 0x0f, 0x31, 0x0d, 0x30,
                                     0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
                                     0x04, 0x52, 0x6f, 0x6f, 0x74};
  EXPECT_EQ(der::Input(kExpectedIssuer),
            authority_key_identifier.authority_cert_issuer);

  ASSERT_TRUE(authority_key_identifier.authority_cert_serial_number);
  const uint8_t kExpectedSerial[] = {0x27, 0x4F};
  EXPECT_EQ(der::Input(kExpectedSerial),
            authority_key_identifier.authority_cert_serial_number);
}

TEST(ParseAuthorityKeyIdentifierTest, IssuerOnly) {
  std::string backing_bytes;
  ParsedAuthorityKeyIdentifier authority_key_identifier;
  EXPECT_FALSE(ParseAuthorityKeyIdentifierTestData(
      "issuer_only.pem", &backing_bytes, &authority_key_identifier));
}

TEST(ParseAuthorityKeyIdentifierTest, SerialOnly) {
  std::string backing_bytes;
  ParsedAuthorityKeyIdentifier authority_key_identifier;
  EXPECT_FALSE(ParseAuthorityKeyIdentifierTestData(
      "serial_only.pem", &backing_bytes, &authority_key_identifier));
}

TEST(ParseAuthorityKeyIdentifierTest, InvalidContents) {
  std::string backing_bytes;
  ParsedAuthorityKeyIdentifier authority_key_identifier;
  EXPECT_FALSE(ParseAuthorityKeyIdentifierTestData(
      "invalid_contents.pem", &backing_bytes, &authority_key_identifier));
}

TEST(ParseAuthorityKeyIdentifierTest, InvalidKeyIdentifier) {
  std::string backing_bytes;
  ParsedAuthorityKeyIdentifier authority_key_identifier;
  EXPECT_FALSE(ParseAuthorityKeyIdentifierTestData(
      "invalid_key_identifier.pem", &backing_bytes, &authority_key_identifier));
}

TEST(ParseAuthorityKeyIdentifierTest, InvalidIssuer) {
  std::string backing_bytes;
  ParsedAuthorityKeyIdentifier authority_key_identifier;
  EXPECT_FALSE(ParseAuthorityKeyIdentifierTestData(
      "invalid_issuer.pem", &backing_bytes, &authority_key_identifier));
}

TEST(ParseAuthorityKeyIdentifierTest, InvalidSerial) {
  std::string backing_bytes;
  ParsedAuthorityKeyIdentifier authority_key_identifier;
  EXPECT_FALSE(ParseAuthorityKeyIdentifierTestData(
      "invalid_serial.pem", &backing_bytes, &authority_key_identifier));
}

TEST(ParseAuthorityKeyIdentifierTest, ExtraContentsAfterIssuerAndSerial) {
  std::string backing_bytes;
  ParsedAuthorityKeyIdentifier authority_key_identifier;
  EXPECT_FALSE(ParseAuthorityKeyIdentifierTestData(
      "extra_contents_after_issuer_and_serial.pem", &backing_bytes,
      &authority_key_identifier));
}

TEST(ParseAuthorityKeyIdentifierTest, ExtraContentsAfterExtensionSequence) {
  std::string backing_bytes;
  ParsedAuthorityKeyIdentifier authority_key_identifier;
  EXPECT_FALSE(ParseAuthorityKeyIdentifierTestData(
      "extra_contents_after_extension_sequence.pem", &backing_bytes,
      &authority_key_identifier));
}

TEST(ParseSubjectKeyIdentifierTest, EmptyInput) {
  der::Input subject_key_identifier;
  EXPECT_FALSE(
      ParseSubjectKeyIdentifier(der::Input(), &subject_key_identifier));
}

TEST(ParseSubjectKeyIdentifierTest, Valid) {
  // OCTET_STRING {`abcd`}
  const uint8_t kInput[] = {0x04, 0x02, 0xab, 0xcd};
  const uint8_t kExpected[] = {0xab, 0xcd};
  der::Input subject_key_identifier;
  EXPECT_TRUE(
      ParseSubjectKeyIdentifier(der::Input(kInput), &subject_key_identifier));
  EXPECT_EQ(der::Input(kExpected), subject_key_identifier);
}

TEST(ParseSubjectKeyIdentifierTest, ExtraData) {
  // OCTET_STRING {`abcd`}
  // NULL
  const uint8_t kInput[] = {0x04, 0x02, 0xab, 0xcd, 0x05};
  der::Input subject_key_identifier;
  EXPECT_FALSE(
      ParseSubjectKeyIdentifier(der::Input(kInput), &subject_key_identifier));
}

}  // namespace

BSSL_NAMESPACE_END
