Botan 3.13.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 (BER_Object &&obj, Limits limits)
 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)
BER_Decoderdecode_bitstring (ASN1_BitString &out, ASN1_Type type_tag=ASN1_Type::BitString, ASN1_Class class_tag=ASN1_Class::Universal)
uint64_t decode_constrained_integer (ASN1_Type type_tag, ASN1_Class class_tag, size_t T_bytes)
template<typename T>
BER_Decoderdecode_default (T &out, ASN1_Type type_tag, ASN1_Class class_tag, const T &default_value)
template<typename T>
BER_Decoderdecode_implicit (BER_Object obj, T &out, ASN1_Type real_type, ASN1_Class real_class)
template<typename T>
BER_Decoderdecode_implicit (T &out, ASN1_Type type_tag, ASN1_Class class_tag, ASN1_Type real_type, ASN1_Class real_class)
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 > &vec, ASN1_Type type_tag=ASN1_Type::Sequence, ASN1_Class class_tag=ASN1_Class::Universal)
BER_Decoderdecode_named_bitstring (uint64_t &bits, size_t width, ASN1_Type type_tag=ASN1_Type::BitString, ASN1_Class class_tag=ASN1_Class::Universal)
BER_Decoderdecode_null ()
template<typename Alloc>
BER_Decoderdecode_octet_aligned_bitstring (std::vector< uint8_t, Alloc > &out, ASN1_Type type_tag=ASN1_Type::BitString, ASN1_Class class_tag=ASN1_Class::Universal)
BER_Decoderdecode_octet_string_bigint (BigInt &b)
template<typename T>
BER_Decoderdecode_optional (std::optional< T > &optval, 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 F>
BER_Decoderdecode_optional_field (uint32_t tag_no, ASN1_Class class_tag, F &&fn)
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 > &vec, ASN1_Type type_tag=ASN1_Type::Sequence, ASN1_Class class_tag=ASN1_Class::Universal)
template<typename Alloc>
BER_Decoderdecode_optional_octet_aligned_bitstring (std::vector< uint8_t, Alloc > &out, ASN1_Type expected_tag, ASN1_Class class_tag=ASN1_Class::ContextSpecific)
template<typename Alloc>
BER_Decoderdecode_optional_octet_aligned_bitstring (std::vector< uint8_t, Alloc > &out, uint32_t 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, 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 27 of file ber_dec.h.

Constructor & Destructor Documentation

◆ BER_Decoder() [1/8]

◆ BER_Decoder() [2/8]

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 659 of file ber_dec.cpp.

659 : m_limits(limits) {
660 m_data_src = std::make_unique<DataSource_Memory>(buf);
661 m_source = m_data_src.get();
662}

References limits().

◆ BER_Decoder() [3/8]

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

Set up to BER decode the data in src

Definition at line 654 of file ber_dec.cpp.

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

References limits().

◆ BER_Decoder() [4/8]

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 166 of file ber_dec.h.

166 :
167 BER_Decoder(obj.data(), limits) {}

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

◆ BER_Decoder() [5/8]

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 173 of file ber_dec.h.

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

References BER_Decoder(), and BOTAN_FUTURE_EXPLICIT.

◆ BER_Decoder() [6/8]

Botan::BER_Decoder::BER_Decoder ( BER_Object && obj,
Limits limits )

Set up to BER decode the data in obj, taking ownership of its contents

Definition at line 646 of file ber_dec.cpp.

646 : m_limits(limits) {
647 m_data_src = std::make_unique<DataSource_BERObject>(std::move(obj));
648 m_source = m_data_src.get();
649}

References limits().

◆ BER_Decoder() [7/8]

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

References BER_Decoder().

◆ BER_Decoder() [8/8]

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

Move constructor

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 )

Request an object decode itself from this stream

Parameters
objthe object to decode into
type_tagmust be NoObject; implicit tagging is not supported here
class_tagmust be NoObject; implicit tagging is not supported here

Definition at line 671 of file ber_dec.cpp.

671 {
672 // TODO support this case properly
673 if(type_tag != ASN1_Type::NoObject || class_tag != ASN1_Class::NoObject) {
674 throw Not_Implemented("BER_Decoder::decode(ASN1_Object) does not support implicit tagged decoding");
675 }
676 obj.decode_from(*this);
677 return (*this);
678}

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

◆ decode() [2/10]

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

Decode a BER encoded INTEGER

Definition at line 368 of file ber_dec.h.

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

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 )

Decode an INTEGER with an IMPLICIT tagging

Parameters
vwhere the value is written
type_tagthe expected type tag
class_tagthe expected class tag

Definition at line 775 of file ber_dec.cpp.

