Botan 3.13.0
Crypto and TLS for C&
Botan::Cert_Extension::IPAddressBlocks::IPAddressOrRange< V > Class Template Referencefinal

#include <x509_ext.h>

Inheritance diagram for Botan::Cert_Extension::IPAddressBlocks::IPAddressOrRange< V >:
Botan::ASN1_Object

Public Member Functions

std::vector< uint8_t > BER_encode () const
void decode_from (BER_Decoder &from) override
void encode_into (DER_Encoder &to) const override
 IPAddressOrRange ()=default
 IPAddressOrRange (const IPAddress< V > &addr)
 IPAddressOrRange (const IPAddress< V > &min, const IPAddress< V > &max)
IPAddress< V > max () const
IPAddress< V > min () const

Detailed Description

template<Version V>
class Botan::Cert_Extension::IPAddressBlocks::IPAddressOrRange< V >

Definition at line 984 of file x509_ext.h.

Constructor & Destructor Documentation

◆ IPAddressOrRange() [1/3]

template<Version V>
Botan::Cert_Extension::IPAddressBlocks::IPAddressOrRange< V >::IPAddressOrRange ( )
default

◆ IPAddressOrRange() [2/3]

template<Version V>
Botan::Cert_Extension::IPAddressBlocks::IPAddressOrRange< V >::IPAddressOrRange ( const IPAddress< V > & addr)
inlineexplicit

Definition at line 991 of file x509_ext.h.

◆ IPAddressOrRange() [3/3]

template<Version V>
Botan::Cert_Extension::IPAddressBlocks::IPAddressOrRange< V >::IPAddressOrRange ( const IPAddress< V > & min,
const IPAddress< V > & max )
inline

Definition at line 993 of file x509_ext.h.

993 : m_min(min), m_max(max) {
994 if(max < min) {
995 throw Decoding_Error("IP address ranges must be sorted");
996 }
997 }

References max(), and min().

Member Function Documentation

◆ BER_encode()

std::vector< uint8_t > Botan::ASN1_Object::BER_encode ( ) const
inherited

Return the encoding of this object. This is a convenience method when just one object needs to be serialized. Use DER_Encoder for complicated encodings.

Definition at line 21 of file asn1_obj.cpp.

21 {
22 std::vector<uint8_t> output;
23 DER_Encoder der(output);
24 this->encode_into(der);
25 return output;
26}
virtual void encode_into(DER_Encoder &to) const =0

References encode_into().

Referenced by decode_from(), Botan::PKCS12::export_to(), Botan::Certificate_Store_In_SQL::find_all_certs(), Botan::Certificate_Store_In_SQL::find_cert(), Botan::X509_Certificate::fingerprint(), Botan::Certificate_Store_In_SQL::insert_cert(), Botan::X509_Object::PEM_encode(), and Botan::PSS_Params::PSS_Params().

◆ decode_from()

template<Version V>
void Botan::Cert_Extension::IPAddressBlocks::IPAddressOrRange< V >::decode_from ( BER_Decoder & from)
overridevirtual

Decode whatever this object is from from

Parameters
fromthe BER_Decoder that will be read from

Implements Botan::ASN1_Object.

Definition at line 2116 of file x509_ext.cpp.

2116 {
2117 const ASN1_Type next_tag = from.peek_next_object().type_tag();
2118
2119 // this can either be a prefix or a single address
2121 // construct a min and a max address from the prefix
2122
2124 from.decode_bitstring(prefix);
2125
2126 // min address gets filled with 0's
2127 m_min = decode_single_address(prefix, true);
2128 // max address with 1's
2129 m_max = decode_single_address(prefix, false);
2130 } else if(next_tag == ASN1_Type::Sequence) {
2131 // this is a range
2132
2135
2136 from.start_sequence().decode_bitstring(addr_min).decode_bitstring(addr_max).end_cons();
2137
2138 m_min = decode_single_address(addr_min, true);
2139 m_max = decode_single_address(addr_max, false);
2140
2141 if(m_min > m_max) {
2142 throw Decoding_Error("IP address ranges must be sorted.");
2143 }
2144 } else {
2145 throw Decoding_Error(fmt("Unexpected type for IPAddressOrRange {}", static_cast<uint32_t>(next_tag)));
2146 }
2147}
std::string fmt(std::string_view format, const T &... args)
Definition fmt.h:53

