8#ifndef BOTAN_BER_DECODER_H_
9#define BOTAN_BER_DECODER_H_
11#include <botan/asn1_obj.h>
12#include <botan/secmem.h>
49 static Limits
BER(
size_t max_nested_indef = 16) {
97 copy.m_allow_standalone_eoc =
true;
118 copy.m_reject_default_value_encoding =
true;
128 Limits(
bool allow_ber,
129 size_t max_nested_indef,
133 m_allow_ber(allow_ber),
134 m_max_nested_indef(max_nested_indef),
140 size_t m_max_nested_indef;
141 bool m_allow_standalone_eoc;
142 std::optional<size_t> m_max_object_size;
143 bool m_reject_default_value_encoding;
156 explicit BER_Decoder(std::span<const uint8_t> buf, Limits limits = Limits::BER());
161 explicit BER_Decoder(DataSource& src, Limits limits = Limits::BER());
242 bool more_items()
const;
321 template <
typename T>
323 requires std::is_standard_layout_v<T> && std::is_trivial_v<T>
327 std::memcpy(
reinterpret_cast<uint8_t*
>(&out), obj.
bits(), obj.
length());
337 template <
typename Alloc>
341 if(
auto next = this->read_next_byte()) {
342 out.push_back(*next);
374 std::vector<uint8_t> out_vec;
385 template <
typename Alloc>
461 template <
typename Alloc>
472 out.assign(bits.
bytes().begin(), bits.
bytes().end());
488 BER_Decoder& decode_named_bitstring(uint64_t& bits,
518 uint64_t decode_constrained_integer(
ASN1_Type type_tag,
ASN1_Class class_tag,
size_t T_bytes);
525 template <
typename T>
538 template <
typename T>
552 template <
typename T>
554 std::optional<T> optval;
556 out = optval ? *optval : default_value;
568 template <
typename T>
570 std::optional<T> optval;
572 if(optval.has_value()) {
573 if(m_limits.require_der_encoding() && m_limits.reject_default_value_encoding() &&
574 *optval == default_value) {
577 out = std::move(*optval);
591 template <
typename T>
605 template <
typename T>
611 const T& default_value = T());
625 template <
typename F>
628 std::forward<F>(fn)(*this);
639 template <
typename T>
641 obj.set_tagging(real_type, real_class);
643 if constexpr(std::is_base_of_v<ASN1_Object, T>) {
647 return decode(out, real_type, real_class);
661 template <
typename T>
676 template <
typename T>
689 template <
typename T>
690 bool decode_optional_list(std::vector<T>& vec,
700 template <
typename T>
705 if(actual != expected) {
720 template <
typename Alloc>
723 uint32_t expected_tag,
729 if(obj.
is_a(type_tag, class_tag)) {
731 BER_Decoder(obj, m_limits).decode(out, real_type).verify_end();
734 decode(out, real_type, type_tag, class_tag);
752 template <
typename Alloc>
768 template <
typename Alloc>
770 uint32_t expected_tag,
776 if(obj.
is_a(type_tag, class_tag)) {
778 BER_Decoder(obj, m_limits).decode_octet_aligned_bitstring(out).verify_end();
799 template <
typename Alloc>
811 std::optional<uint8_t> read_next_byte();
820 std::unique_ptr<DataSource> m_data_src;
830 if(obj.
is_a(type_tag, class_tag)) {
833 BER_Decoder(obj, m_limits).decode(out).verify_end();
836 if constexpr(std::is_base_of_v<ASN1_Object, T>) {
841 this->
decode(out, type_tag, class_tag);
844 optval = std::move(out);
847 optval = std::nullopt;
862 const T& default_value) {
865 if(obj.
is_a(type_tag, class_tag)) {
#define BOTAN_PUBLIC_API(maj, min)
#define BOTAN_DEPRECATED(msg)
#define BOTAN_FUTURE_EXPLICIT
size_t unused_bits() const
std::span< const uint8_t > bytes() const
bool operator==(const Limits &) const =default
static Limits BER(size_t max_nested_indef=16)
Limits with_default_value_encoding_rejected() const
static constexpr size_t DefaultMaxObjectSize
bool reject_default_value_encoding() const
Limits with_standalone_eoc_allowed() const
Limits with_max_object_size(std::optional< size_t > max_object_size) const
size_t max_nested_indefinite_length() const
bool allow_ber_encoding() const
std::optional< size_t > max_object_size() const
bool allow_standalone_eoc() const
bool require_der_encoding() const
BOTAN_FUTURE_EXPLICIT BER_Decoder(BER_Object &&obj)
BER_Decoder(BER_Decoder &&other) noexcept
const BER_Object & peek_next_object()
void push_back(const BER_Object &obj)
BER_Object get_next_object()
BER_Decoder & get_next_value(T &out, ASN1_Type type_tag, ASN1_Class class_tag=ASN1_Class::ContextSpecific)
BER_Decoder & decode_optional_octet_aligned_bitstring(std::vector< uint8_t, Alloc > &out, ASN1_Type expected_tag, ASN1_Class class_tag=ASN1_Class::ContextSpecific)
BER_Decoder & decode_bitstring(ASN1_BitString &out, ASN1_Type type_tag=ASN1_Type::BitString, ASN1_Class class_tag=ASN1_Class::Universal)
BER_Decoder & decode(bool &out)
uint64_t decode_constrained_integer(ASN1_Type type_tag, ASN1_Class class_tag, size_t T_bytes)
BER_Decoder & decode_implicit(T &out, ASN1_Type type_tag, ASN1_Class class_tag, ASN1_Type real_type, ASN1_Class real_class)
BER_Decoder & decode(BigInt &out)
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)
BER_Decoder & raw_bytes(std::vector< uint8_t, Alloc > &out)
BER_Decoder & decode_integer_type(T &out, ASN1_Type type_tag, ASN1_Class class_tag=ASN1_Class::ContextSpecific)
std::vector< uint8_t > get_next_octet_string()
BOTAN_FUTURE_EXPLICIT BER_Decoder(const BER_Object &obj, Limits limits=Limits::BER())
BER_Decoder & decode(std::vector< uint8_t, Alloc > &out, ASN1_Type real_type)
BER_Decoder start_explicit_context_specific(uint32_t tag)
BER_Decoder(const uint8_t buf[], size_t len, Limits limits=Limits::BER())
BER_Decoder & decode_optional_octet_aligned_bitstring(std::vector< uint8_t, Alloc > &out, uint32_t expected_tag, ASN1_Class class_tag=ASN1_Class::ContextSpecific)
BER_Decoder(const BER_Decoder &other)=delete
BER_Decoder start_cons(ASN1_Type type_tag, ASN1_Class class_tag)
BER_Decoder start_sequence()
BER_Decoder & operator=(BER_Decoder &&) noexcept
bool decode_optional_list(std::vector< T > &vec, ASN1_Type type_tag=ASN1_Type::Sequence, ASN1_Class class_tag=ASN1_Class::Universal)
BER_Decoder start_context_specific(uint32_t tag)
BER_Decoder & decode_optional(T &out, ASN1_Type type_tag, ASN1_Class class_tag, const T &default_value=T())
BER_Decoder & decode_implicit(BER_Object obj, T &out, ASN1_Type real_type, ASN1_Class real_class)
BER_Decoder & decode_and_check(const T &expected, std::string_view error_msg)
BER_Decoder & decode(size_t &out)
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)
BER_Decoder & decode_integer_type(T &out)
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())
BER_Decoder & decode_default(T &out, ASN1_Type type_tag, ASN1_Class class_tag, const T &default_value)
BER_Decoder & decode_optional_field(uint32_t tag_no, ASN1_Class class_tag, F &&fn)
BER_Decoder & operator=(const BER_Decoder &)=delete
BER_Decoder & get_next(BER_Object &ber)
BER_Decoder & decode_list(std::vector< T > &vec, ASN1_Type type_tag=ASN1_Type::Sequence, ASN1_Class class_tag=ASN1_Class::Universal)
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)
const uint8_t * bits() const
bool is_a(ASN1_Type type_tag, ASN1_Class class_tag) const
void assert_is_a(ASN1_Type type_tag, ASN1_Class class_tag, std::string_view descr="object") const
@ ExplicitContextSpecific
std::vector< T, secure_allocator< T > > secure_vector