775 {
776 const BER_Object obj = get_next_object();
777 obj.assert_is_a(type_tag, class_tag);
778
779 // An INTEGER must have at least one content octet (X.690 section 8.3.1)
780 if(obj.length() == 0) {
781 throw BER_Decoding_Error("INTEGER encoding has no content octets");
782 }
783
784 // DER requires minimal INTEGER encoding (X.690 section 8.3.2)
785 if(m_limits.require_der_encoding()) {
786 if(obj.length() > 1) {
787 if(obj.bits()[0] == 0x00 && (obj.bits()[1] & 0x80) == 0) {
788 throw BER_Decoding_Error("Detected non-minimal INTEGER encoding in DER structure");
789 }
790 if(obj.bits()[0] == 0xFF && (obj.bits()[1] & 0x80) != 0) {
791 throw BER_Decoding_Error("Detected non-minimal INTEGER encoding in DER structure");
792 }
793 }
794 }
795
796 out = ASN1::integer_from_contents(obj.data());
797
798 return (*this);
799}
BER_Object get_next_object()
Definition ber_dec.cpp:516
BigInt integer_from_contents(std::span< const uint8_t > contents)
Definition ber_dec.cpp:801

References Botan::BER_Object::assert_is_a(), BER_Decoder(), Botan::BER_Object::bits(), Botan::BER_Object::data(), get_next_object(), Botan::ASN1::integer_from_contents(), 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 358 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::CRL_Distribution_Points::Distribution_Point::decode_from(), Botan::Cert_Extension::IPAddressBlocks::IPAddressFamily::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(), Botan::X509_Serial_Number::decode_from(), decode_implicit(), decode_list(), decode_octet_string_bigint(), decode_optional(), 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::PKCS12::PKCS12(), Botan::pkcs12_pbe_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 )

Decode a BOOLEAN with an IMPLICIT tagging

Parameters
vwhere the value is written
type_tagthe expected type tag
class_tagthe expected class tag

Definition at line 702 of file ber_dec.cpp.

702 {
703 const BER_Object obj = get_next_object();
704 obj.assert_is_a(type_tag, class_tag);
705
706 if(obj.length() != 1) {
707 throw BER_Decoding_Error("BER boolean value had invalid size");
708 }
709
710 const uint8_t val = obj.bits()[0];
711
712 // DER requires boolean values to be exactly 0x00 or 0xFF
713 if(m_limits.require_der_encoding() && val != 0x00 && val != 0xFF) {
714 throw BER_Decoding_Error("Detected non-canonical boolean encoding in DER structure");
715 }
716
717 out = (val != 0) ? true : false;
718
719 return (*this);
720}

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 )

Decode a BIT STRING or OCTET STRING with an IMPLICIT tagging

Parameters
vwhere the contents are written
real_typeeither ASN1_Type::OctetString or ASN1_Type::BitString
type_tagthe expected type tag
class_tagthe expected class tag

Definition at line 1018 of file ber_dec.cpp.

1021 {
1022 if(real_type != ASN1_Type::OctetString && real_type != ASN1_Type::BitString) {
1023 throw BER_Bad_Tag("Bad tag for {BIT,OCTET} STRING", static_cast<uint32_t>(real_type));
1024 }
1025
1026 asn1_decode_binary_string(buffer, get_next_object(), real_type, type_tag, class_tag, m_limits);
1027 return (*this);
1028}

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

◆ decode() [7/10]

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

Decode a small BER encoded INTEGER

Definition at line 363 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 )

Decode a small INTEGER with an IMPLICIT tagging

Parameters
vwhere the value is written
type_tagthe expected type tag
class_tagthe expected class tag

Definition at line 725 of file ber_dec.cpp.

725 {
726 BigInt integer;
727 decode(integer, type_tag, class_tag);
728
729 if(integer.signum() < 0) {
730 throw BER_Decoding_Error("Decoded small integer value was negative");
731 }
732
733 if(integer.bits() > 32) {
734 throw BER_Decoding_Error("Decoded integer value larger than expected");
735 }
736
737 out = 0;
738 for(size_t i = 0; i != 4; ++i) {
739 out = (out << 8) | integer.byte_at(3 - i);
740 }
741
742 return (*this);
743}

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 )

Decode a BIT STRING or OCTET STRING with an IMPLICIT tagging

Parameters
vwhere the contents are written
real_typeeither ASN1_Type::OctetString or ASN1_Type::BitString
type_tagthe expected type tag
class_tagthe expected class tag

Definition at line 1030 of file ber_dec.cpp.

1033 {
1034 if(real_type != ASN1_Type::OctetString && real_type != ASN1_Type::BitString) {
1035 throw BER_Bad_Tag("Bad tag for {BIT,OCTET} STRING", static_cast<uint32_t>(real_type));
1036 }
1037
1038 asn1_decode_binary_string(buffer, get_next_object(), real_type, type_tag, class_tag, m_limits);
1039 return (*this);
1040}

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

BER decode a BIT STRING or OCTET STRING

Parameters
outwhere the contents are written
real_typeeither ASN1_Type::OctetString or ASN1_Type::BitString

Definition at line 386 of file ber_dec.h.

386 {
387 return decode(out, real_type, real_type, ASN1_Class::Universal);
388 }

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

