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