298 if(!m_is_ca && m_path_length_constraint.has_value()) {
300 throw Invalid_Argument(
301 "Basic_Constraints nonsensical to set a path length constraint for a non-CA basicConstraints");
310 return m_path_length_constraint.value_or(NO_CERT_PATH_LIMIT);
312 throw Invalid_State(
"Basic_Constraints::get_path_limit: Not a CA");
320 std::vector<uint8_t> output;
334void Basic_Constraints::decode_inner(
const std::vector<uint8_t>& in) {
346 if(m_constraints.empty()) {
347 throw Encoding_Error(
"Cannot encode empty PKIX key constraints");
350 const size_t constraint_bits = m_constraints.value();
351 const size_t unused_bits =
ctz(
static_cast<uint32_t
>(constraint_bits));
353 std::vector<uint8_t> der;
355 der.push_back(2 + ((unused_bits < 8) ? 1 : 0));
356 der.push_back(unused_bits % 8);
357 der.push_back(
static_cast<uint8_t
>((constraint_bits >> 8) & 0xFF));
358 if((constraint_bits & 0xFF) != 0) {
359 der.push_back(
static_cast<uint8_t
>(constraint_bits & 0xFF));
368void Key_Usage::decode_inner(
const std::vector<uint8_t>& in) {
371 BER_Object obj = ber.get_next_object();
375 if(obj.length() == 2 || obj.length() == 3) {
378 const uint8_t* bits = obj.bits();
381 throw BER_Decoding_Error(
"Invalid unused bits in usage constraint");
384 const uint8_t mask =
static_cast<uint8_t
>(0xFF << bits[0]);
386 if(obj.length() == 2) {
388 }
else if(obj.length() == 3) {
392 m_constraints = Key_Constraints(usage);
394 m_constraints = Key_Constraints(0);
402 std::vector<uint8_t> output;
410void Subject_Key_ID::decode_inner(
const std::vector<uint8_t>& in) {
420 m_key_id.resize(hash->output_length());
422 hash->update(pub_key);
423 hash->final(m_key_id.data());
426 const size_t max_skid_len = (192 / 8);
427 if(m_key_id.size() > max_skid_len) {
428 m_key_id.resize(max_skid_len);
436 std::vector<uint8_t> output;
447void Authority_Key_ID::decode_inner(
const std::vector<uint8_t>& in) {
455 std::vector<uint8_t> output;
456 DER_Encoder(output).encode(m_alt_name);
464 std::vector<uint8_t> output;
465 DER_Encoder(output).encode(m_alt_name);
472void Subject_Alternative_Name::decode_inner(
const std::vector<uint8_t>& in) {
473 BER_Decoder(in).
decode(m_alt_name);
479void Issuer_Alternative_Name::decode_inner(
const std::vector<uint8_t>& in) {
480 BER_Decoder(in).
decode(m_alt_name);
487 std::vector<uint8_t> output;
495void Extended_Key_Usage::decode_inner(
const std::vector<uint8_t>& in) {
503 throw Not_Implemented(
"Name_Constraints encoding");
509void Name_Constraints::decode_inner(
const std::vector<uint8_t>& in) {
511 BER_Decoder inner = ber.start_sequence();
513 std::vector<GeneralSubtree> permitted;
515 if(permitted.empty()) {
516 throw Decoding_Error(
"Empty NameConstraint permitted list");
520 std::vector<GeneralSubtree> excluded;
522 if(excluded.empty()) {
523 throw Decoding_Error(
"Empty NameConstraint excluded list");
529 if(permitted.empty() && excluded.empty()) {
530 throw Decoding_Error(
"Empty NameConstraint extension");
533 m_name_constraints = NameConstraints(std::move(permitted), std::move(excluded));
538 const std::vector<X509_Certificate>& cert_path,
539 std::vector<std::set<Certificate_Status_Code>>& cert_status,
541 if(!m_name_constraints.permitted().empty() || !m_name_constraints.excluded().empty()) {
546 const bool issuer_name_constraint_critical = subject.
is_critical(
"X509v3.NameConstraints");
549 for(
size_t j = 0; j < pos; ++j) {
550 const auto& cert = cert_path.at(j);
552 if(!m_name_constraints.is_permitted(cert, issuer_name_constraint_critical)) {
557 if(m_name_constraints.is_excluded(cert, issuer_name_constraint_critical)) {
570class Policy_Information final :
public ASN1_Object {
572 Policy_Information() =
default;
574 explicit Policy_Information(
const OID& oid) : m_oid(oid) {}
576 const OID& oid()
const {
return m_oid; }
578 void encode_into(DER_Encoder& codec)
const override { codec.start_sequence().encode(m_oid).end_cons(); }
580 void decode_from(BER_Decoder& codec)
override {
581 codec.start_sequence().decode(m_oid).discard_remaining().end_cons();
594 std::vector<Policy_Information> policies;
596 policies.reserve(m_oids.size());
597 for(
const auto& oid : m_oids) {
598 policies.push_back(Policy_Information(oid));
601 std::vector<uint8_t> output;
602 DER_Encoder(output).start_sequence().encode_list(policies).end_cons();
609void Certificate_Policies::decode_inner(
const std::vector<uint8_t>& in) {
610 std::vector<Policy_Information> policies;
612 BER_Decoder(in).decode_list(policies);
614 for(
const auto& policy : policies) {
615 m_oids.push_back(policy.oid());
621 const std::vector<X509_Certificate>& ,
622 std::vector<std::set<Certificate_Status_Code>>& cert_status,
624 std::set<OID> oid_set(m_oids.begin(), m_oids.end());
625 if(oid_set.size() != m_oids.size()) {
631 std::vector<uint8_t> output;
634 der.start_sequence();
636 if(!m_ocsp_responder.empty()) {
645 for(
const auto& ca_isser : m_ca_issuers) {
657void Authority_Information_Access::decode_inner(
const std::vector<uint8_t>& in) {
658 BER_Decoder ber = BER_Decoder(in).start_sequence();
660 while(ber.more_items()) {
663 BER_Decoder info = ber.start_sequence();
668 BER_Object name = info.get_next_object();
675 BER_Object name = info.get_next_object();
701 return std::make_unique<CRL_Number>(m_crl_number);
708 std::vector<uint8_t> output;
716void CRL_Number::decode_inner(
const std::vector<uint8_t>& in) {
725 std::vector<uint8_t> output;
733void CRL_ReasonCode::decode_inner(
const std::vector<uint8_t>& in) {
734 size_t reason_code = 0;
736 m_reason =
static_cast<CRL_Code>(reason_code);
740 std::vector<uint8_t> output;
741 DER_Encoder(output).start_sequence().encode_list(m_distribution_points).end_cons();
745void CRL_Distribution_Points::decode_inner(
const std::vector<uint8_t>& buf) {
746 BER_Decoder(buf).decode_list(m_distribution_points).verify_end();
748 std::stringstream ss;
750 for(
const auto& distribution_point : m_distribution_points) {
751 auto contents = distribution_point.point().contents();
753 for(
const auto& pair : contents) {
754 ss << pair.first <<
": " << pair.second <<
" ";
758 m_crl_distribution_urls.push_back(ss.str());
762 const auto uris = m_point.uris();
765 throw Not_Implemented(
"Empty CRL_Distribution_Point encoding not implemented");
768 for(
const auto& uri : uris) {
795void CRL_Issuing_Distribution_Point::decode_inner(
const std::vector<uint8_t>& buf) {
800 throw Not_Implemented(
"TNAuthList extension entry serialization is not supported");
806 const uint32_t type_tag =
static_cast<Type>(obj.
type_tag());
812 m_data = std::move(spc_string);
816 auto& range_items = std::get<RangeContainer>(m_data);
822 if(!is_valid_telephone_number(entry.
start)) {
827 if(entry.
count < 2) {
831 range_items.emplace_back(std::move(entry));
835 if(range_items.empty()) {
842 if(!is_valid_telephone_number(one_string)) {
845 m_data = std::move(one_string);
852 throw Not_Implemented(
"TNAuthList extension serialization is not supported");
855void TNAuthList::decode_inner(
const std::vector<uint8_t>& in) {
857 if(m_tn_entries.empty()) {
864 return std::get<ASN1_String>(m_data).value();
869 return std::get<RangeContainer>(m_data);
874 return std::get<ASN1_String>(m_data).value();
878 std::vector<uint8_t> output;
883void IPAddressBlocks::decode_inner(
const std::vector<uint8_t>& in) {
893 if(m_safi.has_value()) {
894 afam.push_back(m_safi.value());
910 throw Decoding_Error(
fmt(
"Unexpected type for IPAddressFamily {}",
static_cast<uint32_t
>(next_tag)));
915 std::vector<uint8_t> addr_family;
917 const size_t addr_family_length = addr_family.size();
919 if(addr_family_length != 2 && addr_family_length != 3) {
923 m_afi = (addr_family[0] << 8) | addr_family[1];
925 if(addr_family_length == 3) {
926 m_safi = addr_family[2];
933 }
else if(m_afi == 2) {
944void IPAddressBlocks::sort_and_merge() {
955 std::map<std::pair<uint16_t, std::optional<uint8_t>>, std::vector<IPAddressFamily>> afam_map;
957 auto key = std::make_pair(block.afi(), block.safi());
958 std::vector<IPAddressFamily>& fams = afam_map[key];
959 fams.push_back(block);
962 std::vector<IPAddressFamily> merged_blocks;
963 for(
auto& it : afam_map) {
965 std::vector<IPAddressFamily>& fams = it.second;
971 if(std::holds_alternative<IPAddressChoice<Version::IPv4>>(fams[0].addr_choice())) {
972 merged_blocks.push_back(merge<Version::IPv4>(fams));
974 merged_blocks.push_back(merge<Version::IPv6>(fams));
977 m_ip_addr_blocks = merged_blocks;
980template <IPAddressBlocks::Version V>
981IPAddressBlocks::IPAddressFamily IPAddressBlocks::merge(std::vector<IPAddressFamily>& blocks) {
986 BOTAN_ASSERT(!blocks.empty(),
"Cannot merge an empty set of IP address blocks into a single family");
989 if(blocks.size() == 1) {
993 bool all_inherit =
true;
994 bool none_inherit =
true;
995 for(IPAddressFamily& block : blocks) {
996 IPAddressChoice<V> choice = std::get<IPAddressChoice<V>>(block.addr_choice());
997 all_inherit = !choice.ranges().has_value() && all_inherit;
998 none_inherit = choice.ranges().has_value() && none_inherit;
1003 return IPAddressFamily(IPAddressChoice<V>(), blocks[0].safi());
1007 if(!all_inherit && !none_inherit) {
1008 throw Decoding_Error(
"Invalid IPAddressBlocks: Only one of 'inherit' or 'do not inherit' is allowed per family");
1011 std::vector<IPAddressOrRange<V>> merged_ranges;
1012 for(IPAddressFamily& block : blocks) {
1013 IPAddressChoice<V> choice = std::get<IPAddressChoice<V>>(block.addr_choice());
1014 std::vector<IPAddressOrRange<V>> ranges = choice.ranges().value();
1015 for(IPAddressOrRange<V>& r : ranges) {
1016 merged_ranges.push_back(r);
1021 IPAddressChoice<V> choice(merged_ranges);
1022 IPAddressFamily fam(choice, blocks[0].safi());
1031template <IPAddressBlocks::Version V>
1032using IPRangeVec = std::vector<IPAddressBlocks::IPAddressOrRange<V>>;
1036template <IPAddressBlocks::Version V>
1037using IPValidationMap = std::map<uint32_t, std::pair<bool, const IPRangeVec<V>*>>;
1039template <
typename T>
1040std::optional<std::vector<T>> sort_and_merge_ranges(std::optional<std::span<const T>> ranges) {
1049 if(!ranges.has_value()) {
1050 return std::nullopt;
1053 std::vector<T> current(ranges.value().begin(), ranges.value().end());
1055 if(current.empty()) {
1059 std::sort(current.begin(), current.end(), [](T& a, T& b) { return a.min() < b.min(); });
1060 for(
size_t i = 0; i < current.size() - 1;) {
1061 const T a = current[i];
1062 const T b = current[i + 1];
1064 if(b.min() <= a.max() || b.min() == (a.max() + 1)) {
1066 current.erase(current.begin() + i, current.begin() + i + 2);
1067 current.insert(current.begin() + i, T(a.min(), std::max(a.max(), b.max())));
1075template <
typename T>
1076bool validate_subject_in_issuer(std::span<const T> subject, std::span<const T> issuer) {
1081 if(issuer.empty()) {
1082 return subject.empty();
1084 for(
auto subj = subject.begin(), issu = issuer.begin(); subj != subject.end();) {
1086 if(subj->min() > issu->max()) {
1089 if(issu == issuer.end() && subj != subject.end()) {
1094 if(subj->min() < issu->min()) {
1098 if(subj->max() > issu->max()) {
1108template <IPAddressBlocks::Version V>
1109void populate_validation_map(uint32_t afam,
1111 IPValidationMap<V>& map) {
1112 const std::optional<IPRangeVec<V>>& ranges = std::get<IPAddressBlocks::IPAddressChoice<V>>(choice).ranges();
1113 bool has_value = ranges.has_value();
1114 const IPRangeVec<V>* value = has_value ? &ranges.value() :
nullptr;
1115 map.emplace(afam, std::make_pair(has_value, std::move(value)));
1118std::pair<IPValidationMap<IPv4>, IPValidationMap<IPv6>> create_validation_map(
1119 const std::vector<IPAddressBlocks::IPAddressFamily>& addr_blocks) {
1120 IPValidationMap<IPv4> v4_map;
1121 IPValidationMap<IPv6> v6_map;
1123 for(
const IPAddressBlocks::IPAddressFamily& block : addr_blocks) {
1124 uint32_t afam = block.afi();
1125 if(block.safi().has_value()) {
1126 afam =
static_cast<uint32_t
>(afam << 8) | block.safi().value();
1130 if(std::holds_alternative<IPAddressBlocks::IPAddressChoice<IPv4>>(a_choice)) {
1131 populate_validation_map(afam, a_choice, v4_map);
1133 populate_validation_map(afam, a_choice, v6_map);
1137 return std::make_pair(v4_map, v6_map);
1142template <IPAddressBlocks::Version V>
1144 std::optional<std::span<
const IPAddressBlocks::IPAddressOrRange<V>>> ranges) {
1146 m_ip_addr_ranges = sort_and_merge_ranges<IPAddressOrRange<V>>(ranges);
1149template <IPAddressBlocks::Version V>
1151 if(m_ip_addr_ranges.has_value()) {
1158template <IPAddressBlocks::Version V>
1164 m_ip_addr_ranges = std::nullopt;
1166 std::vector<IPAddressOrRange<V>> ip_ranges;
1168 m_ip_addr_ranges = sort_and_merge_ranges<IPAddressOrRange<V>>(ip_ranges);
1170 throw Decoding_Error(
fmt(
"Unexpected type for IPAddressChoice {}",
static_cast<uint32_t
>(next_tag)));
1174template <IPAddressBlocks::Version V>
1190 const size_t version_octets =
static_cast<size_t>(V);
1192 std::array<uint8_t, version_octets>
min = m_min.value();
1193 std::array<uint8_t, version_octets>
max = m_max.value();
1198 bool zeros_done =
false;
1199 bool ones_done =
false;
1202 for(
size_t i = version_octets; i > 0; i--) {
1204 uint8_t local_zeros =
static_cast<uint8_t
>(std::countr_zero(
min[i - 1]));
1205 zeros += local_zeros;
1206 zeros_done = (local_zeros != 8);
1210 uint8_t local_ones =
static_cast<uint8_t
>(std::countr_one(
max[i - 1]));
1212 ones_done = (local_ones != 8);
1215 if(zeros_done && ones_done) {
1221 const uint8_t host = std::min(zeros, ones);
1224 const uint8_t discarded_octets = host / 8;
1226 const uint8_t unused_bits = host % 8;
1228 bool octets_match =
true;
1229 bool used_bits_match =
true;
1232 if(discarded_octets < version_octets) {
1234 for(
size_t i = 0; i < static_cast<uint8_t>(version_octets - discarded_octets - 1); i++) {
1236 octets_match =
false;
1242 const uint8_t shifted_min = (
min[version_octets - 1 - discarded_octets] >> unused_bits);
1243 const uint8_t shifted_max = (
max[version_octets - 1 - discarded_octets] >> unused_bits);
1244 used_bits_match = (shifted_min == shifted_max);
1249 if(octets_match && used_bits_match) {
1251 std::vector<uint8_t> prefix;
1253 prefix.push_back(unused_bits);
1254 for(
size_t i = 0; i < static_cast<uint8_t>(version_octets - discarded_octets); i++) {
1255 prefix.push_back(
min[i]);
1260 const uint8_t discarded_octets_min = zeros / 8;
1261 const uint8_t unused_bits_min = zeros % 8;
1263 const uint8_t discarded_octets_max = ones / 8;
1264 const uint8_t unused_bits_max = ones % 8;
1267 if(unused_bits_max != 0) {
1269 max[version_octets - 1 - discarded_octets_max] >>= unused_bits_max;
1270 max[version_octets - 1 - discarded_octets_max] <<= unused_bits_max;
1273 std::vector<uint8_t> compressed_min;
1274 std::vector<uint8_t> compressed_max;
1277 compressed_min.push_back(unused_bits_min);
1278 for(
size_t i = 0; i < static_cast<uint8_t>(version_octets - discarded_octets_min); i++) {
1279 compressed_min.push_back(
min[i]);
1282 compressed_max.push_back(unused_bits_max);
1283 for(
size_t i = 0; i < static_cast<uint8_t>(version_octets - discarded_octets_max); i++) {
1284 compressed_max.push_back(
max[i]);
1294template <IPAddressBlocks::Version V>
1302 std::vector<uint8_t> prefix_min;
1306 std::vector<uint8_t> prefix_max(prefix_min);
1309 m_min = decode_single_address(std::move(prefix_min),
true);
1311 m_max = decode_single_address(std::move(prefix_max),
false);
1315 std::vector<uint8_t> addr_min;
1316 std::vector<uint8_t> addr_max;
1323 m_min = decode_single_address(std::move(addr_min),
true);
1324 m_max = decode_single_address(std::move(addr_max),
false);
1330 throw Decoding_Error(
fmt(
"Unexpected type for IPAddressOrRange {}",
static_cast<uint32_t
>(next_tag)));
1334template <IPAddressBlocks::Version V>
1337 const size_t version_octets =
static_cast<size_t>(V);
1342 if(decoded.empty() || decoded.size() > version_octets + 1) {
1343 throw Decoding_Error(
fmt(
"IP address range entries must have a length between 1 and {} bytes.", version_octets));
1346 const uint8_t unused = decoded.front();
1347 const uint8_t discarded_octets = version_octets - (
static_cast<uint8_t
>(decoded.size()) - 1);
1349 decoded.erase(decoded.begin());
1351 if(decoded.empty() && unused != 0) {
1352 throw Decoding_Error(
"IP address range entry specified unused bits, but did not provide any octets.");
1357 throw Decoding_Error(
"IP address range entry specified invalid number of unused bits.");
1361 uint8_t fill_discarded = min ? 0 : 0xff;
1362 for(
size_t i = 0; i < discarded_octets; i++) {
1363 decoded.push_back(fill_discarded);
1368 for(
size_t i = 0; i < unused; i++) {
1370 decoded[version_octets - 1 - discarded_octets] &= ~(1 << i);
1372 decoded[version_octets - 1 - discarded_octets] |= (1 << i);
1376 return IPAddressBlocks::IPAddress<V>(decoded);
1379template <IPAddressBlocks::Version V>
1381 if(v.size() != Length) {
1382 throw Decoding_Error(
"number of bytes does not match IP version used");
1385 for(
size_t i = 0; i < Length; i++) {
1392 const std::vector<X509_Certificate>& cert_path,
1393 std::vector<std::set<Certificate_Status_Code>>& cert_status,
1396 auto [v4_needs_check, v6_needs_check] = create_validation_map(m_ip_addr_blocks);
1398 if(pos == cert_path.size() - 1) {
1400 auto validate_root_cert_ext = [&](
const auto& map) {
1402 return std::any_of(map.begin(), map.end(), [&](
const auto& it) {
1403 const auto& [_1, validation_info] = it;
1404 const auto& [needs_checking, _2] = validation_info;
1405 return !needs_checking;
1408 if(validate_root_cert_ext(v4_needs_check) || validate_root_cert_ext(v6_needs_check)) {
1415 for(
auto cert_path_it = cert_path.begin() + pos + 1; cert_path_it != cert_path.end(); cert_path_it++) {
1418 if(parent_ip ==
nullptr) {
1422 auto [issuer_v4, issuer_v6] = create_validation_map(parent_ip->
addr_blocks());
1424 auto validate_against_issuer = [&](
auto& subject_map,
const auto& issuer_map) {
1425 for(
auto map_it = subject_map.begin(); map_it != subject_map.end(); map_it++) {
1426 auto& [afam, validation_info] = *map_it;
1429 if(issuer_map.count(afam) == 0) {
1434 auto& [needs_check, subject_value] = validation_info;
1435 const auto& [issuer_has_value, issuer_value] = issuer_map.at(afam);
1440 if(needs_check && issuer_has_value) {
1441 if(!validate_subject_in_issuer(std::span(*subject_value), std::span(*issuer_value))) {
1445 needs_check =
false;
1451 if(!validate_against_issuer(v4_needs_check, issuer_v4) || !validate_against_issuer(v6_needs_check, issuer_v6)) {
1455 auto validate_no_checks_left = [&](
const auto& map) {
1458 return std::all_of(map.begin(), map.end(), [&](
const auto& it) {
1459 const auto& [_1, validation_info] = it;
1460 const auto& [needs_checking, _2] = validation_info;
1461 return !needs_checking;
1465 if(validate_no_checks_left(v4_needs_check) && validate_no_checks_left(v6_needs_check)) {
1480 std::vector<uint8_t> output;
1485void ASBlocks::decode_inner(
const std::vector<uint8_t>& in) {
1489ASBlocks::ASIdentifierChoice ASBlocks::add_new(
const std::optional<ASIdentifierChoice>& old, asnum_t min, asnum_t max) {
1490 std::vector<ASIdOrRange> range;
1491 if(!old.has_value() || !old.value().ranges().has_value()) {
1492 range = {ASIdOrRange(min, max)};
1494 range = old.value().ranges().value();
1495 range.push_back(ASIdOrRange(min, max));
1497 return ASIdentifierChoice(range);
1503 if(!m_asnum.has_value() && !m_rdi.has_value()) {
1507 if(m_asnum.has_value()) {
1509 into.
encode(m_asnum.value());
1513 if(m_rdi.has_value()) {
1515 into.
encode(m_rdi.value());
1525 throw Decoding_Error(
fmt(
"Unexpected type for ASIdentifiers {}",
static_cast<uint32_t
>(next_tag)));
1531 const uint32_t elem_type_tag =
static_cast<uint32_t
>(elem_obj.
type_tag());
1534 if(elem_type_tag == 0) {
1542 if(
static_cast<uint32_t
>(rdi_type_tag) == 1) {
1548 throw Decoding_Error(
fmt(
"Unexpected type for ASIdentifiers rdi: {}",
static_cast<uint32_t
>(rdi_type_tag)));
1553 if(elem_type_tag == 1) {
1562 fmt(
"Unexpected element with type {} in ASIdentifiers",
static_cast<uint32_t
>(end_type_tag)));
1570 if(m_as_ranges.has_value()) {
1578 m_as_ranges = sort_and_merge_ranges<ASIdOrRange>(
ranges);
1585 m_as_ranges = std::nullopt;
1587 std::vector<ASIdOrRange> as_ranges;
1590 m_as_ranges = sort_and_merge_ranges<ASIdOrRange>(as_ranges);
1592 throw Decoding_Error(
fmt(
"Unexpected type for ASIdentifierChoice {}",
static_cast<uint32_t
>(next_tag)));
1597 if(m_min == m_max) {
1598 into.
encode(
static_cast<size_t>(m_min));
1600 if(m_min >= m_max) {
1622 throw Decoding_Error(
fmt(
"Unexpected type for ASIdOrRange {}",
static_cast<uint32_t
>(next_tag)));
1628 const std::vector<X509_Certificate>& cert_path,
1629 std::vector<std::set<Certificate_Status_Code>>& cert_status,
1632 const bool asnum_present = m_as_identifiers.asnum().has_value();
1633 const bool rdi_present = m_as_identifiers.rdi().has_value();
1634 bool asnum_needs_check = asnum_present ? m_as_identifiers.asnum().value().ranges().has_value() :
false;
1635 bool rdi_needs_check = rdi_present ? m_as_identifiers.rdi().value().ranges().has_value() :
false;
1639 if(pos == cert_path.size() - 1) {
1641 if((asnum_present && !asnum_needs_check) || (rdi_present && !rdi_needs_check)) {
1648 for(
auto it = cert_path.begin() + pos + 1; it != cert_path.end(); it++) {
1649 const ASBlocks*
const parent_as = it->v3_extensions().get_extension_object_as<
ASBlocks>();
1651 if(parent_as ==
nullptr || (asnum_present && !parent_as->
as_identifiers().
asnum().has_value()) ||
1659 if(asnum_needs_check &&
as_identifiers.asnum().value().ranges().has_value()) {
1660 const std::vector<ASBlocks::ASIdOrRange>& subject_asnums = m_as_identifiers.asnum()->ranges().value();
1661 const std::vector<ASBlocks::ASIdOrRange>& issuer_asnums =
as_identifiers.asnum()->ranges().value();
1663 if(!validate_subject_in_issuer<ASBlocks::ASIdOrRange>(subject_asnums, issuer_asnums)) {
1668 asnum_needs_check =
false;
1671 if(rdi_needs_check &&
as_identifiers.rdi().value().ranges().has_value()) {
1672 const std::vector<ASBlocks::ASIdOrRange>& subject_rdis = m_as_identifiers.rdi()->ranges().value();
1673 const std::vector<ASBlocks::ASIdOrRange>& issuer_rdis =
as_identifiers.rdi()->ranges().value();
1675 if(!validate_subject_in_issuer<ASBlocks::ASIdOrRange>(subject_rdis, issuer_rdis)) {
1680 rdi_needs_check =
false;
1683 if(!asnum_needs_check && !rdi_needs_check) {
1690void OCSP_NoCheck::decode_inner(
const std::vector<uint8_t>& buf) {
1698void Unknown_Extension::decode_inner(
const std::vector<uint8_t>& bytes) {