Botan 3.12.0
Crypto and TLS for C&
Botan::BER_Decoder Class Referencefinal

#include <ber_dec.h>

Classes

class  Limits

Public Member Functions

 BER_Decoder (BER_Decoder &&other) noexcept
BOTAN_FUTURE_EXPLICIT BER_Decoder (BER_Object &&obj)
 BER_Decoder (const BER_Decoder &other)=delete
BOTAN_FUTURE_EXPLICIT BER_Decoder (const BER_Object &obj, Limits limits=Limits::BER())
 BER_Decoder (const uint8_t buf[], size_t len, Limits limits=Limits::BER())
 BER_Decoder (DataSource &src, Limits limits=Limits::BER())
 BER_Decoder (std::span< const uint8_t > buf, Limits limits=Limits::BER())
BER_Decoderdecode (ASN1_Object &obj, ASN1_Type type_tag=ASN1_Type::NoObject, ASN1_Class class_tag=ASN1_Class::NoObject)
BER_Decoderdecode (BigInt &out)
BER_Decoderdecode (BigInt &v, ASN1_Type type_tag, ASN1_Class class_tag=ASN1_Class::ContextSpecific)
BER_Decoderdecode (bool &out)
BER_Decoderdecode (bool &v, ASN1_Type type_tag, ASN1_Class class_tag=ASN1_Class::ContextSpecific)
BER_Decoderdecode (secure_vector< uint8_t > &v, ASN1_Type real_type, ASN1_Type type_tag, ASN1_Class class_tag=ASN1_Class::ContextSpecific)
BER_Decoderdecode (size_t &out)
BER_Decoderdecode (size_t &v, ASN1_Type type_tag, ASN1_Class class_tag=ASN1_Class::ContextSpecific)
BER_Decoderdecode (std::vector< uint8_t > &v, ASN1_Type real_type, ASN1_Type type_tag, ASN1_Class class_tag=ASN1_Class::ContextSpecific)
template<typename Alloc>
BER_Decoderdecode (std::vector< uint8_t, Alloc > &out, ASN1_Type real_type)
template<typename T>
BER_Decoderdecode_and_check (const T &expected, std::string_view error_msg)
uint64_t decode_constrained_integer (ASN1_Type type_tag, ASN1_Class class_tag, size_t T_bytes)
template<typename T>
BER_Decoderdecode_integer_type (T &out)
template<typename T>
BER_Decoderdecode_integer_type (T &out, ASN1_Type type_tag, ASN1_Class class_tag=ASN1_Class::ContextSpecific)
template<typename T>
BER_Decoderdecode_list (std::vector< T > &out, ASN1_Type type_tag=ASN1_Type::Sequence, ASN1_Class class_tag=ASN1_Class::Universal)
BER_Decoderdecode_null ()
BER_Decoderdecode_octet_string_bigint (BigInt &b)
template<typename T>
BER_Decoderdecode_optional (std::optional< T > &out, ASN1_Type type_tag, ASN1_Class class_tag)
template<typename T>
BER_Decoderdecode_optional (T &out, ASN1_Type type_tag, ASN1_Class class_tag, const T &default_value=T())
template<typename T>
BER_Decoderdecode_optional_implicit (T &out, ASN1_Type type_tag, ASN1_Class class_tag, ASN1_Type real_type, ASN1_Class real_class, const T &default_value=T())
template<typename T>
bool decode_optional_list (std::vector< T > &out, ASN1_Type type_tag=ASN1_Type::Sequence, ASN1_Class class_tag=ASN1_Class::Universal)
template<typename Alloc>
BER_Decoderdecode_optional_string (std::vector< uint8_t, Alloc > &out, ASN1_Type real_type, ASN1_Type expected_tag, ASN1_Class class_tag=ASN1_Class::ContextSpecific)
template<typename Alloc>
BER_Decoderdecode_optional_string (std::vector< uint8_t, Alloc > &out, ASN1_Type real_type, uint32_t expected_tag, ASN1_Class class_tag=ASN1_Class::ContextSpecific)
BER_Decoderdiscard_remaining ()
BER_Decoderend_cons ()
BER_Decoderget_next (BER_Object &ber)
BER_Object get_next_object ()
std::vector< uint8_t > get_next_octet_string ()
template<typename T>
requires std::is_standard_layout_v<T> && std::is_trivial_v<T>
BER_Decoderget_next_value (T &out, ASN1_Type type_tag, ASN1_Class class_tag=ASN1_Class::ContextSpecific)
Limits limits () const
bool more_items () const
BER_Decoderoperator= (BER_Decoder &&) noexcept
BER_Decoderoperator= (const BER_Decoder &)=delete
const BER_Objectpeek_next_object ()
void push_back (BER_Object &&obj)
void push_back (const BER_Object &obj)
template<typename Alloc>
BER_Decoderraw_bytes (std::vector< uint8_t, Alloc > &out)
BER_Decoder start_cons (ASN1_Type type_tag, ASN1_Class class_tag)
BER_Decoder start_context_specific (uint32_t tag)
BER_Decoder start_explicit_context_specific (uint32_t tag)
BER_Decoder start_sequence ()
BER_Decoder start_set ()
BER_Decoderverify_end ()
BER_Decoderverify_end (std::string_view err_msg)
 ~BER_Decoder ()

