Botan 3.12.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 660 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 667 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 669 of file x509_ext.h.

669 : m_min(min), m_max(max) {
670 if(max < min) {
671 throw Decoding_Error("IP address ranges must be sorted");
672 }
673 }

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

20 {
21 std::vector<uint8_t> output;
22 DER_Encoder der(output);
23 this->encode_into(der);
24 return output;
25}
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 1455 of file x509_ext.cpp.

1455 {
1456 const ASN1_Type next_tag = from.peek_next_object().type_tag();
1457
1458 // this can either be a prefix or a single address
1460 // construct a min and a max address from the prefix
1461
1464
1465 // copy because we modify the address in `decode_single_address`, but we need it twice for min and max
1467
1468 // min address gets filled with 0's
1469 m_min = decode_single_address(std::move(prefix_min), true);
1470 // max address with 1's
1471 m_max = decode_single_address(std::move(prefix_max), false);
1472 } else if(next_tag == ASN1_Type::Sequence) {
1473 // this is a range
1474
1477
1478 from.start_sequence()
1481 .end_cons();
1482
1483 m_min = decode_single_address(std::move(addr_min), true);
1484 m_max = decode_single_address(std::move(addr_max), false);
1485
1486 if(m_min > m_max) {
1487 throw Decoding_Error("IP address ranges must be sorted.");
1488 }
1489 } else {
1490 throw Decoding_Error(fmt("Unexpected type for IPAddressOrRange {}", static_cast<uint32_t>(next_tag)));
1491 }
1492}
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 1335 of file x509_ext.cpp.

1335 {
1336 // Compress IPAddressOrRange as much as possible
1337 // 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
1338 //
1339 // If possible encode as a prefix x.x.x.x/x, else encode as a range of min-max.
1340 // Single addresses are encoded as is (technically a /32 or /128 prefix).
1341 //
1342 // A range can be encoded as a prefix if the lowest n bits of the min address are 0
1343 // and the highest n bits of the max address are 1, or in other words, contiguous sequences of 0s and 1s are omitted.
1344 // To make reconstruction possible, an 'unused' octet is included at the start, since in the case of e.g. /25 only
1345 // the highest bit of the last octet is actually meaningful.
1346 //
1347 // If encoding requires a range, the individual elements can still be compressed using the above method,
1348 // but the number of used bits varies between them.
1349
1350 const size_t version_octets = static_cast<size_t>(V);
1351
1354
1355 uint8_t zeros = 0;
1356 uint8_t ones = 0;
1357
1358 bool zeros_done = false;
1359 bool ones_done = false;
1360
1361 // count contiguous 0s/1s from the right of the min/max addresses
1362 for(size_t i = version_octets; i > 0; i--) {
1363 if(!zeros_done) {
1364 const uint8_t local_zeros = static_cast<uint8_t>(std::countr_zero(min[i - 1]));
1365 zeros += local_zeros;
1366 zeros_done = (local_zeros != 8);
1367 }
1368
1369 if(!ones_done) {
1370 const uint8_t local_ones = static_cast<uint8_t>(std::countr_one(max[i - 1]));
1371 ones += local_ones;
1372 ones_done = (local_ones != 8);
1373 }
1374
1375 if(zeros_done && ones_done) {
1376 break;
1377 }
1378 }
1379
1380 // the part we want to compress
1381 const uint8_t host = std::min(zeros, ones);
1382
1383 // these we can outright drop
1384 const uint8_t discarded_octets = host / 8;
1385 // in a partially used octet
1386 const uint8_t unused_bits = host % 8;
1387
1388 bool octets_match = true;
1389 bool used_bits_match = true;
1390
1391 // we have octets to check
1393 // check all but the last octet
1394 for(size_t i = 0; i < static_cast<uint8_t>(version_octets - discarded_octets - 1); i++) {
1395 if(min[i] != max[i]) {
1396 octets_match = false;
1397 break;
1398 }
1399 }
1400 // check the last significant octet if we have matched so far
1401 if(octets_match) {
1405 }
1406 }
1407
1408 // both the full octets and the partially used one match
1410 // at this point the range can be encoded as a prefix
1412
1413 prefix.push_back(unused_bits);
1415 prefix.push_back(min[i]);
1416 }
1417
1419 } else {
1421 const uint8_t unused_bits_min = zeros % 8;
1422
1423 const uint8_t discarded_octets_max = ones / 8;
1424 const uint8_t unused_bits_max = ones % 8;
1425
1426 // compress the max address by setting unused bits to 0, for the min address these are already 0
1427 if(unused_bits_max != 0) {
1431 }
1432
1435
1436 // construct the address as a byte sequence of the unused bits followed by the compressed address
1439 compressed_min.push_back(min[i]);
1440 }
1441
1444 compressed_max.push_back(max[i]);
1445 }
1446
1447 into.start_sequence()
1450 .end_cons();
1451 }
1452}
#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 677 of file x509_ext.h.

677{ 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 675 of file x509_ext.h.

675{ return m_min; }

Referenced by encode_into(), and IPAddressOrRange().


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