Decode a value and throw unless it equals the expected value

Parameters
expectedthe value the encoding must have
error_msgthe message of the exception thrown on a mismatch

Definition at line 701 of file ber_dec.h.

701 {
702 T actual;
703 decode(actual);
704
705 if(actual != expected) {
706 throw Decoding_Error(error_msg);
707 }
708
709 return (*this);
710 }

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_bitstring()

BER_Decoder & Botan::BER_Decoder::decode_bitstring ( ASN1_BitString & out,
ASN1_Type type_tag = ASN1_Type::BitString,
ASN1_Class class_tag = ASN1_Class::Universal )

Decode a BIT STRING, retaining the count of unused bits

Parameters
outwhere the value is written
type_tagthe expected type tag
class_tagthe expected class tag

Definition at line 1042 of file ber_dec.cpp.

1042 {
1043 const BER_Object obj = get_next_object();
1044
1045 std::vector<uint8_t> bits;
1046 uint8_t unused_bits = 0;
1047
1048 if(is_constructed(obj.class_tag())) {
1049 obj.assert_is_a(type_tag, class_tag | ASN1_Class::Constructed);
1050 if(m_limits.require_der_encoding()) {
1051 throw BER_Decoding_Error("Detected constructed string encoding in DER structure");
1052 }
1053 bits.reserve(obj.length()); // upper possible bound on the output size
1054 unused_bits = asn1_concat_constructed_bit_string(bits, obj, m_limits, 0);
1055 } else {
1056 unused_bits = asn1_bitstring_unused_bits(obj, type_tag, class_tag, m_limits.require_der_encoding());
1057 bits.assign(obj.bits() + 1, obj.bits() + obj.length());
1058 }
1059
1060 if(unused_bits > 0 && !bits.empty()) {
1061 bits.back() &= static_cast<uint8_t>(0xFF << unused_bits);
1062 }
1063
1064 out = ASN1_BitString(std::move(bits), unused_bits);
1065 return (*this);
1066}

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

Referenced by Botan::Cert_Extension::IPAddressBlocks::IPAddressOrRange< V >::decode_from(), decode_named_bitstring(), and decode_octet_aligned_bitstring().

◆ decode_constrained_integer()

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

Decode a non-negative INTEGER that fits in at most T_bytes bytes

Throws BER_Decoding_Error if the value is negative or too large.

Parameters
type_tagthe expected type tag
class_tagthe expected class tag
T_bytesthe maximum size of the value in bytes, at most 8

Definition at line 748 of file ber_dec.cpp.

748 {
749 if(T_bytes > 8) {
750 throw BER_Decoding_Error("Can't decode small integer over 8 bytes");
751 }
752
753 BigInt integer;
754 decode(integer, type_tag, class_tag);
755
756 if(integer.is_negative()) {
757 throw BER_Decoding_Error("Decoded small integer value was negative");
758 }
759
760 if(integer.bits() > 8 * T_bytes) {
761 throw BER_Decoding_Error("Decoded integer value larger than expected");
762 }
763
764 uint64_t out = 0;
765 for(size_t i = 0; i != 8; ++i) {
766 out = (out << 8) | integer.byte_at(7 - i);
767 }
768
769 return out;
770}

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

Referenced by decode_integer_type().

◆ decode_default()

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

Decode a field carrying an ASN.1 DEFAULT value: if the field is absent out is set to default_value. Unlike decode_optional this is only for fields with a DEFAULT (not bare OPTIONAL fields): when the decoder is configured with Limits::with_default_value_encoding_rejected() and is in DER mode, a field that is present but equal to default_value is rejected, since DER requires such components to be omitted.

Definition at line 569 of file ber_dec.h.

569 {
570 std::optional<T> optval;
571 this->decode_optional(optval, type_tag, class_tag);
572 if(optval.has_value()) {
573 if(m_limits.require_der_encoding() && m_limits.reject_default_value_encoding() &&
574 *optval == default_value) {
575 throw BER_Decoding_Error("DER component encoded with its DEFAULT value");
576 }
577 out = std::move(*optval);
578 } else {
579 out = default_value;
580 }
581 return (*this);
582 }
BER_Decoder & decode_optional(T &out, ASN1_Type type_tag, ASN1_Class class_tag, const T &default_value=T())
Definition ber_dec.h:553

References BER_Decoder(), and decode_optional().

◆ decode_implicit() [1/2]

template<typename T>
BER_Decoder & Botan::BER_Decoder::decode_implicit ( BER_Object obj,
T & out,
ASN1_Type real_type,
ASN1_Class real_class )
inline

Decode an already-extracted BER_Object as if its tag were real_type/real_class. Used to consume IMPLICIT-tagged values whose body matches a different universal type (e.g. a context-specific [8] body that should be parsed as an OID).

Definition at line 640 of file ber_dec.h.