Detailed Description

BER Decoding Object

Definition at line 25 of file ber_dec.h.

Constructor & Destructor Documentation

◆ BER_Decoder() [1/7]

◆ BER_Decoder() [2/7]

Botan::BER_Decoder::BER_Decoder ( std::span< const uint8_t > buf,
Limits limits = Limits::BER() )
explicit

Set up to BER decode the data in buf

Definition at line 548 of file ber_dec.cpp.

548 : m_limits(limits) {
549 m_data_src = std::make_unique<DataSource_Memory>(buf);
550 m_source = m_data_src.get();
551}

References limits().

◆ BER_Decoder() [3/7]

Botan::BER_Decoder::BER_Decoder ( DataSource & src,
Limits limits = Limits::BER() )
explicit

Set up to BER decode the data in src

Definition at line 543 of file ber_dec.cpp.

543: m_limits(limits), m_source(&src) {}

References limits().

◆ BER_Decoder() [4/7]

BOTAN_FUTURE_EXPLICIT Botan::BER_Decoder::BER_Decoder ( const BER_Object & obj,
Limits limits = Limits::BER() )
inline

Set up to BER decode the data in obj

Definition at line 80 of file ber_dec.h.

80 :
81 BER_Decoder(obj.data(), limits) {}

References Botan::BER_Decoder::Limits::BER(), BER_Decoder(), BOTAN_FUTURE_EXPLICIT, and limits().

◆ BER_Decoder() [5/7]

BOTAN_FUTURE_EXPLICIT Botan::BER_Decoder::BER_Decoder ( BER_Object && obj)
inline

Set up to BER decode the data in obj TODO(Botan4) remove this?

Definition at line 87 of file ber_dec.h.

87: BER_Decoder(std::move(obj), nullptr) {}

References BER_Decoder(), and BOTAN_FUTURE_EXPLICIT.

◆ BER_Decoder() [6/7]

Botan::BER_Decoder::BER_Decoder ( const BER_Decoder & other)
delete

References BER_Decoder().

◆ BER_Decoder() [7/7]

Botan::BER_Decoder::BER_Decoder ( BER_Decoder && other)
defaultnoexcept

References BER_Decoder().

◆ ~BER_Decoder()

Botan::BER_Decoder::~BER_Decoder ( )
default

References BER_Decoder(), and get_next_value().

Member Function Documentation

◆ decode() [1/10]

BER_Decoder & Botan::BER_Decoder::decode ( ASN1_Object & obj,
ASN1_Type type_tag = ASN1_Type::NoObject,
ASN1_Class class_tag = ASN1_Class::NoObject )

Definition at line 560 of file ber_dec.cpp.

560 {
561 obj.decode_from(*this);
562 return (*this);
563}

References BER_Decoder(), and decode().

◆ decode() [2/10]

BER_Decoder & Botan::BER_Decoder::decode ( BigInt & out)
inline

Definition at line 230 of file ber_dec.h.

BER_Decoder & decode(bool &out)
Definition ber_dec.h:220

References BER_Decoder(), decode(), Botan::Integer, and Botan::Universal.

Referenced by decode().

◆ decode() [3/10]

BER_Decoder & Botan::BER_Decoder::decode ( BigInt & v,
ASN1_Type type_tag,
ASN1_Class class_tag = ASN1_Class::ContextSpecific )

Definition at line 660 of file ber_dec.cpp.

660 {
661 const BER_Object obj = get_next_object();
662 obj.assert_is_a(type_tag, class_tag);
663
664 // DER requires minimal INTEGER encoding (X.690 section 8.3.2)
665 if(m_limits.require_der_encoding()) {
666 if(obj.length() == 0) {
667 throw BER_Decoding_Error("Detected empty INTEGER encoding in DER structure");
668 }
669 if(obj.length() > 1) {
670 if(obj.bits()[0] == 0x00 && (obj.bits()[1] & 0x80) == 0) {
671 throw BER_Decoding_Error("Detected non-minimal INTEGER encoding in DER structure");
672 }
673 if(obj.bits()[0] == 0xFF && (obj.bits()[1] & 0x80) != 0) {
674 throw BER_Decoding_Error("Detected non-minimal INTEGER encoding in DER structure");
675 }
676 }
677 }
678
679 if(obj.length() == 0) {
680 out.clear();
681 } else {
682 const uint8_t first = obj.bits()[0];
683 const bool negative = (first & 0x80) == 0x80;
684
685 if(negative) {
686 secure_vector<uint8_t> vec(obj.bits(), obj.bits() + obj.length());
687 for(size_t i = obj.length(); i > 0; --i) {
688 const bool gt0 = (vec[i - 1] > 0);
689 vec[i - 1] -= 1;
690 if(gt0) {
691 break;
692 }
693 }
694 for(size_t i = 0; i != obj.length(); ++i) {
695 vec[i] = ~vec[i];
696 }
697 out._assign_from_bytes(vec);
698 out.flip_sign();
699 } else {
700 out._assign_from_bytes(obj.data());
701 }
702 }
703
704 return (*this);
705}
BER_Object get_next_object()
Definition ber_dec.cpp:426
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:68

