Botan 3.9.0
Crypto and TLS for C&
Botan::Cert_Extension::IPAddressBlocks Class Referencefinal

#include <x509_ext.h>

Inheritance diagram for Botan::Cert_Extension::IPAddressBlocks:
Botan::Certificate_Extension

Classes

class  IPAddress
class  IPAddressChoice
class  IPAddressFamily
class  IPAddressOrRange

Public Types

enum class  Version : uint8_t { IPv4 = 4 , IPv6 = 16 }

Public Member Functions

template<Version V>
void add_address (const std::array< uint8_t, static_cast< size_t >(V)> &address, std::optional< uint8_t > safi=std::nullopt)
 Add a single IP address to this extension (for the specified SAFI, if any)
template<Version V>
void add_address (const std::array< uint8_t, static_cast< std::size_t >(V)> &min, const std::array< uint8_t, static_cast< std::size_t >(V)> &max, std::optional< uint8_t > safi=std::nullopt)
 Add an IP address range to this extension (for the specified SAFI, if any)
const std::vector< IPAddressFamily > & addr_blocks () const
std::unique_ptr< Certificate_Extensioncopy () const override
template<Version V>
void inherit (std::optional< uint8_t > safi=std::nullopt)
 Mark the specified IP version as 'inherit' (for the specified SAFI, if any)
 IPAddressBlocks ()=default
 IPAddressBlocks (const std::vector< IPAddressFamily > &blocks)
OID oid_of () const override
template<Version V>
void restrict (std::optional< uint8_t > safi=std::nullopt)
 Make the extension contain no allowed IP addresses for the specified IP version (and SAFI, if any)
void validate (const X509_Certificate &subject, const X509_Certificate &issuer, const std::vector< X509_Certificate > &cert_path, std::vector< std::set< Certificate_Status_Code > > &cert_status, size_t pos) override

Static Public Member Functions

static OID static_oid ()

Detailed Description

IP Address Blocks Extension

RFC 3779 X.509 Extensions for IP Addr

Definition at line 586 of file x509_ext.h.

Member Enumeration Documentation

◆ Version

Enumerator
IPv4 
IPv6 

Definition at line 588 of file x509_ext.h.

588 : uint8_t {
589 IPv4 = 4,
590 IPv6 = 16,
591 };

Constructor & Destructor Documentation

◆ IPAddressBlocks() [1/2]

Botan::Cert_Extension::IPAddressBlocks::IPAddressBlocks ( )
default

Referenced by validate().

◆ IPAddressBlocks() [2/2]

Botan::Cert_Extension::IPAddressBlocks::IPAddressBlocks ( const std::vector< IPAddressFamily > & blocks)
inlineexplicit

Definition at line 718 of file x509_ext.h.

718 : m_ip_addr_blocks(blocks) {
719 this->sort_and_merge();
720 }

Member Function Documentation

◆ add_address() [1/2]

template<Version V>
void Botan::Cert_Extension::IPAddressBlocks::add_address ( const std::array< uint8_t, static_cast< size_t >(V)> & address,
std::optional< uint8_t > safi = std::nullopt )
inline

Add a single IP address to this extension (for the specified SAFI, if any)

Definition at line 736 of file x509_ext.h.

737 {
738 add_address<V>(address, address, safi);
739 }
void add_address(const std::array< uint8_t, static_cast< size_t >(V)> &address, std::optional< uint8_t > safi=std::nullopt)
Add a single IP address to this extension (for the specified SAFI, if any)
Definition x509_ext.h:736

References add_address().

Referenced by add_address().

◆ add_address() [2/2]

template<Version V>
void Botan::Cert_Extension::IPAddressBlocks::add_address ( const std::array< uint8_t, static_cast< std::size_t >(V)> & min,
const std::array< uint8_t, static_cast< std::size_t >(V)> & max,
std::optional< uint8_t > safi = std::nullopt )
inline

Add an IP address range to this extension (for the specified SAFI, if any)

Definition at line 743 of file x509_ext.h.

◆ addr_blocks()

const std::vector< IPAddressFamily > & Botan::Cert_Extension::IPAddressBlocks::addr_blocks ( ) const
inline

Definition at line 766 of file x509_ext.h.

766{ return m_ip_addr_blocks; }

Referenced by validate().

◆ copy()

std::unique_ptr< Certificate_Extension > Botan::Cert_Extension::IPAddressBlocks::copy ( ) const
inlineoverridevirtual

Make a copy of this extension

Returns
copy of this

Implements Botan::Certificate_Extension.

Definition at line 722 of file x509_ext.h.

722{ return std::make_unique<IPAddressBlocks>(*this); }

◆ inherit()

template<Version V>
void Botan::Cert_Extension::IPAddressBlocks::inherit ( std::optional< uint8_t > safi = std::nullopt)
inline

Mark the specified IP version as 'inherit' (for the specified SAFI, if any)

Definition at line 761 of file x509_ext.h.

761 {
762 m_ip_addr_blocks.push_back(IPAddressFamily(IPAddressChoice<V>(), safi));
763 sort_and_merge();
764 }

