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