References Botan::BigInt::_assign_from_bytes(), Botan::BER_Object::assert_is_a(), BER_Decoder(), Botan::BER_Object::bits(), Botan::BigInt::clear(), Botan::BER_Object::data(), Botan::BigInt::flip_sign(), get_next_object(), and Botan::BER_Object::length().

◆ decode() [4/10]

BER_Decoder & Botan::BER_Decoder::decode ( bool & out)
inline

Decode a BER encoded BOOLEAN

Definition at line 220 of file ber_dec.h.

References BER_Decoder(), Botan::Boolean, decode(), and Botan::Universal.

Referenced by decode(), decode(), decode(), decode(), decode_and_check(), decode_constrained_integer(), Botan::AlgorithmIdentifier::decode_from(), Botan::AlternativeName::decode_from(), Botan::Attribute::decode_from(), Botan::Cert_Extension::ASBlocks::ASIdentifiers::decode_from(), Botan::Cert_Extension::ASBlocks::ASIdOrRange::decode_from(), Botan::Cert_Extension::IPAddressBlocks::IPAddressFamily::decode_from(), Botan::Cert_Extension::IPAddressBlocks::IPAddressOrRange< V >::decode_from(), Botan::Cert_Extension::TNAuthList::Entry::decode_from(), Botan::CRL_Entry::decode_from(), Botan::Extensions::decode_from(), Botan::GeneralSubtree::decode_from(), Botan::OCSP::CertID::decode_from(), Botan::OCSP::SingleResponse::decode_from(), Botan::X509_DN::decode_from(), Botan::X509_Object::decode_from(), decode_list(), decode_octet_string_bigint(), decode_optional(), decode_optional_implicit(), decode_optional_string(), Botan::Ed25519_PrivateKey::Ed25519_PrivateKey(), Botan::Ed448_PrivateKey::Ed448_PrivateKey(), get_next_octet_string(), Botan::GOST_3410_PublicKey::GOST_3410_PublicKey(), Botan::X509::load_key(), Botan::McEliece_PrivateKey::McEliece_PrivateKey(), Botan::McEliece_PublicKey::McEliece_PublicKey(), Botan::pbes2_decrypt(), Botan::OCSP::Response::Response(), Botan::RSA_PublicKey::RSA_PublicKey(), Botan::TLS::Session::Session(), and Botan::X25519_PrivateKey::X25519_PrivateKey().

◆ decode() [5/10]

BER_Decoder & Botan::BER_Decoder::decode ( bool & v,
ASN1_Type type_tag,
ASN1_Class class_tag = ASN1_Class::ContextSpecific )

Definition at line 587 of file ber_dec.cpp.

587 {
588 const BER_Object obj = get_next_object();
589 obj.assert_is_a(type_tag, class_tag);
590
591 if(obj.length() != 1) {
592 throw BER_Decoding_Error("BER boolean value had invalid size");
593 }
594
595 const uint8_t val = obj.bits()[0];
596
597 // DER requires boolean values to be exactly 0x00 or 0xFF
598 if(m_limits.require_der_encoding() && val != 0x00 && val != 0xFF) {
599 throw BER_Decoding_Error("Detected non-canonical boolean encoding in DER structure");
600 }
601
602 out = (val != 0) ? true : false;
603
604 return (*this);
605}

References Botan::BER_Object::assert_is_a(), BER_Decoder(), Botan::BER_Object::bits(), get_next_object(), and Botan::BER_Object::length().

◆ decode() [6/10]

BER_Decoder & Botan::BER_Decoder::decode ( secure_vector< uint8_t > & v,
ASN1_Type real_type,
ASN1_Type type_tag,
ASN1_Class class_tag = ASN1_Class::ContextSpecific )

Definition at line 766 of file ber_dec.cpp.

769 {
770 if(real_type != ASN1_Type::OctetString && real_type != ASN1_Type::BitString) {
771 throw BER_Bad_Tag("Bad tag for {BIT,OCTET} STRING", static_cast<uint32_t>(real_type));
772 }
773
774 asn1_decode_binary_string(
775 buffer, get_next_object(), real_type, type_tag, class_tag, m_limits.require_der_encoding());
776 return (*this);
777}

References BER_Decoder(), Botan::BitString, get_next_object(), and Botan::OctetString.

◆ decode() [7/10]

BER_Decoder & Botan::BER_Decoder::decode ( size_t & out)
inline

Definition at line 225 of file ber_dec.h.

References BER_Decoder(), decode(), Botan::Integer, and Botan::Universal.

Referenced by decode().

◆ decode() [8/10]

BER_Decoder & Botan::BER_Decoder::decode ( size_t & v,
ASN1_Type type_tag,
ASN1_Class class_tag = ASN1_Class::ContextSpecific )

Definition at line 610 of file ber_dec.cpp.

610 {
611 BigInt integer;
612 decode(integer, type_tag, class_tag);
613
614 if(integer.signum() < 0) {
615 throw BER_Decoding_Error("Decoded small integer value was negative");
616 }
617
618 if(integer.bits() > 32) {
619 throw BER_Decoding_Error("Decoded integer value larger than expected");
620 }
621
622 out = 0;
623 for(size_t i = 0; i != 4; ++i) {
624 out = (out << 8) | integer.byte_at(3 - i);
625 }
626
627 return (*this);
628}

