Botan 2.1.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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