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