640 {
641 obj.set_tagging(real_type, real_class);
642 push_back(std::move(obj));
643 if constexpr(std::is_base_of_v<ASN1_Object, T>) {
644 // The object was re-tagged above; decode_from checks the real tag itself
645 return decode(out);
646 } else {
647 return decode(out, real_type, real_class);
648 }
649 }
void push_back(const BER_Object &obj)
Definition ber_dec.cpp:600

References BER_Decoder(), decode(), and push_back().

Referenced by Botan::AlternativeName::decode_from(), Botan::Cert_Extension::CRL_Distribution_Points::Distribution_Point::decode_from(), Botan::Cert_Extension::DistributionPointName::decode_from(), decode_implicit(), and decode_optional_implicit().

◆ decode_implicit() [2/2]

template<typename T>
BER_Decoder & Botan::BER_Decoder::decode_implicit ( T & out,
ASN1_Type type_tag,
ASN1_Class class_tag,
ASN1_Type real_type,
ASN1_Class real_class )
inline

Read the next object, requiring it be tagged type_tag/class_tag, and decode it as if its tag were real_type/real_class.

Parameters
outwhere the value is written
type_tagthe expected type tag
class_tagthe expected class tag
real_typethe type tag the contents should be parsed as
real_classthe class tag the contents should be parsed as

Definition at line 662 of file ber_dec.h.

663 {
664 BER_Object obj = get_next_object();
665 obj.assert_is_a(type_tag, class_tag);
666 return decode_implicit(std::move(obj), out, real_type, real_class);
667 }
BER_Decoder & decode_implicit(BER_Object obj, T &out, ASN1_Type real_type, ASN1_Class real_class)
Definition ber_dec.h:640

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

◆ decode_integer_type() [1/2]

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

Decode an INTEGER into an integral type, throwing if it does not fit

Parameters
outwhere the value is written

Definition at line 526 of file ber_dec.h.

526 {
528 }
BER_Decoder & decode_integer_type(T &out)
Definition ber_dec.h:526

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

Decode an INTEGER with an IMPLICIT tagging into an integral type, throwing if it does not fit

Parameters
outwhere the value is written
type_tagthe expected type tag
class_tagthe expected class tag

Definition at line 539 of file ber_dec.h.

539 {
540 out = static_cast<T>(decode_constrained_integer(type_tag, class_tag, sizeof(out)));
541 return (*this);
542 }
uint64_t decode_constrained_integer(ASN1_Type type_tag, ASN1_Class class_tag, size_t T_bytes)
Definition ber_dec.cpp:748

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

◆ decode_list()

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

Decode a constructed object containing a list of homogeneously typed values

Parameters
vecwhere the values are appended
type_tagthe expected type tag of the constructed object
class_tagthe expected class tag of the constructed object

Decode a list of homogeneously typed values

Definition at line 880 of file ber_dec.h.

880 {
881 BER_Decoder list = start_cons(type_tag, class_tag);
882
883 while(list.more_items()) {
884 T value;
885 list.decode(value);
886 vec.push_back(std::move(value));
887 }
888
889 list.end_cons();
890
891 return (*this);
892}
BER_Decoder start_cons(ASN1_Type type_tag, ASN1_Class class_tag)
Definition ber_dec.cpp:614

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_named_bitstring()

BER_Decoder & Botan::BER_Decoder::decode_named_bitstring ( uint64_t & bits,
size_t width,
ASN1_Type type_tag = ASN1_Type::BitString,
ASN1_Class class_tag = ASN1_Class::Universal )

Decode a BIT STRING that is actually a bit set, such as X.509 KeyUsage

The first bit of the encoding becomes the most significant of the width bits of bits. Throws if more than width bits are encoded, or in DER mode if the encoding is not minimal (ie the final bit is unset).

Parameters
bitswhere the bit set is written
widththe number of named bits, at most 64
type_tagthe expected type tag
class_tagthe expected class tag

Definition at line 1068 of file ber_dec.cpp.

1071 {
1072 if(width > 64) {
1073 throw Invalid_Argument("BER_Decoder: Named BIT STRING width is too large");
1074 }
1075
1076 ASN1_BitString bits;
1077 decode_bitstring(bits, type_tag, class_tag);
1078
1079 if(bits.bit_length() > width) {
1080 throw BER_Decoding_Error("Named BIT STRING exceeds declared width");
1081 }
1082
1083 if(m_limits.require_der_encoding() && bits.bit_length() > 0 && !bits.bit_at(bits.bit_length() - 1)) {
1084 throw BER_Decoding_Error("Named BIT STRING is not minimally encoded");
1085 }
1086
1087 uint64_t decoded = 0;
1088 for(size_t bit = 0; bit != bits.bit_length(); ++bit) {
1089 if(bits.bit_at(bit)) {
1090 decoded |= uint64_t(1) << (width - 1 - bit);
1091 }
1092 }
1093
1094 out = decoded;
1095 return (*this);
1096}
BER_Decoder & decode_bitstring(ASN1_BitString &out, ASN1_Type type_tag=ASN1_Type::BitString, ASN1_Class class_tag=ASN1_Class::Universal)
Definition ber_dec.cpp:1042

