379bool Subject_Alternative_Name::is_appropriate_context(
Extension_Context context)
const {
383bool Issuer_Alternative_Name::is_appropriate_context(
Extension_Context context)
const {
387bool Extended_Key_Usage::is_appropriate_context(
Extension_Context context)
const {
395bool Certificate_Policies::is_appropriate_context(
Extension_Context context)
const {
399bool Authority_Information_Access::is_appropriate_context(
Extension_Context context)
const {
413bool CRL_Distribution_Points::is_appropriate_context(
Extension_Context context)
const {
417bool CRL_Issuing_Distribution_Point::is_appropriate_context(
Extension_Context context)
const {
425bool NoRevocationAvailable::is_appropriate_context(
Extension_Context context)
const {
450 if(!m_is_ca && m_path_length_constraint.has_value()) {
452 throw Invalid_Argument(
453 "Basic_Constraints nonsensical to set a path length constraint for a non-CA basicConstraints");
462 return m_path_length_constraint.value_or(NO_CERT_PATH_LIMIT);
464 throw Invalid_State(
"Basic_Constraints::get_path_limit: Not a CA");
472 std::vector<uint8_t> output;
486void Basic_Constraints::decode_inner(
const std::vector<uint8_t>& in) {
504 if(!m_is_ca && m_path_length_constraint.has_value()) {
505 throw Decoding_Error(
"BasicConstraints pathLenConstraint must not be present when cA is FALSE");
513 if(m_constraints.empty()) {
514 throw Encoding_Error(
"Cannot encode empty PKIX key constraints");
517 std::vector<uint8_t> der;
518 DER_Encoder(der).encode_named_bitstring(m_constraints.value(), 16);
525void Key_Usage::decode_inner(
const std::vector<uint8_t>& in) {
536 throw Decoding_Error(
"KeyUsage extension must have at least one bit set");
539 m_constraints = Key_Constraints(
static_cast<uint32_t
>(usage));
546 std::vector<uint8_t> output;
554void Subject_Key_ID::decode_inner(
const std::vector<uint8_t>& in) {
558 if(m_key_id.empty()) {
559 throw Decoding_Error(
"SubjectKeyIdentifier must not be empty");
561 if(m_key_id.size() > MaximumKeyIdentifierLength) {
562 throw Decoding_Error(
563 fmt(
"SubjectKeyIdentifier length {} exceeds limit of {} bytes", m_key_id.size(), MaximumKeyIdentifierLength));
579 m_key_id.resize(hash->output_length());
582 hash->final(m_key_id.data());
591 m_key_id.resize(hash->output_length());
593 hash->update(pub_key);
594 hash->final(m_key_id.data());
597 const size_t max_skid_len = (192 / 8);
598 if(m_key_id.size() > max_skid_len) {
599 m_key_id.resize(max_skid_len);
607 std::vector<uint8_t> output;
609 der.start_sequence();
610 if(!m_key_id.empty()) {
613 if(m_authority_cert.has_value()) {
614 emit_general_names_implicit(der, m_authority_cert->issuer, 1);
624void Authority_Key_ID::decode_inner(
const std::vector<uint8_t>& in) {
634 BER_Decoder seq = ber.start_sequence();
637 m_authority_cert.reset();
639 bool key_id_present =
false;
640 std::optional<AlternativeName> authority_cert_issuer;
641 std::optional<X509_Serial_Number> authority_cert_serial;
643 seq.decode_optional_field(0,
645 [&](BER_Decoder& d) {
647 key_id_present =
true;
649 .decode_optional_field(1,
651 [&](BER_Decoder& d) {
652 AlternativeName names;
653 d.decode_implicit(names,
658 authority_cert_issuer = std::move(names);
661 X509_Serial_Number serial;
664 authority_cert_serial = std::move(serial);
671 if(m_key_id.empty()) {
672 throw Decoding_Error(
"AuthorityKeyIdentifier keyIdentifier must not be empty");
674 if(m_key_id.size() > MaximumKeyIdentifierLength) {
675 throw Decoding_Error(
fmt(
"AuthorityKeyIdentifier keyIdentifier length {} exceeds limit of {} bytes",
677 MaximumKeyIdentifierLength));
682 if(authority_cert_issuer.has_value() && authority_cert_issuer->is_empty()) {
683 throw Decoding_Error(
"AuthorityKeyIdentifier authorityCertIssuer must contain at least one GeneralName");
692 if(authority_cert_issuer.has_value() != authority_cert_serial.has_value()) {
693 throw Decoding_Error(
694 "AuthorityKeyIdentifier authorityCertIssuer and authorityCertSerialNumber must both be present or absent");
697 if(authority_cert_issuer.has_value()) {
707 std::vector<uint8_t> output;
708 DER_Encoder(output).encode(m_alt_name);
716 std::vector<uint8_t> output;
717 DER_Encoder(output).encode(m_alt_name);
724void Subject_Alternative_Name::decode_inner(
const std::vector<uint8_t>& in) {
728 if(!m_alt_name.has_items()) {
729 throw Decoding_Error(
"SubjectAlternativeName extension must contain at least one GeneralName");
736void Issuer_Alternative_Name::decode_inner(
const std::vector<uint8_t>& in) {
740 if(!m_alt_name.has_items()) {
741 throw Decoding_Error(
"IssuerAlternativeName extension must contain at least one GeneralName");
749 std::vector<uint8_t> output;
750 DER_Encoder(output).start_sequence().encode_list(m_oids).end_cons();
757void Extended_Key_Usage::decode_inner(
const std::vector<uint8_t>& in) {
761 throw Decoding_Error(
"ExtendedKeyUsage extension must contain at least one KeyPurposeId");
769 const auto& permitted = m_name_constraints.permitted();
770 const auto& excluded = m_name_constraints.excluded();
772 if(permitted.empty() && excluded.empty()) {
773 throw Encoding_Error(
"Refusing to encode empty NameConstraints");
776 std::vector<uint8_t> output;
777 DER_Encoder der(output);
778 der.start_sequence();
779 if(!permitted.empty()) {
780 der.start_explicit_context_specific(0).encode_list(permitted).end_cons();
782 if(!excluded.empty()) {
783 der.start_explicit_context_specific(1).encode_list(excluded).end_cons();
792void Name_Constraints::decode_inner(
const std::vector<uint8_t>& in) {
801 BER_Decoder inner = ber.start_sequence();
803 std::vector<GeneralSubtree> permitted;
805 if(permitted.empty()) {
806 throw Decoding_Error(
"Empty NameConstraint permitted list");
810 std::vector<GeneralSubtree> excluded;
812 if(excluded.empty()) {
813 throw Decoding_Error(
"Empty NameConstraint excluded list");
820 if(permitted.empty() && excluded.empty()) {
821 throw Decoding_Error(
"Empty NameConstraint extension");
824 m_name_constraints = NameConstraints(std::move(permitted), std::move(excluded));
828 const std::optional<X509_Certificate>& ,
829 const std::vector<X509_Certificate>& cert_path,
830 std::vector<std::set<Certificate_Status_Code>>& cert_status,
832 if(!m_name_constraints.permitted().empty() || !m_name_constraints.excluded().empty()) {
837 const bool issuer_name_constraint_critical = subject.
is_critical(
"X509v3.NameConstraints");
840 for(
size_t j = 0; j < pos; ++j) {
841 const auto& cert = cert_path.at(j);
846 if(j > 0 && cert.issuer_dn() == cert.subject_dn()) {
850 if(!m_name_constraints.is_permitted(cert, issuer_name_constraint_critical)) {
855 if(m_name_constraints.is_excluded(cert, issuer_name_constraint_critical)) {
868class Policy_Information final :
public ASN1_Object {
870 Policy_Information() =
default;
872 explicit Policy_Information(
const OID& oid) : m_oid(oid) {}
874 const OID& oid()
const {
return m_oid; }
876 void encode_into(DER_Encoder& codec)
const override { codec.start_sequence().encode(m_oid).end_cons(); }
878 void decode_from(BER_Decoder& codec)
override {
879 codec.start_sequence().decode(m_oid).discard_remaining().end_cons();
886bool policy_oids_have_duplicate(
const std::vector<OID>& oids) {
888 for(
const auto& oid : oids) {
889 if(!seen.insert(oid).second) {
899 m_oids(oids), m_has_duplicate(policy_oids_have_duplicate(m_oids)) {}
905 std::vector<Policy_Information> policies;
907 policies.reserve(m_oids.size());
908 for(
const auto& oid : m_oids) {
909 policies.push_back(Policy_Information(oid));
912 std::vector<uint8_t> output;
920void Certificate_Policies::decode_inner(
const std::vector<uint8_t>& in) {
922 std::vector<Policy_Information> policies;
925 if(policies.empty()) {
926 throw Decoding_Error(
"CertificatePolicies extension must contain at least one PolicyInformation");
929 for(
const auto& policy : policies) {
930 m_oids.push_back(policy.oid());
932 m_has_duplicate = policy_oids_have_duplicate(m_oids);
936 const std::optional<X509_Certificate>& ,
937 const std::vector<X509_Certificate>& ,
938 std::vector<std::set<Certificate_Status_Code>>& cert_status,
940 if(m_has_duplicate) {
947std::vector<URI> parse_aia_uris(
const std::vector<std::string>& uris,
const char* context) {
948 std::vector<URI> out;
949 out.reserve(uris.size());
950 for(
const auto& uri : uris) {
952 out.push_back(std::move(*parsed));
961std::vector<Authority_Information_Access::AccessDescription> uri_access_descriptions(
962 const std::vector<URI>& ocsp_responders,
const std::vector<URI>& ca_issuers) {
963 std::vector<Authority_Information_Access::AccessDescription> out;
964 out.reserve(ocsp_responders.size() + ca_issuers.size());
966 const auto append = [&](
const OID& method,
const std::vector<URI>& uris) {
967 for(
const auto& uri : uris) {
969 out.emplace_back(method,
972 std::vector<uint8_t>(value.value().begin(), value.value().end()));
985 m_ca_issuers(parse_aia_uris(
ca_issuers,
"AuthorityInformationAccess CA issuers")) {
987 if(auto parsed = URI::from_string(ocsp)) {
988 m_ocsp_responders.push_back(std::move(*parsed));
990 throw Invalid_Argument(
"Invalid URI in AuthorityInformationAccess OCSP responder");
993 m_access_descriptions = uri_access_descriptions(m_ocsp_responders, m_ca_issuers);
998 m_ocsp_responders(parse_aia_uris(
ocsp_responders,
"AuthorityInformationAccess OCSP responders")),
999 m_ca_issuers(parse_aia_uris(
ca_issuers,
"AuthorityInformationAccess CA issuers")),
1000 m_access_descriptions(uri_access_descriptions(m_ocsp_responders, m_ca_issuers)) {}
1006 m_access_descriptions(uri_access_descriptions(m_ocsp_responders, m_ca_issuers)) {}
1009 std::vector<std::string> out;
1010 out.reserve(m_ocsp_responders.size());
1011 for(
const auto& uri : m_ocsp_responders) {
1012 out.push_back(uri.original_input());
1018 return std::make_unique<Authority_Information_Access>(*
this);
1023void validate_general_name_encoding(
ASN1_Type tag,
ASN1_Class cls, std::span<const uint8_t> value) {
1025 std::vector<uint8_t> wrapped_name;
1032 throw Decoding_Error(
"GeneralName IA5String value must not be empty");
1036 throw Decoding_Error(
"GeneralName directoryName must not be empty");
1045 validate_general_name_encoding(ad.location_tag(), ad.location_class(), ad.location_value());
1046 }
catch(
const Exception&) {
1047 throw Invalid_Argument(
"AccessDescription accessLocation is not a valid GeneralName");
1059 std::vector<URI>& ocsp_responders,
1060 std::vector<URI>& ca_issuers) {
1062 const auto oid_ca_issuers =
OID::from_string(
"PKIX.CertificateAuthorityIssuers");
1063 if(
const auto uri_str = ad.location_as_uri_string()) {
1064 if(ad.access_method() == oid_ocsp_responders) {
1066 ocsp_responders.push_back(std::move(*uri));
1068 throw Invalid_Argument(
"Invalid URI in AuthorityInformationAccess OCSP responder");
1070 }
else if(ad.access_method() == oid_ca_issuers) {
1072 ca_issuers.push_back(std::move(*uri));
1074 throw Invalid_Argument(
"Invalid URI in AuthorityInformationAccess CA issuers");
1084 for(
const auto& ad : m_access_descriptions) {
1085 validate_access_description(ad);
1086 populate_uri_view_from_access_description(ad, m_ocsp_responders, m_ca_issuers);
1091 validate_access_description(ad);
1092 populate_uri_view_from_access_description(ad, m_ocsp_responders, m_ca_issuers);
1093 m_access_descriptions.push_back(std::move(ad));
1097 std::vector<std::string> out;
1098 out.reserve(m_ca_issuers.size());
1099 for(
const auto& uri : m_ca_issuers) {
1100 out.push_back(uri.original_input());
1107 return std::string(m_location_value.begin(), m_location_value.end());
1109 return std::nullopt;
1113 std::vector<uint8_t> output;
1116 der.start_sequence();
1118 for(
const auto& ad : m_access_descriptions) {
1120 validate_general_name_encoding(ad.location_tag(), ad.location_class(), ad.location_value());
1122 throw Encoding_Error(
"AccessDescription accessLocation is not a valid GeneralName");
1124 der.start_sequence()
1125 .encode(ad.access_method())
1126 .add_object(ad.location_tag(), ad.location_class(), ad.location_value())
1134void Authority_Information_Access::decode_inner(
const std::vector<uint8_t>& in) {
1144 BER_Decoder ber = outer.start_sequence();
1147 const OID ca_issuer =
OID::from_string(
"PKIX.CertificateAuthorityIssuers");
1149 m_access_descriptions.clear();
1150 m_ocsp_responders.clear();
1151 m_ca_issuers.clear();
1153 while(ber.more_items()) {
1156 BER_Decoder info = ber.start_sequence();
1159 const BER_Object name = info.get_next_object();
1166 if(!name.is_set()) {
1167 throw Decoding_Error(
"AuthorityInformationAccess AccessDescription missing accessLocation");
1169 validate_general_name_encoding(name.type_tag(), name.get_class(), name.data());
1172 m_access_descriptions.emplace_back(
1173 oid, name.type_tag(), name.get_class(), std::vector<uint8_t>(name.data().begin(), name.data().end()));
1178 m_ocsp_responders.push_back(std::move(*parsed));
1180 throw Decoding_Error(
"Invalid URI in AuthorityInformationAccess OCSP responder");
1182 }
else if(oid == ca_issuer) {
1184 m_ca_issuers.push_back(std::move(*parsed));
1186 throw Decoding_Error(
"Invalid URI in AuthorityInformationAccess CA issuers");
1195 if(m_access_descriptions.empty()) {
1196 throw Decoding_Error(
"AuthorityInformationAccess extension must contain at least one AccessDescription");
1201 BOTAN_ARG_CHECK(m_crl_number.signum() >= 0,
"CRL number cannot be negative");
1207 return m_crl_number;
1216 return m_crl_number.to_u32bit();
1223 return std::make_unique<CRL_Number>(*
this);
1230 std::vector<uint8_t> output;
1238void CRL_Number::decode_inner(
const std::vector<uint8_t>& in) {
1241 if(m_crl_number.
signum() < 0) {
1251 std::vector<uint8_t> output;
1259void CRL_ReasonCode::decode_inner(
const std::vector<uint8_t>& in) {
1276 size_t reason_code = 0;
1281 if(reason_code == 7 || reason_code > 10) {
1282 throw Decoding_Error(
fmt(
"CRLReason has unknown enumeration value {}", reason_code));
1285 m_reason =
static_cast<CRL_Code>(reason_code);
1290constexpr size_t ReasonFlagsNamedBitWidth = 9;
1292void emit_reason_flags_implicit(DER_Encoder& der, uint32_t tag, ReasonFlags reasons) {
1296ReasonFlags decode_reason_flags_implicit(BER_Decoder& decoder, uint32_t tag) {
1310bool crl_issuer_is_well_formed(
const AlternativeName& crl_issuer) {
1311 const auto& dn = crl_issuer.directory_names();
1312 return crl_issuer.count() == 1 && dn.size() == 1 && !dn.begin()->empty();
1315std::vector<URI> crl_distribution_point_uris_from_distribution_points(
1316 const std::vector<CRL_Distribution_Points::Distribution_Point>& dps) {
1317 std::vector<URI> out;
1318 for(
const auto& dp : dps) {
1319 const auto& dpn = dp.distribution_point_name();
1320 if(dpn.has_value() && dpn->full_name().has_value()) {
1321 for(
const auto& uri : dpn->full_name()->uri_names()) {
1333 return *m_dp_name->full_name();
1337 m_distribution_points(points),
1338 m_crl_distribution_urls(crl_distribution_point_uris_from_distribution_points(m_distribution_points)) {}
1342 return *m_dp_name->full_name();
1346 if(!m_full_name.has_value()) {
1347 throw Encoding_Error(
"DistributionPointName has no fullName to encode");
1352 emit_general_names_implicit(der, *m_full_name, 0);
1366 throw Decoding_Error(
"DistributionPointName fullName must contain at least one GeneralName");
1368 if(std::ranges::any_of(
full_name.directory_names(), [](
const X509_DN& dn) { return dn.empty(); })) {
1369 throw Decoding_Error(
"DistributionPointName fullName must not contain an empty directoryName");
1373 throw Decoding_Error(
"nameRelativeToCrlIssuer not supported in DistributionPointName");
1375 throw Decoding_Error(
"DistributionPointName CHOICE is neither fullName nor nameRelativeToCRLIssuer");
1380 std::vector<uint8_t> output;
1385void CRL_Distribution_Points::decode_inner(
const std::vector<uint8_t>& buf) {
1393 if(m_distribution_points.empty()) {
1394 throw Decoding_Error(
"CRLDistributionPoints extension must contain at least one DistributionPoint");
1397 m_crl_distribution_urls = crl_distribution_point_uris_from_distribution_points(m_distribution_points);
1401 std::vector<std::string> out;
1402 out.reserve(m_crl_distribution_urls.size());
1403 for(
const auto& uri : m_crl_distribution_urls) {
1404 out.push_back(uri.original_input());
1418 const bool has_dp_name = m_dp_name.has_value();
1419 const bool has_crl_issuer = m_crl_issuer.has_value();
1420 if(!has_dp_name && !has_crl_issuer) {
1421 throw Encoding_Error(
"DistributionPoint must contain either distributionPoint or cRLIssuer");
1423 if(has_crl_issuer && !crl_issuer_is_well_formed(*m_crl_issuer)) {
1426 throw Encoding_Error(
"cRLIssuer must contain exactly one non-empty directoryName GeneralName");
1437 emit_reason_flags_implicit(der, 1, *m_reasons);
1440 if(has_crl_issuer) {
1441 emit_general_names_implicit(der, *m_crl_issuer, 2);
1458 m_crl_issuer.reset();
1468 m_dp_name = std::move(name);
1470 .decode_optional_field(
1485 if(m_crl_issuer.has_value() && m_crl_issuer->is_empty()) {
1486 throw Decoding_Error(
"cRLIssuer GeneralNames must contain at least one GeneralName");
1489 if(m_crl_issuer.has_value() && !crl_issuer_is_well_formed(*m_crl_issuer)) {
1492 throw Decoding_Error(
"cRLIssuer must contain exactly one non-empty directoryName GeneralName");
1495 if(!m_dp_name.has_value() && !m_crl_issuer.has_value()) {
1496 throw Decoding_Error(
"DistributionPoint must contain either distributionPoint or cRLIssuer");
1509 throw Encoding_Error(
"Refusing to encode empty IssuingDistributionPoint");
1512 const size_t scope_set =
static_cast<size_t>(m_only_contains_user_certs) +
1513 static_cast<size_t>(m_only_contains_ca_certs) +
1514 static_cast<size_t>(m_only_contains_attribute_certs);
1517 "At most one of onlyContainsUserCerts, onlyContainsCACerts, onlyContainsAttributeCerts may be TRUE");
1520 auto emit_optional_boolean_implicit = [](
DER_Encoder& der, uint32_t tag,
bool value) {
1524 const uint8_t val = 0xFF;
1529 std::vector<uint8_t> output;
1530 DER_Encoder der(output);
1533 if(m_dp_name.has_value()) {
1537 emit_optional_boolean_implicit(der, 1, m_only_contains_user_certs);
1538 emit_optional_boolean_implicit(der, 2, m_only_contains_ca_certs);
1540 if(m_only_some_reasons) {
1541 emit_reason_flags_implicit(der, 3, *m_only_some_reasons);
1544 emit_optional_boolean_implicit(der, 4, m_indirect_crl);
1545 emit_optional_boolean_implicit(der, 5, m_only_contains_attribute_certs);
1551void CRL_Issuing_Distribution_Point::decode_inner(
const std::vector<uint8_t>& buf) {
1564 BER_Decoder seq = outer.start_sequence();
1567 m_only_contains_user_certs =
false;
1568 m_only_contains_ca_certs =
false;
1569 m_only_some_reasons = {};
1570 m_indirect_crl =
false;
1571 m_only_contains_attribute_certs =
false;
1573 auto decode_implicit_bool = [&](BER_Decoder& dec, uint32_t tag) ->
bool {
1582 seq.decode_optional_field(0,
1584 [&](BER_Decoder& d) {
1585 DistributionPointName name;
1586 d.start_context_specific(0).decode(name).verify_end();
1587 m_dp_name = std::move(name);
1589 .decode_optional_field(1,
1591 [&](BER_Decoder& d) { m_only_contains_user_certs = decode_implicit_bool(d, 1); })
1592 .decode_optional_field(
1594 .decode_optional_field(3,
1596 [&](BER_Decoder& d) { m_only_some_reasons = decode_reason_flags_implicit(d, 3); })
1597 .decode_optional_field(
1600 m_only_contains_attribute_certs = decode_implicit_bool(d, 5);
1609 if(!m_dp_name.has_value() && !m_only_contains_user_certs && !m_only_contains_ca_certs &&
1610 !m_only_some_reasons.has_value() && !m_indirect_crl && !m_only_contains_attribute_certs) {
1611 throw Decoding_Error(
"IssuingDistributionPoint must contain at least one field");
1616 const size_t scope_set =
static_cast<size_t>(m_only_contains_user_certs) +
1617 static_cast<size_t>(m_only_contains_ca_certs) +
1618 static_cast<size_t>(m_only_contains_attribute_certs);
1620 throw Decoding_Error(
1621 "IssuingDistributionPoint sets more than one of onlyContainsUserCerts/CACerts/AttributeCerts");
1626 throw Not_Implemented(
"TNAuthList extension entry serialization is not supported");
1636 const uint32_t type_tag =
static_cast<uint32_t
>(obj.
type_tag());
1642 m_data = std::move(spc_string);
1646 auto& range_items = std::get<RangeContainer>(m_data);
1653 if(!is_valid_telephone_number(entry.
start)) {
1658 if(entry.
count < 2) {
1662 range_items.emplace_back(std::move(entry));
1667 if(range_items.empty()) {
1674 if(!is_valid_telephone_number(one_string)) {
1677 m_data = std::move(one_string);
1684 throw Not_Implemented(
"TNAuthList extension serialization is not supported");
1687void TNAuthList::decode_inner(
const std::vector<uint8_t>& in) {
1690 if(m_tn_entries.empty()) {
1697 return std::get<ASN1_String>(m_data).value();
1702 return std::get<RangeContainer>(m_data);
1707 return std::get<ASN1_String>(m_data).value();
1711 std::vector<uint8_t> output;
1716void IPAddressBlocks::decode_inner(
const std::vector<uint8_t>& in) {
1727 if(m_safi.has_value()) {
1728 afam.push_back(m_safi.value());
1744 throw Decoding_Error(
fmt(
"Unexpected type for IPAddressFamily {}",
static_cast<uint32_t
>(next_tag)));
1749 std::vector<uint8_t> addr_family;
1751 const size_t addr_family_length = addr_family.size();
1753 if(addr_family_length != 2 && addr_family_length != 3) {
1757 m_afi = (addr_family[0] << 8) | addr_family[1];
1759 if(addr_family_length == 3) {
1760 m_safi = addr_family[2];
1767 }
else if(m_afi == 2) {
1778void IPAddressBlocks::sort_and_merge() {
1789 std::map<std::pair<uint16_t, std::optional<uint8_t>>, std::vector<IPAddressFamily>> afam_map;
1791 auto key = std::make_pair(block.afi(), block.safi());
1792 std::vector<IPAddressFamily>& fams = afam_map[key];
1793 fams.push_back(block);
1796 std::vector<IPAddressFamily> merged_blocks;
1797 size_t v4_count = 0;
1798 size_t v6_count = 0;
1799 for(
auto& it : afam_map) {
1801 std::vector<IPAddressFamily>& fams = it.second;
1807 if(std::holds_alternative<IPAddressChoice<Version::IPv4>>(fams[0].addr_choice())) {
1808 merged_blocks.push_back(merge<Version::IPv4>(fams));
1811 merged_blocks.push_back(merge<Version::IPv6>(fams));
1816 m_ip_addr_blocks = merged_blocks;
1817 m_v4_count = v4_count;
1818 m_v6_count = v6_count;
1821template <IPAddressBlocks::Version V>
1822IPAddressBlocks::IPAddressFamily IPAddressBlocks::merge(std::vector<IPAddressFamily>& blocks) {
1827 BOTAN_ASSERT(!blocks.empty(),
"Cannot merge an empty set of IP address blocks into a single family");
1830 if(blocks.size() == 1) {
1834 bool all_inherit =
true;
1835 bool none_inherit =
true;
1836 for(
const IPAddressFamily& block : blocks) {
1837 const IPAddressChoice<V> choice = std::get<IPAddressChoice<V>>(block.addr_choice());
1838 all_inherit = !choice.ranges().has_value() && all_inherit;
1839 none_inherit = choice.ranges().has_value() && none_inherit;
1844 return IPAddressFamily(IPAddressChoice<V>(), blocks[0].safi());
1848 if(!all_inherit && !none_inherit) {
1849 throw Decoding_Error(
"Invalid IPAddressBlocks: Only one of 'inherit' or 'do not inherit' is allowed per family");
1852 std::vector<IPAddressOrRange<V>> merged_ranges;
1853 for(
const IPAddressFamily& block : blocks) {
1854 const IPAddressChoice<V> choice = std::get<IPAddressChoice<V>>(block.addr_choice());
1855 const std::vector<IPAddressOrRange<V>> ranges = choice.ranges().value();
1856 for(
const IPAddressOrRange<V>& r : ranges) {
1857 merged_ranges.push_back(r);
1862 IPAddressChoice<V> choice(merged_ranges);
1863 IPAddressFamily fam(choice, blocks[0].safi());
1872template <IPAddressBlocks::Version V>
1873using IPRangeVec = std::vector<IPAddressBlocks::IPAddressOrRange<V>>;
1877template <IPAddressBlocks::Version V>
1878using IPValidationMap = std::map<uint32_t, std::pair<bool, const IPRangeVec<V>*>>;
1880template <
typename T>
1881std::optional<std::vector<T>> sort_and_merge_ranges(std::optional<std::span<const T>> ranges) {
1886 if(!ranges.has_value()) {
1887 return std::nullopt;
1890 std::vector<T> sorted(ranges.value().begin(), ranges.value().end());
1892 if(sorted.empty()) {
1897 std::sort(sorted.begin(), sorted.end(), [](T& a, T& b) { return a.min() < b.min(); });
1900 std::vector<T> merged;
1901 merged.reserve(sorted.size());
1902 merged.push_back(sorted[0]);
1904 for(
size_t i = 1; i < sorted.size(); ++i) {
1905 auto& back = merged.back();
1907 if(sorted[i].min() <= back.max() || sorted[i].min() == (back.max() + 1)) {
1908 back = T(back.min(), std::max(back.max(), sorted[i].max()));
1910 merged.push_back(sorted[i]);
1917template <
typename T>
1918bool validate_subject_in_issuer(std::span<const T> subject, std::span<const T> issuer) {
1923 if(issuer.empty()) {
1924 return subject.empty();
1926 for(
auto subj = subject.begin(), issu = issuer.begin(); subj != subject.end();) {
1928 if(subj->min() > issu->max()) {
1931 if(issu == issuer.end() && subj != subject.end()) {
1936 if(subj->min() < issu->min()) {
1940 if(subj->max() > issu->max()) {
1950template <IPAddressBlocks::Version V>
1951void populate_validation_map(uint32_t afam,
1953 IPValidationMap<V>& map) {
1954 const std::optional<IPRangeVec<V>>& ranges = std::get<IPAddressBlocks::IPAddressChoice<V>>(choice).ranges();
1955 const bool has_value = ranges.has_value();
1956 const IPRangeVec<V>* value = has_value ? &ranges.value() :
nullptr;
1957 map.emplace(afam, std::make_pair(has_value, std::move(value)));
1960std::pair<IPValidationMap<IPv4>, IPValidationMap<IPv6>> create_validation_map(
1961 const std::vector<IPAddressBlocks::IPAddressFamily>& addr_blocks) {
1962 IPValidationMap<IPv4> v4_map;
1963 IPValidationMap<IPv6> v6_map;
1965 for(
const IPAddressBlocks::IPAddressFamily& block : addr_blocks) {
1966 uint32_t afam = block.afi();
1967 if(block.safi().has_value()) {
1968 afam =
static_cast<uint32_t
>(afam << 8) | block.safi().value();
1972 if(std::holds_alternative<IPAddressBlocks::IPAddressChoice<IPv4>>(a_choice)) {
1973 populate_validation_map(afam, a_choice, v4_map);
1975 populate_validation_map(afam, a_choice, v6_map);
1979 return std::make_pair(v4_map, v6_map);
1984template <IPAddressBlocks::Version V>
1986 std::optional<std::span<
const IPAddressBlocks::IPAddressOrRange<V>>> ranges) {
1988 m_ip_addr_ranges = sort_and_merge_ranges<IPAddressOrRange<V>>(ranges);
1991template <IPAddressBlocks::Version V>
1993 if(m_ip_addr_ranges.has_value()) {
2000template <IPAddressBlocks::Version V>
2006 m_ip_addr_ranges = std::nullopt;
2008 std::vector<IPAddressOrRange<V>> ip_ranges;
2010 m_ip_addr_ranges = sort_and_merge_ranges<IPAddressOrRange<V>>(ip_ranges);
2012 throw Decoding_Error(
fmt(
"Unexpected type for IPAddressChoice {}",
static_cast<uint32_t
>(next_tag)));
2016template <IPAddressBlocks::Version V>
2032 const size_t version_octets =
static_cast<size_t>(V);
2034 std::array<uint8_t, version_octets>
min = m_min.value();
2035 std::array<uint8_t, version_octets>
max = m_max.value();
2040 bool zeros_done =
false;
2041 bool ones_done =
false;
2044 for(
size_t i = version_octets; i > 0; i--) {
2046 const uint8_t local_zeros =
static_cast<uint8_t
>(std::countr_zero(
min[i - 1]));
2047 zeros += local_zeros;
2048 zeros_done = (local_zeros != 8);
2052 const uint8_t local_ones =
static_cast<uint8_t
>(std::countr_one(
max[i - 1]));
2054 ones_done = (local_ones != 8);
2057 if(zeros_done && ones_done) {
2063 const uint8_t host = std::min(zeros, ones);
2066 const uint8_t discarded_octets = host / 8;
2068 const uint8_t unused_bits = host % 8;
2070 bool octets_match =
true;
2071 bool used_bits_match =
true;
2074 if(discarded_octets < version_octets) {
2076 for(
size_t i = 0; i < static_cast<uint8_t>(version_octets - discarded_octets - 1); i++) {
2078 octets_match =
false;
2084 const uint8_t shifted_min = (
min[version_octets - 1 - discarded_octets] >> unused_bits);
2085 const uint8_t shifted_max = (
max[version_octets - 1 - discarded_octets] >> unused_bits);
2086 used_bits_match = (shifted_min == shifted_max);
2091 if(octets_match && used_bits_match) {
2093 into.
encode_bitstring(std::span{
min}.first(version_octets - discarded_octets), unused_bits);
2095 const uint8_t discarded_octets_min = zeros / 8;
2096 const uint8_t unused_bits_min = zeros % 8;
2098 const uint8_t discarded_octets_max = ones / 8;
2099 const uint8_t unused_bits_max = ones % 8;
2102 if(unused_bits_max != 0) {
2104 max[version_octets - 1 - discarded_octets_max] >>= unused_bits_max;
2105 max[version_octets - 1 - discarded_octets_max] <<= unused_bits_max;
2109 .
encode_bitstring(std::span{
min}.first(version_octets - discarded_octets_min), unused_bits_min)
2110 .
encode_bitstring(std::span{
max}.first(version_octets - discarded_octets_max), unused_bits_max)
2115template <IPAddressBlocks::Version V>
2127 m_min = decode_single_address(prefix,
true);
2129 m_max = decode_single_address(prefix,
false);
2138 m_min = decode_single_address(addr_min,
true);
2139 m_max = decode_single_address(addr_max,
false);
2145 throw Decoding_Error(
fmt(
"Unexpected type for IPAddressOrRange {}",
static_cast<uint32_t
>(next_tag)));
2149template <IPAddressBlocks::Version V>
2152 const size_t version_octets =
static_cast<size_t>(V);
2156 if(decoded.
bytes().size() > version_octets) {
2157 throw Decoding_Error(
fmt(
"IP address range entries must have a length between 0 and {} bytes.", version_octets));
2160 const uint8_t unused =
static_cast<uint8_t
>(decoded.
unused_bits());
2161 const uint8_t discarded_octets = version_octets -
static_cast<uint8_t
>(decoded.
bytes().size());
2163 std::vector<uint8_t> address(decoded.
bytes().begin(), decoded.
bytes().end());
2165 if(address.empty() && unused != 0) {
2166 throw Decoding_Error(
"IP address range entry specified unused bits, but did not provide any octets.");
2170 const uint8_t fill_discarded = min ? 0 : 0xff;
2171 for(
size_t i = 0; i < discarded_octets; i++) {
2172 address.push_back(fill_discarded);
2177 for(
size_t i = 0; i < unused; i++) {
2179 address[version_octets - 1 - discarded_octets] &= ~(1 << i);
2181 address[version_octets - 1 - discarded_octets] |= (1 << i);
2185 return IPAddressBlocks::IPAddress<V>(address);
2188template <IPAddressBlocks::Version V>
2190 if(v.size() != Length) {
2191 throw Decoding_Error(
"number of bytes does not match IP version used");
2194 for(
size_t i = 0; i < Length; i++) {
2200 const std::optional<X509_Certificate>& ,
2201 const std::vector<X509_Certificate>& cert_path,
2202 std::vector<std::set<Certificate_Status_Code>>& cert_status,
2205 auto [v4_needs_check, v6_needs_check] = create_validation_map(m_ip_addr_blocks);
2207 if(pos == cert_path.size() - 1) {
2209 auto validate_root_cert_ext = [&](
const auto& map) {
2211 return std::any_of(map.begin(), map.end(), [&](
const auto& it) {
2212 const auto& [_1, validation_info] = it;
2213 const auto& [needs_checking, _2] = validation_info;
2214 return !needs_checking;
2217 if(validate_root_cert_ext(v4_needs_check) || validate_root_cert_ext(v6_needs_check)) {
2224 for(
auto cert_path_it = cert_path.begin() + pos + 1; cert_path_it != cert_path.end(); cert_path_it++) {
2227 if(parent_ip ==
nullptr) {
2231 auto [issuer_v4, issuer_v6] = create_validation_map(parent_ip->
addr_blocks());
2233 auto validate_against_issuer = [&](
auto& subject_map,
const auto& issuer_map) {
2234 for(
auto map_it = subject_map.begin(); map_it != subject_map.end(); map_it++) {
2235 auto& [afam, validation_info] = *map_it;
2238 if(issuer_map.count(afam) == 0) {
2243 auto& [needs_check, subject_value] = validation_info;
2244 const auto& [issuer_has_value, issuer_value] = issuer_map.at(afam);
2249 if(needs_check && issuer_has_value) {
2250 if(!validate_subject_in_issuer(std::span(*subject_value), std::span(*issuer_value))) {
2254 needs_check =
false;
2260 if(!validate_against_issuer(v4_needs_check, issuer_v4) || !validate_against_issuer(v6_needs_check, issuer_v6)) {
2264 auto validate_no_checks_left = [&](
const auto& map) {
2267 return std::all_of(map.begin(), map.end(), [&](
const auto& it) {
2268 const auto& [_1, validation_info] = it;
2269 const auto& [needs_checking, _2] = validation_info;
2270 return !needs_checking;
2274 if(validate_no_checks_left(v4_needs_check) && validate_no_checks_left(v6_needs_check)) {
2289 std::vector<uint8_t> output;
2294void ASBlocks::decode_inner(
const std::vector<uint8_t>& in) {
2299ASBlocks::ASIdentifierChoice ASBlocks::add_new(
const std::optional<ASIdentifierChoice>& old, asnum_t min, asnum_t max) {
2300 std::vector<ASIdOrRange> range;
2301 if(!old.has_value() || !old.value().ranges().has_value()) {
2302 range = {ASIdOrRange(min, max)};
2304 range = old.value().ranges().value();
2305 range.push_back(ASIdOrRange(min, max));
2307 return ASIdentifierChoice(range);
2313 if(!m_asnum.has_value() && !m_rdi.has_value()) {
2317 if(m_asnum.has_value()) {
2319 into.
encode(m_asnum.value());
2323 if(m_rdi.has_value()) {
2325 into.
encode(m_rdi.value());
2335 throw Decoding_Error(
fmt(
"Unexpected type for ASIdentifiers {}",
static_cast<uint32_t
>(next_tag)));
2341 const uint32_t elem_type_tag =
static_cast<uint32_t
>(elem_obj.
type_tag());
2344 if(elem_type_tag == 0) {
2352 if(
static_cast<uint32_t
>(rdi_type_tag) == 1) {
2358 throw Decoding_Error(
fmt(
"Unexpected type for ASIdentifiers rdi: {}",
static_cast<uint32_t
>(rdi_type_tag)));
2363 if(elem_type_tag == 1) {
2372 fmt(
"Unexpected element with type {} in ASIdentifiers",
static_cast<uint32_t
>(end_type_tag)));
2378 if(!m_asnum.has_value() && !m_rdi.has_value()) {
2384 if(m_as_ranges.has_value()) {
2392 m_as_ranges = sort_and_merge_ranges<ASIdOrRange>(
ranges);
2400 m_as_ranges = std::nullopt;
2402 std::vector<ASIdOrRange> as_ranges;
2405 m_as_ranges = sort_and_merge_ranges<ASIdOrRange>(as_ranges);
2407 throw Decoding_Error(
fmt(
"Unexpected type for ASIdentifierChoice {}",
static_cast<uint32_t
>(next_tag)));
2412 if(m_min == m_max) {
2413 into.
encode(
static_cast<size_t>(m_min));
2415 if(m_min >= m_max) {
2436 if(m_min >= m_max) {
2440 throw Decoding_Error(
fmt(
"Unexpected type for ASIdOrRange {}",
static_cast<uint32_t
>(next_tag)));
2445 const std::optional<X509_Certificate>& ,
2446 const std::vector<X509_Certificate>& cert_path,
2447 std::vector<std::set<Certificate_Status_Code>>& cert_status,
2450 const bool asnum_present = m_as_identifiers.asnum().has_value();
2451 const bool rdi_present = m_as_identifiers.rdi().has_value();
2453 if(!asnum_present && !rdi_present) {
2459 bool asnum_needs_check = asnum_present ? m_as_identifiers.asnum().value().ranges().has_value() :
false;
2460 bool rdi_needs_check = rdi_present ? m_as_identifiers.rdi().value().ranges().has_value() :
false;
2463 if(pos == cert_path.size() - 1) {
2465 if((asnum_present && !asnum_needs_check) || (rdi_present && !rdi_needs_check)) {
2472 for(
auto it = cert_path.begin() + pos + 1; it != cert_path.end(); it++) {
2473 const ASBlocks*
const parent_as = it->v3_extensions().get_extension_object_as<
ASBlocks>();
2475 if(parent_as ==
nullptr || (asnum_present && !parent_as->
as_identifiers().
asnum().has_value()) ||
2483 if(asnum_needs_check &&
as_identifiers.asnum().value().ranges().has_value()) {
2484 const std::vector<ASBlocks::ASIdOrRange>& subject_asnums = m_as_identifiers.asnum()->ranges().value();
2485 const std::vector<ASBlocks::ASIdOrRange>& issuer_asnums =
as_identifiers.asnum()->ranges().value();
2487 if(!validate_subject_in_issuer<ASBlocks::ASIdOrRange>(subject_asnums, issuer_asnums)) {
2492 asnum_needs_check =
false;
2495 if(rdi_needs_check &&
as_identifiers.rdi().value().ranges().has_value()) {
2496 const std::vector<ASBlocks::ASIdOrRange>& subject_rdis = m_as_identifiers.rdi()->ranges().value();
2497 const std::vector<ASBlocks::ASIdOrRange>& issuer_rdis =
as_identifiers.rdi()->ranges().value();
2499 if(!validate_subject_in_issuer<ASBlocks::ASIdOrRange>(subject_rdis, issuer_rdis)) {
2504 rdi_needs_check =
false;
2507 if(!asnum_needs_check && !rdi_needs_check) {
2515 const std::optional<X509_Certificate>& ,
2516 const std::vector<X509_Certificate>& ,
2517 std::vector<std::set<Certificate_Status_Code>>& cert_status,
2532 return {0x05, 0x00};
2535void OCSP_NoCheck::decode_inner(
const std::vector<uint8_t>& buf) {
2541 return {0x05, 0x00};
2544void NoRevocationAvailable::decode_inner(
const std::vector<uint8_t>& buf) {
2550 const std::optional<X509_Certificate>& ,
2551 const std::vector<X509_Certificate>& ,
2552 std::vector<std::set<Certificate_Status_Code>>& cert_status,
2599 const bool has_ocsp = !aia->ocsp_responder_uris().empty() ||
2600 std::ranges::any_of(aia->access_descriptions(),
2601 [&](
const auto& ad) { return ad.access_method() == id_ad_ocsp; });
2612void Unknown_Extension::decode_inner(
const std::vector<uint8_t>& bytes) {