References BER_Decoder(), Botan::BigInt::bits(), Botan::BigInt::byte_at(), decode(), and Botan::BigInt::signum().

◆ decode() [9/10]

BER_Decoder & Botan::BER_Decoder::decode ( std::vector< uint8_t > & v,
ASN1_Type real_type,
ASN1_Type type_tag,
ASN1_Class class_tag = ASN1_Class::ContextSpecific )

Definition at line 779 of file ber_dec.cpp.

782 {
783 if(real_type != ASN1_Type::OctetString && real_type != ASN1_Type::BitString) {
784 throw BER_Bad_Tag("Bad tag for {BIT,OCTET} STRING", static_cast<uint32_t>(real_type));
785 }
786
787 asn1_decode_binary_string(
788 buffer, get_next_object(), real_type, type_tag, class_tag, m_limits.require_der_encoding());
789 return (*this);
790}

References BER_Decoder(), Botan::BitString, get_next_object(), and Botan::OctetString.

◆ decode() [10/10]

template<typename Alloc>
BER_Decoder & Botan::BER_Decoder::decode ( std::vector< uint8_t, Alloc > & out,
ASN1_Type real_type )
inline

Definition at line 242 of file ber_dec.h.

242 {
243 return decode(out, real_type, real_type, ASN1_Class::Universal);
244 }

References BER_Decoder(), decode(), and Botan::Universal.

◆ decode_and_check()

template<typename T>
BER_Decoder & Botan::BER_Decoder::decode_and_check ( const T & expected,
std::string_view error_msg )
inline

Definition at line 314 of file ber_dec.h.

314 {
315 T actual;
316 decode(actual);
317
318 if(actual != expected) {
319 throw Decoding_Error(error_msg);
320 }
321
322 return (*this);
323 }

References BER_Decoder(), and decode().

Referenced by Botan::EC_PrivateKey::EC_PrivateKey(), Botan::OCSP::Response::Response(), Botan::RSA_PrivateKey::RSA_PrivateKey(), and Botan::TLS::Session::Session().

◆ decode_constrained_integer()

uint64_t Botan::BER_Decoder::decode_constrained_integer ( ASN1_Type type_tag,
ASN1_Class class_tag,
size_t T_bytes )

Definition at line 633 of file ber_dec.cpp.

633 {
634 if(T_bytes > 8) {
635 throw BER_Decoding_Error("Can't decode small integer over 8 bytes");
636 }
637
638 BigInt integer;
639 decode(integer, type_tag, class_tag);
640
641 if(integer.is_negative()) {
642 throw BER_Decoding_Error("Decoded small integer value was negative");
643 }
644
645 if(integer.bits() > 8 * T_bytes) {
646 throw BER_Decoding_Error("Decoded integer value larger than expected");
647 }
648
649 uint64_t out = 0;
650 for(size_t i = 0; i != 8; ++i) {
651 out = (out << 8) | integer.byte_at(7 - i);
652 }
653
654 return out;
655}

References Botan::BigInt::bits(), Botan::BigInt::byte_at(), decode(), and Botan::BigInt::is_negative().

Referenced by decode_integer_type().

◆ decode_integer_type() [1/2]

template<typename T>
BER_Decoder & Botan::BER_Decoder::decode_integer_type ( T & out)
inline

Definition at line 274 of file ber_dec.h.

274 {
276 }
BER_Decoder & decode_integer_type(T &out)
Definition ber_dec.h:274

References BER_Decoder(), decode_integer_type(), Botan::Integer, and Botan::Universal.

Referenced by decode_integer_type(), and Botan::TLS::Session::Session().

◆ decode_integer_type() [2/2]

template<typename T>
BER_Decoder & Botan::BER_Decoder::decode_integer_type ( T & out,
ASN1_Type type_tag,
ASN1_Class class_tag = ASN1_Class::ContextSpecific )
inline

Definition at line 279 of file ber_dec.h.

279 {
280 out = static_cast<T>(decode_constrained_integer(type_tag, class_tag, sizeof(out)));
281 return (*this);
282 }
uint64_t decode_constrained_integer(ASN1_Type type_tag, ASN1_Class class_tag, size_t T_bytes)
Definition ber_dec.cpp:633

References BER_Decoder(), Botan::ContextSpecific, and decode_constrained_integer().

◆ decode_list()

template<typename T>
BER_Decoder & Botan::BER_Decoder::decode_list ( std::vector< T > & out,
ASN1_Type type_tag = ASN1_Type::Sequence,
ASN1_Class class_tag = ASN1_Class::Universal )

Definition at line 430 of file ber_dec.h.

430 {
431 BER_Decoder list = start_cons(type_tag, class_tag);
432
433 while(list.more_items()) {
434 T value;
435 list.decode(value);
436 vec.push_back(std::move(value));
437 }
438
439 list.end_cons();
440
441 return (*this);
442}
BER_Decoder start_cons(ASN1_Type type_tag, ASN1_Class class_tag)
Definition ber_dec.cpp:514

References BER_Decoder(), decode(), end_cons(), more_items(), push_back(), and start_cons().