References BER_Decoder(), Botan::ASN1_BitString::bit_at(), Botan::ASN1_BitString::bit_length(), and decode_bitstring().

◆ decode_null()

BER_Decoder & Botan::BER_Decoder::decode_null ( )

Decode a BER encoded NULL, throwing if the next object is anything else

Definition at line 683 of file ber_dec.cpp.

683 {
684 const BER_Object obj = get_next_object();
685 obj.assert_is_a(ASN1_Type::Null, ASN1_Class::Universal);
686 if(obj.length() > 0) {
687 throw BER_Decoding_Error("NULL object had nonzero size");
688 }
689 return (*this);
690}

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_aligned_bitstring()

template<typename Alloc>
BER_Decoder & Botan::BER_Decoder::decode_octet_aligned_bitstring ( std::vector< uint8_t, Alloc > & out,
ASN1_Type type_tag = ASN1_Type::BitString,
ASN1_Class class_tag = ASN1_Class::Universal )
inline

Decode a BIT STRING, throwing unless it has no unused bits

Parameters
outwhere the bits are written
type_tagthe expected type tag
class_tagthe expected class tag

Definition at line 462 of file ber_dec.h.

464 {
465 ASN1_BitString bits;
466 decode_bitstring(bits, type_tag, class_tag);
467
468 if(bits.unused_bits() != 0) {
469 throw Decoding_Error("Expected octet-aligned BIT STRING");
470 }
471
472 out.assign(bits.bytes().begin(), bits.bytes().end());
473 return (*this);
474 }

References BER_Decoder(), Botan::BitString, Botan::ASN1_BitString::bytes(), decode_bitstring(), Botan::Universal, and Botan::ASN1_BitString::unused_bits().

Referenced by Botan::X509_Object::decode_from(), decode_optional_octet_aligned_bitstring(), Botan::X509::load_key(), and Botan::OCSP::Response::Response().

◆ 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 692 of file ber_dec.cpp.

692 {
695 out = BigInt::from_bytes(out_vec);
696 return (*this);
697}
static BigInt from_bytes(std::span< const uint8_t > bytes)
Definition bigint.cpp:83
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:128

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 > & optval,
ASN1_Type type_tag,
ASN1_Class class_tag )

Decode an OPTIONAL field, setting optval to nullopt if absent

Parameters
optvalwhere the value is written
type_tagthe expected type tag
class_tagthe expected class tag

Decode an OPTIONAL or DEFAULT element

Definition at line 827 of file ber_dec.h.

827 {
828 BER_Object obj = get_next_object();
829
830 if(obj.is_a(type_tag, class_tag)) {
831 T out{};
832 if(class_tag == ASN1_Class::ExplicitContextSpecific) {
833 BER_Decoder(obj, m_limits).decode(out).verify_end();
834 } else {
835 this->push_back(std::move(obj));
836 if constexpr(std::is_base_of_v<ASN1_Object, T>) {
837 // Object types check the tag in decode_from; a re-tagging
838 // implicit override of an object is not supported here
839 this->decode(out);
840 } else {
841 this->decode(out, type_tag, class_tag);
842 }
843 }
844 optval = std::move(out);
845 } else {
846 this->push_back(std::move(obj));
847 optval = std::nullopt;
848 }
849
850 return (*this);
851}

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

Decode an OPTIONAL field, setting out to default_value if absent

Parameters
outwhere the value is written
type_tagthe expected type tag
class_tagthe expected class tag
default_valuethe value used if the field is not present

Definition at line 553 of file ber_dec.h.

553 {
554 std::optional<T> optval;
555 this->decode_optional(optval, type_tag, class_tag);
556 out = optval ? *optval : default_value;
557 return (*this);
558 }

References BER_Decoder(), and decode_optional().

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

◆ decode_optional_field()

template<typename F>
BER_Decoder & Botan::BER_Decoder::decode_optional_field ( uint32_t tag_no,
ASN1_Class class_tag,
F && fn )
inline

Decode an OPTIONAL field identified by a context-specific tag number.

If the next object is tagged [tag_no] with class class_tag, fn is invoked to decode it (fn must consume exactly that object). Otherwise the stream is left unchanged and fn is not called.

For a SEQUENCE of optional tagged fields that (per DER) appear at most once and in increasing tag order: call this once per field in tag order, then end_cons(), which rejects any unconsumed object (i.e. a duplicate, out-of-order, or unknown-tag field).

Definition at line 626 of file ber_dec.h.

626 {
627 if(peek_next_object().is_a(tag_no, class_tag)) {
628 std::forward<F>(fn)(*this);
629 }
630 return (*this);
631 }
const BER_Object & peek_next_object()
Definition ber_dec.cpp:505

References BER_Decoder(), and peek_next_object().

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

◆ 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() )