References Botan::BitString, Botan::BER_Decoder::decode_bitstring(), Botan::BER_Decoder::end_cons(), Botan::fmt(), Botan::BER_Decoder::peek_next_object(), Botan::Sequence, Botan::BER_Decoder::start_sequence(), and Botan::BER_Object::type_tag().

◆ encode_into()

template<Version V>
void Botan::Cert_Extension::IPAddressBlocks::IPAddressOrRange< V >::encode_into ( DER_Encoder & to) const
overridevirtual

Encode whatever this object is into to

Parameters
tothe DER_Encoder that will be written to

Implements Botan::ASN1_Object.

Definition at line 2017 of file x509_ext.cpp.

2017 {
2018 // Compress IPAddressOrRange as much as possible
2019 // cf. https://www.rfc-editor.org/rfc/rfc3779.html#section-2.2.3.7 - https://www.rfc-editor.org/rfc/rfc3779.html#section-2.2.3.9
2020 //
2021 // If possible encode as a prefix x.x.x.x/x, else encode as a range of min-max.
2022 // Single addresses are encoded as is (technically a /32 or /128 prefix).
2023 //
2024 // A range can be encoded as a prefix if the lowest n bits of the min address are 0
2025 // and the highest n bits of the max address are 1, or in other words, contiguous sequences of 0s and 1s are omitted.
2026 // To make reconstruction possible, an 'unused' octet is included at the start, since in the case of e.g. /25 only
2027 // the highest bit of the last octet is actually meaningful.
2028 //
2029 // If encoding requires a range, the individual elements can still be compressed using the above method,
2030 // but the number of used bits varies between them.
2031
2032 const size_t version_octets = static_cast<size_t>(V);
2033
2036
2037 uint8_t zeros = 0;
2038 uint8_t ones = 0;
2039
2040 bool zeros_done = false;
2041 bool ones_done = false;
2042
2043 // count contiguous 0s/1s from the right of the min/max addresses
2044 for(size_t i = version_octets; i > 0; i--) {
2045 if(!zeros_done) {
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);
2049 }
2050
2051 if(!ones_done) {
2052 const uint8_t local_ones = static_cast<uint8_t>(std::countr_one(max[i - 1]));
2053 ones += local_ones;
2054 ones_done = (local_ones != 8);
2055 }
2056
2057 if(zeros_done && ones_done) {
2058 break;
2059 }
2060 }
2061
2062 // the part we want to compress
2063 const uint8_t host = std::min(zeros, ones);
2064
2065 // these we can outright drop
2066 const uint8_t discarded_octets = host / 8;
2067 // in a partially used octet
2068 const uint8_t unused_bits = host % 8;
2069
2070 bool octets_match = true;
2071 bool used_bits_match = true;
2072
2073 // we have octets to check
2075 // check all but the last octet
2076 for(size_t i = 0; i < static_cast<uint8_t>(version_octets - discarded_octets - 1); i++) {
2077 if(min[i] != max[i]) {
2078 octets_match = false;
2079 break;
2080 }
2081 }
2082 // check the last significant octet if we have matched so far
2083 if(octets_match) {
2087 }
2088 }
2089
2090 // both the full octets and the partially used one match
2092 // at this point the range can be encoded as a prefix
2093 into.encode_bitstring(std::span{min}.first(version_octets - discarded_octets), unused_bits);
2094 } else {
2096 const uint8_t unused_bits_min = zeros % 8;
2097
2098 const uint8_t discarded_octets_max = ones / 8;
2099 const uint8_t unused_bits_max = ones % 8;
2100
2101 // compress the max address by setting unused bits to 0, for the min address these are already 0
2102 if(unused_bits_max != 0) {
2106 }
2107
2108 into.start_sequence()
2111 .end_cons();
2112 }
2113}
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75

References BOTAN_ASSERT_NOMSG, Botan::DER_Encoder::encode_bitstring(), Botan::DER_Encoder::end_cons(), max(), min(), and Botan::DER_Encoder::start_sequence().

◆ max()

template<Version V>
IPAddress< V > Botan::Cert_Extension::IPAddressBlocks::IPAddressOrRange< V >::max ( ) const
inline

Definition at line 1001 of file x509_ext.h.

1001{ return m_max; }

Referenced by encode_into(), and IPAddressOrRange().

◆ min()

template<Version V>
IPAddress< V > Botan::Cert_Extension::IPAddressBlocks::IPAddressOrRange< V >::min ( ) const
inline

Definition at line 999 of file x509_ext.h.

999{ return m_min; }

Referenced by encode_into(), and IPAddressOrRange().


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