Referenced by Botan::Cert_Extension::ASBlocks::ASIdentifierChoice::decode_from(), Botan::Cert_Extension::IPAddressBlocks::IPAddressChoice< V >::decode_from(), decode_optional_list(), Botan::OCSP::Response::Response(), and Botan::TLS::Session::Session().

◆ decode_null()

BER_Decoder & Botan::BER_Decoder::decode_null ( )

Definition at line 568 of file ber_dec.cpp.

568 {
569 const BER_Object obj = get_next_object();
570 obj.assert_is_a(ASN1_Type::Null, ASN1_Class::Universal);
571 if(obj.length() > 0) {
572 throw BER_Decoding_Error("NULL object had nonzero size");
573 }
574 return (*this);
575}

References Botan::BER_Object::assert_is_a(), BER_Decoder(), get_next_object(), Botan::BER_Object::length(), Botan::Null, and Botan::Universal.

Referenced by Botan::Cert_Extension::ASBlocks::ASIdentifierChoice::decode_from(), and Botan::Cert_Extension::IPAddressBlocks::IPAddressChoice< V >::decode_from().

◆ decode_octet_string_bigint()

BER_Decoder & Botan::BER_Decoder::decode_octet_string_bigint ( BigInt & b)

Decode an integer value which is typed as an octet string

Definition at line 577 of file ber_dec.cpp.

577 {
580 out = BigInt::from_bytes(out_vec);
581 return (*this);
582}
static BigInt from_bytes(std::span< const uint8_t > bytes)
Definition bigint.cpp:83

References BER_Decoder(), decode(), Botan::BigInt::from_bytes(), and Botan::OctetString.

◆ decode_optional() [1/2]

template<typename T>
BER_Decoder & Botan::BER_Decoder::decode_optional ( std::optional< T > & out,
ASN1_Type type_tag,
ASN1_Class class_tag )

Definition at line 381 of file ber_dec.h.

381 {
382 BER_Object obj = get_next_object();
383
384 if(obj.is_a(type_tag, class_tag)) {
385 T out{};
386 if(class_tag == ASN1_Class::ExplicitContextSpecific) {
387 BER_Decoder(obj, m_limits).decode(out).verify_end();
388 } else {
389 this->push_back(std::move(obj));
390 this->decode(out, type_tag, class_tag);
391 }
392 optval = std::move(out);
393 } else {
394 this->push_back(std::move(obj));
395 optval = std::nullopt;
396 }
397
398 return (*this);
399}
void push_back(const BER_Object &obj)
Definition ber_dec.cpp:500

References BER_Decoder(), decode(), Botan::ExplicitContextSpecific, get_next_object(), Botan::BER_Object::is_a(), and push_back().

◆ decode_optional() [2/2]

template<typename T>
BER_Decoder & Botan::BER_Decoder::decode_optional ( T & out,
ASN1_Type type_tag,
ASN1_Class class_tag,
const T & default_value = T() )
inline

Definition at line 285 of file ber_dec.h.

285 {
286 std::optional<T> optval;
287 this->decode_optional(optval, type_tag, class_tag);
288 out = optval ? *optval : default_value;
289 return (*this);
290 }
BER_Decoder & decode_optional(T &out, ASN1_Type type_tag, ASN1_Class class_tag, const T &default_value=T())
Definition ber_dec.h:285

References BER_Decoder(), and decode_optional().

Referenced by Botan::Extensions::decode_from(), Botan::GeneralSubtree::decode_from(), Botan::OCSP::SingleResponse::decode_from(), decode_optional(), and Botan::OCSP::Response::Response().

◆ decode_optional_implicit()

template<typename T>
BER_Decoder & Botan::BER_Decoder::decode_optional_implicit ( T & out,
ASN1_Type type_tag,
ASN1_Class class_tag,
ASN1_Type real_type,
ASN1_Class real_class,
const T & default_value = T() )

Definition at line 405 of file ber_dec.h.

410 {
411 BER_Object obj = get_next_object();
412
413 if(obj.is_a(type_tag, class_tag)) {
414 obj.set_tagging(real_type, real_class);
415 push_back(std::move(obj));
416 decode(out, real_type, real_class);
417 } else {
418 // Not what we wanted, push it back on the stream
419 out = default_value;
420 push_back(std::move(obj));
421 }
422
423 return (*this);
424}

References BER_Decoder(), decode(), get_next_object(), Botan::BER_Object::is_a(), and push_back().

Referenced by Botan::Cert_Extension::CRL_Distribution_Points::Distribution_Point::decode_from().

◆ decode_optional_list()

template<typename T>
bool Botan::BER_Decoder::decode_optional_list ( std::vector< T > & out,
ASN1_Type type_tag = ASN1_Type::Sequence,
ASN1_Class class_tag = ASN1_Class::Universal )

Definition at line 448 of file ber_dec.h.

448 {
449 if(peek_next_object().is_a(type_tag, class_tag)) {
450 decode_list(vec, type_tag, class_tag);
451 return true;
452 }
453
454 return false;
455}
const BER_Object & peek_next_object()
Definition ber_dec.cpp:415
BER_Decoder & decode_list(std::vector< T > &out, ASN1_Type type_tag=ASN1_Type::Sequence, ASN1_Class class_tag=ASN1_Class::Universal)
Definition ber_dec.h:430