Decode an OPTIONAL IMPLICIT tagged field, setting out to default_value if absent

Parameters
outwhere the value is written
type_tagthe expected type tag
class_tagthe expected class tag
real_typethe type tag the contents should be parsed as
real_classthe class tag the contents should be parsed as
default_valuethe value used if the field is not present

Decode an OPTIONAL or DEFAULT element with an IMPLICIT tagging

Definition at line 857 of file ber_dec.h.

862 {
863 BER_Object obj = get_next_object();
864
865 if(obj.is_a(type_tag, class_tag)) {
866 decode_implicit(std::move(obj), out, real_type, real_class);
867 } else {
868 // Not what we wanted, push it back on the stream
869 out = default_value;
870 push_back(std::move(obj));
871 }
872
873 return (*this);
874}

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

◆ decode_optional_list()

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

Decode a list of homogeneously typed values if one is present

Parameters
vecwhere the values are appended
type_tagthe expected type tag of the constructed object
class_tagthe expected class tag of the constructed object
Returns
true if the list was present

Decode an optional list of homogeneously typed values

Definition at line 898 of file ber_dec.h.

898 {
899 if(peek_next_object().is_a(type_tag, class_tag)) {
900 decode_list(vec, type_tag, class_tag);
901 return true;
902 }
903
904 return false;
905}
BER_Decoder & decode_list(std::vector< T > &vec, ASN1_Type type_tag=ASN1_Type::Sequence, ASN1_Class class_tag=ASN1_Class::Universal)
Definition ber_dec.h:880

References decode_list(), and peek_next_object().

◆ decode_optional_octet_aligned_bitstring() [1/2]

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

Decode an OPTIONAL BIT STRING with no unused bits, clearing out if it is absent

Parameters
outwhere the bits are written
expected_tagthe expected type tag
class_tagthe expected class tag

Definition at line 800 of file ber_dec.h.

802 {
803 return decode_optional_octet_aligned_bitstring(out, static_cast<uint32_t>(expected_tag), class_tag);
804 }
BER_Decoder & decode_optional_octet_aligned_bitstring(std::vector< uint8_t, Alloc > &out, uint32_t expected_tag, ASN1_Class class_tag=ASN1_Class::ContextSpecific)
Definition ber_dec.h:769

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

◆ decode_optional_octet_aligned_bitstring() [2/2]

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

Decode an OPTIONAL BIT STRING with no unused bits, clearing out if it is absent

Parameters
outwhere the bits are written
expected_tagthe expected tag number
class_tagthe expected class tag

Definition at line 769 of file ber_dec.h.

771 {
772 BER_Object obj = get_next_object();
773
774 const ASN1_Type type_tag = static_cast<ASN1_Type>(expected_tag);
775
776 if(obj.is_a(type_tag, class_tag)) {
777 if(class_tag == ASN1_Class::ExplicitContextSpecific) {
778 BER_Decoder(obj, m_limits).decode_octet_aligned_bitstring(out).verify_end();
779 } else {
780 push_back(std::move(obj));
781 decode_octet_aligned_bitstring(out, type_tag, class_tag);
782 }
783 } else {
784 out.clear();
785 push_back(std::move(obj));
786 }
787
788 return (*this);
789 }
BER_Decoder & decode_octet_aligned_bitstring(std::vector< uint8_t, Alloc > &out, ASN1_Type type_tag=ASN1_Type::BitString, ASN1_Class class_tag=ASN1_Class::Universal)
Definition ber_dec.h:462
ASN1_Type
Definition asn1_obj.h:47

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

Referenced by decode_optional_octet_aligned_bitstring().

◆ 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

Decode an OPTIONAL string type, clearing out if it is absent

Parameters
outwhere the contents are written
real_typethe type tag the contents should be parsed as
expected_tagthe expected type tag
class_tagthe expected class tag

Definition at line 753 of file ber_dec.h.

756 {
757 return decode_optional_string(out, real_type, static_cast<uint32_t>(expected_tag), class_tag);
758 }
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:721

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

Decode an OPTIONAL string type, clearing out if it is absent

Parameters
outwhere the contents are written
real_typethe type tag the contents should be parsed as
expected_tagthe expected tag number
class_tagthe expected class tag

Definition at line 721 of file ber_dec.h.

724 {
725 BER_Object obj = get_next_object();
726
727 const ASN1_Type type_tag = static_cast<ASN1_Type>(expected_tag);
728
729 if(obj.is_a(type_tag, class_tag)) {
730 if(class_tag == ASN1_Class::ExplicitContextSpecific) {
731 BER_Decoder(obj, m_limits).decode(out, real_type).verify_end();
732 } else {
733 push_back(std::move(obj));
734 decode(out, real_type, type_tag, class_tag);
735 }
736 } else {
737 out.clear();
738 push_back(std::move(obj));
739 }
740
741 return (*this);
742 }

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 488 of file ber_dec.cpp.

