Botan 3.9.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 644 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 651 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 653 of file x509_ext.h.

653 : m_min(min), m_max(max) {
654 if(max < min) {
655 throw Decoding_Error("IP address ranges must be sorted");
656 }
657 }

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 19 of file asn1_obj.cpp.

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

References encode_into().

Referenced by decode_from(), 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(), Botan::PSS_Params::PSS_Params(), and Botan::Certificate_Store_In_SQL::revoke_cert().

◆ 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 1295 of file x509_ext.cpp.

1295 {
1296 const ASN1_Type next_tag = from.peek_next_object().type_tag();
1297
1298 // this can either be a prefix or a single address
1300 // construct a min and a max address from the prefix
1301
1304
1305 // copy because we modify the address in `decode_single_address`, but we need it twice for min and max
1307
1308 // min address gets filled with 0's
1309 m_min = decode_single_address(std::move(prefix_min), true);
1310 // max address with 1's
1311 m_max = decode_single_address(std::move(prefix_max), false);
1312 } else if(next_tag == ASN1_Type::Sequence) {
1313 // this is a range
1314
1317
1318 from.start_sequence()
1321 .end_cons();
1322
1323 m_min = decode_single_address(std::move(addr_min), true);
1324 m_max = decode_single_address(std::move(addr_max), false);
1325
1326 if(m_min > m_max) {
1327 throw Decoding_Error("IP address ranges must be sorted.");
1328 }
1329 } else {
1330 throw Decoding_Error(fmt("Unexpected type for IPAddressOrRange {}", static_cast<uint32_t>(next_tag)));
1331 }
1332}
std::string fmt(std::string_view format, const T &... args)
Definition fmt.h:53

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

◆ 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 1175 of file x509_ext.cpp.

1175 {
1176 // Compress IPAddressOrRange as much as possible
1177 // 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
1178 //
1179 // If possible encode as a prefix x.x.x.x/x, else encode as a range of min-max.
1180 // Single addresses are encoded as is (technically a /32 or /128 prefix).
1181 //
1182 // A range can be encoded as a prefix if the lowest n bits of the min address are 0
1183 // and the highest n bits of the max address are 1, or in other words, contiguous sequences of 0s and 1s are omitted.
1184 // To make reconstruction possible, an 'unused' octet is included at the start, since in the case of e.g. /25 only
1185 // the highest bit of the last octet is actually meaningful.
1186 //
1187 // If encoding requires a range, the individual elements can still be compressed using the above method,
1188 // but the number of used bits varies between them.
1189
1190 const size_t version_octets = static_cast<size_t>(V);
1191
1194
1195 uint8_t zeros = 0;
1196 uint8_t ones = 0;
1197
1198 bool zeros_done = false;
1199 bool ones_done = false;
1200
1201 // count contiguous 0s/1s from the right of the min/max addresses
1202 for(size_t i = version_octets; i > 0; i--) {
1203 if(!zeros_done) {
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);
1207 }
1208
1209 if(!ones_done) {
1210 uint8_t local_ones = static_cast<uint8_t>(std::countr_one(max[i - 1]));
1211 ones += local_ones;
1212 ones_done = (local_ones != 8);
1213 }
1214
1215 if(zeros_done && ones_done) {
1216 break;
1217 }
1218 }
1219
1220 // the part we want to compress
1221 const uint8_t host = std::min(zeros, ones);
1222
1223 // these we can outright drop
1224 const uint8_t discarded_octets = host / 8;
1225 // in a partially used octet
1226 const uint8_t unused_bits = host % 8;
1227
1228 bool octets_match = true;
1229 bool used_bits_match = true;
1230
1231 // we have octets to check
1233 // check all but the last octet
1234 for(size_t i = 0; i < static_cast<uint8_t>(version_octets - discarded_octets - 1); i++) {
1235 if(min[i] != max[i]) {
1236 octets_match = false;
1237 break;
1238 }
1239 }
1240 // check the last significant octet if we have matched so far
1241 if(octets_match) {
1245 }
1246 }
1247
1248 // both the full octets and the partially used one match
1250 // at this point the range can be encoded as a prefix
1252
1253 prefix.push_back(unused_bits);
1255 prefix.push_back(min[i]);
1256 }
1257
1259 } else {
1261 const uint8_t unused_bits_min = zeros % 8;
1262
1263 const uint8_t discarded_octets_max = ones / 8;
1264 const uint8_t unused_bits_max = ones % 8;
1265
1266 // compress the max address by setting unused bits to 0, for the min address these are already 0
1267 if(unused_bits_max != 0) {
1271 }
1272
1275
1276 // construct the address as a byte sequence of the unused bits followed by the compressed address
1279 compressed_min.push_back(min[i]);
1280 }
1281
1284 compressed_max.push_back(max[i]);
1285 }
1286
1287 into.start_sequence()
1290 .end_cons();
1291 }
1292}
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75

References Botan::DER_Encoder::add_object(), Botan::BitString, BOTAN_ASSERT_NOMSG, Botan::DER_Encoder::end_cons(), max(), min(), Botan::DER_Encoder::start_sequence(), and Botan::Universal.

◆ max()

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

Definition at line 661 of file x509_ext.h.

661{ 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 659 of file x509_ext.h.

659{ return m_min; }

Referenced by encode_into(), and IPAddressOrRange().


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