Sync pki to chromium aef592bb1b83f019c8342bbc2c476758ccb6098d

Adds general_names and crl unittests to pki tests, with
associated data files for crl unittest.

Bug: chromium:1322914

Change-Id: Idda8e4a98ef3744a76717db32628db554c12e415
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/61965
Auto-Submit: Bob Beck <bbe@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/pki/IMPORT b/pki/IMPORT
index 0a0b84f..0ec1b31 100755
--- a/pki/IMPORT
+++ b/pki/IMPORT
@@ -14,6 +14,7 @@
     certificate_policies_unittest \
     name_constraints_unittest \
     ocsp_unittest \
+    crl_unittest \
     parse_certificate_unittest \
     path_builder_unittest \
     verify_certificate_chain_unittest \
diff --git a/pki/crl_getcrlstatusforcert_fuzzer.cc b/pki/crl_getcrlstatusforcert_fuzzer.cc
new file mode 100644
index 0000000..9f0fd14
--- /dev/null
+++ b/pki/crl_getcrlstatusforcert_fuzzer.cc
@@ -0,0 +1,29 @@
+// 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 <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "crl.h"
+#include "input.h"
+#include <openssl/sha.h>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  const bssl::der::Input input_der(data, size);
+
+  uint8_t data_hash[SHA256_DIGEST_LENGTH];
+  SHA256(data, size, data_hash);
+  const net::CrlVersion crl_version =
+      (data_hash[0] % 2) ? net::CrlVersion::V2 : net::CrlVersion::V1;
+  const size_t serial_len = data_hash[1] % (sizeof(data_hash) - 2);
+  assert(serial_len + 2 < sizeof(data_hash));
+  const bssl::der::Input cert_serial(
+      reinterpret_cast<const uint8_t*>(data_hash + 2), serial_len);
+
+  net::GetCRLStatusForCert(cert_serial, crl_version,
+                           std::make_optional(input_der));
+
+  return 0;
+}
diff --git a/pki/crl_parse_crl_certificatelist_fuzzer.cc b/pki/crl_parse_crl_certificatelist_fuzzer.cc
new file mode 100644
index 0000000..2c6c571
--- /dev/null
+++ b/pki/crl_parse_crl_certificatelist_fuzzer.cc
@@ -0,0 +1,24 @@
+// 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 <stddef.h>
+#include <stdint.h>
+
+#include <tuple>
+
+#include "crl.h"
+#include "input.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  bssl::der::Input crl_der(data, size);
+
+  bssl::der::Input tbs_cert_list_tlv;
+  bssl::der::Input signature_algorithm_tlv;
+  bssl::der::BitString signature_value;
+
+  std::ignore = net::ParseCrlCertificateList(
+      crl_der, &tbs_cert_list_tlv, &signature_algorithm_tlv, &signature_value);
+
+  return 0;
+}
diff --git a/pki/crl_parse_crl_tbscertlist_fuzzer.cc b/pki/crl_parse_crl_tbscertlist_fuzzer.cc
new file mode 100644
index 0000000..dae0ea6
--- /dev/null
+++ b/pki/crl_parse_crl_tbscertlist_fuzzer.cc
@@ -0,0 +1,20 @@
+// 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 <stddef.h>
+#include <stdint.h>
+
+#include <tuple>
+
+#include "crl.h"
+#include "input.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  bssl::der::Input input_der(data, size);
+
+  net::ParsedCrlTbsCertList tbs_cert_list;
+  std::ignore = net::ParseCrlTbsCertList(input_der, &tbs_cert_list);
+
+  return 0;
+}
diff --git a/pki/crl_parse_issuing_distribution_point_fuzzer.cc b/pki/crl_parse_issuing_distribution_point_fuzzer.cc
new file mode 100644
index 0000000..d262c6c
--- /dev/null
+++ b/pki/crl_parse_issuing_distribution_point_fuzzer.cc
@@ -0,0 +1,29 @@
+// 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 <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "crl.h"
+#include "input.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  bssl::der::Input idp_der(data, size);
+
+  std::unique_ptr<net::GeneralNames> distribution_point_names;
+  net::ContainedCertsType only_contains_cert_type;
+
+  if (net::ParseIssuingDistributionPoint(idp_der, &distribution_point_names,
+                                         &only_contains_cert_type)) {
+    bool has_distribution_point_names =
+        distribution_point_names &&
+        distribution_point_names->present_name_types != net::GENERAL_NAME_NONE;
+    if (!has_distribution_point_names &&
+        only_contains_cert_type == net::ContainedCertsType::ANY_CERTS) {
+      abort();
+    }
+  }
+  return 0;
+}
diff --git a/pki/crl_unittest.cc b/pki/crl_unittest.cc
new file mode 100644
index 0000000..a2479d4
--- /dev/null
+++ b/pki/crl_unittest.cc
@@ -0,0 +1,209 @@
+// 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 "crl.h"
+
+#include <string_view>
+
+#include "cert_errors.h"
+#include "parsed_certificate.h"
+#include "string_util.h"
+#include "test_helpers.h"
+#include <gtest/gtest.h>
+#include <openssl/pool.h>
+
+namespace bssl {
+
+namespace {
+
+constexpr int64_t kAgeOneWeek = 7 * 24 * 60 * 60;
+
+std::string GetFilePath(std::string_view file_name) {
+  return std::string("testdata/crl_unittest/") + std::string(file_name);
+}
+
+std::shared_ptr<const ParsedCertificate> ParseCertificate(
+    std::string_view data) {
+  CertErrors errors;
+  return ParsedCertificate::Create(
+      bssl::UniquePtr<CRYPTO_BUFFER>(CRYPTO_BUFFER_new(
+          reinterpret_cast<const uint8_t*>(data.data()), data.size(), nullptr)),
+      {}, &errors);
+}
+
+class CheckCRLTest : public ::testing::TestWithParam<const char*> {};
+
+// Test prefix naming scheme:
+//   good = valid CRL, cert affirmatively not revoked
+//   revoked = valid CRL, cert affirmatively revoked
+//   bad = valid CRL, but cert status is unknown (cases like unhandled features,
+//           mismatching issuer or signature, etc)
+//   invalid = corrupt or violates some spec requirement
+constexpr char const* kTestParams[] = {
+    "good.pem",
+    "good_issuer_name_normalization.pem",
+    "good_issuer_no_keyusage.pem",
+    "good_no_nextupdate.pem",
+    "good_fake_extension.pem",
+    "good_fake_extension_no_nextupdate.pem",
+    "good_generalizedtime.pem",
+    "good_no_version.pem",
+    "good_no_crldp.pem",
+    "good_key_rollover.pem",
+    "good_idp_contains_uri.pem",
+    "good_idp_onlycontainsusercerts.pem",
+    "good_idp_onlycontainsusercerts_no_basic_constraints.pem",
+    "good_idp_onlycontainscacerts.pem",
+    "good_idp_uri_and_onlycontainsusercerts.pem",
+    "good_idp_uri_and_onlycontainscacerts.pem",
+    "revoked.pem",
+    "revoked_no_nextupdate.pem",
+    "revoked_fake_crlentryextension.pem",
+    "revoked_generalized_revocationdate.pem",
+    "revoked_key_rollover.pem",
+    "bad_crldp_has_crlissuer.pem",
+    "bad_fake_critical_extension.pem",
+    "bad_fake_critical_crlentryextension.pem",
+    "bad_signature.pem",
+    "bad_thisupdate_in_future.pem",
+    "bad_thisupdate_too_old.pem",
+    "bad_nextupdate_too_old.pem",
+    "bad_wrong_issuer.pem",
+    "bad_key_rollover_signature.pem",
+    "bad_idp_contains_wrong_uri.pem",
+    "bad_idp_indirectcrl.pem",
+    "bad_idp_onlycontainsusercerts.pem",
+    "bad_idp_onlycontainscacerts.pem",
+    "bad_idp_onlycontainscacerts_no_basic_constraints.pem",
+    "bad_idp_uri_and_onlycontainsusercerts.pem",
+    "bad_idp_uri_and_onlycontainscacerts.pem",
+    "invalid_mismatched_signature_algorithm.pem",
+    "invalid_revoked_empty_sequence.pem",
+    "invalid_v1_with_extension.pem",
+    "invalid_v1_with_crlentryextension.pem",
+    "invalid_v1_explicit.pem",
+    "invalid_v3.pem",
+    "invalid_issuer_keyusage_no_crlsign.pem",
+    "invalid_key_rollover_issuer_keyusage_no_crlsign.pem",
+    "invalid_garbage_version.pem",
+    "invalid_garbage_tbs_signature_algorithm.pem",
+    "invalid_garbage_issuer_name.pem",
+    "invalid_garbage_thisupdate.pem",
+    "invalid_garbage_after_thisupdate.pem",
+    "invalid_garbage_after_nextupdate.pem",
+    "invalid_garbage_after_revokedcerts.pem",
+    "invalid_garbage_after_extensions.pem",
+    "invalid_garbage_tbscertlist.pem",
+    "invalid_garbage_signaturealgorithm.pem",
+    "invalid_garbage_signaturevalue.pem",
+    "invalid_garbage_after_signaturevalue.pem",
+    "invalid_garbage_revoked_serial_number.pem",
+    "invalid_garbage_revocationdate.pem",
+    "invalid_garbage_after_revocationdate.pem",
+    "invalid_garbage_after_crlentryextensions.pem",
+    "invalid_garbage_crlentry.pem",
+    "invalid_idp_dpname_choice_extra_data.pem",
+    "invalid_idp_empty_sequence.pem",
+    "invalid_idp_onlycontains_user_and_ca_certs.pem",
+    "invalid_idp_onlycontainsusercerts_v1_leaf.pem",
+};
+
+struct PrintTestName {
+  std::string operator()(
+      const testing::TestParamInfo<const char*>& info) const {
+    std::string_view name(info.param);
+    // Strip ".pem" from the end as GTest names cannot contain period.
+    name.remove_suffix(4);
+    return std::string(name);
+  }
+};
+
+INSTANTIATE_TEST_SUITE_P(All,
+                         CheckCRLTest,
+                         ::testing::ValuesIn(kTestParams),
+                         PrintTestName());
+
+TEST_P(CheckCRLTest, FromFile) {
+  std::string_view file_name(GetParam());
+
+  std::string crl_data;
+  std::string ca_data_2;
+  std::string ca_data;
+  std::string cert_data;
+  const PemBlockMapping mappings[] = {
+      {"CRL", &crl_data},
+      {"CA CERTIFICATE 2", &ca_data_2, /*optional=*/true},
+      {"CA CERTIFICATE", &ca_data},
+      {"CERTIFICATE", &cert_data},
+  };
+
+  ASSERT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings));
+
+  std::shared_ptr<const ParsedCertificate> cert = ParseCertificate(cert_data);
+  ASSERT_TRUE(cert);
+  std::shared_ptr<const ParsedCertificate> issuer_cert =
+      ParseCertificate(ca_data);
+  ASSERT_TRUE(issuer_cert);
+  ParsedCertificateList certs = {cert, issuer_cert};
+  if (!ca_data_2.empty()) {
+    std::shared_ptr<const ParsedCertificate> issuer_cert_2 =
+        ParseCertificate(ca_data_2);
+    ASSERT_TRUE(issuer_cert_2);
+    certs.push_back(issuer_cert_2);
+  }
+
+  // Assumes that all the target certs in the test data certs have at most 1
+  // CRL distributionPoint. If the cert has a CRL distributionPoint, it is
+  // used for verifying the CRL, otherwise the CRL is verified with a
+  // synthesized distributionPoint. This is allowed since there are some
+  // conditions that require a V1 certificate to test, which cannot have a
+  // crlDistributionPoints extension.
+  // TODO(https://crbug.com/749276): This seems slightly hacky. Maybe the
+  // distribution point to use should be specified separately in the test PEM?
+  ParsedDistributionPoint fake_cert_dp;
+  ParsedDistributionPoint* cert_dp = &fake_cert_dp;
+  std::vector<ParsedDistributionPoint> distribution_points;
+  ParsedExtension crl_dp_extension;
+  if (cert->GetExtension(der::Input(kCrlDistributionPointsOid),
+                         &crl_dp_extension)) {
+    ASSERT_TRUE(ParseCrlDistributionPoints(crl_dp_extension.value,
+                                           &distribution_points));
+    ASSERT_LE(distribution_points.size(), 1U);
+    if (!distribution_points.empty()) {
+      cert_dp = &distribution_points[0];
+    }
+  }
+  ASSERT_TRUE(cert_dp);
+
+  // Mar 9 00:00:00 2017 GMT
+  int64_t kVerifyTime = 1489017600;
+
+  CRLRevocationStatus expected_revocation_status = CRLRevocationStatus::UNKNOWN;
+  if (string_util::StartsWith(file_name, "good")) {
+    expected_revocation_status = CRLRevocationStatus::GOOD;
+  } else if (string_util::StartsWith(file_name, "revoked")) {
+    expected_revocation_status = CRLRevocationStatus::REVOKED;
+  }
+
+  CRLRevocationStatus revocation_status =
+      CheckCRL(crl_data, certs, /*target_cert_index=*/0, *cert_dp, kVerifyTime,
+               kAgeOneWeek);
+  EXPECT_EQ(expected_revocation_status, revocation_status);
+
+  // Test with a random cert added to the front of the chain and
+  // |target_cert_index=1|. This is a hacky way to verify that
+  // target_cert_index is actually being honored.
+  ParsedCertificateList other_certs;
+  ASSERT_TRUE(ReadCertChainFromFile(
+      "testdata/parse_certificate_unittest/cert_version3.pem", &other_certs));
+  ASSERT_FALSE(other_certs.empty());
+  certs.insert(certs.begin(), other_certs[0]);
+  revocation_status = CheckCRL(crl_data, certs, /*target_cert_index=*/1,
+                               *cert_dp, kVerifyTime, kAgeOneWeek);
+  EXPECT_EQ(expected_revocation_status, revocation_status);
+}
+
+}  // namespace
+
+}  // namespace net
diff --git a/pki/general_names_unittest.cc b/pki/general_names_unittest.cc
new file mode 100644
index 0000000..0f7754d
--- /dev/null
+++ b/pki/general_names_unittest.cc
@@ -0,0 +1,227 @@
+// Copyright 2017 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "general_names.h"
+
+#include "test_helpers.h"
+#include <gtest/gtest.h>
+
+namespace bssl {
+namespace {
+
+::testing::AssertionResult LoadTestData(const char* token,
+                                        const std::string& basename,
+                                        std::string* result) {
+  std::string path = "testdata/name_constraints_unittest/" + basename;
+
+  const PemBlockMapping mappings[] = {
+      {token, result},
+  };
+
+  return ReadTestDataFromPemFile(path, mappings);
+}
+
+::testing::AssertionResult LoadTestSubjectAltNameData(
+    const std::string& basename,
+    std::string* result) {
+  return LoadTestData("SUBJECT ALTERNATIVE NAME", basename, result);
+}
+
+void ReplaceFirstSubstring(std::string* str,
+                           std::string_view substr,
+                           std::string_view replacement) {
+  size_t idx = str->find(substr);
+  if (idx != std::string::npos) {
+    str->replace(idx, substr.size(), replacement);
+  }
+}
+
+}  // namespace
+
+TEST(GeneralNames, CreateFailsOnEmptySubjectAltName) {
+  std::string invalid_san_der;
+  ASSERT_TRUE(
+      LoadTestSubjectAltNameData("san-invalid-empty.pem", &invalid_san_der));
+  CertErrors errors;
+  EXPECT_FALSE(GeneralNames::Create(der::Input(&invalid_san_der), &errors));
+}
+
+TEST(GeneralNames, OtherName) {
+  std::string san_der;
+  ASSERT_TRUE(LoadTestSubjectAltNameData("san-othername.pem", &san_der));
+
+  CertErrors errors;
+  std::unique_ptr<GeneralNames> general_names =
+      GeneralNames::Create(der::Input(&san_der), &errors);
+  ASSERT_TRUE(general_names);
+  EXPECT_EQ(GENERAL_NAME_OTHER_NAME, general_names->present_name_types);
+  const uint8_t expected_der[] = {0x06, 0x04, 0x2a, 0x03, 0x04, 0x05,
+                                  0x04, 0x04, 0xde, 0xad, 0xbe, 0xef};
+  ASSERT_EQ(1U, general_names->other_names.size());
+  EXPECT_EQ(der::Input(expected_der), general_names->other_names[0]);
+}
+
+TEST(GeneralNames, RFC822Name) {
+  std::string san_der;
+  ASSERT_TRUE(LoadTestSubjectAltNameData("san-rfc822name.pem", &san_der));
+
+  CertErrors errors;
+  std::unique_ptr<GeneralNames> general_names =
+      GeneralNames::Create(der::Input(&san_der), &errors);
+  ASSERT_TRUE(general_names);
+  EXPECT_EQ(GENERAL_NAME_RFC822_NAME, general_names->present_name_types);
+  ASSERT_EQ(1U, general_names->rfc822_names.size());
+  EXPECT_EQ("foo@example.com", general_names->rfc822_names[0]);
+}
+
+TEST(GeneralNames, CreateFailsOnNonAsciiRFC822Name) {
+  std::string san_der;
+  ASSERT_TRUE(LoadTestSubjectAltNameData("san-rfc822name.pem", &san_der));
+  ReplaceFirstSubstring(&san_der, "foo@example.com", "f\xF6\xF6@example.com");
+  CertErrors errors;
+  EXPECT_FALSE(GeneralNames::Create(der::Input(&san_der), &errors));
+}
+
+TEST(GeneralNames, DnsName) {
+  std::string san_der;
+  ASSERT_TRUE(LoadTestSubjectAltNameData("san-dnsname.pem", &san_der));
+
+  CertErrors errors;
+  std::unique_ptr<GeneralNames> general_names =
+      GeneralNames::Create(der::Input(&san_der), &errors);
+  ASSERT_TRUE(general_names);
+  EXPECT_EQ(GENERAL_NAME_DNS_NAME, general_names->present_name_types);
+  ASSERT_EQ(1U, general_names->dns_names.size());
+  EXPECT_EQ("foo.example.com", general_names->dns_names[0]);
+}
+
+TEST(GeneralNames, CreateFailsOnNonAsciiDnsName) {
+  std::string san_der;
+  ASSERT_TRUE(LoadTestSubjectAltNameData("san-dnsname.pem", &san_der));
+  ReplaceFirstSubstring(&san_der, "foo.example.com", "f\xF6\xF6.example.com");
+  CertErrors errors;
+  EXPECT_FALSE(GeneralNames::Create(der::Input(&san_der), &errors));
+}
+
+TEST(GeneralNames, X400Address) {
+  std::string san_der;
+  ASSERT_TRUE(LoadTestSubjectAltNameData("san-x400address.pem", &san_der));
+
+  CertErrors errors;
+  std::unique_ptr<GeneralNames> general_names =
+      GeneralNames::Create(der::Input(&san_der), &errors);
+  ASSERT_TRUE(general_names);
+  EXPECT_EQ(GENERAL_NAME_X400_ADDRESS, general_names->present_name_types);
+  ASSERT_EQ(1U, general_names->x400_addresses.size());
+  const uint8_t expected_der[] = {0x30, 0x06, 0x61, 0x04,
+                                  0x13, 0x02, 0x55, 0x53};
+  EXPECT_EQ(der::Input(expected_der), general_names->x400_addresses[0]);
+}
+
+TEST(GeneralNames, DirectoryName) {
+  std::string san_der;
+  ASSERT_TRUE(LoadTestSubjectAltNameData("san-directoryname.pem", &san_der));
+
+  CertErrors errors;
+  std::unique_ptr<GeneralNames> general_names =
+      GeneralNames::Create(der::Input(&san_der), &errors);
+  ASSERT_TRUE(general_names);
+  EXPECT_EQ(GENERAL_NAME_DIRECTORY_NAME, general_names->present_name_types);
+  ASSERT_EQ(1U, general_names->directory_names.size());
+  const uint8_t expected_der[] = {0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+                                  0x04, 0x06, 0x13, 0x02, 0x55, 0x53};
+  EXPECT_EQ(der::Input(expected_der), general_names->directory_names[0]);
+}
+
+TEST(GeneralNames, EDIPartyName) {
+  std::string san_der;
+  ASSERT_TRUE(LoadTestSubjectAltNameData("san-edipartyname.pem", &san_der));
+
+  CertErrors errors;
+  std::unique_ptr<GeneralNames> general_names =
+      GeneralNames::Create(der::Input(&san_der), &errors);
+  ASSERT_TRUE(general_names);
+  EXPECT_EQ(GENERAL_NAME_EDI_PARTY_NAME, general_names->present_name_types);
+  ASSERT_EQ(1U, general_names->edi_party_names.size());
+  const uint8_t expected_der[] = {0x81, 0x03, 0x66, 0x6f, 0x6f};
+  EXPECT_EQ(der::Input(expected_der), general_names->edi_party_names[0]);
+}
+
+TEST(GeneralNames, URI) {
+  std::string san_der;
+  ASSERT_TRUE(LoadTestSubjectAltNameData("san-uri.pem", &san_der));
+
+  CertErrors errors;
+  std::unique_ptr<GeneralNames> general_names =
+      GeneralNames::Create(der::Input(&san_der), &errors);
+  ASSERT_TRUE(general_names);
+  EXPECT_EQ(GENERAL_NAME_UNIFORM_RESOURCE_IDENTIFIER,
+            general_names->present_name_types);
+  ASSERT_EQ(1U, general_names->uniform_resource_identifiers.size());
+  EXPECT_EQ("http://example.com",
+            general_names->uniform_resource_identifiers[0]);
+}
+
+TEST(GeneralNames, CreateFailsOnNonAsciiURI) {
+  std::string san_der;
+  ASSERT_TRUE(LoadTestSubjectAltNameData("san-uri.pem", &san_der));
+  ReplaceFirstSubstring(&san_der, "http://example.com",
+                        "http://ex\xE4mple.com");
+  CertErrors errors;
+  EXPECT_FALSE(GeneralNames::Create(der::Input(&san_der), &errors));
+}
+
+TEST(GeneralNames, IPAddress_v4) {
+  std::string san_der;
+  ASSERT_TRUE(LoadTestSubjectAltNameData("san-ipaddress4.pem", &san_der));
+
+  CertErrors errors;
+  std::unique_ptr<GeneralNames> general_names =
+      GeneralNames::Create(der::Input(&san_der), &errors);
+  ASSERT_TRUE(general_names);
+  EXPECT_EQ(GENERAL_NAME_IP_ADDRESS, general_names->present_name_types);
+  ASSERT_EQ(1U, general_names->ip_addresses.size());
+  EXPECT_EQ(fillins::IPAddress(192, 168, 6, 7), general_names->ip_addresses[0]);
+  EXPECT_EQ(0U, general_names->ip_address_ranges.size());
+}
+
+TEST(GeneralNames, IPAddress_v6) {
+  std::string san_der;
+  ASSERT_TRUE(LoadTestSubjectAltNameData("san-ipaddress6.pem", &san_der));
+
+  CertErrors errors;
+  std::unique_ptr<GeneralNames> general_names =
+      GeneralNames::Create(der::Input(&san_der), &errors);
+  ASSERT_TRUE(general_names);
+  EXPECT_EQ(GENERAL_NAME_IP_ADDRESS, general_names->present_name_types);
+  ASSERT_EQ(1U, general_names->ip_addresses.size());
+  EXPECT_EQ(
+      fillins::IPAddress(0xFE, 0x80, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14),
+      general_names->ip_addresses[0]);
+  EXPECT_EQ(0U, general_names->ip_address_ranges.size());
+}
+
+TEST(GeneralNames, CreateFailsOnInvalidLengthIpAddress) {
+  std::string invalid_san_der;
+  ASSERT_TRUE(LoadTestSubjectAltNameData("san-invalid-ipaddress.pem",
+                                         &invalid_san_der));
+  CertErrors errors;
+  EXPECT_FALSE(GeneralNames::Create(der::Input(&invalid_san_der), &errors));
+}
+
+TEST(GeneralNames, RegisteredIDs) {
+  std::string san_der;
+  ASSERT_TRUE(LoadTestSubjectAltNameData("san-registeredid.pem", &san_der));
+
+  CertErrors errors;
+  std::unique_ptr<GeneralNames> general_names =
+      GeneralNames::Create(der::Input(&san_der), &errors);
+  ASSERT_TRUE(general_names);
+  EXPECT_EQ(GENERAL_NAME_REGISTERED_ID, general_names->present_name_types);
+  ASSERT_EQ(1U, general_names->registered_ids.size());
+  const uint8_t expected_der[] = {0x2a, 0x03, 0x04};
+  EXPECT_EQ(der::Input(expected_der), general_names->registered_ids[0]);
+}
+
+}  // namespace net
diff --git a/pki/import_spec.json b/pki/import_spec.json
index 705b6ac..f81c87a 100644
--- a/pki/import_spec.json
+++ b/pki/import_spec.json
@@ -55,12 +55,12 @@
      "replace": "#include \"fillins/ip_address.h\"",
      "using": ["bssl::fillins::IPAddress",
                "bssl::fillins::IPAddressBytes"]},
-    {"match": " IPAddress",
-     "replace": " fillins::IPAddress"},
-    {"match": "<IPAddress",
-     "replace": "<fillins::IPAddress"},
-    {"match": "\\(IPAddress",
-     "replace": "(fillins::IPAddress"},
+    {"match": "\\bIPAddressMatchesPrefix\\b",
+     "replace": "fillins::IPAddressMatchesPrefix"},
+    {"match": "\\bIPAddressBytes\\b",
+     "replace": "fillins::IPAddressBytes"},
+    {"match": "\\bIPAddress\\b",
+     "replace": "fillins::IPAddress"},
     {"match": "\"net/data/",
      "replace": "\"testdata/"},
     {"match": "\"net/third_party/nist-pkits",
@@ -266,11 +266,17 @@
     "net/cert/pki/common_cert_errors.h",
     "net/cert/pki/crl.h",
     "net/cert/pki/crl.cc",
+    "net/cert/pki/crl_unittest.cc",
+    "net/cert/pki/crl_parse_crl_certificatelist_fuzzer.cc",
+    "net/cert/pki/crl_parse_crl_tbscertlist_fuzzer.cc",
+    "net/cert/pki/crl_parse_issuing_distribution_point_fuzzer.cc",
+    "net/cert/pki/crl_getcrlstatusforcert_fuzzer.cc",
     "net/cert/pki/extended_key_usage.cc",
     "net/cert/pki/extended_key_usage.h",
     "net/cert/pki/extended_key_usage_unittest.cc",
     "net/cert/pki/general_names.h",
     "net/cert/pki/general_names.cc",
+    "net/cert/pki/general_names_unittest.cc",
     "net/cert/pki/mock_signature_verify_cache.h",
     "net/cert/pki/mock_signature_verify_cache.cc",
     "net/cert/pki/name_constraints.cc",
@@ -285,6 +291,7 @@
     "net/cert/pki/ocsp_parse_ocsp_response_fuzzer.cc",
     "net/cert/pki/ocsp_parse_ocsp_single_response_fuzzer.cc",
     "net/cert/pki/ocsp_unittest.cc",
+    "net/cert/pki/parse_authority_key_identifier_fuzzer.cc",
     "net/cert/pki/parse_certificate.cc",
     "net/cert/pki/parse_certificate.h",
     "net/cert/pki/parse_certificate_unittest.cc",
@@ -340,9 +347,6 @@
     "net/cert/ocsp_verify_result.cc",
     "net/cert/pem.cc",
     "net/cert/pem.h",
-    "net/cert/x509_certificate.cc",
-    "net/cert/x509_certificate.h",
-    "net/cert/x509_cert_types.h",
     "net/der/encode_values.cc",
     "net/der/encode_values.h",
     "net/der/encode_values_unittest.cc",
diff --git a/pki/parse_authority_key_identifier_fuzzer.cc b/pki/parse_authority_key_identifier_fuzzer.cc
new file mode 100644
index 0000000..18d4b62
--- /dev/null
+++ b/pki/parse_authority_key_identifier_fuzzer.cc
@@ -0,0 +1,22 @@
+// 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 <stddef.h>
+#include <stdint.h>
+
+#include <tuple>
+
+#include "parse_certificate.h"
+#include "input.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  bssl::der::Input der(data, size);
+
+  net::ParsedAuthorityKeyIdentifier authority_key_identifier;
+
+  std::ignore =
+      net::ParseAuthorityKeyIdentifier(der, &authority_key_identifier);
+
+  return 0;
+}
diff --git a/pki/testdata/crl_unittest/bad_crldp_has_crlissuer.pem b/pki/testdata/crl_unittest/bad_crldp_has_crlissuer.pem
new file mode 100644
index 0000000..0d224bd
--- /dev/null
+++ b/pki/testdata/crl_unittest/bad_crldp_has_crlissuer.pem
@@ -0,0 +1,219 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf covered by CRLs and not revoked, leaf has crlDistributionPoints with a crlIssuer
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00588a2dbca80630842ffcd6a0a6fe17630d341e0e277c863069025b3169a727188cf7d22a985c027678e034c31c34141d102a7aef73039d1f51ce11261b069598c4b19bae39278bcdb245f55dc644f2165beac3f8aa8e19e13a27bb53cc19387f6afaf2ef8cbe5270380917abae7fa7c0ad4aaa7b70b1102d23951886d854a5cd` }
+}
+-----BEGIN CRL-----
+MIHmMFECAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMloXDTE3MDYwMjAwMTEyMlowDQYJKoZIhvcN
+AQELBQADgYEAWIotvKgGMIQv/Nagpv4XYw00Hg4nfIYwaQJbMWmnJxiM99IqmFwC
+dnjgNMMcNBQdECp673MDnR9RzhEmGwaVmMSxm645J4vNskX1XcZE8hZb6sP4qo4Z
+4Tonu1PMGTh/avry74y+UnA4CRerrn+nwK1KqntwsRAtI5UYhthUpc0=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 7 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00ab5d85660bb35b4be51e87a4acd9511653bfe8e3ea0158a3a301b37aab30c84389341813cd4e554507a5e7c7779f23e1e4b222bf7f1f8ea310440fa853f35cf9a11b12b8b1eed3e0636f0148575790c9862229ee8ee9fa0ae8a6a80406fa437ec58dff128dd9cb3982a97e74358ac74d7e2b9ae42002e6fb29c12d719d0263e5` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+                [2] {
+                  [4] {
+                    SEQUENCE {
+                      SET {
+                        SEQUENCE {
+                          # commonName
+                          OBJECT_IDENTIFIER { 2.5.4.3 }
+                          UTF8String { "Test CRL Issuer CA" }
+                        }
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `009c795613f5cbafdaaf2356d35174d952263dc0816fbe9c89dafb7d1017487711788e66d7b0ab4b2425180a23525b360b33dd8fbda83288008b62aa7a272ae98c02b78ec157108049ac04663c1f92e5390c7a8ff8ee98753250257abbe3ef90c2b93971c5075a9ed3bdeaccecd37b5c068e63cf06bab961a32ecebc3e2e5d1a84` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB/zCCAWigAwIBAgIBBzANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBAKtdhWYLs1tL5R6HpKzZURZTv+jj6gFYo6MBs3qrMMhDiTQYE81OVUUH
+pefHd58j4eSyIr9/H46jEEQPqFPzXPmhGxK4se7T4GNvAUhXV5DJhiIp7o7p+gro
+pqgEBvpDfsWN/xKN2cs5gql+dDWKx01+K5rkIALm+ynBLXGdAmPlAgMBAAGjUjBQ
+ME4GA1UdHwRHMEUwQ6AeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsoiGk
+HzAdMRswGQYDVQQDDBJUZXN0IENSTCBJc3N1ZXIgQ0EwDQYJKoZIhvcNAQELBQAD
+gYEAnHlWE/XLr9qvI1bTUXTZUiY9wIFvvpyJ2vt9EBdIdxF4jmbXsKtLJCUYCiNS
+WzYLM92PvagyiACLYqp6JyrpjAK3jsFXEIBJrARmPB+S5TkMeo/47ph1MlAlervj
+75DCuTlxxQdantO96szs03tcBo5jzwa6uWGjLs68Pi5dGoQ=
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/bad_fake_critical_crlentryextension.pem b/pki/testdata/crl_unittest/bad_fake_critical_crlentryextension.pem
new file mode 100644
index 0000000..f6c256b
--- /dev/null
+++ b/pki/testdata/crl_unittest/bad_fake_critical_crlentryextension.pem
@@ -0,0 +1,224 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf is revoked, but a later entry has a critical crlEntryExtension
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    SEQUENCE {
+      SEQUENCE {
+        INTEGER { 5 }
+        UTCTime { "170201001122Z" }
+      }
+      SEQUENCE {
+        INTEGER { 106 }
+        UTCTime { "170201001122Z" }
+        SEQUENCE {
+          SEQUENCE {
+            OBJECT_IDENTIFIER { 1.2.3.4 }
+            BOOLEAN { `ff` }
+            OCTET_STRING { "Vx" }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00d285154e45b4990268087fcefa9e44c46377a9278e14786a993fdeef5617ff3d446b06b2fcbb91e524ac4282bec21b94051e5d1d114bb65fee0042e74c107819ceb36f2d506fd1a0b3670ce7fa444872402f1cae552014e5e0d418e6996de3fe6dc34fb5a17ea889c7515989ac8dd746e4f12c0647cf214f6e088d238606bc56` }
+}
+-----BEGIN CRL-----
+MIIBITCBiwIBATANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0IEludGVy
+bWVkaWF0ZSBDQRcNMTcwMzAyMDAxMTIyWhcNMTcwNjAyMDAxMTIyWjA4MBICAQUX
+DTE3MDIwMTAwMTEyMlowIgIBahcNMTcwMjAxMDAxMTIyWjAOMAwGAyoDBAEB/wQC
+VngwDQYJKoZIhvcNAQELBQADgYEA0oUVTkW0mQJoCH/O+p5ExGN3qSeOFHhqmT/e
+71YX/z1Eaway/LuR5SSsQoK+whuUBR5dHRFLtl/uAELnTBB4Gc6zby1Qb9Ggs2cM
+5/pESHJALxyuVSAU5eDUGOaZbeP+bcNPtaF+qInHUVmJrI3XRuTxLAZHzyFPbgiN
+I4YGvFY=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/bad_fake_critical_extension.pem b/pki/testdata/crl_unittest/bad_fake_critical_extension.pem
new file mode 100644
index 0000000..3ced415
--- /dev/null
+++ b/pki/testdata/crl_unittest/bad_fake_critical_extension.pem
@@ -0,0 +1,213 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf covered by CRLs and not revoked, but CRL has an unhandled critical extension
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    [0] {
+      SEQUENCE {
+        SEQUENCE {
+          OBJECT_IDENTIFIER { 1.2.3.4 }
+          BOOLEAN { `ff` }
+          OCTET_STRING { "Vx" }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `005f3c1d43342fa5bc0e66667061c50ca6f4da054fdaae914a28193620f4611d59c8ba19ff6573494f35eaf2729cfb5dbbc2edd41e6884e989614bc577de9b917630736e9e38a9001f8d8e8b4c1638a0fae33144ad7fd04c45ac5195b96d4af57e21472d7e621ef2f1535a07459f4d4d2afbfa045b0f040a7da849c54f60c86930` }
+}
+-----BEGIN CRL-----
+MIHpMFQCAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMlqgEDAOMAwGAyoDBAEB/wQCVngwDQYJKoZI
+hvcNAQELBQADgYEAXzwdQzQvpbwOZmZwYcUMpvTaBU/arpFKKBk2IPRhHVnIuhn/
+ZXNJTzXq8nKc+127wu3UHmiE6YlhS8V33puRdjBzbp44qQAfjY6LTBY4oPrjMUSt
+f9BMRaxRlbltSvV+IUctfmIe8vFTWgdFn01NKvv6BFsPBAp9qEnFT2DIaTA=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/bad_idp_contains_wrong_uri.pem b/pki/testdata/crl_unittest/bad_idp_contains_wrong_uri.pem
new file mode 100644
index 0000000..c332e90
--- /dev/null
+++ b/pki/testdata/crl_unittest/bad_idp_contains_wrong_uri.pem
@@ -0,0 +1,224 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf not covered by CRL (IDP with different URI)
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    [0] {
+      SEQUENCE {
+        SEQUENCE {
+          # issuingDistributionPoint
+          OBJECT_IDENTIFIER { 2.5.29.28 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              [0] {
+                [0] {
+                  [6 PRIMITIVE] { "http://example.com/FOO.CRL" }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0060e4465673e30d5d312b2e3b5cc724cf4a1e927d37f92927d55ac6ae4a76f5fc6ca6e6564dc536d5b2559b238691397d83aa0f2265c70033c5060ede8540e92c5495eda163cf145841357e219c0a0e6db03f0ee2161e9f4759cfc6fc89e08a84fc8a3b2c92c29a01c2ae48ca02687e052bbd37a843e0fea0078331fb2d78c061` }
+}
+-----BEGIN CRL-----
+MIIBGTCBgwIBATANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0IEludGVy
+bWVkaWF0ZSBDQRcNMTcwMzAyMDAxMTIyWhcNMTcwNjAyMDAxMTIyWqAwMC4wLAYD
+VR0cAQH/BCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9GT08uQ1JMMA0GCSqG
+SIb3DQEBCwUAA4GBAGDkRlZz4w1dMSsuO1zHJM9KHpJ9N/kpJ9Vaxq5KdvX8bKbm
+Vk3FNtWyVZsjhpE5fYOqDyJlxwAzxQYO3oVA6SxUle2hY88UWEE1fiGcCg5tsD8O
+4hYen0dZz8b8ieCKhPyKOyySwpoBwq5IygJofgUrvTeoQ+D+oAeDMfsteMBh
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00a35afbe7508b58895a28f81ebe71ea37f659fe29d1da13bd5b12460b8cf570dc57966aa97f06382fd01c4fbafc46564de12aa0d1d90d2060ad3f845189dab146559409c673b170edeb83bb56ecd2a7257b2283626d53f62e352c3edbb1a2198ddc73a92deb96b1beffd855f1e1aa005ae2ade2f763cbb0d0bd6cce4b768808c5` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0043b0323ab8f10378ccd100d12068c5bad3c32fdaa1b441ed1a4d52baa46aa967237345db8fdf03e0513825fd43c747aa710e371a88ae5ee4f460c59ddb6c5b08505feaa3cce3272e5c3d9b08a878822d5e601517b903537cb90e9085ec954c460f88af5217cb86e7c48be7d0847ec10f36a8df6177599d4a0d2ad4ea0ca857b2` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQCjWvvnUItYiVoo+B6+ceo39ln+KdHaE71bEkYLjPVw3FeWaql/Bjgv0BxP
+uvxGVk3hKqDR2Q0gYK0/hFGJ2rFGVZQJxnOxcO3rg7tW7NKnJXsig2JtU/YuNSw+
+27GiGY3cc6kt65axvv/YVfHhqgBa4q3i92PLsNC9bM5LdogIxQIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAQ7AyOrjxA3jM0QDRIGjF
+utPDL9qhtEHtGk1SuqRqqWcjc0Xbj98D4FE4Jf1Dx0eqcQ43GoiuXuT0YMWd22xb
+CFBf6qPM4ycuXD2bCKh4gi1eYBUXuQNTfLkOkIXslUxGD4ivUhfLhufEi+fQhH7B
+Dzao32F3WZ1KDSrU6gyoV7I=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00abdd04e5f0239dace20256547addf9df3ebb4081eacb549675116355e574620e2a350118cc9a03f754f73f93e1f95555db4f1533d14c50bebe6823c7e4032e2fa65536bdf33ff918c739680a809f4164f4c901c56d2c18785fc205f705b16086339be26d77d60de259dfbac76780ee5f2b416ff84566c5cc52a9d167ab818c67` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `000e3be5de5d0a6a2a155fa41f786443e6921899ed5566a1ba9fed2cec41dd925d1e077e3b9ce0aeacdf01261d31b828247da6d83d45a2ce469007d4dafda3603463b78bf18eff05e7b97521cbe10e44f185e945fdc09f637b982abbb2f1d380705305c0d63c207f622e6f14ed5509c68ecf907794de3a055137502ba47e37074d` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBAKvdBOXwI52s4gJWVHrd+d8+u0CB6stUlnURY1XldGIOKjUBGMyaA/dU
+9z+T4flVVdtPFTPRTFC+vmgjx+QDLi+mVTa98z/5GMc5aAqAn0Fk9MkBxW0sGHhf
+wgX3BbFghjOb4m131g3iWd+6x2eA7l8rQW/4RWbFzFKp0WergYxnAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAA475d5dCmoqFV+kH3hkQ+aSGJntVWahup/tLOxB3ZJd
+Hgd+O5zgrqzfASYdMbgoJH2m2D1Fos5GkAfU2v2jYDRjt4vxjv8F57l1IcvhDkTx
+helF/cCfY3uYKruy8dOAcFMFwNY8IH9iLm8U7VUJxo7PkHeU3joFUTdQK6R+NwdN
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/bad_idp_indirectcrl.pem b/pki/testdata/crl_unittest/bad_idp_indirectcrl.pem
new file mode 100644
index 0000000..94181ee
--- /dev/null
+++ b/pki/testdata/crl_unittest/bad_idp_indirectcrl.pem
@@ -0,0 +1,225 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+CRL IDP name matches, but has indirectCRL flag set
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    [0] {
+      SEQUENCE {
+        SEQUENCE {
+          # issuingDistributionPoint
+          OBJECT_IDENTIFIER { 2.5.29.28 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              [0] {
+                [0] {
+                  [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                }
+              }
+              [4 PRIMITIVE] { `ff` }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `008575e0844de9900f4ffe043ecf057212ec75c3f5736249ce3f9491c51afecc63b0fd68684419a99b72e6b075054f220ef4574c53bc3502f2751743326633551baf2888bcc3939d9ca4a22660a86be5ef766c872a4640386156905aff45c8bc40b2d2f648275d687c873fa7dfc080b89cd49d528bf1e3166022baee75907aa48a` }
+}
+-----BEGIN CRL-----
+MIIBHDCBhgIBATANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0IEludGVy
+bWVkaWF0ZSBDQRcNMTcwMzAyMDAxMTIyWhcNMTcwNjAyMDAxMTIyWqAzMDEwLwYD
+VR0cAQH/BCUwI6AeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JshAH/MA0G
+CSqGSIb3DQEBCwUAA4GBAIV14IRN6ZAPT/4EPs8FchLsdcP1c2JJzj+UkcUa/sxj
+sP1oaEQZqZty5rB1BU8iDvRXTFO8NQLydRdDMmYzVRuvKIi8w5OdnKSiJmCoa+Xv
+dmyHKkZAOGFWkFr/Rci8QLLS9kgnXWh8hz+n38CAuJzUnVKL8eMWYCK67nWQeqSK
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00bd60ec89240bf0ea7b3f4a6a3f14406eae57ba2becb1b9479cda724cd41d71cd948871c969589c8199f4196193475abbf12e4a660865801695f5904046286522c9e4c7d09ccd28c8a3afc68b15d6917e04be426e26e5c7b3b734b68fe4b9ceb1f3738ebf285c98d89e65b931f2a2986c0bfb3cac53b2320199e4c75885dbd3ef` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00c4ed6f392c591e97505d31c5f2d966754a5ab9279b95d251ddc7391ded5052f130a3ea1b6cbb718acd19ee47e75e0811c8a1f0b2548779f6bcc28e4f110d4e242f4197c4cb7d8d27149ef1ae28af45c2d3fcb83c9c1bc2fb4cd44d9508ec64d54864244e9be13ec1575a6e3951dc233be5859995c6d0ee9be69d098273296065` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQC9YOyJJAvw6ns/Smo/FEBurle6K+yxuUec2nJM1B1xzZSIcclpWJyBmfQZ
+YZNHWrvxLkpmCGWAFpX1kEBGKGUiyeTH0JzNKMijr8aLFdaRfgS+Qm4m5ceztzS2
+j+S5zrHzc46/KFyY2J5luTHyophsC/s8rFOyMgGZ5MdYhdvT7wIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAxO1vOSxZHpdQXTHF8tlm
+dUpauSebldJR3cc5He1QUvEwo+obbLtxis0Z7kfnXggRyKHwslSHefa8wo5PEQ1O
+JC9Bl8TLfY0nFJ7xriivRcLT/Lg8nBvC+0zUTZUI7GTVSGQkTpvhPsFXWm45Udwj
+O+WFmZXG0O6b5p0JgnMpYGU=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00fbff662387c3e71432d3188342014cee96bfd313373db79f4f427c4e6d2b8949b0597f6d3649428dc4eb93f72710f08c9aedf46c38fa6eecb235dad488681e526588be960402e971e14155d065c5ab2213ccb199c195246bfc604173bb4d31e1c7beffe84a3007feb05e5f51c6c1fc942f1fc2e62e6a095271b69665aebd9ae3` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `005eae7b92f2a53dc2350b6041bb514239a999c326708a6b6337aceb4f0b871f70bdfa7caaf218e8daa4a8e0f6ee968ccdc7a1cf13fc5c319e53c5e067cbe4c0602b5bf1f7201cff6c927e406c8021176722969268cacbf1766ad61d967a329e376ac0a8d33eeef2f185304f22a351d80a1ad0969c64e14a41b2783710bc7560c6` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBAPv/ZiOHw+cUMtMYg0IBTO6Wv9MTNz23n09CfE5tK4lJsFl/bTZJQo3E
+65P3JxDwjJrt9Gw4+m7ssjXa1IhoHlJliL6WBALpceFBVdBlxasiE8yxmcGVJGv8
+YEFzu00x4ce+/+hKMAf+sF5fUcbB/JQvH8LmLmoJUnG2lmWuvZrjAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAF6ue5LypT3CNQtgQbtRQjmpmcMmcIprYzes608Lhx9w
+vfp8qvIY6NqkqOD27paMzcehzxP8XDGeU8XgZ8vkwGArW/H3IBz/bJJ+QGyAIRdn
+IpaSaMrL8XZq1h2WejKeN2rAqNM+7vLxhTBPIqNR2Aoa0JacZOFKQbJ4NxC8dWDG
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/bad_idp_onlycontainscacerts.pem b/pki/testdata/crl_unittest/bad_idp_onlycontainscacerts.pem
new file mode 100644
index 0000000..9ba123f
--- /dev/null
+++ b/pki/testdata/crl_unittest/bad_idp_onlycontainscacerts.pem
@@ -0,0 +1,239 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf not covered by CRLs because IDP has onlyContainsCACerts
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    [0] {
+      SEQUENCE {
+        SEQUENCE {
+          # issuingDistributionPoint
+          OBJECT_IDENTIFIER { 2.5.29.28 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              [2 PRIMITIVE] { `ff` }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0091251c86c4252190f1148b40d9993cd075c8c797edd81f8cc14ce322368f3a47434f21d819231ae3c56fcb7a796b669a6a4fcc4980f112c1b5dcf6036cef1e77494d48cf8f16a85aa5dc05e17bd01217d67f52bbdd81ab70385d1800d755d2f4b878adbae521fc9b7c4386aef0b787d0beff34a3975933ce5191153f056c31cc` }
+}
+-----BEGIN CRL-----
+MIH7MGYCAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMloXDTE3MDYwMjAwMTEyMlqgEzARMA8GA1Ud
+HAEB/wQFMAOCAf8wDQYJKoZIhvcNAQELBQADgYEAkSUchsQlIZDxFItA2Zk80HXI
+x5ft2B+MwUzjIjaPOkdDTyHYGSMa48Vvy3p5a2aaak/MSYDxEsG13PYDbO8ed0lN
+SM+PFqhapdwF4XvQEhfWf1K73YGrcDhdGADXVdL0uHituuUh/Jt8Q4au8LeH0L7/
+NKOXWTPOUZEVPwVsMcw=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00f60f4a066d9dc05562f5c879444163b73be0b3d5e32dd7eff091af5d3c70bf3860067236894d085f581c70a1a8753d5b8882b263733e89a47b9989c36ce438b3b96ac16b1ca8878f2d51383055a17df6936c82b4f50729eb2f08f0f46f4106fa5975ec83c06f7d1135468354e01478e78474c56b6aca4d8a3e86ff7e494e6407` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+        SEQUENCE {
+          # basicConstraints
+          OBJECT_IDENTIFIER { 2.5.29.19 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              BOOLEAN { `ff` }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00209bf64b888cbd58493d8898b215ed640ddb04e329e43e3db45a20782ab7acc22dca7cbb11b4fbdb08b8acf163d116948db57b044773d51b8bdf09b1a6465268d60388fee8740aa4167e9d44f19027b075802438c909b9afd0f298027bf0b56e6dd1e92ea5d393e2b422c49bb324433bce95a828149db3e5491d1572b11be5f4` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBzjCCATegAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQD2D0oGbZ3AVWL1yHlEQWO3O+Cz1eMt1+/wka9dPHC/OGAGcjaJTQhfWBxw
+oah1PVuIgrJjcz6JpHuZicNs5DizuWrBaxyoh48tUTgwVaF99pNsgrT1BynrLwjw
+9G9BBvpZdeyDwG99ETVGg1TgFHjnhHTFa2rKTYo+hv9+SU5kBwIDAQABoyMwITAO
+BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOB
+gQAgm/ZLiIy9WEk9iJiyFe1kDdsE4ynkPj20WiB4Kreswi3KfLsRtPvbCLis8WPR
+FpSNtXsER3PVG4vfCbGmRlJo1gOI/uh0CqQWfp1E8ZAnsHWAJDjJCbmv0PKYAnvw
+tW5t0ekupdOT4rQixJuzJEM7zpWoKBSds+VJHRVysRvl9A==
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b86043a5c55800fd75606bd07e94c08c4bbd7c2ed4bcb6f8caac436213ab24587377a0107678abcca31c31fd84b78636034a6ea4853d62bd86d8a5e4c8f741b6efdf1008696e8eed8f30db3fdc78ca13d39d6cca9bc1563111e0bace35ffca03ab146bf07bb4636f6b38cf8b2feb1336e3f209ff30aad4283468a997e8215329` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+        SEQUENCE {
+          # basicConstraints
+          OBJECT_IDENTIFIER { 2.5.29.19 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {}
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00af35a49085f242c33eaad6efba5c2906f7c0ebf5caa66ab2f5ed0a663287da5665963048df790ffb1f223b93a8a40c9a8d26a0d9f0a41dd3d706754a59bfb2579464f984aa7686de56b441759c42b7aeb50b5960eaa27cb469beaeaf2460c1b6d8246dc78d6fce2a05a26f7723f6a1b96c0faf912b4aa67ceaeb432a552e1cb4` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB6jCCAVOgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALhgQ6XFWAD9dWBr0H6UwIxLvXwu1Ly2+MqsQ2ITqyRYc3egEHZ4q8yj
+HDH9hLeGNgNKbqSFPWK9htil5Mj3Qbbv3xAIaW6O7Y8w2z/ceMoT051sypvBVjER
+4LrONf/KA6sUa/B7tGNvazjPiy/rEzbj8gn/MKrUKDRoqZfoIVMpAgMBAAGjPTA7
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMAwG
+A1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADgYEArzWkkIXyQsM+qtbvulwpBvfA
+6/XKpmqy9e0KZjKH2lZlljBI33kP+x8iO5OopAyajSag2fCkHdPXBnVKWb+yV5Rk
++YSqdobeVrRBdZxCt661C1lg6qJ8tGm+rq8kYMG22CRtx41vzioFom93I/ahuWwP
+r5ErSqZ86utDKlUuHLQ=
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/bad_idp_onlycontainscacerts_no_basic_constraints.pem b/pki/testdata/crl_unittest/bad_idp_onlycontainscacerts_no_basic_constraints.pem
new file mode 100644
index 0000000..1ba7b09
--- /dev/null
+++ b/pki/testdata/crl_unittest/bad_idp_onlycontainscacerts_no_basic_constraints.pem
@@ -0,0 +1,230 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf not covered by CRLs because IDP has onlyContainsCACerts, leaf has no basicConstraints
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    [0] {
+      SEQUENCE {
+        SEQUENCE {
+          # issuingDistributionPoint
+          OBJECT_IDENTIFIER { 2.5.29.28 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              [2 PRIMITIVE] { `ff` }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0091251c86c4252190f1148b40d9993cd075c8c797edd81f8cc14ce322368f3a47434f21d819231ae3c56fcb7a796b669a6a4fcc4980f112c1b5dcf6036cef1e77494d48cf8f16a85aa5dc05e17bd01217d67f52bbdd81ab70385d1800d755d2f4b878adbae521fc9b7c4386aef0b787d0beff34a3975933ce5191153f056c31cc` }
+}
+-----BEGIN CRL-----
+MIH7MGYCAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMloXDTE3MDYwMjAwMTEyMlqgEzARMA8GA1Ud
+HAEB/wQFMAOCAf8wDQYJKoZIhvcNAQELBQADgYEAkSUchsQlIZDxFItA2Zk80HXI
+x5ft2B+MwUzjIjaPOkdDTyHYGSMa48Vvy3p5a2aaak/MSYDxEsG13PYDbO8ed0lN
+SM+PFqhapdwF4XvQEhfWf1K73YGrcDhdGADXVdL0uHituuUh/Jt8Q4au8LeH0L7/
+NKOXWTPOUZEVPwVsMcw=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00f60f4a066d9dc05562f5c879444163b73be0b3d5e32dd7eff091af5d3c70bf3860067236894d085f581c70a1a8753d5b8882b263733e89a47b9989c36ce438b3b96ac16b1ca8878f2d51383055a17df6936c82b4f50729eb2f08f0f46f4106fa5975ec83c06f7d1135468354e01478e78474c56b6aca4d8a3e86ff7e494e6407` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+        SEQUENCE {
+          # basicConstraints
+          OBJECT_IDENTIFIER { 2.5.29.19 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              BOOLEAN { `ff` }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00209bf64b888cbd58493d8898b215ed640ddb04e329e43e3db45a20782ab7acc22dca7cbb11b4fbdb08b8acf163d116948db57b044773d51b8bdf09b1a6465268d60388fee8740aa4167e9d44f19027b075802438c909b9afd0f298027bf0b56e6dd1e92ea5d393e2b422c49bb324433bce95a828149db3e5491d1572b11be5f4` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBzjCCATegAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQD2D0oGbZ3AVWL1yHlEQWO3O+Cz1eMt1+/wka9dPHC/OGAGcjaJTQhfWBxw
+oah1PVuIgrJjcz6JpHuZicNs5DizuWrBaxyoh48tUTgwVaF99pNsgrT1BynrLwjw
+9G9BBvpZdeyDwG99ETVGg1TgFHjnhHTFa2rKTYo+hv9+SU5kBwIDAQABoyMwITAO
+BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOB
+gQAgm/ZLiIy9WEk9iJiyFe1kDdsE4ynkPj20WiB4Kreswi3KfLsRtPvbCLis8WPR
+FpSNtXsER3PVG4vfCbGmRlJo1gOI/uh0CqQWfp1E8ZAnsHWAJDjJCbmv0PKYAnvw
+tW5t0ekupdOT4rQixJuzJEM7zpWoKBSds+VJHRVysRvl9A==
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 6 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d19aa4fda893774bdad672e2be8ecc8d8e7c5b8348d67b663cd297e4f068b5ed78be1aa7dd8f7bd871faaa052007b40fb2468fc455f5a691774b55cae696c32d0d0e9f9545118d528fcd8932a9682e50f1aae0b5a88bcbc43308c1f5a230d1dacf8e3c229327784f6f9a6c5b12c9c575e9003f10e38527f94782a424b164a86f` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00e14d6cad7fe998eba094e9e36701bc7dfecf3cbf4eebae9d3a5b5e977de9a557633ed93ab642baa637631e131dd162f069d6430e0198914004c1a4876f621ed56c9fe4d4613f93d7d2ed5eca1b7dd0434aeb89e1e1caa57e686312ea38ff791db53409c1dfb3178a1e11e819c030063f1e16f487abc57dfe1ec1bf2c9e4934db` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBjANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBANGapP2ok3dL2tZy4r6OzI2OfFuDSNZ7ZjzSl+TwaLXteL4ap92Pe9hx
++qoFIAe0D7JGj8RV9aaRd0tVyuaWwy0NDp+VRRGNUo/NiTKpaC5Q8argtaiLy8Qz
+CMH1ojDR2s+OPCKTJ3hPb5psWxLJxXXpAD8Q44Un+UeCpCSxZKhvAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAOFNbK1/6ZjroJTp42cBvH3+zzy/TuuunTpbXpd96aVX
+Yz7ZOrZCuqY3Yx4THdFi8GnWQw4BmJFABMGkh29iHtVsn+TUYT+T19LtXsobfdBD
+SuuJ4eHKpX5oYxLqOP95HbU0CcHfsxeKHhHoGcAwBj8eFvSHq8V9/h7BvyyeSTTb
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/bad_idp_onlycontainsusercerts.pem b/pki/testdata/crl_unittest/bad_idp_onlycontainsusercerts.pem
new file mode 100644
index 0000000..e915d20
--- /dev/null
+++ b/pki/testdata/crl_unittest/bad_idp_onlycontainsusercerts.pem
@@ -0,0 +1,249 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+CA_NEW_BY_OLD not covered by CRLs because IDP has onlyContainsUserCerts
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    [0] {
+      SEQUENCE {
+        SEQUENCE {
+          # issuingDistributionPoint
+          OBJECT_IDENTIFIER { 2.5.29.28 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              [1 PRIMITIVE] { `ff` }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `002f2deff3f117300df880570eebe5789244d45c0fc6db66e0f90d740c55e2344278c301d237579ae2ae73d507b7e60efb244b49461b5c44aa708bc192a4040e1d58b7c22036c36f39acab389f363c50e97a8b62d051f7e94d08a2b465cf95fd04e500c16ea5f1e74b00c6b738abcbfda713bab4a1139ad54f412e70199a255658` }
+}
+-----BEGIN CRL-----
+MIH7MGYCAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMloXDTE3MDYwMjAwMTEyMlqgEzARMA8GA1Ud
+HAEB/wQFMAOBAf8wDQYJKoZIhvcNAQELBQADgYEALy3v8/EXMA34gFcO6+V4kkTU
+XA/G22bg+Q10DFXiNEJ4wwHSN1ea4q5z1Qe35g77JEtJRhtcRKpwi8GSpAQOHVi3
+wiA2w285rKs4nzY8UOl6i2LQUffpTQiitGXPlf0E5QDBbqXx50sAxrc4q8v9pxO6
+tKETmtVPQS5wGZolVlg=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00f60f4a066d9dc05562f5c879444163b73be0b3d5e32dd7eff091af5d3c70bf3860067236894d085f581c70a1a8753d5b8882b263733e89a47b9989c36ce438b3b96ac16b1ca8878f2d51383055a17df6936c82b4f50729eb2f08f0f46f4106fa5975ec83c06f7d1135468354e01478e78474c56b6aca4d8a3e86ff7e494e6407` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+        SEQUENCE {
+          # basicConstraints
+          OBJECT_IDENTIFIER { 2.5.29.19 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              BOOLEAN { `ff` }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00209bf64b888cbd58493d8898b215ed640ddb04e329e43e3db45a20782ab7acc22dca7cbb11b4fbdb08b8acf163d116948db57b044773d51b8bdf09b1a6465268d60388fee8740aa4167e9d44f19027b075802438c909b9afd0f298027bf0b56e6dd1e92ea5d393e2b422c49bb324433bce95a828149db3e5491d1572b11be5f4` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBzjCCATegAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQD2D0oGbZ3AVWL1yHlEQWO3O+Cz1eMt1+/wka9dPHC/OGAGcjaJTQhfWBxw
+oah1PVuIgrJjcz6JpHuZicNs5DizuWrBaxyoh48tUTgwVaF99pNsgrT1BynrLwjw
+9G9BBvpZdeyDwG99ETVGg1TgFHjnhHTFa2rKTYo+hv9+SU5kBwIDAQABoyMwITAO
+BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOB
+gQAgm/ZLiIy9WEk9iJiyFe1kDdsE4ynkPj20WiB4Kreswi3KfLsRtPvbCLis8WPR
+FpSNtXsER3PVG4vfCbGmRlJo1gOI/uh0CqQWfp1E8ZAnsHWAJDjJCbmv0PKYAnvw
+tW5t0ekupdOT4rQixJuzJEM7zpWoKBSds+VJHRVysRvl9A==
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 9 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00bbe351f22cd50acab58fb3db3fac3bbcf03a15c3dbaf83c06e36957f301d04819a1353f87978b81c8104a50438806564bfd8c22a80e3d0973da5b8701d26d925961579b5e86dbf490e78270436a3c92739e6a99f839ad31dddd1365044491028efefeebd14d233cb1cf84ad62fb3ac3c4e5a08ac43a4d69482a5fe8d57e05ec9` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+        SEQUENCE {
+          # basicConstraints
+          OBJECT_IDENTIFIER { 2.5.29.19 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              BOOLEAN { `ff` }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0016ca2c0303547045178664c36b2b44c129a9a61c109c58b8d38854607e20b400b878d7732c95404925da7068f0a5d3f456055b0fa79d0ad0cb136ef6653fd3d1c7331ff47e256c9a60bfc01e0493ad731172659ed9478bb4b2148ae24060f266aeb455df86be037d4b3580ca727058e4af641f299060243a8ab8c8ebb8ee0972` }
+}
+-----BEGIN CERTIFICATE-----
+MIICCDCCAXGgAwIBAgIBCTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAfMR0wGwYDVQQDDBRUZXN0IEludGVybWVkaWF0ZSBDQTCBnzANBgkqhkiG
+9w0BAQEFAAOBjQAwgYkCgYEAu+NR8izVCsq1j7PbP6w7vPA6FcPbr4PAbjaVfzAd
+BIGaE1P4eXi4HIEEpQQ4gGVkv9jCKoDj0Jc9pbhwHSbZJZYVebXobb9JDngnBDaj
+ySc55qmfg5rTHd3RNlBESRAo7+/uvRTSM8sc+ErWL7OsPE5aCKxDpNaUgqX+jVfg
+XskCAwEAAaNQME4wKwYDVR0fBCQwIjAgoB6gHIYaaHR0cDovL2V4YW1wbGUuY29t
+L2Zvby5jcmwwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
+hvcNAQELBQADgYEAFsosAwNUcEUXhmTDaytEwSmpphwQnFi404hUYH4gtAC4eNdz
+LJVASSXacGjwpdP0VgVbD6edCtDLE272ZT/T0cczH/R+JWyaYL/AHgSTrXMRcmWe
+2UeLtLIUiuJAYPJmrrRV34a+A31LNYDKcnBY5K9kHymQYCQ6irjI67juCXI=
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/bad_idp_uri_and_onlycontainscacerts.pem b/pki/testdata/crl_unittest/bad_idp_uri_and_onlycontainscacerts.pem
new file mode 100644
index 0000000..1714a94
--- /dev/null
+++ b/pki/testdata/crl_unittest/bad_idp_uri_and_onlycontainscacerts.pem
@@ -0,0 +1,244 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf not covered by CRLs because IDP has onlyContainsCACerts (and URI, but the URI matches)
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    [0] {
+      SEQUENCE {
+        SEQUENCE {
+          # issuingDistributionPoint
+          OBJECT_IDENTIFIER { 2.5.29.28 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              [0] {
+                [0] {
+                  [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                }
+              }
+              [2 PRIMITIVE] { `ff` }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0009165fe23325882cfc40ada100d2b69d5bd42cf1be641b616c7217d03e24d897c7fab6b4edb210d31715bd4d1ff5c70ac34ec6367d00bf46b3b9a5a911ffbe486073ec4fea7080de6463bc644e0ac51f602761a0c8fdbb96b0d390474660075a0949969b90a6efc78813f27922b96388e6f9f9cd74551d47731e5bc705b8d21d` }
+}
+-----BEGIN CRL-----
+MIIBHDCBhgIBATANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0IEludGVy
+bWVkaWF0ZSBDQRcNMTcwMzAyMDAxMTIyWhcNMTcwNjAyMDAxMTIyWqAzMDEwLwYD
+VR0cAQH/BCUwI6AeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsggH/MA0G
+CSqGSIb3DQEBCwUAA4GBAAkWX+IzJYgs/ECtoQDStp1b1CzxvmQbYWxyF9A+JNiX
+x/q2tO2yENMXFb1NH/XHCsNOxjZ9AL9Gs7mlqRH/vkhgc+xP6nCA3mRjvGROCsUf
+YCdhoMj9u5aw05BHRmAHWglJlpuQpu/HiBPyeSK5Y4jm+fnNdFUdR3MeW8cFuNId
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00e79fb3855fb417ea2314409a8dc820f1dbc9c33ce7602402caa9a42e0713786bfc6601e50b799cc564e8ee22126eff408d2f3c06a78002e4a4d3430d6514c63eab3be74f221b91c424d030b36cd1a42eca57e93c0e381c158371e35fbc7d08ae51ca312aa2647887fabb0d6d7378497466fb052a0aa3bc69cc0def4bbf19563b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+        SEQUENCE {
+          # basicConstraints
+          OBJECT_IDENTIFIER { 2.5.29.19 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              BOOLEAN { `ff` }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00264e1bb2a4887c61168dce49c2b6bfd3b4d1050855b24b05325ea8f10673ccae042aa88912a8ee203ba3283467d6a9234329d9a1a9b60dd281f947c5adcd1b3e97aca3d83d75cbb4709b2f086de9beee39ffea8f500e1a0ba2338e8a0499436d43a024cc97480d511dd51298e952f14ada84b1115b6bf1f29923704cdd917ff2` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBzjCCATegAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDnn7OFX7QX6iMUQJqNyCDx28nDPOdgJALKqaQuBxN4a/xmAeULeZzFZOju
+IhJu/0CNLzwGp4AC5KTTQw1lFMY+qzvnTyIbkcQk0DCzbNGkLspX6TwOOBwVg3Hj
+X7x9CK5RyjEqomR4h/q7DW1zeEl0ZvsFKgqjvGnMDe9LvxlWOwIDAQABoyMwITAO
+BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOB
+gQAmThuypIh8YRaNzknCtr/TtNEFCFWySwUyXqjxBnPMrgQqqIkSqO4gO6MoNGfW
+qSNDKdmhqbYN0oH5R8WtzRs+l6yj2D11y7Rwmy8Ibem+7jn/6o9QDhoLojOOigSZ
+Q21DoCTMl0gNUR3VEpjpUvFK2oSxEVtr8fKZI3BM3ZF/8g==
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00c4162472b586a8e3ee4c879d7882a74272c293cd57033e21e4236773678b49c271330f605f13d01c7c65f2652e789074c370c5550a3871a56fd0f2760316490c7b3bd1a3aa005c4adb7a495450b643c9cc29b8f63db229f9ac0ce75feb66bd085a4a98e0fc7292784d17b952111f50c065be34dd711a53bab534351e8ef748f7` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+        SEQUENCE {
+          # basicConstraints
+          OBJECT_IDENTIFIER { 2.5.29.19 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {}
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `005002948c5ce09db4860b6ba54da3d1d37e2ef9f5e6dbb8845271d689327645b7052bfe9d8b3f5f7ceaa9f46840f73f666a850d9cad556ccd21520776cf9bd2150c0f1f888c7765bd9a10e4d0bd66e7a7fb4af1d02f002fd9583e2de267182188ab319378eb9950c08262e308d1ef9b17c802d1d711a88c04d2dc9758e8d80d3a` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB6jCCAVOgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBAMQWJHK1hqjj7kyHnXiCp0JywpPNVwM+IeQjZ3Nni0nCcTMPYF8T0Bx8
+ZfJlLniQdMNwxVUKOHGlb9DydgMWSQx7O9GjqgBcStt6SVRQtkPJzCm49j2yKfms
+DOdf62a9CFpKmOD8cpJ4TRe5UhEfUMBlvjTdcRpTurU0NR6O90j3AgMBAAGjPTA7
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMAwG
+A1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADgYEAUAKUjFzgnbSGC2ulTaPR034u
++fXm27iEUnHWiTJ2RbcFK/6diz9ffOqp9GhA9z9maoUNnK1VbM0hUgd2z5vSFQwP
+H4iMd2W9mhDk0L1m56f7SvHQLwAv2Vg+LeJnGCGIqzGTeOuZUMCCYuMI0e+bF8gC
+0dcRqIwE0tyXWOjYDTo=
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/bad_idp_uri_and_onlycontainsusercerts.pem b/pki/testdata/crl_unittest/bad_idp_uri_and_onlycontainsusercerts.pem
new file mode 100644
index 0000000..2a73a32
--- /dev/null
+++ b/pki/testdata/crl_unittest/bad_idp_uri_and_onlycontainsusercerts.pem
@@ -0,0 +1,254 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+CA_NEW_BY_OLD not covered by CRLs because IDP has onlyContainsUserCerts (and URI, but the URI matches)
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    [0] {
+      SEQUENCE {
+        SEQUENCE {
+          # issuingDistributionPoint
+          OBJECT_IDENTIFIER { 2.5.29.28 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              [0] {
+                [0] {
+                  [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                }
+              }
+              [1 PRIMITIVE] { `ff` }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0096ba398dce85f87ed5eb6c6d0b759e476877e403d39c8a1ac480da9eda2db258ed7f7c5b78bd889657d54398461d58e4170b66ae5e389ea99d8aed81669c29cff95dd41c06f3e7233a07a8c5a9cd14094345a27ba826635da2ae4e1c1f2794afb3814a4c543979be9cbdb24e159c89f51d022b54e64ec8680e6a0c6deea06066` }
+}
+-----BEGIN CRL-----
+MIIBHDCBhgIBATANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0IEludGVy
+bWVkaWF0ZSBDQRcNMTcwMzAyMDAxMTIyWhcNMTcwNjAyMDAxMTIyWqAzMDEwLwYD
+VR0cAQH/BCUwI6AeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsgQH/MA0G
+CSqGSIb3DQEBCwUAA4GBAJa6OY3Ohfh+1etsbQt1nkdod+QD05yKGsSA2p7aLbJY
+7X98W3i9iJZX1UOYRh1Y5BcLZq5eOJ6pnYrtgWacKc/5XdQcBvPnIzoHqMWpzRQJ
+Q0Wie6gmY12irk4cHyeUr7OBSkxUOXm+nL2yThWcifUdAitU5k7IaA5qDG3uoGBm
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00e79fb3855fb417ea2314409a8dc820f1dbc9c33ce7602402caa9a42e0713786bfc6601e50b799cc564e8ee22126eff408d2f3c06a78002e4a4d3430d6514c63eab3be74f221b91c424d030b36cd1a42eca57e93c0e381c158371e35fbc7d08ae51ca312aa2647887fabb0d6d7378497466fb052a0aa3bc69cc0def4bbf19563b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+        SEQUENCE {
+          # basicConstraints
+          OBJECT_IDENTIFIER { 2.5.29.19 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              BOOLEAN { `ff` }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00264e1bb2a4887c61168dce49c2b6bfd3b4d1050855b24b05325ea8f10673ccae042aa88912a8ee203ba3283467d6a9234329d9a1a9b60dd281f947c5adcd1b3e97aca3d83d75cbb4709b2f086de9beee39ffea8f500e1a0ba2338e8a0499436d43a024cc97480d511dd51298e952f14ada84b1115b6bf1f29923704cdd917ff2` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBzjCCATegAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDnn7OFX7QX6iMUQJqNyCDx28nDPOdgJALKqaQuBxN4a/xmAeULeZzFZOju
+IhJu/0CNLzwGp4AC5KTTQw1lFMY+qzvnTyIbkcQk0DCzbNGkLspX6TwOOBwVg3Hj
+X7x9CK5RyjEqomR4h/q7DW1zeEl0ZvsFKgqjvGnMDe9LvxlWOwIDAQABoyMwITAO
+BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOB
+gQAmThuypIh8YRaNzknCtr/TtNEFCFWySwUyXqjxBnPMrgQqqIkSqO4gO6MoNGfW
+qSNDKdmhqbYN0oH5R8WtzRs+l6yj2D11y7Rwmy8Ibem+7jn/6o9QDhoLojOOigSZ
+Q21DoCTMl0gNUR3VEpjpUvFK2oSxEVtr8fKZI3BM3ZF/8g==
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 9 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00fb0ab8bad8a1cd08f6695198a2aa9ab4001d4aba6506d77dc882496cb2ebac00ed6bb2ca0635a3e62436d4037ed0d0ad2777b48f6311e6dcd8d0311b07e7a3bc54a13d9c1abf37bdd94b9a32b9626e4df5b8fbff46f1142b8b3d513d4922941ac3818cea5fb70e508903799ade9de8dd45462a3fceea995e46c407c78ef429ab` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+        SEQUENCE {
+          # basicConstraints
+          OBJECT_IDENTIFIER { 2.5.29.19 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              BOOLEAN { `ff` }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00cd414248339c9c017d5d2c4a10ac6b18b57b4e9acc8838794645d8e78678428b0eb15b96f23ae4ebea51db258108534dc620d60b12fdc465815acc6544b5eb2f0f93064f23127801a82a1d59683b5aacad4f7c42e34f9b8836f15769c360d962c50804fe37155a7f864f89f0dd677fdae8450cfc92ed0c3673111822b0c8f1a7` }
+}
+-----BEGIN CERTIFICATE-----
+MIICCDCCAXGgAwIBAgIBCTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAfMR0wGwYDVQQDDBRUZXN0IEludGVybWVkaWF0ZSBDQTCBnzANBgkqhkiG
+9w0BAQEFAAOBjQAwgYkCgYEA+wq4utihzQj2aVGYoqqatAAdSrplBtd9yIJJbLLr
+rADta7LKBjWj5iQ21AN+0NCtJ3e0j2MR5tzY0DEbB+ejvFShPZwavze92UuaMrli
+bk31uPv/RvEUK4s9UT1JIpQaw4GM6l+3DlCJA3ma3p3o3UVGKj/O6pleRsQHx470
+KasCAwEAAaNQME4wKwYDVR0fBCQwIjAgoB6gHIYaaHR0cDovL2V4YW1wbGUuY29t
+L2Zvby5jcmwwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
+hvcNAQELBQADgYEAzUFCSDOcnAF9XSxKEKxrGLV7TprMiDh5RkXY54Z4QosOsVuW
+8jrk6+pR2yWBCFNNxiDWCxL9xGWBWsxlRLXrLw+TBk8jEngBqCodWWg7WqytT3xC
+40+biDbxV2nDYNlixQgE/jcVWn+GT4nw3Wd/2uhFDPyS7Qw2cxEYIrDI8ac=
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/bad_key_rollover_signature.pem b/pki/testdata/crl_unittest/bad_key_rollover_signature.pem
new file mode 100644
index 0000000..64c7376
--- /dev/null
+++ b/pki/testdata/crl_unittest/bad_key_rollover_signature.pem
@@ -0,0 +1,285 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf issued by CA's new key which is signed by old key, but CRL isn't signed by either
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0065fd6ab2fa88327868bd5e6374816d5ee6beaadb6ae4378715b2ef368e2bea0df2866a6b53e5e95b802f6f5b15bbc242679cf05a85b1275b541fafcb855e3c5a7d817e342f37661dd68101f6976cca41fb3065a05b22967cc8dda09c89d1c34dc0cf8006c31b65d2339247f694b40797026f35c30105959497e5752c55dc4c53` }
+}
+-----BEGIN CRL-----
+MIHmMFECAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMloXDTE3MDYwMjAwMTEyMlowDQYJKoZIhvcN
+AQELBQADgYEAZf1qsvqIMnhovV5jdIFtXua+qttq5DeHFbLvNo4r6g3yhmprU+Xp
+W4Avb1sVu8JCZ5zwWoWxJ1tUH6/LhV48Wn2BfjQvN2Yd1oEB9pdsykH7MGWgWyKW
+fMjdoJyJ0cNNwM+ABsMbZdIzkkf2lLQHlwJvNcMBBZWUl+V1LFXcTFM=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 8 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b6e8ead8d014f4b5ddaf01f62b66392af991f70d2b011b2dc56de32a1e30d9d476848d31ebcb101094160590bf5ce992e347c8c0810a4d7717950d546c7ccbb966d560cf9042b511babdefc6d6018e95759081f78f1187486885ae0ce397cb49553edc356316cc86ba33cc984f9651658dc400f1d82a08478c65c9538883ec1b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004a64aa4f07ee7f6e9a156a637be6dfebf59562212b3cf0b6391153061331783e54aecbb67e9831480658cb7d07d2f96890ac2f9f8c8dbd726a0bb16aa3bd8104d9a8c3fdcbca2bc433e3cb4cf008d0caa9569bfce07f387e6d875ebe2bbfd18bdb960028c2b20de7a701c895b27e4976d989d7d819a21a836571974b94b49166` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIByjCCATOgAwIBAgIBCDANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAfMR0wGwYDVQQDDBRUZXN0IEludGVybWVkaWF0ZSBDQTCBnzANBgkqhkiG
+9w0BAQEFAAOBjQAwgYkCgYEAtujq2NAU9LXdrwH2K2Y5KvmR9w0rARstxW3jKh4w
+2dR2hI0x68sQEJQWBZC/XOmS40fIwIEKTXcXlQ1UbHzLuWbVYM+QQrURur3vxtYB
+jpV1kIH3jxGHSGiFrgzjl8tJVT7cNWMWzIa6M8yYT5ZRZY3EAPHYKghHjGXJU4iD
+7BsCAwEAAaMSMBAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBAEpk
+qk8H7n9umhVqY3vm3+v1lWIhKzzwtjkRUwYTMXg+VK7Ltn6YMUgGWMt9B9L5aJCs
+L5+Mjb1yaguxaqO9gQTZqMP9y8orxDPjy0zwCNDKqVab/OB/OH5th16+K7/Ri9uW
+ACjCsg3npwHIlbJ+SXbZidfYGaIag2Vxl0uUtJFm
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 9 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d93f6f55f607250217ce3500717d955de64ac5e21d179d2ee54b6b7657a267d8e3ff2d0bcbee37f4d32fda5d8930b393278cf34c260187455740aabb29c2e7e645087baecb5fbc341973ac10fd07972c2867f9a5048f5ff81d569d9c8337e5053ab9efd72c7c0164d7a4fdcb55dba8ec72a56c9c6b6c6d11ab866d8b06ab11d3` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0021a05085069b97f7b91a3ac48ea6c06c41514123547497009bb2e167a359f059fd94064805e3e3a37cd98be3f4ed1b30e66865af5d3bb5b4ad78abc0096614a4561f2bf38b344f2fdd7238a5ff2358f27cda07771421d73bed8cb418776c4b9682b120ee4260aa6fd5263e72d02733e5f0e634b27e08b7fb9184ee1bef4dd6df` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBCTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBANk/b1X2ByUCF841AHF9lV3mSsXiHRedLuVLa3ZXomfY4/8tC8vuN/TT
+L9pdiTCzkyeM80wmAYdFV0CquynC5+ZFCHuuy1+8NBlzrBD9B5csKGf5pQSPX/gd
+Vp2cgzflBTq579csfAFk16T9y1XbqOxypWyca2xtEauGbYsGqxHTAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBACGgUIUGm5f3uRo6xI6mwGxBUUEjVHSXAJuy4WejWfBZ
+/ZQGSAXj46N82Yvj9O0bMOZoZa9dO7W0rXirwAlmFKRWHyvzizRPL91yOKX/I1jy
+fNoHdxQh1zvtjLQYd2xLloKxIO5CYKpv1SY+ctAnM+Xw5jSyfgi3+5GE7hvvTdbf
+-----END CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00c06603ddfbd7981fc745bb9378d177f606816bea25105b7f5ed9b0499bf506f3dc2687e8ee1375d183106c75b0b8ad5010e9e7316a924285984592b5ed7aa4db77bff25a5c99ade2d1eae254a3c1daf09e4194f987ac9f213582a627b9be45e64a50fd2c8b9e21c702125a6b5391d4f86d51e722689f1db653228912140d592b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `001e4faf090e17d359da4f6cc765fd51b135c2fde26d1210857d5bc7038dfa90b79d1db40557423419c4330973363fa5331d90f347055010ee1e8625675161a32cbacdcc6918b43dabd9d6c64a9a2942873db932f569c59cad35729fab922f99a0c08822d1c14bcf28f719d41f622a4006aefa71b032130bb7a6ef18359029162e` }
+}
+-----BEGIN CA CERTIFICATE 2-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDAZgPd+9eYH8dFu5N40Xf2BoFr6iUQW39e2bBJm/UG89wmh+juE3XRgxBs
+dbC4rVAQ6ecxapJChZhFkrXteqTbd7/yWlyZreLR6uJUo8Ha8J5BlPmHrJ8hNYKm
+J7m+ReZKUP0si54hxwISWmtTkdT4bVHnImifHbZTIokSFA1ZKwIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAHk+vCQ4X01naT2zHZf1R
+sTXC/eJtEhCFfVvHA436kLedHbQFV0I0GcQzCXM2P6UzHZDzRwVQEO4ehiVnUWGj
+LLrNzGkYtD2r2dbGSpopQoc9uTL1acWcrTVyn6uSL5mgwIgi0cFLzyj3GdQfYipA
+Bq76cbAyEwu3pu8YNZApFi4=
+-----END CA CERTIFICATE 2-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/bad_nextupdate_too_old.pem b/pki/testdata/crl_unittest/bad_nextupdate_too_old.pem
new file mode 100644
index 0000000..1b3a9f2
--- /dev/null
+++ b/pki/testdata/crl_unittest/bad_nextupdate_too_old.pem
@@ -0,0 +1,205 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf covered by CRLs and not revoked, but nextUpdate time is before verification time
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170308001122Z" }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0068b68fccda7bed9cc934206c64056e6d77559803f7b5510edd7bd4cb64b1daa1912a6d07afa8f5af023b55be83fe56c30318e9f94dbe462d6705a8e8ecb222f5eb0f796c6ad9f344667334b0acf2bb0882472f4df39ccded272920dbfa256ecf490ac6d7879090e923ff3e19610f91f01029997c162bdef9d11b1571464d62d8` }
+}
+-----BEGIN CRL-----
+MIHmMFECAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMloXDTE3MDMwODAwMTEyMlowDQYJKoZIhvcN
+AQELBQADgYEAaLaPzNp77ZzJNCBsZAVubXdVmAP3tVEO3XvUy2Sx2qGRKm0Hr6j1
+rwI7Vb6D/lbDAxjp+U2+Ri1nBajo7LIi9esPeWxq2fNEZnM0sKzyuwiCRy9N85zN
+7ScpINv6JW7PSQrG14eQkOkj/z4ZYQ+R8BApmXwWK9750RsVcUZNYtg=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/bad_signature.pem b/pki/testdata/crl_unittest/bad_signature.pem
new file mode 100644
index 0000000..868b6db
--- /dev/null
+++ b/pki/testdata/crl_unittest/bad_signature.pem
@@ -0,0 +1,205 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+No revoked certs, but CRL signed by a different key
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0078a9f2df782474308f59ea3264098942c153e2eeb72132ff40ebadf26d4f02ac536f336829b78952ec006a878128e9645e45311d51abcebc0dc1be9d56f96a462fd2a4f153780d47fa65f7bb29655f5069d61370769faedebefc14a36bc623d23e8f550e21c60363c93d7c8bdcaa9d4c0ba1c5726f7de56b168fd223c5c12337` }
+}
+-----BEGIN CRL-----
+MIHmMFECAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMloXDTE3MDYwMjAwMTEyMlowDQYJKoZIhvcN
+AQELBQADgYEAeKny33gkdDCPWeoyZAmJQsFT4u63ITL/QOut8m1PAqxTbzNoKbeJ
+UuwAaoeBKOlkXkUxHVGrzrwNwb6dVvlqRi/SpPFTeA1H+mX3uyllX1Bp1hNwdp+u
+3r78FKNrxiPSPo9VDiHGA2PJPXyL3KqdTAuhxXJvfeVrFo/SI8XBIzc=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/bad_thisupdate_in_future.pem b/pki/testdata/crl_unittest/bad_thisupdate_in_future.pem
new file mode 100644
index 0000000..9dda254
--- /dev/null
+++ b/pki/testdata/crl_unittest/bad_thisupdate_in_future.pem
@@ -0,0 +1,205 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf covered by CRLs and not revoked, but thisUpdate is in the future
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170310001122Z" }
+    UTCTime { "170602001122Z" }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00beeb9207854afb6f3df6301227032bf559afc4c00e0adc246a607c9c878240f1489395cdde0447145d8be82f0bb0cdbb75bd5d8fdd6bab55ae5b3842599573141ca80ef333d0286af6c6d937119c577f42e307dac2f7d636fd0dc96baa95b89a582990c92106eeb7bceb8331575eea0091124e99511ad70102e60c4b2da5d61d` }
+}
+-----BEGIN CRL-----
+MIHmMFECAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMxMDAwMTEyMloXDTE3MDYwMjAwMTEyMlowDQYJKoZIhvcN
+AQELBQADgYEAvuuSB4VK+2899jASJwMr9VmvxMAOCtwkamB8nIeCQPFIk5XN3gRH
+FF2L6C8LsM27db1dj91rq1WuWzhCWZVzFByoDvMz0Chq9sbZNxGcV39C4wfawvfW
+Nv0NyWuqlbiaWCmQySEG7re864MxV17qAJESTplRGtcBAuYMSy2l1h0=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/bad_thisupdate_too_old.pem b/pki/testdata/crl_unittest/bad_thisupdate_too_old.pem
new file mode 100644
index 0000000..b867524
--- /dev/null
+++ b/pki/testdata/crl_unittest/bad_thisupdate_too_old.pem
@@ -0,0 +1,205 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf covered by CRLs and not revoked, but thisUpdate time is more than 7 days before verification time
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170301001122Z" }
+    UTCTime { "170602001122Z" }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00948d052edf324f444299266fbd45eaf8f9b7fa303a2a2a72ac4b8f44366ff52b490e9ec28b0d505ed3b0281874feacfffe80c96e3448b8ea2994329b5161938e663c5d8eeef22e0d86d13845ae03bd04f61af71f74e6574146d4e18d2805864ca33fa4520f1e1b5436d6f57bab6e650369b25bb526b1c6991cb5767e8952b943` }
+}
+-----BEGIN CRL-----
+MIHmMFECAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMTAwMTEyMloXDTE3MDYwMjAwMTEyMlowDQYJKoZIhvcN
+AQELBQADgYEAlI0FLt8yT0RCmSZvvUXq+Pm3+jA6KipyrEuPRDZv9StJDp7Ciw1Q
+XtOwKBh0/qz//oDJbjRIuOoplDKbUWGTjmY8XY7u8i4NhtE4Ra4DvQT2GvcfdOZX
+QUbU4Y0oBYZMoz+kUg8eG1Q21vV7q25lA2myW7UmscaZHLV2folSuUM=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/bad_wrong_issuer.pem b/pki/testdata/crl_unittest/bad_wrong_issuer.pem
new file mode 100644
index 0000000..c382447
--- /dev/null
+++ b/pki/testdata/crl_unittest/bad_wrong_issuer.pem
@@ -0,0 +1,205 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+issuer name in CRL is different
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          PrintableString { "Test Unrelated CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0003b69609fbce1b37aee01b7a055e394e5d398c26e49e0b30bb98f992a84ae7c74e8159da02b5566f5982c9150ae0422e10461948d171012ea3b08c6d174248079c28f870d31166eac47b0594f0d8e06de795c59c5da909f0892387be5a3933c7fdfa329b6dfa8f3352f3b5002c511dba112eee0dd6e28e24e2732fa72bbe46d1` }
+}
+-----BEGIN CRL-----
+MIHjME4CAQEwDQYJKoZIhvcNAQELBQAwHDEaMBgGA1UEAxMRVGVzdCBVbnJlbGF0
+ZWQgQ0EXDTE3MDMwMjAwMTEyMloXDTE3MDYwMjAwMTEyMlowDQYJKoZIhvcNAQEL
+BQADgYEAA7aWCfvOGzeu4Bt6BV45Tl05jCbkngswu5j5kqhK58dOgVnaArVWb1mC
+yRUK4EIuEEYZSNFxAS6jsIxtF0JIB5wo+HDTEWbqxHsFlPDY4G3nlcWcXakJ8Ikj
+h75aOTPH/foym236jzNS87UALFEduhEu7g3W4o4k4nMvpyu+RtE=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/generate_crl_test_data.py b/pki/testdata/crl_unittest/generate_crl_test_data.py
new file mode 100755
index 0000000..6be4528
--- /dev/null
+++ b/pki/testdata/crl_unittest/generate_crl_test_data.py
@@ -0,0 +1,1725 @@
+#!/usr/bin/env python
+# 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.
+"""This script is called without any arguments to re-generate all of the *.pem
+files in the script's directory.
+
+The https://github.com/google/der-ascii tools must be in the PATH.
+
+These tests assume that the verification time will be 2017-03-09 00:00:00 GMT
+and verified with a max CRL age of 7 days.
+"""
+
+import datetime
+import subprocess
+import os
+
+from OpenSSL import crypto
+
+import base64
+
+
+HEADER = "Generated by %s. Do not edit." % os.path.split(__file__)[1]
+
+NEXT_SERIAL = 0
+
+# 2017-01-01 00:00 GMT
+CERT_DATE = datetime.datetime(2017, 1, 1, 0, 0)
+
+# 2018-01-01 00:00 GMT
+CERT_EXPIRE = CERT_DATE + datetime.timedelta(days=365)
+
+
+def DictUnion(a, b):
+  return dict(a.items() + b.items())
+
+
+def Der2Ascii(txt):
+  p = subprocess.Popen(['der2ascii'],
+                        stdin=subprocess.PIPE,
+                        stdout=subprocess.PIPE,
+                        stderr=subprocess.PIPE)
+  stdout_data, stderr_data = p.communicate(txt)
+  if p.returncode:
+    raise RuntimeError('der2ascii returned %i: %s' % (p.returncode,
+                                                      stderr_data))
+  return stdout_data
+
+
+def Ascii2Der(txt):
+  p = subprocess.Popen(['ascii2der'],
+                        stdin=subprocess.PIPE,
+                        stdout=subprocess.PIPE,
+                        stderr=subprocess.PIPE)
+  stdout_data, stderr_data = p.communicate(txt)
+  if p.returncode:
+    raise RuntimeError('ascii2der returned %i: %s' % (p.returncode,
+                                                      stderr_data))
+  return stdout_data
+
+
+def Ascii2OpensslDer(txt):
+  der = Ascii2Der(txt)
+  return 'DER:' + ''.join(['%02X' % ord(b) for b in der])
+
+
+def CreateCert(name, signer, pkey=None, crl_dp=None, key_usage=None,
+               is_ca=True, version=2):
+  global NEXT_SERIAL
+  if pkey is None:
+    pkey = crypto.PKey()
+    pkey.generate_key(crypto.TYPE_RSA, 1024)
+  cert = crypto.X509()
+  cert.set_version(version)
+  cert.get_subject().CN = name
+  cert.set_pubkey(pkey)
+  cert.set_serial_number(NEXT_SERIAL)
+  NEXT_SERIAL += 1
+  cert.set_notBefore(CERT_DATE.strftime('%Y%m%d%H%M%SZ'))
+  cert.set_notAfter(CERT_EXPIRE.strftime('%Y%m%d%H%M%SZ'))
+  if version == 2:
+    if crl_dp:
+      cert.add_extensions(
+          [crypto.X509Extension('crlDistributionPoints', False, crl_dp)])
+    if key_usage:
+      cert.add_extensions(
+          [crypto.X509Extension('keyUsage', False, key_usage)])
+    if is_ca is not None:
+      cert.add_extensions(
+          [crypto.X509Extension('basicConstraints', True,
+                                'CA:%s' % ('TRUE' if is_ca else 'FALSE'))])
+  if signer:
+    cert.set_issuer(signer['cert'].get_subject())
+    cert.sign(signer['pkey'], 'sha256')
+  else:
+    cert.set_issuer(cert.get_subject())
+    cert.sign(pkey, 'sha256')
+
+  result = dict(cert=cert, pkey=pkey)
+  if not signer:
+    signer = result
+  result['signer'] = signer
+  return result
+
+
+ROOT_CA = CreateCert('Test CA', None)
+
+# Multiple versions of the intermediate. All use the same name and private key.
+CA = CreateCert('Test Intermediate CA', ROOT_CA,
+                key_usage='critical, keyCertSign, cRLSign')
+CA_NO_KEYUSAGE = CreateCert('Test Intermediate CA', ROOT_CA,
+                            pkey=CA['pkey'], key_usage=None)
+CA_KEYUSAGE_NOCRLSIGN = CreateCert('Test Intermediate CA', ROOT_CA,
+                                   pkey=CA['pkey'],
+                                   key_usage='critical, keyCertSign')
+
+# A different CA with a different name and key.
+OTHER_CA = CreateCert('Test Other Intermediate CA', ROOT_CA)
+
+# The target cert, with a simple crlDistributionPoints pointing to an arbitrary
+# URL, other crlDistributionPoints fields not set.
+LEAF = CreateCert('Test Cert', CA, crl_dp='URI:http://example.com/foo.crl', is_ca=False)
+
+# The target cert, with no basicConstraints.
+LEAF_NO_BASIC_CONSTRAINTS = CreateCert('Test Cert', CA, crl_dp='URI:http://example.com/foo.crl', is_ca=None)
+
+# The target cert, no crlDistributionPoints.
+LEAF_NO_CRLDP = CreateCert('Test Cert', CA, is_ca=False)
+
+# V1 target cert
+LEAF_V1 = CreateCert('Test Cert', CA, version=0, is_ca=None)
+
+# The target cert, crlDistributionPoints with crlIssuer and
+# crlDistributionPoints set.
+LEAF_CRLDP_CRLISSUER = CreateCert('Test Cert', CA, is_ca=False,
+    # It doesn't seem like you can set crlIssuers through the one-line openssl
+    # interface, so just do it manually.
+    crl_dp=Ascii2OpensslDer('''
+         SEQUENCE {
+           SEQUENCE {
+             [0] {
+               [0] {
+                 [6 PRIMITIVE] { "http://example.com/foo.crl" }
+               }
+             }
+             [2] {
+               [4] {
+                 SEQUENCE {
+                   SET {
+                     SEQUENCE {
+                       # commonName
+                       OBJECT_IDENTIFIER { 2.5.4.3 }
+                       UTF8String { "Test CRL Issuer CA" }
+                     }
+                   }
+                 }
+               }
+             }
+           }
+         }
+         '''))
+
+# Self-issued intermediate with a new key signed by the |CA| key.
+CA_NEW_BY_OLD = CreateCert('Test Intermediate CA', CA,
+                           key_usage='critical, keyCertSign, cRLSign',
+                           crl_dp='URI:http://example.com/foo.crl')
+
+# Target cert signed by |CA_NEW_BY_OLD|'s key.
+LEAF_BY_NEW = CreateCert(
+    'Test Cert', CA_NEW_BY_OLD, crl_dp='URI:http://example.com/foo.crl')
+
+
+def SignAsciiCRL(tbs_inner_txt, signer=CA):
+  tbs_txt = 'SEQUENCE {\n%s\n}' % tbs_inner_txt
+  tbs_der = Ascii2Der(tbs_txt)
+  signature = crypto.sign(signer['pkey'], tbs_der, 'sha256')
+  crl_text = '''
+SEQUENCE {
+  %s
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00%s` }
+}
+''' % (tbs_txt, signature.encode('hex'))
+  CRL = Ascii2Der(crl_text)
+
+  return CRL
+
+
+def MakePemBlock(der, name):
+  text = Der2Ascii(der).rstrip('\n')
+  b64 = base64.b64encode(der)
+  wrapped = '\n'.join(b64[pos:pos + 64] for pos in xrange(0, len(b64), 64))
+  return '%s\n-----BEGIN %s-----\n%s\n-----END %s-----' % (
+      text, name, wrapped, name)
+
+
+def WriteStringToFile(data, path):
+  with open(path, "w") as f:
+    f.write(data)
+
+
+def Store(fname, description, leaf, ca, crl_der, ca2=None):
+  ca_cert_der = crypto.dump_certificate(crypto.FILETYPE_ASN1, ca['cert'])
+  cert_der = crypto.dump_certificate(crypto.FILETYPE_ASN1, leaf['cert'])
+
+  out = '\n\n'.join([
+      HEADER,
+      description,
+      MakePemBlock(crl_der, 'CRL'),
+      MakePemBlock(ca_cert_der, 'CA CERTIFICATE'),
+      MakePemBlock(cert_der, 'CERTIFICATE')])
+
+  if ca2:
+    ca_cert_2_der = crypto.dump_certificate(crypto.FILETYPE_ASN1, ca2['cert'])
+    out += '\n\n' + MakePemBlock(ca_cert_2_der, 'CA CERTIFICATE 2')
+
+  open('%s.pem' % fname, 'w').write(out)
+
+
+crl_strings = {
+  'sha256WithRSAEncryption': '''
+    SEQUENCE {
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+  ''',
+
+  'sha384WithRSAEncryption': '''
+    SEQUENCE {
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.12 }
+      NULL {}
+    }
+  ''',
+
+ 'CA_name': '''
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+  ''',
+
+  'thisUpdate': 'UTCTime { "170302001122Z" }',
+  'nextUpdate': 'UTCTime { "170602001122Z" }',
+  'thisUpdateGeneralized': 'GeneralizedTime { "20170302001122Z" }',
+  'nextUpdateGeneralized': 'GeneralizedTime { "20170602001122Z" }',
+  'thisUpdate_too_old': 'UTCTime { "170301001122Z" }',
+  'thisUpdate_in_future': 'UTCTime { "170310001122Z" }',
+  'nextUpdate_too_old': 'UTCTime { "170308001122Z" }',
+
+  'leaf_revoked': '''
+    SEQUENCE {
+      SEQUENCE {
+        INTEGER { %i }
+        UTCTime { "170201001122Z" }
+        # no crlEntryExtensions
+      }
+      SEQUENCE {
+        INTEGER { %i }
+        UTCTime { "170201001122Z" }
+        # no crlEntryExtensions
+      }
+      SEQUENCE {
+        INTEGER { %i }
+        UTCTime { "170201001122Z" }
+        # no crlEntryExtensions
+      }
+    }
+  ''' % (LEAF['cert'].get_serial_number() + 100,
+         LEAF['cert'].get_serial_number(),
+         LEAF['cert'].get_serial_number() + 101),
+
+  'leaf_revoked_fake_extension': '''
+    SEQUENCE {
+      SEQUENCE {
+        INTEGER { %i }
+        UTCTime { "170201001122Z" }
+        # no crlEntryExtensions
+      }
+      SEQUENCE {
+        INTEGER { %i }
+        UTCTime { "170201001122Z" }
+        SEQUENCE {
+          SEQUENCE {
+            OBJECT_IDENTIFIER { 1.2.3.4 }
+            OCTET_STRING { `5678` }
+          }
+        }
+      }
+      SEQUENCE {
+        INTEGER { %i }
+        UTCTime { "170201001122Z" }
+        # no crlEntryExtensions
+      }
+    }
+  ''' % (LEAF['cert'].get_serial_number() + 100,
+         LEAF['cert'].get_serial_number(),
+         LEAF['cert'].get_serial_number() + 101),
+
+  'leaf_revoked_before_fake_critical_extension': '''
+    SEQUENCE {
+      SEQUENCE {
+        INTEGER { %i }
+        UTCTime { "170201001122Z" }
+        # leaf revocation entry has no crlEntryExtensions
+      }
+      SEQUENCE {
+        INTEGER { %i }
+        UTCTime { "170201001122Z" }
+        # next revocation entry has a critical crlEntryExtension
+        SEQUENCE {
+          SEQUENCE {
+            OBJECT_IDENTIFIER { 1.2.3.4 }
+            BOOLEAN { `ff` }
+            OCTET_STRING { `5678` }
+          }
+        }
+      }
+    }
+  ''' % (LEAF['cert'].get_serial_number(),
+         LEAF['cert'].get_serial_number() + 101),
+
+  'leaf_revoked_generalizedtime': '''
+    SEQUENCE {
+      SEQUENCE {
+        INTEGER { %i }
+        GeneralizedTime { "20170201001122Z" }
+        # no crlEntryExtensions
+      }
+      SEQUENCE {
+        INTEGER { %i }
+        GeneralizedTime { "20170201001122Z" }
+        # no crlEntryExtensions
+      }
+      SEQUENCE {
+        INTEGER { %i }
+        GeneralizedTime { "20170201001122Z" }
+        # no crlEntryExtensions
+      }
+    }
+  ''' % (LEAF['cert'].get_serial_number() + 100,
+         LEAF['cert'].get_serial_number(),
+         LEAF['cert'].get_serial_number() + 101),
+
+  'fake_extension': '''
+     SEQUENCE {
+       OBJECT_IDENTIFIER { 1.2.3.4 }
+       OCTET_STRING { `5678` }
+     }
+  ''',
+
+  'fake_critical_extension': '''
+     SEQUENCE {
+       OBJECT_IDENTIFIER { 1.2.3.4 }
+       BOOLEAN { `ff` }
+       OCTET_STRING { `5678` }
+     }
+  ''',
+
+  # An issuingDistributionPoint with multiple fullName values, one of which
+  # matches the URI in |LEAF|'s crlDistributionPoints extension.
+  'issuingDistributionPoint': '''
+     SEQUENCE {
+       OBJECT_IDENTIFIER { 2.5.29.28 }
+       BOOLEAN { `ff` }
+       OCTET_STRING {
+         SEQUENCE {
+           [0] {
+             [0] {
+               [1 PRIMITIVE] { "foo@example.com" }
+               [6 PRIMITIVE] { "http://zexample.com/foo.crl" }
+               [6 PRIMITIVE] { "http://example.com/foo.crl" }
+               [6 PRIMITIVE] { "http://aexample.com/foo.crl" }
+             }
+           }
+         }
+       }
+     }
+  ''',
+
+  'issuingDistributionPoint_wrong_uri': '''
+     SEQUENCE {
+       OBJECT_IDENTIFIER { 2.5.29.28 }
+       BOOLEAN { `ff` }
+       OCTET_STRING {
+         SEQUENCE {
+           [0] {
+             [0] {
+               [6 PRIMITIVE] { "http://example.com/FOO.CRL" }
+             }
+           }
+         }
+       }
+     }
+  ''',
+
+  'issuingDistributionPoint_with_indirectCRL': '''
+     SEQUENCE {
+       OBJECT_IDENTIFIER { 2.5.29.28 }
+       BOOLEAN { `ff` }
+       OCTET_STRING {
+         SEQUENCE {
+           [0] {
+             [0] {
+               [6 PRIMITIVE] { "http://example.com/foo.crl" }
+             }
+           }
+           [4 PRIMITIVE] { `ff` }
+         }
+       }
+     }
+  ''',
+
+  'issuingDistributionPoint_with_onlyContainsUserCerts': '''
+     SEQUENCE {
+       OBJECT_IDENTIFIER { 2.5.29.28 }
+       BOOLEAN { `ff` }
+       OCTET_STRING {
+         SEQUENCE {
+           [1 PRIMITIVE] { `ff` }
+         }
+       }
+     }
+  ''',
+
+  'issuingDistributionPoint_with_uri_and_onlyContainsUserCerts': '''
+     SEQUENCE {
+       OBJECT_IDENTIFIER { 2.5.29.28 }
+       BOOLEAN { `ff` }
+       OCTET_STRING {
+         SEQUENCE {
+           [0] {
+             [0] {
+               [6 PRIMITIVE] { "http://example.com/foo.crl" }
+             }
+           }
+           [1 PRIMITIVE] { `ff` }
+         }
+       }
+     }
+  ''',
+
+  'issuingDistributionPoint_with_uri_and_onlyContainsCACerts': '''
+     SEQUENCE {
+       OBJECT_IDENTIFIER { 2.5.29.28 }
+       BOOLEAN { `ff` }
+       OCTET_STRING {
+         SEQUENCE {
+           [0] {
+             [0] {
+               [6 PRIMITIVE] { "http://example.com/foo.crl" }
+             }
+           }
+           [2 PRIMITIVE] { `ff` }
+         }
+       }
+     }
+  ''',
+
+  'issuingDistributionPoint_with_onlyContainsCACerts': '''
+     SEQUENCE {
+       OBJECT_IDENTIFIER { 2.5.29.28 }
+       BOOLEAN { `ff` }
+       OCTET_STRING {
+         SEQUENCE {
+           [2 PRIMITIVE] { `ff` }
+         }
+       }
+     }
+  ''',
+}
+
+
+Store(
+    'good',
+    'Leaf covered by CRLs and not revoked',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  # no crlExtensions
+''' % crl_strings))
+
+
+Store(
+    'good_issuer_name_normalization',
+    'Good, non-revoked, but issuer name in CRL requires case folding',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  SEQUENCE {
+    SET {
+      SEQUENCE {
+        # commonName
+        OBJECT_IDENTIFIER { 2.5.4.3 }
+        # Name that requires case folding and type conversion.
+        PrintableString { "tEST iNTERMEDIATE ca" }
+      }
+    }
+  }
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  # no crlExtensions
+''' % crl_strings))
+
+
+Store(
+    'good_issuer_no_keyusage',
+    'Leaf covered by CRLs and not revoked, issuer has no keyUsage extension',
+    LEAF, CA_NO_KEYUSAGE,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  # no crlExtensions
+''' % crl_strings, signer=CA_NO_KEYUSAGE))
+
+
+Store(
+    'good_no_nextupdate',
+    'Leaf covered by CRLs and not revoked, optional nextUpdate field is absent',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  # no nextUpdate
+  # no revoked certs list
+  # no crlExtensions
+''' % crl_strings))
+
+
+Store(
+    'good_fake_extension',
+    'Leaf covered by CRLs and not revoked, CRL has an irrelevant non-critical '
+    'extension',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  [0] {
+    SEQUENCE {
+      %(fake_extension)s
+    }
+  }
+''' % crl_strings))
+
+
+Store(
+    'good_fake_extension_no_nextupdate',
+    'Leaf covered by CRLs and not revoked, CRL has an irrelevant non-critical '
+    'extension',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  # no nextUpdate
+  # no revoked certs list
+  [0] {
+    SEQUENCE {
+      %(fake_extension)s
+    }
+  }
+''' % crl_strings))
+
+
+Store(
+    'good_generalizedtime',
+    'Leaf covered by CRLs and not revoked, dates encoded as GeneralizedTime',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdateGeneralized)s
+  %(nextUpdateGeneralized)s
+  # no revoked certs list
+  # no crlExtensions
+''' % crl_strings))
+
+
+Store(
+    'good_no_version',
+    'Leaf covered by CRLs and not revoked, CRL is V1',
+    LEAF, CA,
+    SignAsciiCRL('''
+  # no version
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  # no crlExtensions
+''' % crl_strings))
+
+
+Store(
+    'good_idp_contains_uri',
+    'Leaf covered by CRLs and not revoked, CRL has IDP with URI matching '
+    'cert DP',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  [0] {
+    SEQUENCE {
+      %(issuingDistributionPoint)s
+    }
+  }
+''' % crl_strings))
+
+
+Store(
+    'good_idp_onlycontainsusercerts',
+    'Leaf covered by CRLs and not revoked, CRL has IDP with '
+    'onlyContainsUserCerts',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  [0] {
+    SEQUENCE {
+      %(issuingDistributionPoint_with_onlyContainsUserCerts)s
+    }
+  }
+''' % crl_strings))
+
+
+Store(
+    'good_idp_onlycontainsusercerts_no_basic_constraints',
+    'Leaf covered by CRLs and not revoked, CRL has IDP with '
+    'onlyContainsUserCerts, leaf has no basicConstraints',
+    LEAF_NO_BASIC_CONSTRAINTS, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  [0] {
+    SEQUENCE {
+      %(issuingDistributionPoint_with_onlyContainsUserCerts)s
+    }
+  }
+''' % crl_strings))
+
+
+Store(
+    'good_idp_onlycontainscacerts',
+    'CA_NEW_BY_OLD covered by CRLs and not revoked, CRL has IDP with '
+    'onlyContainsCaCerts',
+    CA_NEW_BY_OLD, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  [0] {
+    SEQUENCE {
+      %(issuingDistributionPoint_with_onlyContainsCACerts)s
+    }
+  }
+''' % crl_strings))
+
+
+Store(
+    'good_idp_uri_and_onlycontainsusercerts',
+    'Leaf covered by CRLs and not revoked, CRL has IDP with URI and '
+    'onlyContainsUserCerts',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  [0] {
+    SEQUENCE {
+      %(issuingDistributionPoint_with_uri_and_onlyContainsUserCerts)s
+    }
+  }
+''' % crl_strings))
+
+
+Store(
+    'good_idp_uri_and_onlycontainscacerts',
+    'CA_NEW_BY_OLD covered by CRLs and not revoked, CRL has IDP with URI and '
+    'onlyContainsCACerts',
+    CA_NEW_BY_OLD, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  [0] {
+    SEQUENCE {
+      %(issuingDistributionPoint_with_uri_and_onlyContainsCACerts)s
+    }
+  }
+''' % crl_strings))
+
+
+Store(
+    'good_no_crldp',
+    'Leaf covered by CRLs and not revoked and has no crlDistributionPoints.\n'
+    'This tests the case where CheckCRL is called with a synthesized '
+    'distributionPoint.',
+    LEAF_NO_CRLDP, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  # no crlExtensions
+''' % crl_strings))
+
+
+Store(
+    'good_key_rollover',
+    "Leaf issued by CA's new key but CRL is signed by old key",
+    LEAF_BY_NEW, CA_NEW_BY_OLD, ca2=CA,
+    crl_der=SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  # no crlExtensions
+''' % crl_strings))
+
+
+Store(
+    'revoked',
+    'Leaf is revoked',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  %(leaf_revoked)s
+  # no crlExtensions
+''' % crl_strings))
+
+
+Store(
+    'revoked_no_nextupdate',
+    'Leaf is revoked, optional nextUpdate field is absent',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  # no nextUpdate
+  %(leaf_revoked)s
+  # no crlExtensions
+''' % crl_strings))
+
+
+Store(
+    'revoked_fake_crlentryextension',
+    'Leaf is revoked, has non-critical crlEntryExtension',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  %(leaf_revoked_fake_extension)s
+  # no crlExtensions
+''' % crl_strings))
+
+
+Store(
+    'revoked_generalized_revocationdate',
+    'Leaf is revoked, revocationDate is encoded as GeneralizedTime',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  %(leaf_revoked_generalizedtime)s
+  # no crlExtensions
+''' % crl_strings))
+
+
+Store(
+    'revoked_key_rollover',
+    "Leaf issued by CA's new key but CRL is signed by old key",
+    LEAF_BY_NEW, CA_NEW_BY_OLD, ca2=CA,
+    crl_der=SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  SEQUENCE {
+    SEQUENCE {
+      INTEGER { %(LEAF_SERIAL)i }
+      UTCTime { "170201001122Z" }
+      # no crlEntryExtensions
+    }
+  }
+  # no crlExtensions
+''' % DictUnion(crl_strings,
+                {'LEAF_SERIAL':LEAF_BY_NEW['cert'].get_serial_number()})))
+
+
+Store(
+    'bad_crldp_has_crlissuer',
+    'Leaf covered by CRLs and not revoked, leaf has crlDistributionPoints '
+    'with a crlIssuer',
+    LEAF_CRLDP_CRLISSUER, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  # no crlExtensions
+''' % crl_strings))
+
+
+Store(
+    'bad_fake_critical_extension',
+    'Leaf covered by CRLs and not revoked, but CRL has an unhandled critical '
+    'extension',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  # no nextUpdate
+  # no revoked certs list
+  [0] {
+    SEQUENCE {
+      %(fake_critical_extension)s
+    }
+  }
+''' % crl_strings))
+
+
+Store(
+    'bad_fake_critical_crlentryextension',
+    'Leaf is revoked, but a later entry has a critical crlEntryExtension',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  %(leaf_revoked_before_fake_critical_extension)s
+  # no crlExtensions
+''' % crl_strings))
+
+
+Store(
+    'bad_signature',
+    'No revoked certs, but CRL signed by a different key',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  # no crlExtensions
+''' % crl_strings, signer=OTHER_CA))
+
+
+Store(
+    'bad_thisupdate_in_future',
+    'Leaf covered by CRLs and not revoked, but thisUpdate is in the future',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate_in_future)s
+  %(nextUpdate)s
+  # no revoked certs list
+  # no crlExtensions
+''' % crl_strings))
+
+
+Store(
+    'bad_thisupdate_too_old',
+    'Leaf covered by CRLs and not revoked, but thisUpdate time is more than '
+    '7 days before verification time',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate_too_old)s
+  %(nextUpdate)s
+  # no revoked certs list
+  # no crlExtensions
+''' % crl_strings))
+
+
+Store(
+    'bad_nextupdate_too_old',
+    'Leaf covered by CRLs and not revoked, but nextUpdate time is before '
+    'verification time',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate_too_old)s
+  # no revoked certs list
+  # no crlExtensions
+''' % crl_strings))
+
+
+Store(
+    'bad_wrong_issuer',
+    'issuer name in CRL is different',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  SEQUENCE {
+    SET {
+      SEQUENCE {
+        # commonName
+        OBJECT_IDENTIFIER { 2.5.4.3 }
+        PrintableString { "Test Unrelated CA" }
+      }
+    }
+  }
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  # no crlExtensions
+''' % crl_strings))
+
+
+Store(
+    'bad_key_rollover_signature',
+    "Leaf issued by CA's new key which is signed by old key, but CRL isn't "
+    "signed by either",
+    LEAF_BY_NEW, CA_NEW_BY_OLD, ca2=CA,
+    crl_der=SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  # no crlExtensions
+''' % crl_strings, signer=OTHER_CA))
+
+
+Store(
+    'bad_idp_contains_wrong_uri',
+    'Leaf not covered by CRL (IDP with different URI)',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  [0] {
+    SEQUENCE {
+      %(issuingDistributionPoint_wrong_uri)s
+    }
+  }
+''' % crl_strings))
+
+
+Store(
+    'bad_idp_indirectcrl',
+    'CRL IDP name matches, but has indirectCRL flag set',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  [0] {
+    SEQUENCE {
+      %(issuingDistributionPoint_with_indirectCRL)s
+    }
+  }
+''' % crl_strings))
+
+
+Store(
+    'bad_idp_onlycontainscacerts',
+    'Leaf not covered by CRLs because IDP has onlyContainsCACerts',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  [0] {
+    SEQUENCE {
+      %(issuingDistributionPoint_with_onlyContainsCACerts)s
+    }
+  }
+''' % crl_strings))
+
+
+Store(
+    'bad_idp_onlycontainscacerts_no_basic_constraints',
+    'Leaf not covered by CRLs because IDP has onlyContainsCACerts, '
+    'leaf has no basicConstraints',
+    LEAF_NO_BASIC_CONSTRAINTS, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  [0] {
+    SEQUENCE {
+      %(issuingDistributionPoint_with_onlyContainsCACerts)s
+    }
+  }
+''' % crl_strings))
+
+
+Store(
+    'bad_idp_onlycontainsusercerts',
+    'CA_NEW_BY_OLD not covered by CRLs because IDP has '
+    'onlyContainsUserCerts',
+    CA_NEW_BY_OLD, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  [0] {
+    SEQUENCE {
+      %(issuingDistributionPoint_with_onlyContainsUserCerts)s
+    }
+  }
+''' % crl_strings))
+
+
+Store(
+    'bad_idp_uri_and_onlycontainsusercerts',
+    'CA_NEW_BY_OLD not covered by CRLs because IDP has '
+    'onlyContainsUserCerts (and URI, but the URI matches)',
+    CA_NEW_BY_OLD, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  [0] {
+    SEQUENCE {
+      %(issuingDistributionPoint_with_uri_and_onlyContainsUserCerts)s
+    }
+  }
+''' % crl_strings))
+
+
+Store(
+    'bad_idp_uri_and_onlycontainscacerts',
+    'Leaf not covered by CRLs because IDP has '
+    'onlyContainsCACerts (and URI, but the URI matches)',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  [0] {
+    SEQUENCE {
+      %(issuingDistributionPoint_with_uri_and_onlyContainsCACerts)s
+    }
+  }
+''' % crl_strings))
+
+
+Store(
+    'invalid_mismatched_signature_algorithm',
+    'Leaf covered by CRLs and not revoked, but signatureAlgorithm in '
+    'CertificateList does not match the one in TBSCertList.',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha384WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  # no crlExtensions
+''' % crl_strings))
+
+
+Store(
+    'invalid_revoked_empty_sequence',
+    'revokedCertificates is an empty sequence (should be omitted)',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  SEQUENCE {
+    # no revoked certs. revokedCertificates should be omitted in this case.
+  }
+  # no crlExtensions
+''' % crl_strings))
+
+
+Store(
+    'invalid_v1_with_extension',
+    'CRL is V1 and has crlExtensions',
+    LEAF, CA,
+    SignAsciiCRL('''
+  # no version
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  # no nextUpdate
+  # no revoked certs list
+  [0] {
+    SEQUENCE {
+      %(fake_extension)s
+    }
+  }
+''' % crl_strings))
+
+
+Store(
+    'invalid_v1_with_crlentryextension',
+    'Leaf is revoked, has non-critical crlEntryExtension, but CRL is V1',
+    LEAF, CA,
+    SignAsciiCRL('''
+  # no version
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  %(leaf_revoked_fake_extension)s
+  # no crlExtensions
+''' % crl_strings))
+
+
+Store(
+    'invalid_v1_explicit',
+    'CRL has explicit V1 version',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 0 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  # no crlExtensions
+''' % crl_strings))
+
+
+Store(
+    'invalid_v3',
+    'CRL has invalid V3 version',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 2 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  # no crlExtensions
+''' % crl_strings))
+
+
+Store(
+    'invalid_issuer_keyusage_no_crlsign',
+    'Leaf covered by CRLs and not revoked, issuer has keyUsage extension '
+    'without the cRLSign bit set',
+    LEAF, CA_KEYUSAGE_NOCRLSIGN,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  # no crlExtensions
+''' % crl_strings, signer=CA_KEYUSAGE_NOCRLSIGN))
+
+
+Store(
+    'invalid_key_rollover_issuer_keyusage_no_crlsign',
+    "Leaf issued by CA's new key but CRL is signed by old key, and the old "
+    "key cert has keyUsage extension without the cRLSign bit set",
+    LEAF_BY_NEW, CA_NEW_BY_OLD, ca2=CA_KEYUSAGE_NOCRLSIGN,
+    crl_der=SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  # no crlExtensions
+''' % crl_strings, signer=CA_KEYUSAGE_NOCRLSIGN))
+
+
+Store(
+    'invalid_garbage_version',
+    'CRL version is garbage',
+    LEAF, CA,
+    SignAsciiCRL('''
+  OCTET_STRING { `01` }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  # no crlExtensions
+''' % crl_strings))
+
+
+Store(
+    'invalid_garbage_tbs_signature_algorithm',
+    'CRL tbs signature algorithm is garbage',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  INTEGER { 1 }
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  # no crlExtensions
+''' % crl_strings))
+
+
+Store(
+    'invalid_garbage_issuer_name',
+    'CRL issuer is garbage',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  INTEGER { 1 }
+  %(thisUpdate)s
+  # no revoked certs list
+  # no crlExtensions
+''' % crl_strings))
+
+
+Store(
+    'invalid_garbage_thisupdate',
+    'CRL thisUpdate is garbage',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  INTEGER { 1 }
+  %(thisUpdate)s
+  # no revoked certs list
+  # no crlExtensions
+''' % crl_strings))
+
+
+Store(
+    'invalid_garbage_after_thisupdate',
+    'CRL garbage after thisupdate',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  # garbage:
+  INTEGER { 1 }
+''' % crl_strings))
+
+
+Store(
+    'invalid_garbage_after_nextupdate',
+    'CRL garbage after nextUpdate',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # garbage:
+  INTEGER { 1 }
+''' % crl_strings))
+
+
+Store(
+    'invalid_garbage_after_revokedcerts',
+    'CRL garbage after revokedCertificates',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  # no nextUpdate
+  %(leaf_revoked)s
+  # no crlExtensions
+  # garbage: nextUpdate doesn't go here:
+  %(nextUpdate)s
+''' % crl_strings))
+
+
+Store(
+    'invalid_garbage_after_extensions',
+    'CRL garbage after extensions',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  [0] {
+    SEQUENCE {
+      %(fake_extension)s
+    }
+  }
+  # Garbage: revoked certs sequence doesn't go here:
+  %(leaf_revoked)s
+''' % crl_strings))
+
+
+Store(
+    'invalid_garbage_tbscertlist',
+    'CRL garbage tbsCertList',
+    LEAF, CA,
+    Ascii2Der('''
+SEQUENCE {
+  OCTET_STRING { `5678` }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  # Actual signatureValue doesn't matter, shouldn't get to verifying signature.
+  BIT_STRING { `001a` }
+}
+'''))
+
+
+Store(
+    'invalid_garbage_signaturealgorithm',
+    'CRL garbage signatureAlgorithm',
+    LEAF, CA,
+    Ascii2Der('''
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    # tbsCertList contents doesn't matter, parsing shouldn't get this far.
+  }
+  OCTET_STRING { `5678` }
+  # Actual signatureValue doesn't matter, shouldn't get to verifying signature.
+  BIT_STRING { `001a` }
+}
+'''))
+
+
+Store(
+    'invalid_garbage_signaturevalue',
+    'CRL garbage signatureValue',
+    LEAF, CA,
+    Ascii2Der('''
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    # tbsCertList contents doesn't matter, parsing shouldn't get this far.
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  # Actual signatureValue contents don't matter, should be BIT_STRING rather
+  # than OCTET_STRING.
+  OCTET_STRING { `001a` }
+}
+'''))
+
+
+Store(
+    'invalid_garbage_after_signaturevalue',
+    'CRL garbage after signatureValue',
+    LEAF, CA,
+    Ascii2Der('''
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    # tbsCertList contents doesn't matter, parsing shouldn't get this far.
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  # Actual signatureValue doesn't matter, shouldn't get to verifying signature.
+  BIT_STRING { `001a` }
+  SEQUENCE {}
+}
+'''))
+
+Store(
+    'invalid_garbage_revoked_serial_number',
+    'Leaf is revoked but a following crlentry is garbage',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+    SEQUENCE {
+      SEQUENCE {
+        INTEGER { %(LEAF_SERIAL)i }
+        UTCTime { "170201001122Z" }
+        # no crlEntryExtensions
+      }
+      SEQUENCE {
+        OCTET_STRING { `7F`}
+        UTCTime { "170201001122Z" }
+        # no crlEntryExtensions
+      }
+    }
+  # no crlExtensions
+''' % (DictUnion(crl_strings,
+                 {'LEAF_SERIAL':LEAF['cert'].get_serial_number()}))))
+
+
+Store(
+    'invalid_garbage_revocationdate',
+    'Leaf is revoked but a following crlentry is garbage',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+    SEQUENCE {
+      SEQUENCE {
+        INTEGER { %(LEAF_SERIAL)i }
+        UTCTime { "170201001122Z" }
+        # no crlEntryExtensions
+      }
+      SEQUENCE {
+        INTEGER { 100001 }
+        OCTET_STRING { "170201001122Z" }
+        # no crlEntryExtensions
+      }
+    }
+  # no crlExtensions
+''' % (DictUnion(crl_strings,
+                 {'LEAF_SERIAL':LEAF['cert'].get_serial_number()}))))
+
+
+Store(
+    'invalid_garbage_after_revocationdate',
+    'Leaf is revoked but a following crlentry is garbage',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+    SEQUENCE {
+      SEQUENCE {
+        INTEGER { %(LEAF_SERIAL)i }
+        UTCTime { "170201001122Z" }
+        # no crlEntryExtensions
+      }
+      SEQUENCE {
+        INTEGER { 100001 }
+        UTCTime { "170201001122Z" }
+        INTEGER { 01 }
+      }
+    }
+  # no crlExtensions
+''' % (DictUnion(crl_strings,
+                 {'LEAF_SERIAL':LEAF['cert'].get_serial_number()}))))
+
+
+Store(
+    'invalid_garbage_after_crlentryextensions',
+    'Leaf is revoked but a following crlentry is garbage',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+    SEQUENCE {
+      SEQUENCE {
+        INTEGER { %(LEAF_SERIAL)i }
+        UTCTime { "170201001122Z" }
+        # no crlEntryExtensions
+      }
+      SEQUENCE {
+        INTEGER { 100001 }
+        UTCTime { "170201001122Z" }
+        SEQUENCE {
+          SEQUENCE {
+            OBJECT_IDENTIFIER { 1.2.3.4 }
+            OCTET_STRING { `5678` }
+          }
+        }
+        INTEGER { 01 }
+      }
+    }
+  # no crlExtensions
+''' % (DictUnion(crl_strings,
+                 {'LEAF_SERIAL':LEAF['cert'].get_serial_number()}))))
+
+
+Store(
+    'invalid_garbage_crlentry',
+    'Leaf is revoked but a following crlentry is garbage',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+    SEQUENCE {
+      SEQUENCE {
+        INTEGER { %(LEAF_SERIAL)i }
+        UTCTime { "170201001122Z" }
+        # no crlEntryExtensions
+      }
+      INTEGER { 01 }
+    }
+  # no crlExtensions
+''' % (DictUnion(crl_strings,
+                 {'LEAF_SERIAL':LEAF['cert'].get_serial_number()}))))
+
+
+Store(
+    'invalid_idp_dpname_choice_extra_data',
+    'IssuingDistributionPoint extension distributionPoint is invalid',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  [0] {
+    SEQUENCE {
+      SEQUENCE {
+        OBJECT_IDENTIFIER { 2.5.29.28 }
+        BOOLEAN { `ff` }
+        OCTET_STRING {
+          SEQUENCE {
+            [0] {
+              [0] {
+                [6 PRIMITIVE] { "http://example.com/foo.crl" }
+              }
+              [1] {
+                SET {
+                  SEQUENCE {
+                    # countryName
+                    OBJECT_IDENTIFIER { 2.5.4.6 }
+                    PrintableString { "US" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+''' % crl_strings))
+
+
+Store(
+    'invalid_idp_empty_sequence',
+    'IssuingDistributionPoint extension is invalid',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  [0] {
+    SEQUENCE {
+      SEQUENCE {
+        OBJECT_IDENTIFIER { 2.5.29.28 }
+        BOOLEAN { `ff` }
+        OCTET_STRING {
+          SEQUENCE {
+          }
+        }
+      }
+    }
+  }
+''' % crl_strings))
+
+
+Store(
+    'invalid_idp_onlycontains_user_and_ca_certs',
+    'IssuingDistributionPoint extension is invalid, cannot specify more than '
+    'one of onlyContainsUserCerts and onlyContainsCACerts',
+    LEAF, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  [0] {
+    SEQUENCE {
+      SEQUENCE {
+        OBJECT_IDENTIFIER { 2.5.29.28 }
+        BOOLEAN { `ff` }
+        OCTET_STRING {
+          SEQUENCE {
+           [1 PRIMITIVE] { `ff` }
+           [2 PRIMITIVE] { `ff` }
+          }
+        }
+      }
+    }
+  }
+''' % crl_strings))
+
+
+Store(
+    'invalid_idp_onlycontainsusercerts_v1_leaf',
+    'v1 leaf is covered by CRL with onlyContainsUserCerts, which is invalid',
+    LEAF_V1, CA,
+    SignAsciiCRL('''
+  INTEGER { 1 }
+  %(sha256WithRSAEncryption)s
+  %(CA_name)s
+  %(thisUpdate)s
+  %(nextUpdate)s
+  # no revoked certs list
+  [0] {
+    SEQUENCE {
+      %(issuingDistributionPoint_with_onlyContainsUserCerts)s
+    }
+  }
+''' % crl_strings))
diff --git a/pki/testdata/crl_unittest/good.pem b/pki/testdata/crl_unittest/good.pem
new file mode 100644
index 0000000..a9d53d7
--- /dev/null
+++ b/pki/testdata/crl_unittest/good.pem
@@ -0,0 +1,205 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf covered by CRLs and not revoked
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00588a2dbca80630842ffcd6a0a6fe17630d341e0e277c863069025b3169a727188cf7d22a985c027678e034c31c34141d102a7aef73039d1f51ce11261b069598c4b19bae39278bcdb245f55dc644f2165beac3f8aa8e19e13a27bb53cc19387f6afaf2ef8cbe5270380917abae7fa7c0ad4aaa7b70b1102d23951886d854a5cd` }
+}
+-----BEGIN CRL-----
+MIHmMFECAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMloXDTE3MDYwMjAwMTEyMlowDQYJKoZIhvcN
+AQELBQADgYEAWIotvKgGMIQv/Nagpv4XYw00Hg4nfIYwaQJbMWmnJxiM99IqmFwC
+dnjgNMMcNBQdECp673MDnR9RzhEmGwaVmMSxm645J4vNskX1XcZE8hZb6sP4qo4Z
+4Tonu1PMGTh/avry74y+UnA4CRerrn+nwK1KqntwsRAtI5UYhthUpc0=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/good_fake_extension.pem b/pki/testdata/crl_unittest/good_fake_extension.pem
new file mode 100644
index 0000000..a1d8df1
--- /dev/null
+++ b/pki/testdata/crl_unittest/good_fake_extension.pem
@@ -0,0 +1,214 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf covered by CRLs and not revoked, CRL has an irrelevant non-critical extension
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    [0] {
+      SEQUENCE {
+        SEQUENCE {
+          OBJECT_IDENTIFIER { 1.2.3.4 }
+          OCTET_STRING { "Vx" }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00c5d99500ed1caac34f485f353e2f694f24ae7130e88a2f40264a4a0deeede7ef4f749e453fb18c397893dcedb458b557370fdb82b6b9ebe298d941ef00713f51a7c30c9236d1a07e9e2fd4e3b854db9b0ddb64759a1234b9a4371fdb35de23fb80c149fd952969007530c6434425f6af57c31437d199a18b26f32beb4657120a` }
+}
+-----BEGIN CRL-----
+MIH1MGACAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMloXDTE3MDYwMjAwMTEyMlqgDTALMAkGAyoD
+BAQCVngwDQYJKoZIhvcNAQELBQADgYEAxdmVAO0cqsNPSF81Pi9pTySucTDoii9A
+JkpKDe7t5+9PdJ5FP7GMOXiT3O20WLVXNw/bgra56+KY2UHvAHE/UafDDJI20aB+
+ni/U47hU25sN22R1mhI0uaQ3H9s13iP7gMFJ/ZUpaQB1MMZDRCX2r1fDFDfRmaGL
+JvMr60ZXEgo=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/good_fake_extension_no_nextupdate.pem b/pki/testdata/crl_unittest/good_fake_extension_no_nextupdate.pem
new file mode 100644
index 0000000..9dc25cf
--- /dev/null
+++ b/pki/testdata/crl_unittest/good_fake_extension_no_nextupdate.pem
@@ -0,0 +1,212 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf covered by CRLs and not revoked, CRL has an irrelevant non-critical extension
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    [0] {
+      SEQUENCE {
+        SEQUENCE {
+          OBJECT_IDENTIFIER { 1.2.3.4 }
+          OCTET_STRING { "Vx" }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0026e97b3d61788f42d5d8cf180be03dbbbbf783a44a7898a0fe9316cc2e3eeee9b0e8ce82c1ee008dcfac46697e091a4c0855955207a0358667cc4ed88ad6cf65b0b760fa49f98304fb2f30b86169b88e7deaca6bbf9b826d7c2b2c29e324193934167350dd4221c6ae188ea2ab46abb6079b7909ab6e015a33fb4dddb10b209f` }
+}
+-----BEGIN CRL-----
+MIHmMFECAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMlqgDTALMAkGAyoDBAQCVngwDQYJKoZIhvcN
+AQELBQADgYEAJul7PWF4j0LV2M8YC+A9u7v3g6RKeJig/pMWzC4+7umw6M6Cwe4A
+jc+sRml+CRpMCFWVUgegNYZnzE7YitbPZbC3YPpJ+YME+y8wuGFpuI596sprv5uC
+bXwrLCnjJBk5NBZzUN1CIcauGI6iq0artgebeQmrbgFaM/tN3bELIJ8=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/good_generalizedtime.pem b/pki/testdata/crl_unittest/good_generalizedtime.pem
new file mode 100644
index 0000000..337e1d5
--- /dev/null
+++ b/pki/testdata/crl_unittest/good_generalizedtime.pem
@@ -0,0 +1,205 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf covered by CRLs and not revoked, dates encoded as GeneralizedTime
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    GeneralizedTime { "20170302001122Z" }
+    GeneralizedTime { "20170602001122Z" }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00bc22ab7658f1380249dd20456b4766b2737862b05086606fc496b9dc06fa82916c56b4b923e8f9036bf1ae44f9c3ba6e8d170182e3d5a7f4911b539d866ffbf11e636e7eae267a875c03d92cd9503daa943966d59908cd3ee655ad915ef8d77ff09ab20f406298e155a9722dc63d6ce2c1dc63010fdb9789827d50cdeb2ff12e` }
+}
+-----BEGIN CRL-----
+MIHqMFUCAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EYDzIwMTcwMzAyMDAxMTIyWhgPMjAxNzA2MDIwMDExMjJaMA0GCSqG
+SIb3DQEBCwUAA4GBALwiq3ZY8TgCSd0gRWtHZrJzeGKwUIZgb8SWudwG+oKRbFa0
+uSPo+QNr8a5E+cO6bo0XAYLj1af0kRtTnYZv+/EeY25+riZ6h1wD2SzZUD2qlDlm
+1ZkIzT7mVa2RXvjXf/Casg9AYpjhValyLcY9bOLB3GMBD9uXiYJ9UM3rL/Eu
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/good_idp_contains_uri.pem b/pki/testdata/crl_unittest/good_idp_contains_uri.pem
new file mode 100644
index 0000000..9918143
--- /dev/null
+++ b/pki/testdata/crl_unittest/good_idp_contains_uri.pem
@@ -0,0 +1,229 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf covered by CRLs and not revoked, CRL has IDP with URI matching cert DP
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    [0] {
+      SEQUENCE {
+        SEQUENCE {
+          # issuingDistributionPoint
+          OBJECT_IDENTIFIER { 2.5.29.28 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              [0] {
+                [0] {
+                  [1 PRIMITIVE] { "foo@example.com" }
+                  [6 PRIMITIVE] { "http://zexample.com/foo.crl" }
+                  [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  [6 PRIMITIVE] { "http://aexample.com/foo.crl" }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `006b659179378a15aac130d45749d08a24c91888959d8fb5356343e453d024c6517ad657f7ee509fa368b0ef54e6cc50077e25b67ee6caed57a15abd2dfd9e13564eb8bc39b75d96ca25215f00851293536d6e988c38e86339a9694d75e03e089116c74cb20f1bf1e8091d5dd946cda218af2810abe5854a2e17c77110b2fa263c` }
+}
+-----BEGIN CRL-----
+MIIBZDCBzgIBATANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0IEludGVy
+bWVkaWF0ZSBDQRcNMTcwMzAyMDAxMTIyWhcNMTcwNjAyMDAxMTIyWqB7MHkwdwYD
+VR0cAQH/BG0wa6BpoGeBD2Zvb0BleGFtcGxlLmNvbYYbaHR0cDovL3pleGFtcGxl
+LmNvbS9mb28uY3JshhpodHRwOi8vZXhhbXBsZS5jb20vZm9vLmNybIYbaHR0cDov
+L2FleGFtcGxlLmNvbS9mb28uY3JsMA0GCSqGSIb3DQEBCwUAA4GBAGtlkXk3ihWq
+wTDUV0nQiiTJGIiVnY+1NWND5FPQJMZRetZX9+5Qn6NosO9U5sxQB34ltn7myu1X
+oVq9Lf2eE1ZOuLw5t12WyiUhXwCFEpNTbW6YjDjoYzmpaU114D4IkRbHTLIPG/Ho
+CR1d2UbNohivKBCr5YVKLhfHcRCy+iY8
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00a35afbe7508b58895a28f81ebe71ea37f659fe29d1da13bd5b12460b8cf570dc57966aa97f06382fd01c4fbafc46564de12aa0d1d90d2060ad3f845189dab146559409c673b170edeb83bb56ecd2a7257b2283626d53f62e352c3edbb1a2198ddc73a92deb96b1beffd855f1e1aa005ae2ade2f763cbb0d0bd6cce4b768808c5` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0043b0323ab8f10378ccd100d12068c5bad3c32fdaa1b441ed1a4d52baa46aa967237345db8fdf03e0513825fd43c747aa710e371a88ae5ee4f460c59ddb6c5b08505feaa3cce3272e5c3d9b08a878822d5e601517b903537cb90e9085ec954c460f88af5217cb86e7c48be7d0847ec10f36a8df6177599d4a0d2ad4ea0ca857b2` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQCjWvvnUItYiVoo+B6+ceo39ln+KdHaE71bEkYLjPVw3FeWaql/Bjgv0BxP
+uvxGVk3hKqDR2Q0gYK0/hFGJ2rFGVZQJxnOxcO3rg7tW7NKnJXsig2JtU/YuNSw+
+27GiGY3cc6kt65axvv/YVfHhqgBa4q3i92PLsNC9bM5LdogIxQIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAQ7AyOrjxA3jM0QDRIGjF
+utPDL9qhtEHtGk1SuqRqqWcjc0Xbj98D4FE4Jf1Dx0eqcQ43GoiuXuT0YMWd22xb
+CFBf6qPM4ycuXD2bCKh4gi1eYBUXuQNTfLkOkIXslUxGD4ivUhfLhufEi+fQhH7B
+Dzao32F3WZ1KDSrU6gyoV7I=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00abdd04e5f0239dace20256547addf9df3ebb4081eacb549675116355e574620e2a350118cc9a03f754f73f93e1f95555db4f1533d14c50bebe6823c7e4032e2fa65536bdf33ff918c739680a809f4164f4c901c56d2c18785fc205f705b16086339be26d77d60de259dfbac76780ee5f2b416ff84566c5cc52a9d167ab818c67` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `000e3be5de5d0a6a2a155fa41f786443e6921899ed5566a1ba9fed2cec41dd925d1e077e3b9ce0aeacdf01261d31b828247da6d83d45a2ce469007d4dafda3603463b78bf18eff05e7b97521cbe10e44f185e945fdc09f637b982abbb2f1d380705305c0d63c207f622e6f14ed5509c68ecf907794de3a055137502ba47e37074d` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBAKvdBOXwI52s4gJWVHrd+d8+u0CB6stUlnURY1XldGIOKjUBGMyaA/dU
+9z+T4flVVdtPFTPRTFC+vmgjx+QDLi+mVTa98z/5GMc5aAqAn0Fk9MkBxW0sGHhf
+wgX3BbFghjOb4m131g3iWd+6x2eA7l8rQW/4RWbFzFKp0WergYxnAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAA475d5dCmoqFV+kH3hkQ+aSGJntVWahup/tLOxB3ZJd
+Hgd+O5zgrqzfASYdMbgoJH2m2D1Fos5GkAfU2v2jYDRjt4vxjv8F57l1IcvhDkTx
+helF/cCfY3uYKruy8dOAcFMFwNY8IH9iLm8U7VUJxo7PkHeU3joFUTdQK6R+NwdN
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/good_idp_onlycontainscacerts.pem b/pki/testdata/crl_unittest/good_idp_onlycontainscacerts.pem
new file mode 100644
index 0000000..71d2724
--- /dev/null
+++ b/pki/testdata/crl_unittest/good_idp_onlycontainscacerts.pem
@@ -0,0 +1,249 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+CA_NEW_BY_OLD covered by CRLs and not revoked, CRL has IDP with onlyContainsCaCerts
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    [0] {
+      SEQUENCE {
+        SEQUENCE {
+          # issuingDistributionPoint
+          OBJECT_IDENTIFIER { 2.5.29.28 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              [2 PRIMITIVE] { `ff` }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0091251c86c4252190f1148b40d9993cd075c8c797edd81f8cc14ce322368f3a47434f21d819231ae3c56fcb7a796b669a6a4fcc4980f112c1b5dcf6036cef1e77494d48cf8f16a85aa5dc05e17bd01217d67f52bbdd81ab70385d1800d755d2f4b878adbae521fc9b7c4386aef0b787d0beff34a3975933ce5191153f056c31cc` }
+}
+-----BEGIN CRL-----
+MIH7MGYCAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMloXDTE3MDYwMjAwMTEyMlqgEzARMA8GA1Ud
+HAEB/wQFMAOCAf8wDQYJKoZIhvcNAQELBQADgYEAkSUchsQlIZDxFItA2Zk80HXI
+x5ft2B+MwUzjIjaPOkdDTyHYGSMa48Vvy3p5a2aaak/MSYDxEsG13PYDbO8ed0lN
+SM+PFqhapdwF4XvQEhfWf1K73YGrcDhdGADXVdL0uHituuUh/Jt8Q4au8LeH0L7/
+NKOXWTPOUZEVPwVsMcw=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00f60f4a066d9dc05562f5c879444163b73be0b3d5e32dd7eff091af5d3c70bf3860067236894d085f581c70a1a8753d5b8882b263733e89a47b9989c36ce438b3b96ac16b1ca8878f2d51383055a17df6936c82b4f50729eb2f08f0f46f4106fa5975ec83c06f7d1135468354e01478e78474c56b6aca4d8a3e86ff7e494e6407` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+        SEQUENCE {
+          # basicConstraints
+          OBJECT_IDENTIFIER { 2.5.29.19 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              BOOLEAN { `ff` }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00209bf64b888cbd58493d8898b215ed640ddb04e329e43e3db45a20782ab7acc22dca7cbb11b4fbdb08b8acf163d116948db57b044773d51b8bdf09b1a6465268d60388fee8740aa4167e9d44f19027b075802438c909b9afd0f298027bf0b56e6dd1e92ea5d393e2b422c49bb324433bce95a828149db3e5491d1572b11be5f4` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBzjCCATegAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQD2D0oGbZ3AVWL1yHlEQWO3O+Cz1eMt1+/wka9dPHC/OGAGcjaJTQhfWBxw
+oah1PVuIgrJjcz6JpHuZicNs5DizuWrBaxyoh48tUTgwVaF99pNsgrT1BynrLwjw
+9G9BBvpZdeyDwG99ETVGg1TgFHjnhHTFa2rKTYo+hv9+SU5kBwIDAQABoyMwITAO
+BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOB
+gQAgm/ZLiIy9WEk9iJiyFe1kDdsE4ynkPj20WiB4Kreswi3KfLsRtPvbCLis8WPR
+FpSNtXsER3PVG4vfCbGmRlJo1gOI/uh0CqQWfp1E8ZAnsHWAJDjJCbmv0PKYAnvw
+tW5t0ekupdOT4rQixJuzJEM7zpWoKBSds+VJHRVysRvl9A==
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 9 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00bbe351f22cd50acab58fb3db3fac3bbcf03a15c3dbaf83c06e36957f301d04819a1353f87978b81c8104a50438806564bfd8c22a80e3d0973da5b8701d26d925961579b5e86dbf490e78270436a3c92739e6a99f839ad31dddd1365044491028efefeebd14d233cb1cf84ad62fb3ac3c4e5a08ac43a4d69482a5fe8d57e05ec9` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+        SEQUENCE {
+          # basicConstraints
+          OBJECT_IDENTIFIER { 2.5.29.19 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              BOOLEAN { `ff` }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0016ca2c0303547045178664c36b2b44c129a9a61c109c58b8d38854607e20b400b878d7732c95404925da7068f0a5d3f456055b0fa79d0ad0cb136ef6653fd3d1c7331ff47e256c9a60bfc01e0493ad731172659ed9478bb4b2148ae24060f266aeb455df86be037d4b3580ca727058e4af641f299060243a8ab8c8ebb8ee0972` }
+}
+-----BEGIN CERTIFICATE-----
+MIICCDCCAXGgAwIBAgIBCTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAfMR0wGwYDVQQDDBRUZXN0IEludGVybWVkaWF0ZSBDQTCBnzANBgkqhkiG
+9w0BAQEFAAOBjQAwgYkCgYEAu+NR8izVCsq1j7PbP6w7vPA6FcPbr4PAbjaVfzAd
+BIGaE1P4eXi4HIEEpQQ4gGVkv9jCKoDj0Jc9pbhwHSbZJZYVebXobb9JDngnBDaj
+ySc55qmfg5rTHd3RNlBESRAo7+/uvRTSM8sc+ErWL7OsPE5aCKxDpNaUgqX+jVfg
+XskCAwEAAaNQME4wKwYDVR0fBCQwIjAgoB6gHIYaaHR0cDovL2V4YW1wbGUuY29t
+L2Zvby5jcmwwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
+hvcNAQELBQADgYEAFsosAwNUcEUXhmTDaytEwSmpphwQnFi404hUYH4gtAC4eNdz
+LJVASSXacGjwpdP0VgVbD6edCtDLE272ZT/T0cczH/R+JWyaYL/AHgSTrXMRcmWe
+2UeLtLIUiuJAYPJmrrRV34a+A31LNYDKcnBY5K9kHymQYCQ6irjI67juCXI=
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/good_idp_onlycontainsusercerts.pem b/pki/testdata/crl_unittest/good_idp_onlycontainsusercerts.pem
new file mode 100644
index 0000000..dcd9ab8
--- /dev/null
+++ b/pki/testdata/crl_unittest/good_idp_onlycontainsusercerts.pem
@@ -0,0 +1,239 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf covered by CRLs and not revoked, CRL has IDP with onlyContainsUserCerts
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    [0] {
+      SEQUENCE {
+        SEQUENCE {
+          # issuingDistributionPoint
+          OBJECT_IDENTIFIER { 2.5.29.28 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              [1 PRIMITIVE] { `ff` }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `002f2deff3f117300df880570eebe5789244d45c0fc6db66e0f90d740c55e2344278c301d237579ae2ae73d507b7e60efb244b49461b5c44aa708bc192a4040e1d58b7c22036c36f39acab389f363c50e97a8b62d051f7e94d08a2b465cf95fd04e500c16ea5f1e74b00c6b738abcbfda713bab4a1139ad54f412e70199a255658` }
+}
+-----BEGIN CRL-----
+MIH7MGYCAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMloXDTE3MDYwMjAwMTEyMlqgEzARMA8GA1Ud
+HAEB/wQFMAOBAf8wDQYJKoZIhvcNAQELBQADgYEALy3v8/EXMA34gFcO6+V4kkTU
+XA/G22bg+Q10DFXiNEJ4wwHSN1ea4q5z1Qe35g77JEtJRhtcRKpwi8GSpAQOHVi3
+wiA2w285rKs4nzY8UOl6i2LQUffpTQiitGXPlf0E5QDBbqXx50sAxrc4q8v9pxO6
+tKETmtVPQS5wGZolVlg=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00f60f4a066d9dc05562f5c879444163b73be0b3d5e32dd7eff091af5d3c70bf3860067236894d085f581c70a1a8753d5b8882b263733e89a47b9989c36ce438b3b96ac16b1ca8878f2d51383055a17df6936c82b4f50729eb2f08f0f46f4106fa5975ec83c06f7d1135468354e01478e78474c56b6aca4d8a3e86ff7e494e6407` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+        SEQUENCE {
+          # basicConstraints
+          OBJECT_IDENTIFIER { 2.5.29.19 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              BOOLEAN { `ff` }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00209bf64b888cbd58493d8898b215ed640ddb04e329e43e3db45a20782ab7acc22dca7cbb11b4fbdb08b8acf163d116948db57b044773d51b8bdf09b1a6465268d60388fee8740aa4167e9d44f19027b075802438c909b9afd0f298027bf0b56e6dd1e92ea5d393e2b422c49bb324433bce95a828149db3e5491d1572b11be5f4` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBzjCCATegAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQD2D0oGbZ3AVWL1yHlEQWO3O+Cz1eMt1+/wka9dPHC/OGAGcjaJTQhfWBxw
+oah1PVuIgrJjcz6JpHuZicNs5DizuWrBaxyoh48tUTgwVaF99pNsgrT1BynrLwjw
+9G9BBvpZdeyDwG99ETVGg1TgFHjnhHTFa2rKTYo+hv9+SU5kBwIDAQABoyMwITAO
+BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOB
+gQAgm/ZLiIy9WEk9iJiyFe1kDdsE4ynkPj20WiB4Kreswi3KfLsRtPvbCLis8WPR
+FpSNtXsER3PVG4vfCbGmRlJo1gOI/uh0CqQWfp1E8ZAnsHWAJDjJCbmv0PKYAnvw
+tW5t0ekupdOT4rQixJuzJEM7zpWoKBSds+VJHRVysRvl9A==
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b86043a5c55800fd75606bd07e94c08c4bbd7c2ed4bcb6f8caac436213ab24587377a0107678abcca31c31fd84b78636034a6ea4853d62bd86d8a5e4c8f741b6efdf1008696e8eed8f30db3fdc78ca13d39d6cca9bc1563111e0bace35ffca03ab146bf07bb4636f6b38cf8b2feb1336e3f209ff30aad4283468a997e8215329` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+        SEQUENCE {
+          # basicConstraints
+          OBJECT_IDENTIFIER { 2.5.29.19 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {}
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00af35a49085f242c33eaad6efba5c2906f7c0ebf5caa66ab2f5ed0a663287da5665963048df790ffb1f223b93a8a40c9a8d26a0d9f0a41dd3d706754a59bfb2579464f984aa7686de56b441759c42b7aeb50b5960eaa27cb469beaeaf2460c1b6d8246dc78d6fce2a05a26f7723f6a1b96c0faf912b4aa67ceaeb432a552e1cb4` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB6jCCAVOgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALhgQ6XFWAD9dWBr0H6UwIxLvXwu1Ly2+MqsQ2ITqyRYc3egEHZ4q8yj
+HDH9hLeGNgNKbqSFPWK9htil5Mj3Qbbv3xAIaW6O7Y8w2z/ceMoT051sypvBVjER
+4LrONf/KA6sUa/B7tGNvazjPiy/rEzbj8gn/MKrUKDRoqZfoIVMpAgMBAAGjPTA7
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMAwG
+A1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADgYEArzWkkIXyQsM+qtbvulwpBvfA
+6/XKpmqy9e0KZjKH2lZlljBI33kP+x8iO5OopAyajSag2fCkHdPXBnVKWb+yV5Rk
++YSqdobeVrRBdZxCt661C1lg6qJ8tGm+rq8kYMG22CRtx41vzioFom93I/ahuWwP
+r5ErSqZ86utDKlUuHLQ=
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/good_idp_onlycontainsusercerts_no_basic_constraints.pem b/pki/testdata/crl_unittest/good_idp_onlycontainsusercerts_no_basic_constraints.pem
new file mode 100644
index 0000000..e04556b
--- /dev/null
+++ b/pki/testdata/crl_unittest/good_idp_onlycontainsusercerts_no_basic_constraints.pem
@@ -0,0 +1,230 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf covered by CRLs and not revoked, CRL has IDP with onlyContainsUserCerts, leaf has no basicConstraints
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    [0] {
+      SEQUENCE {
+        SEQUENCE {
+          # issuingDistributionPoint
+          OBJECT_IDENTIFIER { 2.5.29.28 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              [1 PRIMITIVE] { `ff` }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `002f2deff3f117300df880570eebe5789244d45c0fc6db66e0f90d740c55e2344278c301d237579ae2ae73d507b7e60efb244b49461b5c44aa708bc192a4040e1d58b7c22036c36f39acab389f363c50e97a8b62d051f7e94d08a2b465cf95fd04e500c16ea5f1e74b00c6b738abcbfda713bab4a1139ad54f412e70199a255658` }
+}
+-----BEGIN CRL-----
+MIH7MGYCAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMloXDTE3MDYwMjAwMTEyMlqgEzARMA8GA1Ud
+HAEB/wQFMAOBAf8wDQYJKoZIhvcNAQELBQADgYEALy3v8/EXMA34gFcO6+V4kkTU
+XA/G22bg+Q10DFXiNEJ4wwHSN1ea4q5z1Qe35g77JEtJRhtcRKpwi8GSpAQOHVi3
+wiA2w285rKs4nzY8UOl6i2LQUffpTQiitGXPlf0E5QDBbqXx50sAxrc4q8v9pxO6
+tKETmtVPQS5wGZolVlg=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00f60f4a066d9dc05562f5c879444163b73be0b3d5e32dd7eff091af5d3c70bf3860067236894d085f581c70a1a8753d5b8882b263733e89a47b9989c36ce438b3b96ac16b1ca8878f2d51383055a17df6936c82b4f50729eb2f08f0f46f4106fa5975ec83c06f7d1135468354e01478e78474c56b6aca4d8a3e86ff7e494e6407` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+        SEQUENCE {
+          # basicConstraints
+          OBJECT_IDENTIFIER { 2.5.29.19 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              BOOLEAN { `ff` }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00209bf64b888cbd58493d8898b215ed640ddb04e329e43e3db45a20782ab7acc22dca7cbb11b4fbdb08b8acf163d116948db57b044773d51b8bdf09b1a6465268d60388fee8740aa4167e9d44f19027b075802438c909b9afd0f298027bf0b56e6dd1e92ea5d393e2b422c49bb324433bce95a828149db3e5491d1572b11be5f4` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBzjCCATegAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQD2D0oGbZ3AVWL1yHlEQWO3O+Cz1eMt1+/wka9dPHC/OGAGcjaJTQhfWBxw
+oah1PVuIgrJjcz6JpHuZicNs5DizuWrBaxyoh48tUTgwVaF99pNsgrT1BynrLwjw
+9G9BBvpZdeyDwG99ETVGg1TgFHjnhHTFa2rKTYo+hv9+SU5kBwIDAQABoyMwITAO
+BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOB
+gQAgm/ZLiIy9WEk9iJiyFe1kDdsE4ynkPj20WiB4Kreswi3KfLsRtPvbCLis8WPR
+FpSNtXsER3PVG4vfCbGmRlJo1gOI/uh0CqQWfp1E8ZAnsHWAJDjJCbmv0PKYAnvw
+tW5t0ekupdOT4rQixJuzJEM7zpWoKBSds+VJHRVysRvl9A==
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 6 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d19aa4fda893774bdad672e2be8ecc8d8e7c5b8348d67b663cd297e4f068b5ed78be1aa7dd8f7bd871faaa052007b40fb2468fc455f5a691774b55cae696c32d0d0e9f9545118d528fcd8932a9682e50f1aae0b5a88bcbc43308c1f5a230d1dacf8e3c229327784f6f9a6c5b12c9c575e9003f10e38527f94782a424b164a86f` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00e14d6cad7fe998eba094e9e36701bc7dfecf3cbf4eebae9d3a5b5e977de9a557633ed93ab642baa637631e131dd162f069d6430e0198914004c1a4876f621ed56c9fe4d4613f93d7d2ed5eca1b7dd0434aeb89e1e1caa57e686312ea38ff791db53409c1dfb3178a1e11e819c030063f1e16f487abc57dfe1ec1bf2c9e4934db` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBjANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBANGapP2ok3dL2tZy4r6OzI2OfFuDSNZ7ZjzSl+TwaLXteL4ap92Pe9hx
++qoFIAe0D7JGj8RV9aaRd0tVyuaWwy0NDp+VRRGNUo/NiTKpaC5Q8argtaiLy8Qz
+CMH1ojDR2s+OPCKTJ3hPb5psWxLJxXXpAD8Q44Un+UeCpCSxZKhvAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAOFNbK1/6ZjroJTp42cBvH3+zzy/TuuunTpbXpd96aVX
+Yz7ZOrZCuqY3Yx4THdFi8GnWQw4BmJFABMGkh29iHtVsn+TUYT+T19LtXsobfdBD
+SuuJ4eHKpX5oYxLqOP95HbU0CcHfsxeKHhHoGcAwBj8eFvSHq8V9/h7BvyyeSTTb
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/good_idp_uri_and_onlycontainscacerts.pem b/pki/testdata/crl_unittest/good_idp_uri_and_onlycontainscacerts.pem
new file mode 100644
index 0000000..5784f09
--- /dev/null
+++ b/pki/testdata/crl_unittest/good_idp_uri_and_onlycontainscacerts.pem
@@ -0,0 +1,254 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+CA_NEW_BY_OLD covered by CRLs and not revoked, CRL has IDP with onlyContainsCACerts
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    [0] {
+      SEQUENCE {
+        SEQUENCE {
+          # issuingDistributionPoint
+          OBJECT_IDENTIFIER { 2.5.29.28 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              [0] {
+                [0] {
+                  [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                }
+              }
+              [2 PRIMITIVE] { `ff` }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00c178b9f518f750b1af57ac18f4f2b2655073da220f27ab188badbb12ef009b2db63452a4517be6482862798e73eacd7cbd4d7ffc3ee10720cbed3e40c773dbc16f8697929f0e4806ba0a6462e423835777ad71b76bdf36dcf1e27774ea737fc2789d3454a681204f01660304472bf924cfb1ee4f0f0803b08d8038f00ae1dae9` }
+}
+-----BEGIN CRL-----
+MIIBHDCBhgIBATANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0IEludGVy
+bWVkaWF0ZSBDQRcNMTcwMzAyMDAxMTIyWhcNMTcwNjAyMDAxMTIyWqAzMDEwLwYD
+VR0cAQH/BCUwI6AeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsggH/MA0G
+CSqGSIb3DQEBCwUAA4GBAMF4ufUY91Cxr1esGPTysmVQc9oiDyerGIutuxLvAJst
+tjRSpFF75kgoYnmOc+rNfL1Nf/w+4Qcgy+0+QMdz28FvhpeSnw5IBroKZGLkI4NX
+d61xt2vfNtzx4nd06nN/wnidNFSmgSBPAWYDBEcr+STPse5PDwgDsI2AOPAK4drp
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00f60f4a066d9dc05562f5c879444163b73be0b3d5e32dd7eff091af5d3c70bf3860067236894d085f581c70a1a8753d5b8882b263733e89a47b9989c36ce438b3b96ac16b1ca8878f2d51383055a17df6936c82b4f50729eb2f08f0f46f4106fa5975ec83c06f7d1135468354e01478e78474c56b6aca4d8a3e86ff7e494e6407` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+        SEQUENCE {
+          # basicConstraints
+          OBJECT_IDENTIFIER { 2.5.29.19 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              BOOLEAN { `ff` }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00209bf64b888cbd58493d8898b215ed640ddb04e329e43e3db45a20782ab7acc22dca7cbb11b4fbdb08b8acf163d116948db57b044773d51b8bdf09b1a6465268d60388fee8740aa4167e9d44f19027b075802438c909b9afd0f298027bf0b56e6dd1e92ea5d393e2b422c49bb324433bce95a828149db3e5491d1572b11be5f4` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBzjCCATegAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQD2D0oGbZ3AVWL1yHlEQWO3O+Cz1eMt1+/wka9dPHC/OGAGcjaJTQhfWBxw
+oah1PVuIgrJjcz6JpHuZicNs5DizuWrBaxyoh48tUTgwVaF99pNsgrT1BynrLwjw
+9G9BBvpZdeyDwG99ETVGg1TgFHjnhHTFa2rKTYo+hv9+SU5kBwIDAQABoyMwITAO
+BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOB
+gQAgm/ZLiIy9WEk9iJiyFe1kDdsE4ynkPj20WiB4Kreswi3KfLsRtPvbCLis8WPR
+FpSNtXsER3PVG4vfCbGmRlJo1gOI/uh0CqQWfp1E8ZAnsHWAJDjJCbmv0PKYAnvw
+tW5t0ekupdOT4rQixJuzJEM7zpWoKBSds+VJHRVysRvl9A==
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 9 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00bbe351f22cd50acab58fb3db3fac3bbcf03a15c3dbaf83c06e36957f301d04819a1353f87978b81c8104a50438806564bfd8c22a80e3d0973da5b8701d26d925961579b5e86dbf490e78270436a3c92739e6a99f839ad31dddd1365044491028efefeebd14d233cb1cf84ad62fb3ac3c4e5a08ac43a4d69482a5fe8d57e05ec9` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+        SEQUENCE {
+          # basicConstraints
+          OBJECT_IDENTIFIER { 2.5.29.19 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              BOOLEAN { `ff` }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0016ca2c0303547045178664c36b2b44c129a9a61c109c58b8d38854607e20b400b878d7732c95404925da7068f0a5d3f456055b0fa79d0ad0cb136ef6653fd3d1c7331ff47e256c9a60bfc01e0493ad731172659ed9478bb4b2148ae24060f266aeb455df86be037d4b3580ca727058e4af641f299060243a8ab8c8ebb8ee0972` }
+}
+-----BEGIN CERTIFICATE-----
+MIICCDCCAXGgAwIBAgIBCTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAfMR0wGwYDVQQDDBRUZXN0IEludGVybWVkaWF0ZSBDQTCBnzANBgkqhkiG
+9w0BAQEFAAOBjQAwgYkCgYEAu+NR8izVCsq1j7PbP6w7vPA6FcPbr4PAbjaVfzAd
+BIGaE1P4eXi4HIEEpQQ4gGVkv9jCKoDj0Jc9pbhwHSbZJZYVebXobb9JDngnBDaj
+ySc55qmfg5rTHd3RNlBESRAo7+/uvRTSM8sc+ErWL7OsPE5aCKxDpNaUgqX+jVfg
+XskCAwEAAaNQME4wKwYDVR0fBCQwIjAgoB6gHIYaaHR0cDovL2V4YW1wbGUuY29t
+L2Zvby5jcmwwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
+hvcNAQELBQADgYEAFsosAwNUcEUXhmTDaytEwSmpphwQnFi404hUYH4gtAC4eNdz
+LJVASSXacGjwpdP0VgVbD6edCtDLE272ZT/T0cczH/R+JWyaYL/AHgSTrXMRcmWe
+2UeLtLIUiuJAYPJmrrRV34a+A31LNYDKcnBY5K9kHymQYCQ6irjI67juCXI=
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/good_idp_uri_and_onlycontainsusercerts.pem b/pki/testdata/crl_unittest/good_idp_uri_and_onlycontainsusercerts.pem
new file mode 100644
index 0000000..8f5d364
--- /dev/null
+++ b/pki/testdata/crl_unittest/good_idp_uri_and_onlycontainsusercerts.pem
@@ -0,0 +1,244 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf covered by CRLs and not revoked, CRL has IDP with onlyContainsUserCerts
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    [0] {
+      SEQUENCE {
+        SEQUENCE {
+          # issuingDistributionPoint
+          OBJECT_IDENTIFIER { 2.5.29.28 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              [0] {
+                [0] {
+                  [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                }
+              }
+              [1 PRIMITIVE] { `ff` }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `009a41c69e30a49b28b57ffbd85a35856d0eb161a02e00c55e68dac36b826bbae72197b3fea075d03f7f033eaaf8b75f0e47a8975509b3160425f7744c0a81bccbbb7f3fc109aab610ffb960aede74364952e7ba5a620bacbf51483e47061eb2346cac99285230e9bd06d82a06bfa7dee48766677de1f9eb3a5199a2ee750380c7` }
+}
+-----BEGIN CRL-----
+MIIBHDCBhgIBATANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0IEludGVy
+bWVkaWF0ZSBDQRcNMTcwMzAyMDAxMTIyWhcNMTcwNjAyMDAxMTIyWqAzMDEwLwYD
+VR0cAQH/BCUwI6AeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsgQH/MA0G
+CSqGSIb3DQEBCwUAA4GBAJpBxp4wpJsotX/72Fo1hW0OsWGgLgDFXmjaw2uCa7rn
+IZez/qB10D9/Az6q+LdfDkeol1UJsxYEJfd0TAqBvMu7fz/BCaq2EP+5YK7edDZJ
+Uue6WmILrL9RSD5HBh6yNGysmShSMOm9BtgqBr+n3uSHZmd94fnrOlGZou51A4DH
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00f60f4a066d9dc05562f5c879444163b73be0b3d5e32dd7eff091af5d3c70bf3860067236894d085f581c70a1a8753d5b8882b263733e89a47b9989c36ce438b3b96ac16b1ca8878f2d51383055a17df6936c82b4f50729eb2f08f0f46f4106fa5975ec83c06f7d1135468354e01478e78474c56b6aca4d8a3e86ff7e494e6407` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+        SEQUENCE {
+          # basicConstraints
+          OBJECT_IDENTIFIER { 2.5.29.19 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              BOOLEAN { `ff` }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00209bf64b888cbd58493d8898b215ed640ddb04e329e43e3db45a20782ab7acc22dca7cbb11b4fbdb08b8acf163d116948db57b044773d51b8bdf09b1a6465268d60388fee8740aa4167e9d44f19027b075802438c909b9afd0f298027bf0b56e6dd1e92ea5d393e2b422c49bb324433bce95a828149db3e5491d1572b11be5f4` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBzjCCATegAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQD2D0oGbZ3AVWL1yHlEQWO3O+Cz1eMt1+/wka9dPHC/OGAGcjaJTQhfWBxw
+oah1PVuIgrJjcz6JpHuZicNs5DizuWrBaxyoh48tUTgwVaF99pNsgrT1BynrLwjw
+9G9BBvpZdeyDwG99ETVGg1TgFHjnhHTFa2rKTYo+hv9+SU5kBwIDAQABoyMwITAO
+BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOB
+gQAgm/ZLiIy9WEk9iJiyFe1kDdsE4ynkPj20WiB4Kreswi3KfLsRtPvbCLis8WPR
+FpSNtXsER3PVG4vfCbGmRlJo1gOI/uh0CqQWfp1E8ZAnsHWAJDjJCbmv0PKYAnvw
+tW5t0ekupdOT4rQixJuzJEM7zpWoKBSds+VJHRVysRvl9A==
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b86043a5c55800fd75606bd07e94c08c4bbd7c2ed4bcb6f8caac436213ab24587377a0107678abcca31c31fd84b78636034a6ea4853d62bd86d8a5e4c8f741b6efdf1008696e8eed8f30db3fdc78ca13d39d6cca9bc1563111e0bace35ffca03ab146bf07bb4636f6b38cf8b2feb1336e3f209ff30aad4283468a997e8215329` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+        SEQUENCE {
+          # basicConstraints
+          OBJECT_IDENTIFIER { 2.5.29.19 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {}
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00af35a49085f242c33eaad6efba5c2906f7c0ebf5caa66ab2f5ed0a663287da5665963048df790ffb1f223b93a8a40c9a8d26a0d9f0a41dd3d706754a59bfb2579464f984aa7686de56b441759c42b7aeb50b5960eaa27cb469beaeaf2460c1b6d8246dc78d6fce2a05a26f7723f6a1b96c0faf912b4aa67ceaeb432a552e1cb4` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB6jCCAVOgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALhgQ6XFWAD9dWBr0H6UwIxLvXwu1Ly2+MqsQ2ITqyRYc3egEHZ4q8yj
+HDH9hLeGNgNKbqSFPWK9htil5Mj3Qbbv3xAIaW6O7Y8w2z/ceMoT051sypvBVjER
+4LrONf/KA6sUa/B7tGNvazjPiy/rEzbj8gn/MKrUKDRoqZfoIVMpAgMBAAGjPTA7
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMAwG
+A1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADgYEArzWkkIXyQsM+qtbvulwpBvfA
+6/XKpmqy9e0KZjKH2lZlljBI33kP+x8iO5OopAyajSag2fCkHdPXBnVKWb+yV5Rk
++YSqdobeVrRBdZxCt661C1lg6qJ8tGm+rq8kYMG22CRtx41vzioFom93I/ahuWwP
+r5ErSqZ86utDKlUuHLQ=
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/good_issuer_name_normalization.pem b/pki/testdata/crl_unittest/good_issuer_name_normalization.pem
new file mode 100644
index 0000000..dd951dc
--- /dev/null
+++ b/pki/testdata/crl_unittest/good_issuer_name_normalization.pem
@@ -0,0 +1,205 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Good, non-revoked, but issuer name in CRL requires case folding
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          PrintableString { "tEST iNTERMEDIATE ca" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `001a3b9d49161020f9be1ed5f0ebdc417dcdc637edd030eaa1f8bb221269193c02f48b8c37f89846aa54ba2cc69f3c1dcd1c1af0aa68ca063bb9341eb6b20d9dde6d44d8ff336f3aa0bae2832cccda4a52dbfdb77e1acb1f1b7a337c661dbb74a32c51501196a1393f7da1524b6714569493b892398bb28988a600054b245b17ee` }
+}
+-----BEGIN CRL-----
+MIHmMFECAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAxMUdEVTVCBpTlRFUk1F
+RElBVEUgY2EXDTE3MDMwMjAwMTEyMloXDTE3MDYwMjAwMTEyMlowDQYJKoZIhvcN
+AQELBQADgYEAGjudSRYQIPm+HtXw69xBfc3GN+3QMOqh+LsiEmkZPAL0i4w3+JhG
+qlS6LMafPB3NHBrwqmjKBju5NB62sg2d3m1E2P8zbzqguuKDLMzaSlLb/bd+Gssf
+G3ozfGYdu3SjLFFQEZahOT99oVJLZxRWlJO4kjmLsomIpgAFSyRbF+4=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/good_issuer_no_keyusage.pem b/pki/testdata/crl_unittest/good_issuer_no_keyusage.pem
new file mode 100644
index 0000000..dc8fde4
--- /dev/null
+++ b/pki/testdata/crl_unittest/good_issuer_no_keyusage.pem
@@ -0,0 +1,192 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf covered by CRLs and not revoked, issuer has no keyUsage extension
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00588a2dbca80630842ffcd6a0a6fe17630d341e0e277c863069025b3169a727188cf7d22a985c027678e034c31c34141d102a7aef73039d1f51ce11261b069598c4b19bae39278bcdb245f55dc644f2165beac3f8aa8e19e13a27bb53cc19387f6afaf2ef8cbe5270380917abae7fa7c0ad4aaa7b70b1102d23951886d854a5cd` }
+}
+-----BEGIN CRL-----
+MIHmMFECAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMloXDTE3MDYwMjAwMTEyMlowDQYJKoZIhvcN
+AQELBQADgYEAWIotvKgGMIQv/Nagpv4XYw00Hg4nfIYwaQJbMWmnJxiM99IqmFwC
+dnjgNMMcNBQdECp673MDnR9RzhEmGwaVmMSxm645J4vNskX1XcZE8hZb6sP4qo4Z
+4Tonu1PMGTh/avry74y+UnA4CRerrn+nwK1KqntwsRAtI5UYhthUpc0=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 2 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `009fb806f8b9724c4d8ea467cf4ba45d75dab0cbe702ae42b47c03a7c83749779cb1b1ae7f5e596ded1d8231734c3b46c186981f5b937676183b061290dfa42746f07c56f77097dd4922650286b062f6b2c1d0ad31d46fce873fe7a4bf65677b0ed63f2c529a61c7bbe8b7d381e238c9c57b716b1b42cae0e22a061747c2f440c1` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBqTCCARKgAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABMA0GCSqG
+SIb3DQEBCwUAA4GBAJ+4Bvi5ckxNjqRnz0ukXXXasMvnAq5CtHwDp8g3SXecsbGu
+f15Zbe0dgjFzTDtGwYaYH1uTdnYYOwYSkN+kJ0bwfFb3cJfdSSJlAoawYvaywdCt
+MdRvzoc/56S/ZWd7DtY/LFKaYce76LfTgeI4ycV7cWsbQsrg4ioGF0fC9EDB
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/good_key_rollover.pem b/pki/testdata/crl_unittest/good_key_rollover.pem
new file mode 100644
index 0000000..c4facd4
--- /dev/null
+++ b/pki/testdata/crl_unittest/good_key_rollover.pem
@@ -0,0 +1,285 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf issued by CA's new key but CRL is signed by old key
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0020558426a4eec452d6c1e7489bb265595b2b90f645746ae1c1e3e6532c527eda46b23eda281bf99aa2950e1514d72fe540751a799b04dc1945b14956494e24e1cbbf04eb027167962fb72f56d249c849e5575cd86cf967a6d1f9691433f40a21a5db5630d9ac3d425e0832549807e9f5cfb8a916931ec5182c86971f834a3405` }
+}
+-----BEGIN CRL-----
+MIHmMFECAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMloXDTE3MDYwMjAwMTEyMlowDQYJKoZIhvcN
+AQELBQADgYEAIFWEJqTuxFLWwedIm7JlWVsrkPZFdGrhwePmUyxSftpGsj7aKBv5
+mqKVDhUU1y/lQHUaeZsE3BlFsUlWSU4k4cu/BOsCcWeWL7cvVtJJyEnlV1zYbPln
+ptH5aRQz9AohpdtWMNmsPUJeCDJUmAfp9c+4qRaTHsUYLIaXH4NKNAU=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 8 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b6e8ead8d014f4b5ddaf01f62b66392af991f70d2b011b2dc56de32a1e30d9d476848d31ebcb101094160590bf5ce992e347c8c0810a4d7717950d546c7ccbb966d560cf9042b511babdefc6d6018e95759081f78f1187486885ae0ce397cb49553edc356316cc86ba33cc984f9651658dc400f1d82a08478c65c9538883ec1b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004a64aa4f07ee7f6e9a156a637be6dfebf59562212b3cf0b6391153061331783e54aecbb67e9831480658cb7d07d2f96890ac2f9f8c8dbd726a0bb16aa3bd8104d9a8c3fdcbca2bc433e3cb4cf008d0caa9569bfce07f387e6d875ebe2bbfd18bdb960028c2b20de7a701c895b27e4976d989d7d819a21a836571974b94b49166` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIByjCCATOgAwIBAgIBCDANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAfMR0wGwYDVQQDDBRUZXN0IEludGVybWVkaWF0ZSBDQTCBnzANBgkqhkiG
+9w0BAQEFAAOBjQAwgYkCgYEAtujq2NAU9LXdrwH2K2Y5KvmR9w0rARstxW3jKh4w
+2dR2hI0x68sQEJQWBZC/XOmS40fIwIEKTXcXlQ1UbHzLuWbVYM+QQrURur3vxtYB
+jpV1kIH3jxGHSGiFrgzjl8tJVT7cNWMWzIa6M8yYT5ZRZY3EAPHYKghHjGXJU4iD
+7BsCAwEAAaMSMBAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBAEpk
+qk8H7n9umhVqY3vm3+v1lWIhKzzwtjkRUwYTMXg+VK7Ltn6YMUgGWMt9B9L5aJCs
+L5+Mjb1yaguxaqO9gQTZqMP9y8orxDPjy0zwCNDKqVab/OB/OH5th16+K7/Ri9uW
+ACjCsg3npwHIlbJ+SXbZidfYGaIag2Vxl0uUtJFm
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 9 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d93f6f55f607250217ce3500717d955de64ac5e21d179d2ee54b6b7657a267d8e3ff2d0bcbee37f4d32fda5d8930b393278cf34c260187455740aabb29c2e7e645087baecb5fbc341973ac10fd07972c2867f9a5048f5ff81d569d9c8337e5053ab9efd72c7c0164d7a4fdcb55dba8ec72a56c9c6b6c6d11ab866d8b06ab11d3` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0021a05085069b97f7b91a3ac48ea6c06c41514123547497009bb2e167a359f059fd94064805e3e3a37cd98be3f4ed1b30e66865af5d3bb5b4ad78abc0096614a4561f2bf38b344f2fdd7238a5ff2358f27cda07771421d73bed8cb418776c4b9682b120ee4260aa6fd5263e72d02733e5f0e634b27e08b7fb9184ee1bef4dd6df` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBCTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBANk/b1X2ByUCF841AHF9lV3mSsXiHRedLuVLa3ZXomfY4/8tC8vuN/TT
+L9pdiTCzkyeM80wmAYdFV0CquynC5+ZFCHuuy1+8NBlzrBD9B5csKGf5pQSPX/gd
+Vp2cgzflBTq579csfAFk16T9y1XbqOxypWyca2xtEauGbYsGqxHTAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBACGgUIUGm5f3uRo6xI6mwGxBUUEjVHSXAJuy4WejWfBZ
+/ZQGSAXj46N82Yvj9O0bMOZoZa9dO7W0rXirwAlmFKRWHyvzizRPL91yOKX/I1jy
+fNoHdxQh1zvtjLQYd2xLloKxIO5CYKpv1SY+ctAnM+Xw5jSyfgi3+5GE7hvvTdbf
+-----END CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00c06603ddfbd7981fc745bb9378d177f606816bea25105b7f5ed9b0499bf506f3dc2687e8ee1375d183106c75b0b8ad5010e9e7316a924285984592b5ed7aa4db77bff25a5c99ade2d1eae254a3c1daf09e4194f987ac9f213582a627b9be45e64a50fd2c8b9e21c702125a6b5391d4f86d51e722689f1db653228912140d592b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `001e4faf090e17d359da4f6cc765fd51b135c2fde26d1210857d5bc7038dfa90b79d1db40557423419c4330973363fa5331d90f347055010ee1e8625675161a32cbacdcc6918b43dabd9d6c64a9a2942873db932f569c59cad35729fab922f99a0c08822d1c14bcf28f719d41f622a4006aefa71b032130bb7a6ef18359029162e` }
+}
+-----BEGIN CA CERTIFICATE 2-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDAZgPd+9eYH8dFu5N40Xf2BoFr6iUQW39e2bBJm/UG89wmh+juE3XRgxBs
+dbC4rVAQ6ecxapJChZhFkrXteqTbd7/yWlyZreLR6uJUo8Ha8J5BlPmHrJ8hNYKm
+J7m+ReZKUP0si54hxwISWmtTkdT4bVHnImifHbZTIokSFA1ZKwIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAHk+vCQ4X01naT2zHZf1R
+sTXC/eJtEhCFfVvHA436kLedHbQFV0I0GcQzCXM2P6UzHZDzRwVQEO4ehiVnUWGj
+LLrNzGkYtD2r2dbGSpopQoc9uTL1acWcrTVyn6uSL5mgwIgi0cFLzyj3GdQfYipA
+Bq76cbAyEwu3pu8YNZApFi4=
+-----END CA CERTIFICATE 2-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/good_no_crldp.pem b/pki/testdata/crl_unittest/good_no_crldp.pem
new file mode 100644
index 0000000..d4b8020
--- /dev/null
+++ b/pki/testdata/crl_unittest/good_no_crldp.pem
@@ -0,0 +1,209 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf covered by CRLs and not revoked and has no crlDistributionPoints.
+This tests the case where CheckCRL is called with a synthesized distributionPoint.
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0091924cb896e010f9afbbb946ff76203e39915dd23353743196256b04c594869475eb41441cf14fd9f83d2b1b7ccbd78527ebe5375ac502d0b7fd5416dc0972d6089b6d7cbb5c1af7068541ec292fb8a451325a1efc496886dc75cb32d625afe1c21e81d8689f183670009a4e4af8882bfb82c3301fc2412c1e4ecb1923ca9a12` }
+}
+-----BEGIN CRL-----
+MIHmMFECAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMloXDTE3MDYwMjAwMTEyMlowDQYJKoZIhvcN
+AQELBQADgYEAkZJMuJbgEPmvu7lG/3YgPjmRXdIzU3QxliVrBMWUhpR160FEHPFP
+2fg9Kxt8y9eFJ+vlN1rFAtC3/VQW3Aly1gibbXy7XBr3BoVB7CkvuKRRMloe/Elo
+htx1yzLWJa/hwh6B2GifGDZwAJpOSviIK/uCwzAfwkEsHk7LGSPKmhI=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00ad1720bb9ea16d76a76a659decc0b5e4b3a93e3852d3899bb0fbff0d31e4996d5d488d8b169ffd1b0b030b4969ab99191190c4107b9c92be097d46d0835e993f546bd4b8cd2a508e7578c590ec667898a12cada775a2338059ec565fd177dc445a1008f665dbaffa0b1d34f390caa8c611cb6b126df75566db5bcfa5c5a6cc7d` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+        SEQUENCE {
+          # basicConstraints
+          OBJECT_IDENTIFIER { 2.5.29.19 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              BOOLEAN { `ff` }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00604b045a10bb186cc936b77d28093d479bd89627c762a53411d6060cba7acc7a4861fc27b35c2b1c50f55d4e2f96050bb6478780c1fa93136d20a0a8d26b14818485690860907b69519c1a22abfd508a5bb4da5825c00ccba70c2e362e056e5929176785566d06fd454369570fdaefe551a3a9e7fbb241a55986978f7accbe7d` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBzjCCATegAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQCtFyC7nqFtdqdqZZ3swLXks6k+OFLTiZuw+/8NMeSZbV1IjYsWn/0bCwML
+SWmrmRkRkMQQe5ySvgl9RtCDXpk/VGvUuM0qUI51eMWQ7GZ4mKEsrad1ojOAWexW
+X9F33ERaEAj2Zduv+gsdNPOQyqjGEctrEm33VWbbW8+lxabMfQIDAQABoyMwITAO
+BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOB
+gQBgSwRaELsYbMk2t30oCT1Hm9iWJ8dipTQR1gYMunrMekhh/CezXCscUPVdTi+W
+BQu2R4eAwfqTE20goKjSaxSBhIVpCGCQe2lRnBoiq/1Qilu02lglwAzLpwwuNi4F
+blkpF2eFVm0G/UVDaVcP2u/lUaOp5/uyQaVZhpePesy+fQ==
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 7 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b8c0bec26a099fbc4ef454675953b15ef3048fdf1070d28376123c6479a7c2e4501afc202de597cb6b862337eba9572de84752eb628cd10effb34693a0d4d1b8ecd00dc18f5c76d04c0ebb58895df4bfc17088e183bc62a64c3d524942fa868da0c592d666cdb88baa9d7edb85b247c84660c9b64c5d00204f4752315df54e51` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # basicConstraints
+          OBJECT_IDENTIFIER { 2.5.29.19 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {}
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `003dc4429a30e9926a5554889f9366894e152b172b75718869be6f639f3bc8f911185a24dfadb865d27b9bcec7b64b503acb5784a5bdf65d8e757a567596d56ff01b542229f14a81c91408c8d8fff46b1b23a132e2773b392517ee3986c52bae5f0e25e5dae587c76a6ac62366b33ded781804b504abfb4ac667c48dfef0f112f2` }
+}
+-----BEGIN CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBBzANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALjAvsJqCZ+8TvRUZ1lTsV7zBI/fEHDSg3YSPGR5p8LkUBr8IC3ll8tr
+hiM366lXLehHUutijNEO/7NGk6DU0bjs0A3Bj1x20EwOu1iJXfS/wXCI4YO8YqZM
+PVJJQvqGjaDFktZmzbiLqp1+24WyR8hGYMm2TF0AIE9HUjFd9U5RAgMBAAGjEDAO
+MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADgYEAPcRCmjDpkmpVVIifk2aJ
+ThUrFyt1cYhpvm9jnzvI+REYWiTfrbhl0nubzse2S1A6y1eEpb32XY51elZ1ltVv
+8BtUIinxSoHJFAjI2P/0axsjoTLidzs5JRfuOYbFK65fDiXl2uWHx2pqxiNmsz3t
+eBgEtQSr+0rGZ8SN/vDxEvI=
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/good_no_nextupdate.pem b/pki/testdata/crl_unittest/good_no_nextupdate.pem
new file mode 100644
index 0000000..e7c73ea
--- /dev/null
+++ b/pki/testdata/crl_unittest/good_no_nextupdate.pem
@@ -0,0 +1,204 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf covered by CRLs and not revoked, optional nextUpdate field is absent
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0059b3e124f21f95c050d38df1062713dbf0d485abd30e3d588c580b645bf667ae5ed20a81dc9f86e4b20cc0d27b48296d6cba4863747ed7498afb1e015e47890764940e6586f6ddf4938e54cc7a84111cb0172e406ccac5d52eb0f1e5a0a432a3ffab718030ad49a1501466e1a4c5a5c8ae19e067ca69ffa32986cf3bc8fa66dd` }
+}
+-----BEGIN CRL-----
+MIHXMEICAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMlowDQYJKoZIhvcNAQELBQADgYEAWbPhJPIf
+lcBQ043xBicT2/DUhavTDj1YjFgLZFv2Z65e0gqB3J+G5LIMwNJ7SCltbLpIY3R+
+10mK+x4BXkeJB2SUDmWG9t30k45UzHqEERywFy5AbMrF1S6w8eWgpDKj/6txgDCt
+SaFQFGbhpMWlyK4Z4GfKaf+jKYbPO8j6Zt0=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/good_no_version.pem b/pki/testdata/crl_unittest/good_no_version.pem
new file mode 100644
index 0000000..8e4565a
--- /dev/null
+++ b/pki/testdata/crl_unittest/good_no_version.pem
@@ -0,0 +1,204 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf covered by CRLs and not revoked, CRL is V1
+
+SEQUENCE {
+  SEQUENCE {
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `002a61e69852e5d444564fdadeeb50892d944ec685658a199eeaab3baaa8916deff23e018892320c1b922c84f299f7e311bf50975530ca9834893ade9515930265b315475dd4addbf7dcb6e003686b0dea3b7b3bc0f624f711f73cc10b68274184722e2bf79b0842f479613d1a286116853228cba11d141bf52b45a1563259dc7b` }
+}
+-----BEGIN CRL-----
+MIHjME4wDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1lZGlh
+dGUgQ0EXDTE3MDMwMjAwMTEyMloXDTE3MDYwMjAwMTEyMlowDQYJKoZIhvcNAQEL
+BQADgYEAKmHmmFLl1ERWT9re61CJLZROxoVlihme6qs7qqiRbe/yPgGIkjIMG5Is
+hPKZ9+MRv1CXVTDKmDSJOt6VFZMCZbMVR13Urdv33LbgA2hrDeo7ezvA9iT3Efc8
+wQtoJ0GEci4r95sIQvR5YT0aKGEWhTIoy6EdFBv1K0WhVjJZ3Hs=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/invalid_garbage_after_crlentryextensions.pem b/pki/testdata/crl_unittest/invalid_garbage_after_crlentryextensions.pem
new file mode 100644
index 0000000..e374aba
--- /dev/null
+++ b/pki/testdata/crl_unittest/invalid_garbage_after_crlentryextensions.pem
@@ -0,0 +1,224 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf is revoked but a following crlentry is garbage
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    SEQUENCE {
+      SEQUENCE {
+        INTEGER { 5 }
+        UTCTime { "170201001122Z" }
+      }
+      SEQUENCE {
+        INTEGER { `0186a1` }
+        UTCTime { "170201001122Z" }
+        SEQUENCE {
+          SEQUENCE {
+            OBJECT_IDENTIFIER { 1.2.3.4 }
+            OCTET_STRING { "Vx" }
+          }
+        }
+        INTEGER { 1 }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `007817704bcebfb93d4a43ce9fc22b5e8e271aa7507b2f2623625bfad336bffd7cc902f04396cef8cfd22cbc4dd19835732f323427b73efe7f4de86175704133f1b2a9ebd683ba361d7b1b3d7c5c1eb29eacf069d15906f323dfef099f88acca3fced86f3054ad8d78c41b16afe7348ef63318b22d377efacf83cb272d5af3004c` }
+}
+-----BEGIN CRL-----
+MIIBIzCBjQIBATANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0IEludGVy
+bWVkaWF0ZSBDQRcNMTcwMzAyMDAxMTIyWhcNMTcwNjAyMDAxMTIyWjA6MBICAQUX
+DTE3MDIwMTAwMTEyMlowJAIDAYahFw0xNzAyMDEwMDExMjJaMAswCQYDKgMEBAJW
+eAIBATANBgkqhkiG9w0BAQsFAAOBgQB4F3BLzr+5PUpDzp/CK16OJxqnUHsvJiNi
+W/rTNr/9fMkC8EOWzvjP0iy8TdGYNXMvMjQntz7+f03oYXVwQTPxsqnr1oO6Nh17
+Gz18XB6ynqzwadFZBvMj3+8Jn4isyj/O2G8wVK2NeMQbFq/nNI72MxiyLTd++s+D
+yyctWvMATA==
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/invalid_garbage_after_extensions.pem b/pki/testdata/crl_unittest/invalid_garbage_after_extensions.pem
new file mode 100644
index 0000000..3b43156
--- /dev/null
+++ b/pki/testdata/crl_unittest/invalid_garbage_after_extensions.pem
@@ -0,0 +1,229 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+CRL garbage after extensions
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    [0] {
+      SEQUENCE {
+        SEQUENCE {
+          OBJECT_IDENTIFIER { 1.2.3.4 }
+          OCTET_STRING { "Vx" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        INTEGER { 105 }
+        UTCTime { "170201001122Z" }
+      }
+      SEQUENCE {
+        INTEGER { 5 }
+        UTCTime { "170201001122Z" }
+      }
+      SEQUENCE {
+        INTEGER { 106 }
+        UTCTime { "170201001122Z" }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0057e0c594cbb0f00ec76295a434b45e1436139d82ef2330889344a59766e05081b7b053148d7f0344170c59e31b5c62f21b8557d0fb7eb0bc2db092848eac5f8a41a9ccfafa764baf8f3f041c5e51c254cf106e804ba69ff88f9dea7d7720325b1b440ab32f6295d800bf0b1afdb7a523dea87fff5dd7626d036774c2e6c60f32` }
+}
+-----BEGIN CRL-----
+MIIBNDCBngIBATANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0IEludGVy
+bWVkaWF0ZSBDQRcNMTcwMzAyMDAxMTIyWhcNMTcwNjAyMDAxMTIyWqANMAswCQYD
+KgMEBAJWeDA8MBICAWkXDTE3MDIwMTAwMTEyMlowEgIBBRcNMTcwMjAxMDAxMTIy
+WjASAgFqFw0xNzAyMDEwMDExMjJaMA0GCSqGSIb3DQEBCwUAA4GBAFfgxZTLsPAO
+x2KVpDS0XhQ2E52C7yMwiJNEpZdm4FCBt7BTFI1/A0QXDFnjG1xi8huFV9D7frC8
+LbCShI6sX4pBqcz6+nZLr48/BBxeUcJUzxBugEumn/iPnep9dyAyWxtECrMvYpXY
+AL8LGv23pSPeqH//XddibQNndMLmxg8y
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/invalid_garbage_after_nextupdate.pem b/pki/testdata/crl_unittest/invalid_garbage_after_nextupdate.pem
new file mode 100644
index 0000000..9df6b52
--- /dev/null
+++ b/pki/testdata/crl_unittest/invalid_garbage_after_nextupdate.pem
@@ -0,0 +1,206 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+CRL garbage after nextUpdate
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    INTEGER { 1 }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004d0bd09c1bd7247262b060443aff865d5532690d580772e092d76d601b0196420a22f8362ac5c2cace8d4a2ad17ceb9bc492ca11600026e85088173ed6169079fd9c48f1ac8126280105ef800fa69bbaa0b41e21c0b910100e2cbfeee7242bbff83fcc71c6e58652d88c73452ab96b08ccb640d41e26d731d359780a2fb97cf8` }
+}
+-----BEGIN CRL-----
+MIHpMFQCAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMloXDTE3MDYwMjAwMTEyMloCAQEwDQYJKoZI
+hvcNAQELBQADgYEATQvQnBvXJHJisGBEOv+GXVUyaQ1YB3LgktdtYBsBlkIKIvg2
+KsXCys6NSirRfOubxJLKEWAAJuhQiBc+1haQef2cSPGsgSYoAQXvgA+mm7qgtB4h
+wLkQEA4sv+7nJCu/+D/MccblhlLYjHNFKrlrCMy2QNQeJtcx01l4Ci+5fPg=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/invalid_garbage_after_revocationdate.pem b/pki/testdata/crl_unittest/invalid_garbage_after_revocationdate.pem
new file mode 100644
index 0000000..1ffbc25
--- /dev/null
+++ b/pki/testdata/crl_unittest/invalid_garbage_after_revocationdate.pem
@@ -0,0 +1,217 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf is revoked but a following crlentry is garbage
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    SEQUENCE {
+      SEQUENCE {
+        INTEGER { 5 }
+        UTCTime { "170201001122Z" }
+      }
+      SEQUENCE {
+        INTEGER { `0186a1` }
+        UTCTime { "170201001122Z" }
+        INTEGER { 1 }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `003d1bfd317ce0f173fcca74ecc0cf5392fc1f91e7e46fd1546e6f96761608f8454b2c15f8c7723c2248ff25e4cc655b1c2c288ca88cc36e6c00bb366ab5bf380eaa779b9a62f579fac97134eacc0291034a25d1659cfc862d3df6513f4e9c7dd4ebe183bc6e69edbcfeaca43df8fb557d7f75f14cfbfa28ee1357a7904f437934` }
+}
+-----BEGIN CRL-----
+MIIBFjCBgAIBATANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0IEludGVy
+bWVkaWF0ZSBDQRcNMTcwMzAyMDAxMTIyWhcNMTcwNjAyMDAxMTIyWjAtMBICAQUX
+DTE3MDIwMTAwMTEyMlowFwIDAYahFw0xNzAyMDEwMDExMjJaAgEBMA0GCSqGSIb3
+DQEBCwUAA4GBAD0b/TF84PFz/Mp07MDPU5L8H5Hn5G/RVG5vlnYWCPhFSywV+Mdy
+PCJI/yXkzGVbHCwojKiMw25sALs2arW/OA6qd5uaYvV5+slxNOrMApEDSiXRZZz8
+hi099lE/Tpx91Ovhg7xuae28/qykPfj7VX1/dfFM+/oo7hNXp5BPQ3k0
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/invalid_garbage_after_revokedcerts.pem b/pki/testdata/crl_unittest/invalid_garbage_after_revokedcerts.pem
new file mode 100644
index 0000000..5c9d1ee
--- /dev/null
+++ b/pki/testdata/crl_unittest/invalid_garbage_after_revokedcerts.pem
@@ -0,0 +1,221 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+CRL garbage after revokedCertificates
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    SEQUENCE {
+      SEQUENCE {
+        INTEGER { 105 }
+        UTCTime { "170201001122Z" }
+      }
+      SEQUENCE {
+        INTEGER { 5 }
+        UTCTime { "170201001122Z" }
+      }
+      SEQUENCE {
+        INTEGER { 106 }
+        UTCTime { "170201001122Z" }
+      }
+    }
+    UTCTime { "170602001122Z" }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0036192adc3a259256fc33756e38fa655a5396bbc836eab9a075fcec5310617af0ebc70998d352f6d66e0c4ee84368566244083cc16dc78183329f336c848912386804b294b2daf800880314c7c7a605cf2545ecf2a8461eb686bed4d726ea80d66e376643f26b987fa0d10ffc84bdab973a68573793e83b1488363b9314110254` }
+}
+-----BEGIN CRL-----
+MIIBJTCBjwIBATANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0IEludGVy
+bWVkaWF0ZSBDQRcNMTcwMzAyMDAxMTIyWjA8MBICAWkXDTE3MDIwMTAwMTEyMlow
+EgIBBRcNMTcwMjAxMDAxMTIyWjASAgFqFw0xNzAyMDEwMDExMjJaFw0xNzA2MDIw
+MDExMjJaMA0GCSqGSIb3DQEBCwUAA4GBADYZKtw6JZJW/DN1bjj6ZVpTlrvINuq5
+oHX87FMQYXrw68cJmNNS9tZuDE7oQ2hWYkQIPMFtx4GDMp8zbISJEjhoBLKUstr4
+AIgDFMfHpgXPJUXs8qhGHraGvtTXJuqA1m43ZkPya5h/oNEP/IS9q5c6aFc3k+g7
+FIg2O5MUEQJU
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/invalid_garbage_after_signaturevalue.pem b/pki/testdata/crl_unittest/invalid_garbage_after_signaturevalue.pem
new file mode 100644
index 0000000..143eb8a
--- /dev/null
+++ b/pki/testdata/crl_unittest/invalid_garbage_after_signaturevalue.pem
@@ -0,0 +1,186 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+CRL garbage after signatureValue
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `001a` }
+  SEQUENCE {}
+}
+-----BEGIN CRL-----
+MBowAwIBATANBgkqhkiG9w0BAQsFAAMCABowAA==
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/invalid_garbage_after_thisupdate.pem b/pki/testdata/crl_unittest/invalid_garbage_after_thisupdate.pem
new file mode 100644
index 0000000..cf70d7c
--- /dev/null
+++ b/pki/testdata/crl_unittest/invalid_garbage_after_thisupdate.pem
@@ -0,0 +1,205 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+CRL garbage after thisupdate
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    INTEGER { 1 }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004520bf9afe9dced0dbba0049a47fdd17a50ea4e053a3d2438b4284baa50631c776971cd045d25fcb7e824474ef09561ac778bd5a71c9f372b3d4795c3c67c336bc1fb8b043ed85f9c8aa0483bf85140a40f5911e88e11892c97bc85aeefcafbb4b40ba9c4ca50e5e717d7fa046f39fb33a3cd8123fd45abdfce3b23b9dda45ac` }
+}
+-----BEGIN CRL-----
+MIHaMEUCAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMloCAQEwDQYJKoZIhvcNAQELBQADgYEARSC/
+mv6dztDbugBJpH/dF6UOpOBTo9JDi0KEuqUGMcd2lxzQRdJfy36CRHTvCVYax3i9
+WnHJ83Kz1HlcPGfDNrwfuLBD7YX5yKoEg7+FFApA9ZEeiOEYksl7yFru/K+7S0C6
+nEylDl5xfX+gRvOfszo82BI/1Fq9/OOyO53aRaw=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/invalid_garbage_crlentry.pem b/pki/testdata/crl_unittest/invalid_garbage_crlentry.pem
new file mode 100644
index 0000000..55d6651
--- /dev/null
+++ b/pki/testdata/crl_unittest/invalid_garbage_crlentry.pem
@@ -0,0 +1,213 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf is revoked but a following crlentry is garbage
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    SEQUENCE {
+      SEQUENCE {
+        INTEGER { 5 }
+        UTCTime { "170201001122Z" }
+      }
+      INTEGER { 1 }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00343d267fd250c6352f9733255fa9902b1582cbb7546945559e45dd693748c391e116b9faa213897f341c034a26762e1dceb68b06f9c96f3f837d111a4f199e3e04291f571161f8231144f92fdbaa7ed3163be1d91ea5aac7e509d5755ac02b8bdae35b02607c94782484d98973f8b0346bd211b5fb9642daf2853a7695b9ab24` }
+}
+-----BEGIN CRL-----
+MIH/MGoCAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMloXDTE3MDYwMjAwMTEyMlowFzASAgEFFw0x
+NzAyMDEwMDExMjJaAgEBMA0GCSqGSIb3DQEBCwUAA4GBADQ9Jn/SUMY1L5czJV+p
+kCsVgsu3VGlFVZ5F3Wk3SMOR4Ra5+qITiX80HANKJnYuHc62iwb5yW8/g30RGk8Z
+nj4EKR9XEWH4IxFE+S/bqn7TFjvh2R6lqsflCdV1WsAri9rjWwJgfJR4JITZiXP4
+sDRr0hG1+5ZC2vKFOnaVuask
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/invalid_garbage_issuer_name.pem b/pki/testdata/crl_unittest/invalid_garbage_issuer_name.pem
new file mode 100644
index 0000000..9ebd566
--- /dev/null
+++ b/pki/testdata/crl_unittest/invalid_garbage_issuer_name.pem
@@ -0,0 +1,195 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+CRL issuer is garbage
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    INTEGER { 1 }
+    UTCTime { "170302001122Z" }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `003ed3bcade4824c2b5c7024f5175433b6c6f229f7798c73a4ae53cb8cd4c2ef114d3b38545459ab411ad2c2fc3234ae8e5d605d9a2cbfa3a8715a6276822a6838d40bd8008ee70a604ff235e94f6fcff16859738d505a188ce158973d189914253787d9572061b6289e68ce873fd519442780ee063dd6c0f07e92d5469e46e565` }
+}
+-----BEGIN CRL-----
+MIG5MCQCAQEwDQYJKoZIhvcNAQELBQACAQEXDTE3MDMwMjAwMTEyMlowDQYJKoZI
+hvcNAQELBQADgYEAPtO8reSCTCtccCT1F1QztsbyKfd5jHOkrlPLjNTC7xFNOzhU
+VFmrQRrSwvwyNK6OXWBdmiy/o6hxWmJ2gipoONQL2ACO5wpgT/I16U9vz/FoWXON
+UFoYjOFYlz0YmRQlN4fZVyBhtiieaM6HP9UZRCeA7gY91sDwfpLVRp5G5WU=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/invalid_garbage_revocationdate.pem b/pki/testdata/crl_unittest/invalid_garbage_revocationdate.pem
new file mode 100644
index 0000000..d6945e9
--- /dev/null
+++ b/pki/testdata/crl_unittest/invalid_garbage_revocationdate.pem
@@ -0,0 +1,216 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf is revoked but a following crlentry is garbage
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    SEQUENCE {
+      SEQUENCE {
+        INTEGER { 5 }
+        UTCTime { "170201001122Z" }
+      }
+      SEQUENCE {
+        INTEGER { `0186a1` }
+        OCTET_STRING { "170201001122Z" }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00aa809d9d62ee7c418c6807c6472d5567e0fe8b56c12556a7eef728dd6edfaeea497fd6c0f244fe26992847dcbea56a93947c3a5d8d58d008dad73bb4152d284ce9b2c3558e4e68923a7dcbf96ba3823ee72f1d35aa16681630e0d95c75f3820f556dd4ab16d1c873543c33dbcaf561fa4ba590c4455dee1c5a888f39a0dde5d3` }
+}
+-----BEGIN CRL-----
+MIIBEjB9AgEBMA0GCSqGSIb3DQEBCwUAMB8xHTAbBgNVBAMMFFRlc3QgSW50ZXJt
+ZWRpYXRlIENBFw0xNzAzMDIwMDExMjJaFw0xNzA2MDIwMDExMjJaMCowEgIBBRcN
+MTcwMjAxMDAxMTIyWjAUAgMBhqEEDTE3MDIwMTAwMTEyMlowDQYJKoZIhvcNAQEL
+BQADgYEAqoCdnWLufEGMaAfGRy1VZ+D+i1bBJVan7vco3W7frupJf9bA8kT+Jpko
+R9y+pWqTlHw6XY1Y0Aja1zu0FS0oTOmyw1WOTmiSOn3L+Wujgj7nLx01qhZoFjDg
+2Vx184IPVW3UqxbRyHNUPDPbyvVh+kulkMRFXe4cWoiPOaDd5dM=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/invalid_garbage_revoked_serial_number.pem b/pki/testdata/crl_unittest/invalid_garbage_revoked_serial_number.pem
new file mode 100644
index 0000000..62fd948
--- /dev/null
+++ b/pki/testdata/crl_unittest/invalid_garbage_revoked_serial_number.pem
@@ -0,0 +1,216 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf is revoked but a following crlentry is garbage
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    SEQUENCE {
+      SEQUENCE {
+        INTEGER { 5 }
+        UTCTime { "170201001122Z" }
+      }
+      SEQUENCE {
+        OCTET_STRING { `7f` }
+        UTCTime { "170201001122Z" }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00af638474bc29b1490911f360b89b47f695cc5545ba3068f929d948007b5c3262926ab7df7ab8ffd95a551ea6f153fcf7ccef202b9d2658f0ee017b874652d8fea1e76d7a0f94f1f2cb86934e429c2520ee7d1858fee34fa3b2c89cd92affd288085256f0684ad499c6ee5aa2413c5fac037e40efe30590aa129d5040edc462e4` }
+}
+-----BEGIN CRL-----
+MIIBEDB7AgEBMA0GCSqGSIb3DQEBCwUAMB8xHTAbBgNVBAMMFFRlc3QgSW50ZXJt
+ZWRpYXRlIENBFw0xNzAzMDIwMDExMjJaFw0xNzA2MDIwMDExMjJaMCgwEgIBBRcN
+MTcwMjAxMDAxMTIyWjASBAF/Fw0xNzAyMDEwMDExMjJaMA0GCSqGSIb3DQEBCwUA
+A4GBAK9jhHS8KbFJCRHzYLibR/aVzFVFujBo+SnZSAB7XDJikmq333q4/9laVR6m
+8VP898zvICudJljw7gF7h0ZS2P6h5216D5Tx8suGk05CnCUg7n0YWP7jT6OyyJzZ
+Kv/SiAhSVvBoStSZxu5aokE8X6wDfkDv4wWQqhKdUEDtxGLk
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/invalid_garbage_signaturealgorithm.pem b/pki/testdata/crl_unittest/invalid_garbage_signaturealgorithm.pem
new file mode 100644
index 0000000..472c971
--- /dev/null
+++ b/pki/testdata/crl_unittest/invalid_garbage_signaturealgorithm.pem
@@ -0,0 +1,181 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+CRL garbage signatureAlgorithm
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+  }
+  OCTET_STRING { "Vx" }
+  BIT_STRING { `001a` }
+}
+-----BEGIN CRL-----
+MA0wAwIBAQQCVngDAgAa
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/invalid_garbage_signaturevalue.pem b/pki/testdata/crl_unittest/invalid_garbage_signaturevalue.pem
new file mode 100644
index 0000000..c833c99
--- /dev/null
+++ b/pki/testdata/crl_unittest/invalid_garbage_signaturevalue.pem
@@ -0,0 +1,185 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+CRL garbage signatureValue
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  OCTET_STRING { `001a` }
+}
+-----BEGIN CRL-----
+MBgwAwIBATANBgkqhkiG9w0BAQsFAAQCABo=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/invalid_garbage_tbs_signature_algorithm.pem b/pki/testdata/crl_unittest/invalid_garbage_tbs_signature_algorithm.pem
new file mode 100644
index 0000000..53da79a
--- /dev/null
+++ b/pki/testdata/crl_unittest/invalid_garbage_tbs_signature_algorithm.pem
@@ -0,0 +1,201 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+CRL tbs signature algorithm is garbage
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    INTEGER { 1 }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `001b1645d54ad0b977862fdb0a977905d881c49acf6ca3328d27b0a3c8a4498a785b98fe48b9d06a85885a066b617c65e179dd393f331e172a0591694f79fa63891e3667194b84360b8f20cceed55135acf64c3cd45bf3431dccb99b4d02f0251a717fc81269fb521dfa280897e4bbff60c63cfac5d9bda7d6bc65d9f09a4cc3e7` }
+}
+-----BEGIN CRL-----
+MIHaMEUCAQECAQEwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1lZGlhdGUgQ0EXDTE3
+MDMwMjAwMTEyMloXDTE3MDYwMjAwMTEyMlowDQYJKoZIhvcNAQELBQADgYEAGxZF
+1UrQuXeGL9sKl3kF2IHEms9sozKNJ7CjyKRJinhbmP5IudBqhYhaBmthfGXhed05
+PzMeFyoFkWlPefpjiR42ZxlLhDYLjyDM7tVRNaz2TDzUW/NDHcy5m00C8CUacX/I
+Emn7Uh36KAiX5Lv/YMY8+sXZvafWvGXZ8JpMw+c=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/invalid_garbage_tbscertlist.pem b/pki/testdata/crl_unittest/invalid_garbage_tbscertlist.pem
new file mode 100644
index 0000000..76400f9
--- /dev/null
+++ b/pki/testdata/crl_unittest/invalid_garbage_tbscertlist.pem
@@ -0,0 +1,183 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+CRL garbage tbsCertList
+
+SEQUENCE {
+  OCTET_STRING { "Vx" }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `001a` }
+}
+-----BEGIN CRL-----
+MBcEAlZ4MA0GCSqGSIb3DQEBCwUAAwIAGg==
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/invalid_garbage_thisupdate.pem b/pki/testdata/crl_unittest/invalid_garbage_thisupdate.pem
new file mode 100644
index 0000000..9560a67
--- /dev/null
+++ b/pki/testdata/crl_unittest/invalid_garbage_thisupdate.pem
@@ -0,0 +1,205 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+CRL thisUpdate is garbage
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    INTEGER { 1 }
+    UTCTime { "170302001122Z" }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `003c8fe028759a675e5a087f00d32fc193e219b5dde6ae46c295a79c498d773dae4bbd68b7abe72ac7e497e132cd734b0ebaa5300831da35db71130dbcdfd49f9cf431f6aa0b88dd10aba03931d018f9e1efb4a8cc979a65f1258c727c0a8b39a106058c73bff05d45257f777176aedb1ef690c5998adbc437d8a67a6a55ff28e5` }
+}
+-----BEGIN CRL-----
+MIHaMEUCAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0ECAQEXDTE3MDMwMjAwMTEyMlowDQYJKoZIhvcNAQELBQADgYEAPI/g
+KHWaZ15aCH8A0y/Bk+IZtd3mrkbClaecSY13Pa5LvWi3q+cqx+SX4TLNc0sOuqUw
+CDHaNdtxEw2839SfnPQx9qoLiN0Qq6A5MdAY+eHvtKjMl5pl8SWMcnwKizmhBgWM
+c7/wXUUlf3dxdq7bHvaQxZmK28Q32KZ6alX/KOU=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/invalid_garbage_version.pem b/pki/testdata/crl_unittest/invalid_garbage_version.pem
new file mode 100644
index 0000000..12f958c
--- /dev/null
+++ b/pki/testdata/crl_unittest/invalid_garbage_version.pem
@@ -0,0 +1,205 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+CRL version is garbage
+
+SEQUENCE {
+  SEQUENCE {
+    OCTET_STRING { `01` }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `003f4ac6992793187b7d0fcfa91f070ab1e4e48eccd9c61c1bb696bce0a6f9dd478892d41c9dfb9e8eb1a3a7491a360f379616495f13531631dc8061bc1ca3079f255e374778fc811d517cc846a51725870f541452f3007c3dcb6562a954a9c4a238148bc17e32e2ac4414fba84d1f7856508b65e59bb6b75c565d093bff26fcd5` }
+}
+-----BEGIN CRL-----
+MIHmMFEEAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMloXDTE3MDYwMjAwMTEyMlowDQYJKoZIhvcN
+AQELBQADgYEAP0rGmSeTGHt9D8+pHwcKseTkjszZxhwbtpa84Kb53UeIktQcnfue
+jrGjp0kaNg83lhZJXxNTFjHcgGG8HKMHnyVeN0d4/IEdUXzIRqUXJYcPVBRS8wB8
+PctlYqlUqcSiOBSLwX4y4qxEFPuoTR94VlCLZeWbtrdcVl0JO/8m/NU=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/invalid_idp_dpname_choice_extra_data.pem b/pki/testdata/crl_unittest/invalid_idp_dpname_choice_extra_data.pem
new file mode 100644
index 0000000..d64b2d2
--- /dev/null
+++ b/pki/testdata/crl_unittest/invalid_idp_dpname_choice_extra_data.pem
@@ -0,0 +1,234 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+IssuingDistributionPoint extension distributionPoint is invalid
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    [0] {
+      SEQUENCE {
+        SEQUENCE {
+          # issuingDistributionPoint
+          OBJECT_IDENTIFIER { 2.5.29.28 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              [0] {
+                [0] {
+                  [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                }
+                [1] {
+                  SET {
+                    SEQUENCE {
+                      # countryName
+                      OBJECT_IDENTIFIER { 2.5.4.6 }
+                      PrintableString { "US" }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0006c98c9191f2a57043ef6422f23c2a6f458a5bdcd995b70dc6e5c2525e61c09bab709c79ef892dc5a406bbe4f8409ae1e33e0bb243318f339f5472134c14d0a183ea1dccc520063868534e74a64abfe5302c182fee2cde2f035c1c8bf8f4f75f9fcc7c6a66a172de8c0b3dab3fe6b8d52f7321e0b7f5a89535b602f9f20f6394` }
+}
+-----BEGIN CRL-----
+MIIBKDCBkgIBATANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0IEludGVy
+bWVkaWF0ZSBDQRcNMTcwMzAyMDAxMTIyWhcNMTcwNjAyMDAxMTIyWqA/MD0wOwYD
+VR0cAQH/BDEwL6AtoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsoQ0xCzAJ
+BgNVBAYTAlVTMA0GCSqGSIb3DQEBCwUAA4GBAAbJjJGR8qVwQ+9kIvI8Km9Filvc
+2ZW3DcblwlJeYcCbq3Ccee+JLcWkBrvk+ECa4eM+C7JDMY8zn1RyE0wU0KGD6h3M
+xSAGOGhTTnSmSr/lMCwYL+4s3i8DXByL+PT3X5/MfGpmoXLejAs9qz/muNUvcyHg
+t/WolTW2AvnyD2OU
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d8f829b13d9a2659010e0313b15f2d11e54598cfb739bc936522719d585f86b7e81b4ed40007618edb03fea56c65b8bfb68c560984de16c02db43eed00d6d2409661c7976def87811cdce44f3e9498bfb1316f7c1d79158495780660e07c5fc4d302288fe0a9c409a7c708f48f1c1dd8e878bc00f4e7c596edaf3994ac0eb4dd` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `003f30d040e2a230cd961b63ba65ccf7c61f60f364d0a5c4a5afa72303ebbdd7be2a879e57d9c09ca28495cd8bd62678207214e36c80dfbf8a722f808260c52a9713a27518c9a1075ab786268cf29972e82ad4a750502491de00e3cec21f7fc424830a5382fc2ff6db4c7ddbf3f6cf89985a9de7002a78556c6a778e9ff6cc369d` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDY+CmxPZomWQEOAxOxXy0R5UWYz7c5vJNlInGdWF+Gt+gbTtQAB2GO2wP+
+pWxluL+2jFYJhN4WwC20Pu0A1tJAlmHHl23vh4Ec3ORPPpSYv7Exb3wdeRWElXgG
+YOB8X8TTAiiP4KnECafHCPSPHB3Y6Hi8APTnxZbtrzmUrA603QIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAPzDQQOKiMM2WG2O6Zcz3
+xh9g82TQpcSlr6cjA+u9174qh55X2cCcooSVzYvWJnggchTjbIDfv4pyL4CCYMUq
+lxOidRjJoQdat4YmjPKZcugq1KdQUCSR3gDjzsIff8QkgwpTgvwv9ttMfdvz9s+J
+mFqd5wAqeFVsaneOn/bMNp0=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00a5c695feb8c268dd012b8f112f5bcd7e0ad91f4e7491bd4903ccfc4d9e88e96d6b43fbfb89ad6e88028e7bcad2aeee3c735fb31639ed92455daee9d8fafd468d2ba9ddcf487880498b64e95a3d47d8358d8cfdaeb8a962fdbf1e8fb4e06deda0a072996f46495b5de9ff39a8b1bdc995afe9b453988cbc33d0d467e49dca1349` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00549634347f1e456ae66f4ef3cff73c1176a61305805ed402505471e23b58a9c61ad2f77c2e13da450a60bf54958a69841a4102f296881689d95f10e604b36e6082504c433083591399d020c7f3d173fb261156d8a60a889bac1a755338c7daba530750e249c88ad5657e7832337507ae3c65101aba15f83635d351f07b548de3` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBAKXGlf64wmjdASuPES9bzX4K2R9OdJG9SQPM/E2eiOlta0P7+4mtbogC
+jnvK0q7uPHNfsxY57ZJFXa7p2Pr9Ro0rqd3PSHiASYtk6Vo9R9g1jYz9rripYv2/
+Ho+04G3toKBymW9GSVtd6f85qLG9yZWv6bRTmIy8M9DUZ+SdyhNJAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAFSWNDR/HkVq5m9O88/3PBF2phMFgF7UAlBUceI7WKnG
+GtL3fC4T2kUKYL9UlYpphBpBAvKWiBaJ2V8Q5gSzbmCCUExDMINZE5nQIMfz0XP7
+JhFW2KYKiJusGnVTOMfaulMHUOJJyIrVZX54MjN1B648ZRAauhX4NjXTUfB7VI3j
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/invalid_idp_empty_sequence.pem b/pki/testdata/crl_unittest/invalid_idp_empty_sequence.pem
new file mode 100644
index 0000000..1d070b9
--- /dev/null
+++ b/pki/testdata/crl_unittest/invalid_idp_empty_sequence.pem
@@ -0,0 +1,218 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+IssuingDistributionPoint extension is invalid
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    [0] {
+      SEQUENCE {
+        SEQUENCE {
+          # issuingDistributionPoint
+          OBJECT_IDENTIFIER { 2.5.29.28 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {}
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `007e30782faeb5a9b4aed94ade2d1aafe5b17af96ee9ebe1696b6bb6f92815a3d8643acbfa59bacb4255e635e02cd62c14cdfc13e128ceace0ffc96da315eee2dd35995f322c972c3ee4ff7fc7b463339cfc85eec97cde4b7e1a1e8ce2f336fcab4a548164d84f6b83d652c4e08c5b31468c69fb3478bd2af335ab6e27cdb52583` }
+}
+-----BEGIN CRL-----
+MIH4MGMCAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMloXDTE3MDYwMjAwMTEyMlqgEDAOMAwGA1Ud
+HAEB/wQCMAAwDQYJKoZIhvcNAQELBQADgYEAfjB4L661qbSu2UreLRqv5bF6+W7p
+6+Fpa2u2+SgVo9hkOsv6WbrLQlXmNeAs1iwUzfwT4SjOrOD/yW2jFe7i3TWZXzIs
+lyw+5P9/x7RjM5z8he7JfN5LfhoejOLzNvyrSlSBZNhPa4PWUsTgjFsxRoxp+zR4
+vSrzNatuJ821JYM=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b17ca575a8ed4c57e6290feec7641298cb22569fc6cdaed87186b5fb9fa201c7986b7a758753c7b407606487c3ed223a402c7ee930e22654e9390b4cdae8b8e135ca73e5550c116d29d10ef59ccff23f63e50399a7430ea3b8e040ebe63776450642b895ca20468038980c23ca30e49e93633f6507da641b4db1518f74958d8b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00a329373d689f35e199ce1b0a1eef4f6c36b926344368f00687b37489ab486407ea3cadb4441d4f383d18feebb68fcee74fa2204c645c2369ef0bdce02bc646a1d36a2383625b7b46d23e344ef5e85e015f1176ab7ce112a7604e34767ef9c47b818e6599ec752255b04fb3339dfc56bb7c3c62bd8109deff2fc75d615b64d65d` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQCxfKV1qO1MV+YpD+7HZBKYyyJWn8bNrthxhrX7n6IBx5hrenWHU8e0B2Bk
+h8PtIjpALH7pMOImVOk5C0za6LjhNcpz5VUMEW0p0Q71nM/yP2PlA5mnQw6juOBA
+6+Y3dkUGQriVyiBGgDiYDCPKMOSek2M/ZQfaZBtNsVGPdJWNiwIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAoyk3PWifNeGZzhsKHu9P
+bDa5JjRDaPAGh7N0iatIZAfqPK20RB1POD0Y/uu2j87nT6IgTGRcI2nvC9zgK8ZG
+odNqI4NiW3tG0j40TvXoXgFfEXarfOESp2BONHZ++cR7gY5lmex1IlWwT7MznfxW
+u3w8Yr2BCd7/L8ddYVtk1l0=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d1f551f3f9137e84c706271349971ec0fea83a78d7cfcb86f37eacbcdd4cf6f76e8b8f158efacf1c5d8c9a37dc273b8e547c2c86c97ef744b1efc523b5470449b99889b46265668e5a3d61d2f75bb03a528f68abd56cac295abd47ac19532e72ccc8e40e914d276504f2f738d1b32c19dea39a1ca011ec91ded82eef136323ed` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0030608eee0754a85a3ea4caba97270ed8222c007aa3986916a47a0658ea7df85aac02ceb7b30a80d8decb1090e28e09d1481b61312554466e2b8d640c79e4d266c527b4e875ad372666f2e877f0edca1503273377381c76b383396106689c17a967cc6b290ddc6c146405b15a2ca6bc47f1a6b65fd65810bef9347bb2e04bf2dc` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBANH1UfP5E36ExwYnE0mXHsD+qDp418/LhvN+rLzdTPb3bouPFY76zxxd
+jJo33Cc7jlR8LIbJfvdEse/FI7VHBEm5mIm0YmVmjlo9YdL3W7A6Uo9oq9VsrCla
+vUesGVMucszI5A6RTSdlBPL3ONGzLBneo5ocoBHskd7YLu8TYyPtAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBADBgju4HVKhaPqTKupcnDtgiLAB6o5hpFqR6Bljqffha
+rALOt7MKgNjeyxCQ4o4J0UgbYTElVEZuK41kDHnk0mbFJ7Toda03Jmby6Hfw7coV
+AyczdzgcdrODOWEGaJwXqWfMaykN3GwUZAWxWiymvEfxprZf1lgQvvk0e7LgS/Lc
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/invalid_idp_onlycontains_user_and_ca_certs.pem b/pki/testdata/crl_unittest/invalid_idp_onlycontains_user_and_ca_certs.pem
new file mode 100644
index 0000000..8fea270
--- /dev/null
+++ b/pki/testdata/crl_unittest/invalid_idp_onlycontains_user_and_ca_certs.pem
@@ -0,0 +1,240 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+IssuingDistributionPoint extension is invalid, cannot specify more than one of onlyContainsUserCerts and onlyContainsCACerts
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    [0] {
+      SEQUENCE {
+        SEQUENCE {
+          # issuingDistributionPoint
+          OBJECT_IDENTIFIER { 2.5.29.28 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              [1 PRIMITIVE] { `ff` }
+              [2 PRIMITIVE] { `ff` }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00732914c46fddaa6b366d24adc1c5b88697be036387013016f43cc63ea67b9714faa195dfaadf33d6a0bd56bb1b47adeb3b68aa8c7819af7325fe6e9371b5a38fea52e9f709902423f925b1da9f221c85e29d0e143af1603f8634f59db32ae3e88a831df27b38134669be032953a75318fb7f910421ab0e400a2f63299f9d0ada` }
+}
+-----BEGIN CRL-----
+MIH+MGkCAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMloXDTE3MDYwMjAwMTEyMlqgFjAUMBIGA1Ud
+HAEB/wQIMAaBAf+CAf8wDQYJKoZIhvcNAQELBQADgYEAcykUxG/dqms2bSStwcW4
+hpe+A2OHATAW9DzGPqZ7lxT6oZXfqt8z1qC9VrsbR63rO2iqjHgZr3Ml/m6TcbWj
+j+pS6fcJkCQj+SWx2p8iHIXinQ4UOvFgP4Y09Z2zKuPoioMd8ns4E0ZpvgMpU6dT
+GPt/kQQhqw5ACi9jKZ+dCto=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00f60f4a066d9dc05562f5c879444163b73be0b3d5e32dd7eff091af5d3c70bf3860067236894d085f581c70a1a8753d5b8882b263733e89a47b9989c36ce438b3b96ac16b1ca8878f2d51383055a17df6936c82b4f50729eb2f08f0f46f4106fa5975ec83c06f7d1135468354e01478e78474c56b6aca4d8a3e86ff7e494e6407` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+        SEQUENCE {
+          # basicConstraints
+          OBJECT_IDENTIFIER { 2.5.29.19 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              BOOLEAN { `ff` }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00209bf64b888cbd58493d8898b215ed640ddb04e329e43e3db45a20782ab7acc22dca7cbb11b4fbdb08b8acf163d116948db57b044773d51b8bdf09b1a6465268d60388fee8740aa4167e9d44f19027b075802438c909b9afd0f298027bf0b56e6dd1e92ea5d393e2b422c49bb324433bce95a828149db3e5491d1572b11be5f4` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBzjCCATegAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQD2D0oGbZ3AVWL1yHlEQWO3O+Cz1eMt1+/wka9dPHC/OGAGcjaJTQhfWBxw
+oah1PVuIgrJjcz6JpHuZicNs5DizuWrBaxyoh48tUTgwVaF99pNsgrT1BynrLwjw
+9G9BBvpZdeyDwG99ETVGg1TgFHjnhHTFa2rKTYo+hv9+SU5kBwIDAQABoyMwITAO
+BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOB
+gQAgm/ZLiIy9WEk9iJiyFe1kDdsE4ynkPj20WiB4Kreswi3KfLsRtPvbCLis8WPR
+FpSNtXsER3PVG4vfCbGmRlJo1gOI/uh0CqQWfp1E8ZAnsHWAJDjJCbmv0PKYAnvw
+tW5t0ekupdOT4rQixJuzJEM7zpWoKBSds+VJHRVysRvl9A==
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b86043a5c55800fd75606bd07e94c08c4bbd7c2ed4bcb6f8caac436213ab24587377a0107678abcca31c31fd84b78636034a6ea4853d62bd86d8a5e4c8f741b6efdf1008696e8eed8f30db3fdc78ca13d39d6cca9bc1563111e0bace35ffca03ab146bf07bb4636f6b38cf8b2feb1336e3f209ff30aad4283468a997e8215329` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+        SEQUENCE {
+          # basicConstraints
+          OBJECT_IDENTIFIER { 2.5.29.19 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {}
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00af35a49085f242c33eaad6efba5c2906f7c0ebf5caa66ab2f5ed0a663287da5665963048df790ffb1f223b93a8a40c9a8d26a0d9f0a41dd3d706754a59bfb2579464f984aa7686de56b441759c42b7aeb50b5960eaa27cb469beaeaf2460c1b6d8246dc78d6fce2a05a26f7723f6a1b96c0faf912b4aa67ceaeb432a552e1cb4` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB6jCCAVOgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALhgQ6XFWAD9dWBr0H6UwIxLvXwu1Ly2+MqsQ2ITqyRYc3egEHZ4q8yj
+HDH9hLeGNgNKbqSFPWK9htil5Mj3Qbbv3xAIaW6O7Y8w2z/ceMoT051sypvBVjER
+4LrONf/KA6sUa/B7tGNvazjPiy/rEzbj8gn/MKrUKDRoqZfoIVMpAgMBAAGjPTA7
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMAwG
+A1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADgYEArzWkkIXyQsM+qtbvulwpBvfA
+6/XKpmqy9e0KZjKH2lZlljBI33kP+x8iO5OopAyajSag2fCkHdPXBnVKWb+yV5Rk
++YSqdobeVrRBdZxCt661C1lg6qJ8tGm+rq8kYMG22CRtx41vzioFom93I/ahuWwP
+r5ErSqZ86utDKlUuHLQ=
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/invalid_idp_onlycontainsusercerts_v1_leaf.pem b/pki/testdata/crl_unittest/invalid_idp_onlycontainsusercerts_v1_leaf.pem
new file mode 100644
index 0000000..5cc264e
--- /dev/null
+++ b/pki/testdata/crl_unittest/invalid_idp_onlycontainsusercerts_v1_leaf.pem
@@ -0,0 +1,207 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+v1 leaf is covered by CRL with onlyContainsUserCerts, which is invalid
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    [0] {
+      SEQUENCE {
+        SEQUENCE {
+          # issuingDistributionPoint
+          OBJECT_IDENTIFIER { 2.5.29.28 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              [1 PRIMITIVE] { `ff` }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00a0622aaa13d75795b643f7bde4794f8a9cc5f4c45080929e8db6b5516d897a91cbeff8d2196407f4fd453aeb903c256da07a13063096edfc3577d7931df5a8a449b8990375fdb07dd6257c6a2df8aaecd8d9c1581906a93f8c951dce6d8974399ea6c060a303877891815fc0fd8df9fe55e35997246c368b9a0d2150f6f50fcd` }
+}
+-----BEGIN CRL-----
+MIH7MGYCAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMloXDTE3MDYwMjAwMTEyMlqgEzARMA8GA1Ud
+HAEB/wQFMAOBAf8wDQYJKoZIhvcNAQELBQADgYEAoGIqqhPXV5W2Q/e95HlPipzF
+9MRQgJKejba1UW2JepHL7/jSGWQH9P1FOuuQPCVtoHoTBjCW7fw1d9eTHfWopEm4
+mQN1/bB91iV8ai34quzY2cFYGQapP4yVHc5tiXQ5nqbAYKMDh3iRgV/A/Y35/lXj
+WZckbDaLmg0hUPb1D80=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00bc0c9b8bfb43c66a78d796d2727ecfebd8701881296df17c64948844be617a7b0a2f6ca398eddb11bbc7a2aae8479cebd5c1763fd719fb5b33e661b7b401c501bfa8889074d133bfce2a4d2753b4d2fc4f58185bb6711536b5f8333bda853b8abd68f22b4f2403ad740a56a3f66eaedeb216ce3f02ffc869fc40f38bd91b038b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+        SEQUENCE {
+          # basicConstraints
+          OBJECT_IDENTIFIER { 2.5.29.19 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            SEQUENCE {
+              BOOLEAN { `ff` }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0080c61fa7019fe41df7eed8ef6301a8fd8519fbd75060ccffc8519dac9d7a3a933de781b8fd857f4c5aed87abbd044b545ff61428a2ba061c615b24fe70dacb4a3942996df651aadb16905595f55e345981f46025d99cfb714ac338693809dc2210c68a548da50ed5d118026efa6f28839b50f471d9e7ce5a4c24d6136548dba9` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBzjCCATegAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQC8DJuL+0PGanjXltJyfs/r2HAYgSlt8XxklIhEvmF6ewovbKOY7dsRu8ei
+quhHnOvVwXY/1xn7WzPmYbe0AcUBv6iIkHTRM7/OKk0nU7TS/E9YGFu2cRU2tfgz
+O9qFO4q9aPIrTyQDrXQKVqP2bq7eshbOPwL/yGn8QPOL2RsDiwIDAQABoyMwITAO
+BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOB
+gQCAxh+nAZ/kHffu2O9jAaj9hRn711BgzP/IUZ2snXo6kz3ngbj9hX9MWu2Hq70E
+S1Rf9hQooroGHGFbJP5w2stKOUKZbfZRqtsWkFWV9V40WYH0YCXZnPtxSsM4aTgJ
+3CIQxopUjaUO1dEYAm76byiDm1D0cdnnzlpMJNYTZUjbqQ==
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 8 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00ae0e3777c64af43b4c326717f5f6a090f63e374c946fe7e41dc3d50260844a059b9d2aad7cccfb5b75cb925e029ab60a107ad197caecee0f1868275ff34eec0ed2dee741d24bb3cf780eb2b5d6e470c7bc722140a95db43491a09581f696cbf3eeb7134467e36a206739124da49134b9a148d10c5f0e94f89f78800b1d677f03` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0030d3ac4b944003e8f9e605c349bad290ae2a6ba9563dc64cd9adf91d689c5faafa45d8f5cebbca975f005ab87b6981b822ce0a107cbb21a39c29890c0d10f045833f8624e80adf73e5e8588911579f12a42310765791dac4a329b77089e3c12c0e6a9ca2eed870b8abcd4ce5e809a31a592bb968e29e0b22c4093ef20b9cc152` }
+}
+-----BEGIN CERTIFICATE-----
+MIIBpjCCAQ8CAQgwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRl
+cm1lZGlhdGUgQ0EwIhgPMjAxNzAxMDEwMDAwMDBaGA8yMDE4MDEwMTAwMDAwMFow
+FDESMBAGA1UEAwwJVGVzdCBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
+gQCuDjd3xkr0O0wyZxf19qCQ9j43TJRv5+Qdw9UCYIRKBZudKq18zPtbdcuSXgKa
+tgoQetGXyuzuDxhoJ1/zTuwO0t7nQdJLs894DrK11uRwx7xyIUCpXbQ0kaCVgfaW
+y/PutxNEZ+NqIGc5Ek2kkTS5oUjRDF8OlPifeIALHWd/AwIDAQABMA0GCSqGSIb3
+DQEBCwUAA4GBADDTrEuUQAPo+eYFw0m60pCuKmupVj3GTNmt+R1onF+q+kXY9c67
+ypdfAFq4e2mBuCLOChB8uyGjnCmJDA0Q8EWDP4Yk6Arfc+XoWIkRV58SpCMQdleR
+2sSjKbdwiePBLA5qnKLu2HC4q81M5egJoxpZK7lo4p4LIsQJPvILnMFS
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/invalid_issuer_keyusage_no_crlsign.pem b/pki/testdata/crl_unittest/invalid_issuer_keyusage_no_crlsign.pem
new file mode 100644
index 0000000..3625dd6
--- /dev/null
+++ b/pki/testdata/crl_unittest/invalid_issuer_keyusage_no_crlsign.pem
@@ -0,0 +1,205 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf covered by CRLs and not revoked, issuer has keyUsage extension without the cRLSign bit set
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00588a2dbca80630842ffcd6a0a6fe17630d341e0e277c863069025b3169a727188cf7d22a985c027678e034c31c34141d102a7aef73039d1f51ce11261b069598c4b19bae39278bcdb245f55dc644f2165beac3f8aa8e19e13a27bb53cc19387f6afaf2ef8cbe5270380917abae7fa7c0ad4aaa7b70b1102d23951886d854a5cd` }
+}
+-----BEGIN CRL-----
+MIHmMFECAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMloXDTE3MDYwMjAwMTEyMlowDQYJKoZIhvcN
+AQELBQADgYEAWIotvKgGMIQv/Nagpv4XYw00Hg4nfIYwaQJbMWmnJxiM99IqmFwC
+dnjgNMMcNBQdECp673MDnR9RzhEmGwaVmMSxm645J4vNskX1XcZE8hZb6sP4qo4Z
+4Tonu1PMGTh/avry74y+UnA4CRerrn+nwK1KqntwsRAtI5UYhthUpc0=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 3 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0204` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0053cde887ae95c6177b3c3ea869942ae3d5c8a4b267d755cd21825e82e3e1fd0e633ad8bc738a083c9b0c1fe7c631821e5fdd4d016cc3d9ebbe3635dd2679940e8ab4aedd641b8df9ed5a16374bd2231ce0313d9867a274645daa677315110faefda5d46834c4dae429fda10c5720304da700ccc20fae46cd371f6f37d84ac4ce` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBAzANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADgYEAU83oh66Vxhd7PD6oaZQq
+49XIpLJn11XNIYJeguPh/Q5jOti8c4oIPJsMH+fGMYIeX91NAWzD2eu+NjXdJnmU
+Doq0rt1kG4357VoWN0vSIxzgMT2YZ6J0ZF2qZ3MVEQ+u/aXUaDTE2uQp/aEMVyAw
+TacAzMIPrkbNNx9vN9hKxM4=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/invalid_key_rollover_issuer_keyusage_no_crlsign.pem b/pki/testdata/crl_unittest/invalid_key_rollover_issuer_keyusage_no_crlsign.pem
new file mode 100644
index 0000000..e08ef11
--- /dev/null
+++ b/pki/testdata/crl_unittest/invalid_key_rollover_issuer_keyusage_no_crlsign.pem
@@ -0,0 +1,285 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf issued by CA's new key but CRL is signed by old key, and the old key cert has keyUsage extension without the cRLSign bit set
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0020558426a4eec452d6c1e7489bb265595b2b90f645746ae1c1e3e6532c527eda46b23eda281bf99aa2950e1514d72fe540751a799b04dc1945b14956494e24e1cbbf04eb027167962fb72f56d249c849e5575cd86cf967a6d1f9691433f40a21a5db5630d9ac3d425e0832549807e9f5cfb8a916931ec5182c86971f834a3405` }
+}
+-----BEGIN CRL-----
+MIHmMFECAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMloXDTE3MDYwMjAwMTEyMlowDQYJKoZIhvcN
+AQELBQADgYEAIFWEJqTuxFLWwedIm7JlWVsrkPZFdGrhwePmUyxSftpGsj7aKBv5
+mqKVDhUU1y/lQHUaeZsE3BlFsUlWSU4k4cu/BOsCcWeWL7cvVtJJyEnlV1zYbPln
+ptH5aRQz9AohpdtWMNmsPUJeCDJUmAfp9c+4qRaTHsUYLIaXH4NKNAU=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 8 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b6e8ead8d014f4b5ddaf01f62b66392af991f70d2b011b2dc56de32a1e30d9d476848d31ebcb101094160590bf5ce992e347c8c0810a4d7717950d546c7ccbb966d560cf9042b511babdefc6d6018e95759081f78f1187486885ae0ce397cb49553edc356316cc86ba33cc984f9651658dc400f1d82a08478c65c9538883ec1b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004a64aa4f07ee7f6e9a156a637be6dfebf59562212b3cf0b6391153061331783e54aecbb67e9831480658cb7d07d2f96890ac2f9f8c8dbd726a0bb16aa3bd8104d9a8c3fdcbca2bc433e3cb4cf008d0caa9569bfce07f387e6d875ebe2bbfd18bdb960028c2b20de7a701c895b27e4976d989d7d819a21a836571974b94b49166` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIByjCCATOgAwIBAgIBCDANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAfMR0wGwYDVQQDDBRUZXN0IEludGVybWVkaWF0ZSBDQTCBnzANBgkqhkiG
+9w0BAQEFAAOBjQAwgYkCgYEAtujq2NAU9LXdrwH2K2Y5KvmR9w0rARstxW3jKh4w
+2dR2hI0x68sQEJQWBZC/XOmS40fIwIEKTXcXlQ1UbHzLuWbVYM+QQrURur3vxtYB
+jpV1kIH3jxGHSGiFrgzjl8tJVT7cNWMWzIa6M8yYT5ZRZY3EAPHYKghHjGXJU4iD
+7BsCAwEAAaMSMBAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBAEpk
+qk8H7n9umhVqY3vm3+v1lWIhKzzwtjkRUwYTMXg+VK7Ltn6YMUgGWMt9B9L5aJCs
+L5+Mjb1yaguxaqO9gQTZqMP9y8orxDPjy0zwCNDKqVab/OB/OH5th16+K7/Ri9uW
+ACjCsg3npwHIlbJ+SXbZidfYGaIag2Vxl0uUtJFm
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 9 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d93f6f55f607250217ce3500717d955de64ac5e21d179d2ee54b6b7657a267d8e3ff2d0bcbee37f4d32fda5d8930b393278cf34c260187455740aabb29c2e7e645087baecb5fbc341973ac10fd07972c2867f9a5048f5ff81d569d9c8337e5053ab9efd72c7c0164d7a4fdcb55dba8ec72a56c9c6b6c6d11ab866d8b06ab11d3` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0021a05085069b97f7b91a3ac48ea6c06c41514123547497009bb2e167a359f059fd94064805e3e3a37cd98be3f4ed1b30e66865af5d3bb5b4ad78abc0096614a4561f2bf38b344f2fdd7238a5ff2358f27cda07771421d73bed8cb418776c4b9682b120ee4260aa6fd5263e72d02733e5f0e634b27e08b7fb9184ee1bef4dd6df` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBCTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBANk/b1X2ByUCF841AHF9lV3mSsXiHRedLuVLa3ZXomfY4/8tC8vuN/TT
+L9pdiTCzkyeM80wmAYdFV0CquynC5+ZFCHuuy1+8NBlzrBD9B5csKGf5pQSPX/gd
+Vp2cgzflBTq579csfAFk16T9y1XbqOxypWyca2xtEauGbYsGqxHTAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBACGgUIUGm5f3uRo6xI6mwGxBUUEjVHSXAJuy4WejWfBZ
+/ZQGSAXj46N82Yvj9O0bMOZoZa9dO7W0rXirwAlmFKRWHyvzizRPL91yOKX/I1jy
+fNoHdxQh1zvtjLQYd2xLloKxIO5CYKpv1SY+ctAnM+Xw5jSyfgi3+5GE7hvvTdbf
+-----END CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 3 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00c06603ddfbd7981fc745bb9378d177f606816bea25105b7f5ed9b0499bf506f3dc2687e8ee1375d183106c75b0b8ad5010e9e7316a924285984592b5ed7aa4db77bff25a5c99ade2d1eae254a3c1daf09e4194f987ac9f213582a627b9be45e64a50fd2c8b9e21c702125a6b5391d4f86d51e722689f1db653228912140d592b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0204` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `005851297c29fe12607f28d225349695d8c0ae6afa572ea69255142be1712994ff149b801c87a2436d469186a56a21765fd0eadd1ea9cbebeb3771bbacfe558697e3fc1fd34b1f2ad2db8ba3b946748292bb413e8feb916b2dc8c0ac8e0de0e5bc3c13e42704db2d718cf64b628d42ad0ee08d4639dcfcba4ceed37189164ad3ce` }
+}
+-----BEGIN CA CERTIFICATE 2-----
+MIIBvTCCASagAwIBAgIBAzANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDAZgPd+9eYH8dFu5N40Xf2BoFr6iUQW39e2bBJm/UG89wmh+juE3XRgxBs
+dbC4rVAQ6ecxapJChZhFkrXteqTbd7/yWlyZreLR6uJUo8Ha8J5BlPmHrJ8hNYKm
+J7m+ReZKUP0si54hxwISWmtTkdT4bVHnImifHbZTIokSFA1ZKwIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADgYEAWFEpfCn+EmB/KNIlNJaV
+2MCuavpXLqaSVRQr4XEplP8Um4Ach6JDbUaRhqVqIXZf0OrdHqnL6+s3cbus/lWG
+l+P8H9NLHyrS24ujuUZ0gpK7QT6P65FrLcjArI4N4OW8PBPkJwTbLXGM9ktijUKt
+DuCNRjnc/LpM7tNxiRZK084=
+-----END CA CERTIFICATE 2-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/invalid_mismatched_signature_algorithm.pem b/pki/testdata/crl_unittest/invalid_mismatched_signature_algorithm.pem
new file mode 100644
index 0000000..660eff3
--- /dev/null
+++ b/pki/testdata/crl_unittest/invalid_mismatched_signature_algorithm.pem
@@ -0,0 +1,205 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf covered by CRLs and not revoked, but signatureAlgorithm in CertificateList does not match the one in TBSCertList.
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha384WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.12 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0033bb91b04ad046e8d72ffd16c5bcf828f8f017786bb7542748d3b58fb2e645ec319ba296c52b0a24aba9aab2f6cf07a55be8ecc37abee1aaea7fb77491f989389fb4a19f7c8c8064340de5a1e1fa34eae3286538f68cf6c9a3d95e29e70ffe9d42b3f98f223c254fa895298cfbaa5c28f57a69c09cfed3cbc8f501ebcaa9993f` }
+}
+-----BEGIN CRL-----
+MIHmMFECAQEwDQYJKoZIhvcNAQEMBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMloXDTE3MDYwMjAwMTEyMlowDQYJKoZIhvcN
+AQELBQADgYEAM7uRsErQRujXL/0Wxbz4KPjwF3hrt1QnSNO1j7LmRewxm6KWxSsK
+JKupqrL2zwelW+jsw3q+4arqf7d0kfmJOJ+0oZ98jIBkNA3loeH6NOrjKGU49oz2
+yaPZXinnD/6dQrP5jyI8JU+olSmM+6pcKPV6acCc/tPLyPUB68qpmT8=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/invalid_revoked_empty_sequence.pem b/pki/testdata/crl_unittest/invalid_revoked_empty_sequence.pem
new file mode 100644
index 0000000..6576362
--- /dev/null
+++ b/pki/testdata/crl_unittest/invalid_revoked_empty_sequence.pem
@@ -0,0 +1,206 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+revokedCertificates is an empty sequence (should be omitted)
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    SEQUENCE {}
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00100e6f69134bc4aeb6bf6ea5ddb82dbb1ddc191c50d865acb0a1f2be7a8e5bbbe7a60608ba890d22739ac5c1af93753c098fe177af1b45cf353276b856a804bee3faeccbfd8e4a814dbe31d2964ef2cb838e0c288eda6179327b76e1cdc3a05f25f99b2c7a689467f08a5d32b726680409d85f68a30455b069fae96bddc7b302` }
+}
+-----BEGIN CRL-----
+MIHoMFMCAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMloXDTE3MDYwMjAwMTEyMlowADANBgkqhkiG
+9w0BAQsFAAOBgQAQDm9pE0vErra/bqXduC27HdwZHFDYZaywofK+eo5bu+emBgi6
+iQ0ic5rFwa+TdTwJj+F3rxtFzzUydrhWqAS+4/rsy/2OSoFNvjHSlk7yy4OODCiO
+2mF5Mnt24c3DoF8l+ZssemiUZ/CKXTK3JmgECdhfaKMEVbBp+ulr3cezAg==
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/invalid_v1_explicit.pem b/pki/testdata/crl_unittest/invalid_v1_explicit.pem
new file mode 100644
index 0000000..48ef2cc
--- /dev/null
+++ b/pki/testdata/crl_unittest/invalid_v1_explicit.pem
@@ -0,0 +1,205 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+CRL has explicit V1 version
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 0 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `009581ed1d84cc719f5b1a05cc0b82404bd9f8651d0e5478d9a3057eeb1c84b297122d9ceebdae45442058769a744748551f3eaf78b7aaad010168806ac481af61ba27c67b9f7052e226687e831e0848b6a6723d62c7106a7292d42c66ab5d487e971c9b9ef916d941f0df3de00928f9a594345c710ec42943a007f57796870aad` }
+}
+-----BEGIN CRL-----
+MIHmMFECAQAwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMloXDTE3MDYwMjAwMTEyMlowDQYJKoZIhvcN
+AQELBQADgYEAlYHtHYTMcZ9bGgXMC4JAS9n4ZR0OVHjZowV+6xyEspcSLZzuva5F
+RCBYdpp0R0hVHz6veLeqrQEBaIBqxIGvYbonxnufcFLiJmh+gx4ISLamcj1ixxBq
+cpLULGarXUh+lxybnvkW2UHw3z3gCSj5pZQ0XHEOxClDoAf1d5aHCq0=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/invalid_v1_with_crlentryextension.pem b/pki/testdata/crl_unittest/invalid_v1_with_crlentryextension.pem
new file mode 100644
index 0000000..80f4d1c
--- /dev/null
+++ b/pki/testdata/crl_unittest/invalid_v1_with_crlentryextension.pem
@@ -0,0 +1,226 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf is revoked, has non-critical crlEntryExtension, but CRL is V1
+
+SEQUENCE {
+  SEQUENCE {
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    SEQUENCE {
+      SEQUENCE {
+        INTEGER { 105 }
+        UTCTime { "170201001122Z" }
+      }
+      SEQUENCE {
+        INTEGER { 5 }
+        UTCTime { "170201001122Z" }
+        SEQUENCE {
+          SEQUENCE {
+            OBJECT_IDENTIFIER { 1.2.3.4 }
+            OCTET_STRING { "Vx" }
+          }
+        }
+      }
+      SEQUENCE {
+        INTEGER { 106 }
+        UTCTime { "170201001122Z" }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00a2fb1d94229faf24bf6370773c0891eeb4fdf8f1e5249b14d8b6d01163c335acc8b42b806a25d44cbdb634cd97ac54af2a7801e39a435e34d8fc857a8fcff2dcbd92528e42b088761b7837fc10a25efe6f3da08a3c4fabbebf8b24947b146db025ec03508710efba824e220c873cb003f76ae2811f4f1ce9d2a3fd88daa57e68` }
+}
+-----BEGIN CRL-----
+MIIBLzCBmTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0IEludGVybWVk
+aWF0ZSBDQRcNMTcwMzAyMDAxMTIyWhcNMTcwNjAyMDAxMTIyWjBJMBICAWkXDTE3
+MDIwMTAwMTEyMlowHwIBBRcNMTcwMjAxMDAxMTIyWjALMAkGAyoDBAQCVngwEgIB
+ahcNMTcwMjAxMDAxMTIyWjANBgkqhkiG9w0BAQsFAAOBgQCi+x2UIp+vJL9jcHc8
+CJHutP348eUkmxTYttARY8M1rMi0K4BqJdRMvbY0zZesVK8qeAHjmkNeNNj8hXqP
+z/LcvZJSjkKwiHYbeDf8EKJe/m89oIo8T6u+v4sklHsUbbAl7ANQhxDvuoJOIgyH
+PLAD92rigR9PHOnSo/2I2qV+aA==
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/invalid_v1_with_extension.pem b/pki/testdata/crl_unittest/invalid_v1_with_extension.pem
new file mode 100644
index 0000000..0614ed3
--- /dev/null
+++ b/pki/testdata/crl_unittest/invalid_v1_with_extension.pem
@@ -0,0 +1,211 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+CRL is V1 and has crlExtensions
+
+SEQUENCE {
+  SEQUENCE {
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    [0] {
+      SEQUENCE {
+        SEQUENCE {
+          OBJECT_IDENTIFIER { 1.2.3.4 }
+          OCTET_STRING { "Vx" }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `003a96714ebf8d6153888f3d2833f42848ef5d2bbba3f8a44e958ec204113ed9a0de82255da8180cc06285b33d3d3e34ff9be49ec8dab07b3bd9c131e5cd79a43db03f4111945848ecde8bd043a7ce2ffca8f0951a020d4559fd11108bb97b034b920f9a3db500c5ae2021224ff1752b115f82865b44b606f603bd9814a7dbba44` }
+}
+-----BEGIN CRL-----
+MIHjME4wDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1lZGlh
+dGUgQ0EXDTE3MDMwMjAwMTEyMlqgDTALMAkGAyoDBAQCVngwDQYJKoZIhvcNAQEL
+BQADgYEAOpZxTr+NYVOIjz0oM/QoSO9dK7uj+KROlY7CBBE+2aDegiVdqBgMwGKF
+sz09PjT/m+SeyNqwezvZwTHlzXmkPbA/QRGUWEjs3ovQQ6fOL/yo8JUaAg1FWf0R
+EIu5ewNLkg+aPbUAxa4gISJP8XUrEV+ChltEtgb2A72YFKfbukQ=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/invalid_v3.pem b/pki/testdata/crl_unittest/invalid_v3.pem
new file mode 100644
index 0000000..d875860
--- /dev/null
+++ b/pki/testdata/crl_unittest/invalid_v3.pem
@@ -0,0 +1,205 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+CRL has invalid V3 version
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 2 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `005e4353437c2f00455f2bf02896f9d26df3a38b95484bd055f00fa87bd6708ba15d55b1c808b0e321b31bb56147111ef7aecb331f09a36e0015f43bb71b41fb3351fe6e8f7dc82d510a701adc5cd5f853bb8f70a73d2dd55c93cf419d9f961be610a63d3155d01d5b3d4de7fd218aec3a6bed9e115c353ddaf9c94f14272d92d6` }
+}
+-----BEGIN CRL-----
+MIHmMFECAQIwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMloXDTE3MDYwMjAwMTEyMlowDQYJKoZIhvcN
+AQELBQADgYEAXkNTQ3wvAEVfK/AolvnSbfOji5VIS9BV8A+oe9Zwi6FdVbHICLDj
+IbMbtWFHER73rsszHwmjbgAV9Du3G0H7M1H+bo99yC1RCnAa3FzV+FO7j3CnPS3V
+XJPPQZ2flhvmEKY9MVXQHVs9Tef9IYrsOmvtnhFcNT3a+clPFCctktY=
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/revoked.pem b/pki/testdata/crl_unittest/revoked.pem
new file mode 100644
index 0000000..9234722
--- /dev/null
+++ b/pki/testdata/crl_unittest/revoked.pem
@@ -0,0 +1,221 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf is revoked
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    SEQUENCE {
+      SEQUENCE {
+        INTEGER { 105 }
+        UTCTime { "170201001122Z" }
+      }
+      SEQUENCE {
+        INTEGER { 5 }
+        UTCTime { "170201001122Z" }
+      }
+      SEQUENCE {
+        INTEGER { 106 }
+        UTCTime { "170201001122Z" }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0011cc5c116d78337b3d2bd9724b4db3d75b8a81666726cb76774ad5cdc67410e55b2d05a47a272ed62640e53eaf9150e17c3153510e71c1b7df5093313b6b7f8f0abb95a9a64f9290c1d7f130b354a18b83ba2d7a9b5e19434dbba578890b4bda522c19862be404ebc78270fbdaebb61e6d5da8f05b919c0da0a7b2f7773cc13e` }
+}
+-----BEGIN CRL-----
+MIIBJTCBjwIBATANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0IEludGVy
+bWVkaWF0ZSBDQRcNMTcwMzAyMDAxMTIyWhcNMTcwNjAyMDAxMTIyWjA8MBICAWkX
+DTE3MDIwMTAwMTEyMlowEgIBBRcNMTcwMjAxMDAxMTIyWjASAgFqFw0xNzAyMDEw
+MDExMjJaMA0GCSqGSIb3DQEBCwUAA4GBABHMXBFteDN7PSvZcktNs9dbioFmZybL
+dndK1c3GdBDlWy0FpHonLtYmQOU+r5FQ4XwxU1EOccG331CTMTtrf48Ku5Wppk+S
+kMHX8TCzVKGLg7otepteGUNNu6V4iQtL2lIsGYYr5ATrx4Jw+9rrth5tXajwW5Gc
+DaCnsvd3PME+
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/revoked_fake_crlentryextension.pem b/pki/testdata/crl_unittest/revoked_fake_crlentryextension.pem
new file mode 100644
index 0000000..5ac34b0
--- /dev/null
+++ b/pki/testdata/crl_unittest/revoked_fake_crlentryextension.pem
@@ -0,0 +1,227 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf is revoked, has non-critical crlEntryExtension
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    SEQUENCE {
+      SEQUENCE {
+        INTEGER { 105 }
+        UTCTime { "170201001122Z" }
+      }
+      SEQUENCE {
+        INTEGER { 5 }
+        UTCTime { "170201001122Z" }
+        SEQUENCE {
+          SEQUENCE {
+            OBJECT_IDENTIFIER { 1.2.3.4 }
+            OCTET_STRING { "Vx" }
+          }
+        }
+      }
+      SEQUENCE {
+        INTEGER { 106 }
+        UTCTime { "170201001122Z" }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00b0a9d7db74d37682d636d76f4bc71e3128090466462304b3e65206ae30b49a29f84a5e751664743b039672f826aecb6cabf529e7c99597d546199518eacdd9e0eabb329476f3db85943940faf4b94df43fbaca025e836106545ec2195c8ea089037c2dd86c44d9040ba9b9cfdc55bf2101565aa2f20e2a436966d891ad9f4ebb` }
+}
+-----BEGIN CRL-----
+MIIBMjCBnAIBATANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0IEludGVy
+bWVkaWF0ZSBDQRcNMTcwMzAyMDAxMTIyWhcNMTcwNjAyMDAxMTIyWjBJMBICAWkX
+DTE3MDIwMTAwMTEyMlowHwIBBRcNMTcwMjAxMDAxMTIyWjALMAkGAyoDBAQCVngw
+EgIBahcNMTcwMjAxMDAxMTIyWjANBgkqhkiG9w0BAQsFAAOBgQCwqdfbdNN2gtY2
+129Lxx4xKAkEZkYjBLPmUgauMLSaKfhKXnUWZHQ7A5Zy+Cauy2yr9SnnyZWX1UYZ
+lRjqzdng6rsylHbz24WUOUD69LlN9D+6ygJeg2EGVF7CGVyOoIkDfC3YbETZBAup
+uc/cVb8hAVZaovIOKkNpZtiRrZ9Ouw==
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/revoked_generalized_revocationdate.pem b/pki/testdata/crl_unittest/revoked_generalized_revocationdate.pem
new file mode 100644
index 0000000..ca23bc1
--- /dev/null
+++ b/pki/testdata/crl_unittest/revoked_generalized_revocationdate.pem
@@ -0,0 +1,221 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf is revoked, revocationDate is encoded as GeneralizedTime
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    SEQUENCE {
+      SEQUENCE {
+        INTEGER { 105 }
+        GeneralizedTime { "20170201001122Z" }
+      }
+      SEQUENCE {
+        INTEGER { 5 }
+        GeneralizedTime { "20170201001122Z" }
+      }
+      SEQUENCE {
+        INTEGER { 106 }
+        GeneralizedTime { "20170201001122Z" }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `007d59b22ac22552a9be1ef56450194342faa40058a2dc1b8d4441ef26ebaf6cbfa02b8942df309e0a58d7feb3a75aa1a07e44a6dbfa1b9700d10a38520204c5f50358f6f94ea0d4d0c04e0f30a792b9b51dc10ae6aaaa3e3baddfa3c0f717dfd0bf14a12a24106f1517650ae6186b632d23d830a0502756b1b0d07564faeb8ae8` }
+}
+-----BEGIN CRL-----
+MIIBKzCBlQIBATANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0IEludGVy
+bWVkaWF0ZSBDQRcNMTcwMzAyMDAxMTIyWhcNMTcwNjAyMDAxMTIyWjBCMBQCAWkY
+DzIwMTcwMjAxMDAxMTIyWjAUAgEFGA8yMDE3MDIwMTAwMTEyMlowFAIBahgPMjAx
+NzAyMDEwMDExMjJaMA0GCSqGSIb3DQEBCwUAA4GBAH1ZsirCJVKpvh71ZFAZQ0L6
+pABYotwbjURB7ybrr2y/oCuJQt8wngpY1/6zp1qhoH5Eptv6G5cA0Qo4UgIExfUD
+WPb5TqDU0MBODzCnkrm1HcEK5qqqPjut36PA9xff0L8UoSokEG8VF2UK5hhrYy0j
+2DCgUCdWsbDQdWT664ro
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/revoked_key_rollover.pem b/pki/testdata/crl_unittest/revoked_key_rollover.pem
new file mode 100644
index 0000000..dd6086f
--- /dev/null
+++ b/pki/testdata/crl_unittest/revoked_key_rollover.pem
@@ -0,0 +1,292 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf issued by CA's new key but CRL is signed by old key
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    UTCTime { "170602001122Z" }
+    SEQUENCE {
+      SEQUENCE {
+        INTEGER { 9 }
+        UTCTime { "170201001122Z" }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0013d419461c51637185f5c0755a10669249c3e4c63f6ed6bec0c2a7869c7a540db4315b47f6b5c71c92928f48b19714a1a777ce408b71a4c1fde531b721280734c5e38ee644bc62c1b7080cb82201c41e902313d9decde3a496c8822954d7a83d891955c7f8b0096c6e217e08a0d5e92779286b350458df3af1f357bd6ce08420` }
+}
+-----BEGIN CRL-----
+MIH8MGcCAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1l
+ZGlhdGUgQ0EXDTE3MDMwMjAwMTEyMloXDTE3MDYwMjAwMTEyMlowFDASAgEJFw0x
+NzAyMDEwMDExMjJaMA0GCSqGSIb3DQEBCwUAA4GBABPUGUYcUWNxhfXAdVoQZpJJ
+w+TGP27WvsDCp4acelQNtDFbR/a1xxySko9IsZcUoad3zkCLcaTB/eUxtyEoBzTF
+447mRLxiwbcIDLgiAcQekCMT2d7N46SWyIIpVNeoPYkZVcf4sAlsbiF+CKDV6Sd5
+KGs1BFjfOvHzV71s4IQg
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 8 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b6e8ead8d014f4b5ddaf01f62b66392af991f70d2b011b2dc56de32a1e30d9d476848d31ebcb101094160590bf5ce992e347c8c0810a4d7717950d546c7ccbb966d560cf9042b511babdefc6d6018e95759081f78f1187486885ae0ce397cb49553edc356316cc86ba33cc984f9651658dc400f1d82a08478c65c9538883ec1b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004a64aa4f07ee7f6e9a156a637be6dfebf59562212b3cf0b6391153061331783e54aecbb67e9831480658cb7d07d2f96890ac2f9f8c8dbd726a0bb16aa3bd8104d9a8c3fdcbca2bc433e3cb4cf008d0caa9569bfce07f387e6d875ebe2bbfd18bdb960028c2b20de7a701c895b27e4976d989d7d819a21a836571974b94b49166` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIByjCCATOgAwIBAgIBCDANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAfMR0wGwYDVQQDDBRUZXN0IEludGVybWVkaWF0ZSBDQTCBnzANBgkqhkiG
+9w0BAQEFAAOBjQAwgYkCgYEAtujq2NAU9LXdrwH2K2Y5KvmR9w0rARstxW3jKh4w
+2dR2hI0x68sQEJQWBZC/XOmS40fIwIEKTXcXlQ1UbHzLuWbVYM+QQrURur3vxtYB
+jpV1kIH3jxGHSGiFrgzjl8tJVT7cNWMWzIa6M8yYT5ZRZY3EAPHYKghHjGXJU4iD
+7BsCAwEAAaMSMBAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBAEpk
+qk8H7n9umhVqY3vm3+v1lWIhKzzwtjkRUwYTMXg+VK7Ltn6YMUgGWMt9B9L5aJCs
+L5+Mjb1yaguxaqO9gQTZqMP9y8orxDPjy0zwCNDKqVab/OB/OH5th16+K7/Ri9uW
+ACjCsg3npwHIlbJ+SXbZidfYGaIag2Vxl0uUtJFm
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 9 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d93f6f55f607250217ce3500717d955de64ac5e21d179d2ee54b6b7657a267d8e3ff2d0bcbee37f4d32fda5d8930b393278cf34c260187455740aabb29c2e7e645087baecb5fbc341973ac10fd07972c2867f9a5048f5ff81d569d9c8337e5053ab9efd72c7c0164d7a4fdcb55dba8ec72a56c9c6b6c6d11ab866d8b06ab11d3` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `0021a05085069b97f7b91a3ac48ea6c06c41514123547497009bb2e167a359f059fd94064805e3e3a37cd98be3f4ed1b30e66865af5d3bb5b4ad78abc0096614a4561f2bf38b344f2fdd7238a5ff2358f27cda07771421d73bed8cb418776c4b9682b120ee4260aa6fd5263e72d02733e5f0e634b27e08b7fb9184ee1bef4dd6df` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBCTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBANk/b1X2ByUCF841AHF9lV3mSsXiHRedLuVLa3ZXomfY4/8tC8vuN/TT
+L9pdiTCzkyeM80wmAYdFV0CquynC5+ZFCHuuy1+8NBlzrBD9B5csKGf5pQSPX/gd
+Vp2cgzflBTq579csfAFk16T9y1XbqOxypWyca2xtEauGbYsGqxHTAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBACGgUIUGm5f3uRo6xI6mwGxBUUEjVHSXAJuy4WejWfBZ
+/ZQGSAXj46N82Yvj9O0bMOZoZa9dO7W0rXirwAlmFKRWHyvzizRPL91yOKX/I1jy
+fNoHdxQh1zvtjLQYd2xLloKxIO5CYKpv1SY+ctAnM+Xw5jSyfgi3+5GE7hvvTdbf
+-----END CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00c06603ddfbd7981fc745bb9378d177f606816bea25105b7f5ed9b0499bf506f3dc2687e8ee1375d183106c75b0b8ad5010e9e7316a924285984592b5ed7aa4db77bff25a5c99ade2d1eae254a3c1daf09e4194f987ac9f213582a627b9be45e64a50fd2c8b9e21c702125a6b5391d4f86d51e722689f1db653228912140d592b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `001e4faf090e17d359da4f6cc765fd51b135c2fde26d1210857d5bc7038dfa90b79d1db40557423419c4330973363fa5331d90f347055010ee1e8625675161a32cbacdcc6918b43dabd9d6c64a9a2942873db932f569c59cad35729fab922f99a0c08822d1c14bcf28f719d41f622a4006aefa71b032130bb7a6ef18359029162e` }
+}
+-----BEGIN CA CERTIFICATE 2-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDAZgPd+9eYH8dFu5N40Xf2BoFr6iUQW39e2bBJm/UG89wmh+juE3XRgxBs
+dbC4rVAQ6ecxapJChZhFkrXteqTbd7/yWlyZreLR6uJUo8Ha8J5BlPmHrJ8hNYKm
+J7m+ReZKUP0si54hxwISWmtTkdT4bVHnImifHbZTIokSFA1ZKwIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAHk+vCQ4X01naT2zHZf1R
+sTXC/eJtEhCFfVvHA436kLedHbQFV0I0GcQzCXM2P6UzHZDzRwVQEO4ehiVnUWGj
+LLrNzGkYtD2r2dbGSpopQoc9uTL1acWcrTVyn6uSL5mgwIgi0cFLzyj3GdQfYipA
+Bq76cbAyEwu3pu8YNZApFi4=
+-----END CA CERTIFICATE 2-----
\ No newline at end of file
diff --git a/pki/testdata/crl_unittest/revoked_no_nextupdate.pem b/pki/testdata/crl_unittest/revoked_no_nextupdate.pem
new file mode 100644
index 0000000..044149c
--- /dev/null
+++ b/pki/testdata/crl_unittest/revoked_no_nextupdate.pem
@@ -0,0 +1,219 @@
+Generated by generate_crl_test_data.py. Do not edit.
+
+Leaf is revoked, optional nextUpdate field is absent
+
+SEQUENCE {
+  SEQUENCE {
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    UTCTime { "170302001122Z" }
+    SEQUENCE {
+      SEQUENCE {
+        INTEGER { 105 }
+        UTCTime { "170201001122Z" }
+      }
+      SEQUENCE {
+        INTEGER { 5 }
+        UTCTime { "170201001122Z" }
+      }
+      SEQUENCE {
+        INTEGER { 106 }
+        UTCTime { "170201001122Z" }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00a1d992097ae54c4d66efc1662ac63772bff450d1de6eb15c50c182db8cb93c71f73606bf1c35f978438d708f07aba24cc8059550ea0fa6373ac44e36f4a298ebaba1493e4ed0ade0ea3071aaf6636572c087d2b405386e1336360ce3d43c2794fe3448df1582a3b51c3e3f2549ad565a6d8caebe7231ca12d517b4c33d31bc53` }
+}
+-----BEGIN CRL-----
+MIIBFjCBgAIBATANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0IEludGVy
+bWVkaWF0ZSBDQRcNMTcwMzAyMDAxMTIyWjA8MBICAWkXDTE3MDIwMTAwMTEyMlow
+EgIBBRcNMTcwMjAxMDAxMTIyWjASAgFqFw0xNzAyMDEwMDExMjJaMA0GCSqGSIb3
+DQEBCwUAA4GBAKHZkgl65UxNZu/BZirGN3K/9FDR3m6xXFDBgtuMuTxx9zYGvxw1
++XhDjXCPB6uiTMgFlVDqD6Y3OsRONvSimOuroUk+TtCt4Oowcar2Y2VywIfStAU4
+bhM2Ngzj1DwnlP40SN8VgqO1HD4/JUmtVlptjK6+cjHKEtUXtMM9MbxT
+-----END CRL-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 1 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00d822bfcd639ed70cd80d463b773cbc2d3a7c6d1523802a3adfaa928ba5266c501291e4a1a9b4d74f86687716380febfa0241e17afef736f1f7cc3908c219e09d8226a583b3c9c7f50b5c696640125daa14915d7dc5190d949363020c856016ec495685657d2da812254a8a0493e2c5453eea8a3b3be249392be1ab06aaac7bcb` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # keyUsage
+          OBJECT_IDENTIFIER { 2.5.29.15 }
+          BOOLEAN { `ff` }
+          OCTET_STRING {
+            BIT_STRING { `0106` }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `00564c8f891a5a03aab92dc18ab6f149027943c85a065b17d662af907c7b9a72135295c5768b63547d56ac24db2acc17de5b3efe864b3e1a3a40bd776488043bde40536c128b4070d0d42cdd59c61fd88e62727fb612836cee3914f8ed73eb45846814b3ac4ad9ff72ce914ac6758c919461029790753341135ca2aedcf41ca34b` }
+}
+-----BEGIN CA CERTIFICATE-----
+MIIBvTCCASagAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMCIYDzIwMTcwMTAxMDAwMDAwWhgPMjAxODAxMDEwMDAwMDBaMB8xHTAbBgNV
+BAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQDYIr/NY57XDNgNRjt3PLwtOnxtFSOAKjrfqpKLpSZsUBKR5KGptNdPhmh3
+FjgP6/oCQeF6/vc28ffMOQjCGeCdgialg7PJx/ULXGlmQBJdqhSRXX3FGQ2Uk2MC
+DIVgFuxJVoVlfS2oEiVKigST4sVFPuqKOzviSTkr4asGqqx7ywIDAQABoxIwEDAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAVkyPiRpaA6q5LcGKtvFJ
+AnlDyFoGWxfWYq+QfHuachNSlcV2i2NUfVasJNsqzBfeWz7+hks+GjpAvXdkiAQ7
+3kBTbBKLQHDQ1CzdWcYf2I5icn+2EoNs7jkU+O1z60WEaBSzrErZ/3LOkUrGdYyR
+lGECl5B1M0ETXKKu3PQco0s=
+-----END CA CERTIFICATE-----
+
+SEQUENCE {
+  SEQUENCE {
+    [0] {
+      INTEGER { 2 }
+    }
+    INTEGER { 5 }
+    SEQUENCE {
+      # sha256WithRSAEncryption
+      OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+      NULL {}
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Intermediate CA" }
+        }
+      }
+    }
+    SEQUENCE {
+      GeneralizedTime { "20170101000000Z" }
+      GeneralizedTime { "20180101000000Z" }
+    }
+    SEQUENCE {
+      SET {
+        SEQUENCE {
+          # commonName
+          OBJECT_IDENTIFIER { 2.5.4.3 }
+          UTF8String { "Test Cert" }
+        }
+      }
+    }
+    SEQUENCE {
+      SEQUENCE {
+        # rsaEncryption
+        OBJECT_IDENTIFIER { 1.2.840.113549.1.1.1 }
+        NULL {}
+      }
+      BIT_STRING {
+        `00`
+        SEQUENCE {
+          INTEGER { `00b2b9316002947538fd87b0dd430ad82d8938f019ad260d909c351ed586b993b25304ffc9881eac4a7ea5aff12762f7cedb345450d9d90ffd049f374cf1f528ae38679ba1aeea2df1f264c5f1ce8573a5549fee8c4dbec9836fd602eccb31cdd269267cbf673432886e28e4c18d5d1494760186ff65b1d958dfcd0659f75fad5b` }
+          INTEGER { 65537 }
+        }
+      }
+    }
+    [3] {
+      SEQUENCE {
+        SEQUENCE {
+          # cRLDistributionPoints
+          OBJECT_IDENTIFIER { 2.5.29.31 }
+          OCTET_STRING {
+            SEQUENCE {
+              SEQUENCE {
+                [0] {
+                  [0] {
+                    [6 PRIMITIVE] { "http://example.com/foo.crl" }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  SEQUENCE {
+    # sha256WithRSAEncryption
+    OBJECT_IDENTIFIER { 1.2.840.113549.1.1.11 }
+    NULL {}
+  }
+  BIT_STRING { `004f29397e7969a2b6fb2cf3e3d1efa5f44183abd33454414f3a140f00203cfbd47d3f0cab3a98355a822641527096ee6ab757e8c602a635af4a7ed4272f9452cd82ce18a7354affa7b7664706c18f4161a65d09532c7fc01c4cadcd776331fe88beb1b4e6c37b245bc10aade8e644bc86844db1390da8b0df09077e59b6e85a8e` }
+}
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAUWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMTgwMTAxMDAw
+MDAwWjAUMRIwEAYDVQQDDAlUZXN0IENlcnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBALK5MWAClHU4/Yew3UMK2C2JOPAZrSYNkJw1HtWGuZOyUwT/yYgerEp+
+pa/xJ2L3zts0VFDZ2Q/9BJ83TPH1KK44Z5uhruot8fJkxfHOhXOlVJ/ujE2+yYNv
+1gLsyzHN0mkmfL9nNDKIbijkwY1dFJR2AYb/ZbHZWN/NBln3X61bAgMBAAGjLzAt
+MCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9leGFtcGxlLmNvbS9mb28uY3JsMA0G
+CSqGSIb3DQEBCwUAA4GBAE8pOX55aaK2+yzz49HvpfRBg6vTNFRBTzoUDwAgPPvU
+fT8MqzqYNVqCJkFScJbuardX6MYCpjWvSn7UJy+UUs2CzhinNUr/p7dmRwbBj0Fh
+pl0JUyx/wBxMrc13YzH+iL6xtObDeyRbwQqt6OZEvIaETbE5Daiw3wkHflm26FqO
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/pki/testdata/verify_certificate_chain_unittest/intermediate-eku-any-and-clientauth/clientauth-strict.test~ b/pki/testdata/verify_certificate_chain_unittest/intermediate-eku-any-and-clientauth/clientauth-strict.test~
deleted file mode 100644
index 39c290f..0000000
--- a/pki/testdata/verify_certificate_chain_unittest/intermediate-eku-any-and-clientauth/clientauth-strict.test~
+++ /dev/null
@@ -1,5 +0,0 @@
-chain: chain.pem
-last_cert_trust: TRUSTED_ANCHOR
-utc_time: DEFAULT
-key_purpose: CLIENT_AUTH
-expected_errors:
diff --git a/pki/testdata/verify_certificate_chain_unittest/intermediate-eku-any-and-clientauth/serverauth-strict.test~ b/pki/testdata/verify_certificate_chain_unittest/intermediate-eku-any-and-clientauth/serverauth-strict.test~
deleted file mode 100644
index dde5873..0000000
--- a/pki/testdata/verify_certificate_chain_unittest/intermediate-eku-any-and-clientauth/serverauth-strict.test~
+++ /dev/null
@@ -1,10 +0,0 @@
-chain: chain.pem
-last_cert_trust: TRUSTED_ANCHOR
-utc_time: DEFAULT
-key_purpose: SERVER_AUTH_STRICT
-expected_errors:
-DERP
------ Certificate i=1 (CN=Intermediate) -----
-WARNING: The extended key usage does not include server auth but instead includes any auth
-ERROR: The extended key usage does not include server auth
-
diff --git a/pki/testdata/verify_certificate_chain_unittest/intermediate-eku-server-gated-crypto/sha1-eku-clientAuth-strict.test~ b/pki/testdata/verify_certificate_chain_unittest/intermediate-eku-server-gated-crypto/sha1-eku-clientAuth-strict.test~
deleted file mode 100644
index e564cba..0000000
--- a/pki/testdata/verify_certificate_chain_unittest/intermediate-eku-server-gated-crypto/sha1-eku-clientAuth-strict.test~
+++ /dev/null
@@ -1,9 +0,0 @@
-chain: sha1-chain.pem
-last_cert_trust: TRUSTED_ANCHOR
-utc_time: DEFAULT
-key_purpose: CLIENT_AUTH
-expected_errors:
------ Certificate i=1 (CN=Intermediate) -----
-WARNING: The extended key usage does not include client auth or server auth
-ERROR: The extended key usage does not include client auth
-
diff --git a/pki/testdata/verify_certificate_chain_unittest/intermediate-eku-server-gated-crypto/sha1-eku-serverAuth-strict.test~ b/pki/testdata/verify_certificate_chain_unittest/intermediate-eku-server-gated-crypto/sha1-eku-serverAuth-strict.test~
deleted file mode 100644
index 7c7b183..0000000
--- a/pki/testdata/verify_certificate_chain_unittest/intermediate-eku-server-gated-crypto/sha1-eku-serverAuth-strict.test~
+++ /dev/null
@@ -1,9 +0,0 @@
-chain: sha1-chain.pem
-last_cert_trust: TRUSTED_ANCHOR
-utc_time: DEFAULT
-key_purpose: SERVER_AUTH
-expected_errors:
------ Certificate i=1 (CN=Intermediate) -----
-WARNING: The extended key usage does not include client auth or server auth
-WARNING: The extended key usage does not include server auth but instead includes Netscape Server Gated Crypto
-
diff --git a/pki/testdata/verify_certificate_chain_unittest/intermediate-eku-server-gated-crypto/sha256-eku-clientAuth-strict.test~ b/pki/testdata/verify_certificate_chain_unittest/intermediate-eku-server-gated-crypto/sha256-eku-clientAuth-strict.test~
deleted file mode 100644
index caeec38..0000000
--- a/pki/testdata/verify_certificate_chain_unittest/intermediate-eku-server-gated-crypto/sha256-eku-clientAuth-strict.test~
+++ /dev/null
@@ -1,9 +0,0 @@
-chain: sha256-chain.pem
-last_cert_trust: TRUSTED_ANCHOR
-utc_time: DEFAULT
-key_purpose: CLIENT_AUTH
-expected_errors:
------ Certificate i=1 (CN=Intermediate) -----
-WARNING: The extended key usage does not include client auth or server auth
-ERROR: The extended key usage does not include client auth
-
diff --git a/pki/testdata/verify_certificate_chain_unittest/intermediate-eku-server-gated-crypto/sha256-eku-serverAuth-strict.test~ b/pki/testdata/verify_certificate_chain_unittest/intermediate-eku-server-gated-crypto/sha256-eku-serverAuth-strict.test~
deleted file mode 100644
index fa7127f..0000000
--- a/pki/testdata/verify_certificate_chain_unittest/intermediate-eku-server-gated-crypto/sha256-eku-serverAuth-strict.test~
+++ /dev/null
@@ -1,10 +0,0 @@
-chain: sha256-chain.pem
-last_cert_trust: TRUSTED_ANCHOR
-utc_time: DEFAULT
-key_purpose: SERVER_AUTH
-expected_errors:
------ Certificate i=1 (CN=Intermediate) -----
-WARNING: The extended key usage does not include client auth or server auth
-WARNING: The extended key usage does not include server auth but instead includes Netscape Server Gated Crypto
-ERROR: The extended key usage does not include server auth
-
diff --git a/pki/testdata/verify_certificate_chain_unittest/target-eku-none/clientauth-strict.test~ b/pki/testdata/verify_certificate_chain_unittest/target-eku-none/clientauth-strict.test~
deleted file mode 100644
index 034e219..0000000
--- a/pki/testdata/verify_certificate_chain_unittest/target-eku-none/clientauth-strict.test~
+++ /dev/null
@@ -1,9 +0,0 @@
-chain: chain.pem
-last_cert_trust: TRUSTED_ANCHOR
-utc_time: DEFAULT
-key_purpose: CLIENT_AUTH_STRICT
-expected_errors:
------ Certificate i=1 (CN=Intermediate) -----
-WARNING: The extended key usage does not include server auth but instead includes any auth
-ERROR: The extended key usage does not include server auth
-
diff --git a/pki/testdata/verify_certificate_chain_unittest/target-eku-none/serverauth-strict.test~ b/pki/testdata/verify_certificate_chain_unittest/target-eku-none/serverauth-strict.test~
deleted file mode 100644
index 5840823..0000000
--- a/pki/testdata/verify_certificate_chain_unittest/target-eku-none/serverauth-strict.test~
+++ /dev/null
@@ -1,9 +0,0 @@
-chain: chain.pem
-last_cert_trust: TRUSTED_ANCHOR
-utc_time: DEFAULT
-key_purpose: SERVER_AUTH_STRICT
-expected_errors:
------ Certificate i=1 (CN=Intermediate) -----
-WARNING: The extended key usage does not include server auth but instead includes any auth
-ERROR: The extended key usage does not include server auth
-
diff --git a/pki/x509_cert_types.h b/pki/x509_cert_types.h
deleted file mode 100644
index 42f9238..0000000
--- a/pki/x509_cert_types.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2012 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BSSL_PKI_X509_CERT_TYPES_H_
-#define BSSL_PKI_X509_CERT_TYPES_H_
-
-#include "fillins/openssl_util.h"
-#include <string>
-#include <vector>
-
-
-#include "input.h"
-
-namespace bssl {
-
-// CertPrincipal represents the issuer or subject field of an X.509 certificate.
-struct OPENSSL_EXPORT CertPrincipal {
-  CertPrincipal();
-  CertPrincipal(const CertPrincipal&);
-  CertPrincipal(CertPrincipal&&);
-  ~CertPrincipal();
-
-  // Configures handling of PrintableString values in the DistinguishedName. Do
-  // not use non-default handling without consulting //net owners. With
-  // kAsUTF8Hack, PrintableStrings are interpreted as UTF-8 strings.
-  enum class PrintableStringHandling { kDefault, kAsUTF8Hack };
-
-  // Parses a BER-format DistinguishedName.
-  bool ParseDistinguishedName(
-      der::Input ber_name_data,
-      PrintableStringHandling printable_string_handling =
-          PrintableStringHandling::kDefault);
-
-  // Returns a name that can be used to represent the issuer.  It tries in this
-  // order: CN, O and OU and returns the first non-empty one found.
-  std::string GetDisplayName() const;
-
-  // True if this object is equal to `other`. This is only exposed for testing,
-  // as a CertPrincipal object does not fully represent the X.509 Name it was
-  // parsed from, and comparing them likely does not mean what you want.
-  bool EqualsForTesting(const CertPrincipal& other) const;
-
-  // The different attributes for a principal, stored in UTF-8.  They may be "".
-  // Note that some of them can have several values.
-
-  std::string common_name;
-  std::string locality_name;
-  std::string state_or_province_name;
-  std::string country_name;
-
-  std::vector<std::string> organization_names;
-  std::vector<std::string> organization_unit_names;
-
- private:
-  // Comparison operator is private and only defined for use by
-  // EqualsForTesting, see comment there for more details.
-  bool operator==(const CertPrincipal& other) const;
-};
-
-}  // namespace net
-
-#endif  // BSSL_PKI_X509_CERT_TYPES_H_
diff --git a/pki/x509_certificate.cc b/pki/x509_certificate.cc
deleted file mode 100644
index 1505c71..0000000
--- a/pki/x509_certificate.cc
+++ /dev/null
@@ -1,784 +0,0 @@
-// Copyright 2012 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "fillins/bits.h"
-#include "string_util.h"
-#include "x509_certificate.h"
-
-#include <limits.h>
-#include <stdlib.h>
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "fillins/base64.h"
-
-#include <openssl/span.h>
-#include "base/logging.h"
-
-
-#include <string_view>
-
-#include "fillins/string_util.h"
-
-
-#include "fillins/openssl_util.h"
-#include "fillins/ip_address.h"
-#include "base/registry_controlled_domains/registry_controlled_domain.h"
-#include "base/tracing.h"
-#include "base/url_util.h"
-#include "asn1_util.h"
-#include "pem.h"
-#include "cert_errors.h"
-#include "name_constraints.h"
-#include "parsed_certificate.h"
-#include "signature_algorithm.h"
-#include "verify_certificate_chain.h"
-#include "verify_name_match.h"
-#include "verify_signed_data.h"
-#include "time_conversions.h"
-#include "fillins/x509_util.h"
-#include "parser.h"
-
-#include <openssl/evp.h>
-#include <openssl/pool.h>
-#include <openssl/sha.h>
-#include "url/url_canon.h"
-
-namespace bssl {
-
-namespace {
-
-// Indicates the order to use when trying to decode binary data, which is
-// based on (speculation) as to what will be most common -> least common
-const X509Certificate::Format kFormatDecodePriority[] = {
-  X509Certificate::FORMAT_SINGLE_CERTIFICATE,
-  X509Certificate::FORMAT_PKCS7
-};
-
-// The PEM block header used for DER certificates
-const char kCertificateHeader[] = "CERTIFICATE";
-// The PEM block header used for PKCS#7 data
-const char kPKCS7Header[] = "PKCS7";
-
-// Utility to split |src| on the first occurrence of |c|, if any. |right| will
-// either be empty if |c| was not found, or will contain the remainder of the
-// string including the split character itself.
-void SplitOnChar(std::string_view src,
-                 char c,
-                 std::string_view* left,
-                 std::string_view* right) {
-  size_t pos = src.find(c);
-  if (pos == std::string_view::npos) {
-    *left = src;
-    *right = std::string_view();
-  } else {
-    *left = src.substr(0, pos);
-    *right = src.substr(pos);
-  }
-}
-
-// Sets |value| to the Value from a DER Sequence Tag-Length-Value and return
-// true, or return false if the TLV was not a valid DER Sequence.
-[[nodiscard]] bool ParseSequenceValue(const der::Input& tlv,
-                                      der::Input* value) {
-  der::Parser parser(tlv);
-  return parser.ReadTag(der::kSequence, value) && !parser.HasMore();
-}
-
-// Normalize |cert|'s Issuer and store it in |out_normalized_issuer|, returning
-// true on success or false if there was a parsing error.
-bool GetNormalizedCertIssuer(CRYPTO_BUFFER* cert,
-                             std::string* out_normalized_issuer) {
-  der::Input tbs_certificate_tlv;
-  der::Input signature_algorithm_tlv;
-  der::BitString signature_value;
-  if (!ParseCertificate(
-          der::Input(CRYPTO_BUFFER_data(cert), CRYPTO_BUFFER_len(cert)),
-          &tbs_certificate_tlv, &signature_algorithm_tlv, &signature_value,
-          nullptr)) {
-    return false;
-  }
-  ParsedTbsCertificate tbs;
-  if (!ParseTbsCertificate(tbs_certificate_tlv,
-                           x509_util::DefaultParseCertificateOptions(), &tbs,
-                           nullptr))
-    return false;
-
-  der::Input issuer_value;
-  if (!ParseSequenceValue(tbs.issuer_tlv, &issuer_value))
-    return false;
-
-  CertErrors errors;
-  return NormalizeName(issuer_value, out_normalized_issuer, &errors);
-}
-
-bssl::UniquePtr<CRYPTO_BUFFER> CreateCertBufferFromBytesWithSanityCheck(
-    bssl::Span<const uint8_t> data) {
-  der::Input tbs_certificate_tlv;
-  der::Input signature_algorithm_tlv;
-  der::BitString signature_value;
-  // Do a bare minimum of DER parsing here to see if the input looks
-  // certificate-ish.
-  if (!ParseCertificate(der::Input(data.data(), data.size()),
-                        &tbs_certificate_tlv, &signature_algorithm_tlv,
-                        &signature_value, nullptr)) {
-    return nullptr;
-  }
-  return x509_util::CreateCryptoBuffer(data);
-}
-
-}  // namespace
-
-// static
-std::shared_ptr<X509Certificate> X509Certificate::CreateFromBuffer(
-    bssl::UniquePtr<CRYPTO_BUFFER> cert_buffer,
-    std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates) {
-  return CreateFromBufferUnsafeOptions(std::move(cert_buffer),
-                                       std::move(intermediates), {});
-}
-
-// static
-std::shared_ptr<X509Certificate> X509Certificate::CreateFromBufferUnsafeOptions(
-    bssl::UniquePtr<CRYPTO_BUFFER> cert_buffer,
-    std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates,
-    UnsafeCreateOptions options) {
-  DCHECK(cert_buffer);
-  ParsedFields parsed;
-  if (!parsed.Initialize(cert_buffer.get(), options)) {
-    return nullptr;
-  }
-  return base::WrapRefCounted(new X509Certificate(
-      std::move(parsed), std::move(cert_buffer), std::move(intermediates)));
-}
-
-// static
-std::shared_ptr<X509Certificate> X509Certificate::CreateFromDERCertChain(
-    const std::vector<std::string_view>& der_certs) {
-  return CreateFromDERCertChainUnsafeOptions(der_certs, {});
-}
-
-// static
-std::shared_ptr<X509Certificate>
-X509Certificate::CreateFromDERCertChainUnsafeOptions(
-    const std::vector<std::string_view>& der_certs,
-    UnsafeCreateOptions options) {
-  TRACE_EVENT0("io", "X509Certificate::CreateFromDERCertChain");
-  if (der_certs.empty())
-    return nullptr;
-
-  std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediate_ca_certs;
-  intermediate_ca_certs.reserve(der_certs.size() - 1);
-  for (size_t i = 1; i < der_certs.size(); i++) {
-    intermediate_ca_certs.push_back(
-        x509_util::CreateCryptoBuffer(der_certs[i]));
-  }
-
-  return CreateFromBufferUnsafeOptions(
-      x509_util::CreateCryptoBuffer(der_certs[0]),
-      std::move(intermediate_ca_certs), options);
-}
-
-// static
-std::shared_ptr<X509Certificate> X509Certificate::CreateFromBytes(
-    bssl::Span<const uint8_t> data) {
-  return CreateFromBytesUnsafeOptions(data, {});
-}
-
-// static
-std::shared_ptr<X509Certificate> X509Certificate::CreateFromBytesUnsafeOptions(
-    bssl::Span<const uint8_t> data,
-    UnsafeCreateOptions options) {
-  std::shared_ptr<X509Certificate> cert = CreateFromBufferUnsafeOptions(
-      x509_util::CreateCryptoBuffer(data), {}, options);
-  return cert;
-}
-
-// static
-std::shared_ptr<X509Certificate> X509Certificate::CreateFromPickle(
-    base::PickleIterator* pickle_iter) {
-  return CreateFromPickleUnsafeOptions(pickle_iter, {});
-}
-
-// static
-std::shared_ptr<X509Certificate> X509Certificate::CreateFromPickleUnsafeOptions(
-    base::PickleIterator* pickle_iter,
-    UnsafeCreateOptions options) {
-  size_t chain_length = 0;
-  if (!pickle_iter->ReadLength(&chain_length))
-    return nullptr;
-
-  std::vector<std::string_view> cert_chain;
-  const char* data = nullptr;
-  size_t data_length = 0;
-  for (size_t i = 0; i < chain_length; ++i) {
-    if (!pickle_iter->ReadData(&data, &data_length))
-      return nullptr;
-    cert_chain.emplace_back(data, data_length);
-  }
-  return CreateFromDERCertChainUnsafeOptions(cert_chain, options);
-}
-
-// static
-CertificateList X509Certificate::CreateCertificateListFromBytes(
-    bssl::Span<const uint8_t> data,
-    int format) {
-  std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> certificates;
-
-  // Check to see if it is in a PEM-encoded form. This check is performed
-  // first, as both OS X and NSS will both try to convert if they detect
-  // PEM encoding, except they don't do it consistently between the two.
-  std::string_view data_string(reinterpret_cast<const char*>(data.data()),
-                                data.size());
-  std::vector<std::string> pem_headers;
-
-  // To maintain compatibility with NSS/Firefox, CERTIFICATE is a universally
-  // valid PEM block header for any format.
-  pem_headers.push_back(kCertificateHeader);
-  if (format & FORMAT_PKCS7)
-    pem_headers.push_back(kPKCS7Header);
-
-  PEMTokenizer pem_tokenizer(data_string, pem_headers);
-  while (pem_tokenizer.GetNext()) {
-    std::string decoded(pem_tokenizer.data());
-
-    bssl::UniquePtr<CRYPTO_BUFFER> handle;
-    if (format & FORMAT_PEM_CERT_SEQUENCE) {
-      handle = CreateCertBufferFromBytesWithSanityCheck(
-          fillins::as_bytes(bssl::MakeSpan(decoded)));
-    }
-    if (handle) {
-      // Parsed a DER encoded certificate. All PEM blocks that follow must
-      // also be DER encoded certificates wrapped inside of PEM blocks.
-      format = FORMAT_PEM_CERT_SEQUENCE;
-      certificates.push_back(std::move(handle));
-      continue;
-    }
-
-    // If the first block failed to parse as a DER certificate, and
-    // formats other than PEM are acceptable, check to see if the decoded
-    // data is one of the accepted formats.
-    if (format & ~FORMAT_PEM_CERT_SEQUENCE) {
-      for (size_t i = 0;
-           certificates.empty() && i < std::size(kFormatDecodePriority); ++i) {
-        if (format & kFormatDecodePriority[i]) {
-          certificates = CreateCertBuffersFromBytes(
-              fillins::as_bytes(bssl::MakeSpan(decoded)),
-              kFormatDecodePriority[i]);
-        }
-      }
-    }
-
-    // Stop parsing after the first block for any format but a sequence of
-    // PEM-encoded DER certificates. The case of FORMAT_PEM_CERT_SEQUENCE
-    // is handled above, and continues processing until a certificate fails
-    // to parse.
-    break;
-  }
-
-  // Try each of the formats, in order of parse preference, to see if |data|
-  // contains the binary representation of a Format, if it failed to parse
-  // as a PEM certificate/chain.
-  for (size_t i = 0;
-       certificates.empty() && i < std::size(kFormatDecodePriority); ++i) {
-    if (format & kFormatDecodePriority[i])
-      certificates = CreateCertBuffersFromBytes(data, kFormatDecodePriority[i]);
-  }
-
-  CertificateList results;
-  // No certificates parsed.
-  if (certificates.empty())
-    return results;
-
-  for (auto& it : certificates) {
-    std::shared_ptr<X509Certificate> cert = CreateFromBuffer(std::move(it), {});
-    if (cert)
-      results.push_back(std::move(cert));
-  }
-
-  return results;
-}
-
-std::shared_ptr<X509Certificate> X509Certificate::CloneWithDifferentIntermediates(
-    std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates) {
-  // If intermediates are the same, return another reference to the same
-  // object. Note that this only does a pointer equality comparison on the
-  // CRYPTO_BUFFERs, which is generally sufficient, but in some edge cases
-  // buffers have equal contents but with different addresses. This is
-  // acceptable as this is just an optimization.
-  if (intermediates == intermediate_ca_certs_) {
-    return this;
-  }
-
-  return base::WrapRefCounted(
-      new X509Certificate(*this, std::move(intermediates)));
-}
-
-void X509Certificate::Persist(base::Pickle* pickle) const {
-  DCHECK(cert_buffer_);
-  // This would be an absolutely insane number of intermediates.
-  if (intermediate_ca_certs_.size() > static_cast<size_t>(INT_MAX) - 1) {
-    abort(); //NOTREACHED;
-    return;
-  }
-  pickle->WriteInt(static_cast<int>(intermediate_ca_certs_.size() + 1));
-  pickle->WriteString(x509_util::CryptoBufferAsStringPiece(cert_buffer_.get()));
-  for (const auto& intermediate : intermediate_ca_certs_) {
-    pickle->WriteString(
-        x509_util::CryptoBufferAsStringPiece(intermediate.get()));
-  }
-}
-
-bool X509Certificate::GetSubjectAltName(
-    std::vector<std::string>* dns_names,
-    std::vector<std::string>* ip_addrs) const {
-  if (dns_names)
-    dns_names->clear();
-  if (ip_addrs)
-    ip_addrs->clear();
-
-  der::Input tbs_certificate_tlv;
-  der::Input signature_algorithm_tlv;
-  der::BitString signature_value;
-  if (!ParseCertificate(der::Input(CRYPTO_BUFFER_data(cert_buffer_.get()),
-                                   CRYPTO_BUFFER_len(cert_buffer_.get())),
-                        &tbs_certificate_tlv, &signature_algorithm_tlv,
-                        &signature_value, nullptr)) {
-    return false;
-  }
-
-  ParsedTbsCertificate tbs;
-  if (!ParseTbsCertificate(tbs_certificate_tlv,
-                           x509_util::DefaultParseCertificateOptions(), &tbs,
-                           nullptr))
-    return false;
-  if (!tbs.extensions_tlv)
-    return false;
-
-  std::map<der::Input, ParsedExtension> extensions;
-  if (!ParseExtensions(tbs.extensions_tlv.value(), &extensions))
-    return false;
-
-  ParsedExtension subject_alt_names_extension;
-  if (!ConsumeExtension(der::Input(kSubjectAltNameOid), &extensions,
-                        &subject_alt_names_extension)) {
-    return false;
-  }
-
-  CertErrors errors;
-  std::unique_ptr<GeneralNames> subject_alt_names =
-      GeneralNames::Create(subject_alt_names_extension.value, &errors);
-  if (!subject_alt_names)
-    return false;
-
-  if (dns_names) {
-    for (const auto& dns_name : subject_alt_names->dns_names)
-      dns_names->push_back(std::string(dns_name));
-  }
-  if (ip_addrs) {
-    for (const fillins::IPAddress& addr : subject_alt_names->ip_addresses) {
-      ip_addrs->push_back(
-          std::string(reinterpret_cast<const char*>(addr.bytes().data()),
-                      addr.bytes().size()));
-    }
-  }
-
-  return !subject_alt_names->dns_names.empty() ||
-         !subject_alt_names->ip_addresses.empty();
-}
-
-bool X509Certificate::HasExpired() const {
-  return absl::Now() > valid_expiry();
-}
-
-bool X509Certificate::EqualsExcludingChain(const X509Certificate* other) const {
-  return x509_util::CryptoBufferEqual(cert_buffer_.get(),
-                                      other->cert_buffer_.get());
-}
-
-bool X509Certificate::EqualsIncludingChain(const X509Certificate* other) const {
-  if (intermediate_ca_certs_.size() != other->intermediate_ca_certs_.size() ||
-      !EqualsExcludingChain(other)) {
-    return false;
-  }
-  for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) {
-    if (!x509_util::CryptoBufferEqual(intermediate_ca_certs_[i].get(),
-                                      other->intermediate_ca_certs_[i].get())) {
-      return false;
-    }
-  }
-  return true;
-}
-
-bool X509Certificate::IsIssuedByEncoded(
-    const std::vector<std::string>& valid_issuers) const {
-  std::vector<std::string> normalized_issuers;
-  CertErrors errors;
-  for (const auto& raw_issuer : valid_issuers) {
-    der::Input issuer_value;
-    std::string normalized_issuer;
-    if (!ParseSequenceValue(der::Input(&raw_issuer), &issuer_value) ||
-        !NormalizeName(issuer_value, &normalized_issuer, &errors)) {
-      continue;
-    }
-    normalized_issuers.push_back(std::move(normalized_issuer));
-  }
-
-  std::string normalized_cert_issuer;
-  if (!GetNormalizedCertIssuer(cert_buffer_.get(), &normalized_cert_issuer))
-    return false;
-  if (base::Contains(normalized_issuers, normalized_cert_issuer))
-    return true;
-
-  for (const auto& intermediate : intermediate_ca_certs_) {
-    if (!GetNormalizedCertIssuer(intermediate.get(), &normalized_cert_issuer))
-      return false;
-    if (base::Contains(normalized_issuers, normalized_cert_issuer))
-      return true;
-  }
-  return false;
-}
-
-// static
-bool X509Certificate::VerifyHostname(
-    const std::string& hostname,
-    const std::vector<std::string>& cert_san_dns_names,
-    const std::vector<std::string>& cert_san_ip_addrs) {
-  DCHECK(!hostname.empty());
-
-  if (cert_san_dns_names.empty() && cert_san_ip_addrs.empty()) {
-    // Either a dNSName or iPAddress subjectAltName MUST be present in order
-    // to match, so fail quickly if not.
-    return false;
-  }
-
-  // Perform name verification following http://tools.ietf.org/html/rfc6125.
-  // The terminology used in this method is as per that RFC:-
-  // Reference identifier == the host the local user/agent is intending to
-  //                         access, i.e. the thing displayed in the URL bar.
-  // Presented identifier(s) == name(s) the server knows itself as, in its cert.
-
-  // CanonicalizeHost requires surrounding brackets to parse an IPv6 address.
-  const std::string host_or_ip = hostname.find(':') != std::string::npos ?
-      "[" + hostname + "]" : hostname;
-  url::CanonHostInfo host_info;
-  std::string reference_name = CanonicalizeHost(host_or_ip, &host_info);
-
-  // If the host cannot be canonicalized, fail fast.
-  if (reference_name.empty())
-    return false;
-
-  // Fully handle all cases where |hostname| contains an IP address.
-  if (host_info.IsIPAddress()) {
-    std::string_view ip_addr_string(
-        reinterpret_cast<const char*>(host_info.address),
-        host_info.AddressLength());
-    return base::Contains(cert_san_ip_addrs, ip_addr_string);
-  }
-
-  // The host portion of a URL may support a variety of name resolution formats
-  // and services. However, the only supported name types in this code are IP
-  // addresses, which have been handled above via iPAddress subjectAltNames,
-  // and DNS names, via dNSName subjectAltNames.
-  // Validate that the host conforms to the DNS preferred name syntax, in
-  // either relative or absolute form, and exclude the "root" label for DNS.
-  if (reference_name == "." || !IsCanonicalizedHostCompliant(reference_name))
-    return false;
-
-  // CanonicalizeHost does not normalize absolute vs relative DNS names. If
-  // the input name was absolute (included trailing .), normalize it as if it
-  // was relative.
-  if (reference_name.back() == '.')
-    reference_name.pop_back();
-
-  // |reference_domain| is the remainder of |host| after the leading host
-  // component is stripped off, but includes the leading dot e.g.
-  // "www.f.com" -> ".f.com".
-  // If there is no meaningful domain part to |host| (e.g. it contains no dots)
-  // then |reference_domain| will be empty.
-  std::string_view reference_host, reference_domain;
-  SplitOnChar(reference_name, '.', &reference_host, &reference_domain);
-  bool allow_wildcards = false;
-  if (!reference_domain.empty()) {
-    DCHECK(bssl::string_util::StartsWith(reference_domain, "."));
-
-    // Do not allow wildcards for public/ICANN registry controlled domains -
-    // that is, prevent *.com or *.co.uk as valid presented names, but do not
-    // prevent *.appspot.com (a private registry controlled domain).
-    // In addition, unknown top-level domains (such as 'intranet' domains or
-    // new TLDs/gTLDs not yet added to the registry controlled domain dataset)
-    // are also implicitly prevented.
-    // Because |reference_domain| must contain at least one name component that
-    // is not registry controlled, this ensures that all reference domains
-    // contain at least three domain components when using wildcards.
-    size_t registry_length =
-        registry_controlled_domains::GetCanonicalHostRegistryLength(
-            reference_name,
-            registry_controlled_domains::INCLUDE_UNKNOWN_REGISTRIES,
-            registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES);
-
-    // Because |reference_name| was already canonicalized, the following
-    // should never happen.
-    CHECK_NE(std::string::npos, registry_length);
-
-    // Account for the leading dot in |reference_domain|.
-    bool is_registry_controlled =
-        registry_length != 0 &&
-        registry_length == (reference_domain.size() - 1);
-
-    // Additionally, do not attempt wildcard matching for purely numeric
-    // hostnames.
-    allow_wildcards =
-        !is_registry_controlled &&
-        reference_name.find_first_not_of("0123456789.") != std::string::npos;
-  }
-
-  // Now step through the DNS names doing wild card comparison (if necessary)
-  // on each against the reference name.
-  for (const auto& cert_san_dns_name : cert_san_dns_names) {
-    // Catch badly corrupt cert names up front.
-    if (cert_san_dns_name.empty() ||
-        cert_san_dns_name.find('\0') != std::string::npos) {
-      continue;
-    }
-    std::string presented_name(base::ToLowerASCII(cert_san_dns_name));
-
-    // Remove trailing dot, if any.
-    if (*presented_name.rbegin() == '.')
-      presented_name.resize(presented_name.length() - 1);
-
-    // The hostname must be at least as long as the cert name it is matching,
-    // as we require the wildcard (if present) to match at least one character.
-    if (presented_name.length() > reference_name.length())
-      continue;
-
-    std::string_view presented_host, presented_domain;
-    SplitOnChar(presented_name, '.', &presented_host, &presented_domain);
-
-    if (presented_domain != reference_domain)
-      continue;
-
-    if (presented_host != "*") {
-      if (presented_host == reference_host)
-        return true;
-      continue;
-    }
-
-    if (!allow_wildcards)
-      continue;
-
-    return true;
-  }
-  return false;
-}
-
-bool X509Certificate::VerifyNameMatch(const std::string& hostname) const {
-  std::vector<std::string> dns_names, ip_addrs;
-  GetSubjectAltName(&dns_names, &ip_addrs);
-  return VerifyHostname(hostname, dns_names, ip_addrs);
-}
-
-// static
-bool X509Certificate::GetPEMEncodedFromDER(std::string_view der_encoded,
-                                           std::string* pem_encoded) {
-  if (der_encoded.empty())
-    return false;
-
-  *pem_encoded = PEMEncode(der_encoded, "CERTIFICATE");
-  return true;
-}
-
-// static
-bool X509Certificate::GetPEMEncoded(const CRYPTO_BUFFER* cert_buffer,
-                                    std::string* pem_encoded) {
-  return GetPEMEncodedFromDER(x509_util::CryptoBufferAsStringPiece(cert_buffer),
-                              pem_encoded);
-}
-
-bool X509Certificate::GetPEMEncodedChain(
-    std::vector<std::string>* pem_encoded) const {
-  std::vector<std::string> encoded_chain;
-  std::string pem_data;
-  if (!GetPEMEncoded(cert_buffer(), &pem_data))
-    return false;
-  encoded_chain.push_back(pem_data);
-  for (const auto& intermediate_ca_cert : intermediate_ca_certs_) {
-    if (!GetPEMEncoded(intermediate_ca_cert.get(), &pem_data))
-      return false;
-    encoded_chain.push_back(pem_data);
-  }
-  pem_encoded->swap(encoded_chain);
-  return true;
-}
-
-// static
-void X509Certificate::GetPublicKeyInfo(const CRYPTO_BUFFER* cert_buffer,
-                                       size_t* size_bits,
-                                       PublicKeyType* type) {
-  *type = kPublicKeyTypeUnknown;
-  *size_bits = 0;
-
-  std::string_view spki;
-  if (!asn1::ExtractSPKIFromDERCert(
-          std::string_view(
-              reinterpret_cast<const char*>(CRYPTO_BUFFER_data(cert_buffer)),
-              CRYPTO_BUFFER_len(cert_buffer)),
-          &spki)) {
-    return;
-  }
-
-  bssl::UniquePtr<EVP_PKEY> pkey;
-  fillins::OpenSSLErrStackTracer err_tracer;
-  CBS cbs;
-  CBS_init(&cbs, reinterpret_cast<const uint8_t*>(spki.data()), spki.size());
-  pkey.reset(EVP_parse_public_key(&cbs));
-  if (!pkey)
-    return;
-
-  switch (EVP_PKEY_id(pkey.get())) {
-    case EVP_PKEY_RSA:
-      *type = kPublicKeyTypeRSA;
-      break;
-    case EVP_PKEY_DSA:
-      *type = kPublicKeyTypeDSA;
-      break;
-    case EVP_PKEY_EC:
-      *type = kPublicKeyTypeECDSA;
-      break;
-    case EVP_PKEY_DH:
-      *type = kPublicKeyTypeDH;
-      break;
-  }
-  *size_bits = base::saturated_cast<size_t>(EVP_PKEY_bits(pkey.get()));
-}
-
-// static
-std::vector<bssl::UniquePtr<CRYPTO_BUFFER>>
-X509Certificate::CreateCertBuffersFromBytes(bssl::Span<const uint8_t> data,
-                                            Format format) {
-  std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> results;
-
-  switch (format) {
-    case FORMAT_SINGLE_CERTIFICATE: {
-      bssl::UniquePtr<CRYPTO_BUFFER> handle =
-          CreateCertBufferFromBytesWithSanityCheck(data);
-      if (handle)
-        results.push_back(std::move(handle));
-      break;
-    }
-    case FORMAT_PKCS7: {
-      x509_util::CreateCertBuffersFromPKCS7Bytes(data, &results);
-      break;
-    }
-    default: {
-      abort(); //NOTREACHED << "Certificate format " << format << " unimplemented";
-      break;
-    }
-  }
-
-  return results;
-}
-
-// static
-SHA256HashValue X509Certificate::CalculateFingerprint256(
-    const CRYPTO_BUFFER* cert) {
-  SHA256HashValue sha256;
-
-  SHA256(CRYPTO_BUFFER_data(cert), CRYPTO_BUFFER_len(cert), sha256.data);
-  return sha256;
-}
-
-SHA256HashValue X509Certificate::CalculateChainFingerprint256() const {
-  SHA256HashValue sha256;
-  memset(sha256.data, 0, sizeof(sha256.data));
-
-  SHA256_CTX sha256_ctx;
-  SHA256_Init(&sha256_ctx);
-  SHA256_Update(&sha256_ctx, CRYPTO_BUFFER_data(cert_buffer_.get()),
-                CRYPTO_BUFFER_len(cert_buffer_.get()));
-  for (const auto& cert : intermediate_ca_certs_) {
-    SHA256_Update(&sha256_ctx, CRYPTO_BUFFER_data(cert.get()),
-                  CRYPTO_BUFFER_len(cert.get()));
-  }
-  SHA256_Final(sha256.data, &sha256_ctx);
-
-  return sha256;
-}
-
-// static
-bool X509Certificate::IsSelfSigned(CRYPTO_BUFFER* cert_buffer) {
-  std::shared_ptr<const ParsedCertificate> parsed_cert =
-      ParsedCertificate::Create(bssl::UpRef(cert_buffer),
-                                x509_util::DefaultParseCertificateOptions(),
-                                /*errors=*/nullptr);
-  if (!parsed_cert) {
-    return false;
-  }
-  return VerifyCertificateIsSelfSigned(*parsed_cert, /*cache=*/nullptr,
-                                       /*errors=*/nullptr);
-}
-
-X509Certificate::X509Certificate(
-    ParsedFields parsed,
-    bssl::UniquePtr<CRYPTO_BUFFER> cert_buffer,
-    std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates)
-    : parsed_(std::move(parsed)),
-      cert_buffer_(std::move(cert_buffer)),
-      intermediate_ca_certs_(std::move(intermediates)) {}
-
-X509Certificate::X509Certificate(
-    const X509Certificate& other,
-    std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates)
-    : parsed_(other.parsed_),
-      cert_buffer_(bssl::UpRef(other.cert_buffer_)),
-      intermediate_ca_certs_(std::move(intermediates)) {}
-
-X509Certificate::~X509Certificate() = default;
-
-X509Certificate::ParsedFields::ParsedFields() = default;
-X509Certificate::ParsedFields::ParsedFields(const ParsedFields&) = default;
-X509Certificate::ParsedFields::ParsedFields(ParsedFields&&) = default;
-X509Certificate::ParsedFields::~ParsedFields() = default;
-
-bool X509Certificate::ParsedFields::Initialize(
-    const CRYPTO_BUFFER* cert_buffer,
-    X509Certificate::UnsafeCreateOptions options) {
-  der::Input tbs_certificate_tlv;
-  der::Input signature_algorithm_tlv;
-  der::BitString signature_value;
-
-  if (!ParseCertificate(der::Input(CRYPTO_BUFFER_data(cert_buffer),
-                                   CRYPTO_BUFFER_len(cert_buffer)),
-                        &tbs_certificate_tlv, &signature_algorithm_tlv,
-                        &signature_value, nullptr)) {
-    return false;
-  }
-
-  ParsedTbsCertificate tbs;
-  if (!ParseTbsCertificate(tbs_certificate_tlv,
-                           x509_util::DefaultParseCertificateOptions(), &tbs,
-                           nullptr))
-    return false;
-
-  CertPrincipal::PrintableStringHandling printable_string_handling =
-      options.printable_string_is_utf8
-          ? CertPrincipal::PrintableStringHandling::kAsUTF8Hack
-          : CertPrincipal::PrintableStringHandling::kDefault;
-  if (!subject_.ParseDistinguishedName(tbs.subject_tlv,
-                                       printable_string_handling) ||
-      !issuer_.ParseDistinguishedName(tbs.issuer_tlv,
-                                      printable_string_handling)) {
-    return false;
-  }
-
-  if (!GeneralizedTimeToTime(tbs.validity_not_before, &valid_start_) ||
-      !GeneralizedTimeToTime(tbs.validity_not_after, &valid_expiry_)) {
-    return false;
-  }
-  serial_number_ = tbs.serial_number.AsString();
-  return true;
-}
-
-}  // namespace net
diff --git a/pki/x509_certificate.h b/pki/x509_certificate.h
deleted file mode 100644
index bc2d8d1..0000000
--- a/pki/x509_certificate.h
+++ /dev/null
@@ -1,343 +0,0 @@
-// Copyright 2012 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BSSL_PKI_X509_CERTIFICATE_H_
-#define BSSL_PKI_X509_CERTIFICATE_H_
-
-#include "fillins/openssl_util.h"
-#include "fillins/time.h"
-#include <stddef.h>
-#include <string.h>
-
-#include <string>
-#include <vector>
-
-#include <openssl/span.h>
-
-#include <memory>
-#include <string_view>
-
-
-#include "fillins/hash_value.h"
-
-#include "x509_cert_types.h"
-#include <openssl/base.h>
-
-namespace base {
-class Pickle;
-class PickleIterator;
-}
-
-namespace bssl {
-
-class X509Certificate;
-
-typedef std::vector<std::shared_ptr<X509Certificate> > CertificateList;
-
-// A X.509 certificate represents a particular identity or end-entity
-// certificate, such as an SSL server identity or an SSL client certificate. An
-// X509Certificate contains this leaf certificate accessible via cert_buffer().
-// An X509Certificate may also contain 0 or more intermediary X.509 certificates
-// that are used to build a path to a root certificate. These are accessed via
-// intermediate_buffers().
-class OPENSSL_EXPORT X509Certificate
-     {
- public:
-  enum PublicKeyType {
-    kPublicKeyTypeUnknown,
-    kPublicKeyTypeRSA,
-    kPublicKeyTypeDSA,
-    kPublicKeyTypeECDSA,
-    kPublicKeyTypeDH,
-    kPublicKeyTypeECDH
-  };
-
-  enum Format {
-    // The data contains a single DER-encoded certificate, or a PEM-encoded
-    // DER certificate with the PEM encoding block name of "CERTIFICATE".
-    // Any subsequent blocks will be ignored.
-    FORMAT_SINGLE_CERTIFICATE = 1 << 0,
-
-    // The data contains a sequence of one or more PEM-encoded, DER
-    // certificates, with the PEM encoding block name of "CERTIFICATE".
-    // All PEM blocks will be parsed, until the first error is encountered.
-    FORMAT_PEM_CERT_SEQUENCE = 1 << 1,
-
-    // The data contains a PKCS#7 SignedData structure, whose certificates
-    // member is to be used to initialize the certificate and intermediates.
-    // The data may further be encoded using PEM, specifying block names of
-    // either "PKCS7" or "CERTIFICATE".
-    FORMAT_PKCS7 = 1 << 2,
-
-    // Automatically detect the format.
-    FORMAT_AUTO = FORMAT_SINGLE_CERTIFICATE | FORMAT_PEM_CERT_SEQUENCE |
-                  FORMAT_PKCS7,
-  };
-
-  // Create an X509Certificate from a CRYPTO_BUFFER containing the DER-encoded
-  // representation. Returns NULL on failure to parse or extract data from the
-  // the certificate. Note that this does not guarantee the certificate is
-  // fully parsed and validated, only that the members of this class, such as
-  // subject, issuer, expiry times, and serial number, could be successfully
-  // initialized from the certificate.
-  static std::shared_ptr<X509Certificate> CreateFromBuffer(
-      bssl::UniquePtr<CRYPTO_BUFFER> cert_buffer,
-      std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates);
-
-  // Options for configuring certificate parsing.
-  // Do not use without consulting //net owners.
-  struct UnsafeCreateOptions {
-    bool printable_string_is_utf8 = false;
-  };
-  // Create an X509Certificate with non-standard parsing options.
-  // Do not use without consulting //net owners.
-  static std::shared_ptr<X509Certificate> CreateFromBufferUnsafeOptions(
-      bssl::UniquePtr<CRYPTO_BUFFER> cert_buffer,
-      std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates,
-      UnsafeCreateOptions options);
-
-  // Create an X509Certificate from a chain of DER encoded certificates. The
-  // first certificate in the chain is the end-entity certificate to which a
-  // handle is returned. The other certificates in the chain are intermediate
-  // certificates.
-  static std::shared_ptr<X509Certificate> CreateFromDERCertChain(
-      const std::vector<std::string_view>& der_certs);
-
-  // Create an X509Certificate from a chain of DER encoded certificates with
-  // non-standard parsing options.
-  // Do not use without consulting //net owners.
-  static std::shared_ptr<X509Certificate> CreateFromDERCertChainUnsafeOptions(
-      const std::vector<std::string_view>& der_certs,
-      UnsafeCreateOptions options);
-
-  // Create an X509Certificate from the DER-encoded representation.
-  // Returns NULL on failure.
-  static std::shared_ptr<X509Certificate> CreateFromBytes(
-      bssl::Span<const uint8_t> data);
-
-  // Create an X509Certificate with non-standard parsing options.
-  // Do not use without consulting //net owners.
-  static std::shared_ptr<X509Certificate> CreateFromBytesUnsafeOptions(
-      bssl::Span<const uint8_t> data,
-      UnsafeCreateOptions options);
-
-  // Create an X509Certificate from the representation stored in the given
-  // pickle.  The data for this object is found relative to the given
-  // pickle_iter, which should be passed to the pickle's various Read* methods.
-  // Returns NULL on failure.
-  static std::shared_ptr<X509Certificate> CreateFromPickle(
-      base::PickleIterator* pickle_iter);
-
-  // Create an X509Certificate from the representation stored in the given
-  // pickle with non-standard parsing options.
-  // Do not use without consulting //net owners.
-  static std::shared_ptr<X509Certificate> CreateFromPickleUnsafeOptions(
-      base::PickleIterator* pickle_iter,
-      UnsafeCreateOptions options);
-
-  // Parses all of the certificates possible from |data|. |format| is a
-  // bit-wise OR of Format, indicating the possible formats the
-  // certificates may have been serialized as. If an error occurs, an empty
-  // collection will be returned.
-  static CertificateList CreateCertificateListFromBytes(
-      bssl::Span<const uint8_t> data,
-      int format);
-
-  // Return a X509Certificate object representing the same certificate but
-  // with a different set of intermediates. If |intermediates| are the same as
-  // |intermediate_ca_certs_|, it will return a reference to the same
-  // X509Certificate object rather than cloning.
-  std::shared_ptr<X509Certificate> CloneWithDifferentIntermediates(
-      std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates);
-
-  X509Certificate(const X509Certificate&) = delete;
-  X509Certificate& operator=(const X509Certificate&) = delete;
-
-  // Appends a representation of this object to the given pickle.
-  // The Pickle contains the certificate and any certificates that were
-  // stored in |intermediate_ca_certs_| at the time it was serialized.
-  // The format is [int count], [data - this certificate],
-  // [data - intermediate1], ... [data - intermediateN].
-  // All certificates are stored in DER form.
-  void Persist(base::Pickle* pickle) const;
-
-  // The serial number, DER encoded, possibly including a leading 00 byte.
-  const std::string& serial_number() const { return parsed_.serial_number_; }
-
-  // The subject of the certificate.  For HTTPS server certificates, this
-  // represents the web server.  The common name of the subject should match
-  // the host name of the web server.
-  const CertPrincipal& subject() const { return parsed_.subject_; }
-
-  // The issuer of the certificate.
-  const CertPrincipal& issuer() const { return parsed_.issuer_; }
-
-  // Time period during which the certificate is valid.  More precisely, this
-  // certificate is invalid before the |valid_start| date and invalid after
-  // the |valid_expiry| date.
-  // If we were unable to parse either date from the certificate (or if the cert
-  // lacks either date), the date will be null (i.e., is_null() will be true).
-  const absl::Time& valid_start() const { return parsed_.valid_start_; }
-  const absl::Time& valid_expiry() const { return parsed_.valid_expiry_; }
-
-  // Gets the subjectAltName extension field from the certificate, if any.
-  // For future extension; currently this only returns those name types that
-  // are required for HTTP certificate name verification - see VerifyHostname.
-  // Returns true if any dNSName or iPAddress SAN was present. If |dns_names|
-  // is non-null, it will be set to all dNSNames present. If |ip_addrs| is
-  // non-null, it will be set to all iPAddresses present.
-  bool GetSubjectAltName(std::vector<std::string>* dns_names,
-                         std::vector<std::string>* ip_addrs) const;
-
-  // Convenience method that returns whether this certificate has expired as of
-  // now.
-  bool HasExpired() const;
-
-  // Returns true if this object and |other| represent the same certificate.
-  // Does not consider any associated intermediates.
-  bool EqualsExcludingChain(const X509Certificate* other) const;
-
-  // Returns true if this object and |other| represent the same certificate
-  // and intermediates.
-  bool EqualsIncludingChain(const X509Certificate* other) const;
-
-  // Do any of the given issuer names appear in this cert's chain of trust?
-  // |valid_issuers| is a list of DER-encoded X.509 DistinguishedNames.
-  bool IsIssuedByEncoded(const std::vector<std::string>& valid_issuers) const;
-
-  // Verifies that |hostname| matches this certificate.
-  // Does not verify that the certificate is valid, only that the certificate
-  // matches this host.
-  bool VerifyNameMatch(const std::string& hostname) const;
-
-  // Returns the PEM encoded data from a DER encoded certificate. If the
-  // return value is true, then the PEM encoded certificate is written to
-  // |pem_encoded|.
-  static bool GetPEMEncodedFromDER(std::string_view der_encoded,
-                                   std::string* pem_encoded);
-
-  // Returns the PEM encoded data from a CRYPTO_BUFFER. If the return value is
-  // true, then the PEM encoded certificate is written to |pem_encoded|.
-  static bool GetPEMEncoded(const CRYPTO_BUFFER* cert_buffer,
-                            std::string* pem_encoded);
-
-  // Encodes the entire certificate chain (this certificate and any
-  // intermediate certificates stored in |intermediate_ca_certs_|) as a series
-  // of PEM encoded strings. Returns true if all certificates were encoded,
-  // storing the result in |*pem_encoded|, with this certificate stored as
-  // the first element.
-  bool GetPEMEncodedChain(std::vector<std::string>* pem_encoded) const;
-
-  // Sets |*size_bits| to be the length of the public key in bits, and sets
-  // |*type| to one of the |PublicKeyType| values. In case of
-  // |kPublicKeyTypeUnknown|, |*size_bits| will be set to 0.
-  static void GetPublicKeyInfo(const CRYPTO_BUFFER* cert_buffer,
-                               size_t* size_bits,
-                               PublicKeyType* type);
-
-  // Returns the CRYPTO_BUFFER holding this certificate's DER encoded data. The
-  // data is not guaranteed to be valid DER or to encode a valid Certificate
-  // object.
-  CRYPTO_BUFFER* cert_buffer() const { return cert_buffer_.get(); }
-
-  // Returns the associated intermediate certificates that were specified
-  // during creation of this object, if any. The intermediates are not
-  // guaranteed to be valid DER or to encode valid Certificate objects.
-  // Ownership follows the "get" rule: it is the caller's responsibility to
-  // retain the elements of the result.
-  const std::vector<bssl::UniquePtr<CRYPTO_BUFFER>>& intermediate_buffers()
-      const {
-    return intermediate_ca_certs_;
-  }
-
-  // Creates all possible CRYPTO_BUFFERs from |data| encoded in a specific
-  // |format|. Returns an empty collection on failure.
-  static std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> CreateCertBuffersFromBytes(
-      bssl::Span<const uint8_t> data,
-      Format format);
-
-  // Calculates the SHA-256 fingerprint of the certificate.  Returns an empty
-  // (all zero) fingerprint on failure.
-  static SHA256HashValue CalculateFingerprint256(
-      const CRYPTO_BUFFER* cert_buffer);
-
-  // Calculates the SHA-256 fingerprint for the complete chain, including the
-  // leaf certificate and all intermediate CA certificates. Returns an empty
-  // (all zero) fingerprint on failure.
-  SHA256HashValue CalculateChainFingerprint256() const;
-
-  // Returns true if the certificate is self-signed.
-  static bool IsSelfSigned(CRYPTO_BUFFER* cert_buffer);
-
- private:
-  
-  friend class TestRootCerts;  // For unit tests
-
-  
-  
-
-  class ParsedFields {
-   public:
-    ParsedFields();
-    ParsedFields(const ParsedFields&);
-    ParsedFields(ParsedFields&&);
-    ~ParsedFields();
-
-    bool Initialize(const CRYPTO_BUFFER* cert_buffer,
-                    UnsafeCreateOptions options);
-
-    // The subject of the certificate.
-    CertPrincipal subject_;
-
-    // The issuer of the certificate.
-    CertPrincipal issuer_;
-
-    // This certificate is not valid before |valid_start_|
-    absl::Time valid_start_;
-
-    // This certificate is not valid after |valid_expiry_|
-    absl::Time valid_expiry_;
-
-    // The serial number of this certificate, DER encoded.
-    std::string serial_number_;
-  };
-
-  // Construct an X509Certificate from a CRYPTO_BUFFER containing the
-  // DER-encoded representation.
-  X509Certificate(ParsedFields parsed,
-                  bssl::UniquePtr<CRYPTO_BUFFER> cert_buffer,
-                  std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates);
-
-  // Copy |other|, except with a different set of intermediates.
-  X509Certificate(const X509Certificate& other,
-                  std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates);
-
-  ~X509Certificate();
-
-  // Verifies that |hostname| matches one of the certificate names or IP
-  // addresses supplied, based on TLS name matching rules - specifically,
-  // following http://tools.ietf.org/html/rfc6125.
-  // The members of |cert_san_dns_names| and |cert_san_ipaddrs| must be filled
-  // from the dNSName and iPAddress components of the subject alternative name
-  // extension, if present. Note these IP addresses are NOT ascii-encoded:
-  // they must be 4 or 16 bytes of network-ordered data, for IPv4 and IPv6
-  // addresses, respectively.
-  static bool VerifyHostname(const std::string& hostname,
-                             const std::vector<std::string>& cert_san_dns_names,
-                             const std::vector<std::string>& cert_san_ip_addrs);
-
-  // Fields that were parsed from |cert_buffer_|.
-  const ParsedFields parsed_;
-
-  // A handle to the DER encoded certificate data.
-  const bssl::UniquePtr<CRYPTO_BUFFER> cert_buffer_;
-
-  // Untrusted intermediate certificates associated with this certificate
-  // that may be needed for chain building.
-  const std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediate_ca_certs_;
-};
-
-}  // namespace net
-
-#endif  // BSSL_PKI_X509_CERTIFICATE_H_
diff --git a/sources.cmake b/sources.cmake
index 10767d3..3153efc 100644
--- a/sources.cmake
+++ b/sources.cmake
@@ -386,10 +386,12 @@
   crypto/test/gtest_main.cc
   pki/cert_issuer_source_static_unittest.cc
   pki/certificate_policies_unittest.cc
+  pki/crl_unittest.cc
   pki/encode_values_unittest.cc
   pki/extended_key_usage_unittest.cc
   pki/fillins/file_util.cc
   pki/fillins/path_service.cc
+  pki/general_names_unittest.cc
   pki/input_unittest.cc
   pki/mock_signature_verify_cache.cc
   pki/name_constraints_unittest.cc
@@ -486,6 +488,73 @@
   pki/testdata/certificate_policies_unittest/policy_1_2_3_and_1_2_4_with_qualifiers.pem
   pki/testdata/certificate_policies_unittest/policy_1_2_3_with_custom_qualifier.pem
   pki/testdata/certificate_policies_unittest/policy_1_2_3_with_qualifier.pem
+  pki/testdata/crl_unittest/bad_crldp_has_crlissuer.pem
+  pki/testdata/crl_unittest/bad_fake_critical_crlentryextension.pem
+  pki/testdata/crl_unittest/bad_fake_critical_extension.pem
+  pki/testdata/crl_unittest/bad_idp_contains_wrong_uri.pem
+  pki/testdata/crl_unittest/bad_idp_indirectcrl.pem
+  pki/testdata/crl_unittest/bad_idp_onlycontainscacerts.pem
+  pki/testdata/crl_unittest/bad_idp_onlycontainscacerts_no_basic_constraints.pem
+  pki/testdata/crl_unittest/bad_idp_onlycontainsusercerts.pem
+  pki/testdata/crl_unittest/bad_idp_uri_and_onlycontainscacerts.pem
+  pki/testdata/crl_unittest/bad_idp_uri_and_onlycontainsusercerts.pem
+  pki/testdata/crl_unittest/bad_key_rollover_signature.pem
+  pki/testdata/crl_unittest/bad_nextupdate_too_old.pem
+  pki/testdata/crl_unittest/bad_signature.pem
+  pki/testdata/crl_unittest/bad_thisupdate_in_future.pem
+  pki/testdata/crl_unittest/bad_thisupdate_too_old.pem
+  pki/testdata/crl_unittest/bad_wrong_issuer.pem
+  pki/testdata/crl_unittest/generate_crl_test_data.py
+  pki/testdata/crl_unittest/good.pem
+  pki/testdata/crl_unittest/good_fake_extension.pem
+  pki/testdata/crl_unittest/good_fake_extension_no_nextupdate.pem
+  pki/testdata/crl_unittest/good_generalizedtime.pem
+  pki/testdata/crl_unittest/good_idp_contains_uri.pem
+  pki/testdata/crl_unittest/good_idp_onlycontainscacerts.pem
+  pki/testdata/crl_unittest/good_idp_onlycontainsusercerts.pem
+  pki/testdata/crl_unittest/good_idp_onlycontainsusercerts_no_basic_constraints.pem
+  pki/testdata/crl_unittest/good_idp_uri_and_onlycontainscacerts.pem
+  pki/testdata/crl_unittest/good_idp_uri_and_onlycontainsusercerts.pem
+  pki/testdata/crl_unittest/good_issuer_name_normalization.pem
+  pki/testdata/crl_unittest/good_issuer_no_keyusage.pem
+  pki/testdata/crl_unittest/good_key_rollover.pem
+  pki/testdata/crl_unittest/good_no_crldp.pem
+  pki/testdata/crl_unittest/good_no_nextupdate.pem
+  pki/testdata/crl_unittest/good_no_version.pem
+  pki/testdata/crl_unittest/invalid_garbage_after_crlentryextensions.pem
+  pki/testdata/crl_unittest/invalid_garbage_after_extensions.pem
+  pki/testdata/crl_unittest/invalid_garbage_after_nextupdate.pem
+  pki/testdata/crl_unittest/invalid_garbage_after_revocationdate.pem
+  pki/testdata/crl_unittest/invalid_garbage_after_revokedcerts.pem
+  pki/testdata/crl_unittest/invalid_garbage_after_signaturevalue.pem
+  pki/testdata/crl_unittest/invalid_garbage_after_thisupdate.pem
+  pki/testdata/crl_unittest/invalid_garbage_crlentry.pem
+  pki/testdata/crl_unittest/invalid_garbage_issuer_name.pem
+  pki/testdata/crl_unittest/invalid_garbage_revocationdate.pem
+  pki/testdata/crl_unittest/invalid_garbage_revoked_serial_number.pem
+  pki/testdata/crl_unittest/invalid_garbage_signaturealgorithm.pem
+  pki/testdata/crl_unittest/invalid_garbage_signaturevalue.pem
+  pki/testdata/crl_unittest/invalid_garbage_tbs_signature_algorithm.pem
+  pki/testdata/crl_unittest/invalid_garbage_tbscertlist.pem
+  pki/testdata/crl_unittest/invalid_garbage_thisupdate.pem
+  pki/testdata/crl_unittest/invalid_garbage_version.pem
+  pki/testdata/crl_unittest/invalid_idp_dpname_choice_extra_data.pem
+  pki/testdata/crl_unittest/invalid_idp_empty_sequence.pem
+  pki/testdata/crl_unittest/invalid_idp_onlycontains_user_and_ca_certs.pem
+  pki/testdata/crl_unittest/invalid_idp_onlycontainsusercerts_v1_leaf.pem
+  pki/testdata/crl_unittest/invalid_issuer_keyusage_no_crlsign.pem
+  pki/testdata/crl_unittest/invalid_key_rollover_issuer_keyusage_no_crlsign.pem
+  pki/testdata/crl_unittest/invalid_mismatched_signature_algorithm.pem
+  pki/testdata/crl_unittest/invalid_revoked_empty_sequence.pem
+  pki/testdata/crl_unittest/invalid_v1_explicit.pem
+  pki/testdata/crl_unittest/invalid_v1_with_crlentryextension.pem
+  pki/testdata/crl_unittest/invalid_v1_with_extension.pem
+  pki/testdata/crl_unittest/invalid_v3.pem
+  pki/testdata/crl_unittest/revoked.pem
+  pki/testdata/crl_unittest/revoked_fake_crlentryextension.pem
+  pki/testdata/crl_unittest/revoked_generalized_revocationdate.pem
+  pki/testdata/crl_unittest/revoked_key_rollover.pem
+  pki/testdata/crl_unittest/revoked_no_nextupdate.pem
   pki/testdata/name_constraints_unittest/directoryname-excludeall.pem
   pki/testdata/name_constraints_unittest/directoryname-excluded.pem
   pki/testdata/name_constraints_unittest/directoryname.pem