488 {
489 m_pushed = BER_Object();
490 uint8_t buf = 0;
491 while(m_source->read_byte(buf) != 0) {}
492 return (*this);
493}

References BER_Decoder().

Referenced by Botan::Ed25519_PrivateKey::Ed25519_PrivateKey(), 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 630 of file ber_dec.cpp.

630 {
631 if(m_parent == nullptr) {
632 throw Invalid_State("BER_Decoder::end_cons called with null parent");
633 }
634 if(!m_source->end_of_data() || m_pushed.is_set()) {
635 throw Decoding_Error("BER_Decoder::end_cons called with data left");
636 }
637 return (*m_parent);
638}

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::X509::load_key(), Botan::McEliece_PrivateKey::McEliece_PrivateKey(), Botan::McEliece_PublicKey::McEliece_PublicKey(), Botan::pbes2_decrypt(), Botan::PKCS12::PKCS12(), Botan::pkcs12_pbe_decrypt(), Botan::OCSP::Response::Response(), and Botan::RSA_PublicKey::RSA_PublicKey().

◆ get_next()

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

Get the next object in the data stream, storing it in ber

If EOF, ber is set to an object with type NO_OBJECT.

Definition at line 210 of file ber_dec.h.

210 {
211 ber = get_next_object();
212 return (*this);
213 }

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 516 of file ber_dec.cpp.

516 {
517 BER_Object next;
518
519 if(m_pushed.is_set()) {
520 std::swap(next, m_pushed);
521 return next;
522 }
523
524 for(;;) {
527 decode_tag(m_source, type_tag, class_tag);
528 next.set_tagging(type_tag, class_tag);
529 if(next.is_set() == false) { // no more objects
530 return next;
531 }
532
533 const size_t allow_indef = m_limits.allow_ber_encoding() ? m_limits.max_nested_indefinite_length() : 0;
534 const bool der_mode = m_limits.require_der_encoding();
535 const auto dl = decode_length(m_source, allow_indef, der_mode, is_constructed(class_tag));
536
537 // Per X.690 8.1.5 the only valid EOC encoding is the two-octet
538 // sequence 0x00 0x00. Reject any other length encoding on a tag of
539 // (Eoc, Universal) before we consume the "content" bytes.
540 if(type_tag == ASN1_Type::Eoc && class_tag == ASN1_Class::Universal &&
541 (dl.content_length() != 0 || dl.indefinite_length())) {
542 throw BER_Decoding_Error("EOC marker with non-zero length");
543 }
544
545 if(const auto max_size = m_limits.max_object_size(); max_size && dl.content_length() > *max_size) {
546 throw BER_Decoding_Error("Encoded object exceeds maximum size");
547 }
548
549 if(!m_source->check_available(dl.total_length())) {
550 throw BER_Decoding_Error("Value truncated");
551 }
552
553 uint8_t* out = next.mutable_bits(dl.content_length());
554 if(m_source->read(out, dl.content_length()) != dl.content_length()) {
555 throw BER_Decoding_Error("Value truncated");
556 }
557
558 if(dl.indefinite_length()) {
559 // After reading the data consume the 2-byte EOC
560 uint8_t eoc[2] = {0xFF, 0xFF};
561 if(m_source->read(eoc, 2) != 2 || eoc[0] != 0x00 || eoc[1] != 0x00) {
562 throw BER_Decoding_Error("Missing or malformed EOC marker");
563 }
564 }
565
566 if(next.tagging() == static_cast<uint32_t>(ASN1_Type::Eoc)) {
567 if(m_limits.require_der_encoding()) {
568 throw BER_Decoding_Error("Detected EOC marker in DER structure");
569 }
570 // An EOC marker is only valid as an indefinite-length terminator, which
571 // is consumed above when reading the indefinite-length object. A
572 // standalone EOC is rejected unless the caller opted to tolerate it.
573 if(m_limits.allow_standalone_eoc()) {
574 continue;
575 }
576 throw BER_Decoding_Error("Encountered EOC marker outside of indefinite-length encoding");
577 }
578
579 break;
580 }
581
582 return next;
583}
ASN1_Class
Definition asn1_obj.h:32

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

Referenced by decode(), decode(), decode(), decode(), decode_bitstring(), 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_implicit(), decode_null(), decode_optional(), decode_optional_implicit(), decode_optional_octet_aligned_bitstring(), decode_optional_string(), get_next(), peek_next_object(), Botan::OCSP::Response::Response(), and start_cons().

◆ get_next_octet_string()

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

Decode the next object as an OCTET STRING and return its contents

Definition at line 373 of file ber_dec.h.

373 {
374 std::vector<uint8_t> out_vec;
376 return out_vec;
377 }

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 322 of file ber_dec.h.

324 {
325 const BER_Object obj = get_next_value(sizeof(T), type_tag, class_tag);
326
327 std::memcpy(reinterpret_cast<uint8_t*>(&out), obj.bits(), obj.length());
328
329 return (*this);
330 }
BER_Decoder & get_next_value(T &out, ASN1_Type type_tag, ASN1_Class class_tag=ASN1_Class::ContextSpecific)
Definition ber_dec.h:322

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()