◆ oid_of()

OID Botan::Cert_Extension::IPAddressBlocks::oid_of ( ) const
inlineoverridevirtual
Returns
OID representing this extension

Implements Botan::Certificate_Extension.

Definition at line 726 of file x509_ext.h.

726{ return static_oid(); }

References static_oid().

◆ restrict()

template<Version V>
void Botan::Cert_Extension::IPAddressBlocks::restrict ( std::optional< uint8_t > safi = std::nullopt)
inline

Make the extension contain no allowed IP addresses for the specified IP version (and SAFI, if any)

Definition at line 753 of file x509_ext.h.

753 {
754 std::vector<IPAddressOrRange<V>> addresses = {};
755 m_ip_addr_blocks.push_back(IPAddressFamily(IPAddressChoice<V>(addresses), safi));
756 sort_and_merge();
757 }

◆ static_oid()

OID Botan::Cert_Extension::IPAddressBlocks::static_oid ( )
inlinestatic

Definition at line 724 of file x509_ext.h.

724{ return OID({1, 3, 6, 1, 5, 5, 7, 1, 7}); }

Referenced by oid_of().

◆ validate()

void Botan::Cert_Extension::IPAddressBlocks::validate ( const X509_Certificate & subject,
const X509_Certificate & issuer,
const std::vector< X509_Certificate > & cert_path,
std::vector< std::set< Certificate_Status_Code > > & cert_status,
size_t pos )
overridevirtual

Reimplemented from Botan::Certificate_Extension.

Definition at line 1390 of file x509_ext.cpp.

1394 {
1395 // maps in the form of (s)afi -> (needs_checking, ranges)
1396 auto [v4_needs_check, v6_needs_check] = create_validation_map(m_ip_addr_blocks);
1397
1398 if(pos == cert_path.size() - 1) {
1399 // checks if any range / family has 'inherit' as a value somewhere, not allowed for the root cert
1400 auto validate_root_cert_ext = [&](const auto& map) {
1401 // check if any range has a value of 'false', indicating 'inherit'
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;
1406 });
1407 };
1408 if(validate_root_cert_ext(v4_needs_check) || validate_root_cert_ext(v6_needs_check)) {
1409 cert_status.at(pos).insert(Certificate_Status_Code::IPADDR_BLOCKS_ERROR);
1410 }
1411 return;
1412 }
1413
1414 // traverse the chain until we find a cert with concrete values for the extension (so not 'inherit')
1415 for(auto cert_path_it = cert_path.begin() + pos + 1; cert_path_it != cert_path.end(); cert_path_it++) {
1416 const IPAddressBlocks* const parent_ip = cert_path_it->v3_extensions().get_extension_object_as<IPAddressBlocks>();
1417 // extension not present for parent
1418 if(parent_ip == nullptr) {
1419 cert_status.at(pos).insert(Certificate_Status_Code::IPADDR_BLOCKS_ERROR);
1420 return;
1421 }
1422 auto [issuer_v4, issuer_v6] = create_validation_map(parent_ip->addr_blocks());
1423
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;
1427
1428 // the issuer does not have this combination of afi/safi
1429 if(issuer_map.count(afam) == 0) {
1430 cert_status.at(pos).insert(Certificate_Status_Code::IPADDR_BLOCKS_ERROR);
1431 return false;
1432 }
1433
1434 auto& [needs_check, subject_value] = validation_info;
1435 const auto& [issuer_has_value, issuer_value] = issuer_map.at(afam);
1436 BOTAN_ASSERT_NOMSG(!needs_check || subject_value != nullptr);
1437 BOTAN_ASSERT_NOMSG(!issuer_has_value || issuer_value != nullptr);
1438
1439 // we still need to check this range and the issuer has an actual value for it (so not 'inherit')
1440 if(needs_check && issuer_has_value) {
1441 if(!validate_subject_in_issuer(std::span(*subject_value), std::span(*issuer_value))) {
1442 cert_status.at(pos).insert(Certificate_Status_Code::IPADDR_BLOCKS_ERROR);
1443 return false;
1444 }
1445 needs_check = false;
1446 }
1447 }
1448 return true;
1449 };
1450
1451 if(!validate_against_issuer(v4_needs_check, issuer_v4) || !validate_against_issuer(v6_needs_check, issuer_v6)) {
1452 return;
1453 }
1454
1455 auto validate_no_checks_left = [&](const auto& map) {
1456 // check if all ranges have been checked, either by comparing their ranges if they have any,
1457 // or if they are inherit, their parent(s) will be validated later
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;
1462 });
1463 };
1464
1465 if(validate_no_checks_left(v4_needs_check) && validate_no_checks_left(v6_needs_check)) {
1466 // we've validated what we need to and can stop traversing the cert chain
1467 return;
1468 }
1469 }
1470}
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75

References addr_blocks(), BOTAN_ASSERT_NOMSG, Botan::IPADDR_BLOCKS_ERROR, and IPAddressBlocks().


The documentation for this class was generated from the following files: