Botan 3.4.0
Crypto and TLS for C&
ber_dec.cpp
Go to the documentation of this file.
1/*
2* BER Decoder
3* (C) 1999-2008,2015,2017,2018 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#include <botan/ber_dec.h>
9
10#include <botan/bigint.h>
11#include <botan/internal/loadstor.h>
12#include <botan/internal/safeint.h>
13#include <memory>
14
15namespace Botan {
16
17namespace {
18
19/*
20* This value is somewhat arbitrary. OpenSSL allows up to 128 nested
21* indefinite length sequences. If you increase this, also increase the
22* limit in the test in test_asn1.cpp
23*/
24const size_t ALLOWED_EOC_NESTINGS = 16;
25
26/*
27* BER decode an ASN.1 type tag
28*/
29size_t decode_tag(DataSource* ber, ASN1_Type& type_tag, ASN1_Class& class_tag) {
30 uint8_t b;
31 if(!ber->read_byte(b)) {
32 type_tag = ASN1_Type::NoObject;
33 class_tag = ASN1_Class::NoObject;
34 return 0;
35 }
36
37 if((b & 0x1F) != 0x1F) {
38 type_tag = ASN1_Type(b & 0x1F);
39 class_tag = ASN1_Class(b & 0xE0);
40 return 1;
41 }
42
43 size_t tag_bytes = 1;
44 class_tag = ASN1_Class(b & 0xE0);
45
46 size_t tag_buf = 0;
47 while(true) {
48 if(!ber->read_byte(b)) {
49 throw BER_Decoding_Error("Long-form tag truncated");
50 }
51 if(tag_buf & 0xFF000000) {
52 throw BER_Decoding_Error("Long-form tag overflowed 32 bits");
53 }
54 ++tag_bytes;
55 tag_buf = (tag_buf << 7) | (b & 0x7F);
56 if((b & 0x80) == 0) {
57 break;
58 }
59 }
60 type_tag = ASN1_Type(tag_buf);
61 return tag_bytes;
62}
63
64/*
65* Find the EOC marker
66*/
67size_t find_eoc(DataSource* src, size_t allow_indef);
68
69/*
70* BER decode an ASN.1 length field
71*/
72size_t decode_length(DataSource* ber, size_t& field_size, size_t allow_indef) {
73 uint8_t b;
74 if(!ber->read_byte(b)) {
75 throw BER_Decoding_Error("Length field not found");
76 }
77 field_size = 1;
78 if((b & 0x80) == 0) {
79 return b;
80 }
81
82 field_size += (b & 0x7F);
83 if(field_size > 5) {
84 throw BER_Decoding_Error("Length field is too large");
85 }
86
87 if(field_size == 1) {
88 if(allow_indef == 0) {
89 throw BER_Decoding_Error("Nested EOC markers too deep, rejecting to avoid stack exhaustion");
90 } else {
91 return find_eoc(ber, allow_indef - 1);
92 }
93 }
94
95 size_t length = 0;
96
97 for(size_t i = 0; i != field_size - 1; ++i) {
98 if(get_byte<0>(length) != 0) {
99 throw BER_Decoding_Error("Field length overflow");
100 }
101 if(!ber->read_byte(b)) {
102 throw BER_Decoding_Error("Corrupted length field");
103 }
104 length = (length << 8) | b;
105 }
106 return length;
107}
108
109/*
110* Find the EOC marker
111*/
112size_t find_eoc(DataSource* ber, size_t allow_indef) {
113 secure_vector<uint8_t> buffer(BOTAN_DEFAULT_BUFFER_SIZE), data;
114
115 while(true) {
116 const size_t got = ber->peek(buffer.data(), buffer.size(), data.size());
117 if(got == 0) {
118 break;
119 }
120
121 data += std::make_pair(buffer.data(), got);
122 }
123
124 DataSource_Memory source(data);
125 data.clear();
126
127 size_t length = 0;
128 while(true) {
129 ASN1_Type type_tag;
130 ASN1_Class class_tag;
131 size_t tag_size = decode_tag(&source, type_tag, class_tag);
132 if(type_tag == ASN1_Type::NoObject) {
133 break;
134 }
135
136 size_t length_size = 0;
137 size_t item_size = decode_length(&source, length_size, allow_indef);
138 source.discard_next(item_size);
139
140 length = BOTAN_CHECKED_ADD(length, item_size);
141 length = BOTAN_CHECKED_ADD(length, tag_size);
142 length = BOTAN_CHECKED_ADD(length, length_size);
143
144 if(type_tag == ASN1_Type::Eoc && class_tag == ASN1_Class::Universal) {
145 break;
146 }
147 }
148 return length;
149}
150
151class DataSource_BERObject final : public DataSource {
152 public:
153 size_t read(uint8_t out[], size_t length) override {
154 BOTAN_ASSERT_NOMSG(m_offset <= m_obj.length());
155 const size_t got = std::min<size_t>(m_obj.length() - m_offset, length);
156 copy_mem(out, m_obj.bits() + m_offset, got);
157 m_offset += got;
158 return got;
159 }
160
161 size_t peek(uint8_t out[], size_t length, size_t peek_offset) const override {
162 BOTAN_ASSERT_NOMSG(m_offset <= m_obj.length());
163 const size_t bytes_left = m_obj.length() - m_offset;
164
165 if(peek_offset >= bytes_left) {
166 return 0;
167 }
168
169 const size_t got = std::min(bytes_left - peek_offset, length);
170 copy_mem(out, m_obj.bits() + m_offset + peek_offset, got);
171 return got;
172 }
173
174 bool check_available(size_t n) override {
175 BOTAN_ASSERT_NOMSG(m_offset <= m_obj.length());
176 return (n <= (m_obj.length() - m_offset));
177 }
178
179 bool end_of_data() const override { return get_bytes_read() == m_obj.length(); }
180
181 size_t get_bytes_read() const override { return m_offset; }
182
183 explicit DataSource_BERObject(BER_Object&& obj) : m_obj(std::move(obj)), m_offset(0) {}
184
185 private:
186 BER_Object m_obj;
187 size_t m_offset;
188};
189
190} // namespace
191
192/*
193* Check if more objects are there
194*/
196 if(m_source->end_of_data() && !m_pushed.is_set()) {
197 return false;
198 }
199 return true;
200}
201
202/*
203* Verify that no bytes remain in the source
204*/
206 return verify_end("BER_Decoder::verify_end called, but data remains");
207}
208
209/*
210* Verify that no bytes remain in the source
211*/
212BER_Decoder& BER_Decoder::verify_end(std::string_view err) {
213 if(!m_source->end_of_data() || m_pushed.is_set()) {
214 throw Decoding_Error(err);
215 }
216 return (*this);
217}
218
219/*
220* Discard all the bytes remaining in the source
221*/
223 uint8_t buf;
224 while(m_source->read_byte(buf)) {}
225 return (*this);
226}
227
228/*
229* Return the BER encoding of the next object
230*/
232 BER_Object next;
233
234 if(m_pushed.is_set()) {
235 std::swap(next, m_pushed);
236 return next;
237 }
238
239 for(;;) {
240 ASN1_Type type_tag;
241 ASN1_Class class_tag;
242 decode_tag(m_source, type_tag, class_tag);
243 next.set_tagging(type_tag, class_tag);
244 if(next.is_set() == false) { // no more objects
245 return next;
246 }
247
248 size_t field_size;
249 const size_t length = decode_length(m_source, field_size, ALLOWED_EOC_NESTINGS);
250 if(!m_source->check_available(length)) {
251 throw BER_Decoding_Error("Value truncated");
252 }
253
254 uint8_t* out = next.mutable_bits(length);
255 if(m_source->read(out, length) != length) {
256 throw BER_Decoding_Error("Value truncated");
257 }
258
259 if(next.tagging() == static_cast<uint32_t>(ASN1_Type::Eoc)) {
260 continue;
261 } else {
262 break;
263 }
264 }
265
266 return next;
267}
268
269/*
270* Push a object back into the stream
271*/
273 if(m_pushed.is_set()) {
274 throw Invalid_State("BER_Decoder: Only one push back is allowed");
275 }
276 m_pushed = obj;
277}
278
280 if(m_pushed.is_set()) {
281 throw Invalid_State("BER_Decoder: Only one push back is allowed");
282 }
283 m_pushed = std::move(obj);
284}
285
288 obj.assert_is_a(type_tag, class_tag | ASN1_Class::Constructed);
289 return BER_Decoder(std::move(obj), this);
290}
291
292/*
293* Finish decoding a CONSTRUCTED type
294*/
296 if(!m_parent) {
297 throw Invalid_State("BER_Decoder::end_cons called with null parent");
298 }
299 if(!m_source->end_of_data()) {
300 throw Decoding_Error("BER_Decoder::end_cons called with data left");
301 }
302 return (*m_parent);
303}
304
306 m_data_src = std::make_unique<DataSource_BERObject>(std::move(obj));
307 m_source = m_data_src.get();
308 m_parent = parent;
309}
310
311/*
312* BER_Decoder Constructor
313*/
315 m_source = &src;
316}
317
318/*
319* BER_Decoder Constructor
320 */
321BER_Decoder::BER_Decoder(const uint8_t data[], size_t length) {
322 m_data_src = std::make_unique<DataSource_Memory>(data, length);
323 m_source = m_data_src.get();
324}
325
326/*
327* BER_Decoder Constructor
328*/
330 m_data_src = std::make_unique<DataSource_Memory>(data);
331 m_source = m_data_src.get();
332}
333
334/*
335* BER_Decoder Constructor
336*/
337BER_Decoder::BER_Decoder(const std::vector<uint8_t>& data) {
338 m_data_src = std::make_unique<DataSource_Memory>(data.data(), data.size());
339 m_source = m_data_src.get();
340}
341
342/*
343* BER_Decoder Copy Constructor
344*/
346 m_source = other.m_source;
347
348 // take ownership
349 std::swap(m_data_src, other.m_data_src);
350 m_parent = other.m_parent;
351}
352
353/*
354* Request for an object to decode itself
355*/
357 obj.decode_from(*this);
358 return (*this);
359}
360
361/*
362* Decode a BER encoded NULL
363*/
367 if(obj.length() > 0) {
368 throw BER_Decoding_Error("NULL object had nonzero size");
369 }
370 return (*this);
371}
372
376 out = BigInt::decode(out_vec.data(), out_vec.size());
377 return (*this);
378}
379
380/*
381* Decode a BER encoded BOOLEAN
382*/
383BER_Decoder& BER_Decoder::decode(bool& out, ASN1_Type type_tag, ASN1_Class class_tag) {
385 obj.assert_is_a(type_tag, class_tag);
386
387 if(obj.length() != 1) {
388 throw BER_Decoding_Error("BER boolean value had invalid size");
389 }
390
391 out = (obj.bits()[0]) ? true : false;
392 return (*this);
393}
394
395/*
396* Decode a small BER encoded INTEGER
397*/
398BER_Decoder& BER_Decoder::decode(size_t& out, ASN1_Type type_tag, ASN1_Class class_tag) {
399 BigInt integer;
400 decode(integer, type_tag, class_tag);
401
402 if(integer.is_negative()) {
403 throw BER_Decoding_Error("Decoded small integer value was negative");
404 }
405
406 if(integer.bits() > 32) {
407 throw BER_Decoding_Error("Decoded integer value larger than expected");
408 }
409
410 out = 0;
411 for(size_t i = 0; i != 4; ++i) {
412 out = (out << 8) | integer.byte_at(3 - i);
413 }
414
415 return (*this);
416}
417
418/*
419* Decode a small BER encoded INTEGER
420*/
421uint64_t BER_Decoder::decode_constrained_integer(ASN1_Type type_tag, ASN1_Class class_tag, size_t T_bytes) {
422 if(T_bytes > 8) {
423 throw BER_Decoding_Error("Can't decode small integer over 8 bytes");
424 }
425
426 BigInt integer;
427 decode(integer, type_tag, class_tag);
428
429 if(integer.bits() > 8 * T_bytes) {
430 throw BER_Decoding_Error("Decoded integer value larger than expected");
431 }
432
433 uint64_t out = 0;
434 for(size_t i = 0; i != 8; ++i) {
435 out = (out << 8) | integer.byte_at(7 - i);
436 }
437
438 return out;
439}
440
441/*
442* Decode a BER encoded INTEGER
443*/
446 obj.assert_is_a(type_tag, class_tag);
447
448 if(obj.length() == 0) {
449 out.clear();
450 } else {
451 const bool negative = (obj.bits()[0] & 0x80) ? true : false;
452
453 if(negative) {
454 secure_vector<uint8_t> vec(obj.bits(), obj.bits() + obj.length());
455 for(size_t i = obj.length(); i > 0; --i) {
456 if(vec[i - 1]--) {
457 break;
458 }
459 }
460 for(size_t i = 0; i != obj.length(); ++i) {
461 vec[i] = ~vec[i];
462 }
463 out = BigInt(vec.data(), vec.size());
464 out.flip_sign();
465 } else {
466 out = BigInt(obj.bits(), obj.length());
467 }
468 }
469
470 return (*this);
471}
472
473namespace {
474
475template <typename Alloc>
476void asn1_decode_binary_string(std::vector<uint8_t, Alloc>& buffer,
477 const BER_Object& obj,
478 ASN1_Type real_type,
479 ASN1_Type type_tag,
480 ASN1_Class class_tag) {
481 obj.assert_is_a(type_tag, class_tag);
482
483 if(real_type == ASN1_Type::OctetString) {
484 buffer.assign(obj.bits(), obj.bits() + obj.length());
485 } else {
486 if(obj.length() == 0) {
487 throw BER_Decoding_Error("Invalid BIT STRING");
488 }
489 if(obj.bits()[0] >= 8) {
490 throw BER_Decoding_Error("Bad number of unused bits in BIT STRING");
491 }
492
493 buffer.resize(obj.length() - 1);
494
495 if(obj.length() > 1) {
496 copy_mem(buffer.data(), obj.bits() + 1, obj.length() - 1);
497 }
498 }
499}
500
501} // namespace
502
503/*
504* BER decode a BIT STRING or OCTET STRING
505*/
507 ASN1_Type real_type,
508 ASN1_Type type_tag,
509 ASN1_Class class_tag) {
510 if(real_type != ASN1_Type::OctetString && real_type != ASN1_Type::BitString) {
511 throw BER_Bad_Tag("Bad tag for {BIT,OCTET} STRING", static_cast<uint32_t>(real_type));
512 }
513
514 asn1_decode_binary_string(buffer, get_next_object(), real_type, type_tag, class_tag);
515 return (*this);
516}
517
518BER_Decoder& BER_Decoder::decode(std::vector<uint8_t>& buffer,
519 ASN1_Type real_type,
520 ASN1_Type type_tag,
521 ASN1_Class class_tag) {
522 if(real_type != ASN1_Type::OctetString && real_type != ASN1_Type::BitString) {
523 throw BER_Bad_Tag("Bad tag for {BIT,OCTET} STRING", static_cast<uint32_t>(real_type));
524 }
525
526 asn1_decode_binary_string(buffer, get_next_object(), real_type, type_tag, class_tag);
527 return (*this);
528}
529
530} // namespace Botan
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:59
virtual void decode_from(BER_Decoder &from)=0
BER_Decoder(const uint8_t buf[], size_t len)
Definition ber_dec.cpp:321
void push_back(const BER_Object &obj)
Definition ber_dec.cpp:272
BER_Object get_next_object()
Definition ber_dec.cpp:231
BER_Decoder & decode(bool &out)
Definition ber_dec.h:176
uint64_t decode_constrained_integer(ASN1_Type type_tag, ASN1_Class class_tag, size_t T_bytes)
Definition ber_dec.cpp:421
bool more_items() const
Definition ber_dec.cpp:195
BER_Decoder & verify_end()
Definition ber_dec.cpp:205
BER_Decoder & end_cons()
Definition ber_dec.cpp:295
BER_Decoder start_cons(ASN1_Type type_tag, ASN1_Class class_tag)
Definition ber_dec.cpp:286
BER_Decoder & discard_remaining()
Definition ber_dec.cpp:222
BER_Decoder & decode_octet_string_bigint(BigInt &b)
Definition ber_dec.cpp:373
BER_Decoder & decode_null()
Definition ber_dec.cpp:364
size_t length() const
Definition asn1_obj.h:152
const uint8_t * bits() const
Definition asn1_obj.h:150
void assert_is_a(ASN1_Type type_tag, ASN1_Class class_tag, std::string_view descr="object") const
Definition asn1_obj.cpp:29
uint32_t tagging() const
Definition asn1_obj.h:140
bool is_set() const
Definition asn1_obj.h:138
static BigInt decode(const uint8_t buf[], size_t length)
Definition bigint.h:773
void flip_sign()
Definition bigint.h:555
size_t bits() const
Definition bigint.cpp:290
uint8_t byte_at(size_t n) const
Definition bigint.cpp:125
void clear()
Definition bigint.h:370
bool is_negative() const
Definition bigint.h:528
size_t read_byte(uint8_t &out)
Definition data_src.cpp:26
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
Definition build.h:391
ASN1_Class
Definition asn1_obj.h:28
ASN1_Type
Definition asn1_obj.h:43
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:61
constexpr void copy_mem(T *out, const T *in, size_t n)
Definition mem_ops.h:146
#define BOTAN_CHECKED_ADD(x, y)
Definition safeint.h:73