References decode_list(), and peek_next_object().

◆ decode_optional_string() [1/2]

template<typename Alloc>
BER_Decoder & Botan::BER_Decoder::decode_optional_string ( std::vector< uint8_t, Alloc > & out,
ASN1_Type real_type,
ASN1_Type expected_tag,
ASN1_Class class_tag = ASN1_Class::ContextSpecific )
inline

Definition at line 353 of file ber_dec.h.

356 {
357 return decode_optional_string(out, real_type, static_cast<uint32_t>(expected_tag), class_tag);
358 }
BER_Decoder & decode_optional_string(std::vector< uint8_t, Alloc > &out, ASN1_Type real_type, uint32_t expected_tag, ASN1_Class class_tag=ASN1_Class::ContextSpecific)
Definition ber_dec.h:329

References BER_Decoder(), Botan::ContextSpecific, and decode_optional_string().

◆ decode_optional_string() [2/2]

template<typename Alloc>
BER_Decoder & Botan::BER_Decoder::decode_optional_string ( std::vector< uint8_t, Alloc > & out,
ASN1_Type real_type,
uint32_t expected_tag,
ASN1_Class class_tag = ASN1_Class::ContextSpecific )
inline

Definition at line 329 of file ber_dec.h.

332 {
333 BER_Object obj = get_next_object();
334
335 const ASN1_Type type_tag = static_cast<ASN1_Type>(expected_tag);
336
337 if(obj.is_a(type_tag, class_tag)) {
338 if(class_tag == ASN1_Class::ExplicitContextSpecific) {
339 BER_Decoder(obj, m_limits).decode(out, real_type).verify_end();
340 } else {
341 push_back(std::move(obj));
342 decode(out, real_type, type_tag, class_tag);
343 }
344 } else {
345 out.clear();
346 push_back(std::move(obj));
347 }
348
349 return (*this);
350 }
ASN1_Type
Definition asn1_obj.h:43

References BER_Decoder(), Botan::ContextSpecific, decode(), Botan::ExplicitContextSpecific, get_next_object(), Botan::BER_Object::is_a(), and push_back().

Referenced by decode_optional_string(), and Botan::OCSP::Response::Response().

◆ discard_remaining()

BER_Decoder & Botan::BER_Decoder::discard_remaining ( )

Discard any data that remains unread Returns (*this)

Definition at line 398 of file ber_dec.cpp.

398 {
399 m_pushed = BER_Object();
400 uint8_t buf = 0;
401 while(m_source->read_byte(buf) != 0) {}
402 return (*this);
403}

References BER_Decoder().

Referenced by Botan::Ed25519_PrivateKey::Ed25519_PrivateKey(), Botan::GOST_3410_PublicKey::GOST_3410_PublicKey(), and Botan::X25519_PrivateKey::X25519_PrivateKey().

◆ end_cons()

BER_Decoder & Botan::BER_Decoder::end_cons ( )

Finish decoding a constructed data, throws if any data remains. Returns the parent of *this (ie the object on which start_cons was called).

Definition at line 524 of file ber_dec.cpp.

524 {
525 if(m_parent == nullptr) {
526 throw Invalid_State("BER_Decoder::end_cons called with null parent");
527 }
528 if(!m_source->end_of_data() || m_pushed.is_set()) {
529 throw Decoding_Error("BER_Decoder::end_cons called with data left");
530 }
531 return (*m_parent);
532}

References BER_Decoder().

Referenced by Botan::AlgorithmIdentifier::decode_from(), Botan::Attribute::decode_from(), Botan::Cert_Extension::ASBlocks::ASIdentifiers::decode_from(), Botan::Cert_Extension::ASBlocks::ASIdOrRange::decode_from(), Botan::Cert_Extension::CRL_Distribution_Points::Distribution_Point::decode_from(), Botan::Cert_Extension::IPAddressBlocks::IPAddressFamily::decode_from(), Botan::Cert_Extension::IPAddressBlocks::IPAddressOrRange< V >::decode_from(), Botan::Cert_Extension::TNAuthList::Entry::decode_from(), Botan::CRL_Entry::decode_from(), Botan::Extensions::decode_from(), Botan::GeneralSubtree::decode_from(), Botan::OCSP::CertID::decode_from(), Botan::OCSP::SingleResponse::decode_from(), Botan::X509_DN::decode_from(), Botan::X509_Object::decode_from(), decode_list(), Botan::GOST_3410_PublicKey::GOST_3410_PublicKey(), Botan::X509::load_key(), Botan::McEliece_PrivateKey::McEliece_PrivateKey(), Botan::McEliece_PublicKey::McEliece_PublicKey(), Botan::pbes2_decrypt(), Botan::OCSP::Response::Response(), and Botan::RSA_PublicKey::RSA_PublicKey().

◆ get_next()

BER_Decoder & Botan::BER_Decoder::get_next ( BER_Object & ber)
inline

Definition at line 106 of file ber_dec.h.

106 {
107 ber = get_next_object();
108 return (*this);
109 }

References BER_Decoder(), and get_next_object().

Referenced by Botan::OCSP::SingleResponse::decode_from().

◆ get_next_object()

