8#include <botan/ber_dec.h>
10#include <botan/bigint.h>
11#include <botan/data_src.h>
12#include <botan/internal/asn1_utils.h>
13#include <botan/internal/int_utils.h>
14#include <botan/internal/loadstor.h>
30 auto b = ber->read_byte();
38 if((*b & 0x1F) != 0x1F) {
60 if((tag_buf >> 25) != 0) {
67 if(tag_bytes == 1 && (*b & 0x7F) == 0) {
71 tag_buf = (tag_buf << 7) | (*b & 0x7F);
72 if((*b & 0x80) == 0) {
96size_t find_eoc(
DataSource* src,
size_t base_offset,
size_t allow_indef);
105class BerDecodedLength final {
107 BerDecodedLength(
size_t content_length,
size_t field_length) :
108 BerDecodedLength(content_length, field_length, false) {}
110 static BerDecodedLength indefinite(
size_t content_length,
size_t field_length) {
111 return BerDecodedLength(content_length, field_length,
true);
114 size_t content_length()
const {
return m_content_length; }
117 size_t total_length()
const {
return m_indefinite ? m_content_length + 2 : m_content_length; }
119 size_t field_length()
const {
return m_field_length; }
121 bool indefinite_length()
const {
return m_indefinite; }
124 BerDecodedLength(
size_t content_length,
size_t field_length,
bool indefinite) :
125 m_content_length(content_length), m_field_length(field_length), m_indefinite(indefinite) {}
127 size_t m_content_length;
128 size_t m_field_length;
135BerDecodedLength decode_length(
DataSource* ber,
size_t allow_indef,
bool der_mode,
bool constructed) {
137 if(ber->read_byte(b) == 0) {
140 if((b & 0x80) == 0) {
141 return BerDecodedLength(b, 1);
144 const size_t num_length_bytes = (b & 0x7F);
145 if(num_length_bytes > 4) {
149 const size_t field_size = 1 + num_length_bytes;
151 if(num_length_bytes == 0) {
154 }
else if(!constructed) {
156 throw BER_Decoding_Error(
"Indefinite-length encoding used with non-constructed type");
157 }
else if(allow_indef == 0) {
158 throw BER_Decoding_Error(
"Nested EOC markers too deep, rejecting to avoid stack exhaustion");
162 const size_t eoc_len = find_eoc(ber, 0, allow_indef - 1);
166 return BerDecodedLength::indefinite(eoc_len - 2, field_size);
172 for(
size_t i = 0; i != num_length_bytes; ++i) {
173 if(ber->read_byte(b) == 0) {
177 length = (length << 8) | b;
185 if(num_length_bytes > 1 && length < (
size_t(1) << ((num_length_bytes - 1) * 8))) {
190 return BerDecodedLength(length, field_size);
199 if(src->peek(&b, 1, offset) == 0) {
205 if((b & 0x1F) != 0x1F) {
218 size_t tag_bytes = 1;
219 uint32_t tag_buf = 0;
222 if(src->peek(&b, 1, offset + tag_bytes) == 0) {
226 if((tag_buf >> 25) != 0) {
233 if(tag_bytes == 1 && (b & 0x7F) == 0) {
237 tag_buf = (tag_buf << 7) | (b & 0x7F);
238 if((b & 0x80) == 0) {
265 DataSource* src,
size_t offset,
size_t& field_size,
size_t allow_indef,
bool constructed,
bool der_mode) {
267 if(src->peek(&b, 1, offset) == 0) {
272 if((b & 0x80) == 0) {
276 const size_t num_length_bytes = (b & 0x7F);
277 field_size += num_length_bytes;
282 if(num_length_bytes == 0) {
289 throw BER_Decoding_Error(
"Indefinite-length encoding used with non-constructed type");
291 if(allow_indef == 0) {
292 throw BER_Decoding_Error(
"Nested EOC markers too deep, rejecting to avoid stack exhaustion");
294 return find_eoc(src, offset + 1, allow_indef - 1);
298 for(
size_t i = 0; i < num_length_bytes; ++i) {
299 if(src->peek(&b, 1, offset + 1 + i) == 0) {
305 length = (length << 8) | b;
314size_t find_eoc(
DataSource* src,
size_t base_offset,
size_t allow_indef) {
315 size_t offset = base_offset;
320 const size_t tag_size = peek_tag(src, offset, type_tag, class_tag);
325 size_t length_size = 0;
326 const size_t item_size =
327 peek_length(src, offset + tag_size, length_size, allow_indef, is_constructed(class_tag),
false);
329 if(
auto new_offset =
checked_add(offset, tag_size, length_size, item_size)) {
330 offset = new_offset.value();
337 if(length_size != 1 || item_size != 0) {
344 return offset - base_offset;
347class DataSource_BERObject final :
public DataSource {
349 size_t read(uint8_t out[],
size_t length)
override {
351 const size_t got = std::min<size_t>(m_obj.length() - m_offset, length);
352 copy_mem(out, m_obj.bits() + m_offset, got);
357 size_t peek(uint8_t out[],
size_t length,
size_t peek_offset)
const override {
359 const size_t bytes_left = m_obj.length() - m_offset;
361 if(peek_offset >= bytes_left) {
365 const size_t got = std::min(bytes_left - peek_offset, length);
366 copy_mem(out, m_obj.bits() + m_offset + peek_offset, got);
370 bool check_available(
size_t n)
override {
372 return (n <= (m_obj.length() - m_offset));
375 bool end_of_data()
const override {
return get_bytes_read() == m_obj.length(); }
377 size_t get_bytes_read()
const override {
return m_offset; }
379 explicit DataSource_BERObject(BER_Object&& obj) : m_obj(std::move(obj)) {}
390class DataSource_Span final :
public DataSource {
392 size_t read(uint8_t out[],
size_t length)
override {
393 const size_t got = std::min(m_buf.size() - m_offset, length);
394 copy_mem(out, m_buf.data() + m_offset, got);
399 size_t peek(uint8_t out[],
size_t length,
size_t peek_offset)
const override {
400 if(peek_offset >= m_buf.size() - m_offset) {
403 const size_t got = std::min(m_buf.size() - m_offset - peek_offset, length);
404 copy_mem(out, m_buf.data() + m_offset + peek_offset, got);
408 bool check_available(
size_t n)
override {
return n <= (m_buf.size() - m_offset); }
410 bool end_of_data()
const override {
return m_offset == m_buf.size(); }
412 size_t get_bytes_read()
const override {
return m_offset; }
414 explicit DataSource_Span(std::span<const uint8_t> buf) : m_buf(buf) {}
417 std::span<const uint8_t> m_buf;
426void verify_set_is_sorted(std::span<const uint8_t> content) {
427 DataSource_Span src(content);
429 std::optional<std::span<const uint8_t>> prev;
431 while(offset < content.size()) {
434 const size_t tag_size = peek_tag(&src, offset, type_tag, class_tag);
436 size_t length_size = 0;
437 const size_t item_size =
438 peek_length(&src, offset + tag_size, length_size, 0, is_constructed(class_tag),
true);
440 const auto end =
checked_add(offset, tag_size, length_size, item_size);
441 if(!end || *end > content.size()) {
445 const auto elem = content.subspan(offset, *end - offset);
446 if(prev && std::lexicographical_compare(elem.begin(), elem.end(), prev->begin(), prev->end())) {
462 if(m_source->end_of_data() && !m_pushed.is_set()) {
472 return verify_end(
"BER_Decoder::verify_end called, but data remains");
479 if(!m_source->end_of_data() || m_pushed.is_set()) {
491 while(m_source->read_byte(buf) != 0) {}
495std::optional<uint8_t> BER_Decoder::read_next_byte() {
506 if(!m_pushed.is_set()) {
519 if(m_pushed.is_set()) {
520 std::swap(next, m_pushed);
527 decode_tag(m_source, type_tag, class_tag);
528 next.set_tagging(type_tag, class_tag);
529 if(next.
is_set() ==
false) {
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));
541 (dl.content_length() != 0 || dl.indefinite_length())) {
545 if(
const auto max_size = m_limits.max_object_size(); max_size && dl.content_length() > *max_size) {
549 if(!m_source->check_available(dl.total_length())) {
553 uint8_t* out = next.mutable_bits(dl.content_length());
554 if(m_source->read(out, dl.content_length()) != dl.content_length()) {
558 if(dl.indefinite_length()) {
560 uint8_t eoc[2] = {0xFF, 0xFF};
561 if(m_source->read(eoc, 2) != 2 || eoc[0] != 0x00 || eoc[1] != 0x00) {
567 if(m_limits.require_der_encoding()) {
573 if(m_limits.allow_standalone_eoc()) {
576 throw BER_Decoding_Error(
"Encountered EOC marker outside of indefinite-length encoding");
589 if(obj.
length() != sizeofT) {
591 "; Output type size is " + std::to_string(sizeofT));
601 if(m_pushed.is_set()) {
602 throw Invalid_State(
"BER_Decoder: Only one push back is allowed");
608 if(m_pushed.is_set()) {
609 throw Invalid_State(
"BER_Decoder: Only one push back is allowed");
611 m_pushed = std::move(obj);
620 verify_set_is_sorted(std::span<const uint8_t>{obj.
bits(), obj.
length()});
631 if(m_parent ==
nullptr) {
632 throw Invalid_State(
"BER_Decoder::end_cons called with null parent");
634 if(!m_source->end_of_data() || m_pushed.is_set()) {
635 throw Decoding_Error(
"BER_Decoder::end_cons called with data left");
641 m_limits(parent != nullptr ? parent->limits() :
BER_Decoder::Limits::BER()), m_parent(parent) {
642 m_data_src = std::make_unique<DataSource_BERObject>(std::move(obj));
643 m_source = m_data_src.get();
647 m_data_src = std::make_unique<DataSource_BERObject>(std::move(obj));
648 m_source = m_data_src.get();
660 m_data_src = std::make_unique<DataSource_Memory>(buf);
661 m_source = m_data_src.get();
674 throw Not_Implemented(
"BER_Decoder::decode(ASN1_Object) does not support implicit tagged decoding");
676 obj.decode_from(*
this);
710 const uint8_t val = obj.
bits()[0];
713 if(m_limits.require_der_encoding() && val != 0x00 && val != 0xFF) {
717 out = (val != 0) ?
true :
false;
727 decode(integer, type_tag, class_tag);
729 if(integer.
signum() < 0) {
733 if(integer.
bits() > 32) {
738 for(
size_t i = 0; i != 4; ++i) {
739 out = (out << 8) | integer.
byte_at(3 - i);
754 decode(integer, type_tag, class_tag);
760 if(integer.
bits() > 8 * T_bytes) {
765 for(
size_t i = 0; i != 8; ++i) {
766 out = (out << 8) | integer.
byte_at(7 - i);
785 if(m_limits.require_der_encoding()) {
787 if(obj.
bits()[0] == 0x00 && (obj.
bits()[1] & 0x80) == 0) {
790 if(obj.
bits()[0] == 0xFF && (obj.
bits()[1] & 0x80) != 0) {
802 if(contents.empty()) {
808 const bool negative = (contents[0] & 0x80) == 0x80;
812 for(
size_t i = vec.size(); i > 0; --i) {
813 const bool gt0 = (vec[i - 1] > 0);
819 for(
auto&
byte : vec) {
844constexpr size_t ALLOWED_CONSTRUCTED_STRING_NESTING = 2;
853template <
typename Alloc>
854void asn1_concat_constructed_octet_string(std::vector<uint8_t, Alloc>& buffer,
855 const BER_Object& obj,
856 const BER_Decoder::Limits& limits,
858 if(depth >= ALLOWED_CONSTRUCTED_STRING_NESTING) {
859 throw BER_Decoding_Error(
"Constructed OCTET STRING is too deeply nested");
863 while(segments.more_items()) {
864 const BER_Object seg = segments.get_next_object();
866 buffer.insert(buffer.end(), seg.bits(), seg.bits() + seg.length());
868 asn1_concat_constructed_octet_string(buffer, seg, limits, depth + 1);
881template <
typename Alloc>
882uint8_t asn1_concat_constructed_bit_string(std::vector<uint8_t, Alloc>& buffer,
886 if(depth >= ALLOWED_CONSTRUCTED_STRING_NESTING) {
890 uint8_t unused_bits = 0;
893 while(segments.more_items()) {
894 if(unused_bits != 0) {
895 throw BER_Decoding_Error(
"Constructed BIT STRING has unused bits before the final segment");
898 const BER_Object seg = segments.get_next_object();
900 if(seg.length() == 0) {
903 unused_bits = seg.bits()[0];
904 if(unused_bits >= 8) {
907 if(seg.length() == 1 && unused_bits != 0) {
910 buffer.insert(buffer.end(), seg.bits() + 1, seg.bits() + seg.length());
912 unused_bits = asn1_concat_constructed_bit_string(buffer, seg, limits, depth + 1);
921template <
typename Alloc>
922void asn1_decode_binary_string(std::vector<uint8_t, Alloc>& buffer,
930 if(is_constructed(obj)) {
933 if(limits.require_der_encoding()) {
938 std::vector<uint8_t, Alloc>
concat;
939 concat.reserve(obj.length());
941 asn1_concat_constructed_octet_string(
concat, obj, limits, 0);
943 asn1_concat_constructed_bit_string(
concat, obj, limits, 0);
945 buffer = std::move(
concat);
949 obj.assert_is_a(type_tag, class_tag);
952 buffer.assign(obj.bits(), obj.bits() + obj.length());
954 if(obj.length() == 0) {
958 const uint8_t unused_bits = obj.bits()[0];
960 if(unused_bits >= 8) {
965 if(unused_bits > 0 && obj.length() < 2) {
970 if(limits.require_der_encoding() && unused_bits > 0) {
971 const uint8_t last_byte = obj.bits()[obj.length() - 1];
972 if((last_byte & ((1 << unused_bits) - 1)) != 0) {
973 throw BER_Decoding_Error(
"Detected non-zero padding bits in BIT STRING in DER structure");
977 buffer.resize(obj.length() - 1);
979 if(obj.length() > 1) {
980 copy_mem(buffer.data(), obj.bits() + 1, obj.length() - 1);
986 obj.assert_is_a(type_tag, class_tag);
989 if(obj.length() == 0) {
993 const uint8_t unused_bits = obj.bits()[0];
995 if(unused_bits >= 8) {
999 if(obj.length() == 1 && unused_bits != 0) {
1003 if(require_der && unused_bits > 0) {
1004 const uint8_t last_byte = obj.bits()[obj.length() - 1];
1005 if((last_byte & ((1 << unused_bits) - 1)) != 0) {
1006 throw BER_Decoding_Error(
"Detected non-zero padding bits in BIT STRING in DER structure");
1023 throw BER_Bad_Tag(
"Bad tag for {BIT,OCTET} STRING",
static_cast<uint32_t
>(real_type));
1026 asn1_decode_binary_string(buffer,
get_next_object(), real_type, type_tag, class_tag, m_limits);
1035 throw BER_Bad_Tag(
"Bad tag for {BIT,OCTET} STRING",
static_cast<uint32_t
>(real_type));
1038 asn1_decode_binary_string(buffer,
get_next_object(), real_type, type_tag, class_tag, m_limits);
1045 std::vector<uint8_t> bits;
1046 uint8_t unused_bits = 0;
1050 if(m_limits.require_der_encoding()) {
1053 bits.reserve(obj.
length());
1054 unused_bits = asn1_concat_constructed_bit_string(bits, obj, m_limits, 0);
1056 unused_bits = asn1_bitstring_unused_bits(obj, type_tag, class_tag, m_limits.require_der_encoding());
1060 if(unused_bits > 0 && !bits.empty()) {
1061 bits.back() &=
static_cast<uint8_t
>(0xFF << unused_bits);
1073 throw Invalid_Argument(
"BER_Decoder: Named BIT STRING width is too large");
1087 uint64_t decoded = 0;
1088 for(
size_t bit = 0; bit != bits.
bit_length(); ++bit) {
1090 decoded |= uint64_t(1) << (width - 1 - bit);
1106 DataSource_Span src(bytes);
1110 const size_t tag_bytes = decode_tag(&src, type_tag, class_tag);
1112 if(type_tag != expected_type || class_tag != expected_class) {
1116 const auto dl = decode_length(&src, 0,
true, is_constructed(expected_class));
1118 const size_t header_bytes = tag_bytes + dl.field_length();
1119 if(header_bytes > bytes.size()) {
1122 return dl.content_length() == bytes.size() - header_bytes;
#define BOTAN_ASSERT_NOMSG(expr)
bool bit_at(size_t bit) const
size_t bit_length() const
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)
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_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 & verify_end()
BER_Decoder(const uint8_t buf[], size_t len, Limits limits=Limits::BER())
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()
BER_Decoder & operator=(const BER_Decoder &)=delete
const uint8_t * bits() const
void assert_is_a(ASN1_Type type_tag, ASN1_Class class_tag, std::string_view descr="object") const
std::span< const uint8_t > data() const
ASN1_Class class_tag() const
static BigInt from_bytes(std::span< const uint8_t > bytes)
uint8_t byte_at(size_t n) const
void _assign_from_bytes(std::span< const uint8_t > bytes)
size_t read_byte(uint8_t &out)
bool is_single_der_object(std::span< const uint8_t > bytes, ASN1_Type expected_type, ASN1_Class expected_class)
BigInt integer_from_contents(std::span< const uint8_t > contents)
bool is_der_sequence_header(std::span< const uint8_t > bytes)
constexpr uint8_t get_byte(T input)
constexpr std::optional< T > checked_add(T a, T b)
constexpr void copy_mem(T *out, const T *in, size_t n)
constexpr auto concat(Rs &&... ranges)
std::vector< T, secure_allocator< T > > secure_vector
std::uint8_t byte
Unsigned 8 bit integer; retained for compatibility with older versions.