8#include <botan/ber_dec.h>
9#include <botan/bigint.h>
10#include <botan/internal/loadstor.h>
11#include <botan/internal/safeint.h>
22const size_t ALLOWED_EOC_NESTINGS = 16;
30 if(!ber->read_byte(
b))
37 if((
b & 0x1F) != 0x1F)
50 if(!ber->read_byte(
b))
51 throw BER_Decoding_Error(
"Long-form tag truncated");
52 if(tag_buf & 0xFF000000)
53 throw BER_Decoding_Error(
"Long-form tag overflowed 32 bits");
55 tag_buf = (tag_buf << 7) | (
b & 0x7F);
56 if((
b & 0x80) == 0)
break;
65size_t find_eoc(DataSource* src,
size_t allow_indef);
70size_t decode_length(DataSource* ber,
size_t& field_size,
size_t allow_indef)
73 if(!ber->read_byte(
b))
74 throw BER_Decoding_Error(
"Length field not found");
79 field_size += (
b & 0x7F);
81 throw BER_Decoding_Error(
"Length field is too large");
87 throw BER_Decoding_Error(
"Nested EOC markers too deep, rejecting to avoid stack exhaustion");
91 return find_eoc(ber, allow_indef - 1);
97 for(
size_t i = 0; i != field_size - 1; ++i)
99 if(get_byte<0>(length) != 0)
100 throw BER_Decoding_Error(
"Field length overflow");
101 if(!ber->read_byte(
b))
102 throw BER_Decoding_Error(
"Corrupted length field");
103 length = (length << 8) |
b;
111size_t find_eoc(DataSource* ber,
size_t allow_indef)
117 const size_t got = ber->peek(buffer.data(), buffer.size(), data.size());
121 data += std::make_pair(buffer.data(), got);
124 DataSource_Memory source(data);
132 size_t tag_size = decode_tag(&source, type_tag, class_tag);
136 size_t length_size = 0;
137 size_t item_size = decode_length(&source, length_size, allow_indef);
138 source.discard_next(item_size);
150class DataSource_BERObject
final :
public DataSource
153 size_t read(uint8_t out[],
size_t length)
override
156 const size_t got = std::min<size_t>(m_obj.length() - m_offset, length);
157 copy_mem(out, m_obj.bits() + m_offset, got);
162 size_t peek(uint8_t out[],
size_t length,
size_t peek_offset)
const override
165 const size_t bytes_left = m_obj.length() - m_offset;
167 if(peek_offset >= bytes_left)
170 const size_t got = std::min(bytes_left - peek_offset, length);
171 copy_mem(out, m_obj.bits() + peek_offset, got);
175 bool check_available(
size_t n)
override
178 return (n <= (m_obj.length() - m_offset));
181 bool end_of_data()
const override
183 return get_bytes_read() == m_obj.length();
186 size_t get_bytes_read()
const override {
return m_offset; }
188 explicit DataSource_BERObject(BER_Object&& obj) : m_obj(
std::move(obj)), m_offset(0) {}
212 return verify_end(
"BER_Decoder::verify_end called, but data remains");
245 std::swap(next, m_pushed);
253 decode_tag(m_source, type_tag, class_tag);
254 next.set_tagging(type_tag, class_tag);
255 if(next.
is_set() ==
false)
259 const size_t length = decode_length(m_source, field_size, ALLOWED_EOC_NESTINGS);
263 uint8_t* out = next.mutable_bits(length);
264 if(m_source->
read(out, length) != length)
282 throw Invalid_State(
"BER_Decoder: Only one push back is allowed");
289 throw Invalid_State(
"BER_Decoder: Only one push back is allowed");
290 m_pushed = std::move(obj);
306 throw Invalid_State(
"BER_Decoder::end_cons called with null parent");
308 throw Decoding_Error(
"BER_Decoder::end_cons called with data left");
314 m_data_src.reset(
new DataSource_BERObject(std::move(obj)));
315 m_source = m_data_src.get();
333 m_source = m_data_src.get();
342 m_source = m_data_src.get();
351 m_source = m_data_src.get();
359 m_source = other.m_source;
362 std::swap(m_data_src, other.m_data_src);
363 m_parent = other.m_parent;
408 out = (obj.
bits()[0]) ?
true :
false;
420 decode(integer, type_tag, class_tag);
425 if(integer.
bits() > 32)
429 for(
size_t i = 0; i != 4; ++i)
430 out = (out << 8) | integer.
byte_at(3-i);
446 decode(integer, type_tag, class_tag);
448 if(integer.
bits() > 8*T_bytes)
452 for(
size_t i = 0; i != 8; ++i)
453 out = (out << 8) | integer.
byte_at(7-i);
474 const bool negative = (obj.
bits()[0] & 0x80) ?
true :
false;
479 for(
size_t i = obj.
length(); i > 0; --i)
482 for(
size_t i = 0; i != obj.
length(); ++i)
484 out =
BigInt(vec.data(), vec.size());
498template<
typename Alloc>
499void asn1_decode_binary_string(std::vector<uint8_t, Alloc>& buffer,
514 throw BER_Decoding_Error(
"Invalid BIT STRING");
515 if(obj.
bits()[0] >= 8)
516 throw BER_Decoding_Error(
"Bad number of unused bits in BIT STRING");
518 buffer.resize(obj.
length() - 1);
535 throw BER_Bad_Tag(
"Bad tag for {BIT,OCTET} STRING",
static_cast<uint32_t
>(real_type));
537 asn1_decode_binary_string(buffer,
get_next_object(), real_type, type_tag, class_tag);
546 throw BER_Bad_Tag(
"Bad tag for {BIT,OCTET} STRING",
static_cast<uint32_t
>(real_type));
548 asn1_decode_binary_string(buffer,
get_next_object(), real_type, type_tag, class_tag);
#define BOTAN_ASSERT_NOMSG(expr)
virtual void decode_from(BER_Decoder &from)=0
BER_Decoder(const uint8_t buf[], size_t len)
void push_back(const BER_Object &obj)
BER_Object get_next_object()
BER_Decoder & decode(bool &out)
uint64_t decode_constrained_integer(ASN1_Type type_tag, ASN1_Class class_tag, size_t T_bytes)
BER_Decoder & verify_end()
BER_Decoder start_cons(ASN1_Type type_tag, ASN1_Class class_tag)
BER_Decoder & discard_remaining()
BER_Decoder & decode_octet_string_bigint(BigInt &b)
BER_Decoder & decode_null()
const uint8_t * bits() const
void assert_is_a(ASN1_Type type_tag, ASN1_Class class_tag, const std::string &descr="object") const
static BigInt decode(const uint8_t buf[], size_t length)
uint8_t byte_at(size_t n) const
size_t read_byte(uint8_t &out)
virtual size_t read(uint8_t out[], size_t length)=0
virtual bool check_available(size_t n)=0
virtual bool end_of_data() const =0
int(* final)(unsigned char *, CTX *)
#define BOTAN_DEFAULT_BUFFER_SIZE
constexpr void copy_mem(T *out, const T *in, size_t n)
std::vector< T, secure_allocator< T > > secure_vector
#define BOTAN_CHECKED_ADD(x, y)