BER_Object Botan::BER_Decoder::get_next_object ( )

Get the next object in the data stream. If EOF, returns an object with type NO_OBJECT.

Definition at line 426 of file ber_dec.cpp.

426 {
427 BER_Object next;
428
429 if(m_pushed.is_set()) {
430 std::swap(next, m_pushed);
431 return next;
432 }
433
434 for(;;) {
437 decode_tag(m_source, type_tag, class_tag);
438 next.set_tagging(type_tag, class_tag);
439 if(next.is_set() == false) { // no more objects
440 return next;
441 }
442
443 const size_t allow_indef = m_limits.allow_ber_encoding() ? m_limits.max_nested_indefinite_length() : 0;
444 const bool der_mode = m_limits.require_der_encoding();
445 const auto dl = decode_length(m_source, allow_indef, der_mode, is_constructed(class_tag));
446
447 // Per X.690 8.1.5 the only valid EOC encoding is the two-octet
448 // sequence 0x00 0x00. Reject any other length encoding on a tag of
449 // (Eoc, Universal) before we consume the "content" bytes.
450 if(type_tag == ASN1_Type::Eoc && class_tag == ASN1_Class::Universal &&
451 (dl.content_length() != 0 || dl.indefinite_length())) {
452 throw BER_Decoding_Error("EOC marker with non-zero length");
453 }
454
455 if(!m_source->check_available(dl.total_length())) {
456 throw BER_Decoding_Error("Value truncated");
457 }
458
459 uint8_t* out = next.mutable_bits(dl.content_length());
460 if(m_source->read(out, dl.content_length()) != dl.content_length()) {
461 throw BER_Decoding_Error("Value truncated");
462 }
463
464 if(dl.indefinite_length()) {
465 // After reading the data consume the 2-byte EOC
466 uint8_t eoc[2] = {0xFF, 0xFF};
467 if(m_source->read(eoc, 2) != 2 || eoc[0] != 0x00 || eoc[1] != 0x00) {
468 throw BER_Decoding_Error("Missing or malformed EOC marker");
469 }
470 }
471
472 if(next.tagging() == static_cast<uint32_t>(ASN1_Type::Eoc)) {
473 if(m_limits.require_der_encoding()) {
474 throw BER_Decoding_Error("Detected EOC marker in DER structure");
475 }
476 continue;
477 } else {
478 break;
479 }
480 }
481
482 return next;
483}
ASN1_Class
Definition asn1_obj.h:28

References Botan::Eoc, Botan::BER_Object::is_set(), Botan::NoObject, Botan::BER_Object::tagging(), and Botan::Universal.

Referenced by decode(), decode(), decode(), decode(), Botan::AlternativeName::decode_from(), Botan::ASN1_String::decode_from(), Botan::ASN1_Time::decode_from(), Botan::Cert_Extension::ASBlocks::ASIdentifiers::decode_from(), Botan::Cert_Extension::TNAuthList::Entry::decode_from(), Botan::GeneralName::decode_from(), Botan::OID::decode_from(), decode_null(), decode_optional(), decode_optional_implicit(), decode_optional_string(), get_next(), peek_next_object(), and start_cons().

◆ get_next_octet_string()

std::vector< uint8_t > Botan::BER_Decoder::get_next_octet_string ( )
inline

Definition at line 232 of file ber_dec.h.

232 {
233 std::vector<uint8_t> out_vec;
235 return out_vec;
236 }

References decode(), and Botan::OctetString.

Referenced by Botan::OCSP::Response::Response().

◆ get_next_value()

template<typename T>
requires std::is_standard_layout_v<T> && std::is_trivial_v<T>
BER_Decoder & Botan::BER_Decoder::get_next_value ( T & out,
ASN1_Type type_tag,
ASN1_Class class_tag = ASN1_Class::ContextSpecific )
inline

Get next object and copy value to POD type Asserts value length is equal to POD type sizeof. Asserts Type tag and optional Class tag according to parameters. Copy value to POD type (struct, union, C-style array, std::array, etc.).

Parameters
outPOD type reference where to copy object value
type_tagASN1_Type enum to assert type on object read
class_tagASN1_Type enum to assert class on object read (default: CONTEXT_SPECIFIC)
Returns
this reference

Definition at line 189 of file ber_dec.h.

191 {
192 const BER_Object obj = get_next_value(sizeof(T), type_tag, class_tag);
193
194 std::memcpy(reinterpret_cast<uint8_t*>(&out), obj.bits(), obj.length());
195
196 return (*this);
197 }
BER_Decoder & get_next_value(T &out, ASN1_Type type_tag, ASN1_Class class_tag=ASN1_Class::ContextSpecific)
Definition ber_dec.h:189

References BER_Decoder(), Botan::BER_Object::bits(), Botan::ContextSpecific, get_next_value(), and Botan::BER_Object::length().

Referenced by get_next_value(), and ~BER_Decoder().

◆ limits()

Limits Botan::BER_Decoder::limits ( ) const
inline

◆ more_items()

bool Botan::BER_Decoder::more_items ( ) const

Return true if there is at least one more item remaining

Definition at line 371 of file ber_dec.cpp.

371 {
372 if(m_source->end_of_data() && !m_pushed.is_set()) {
373 return false;
374 }
375 return true;
376}