◆ more_items()

bool Botan::BER_Decoder::more_items ( ) const

Return true if there is at least one more item remaining

Definition at line 461 of file ber_dec.cpp.

461 {
462 if(m_source->end_of_data() && !m_pushed.is_set()) {
463 return false;
464 }
465 return true;
466}

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(), Botan::PKCS12::PKCS12(), and Botan::OCSP::Response::Response().

◆ operator=() [1/2]

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

Move assignment

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 505 of file ber_dec.cpp.

505 {
506 if(!m_pushed.is_set()) {
507 m_pushed = get_next_object();
508 }
509
510 return m_pushed;
511}

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::DistributionPointName::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(), Botan::OCSP::SingleResponse::decode_from(), decode_optional_field(), 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 607 of file ber_dec.cpp.

607 {
608 if(m_pushed.is_set()) {
609 throw Invalid_State("BER_Decoder: Only one push back is allowed");
610 }
611 m_pushed = std::move(obj);
612}

◆ 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 600 of file ber_dec.cpp.

600 {
601 if(m_pushed.is_set()) {
602 throw Invalid_State("BER_Decoder: Only one push back is allowed");
603 }
604 m_pushed = obj;
605}

Referenced by decode_implicit(), decode_list(), decode_optional(), decode_optional_implicit(), decode_optional_octet_aligned_bitstring(), 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

Save all the bytes remaining in the source

Parameters
outwhere the remaining bytes are written

Definition at line 338 of file ber_dec.h.

338 {
339 out.clear();
340 for(;;) {
341 if(auto next = this->read_next_byte()) {
342 out.push_back(*next);
343 } else {
344 break;
345 }
346 }
347 return (*this);
348 }

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 )

Start decoding a constructed object, returning a decoder for its contents. The returned decoder must be closed with end_cons().

Parameters
type_tagthe expected type tag
class_tagthe expected class tag

Definition at line 614 of file ber_dec.cpp.

614 {
615 BER_Object obj = get_next_object();
616 obj.assert_is_a(type_tag, class_tag | ASN1_Class::Constructed);
617
618 // In DER mode the elements of a universal SET must appear in sorted order
619 if(m_limits.require_der_encoding() && type_tag == ASN1_Type::Set && class_tag == ASN1_Class::Universal) {
620 verify_set_is_sorted(std::span<const uint8_t>{obj.bits(), obj.length()});
621 }
622
623 BER_Decoder child(std::move(obj), this);
624 return child;
625}

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

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 decoding an IMPLICIT context specific constructed object, returning a decoder for its contents. The returned decoder must be closed with end_cons().

Parameters
tagthe expected context specific tag number

Definition at line 290 of file ber_dec.h.

290 {
292 }

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

Referenced by Botan::Cert_Extension::CRL_Distribution_Points::Distribution_Point::decode_from(), Botan::OCSP::SingleResponse::decode_from(), Botan::PKCS12::PKCS12(), and Botan::OCSP::Response::Response().

◆ start_explicit_context_specific()

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

Start decoding an EXPLICIT context specific constructed object, returning a decoder for its contents. The returned decoder must be closed with end_cons().

Parameters
tagthe expected context specific tag number

Definition at line 301 of file ber_dec.h.

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

◆ start_sequence()

BER_Decoder Botan::BER_Decoder::start_sequence ( )
inline

Start decoding a SEQUENCE, returning a decoder for its contents. The returned decoder must be closed with end_cons().

Definition at line 275 of file ber_dec.h.

References BER_Decoder(), Botan::Sequence, start_cons(), and Botan::Universal.

Referenced by 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::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(), Botan::EC_PrivateKey::EC_PrivateKey(), Botan::X509::load_key(), Botan::McEliece_PrivateKey::McEliece_PrivateKey(), Botan::McEliece_PublicKey::McEliece_PublicKey(), Botan::pbes2_decrypt(), Botan::PKCS12::PKCS12(), Botan::pkcs12_pbe_decrypt(), Botan::OCSP::Response::Response(), Botan::RSA_PrivateKey::RSA_PrivateKey(), Botan::RSA_PublicKey::RSA_PublicKey(), and Botan::TLS::Session::Session().

◆ start_set()

BER_Decoder Botan::BER_Decoder::start_set ( )
inline

Start decoding a SET, returning a decoder for its contents. The returned decoder must be closed with end_cons().

Definition at line 281 of file ber_dec.h.

References BER_Decoder(), Botan::Set, start_cons(), and Botan::Universal.

Referenced by Botan::Attribute::decode_from(), and Botan::X509_DN::decode_from().

◆ 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 478 of file ber_dec.cpp.

478 {
479 if(!m_source->end_of_data() || m_pushed.is_set()) {
480 throw Decoding_Error(err);
481 }
482 return (*this);
483}

References BER_Decoder().


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