Referenced by Botan::AlternativeName::decode_from(), Botan::Cert_Extension::TNAuthList::Entry::decode_from(), Botan::CRL_Entry::decode_from(), Botan::Extensions::decode_from(), Botan::X509_DN::decode_from(), decode_list(), and Botan::OCSP::Response::Response().

◆ operator=() [1/2]

BER_Decoder & Botan::BER_Decoder::operator= ( BER_Decoder && )
defaultnoexcept

References BER_Decoder().

◆ operator=() [2/2]

BER_Decoder & Botan::BER_Decoder::operator= ( const BER_Decoder & )
delete

References BER_Decoder().

◆ peek_next_object()

const BER_Object & Botan::BER_Decoder::peek_next_object ( )

Peek at the next object without removing it from the stream

If an object has been pushed, then it returns that object. Otherwise it reads the next object and pushes it. Thus, a you call peek_next_object followed by push_back without a subsequent read, it will fail.

Definition at line 415 of file ber_dec.cpp.

415 {
416 if(!m_pushed.is_set()) {
417 m_pushed = get_next_object();
418 }
419
420 return m_pushed;
421}

References get_next_object().

Referenced by Botan::Cert_Extension::ASBlocks::ASIdentifierChoice::decode_from(), Botan::Cert_Extension::ASBlocks::ASIdentifiers::decode_from(), Botan::Cert_Extension::ASBlocks::ASIdOrRange::decode_from(), Botan::Cert_Extension::IPAddressBlocks::IPAddressChoice< V >::decode_from(), Botan::Cert_Extension::IPAddressBlocks::IPAddressFamily::decode_from(), Botan::Cert_Extension::IPAddressBlocks::IPAddressOrRange< V >::decode_from(), and decode_optional_list().

◆ push_back() [1/2]

void Botan::BER_Decoder::push_back ( BER_Object && obj)

Push an object back onto the stream. Throws if another object was previously pushed and has not been subsequently read out.

Definition at line 507 of file ber_dec.cpp.

507 {
508 if(m_pushed.is_set()) {
509 throw Invalid_State("BER_Decoder: Only one push back is allowed");
510 }
511 m_pushed = std::move(obj);
512}

◆ push_back() [2/2]

void Botan::BER_Decoder::push_back ( const BER_Object & obj)

Push an object back onto the stream. Throws if another object was previously pushed and has not been subsequently read out.

Definition at line 500 of file ber_dec.cpp.

500 {
501 if(m_pushed.is_set()) {
502 throw Invalid_State("BER_Decoder: Only one push back is allowed");
503 }
504 m_pushed = obj;
505}

Referenced by decode_list(), decode_optional(), decode_optional_implicit(), decode_optional_string(), Botan::GOST_3410_PublicKey::GOST_3410_PublicKey(), and Botan::McEliece_PrivateKey::McEliece_PrivateKey().

◆ raw_bytes()

template<typename Alloc>
BER_Decoder & Botan::BER_Decoder::raw_bytes ( std::vector< uint8_t, Alloc > & out)
inline

Definition at line 203 of file ber_dec.h.

203 {
204 out.clear();
205 for(;;) {
206 if(auto next = this->read_next_byte()) {
207 out.push_back(*next);
208 } else {
209 break;
210 }
211 }
212 return (*this);
213 }

References BER_Decoder().

Referenced by Botan::AlgorithmIdentifier::decode_from(), Botan::Attribute::decode_from(), Botan::X509_DN::decode_from(), Botan::X509_Object::decode_from(), and Botan::OCSP::Response::Response().

◆ start_cons()

BER_Decoder Botan::BER_Decoder::start_cons ( ASN1_Type type_tag,
ASN1_Class class_tag )

Definition at line 514 of file ber_dec.cpp.

514 {
515 BER_Object obj = get_next_object();
516 obj.assert_is_a(type_tag, class_tag | ASN1_Class::Constructed);
517 BER_Decoder child(std::move(obj), this);
518 return child;
519}

References Botan::BER_Object::assert_is_a(), BER_Decoder(), Botan::Constructed, and get_next_object().

Referenced by decode_list(), start_context_specific(), start_explicit_context_specific(), start_sequence(), and start_set().

◆ start_context_specific()

BER_Decoder Botan::BER_Decoder::start_context_specific ( uint32_t tag)
inline

◆ start_explicit_context_specific()

BER_Decoder Botan::BER_Decoder::start_explicit_context_specific ( uint32_t tag)
inline

Definition at line 168 of file ber_dec.h.

References BER_Decoder(), Botan::ExplicitContextSpecific, and start_cons().

◆ start_sequence()

◆ start_set()

BER_Decoder Botan::BER_Decoder::start_set ( )
inline

◆ verify_end() [1/2]

◆ verify_end() [2/2]

BER_Decoder & Botan::BER_Decoder::verify_end ( std::string_view err_msg)

Verify the stream is concluded, throws otherwise. Returns (*this)

Definition at line 388 of file ber_dec.cpp.

388 {
389 if(!m_source->end_of_data() || m_pushed.is_set()) {
390 throw Decoding_Error(err);
391 }
392 return (*this);
393}

References BER_Decoder().


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