• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 5123321399

30 May 2023 04:06PM UTC coverage: 92.213% (+0.004%) from 92.209%
5123321399

Pull #3558

github

web-flow
Merge dd72f7389 into 057bcbc35
Pull Request #3558: Add braces around all if/else statements

75602 of 81986 relevant lines covered (92.21%)

11859779.3 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.05
/src/lib/asn1/ber_dec.cpp
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

15
namespace Botan {
16

17
namespace {
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
*/
24
const size_t ALLOWED_EOC_NESTINGS = 16;
25

26
/*
27
* BER decode an ASN.1 type tag
28
*/
29
size_t decode_tag(DataSource* ber, ASN1_Type& type_tag, ASN1_Class& class_tag) {
7,113,431✔
30
   uint8_t b;
7,113,431✔
31
   if(!ber->read_byte(b)) {
7,113,431✔
32
      type_tag = ASN1_Type::NoObject;
71,154✔
33
      class_tag = ASN1_Class::NoObject;
71,154✔
34
      return 0;
71,154✔
35
   }
36

37
   if((b & 0x1F) != 0x1F) {
7,042,277✔
38
      type_tag = ASN1_Type(b & 0x1F);
7,037,496✔
39
      class_tag = ASN1_Class(b & 0xE0);
7,037,496✔
40
      return 1;
7,037,496✔
41
   }
42

43
   size_t tag_bytes = 1;
4,781✔
44
   class_tag = ASN1_Class(b & 0xE0);
4,781✔
45

46
   size_t tag_buf = 0;
4,781✔
47
   while(true) {
9,324✔
48
      if(!ber->read_byte(b)) {
9,324✔
49
         throw BER_Decoding_Error("Long-form tag truncated");
111✔
50
      }
51
      if(tag_buf & 0xFF000000) {
9,213✔
52
         throw BER_Decoding_Error("Long-form tag overflowed 32 bits");
17✔
53
      }
54
      ++tag_bytes;
9,196✔
55
      tag_buf = (tag_buf << 7) | (b & 0x7F);
9,196✔
56
      if((b & 0x80) == 0) {
9,196✔
57
         break;
58
      }
59
   }
60
   type_tag = ASN1_Type(tag_buf);
4,653✔
61
   return tag_bytes;
4,653✔
62
}
63

64
/*
65
* Find the EOC marker
66
*/
67
size_t find_eoc(DataSource* src, size_t allow_indef);
68

69
/*
70
* BER decode an ASN.1 length field
71
*/
72
size_t decode_length(DataSource* ber, size_t& field_size, size_t allow_indef) {
7,042,054✔
73
   uint8_t b;
7,042,054✔
74
   if(!ber->read_byte(b)) {
7,042,054✔
75
      throw BER_Decoding_Error("Length field not found");
1,952✔
76
   }
77
   field_size = 1;
7,040,102✔
78
   if((b & 0x80) == 0) {
7,040,102✔
79
      return b;
6,658,908✔
80
   }
81

82
   field_size += (b & 0x7F);
381,194✔
83
   if(field_size > 5) {
381,194✔
84
      throw BER_Decoding_Error("Length field is too large");
950✔
85
   }
86

87
   if(field_size == 1) {
380,244✔
88
      if(allow_indef == 0) {
200,216✔
89
         throw BER_Decoding_Error("Nested EOC markers too deep, rejecting to avoid stack exhaustion");
229✔
90
      } else {
91
         return find_eoc(ber, allow_indef - 1);
199,987✔
92
      }
93
   }
94

95
   size_t length = 0;
96

97
   for(size_t i = 0; i != field_size - 1; ++i) {
493,125✔
98
      if(get_byte<0>(length) != 0) {
313,198✔
99
         throw BER_Decoding_Error("Field length overflow");
×
100
      }
101
      if(!ber->read_byte(b)) {
313,198✔
102
         throw BER_Decoding_Error("Corrupted length field");
101✔
103
      }
104
      length = (length << 8) | b;
313,097✔
105
   }
106
   return length;
107
}
108

109
/*
110
* Find the EOC marker
111
*/
112
size_t find_eoc(DataSource* ber, size_t allow_indef) {
199,987✔
113
   secure_vector<uint8_t> buffer(BOTAN_DEFAULT_BUFFER_SIZE), data;
199,987✔
114

115
   while(true) {
611,903✔
116
      const size_t got = ber->peek(buffer.data(), buffer.size(), data.size());
405,945✔
117
      if(got == 0) {
405,945✔
118
         break;
119
      }
120

121
      data += std::make_pair(buffer.data(), got);
205,958✔
122
   }
205,958✔
123

124
   DataSource_Memory source(data);
199,987✔
125
   data.clear();
199,987✔
126

127
   size_t length = 0;
128
   while(true) {
1,232,555✔
129
      ASN1_Type type_tag;
716,271✔
130
      ASN1_Class class_tag;
716,271✔
131
      size_t tag_size = decode_tag(&source, type_tag, class_tag);
716,271✔
132
      if(type_tag == ASN1_Type::NoObject) {
716,224✔
133
         break;
134
      }
135

136
      size_t length_size = 0;
682,195✔
137
      size_t item_size = decode_length(&source, length_size, allow_indef);
682,195✔
138
      source.discard_next(item_size);
673,989✔
139

140
      length = BOTAN_CHECKED_ADD(length, item_size);
673,989✔
141
      length = BOTAN_CHECKED_ADD(length, tag_size);
673,989✔
142
      length = BOTAN_CHECKED_ADD(length, length_size);
673,989✔
143

144
      if(type_tag == ASN1_Type::Eoc && class_tag == ASN1_Class::Universal) {
673,989✔
145
         break;
146
      }
147
   }
516,284✔
148
   return length;
191,734✔
149
}
589,650✔
150

151
class DataSource_BERObject final : public DataSource {
152
   public:
153
      size_t read(uint8_t out[], size_t length) override {
18,277,929✔
154
         BOTAN_ASSERT_NOMSG(m_offset <= m_obj.length());
18,277,929✔
155
         const size_t got = std::min<size_t>(m_obj.length() - m_offset, length);
18,277,929✔
156
         copy_mem(out, m_obj.bits() + m_offset, got);
18,277,929✔
157
         m_offset += got;
18,277,929✔
158
         return got;
18,277,929✔
159
      }
160

161
      size_t peek(uint8_t out[], size_t length, size_t peek_offset) const override {
12,900✔
162
         BOTAN_ASSERT_NOMSG(m_offset <= m_obj.length());
12,900✔
163
         const size_t bytes_left = m_obj.length() - m_offset;
12,900✔
164

165
         if(peek_offset >= bytes_left) {
12,900✔
166
            return 0;
167
         }
168

169
         const size_t got = std::min(bytes_left - peek_offset, length);
6,446✔
170
         copy_mem(out, m_obj.bits() + peek_offset, got);
6,446✔
171
         return got;
6,446✔
172
      }
173

174
      bool check_available(size_t n) override {
892,014✔
175
         BOTAN_ASSERT_NOMSG(m_offset <= m_obj.length());
892,014✔
176
         return (n <= (m_obj.length() - m_offset));
892,014✔
177
      }
178

179
      bool end_of_data() const override { return get_bytes_read() == m_obj.length(); }
762,904✔
180

181
      size_t get_bytes_read() const override { return m_offset; }
762,904✔
182

183
      explicit DataSource_BERObject(BER_Object&& obj) : m_obj(std::move(obj)), m_offset(0) {}
552,022✔
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
*/
195
bool BER_Decoder::more_items() const {
496,923✔
196
   if(m_source->end_of_data() && !m_pushed.is_set()) {
496,923✔
197
      return false;
173,986✔
198
   }
199
   return true;
200
}
201

202
/*
203
* Verify that no bytes remain in the source
204
*/
205
BER_Decoder& BER_Decoder::verify_end() { return verify_end("BER_Decoder::verify_end called, but data remains"); }
56,586✔
206

207
/*
208
* Verify that no bytes remain in the source
209
*/
210
BER_Decoder& BER_Decoder::verify_end(std::string_view err) {
71,640✔
211
   if(!m_source->end_of_data() || m_pushed.is_set()) {
71,640✔
212
      throw Decoding_Error(err);
191✔
213
   }
214
   return (*this);
71,449✔
215
}
216

217
/*
218
* Discard all the bytes remaining in the source
219
*/
220
BER_Decoder& BER_Decoder::discard_remaining() {
5,775✔
221
   uint8_t buf;
5,775✔
222
   while(m_source->read_byte(buf)) {}
92,650✔
223
   return (*this);
5,775✔
224
}
225

226
/*
227
* Return the BER encoding of the next object
228
*/
229
BER_Object BER_Decoder::get_next_object() {
1,458,843✔
230
   BER_Object next;
1,458,843✔
231

232
   if(m_pushed.is_set()) {
1,458,843✔
233
      std::swap(next, m_pushed);
101,203✔
234
      return next;
101,203✔
235
   }
236

237
   for(;;) {
6,397,160✔
238
      ASN1_Type type_tag;
6,397,160✔
239
      ASN1_Class class_tag;
6,397,160✔
240
      decode_tag(m_source, type_tag, class_tag);
6,397,160✔
241
      next.set_tagging(type_tag, class_tag);
6,397,079✔
242
      if(next.is_set() == false) {  // no more objects
6,397,079✔
243
         return next;
37,220✔
244
      }
245

246
      size_t field_size;
6,359,859✔
247
      const size_t length = decode_length(m_source, field_size, ALLOWED_EOC_NESTINGS);
6,359,859✔
248
      if(!m_source->check_available(length)) {
6,356,580✔
249
         throw BER_Decoding_Error("Value truncated");
4,615✔
250
      }
251

252
      uint8_t* out = next.mutable_bits(length);
6,351,965✔
253
      if(m_source->read(out, length) != length) {
6,351,965✔
254
         throw BER_Decoding_Error("Value truncated");
×
255
      }
256

257
      if(next.tagging() == static_cast<uint32_t>(ASN1_Type::Eoc)) {
6,351,965✔
258
         continue;
5,039,520✔
259
      } else {
260
         break;
261
      }
262
   }
263

264
   return next;
1,312,445✔
265
}
7,975✔
266

267
/*
268
* Push a object back into the stream
269
*/
270
void BER_Decoder::push_back(const BER_Object& obj) {
1,184✔
271
   if(m_pushed.is_set()) {
1,184✔
272
      throw Invalid_State("BER_Decoder: Only one push back is allowed");
×
273
   }
274
   m_pushed = obj;
1,184✔
275
}
1,184✔
276

277
void BER_Decoder::push_back(BER_Object&& obj) {
119,047✔
278
   if(m_pushed.is_set()) {
119,047✔
279
      throw Invalid_State("BER_Decoder: Only one push back is allowed");
×
280
   }
281
   m_pushed = std::move(obj);
119,047✔
282
}
119,047✔
283

284
BER_Decoder BER_Decoder::start_cons(ASN1_Type type_tag, ASN1_Class class_tag) {
539,992✔
285
   BER_Object obj = get_next_object();
539,992✔
286
   obj.assert_is_a(type_tag, class_tag | ASN1_Class::Constructed);
536,393✔
287
   return BER_Decoder(std::move(obj), this);
534,644✔
288
}
534,644✔
289

290
/*
291
* Finish decoding a CONSTRUCTED type
292
*/
293
BER_Decoder& BER_Decoder::end_cons() {
378,373✔
294
   if(!m_parent) {
378,373✔
295
      throw Invalid_State("BER_Decoder::end_cons called with null parent");
×
296
   }
297
   if(!m_source->end_of_data()) {
378,373✔
298
      throw Decoding_Error("BER_Decoder::end_cons called with data left");
90✔
299
   }
300
   return (*m_parent);
378,283✔
301
}
302

303
BER_Decoder::BER_Decoder(BER_Object&& obj, BER_Decoder* parent) {
552,022✔
304
   m_data_src = std::make_unique<DataSource_BERObject>(std::move(obj));
552,022✔
305
   m_source = m_data_src.get();
552,022✔
306
   m_parent = parent;
552,022✔
307
}
552,022✔
308

309
/*
310
* BER_Decoder Constructor
311
*/
312
BER_Decoder::BER_Decoder(DataSource& src) { m_source = &src; }
36,746✔
313

314
/*
315
* BER_Decoder Constructor
316
 */
317
BER_Decoder::BER_Decoder(const uint8_t data[], size_t length) {
62,290✔
318
   m_data_src = std::make_unique<DataSource_Memory>(data, length);
62,290✔
319
   m_source = m_data_src.get();
62,290✔
320
}
62,290✔
321

322
/*
323
* BER_Decoder Constructor
324
*/
325
BER_Decoder::BER_Decoder(const secure_vector<uint8_t>& data) {
4,205✔
326
   m_data_src = std::make_unique<DataSource_Memory>(data);
4,205✔
327
   m_source = m_data_src.get();
4,205✔
328
}
4,205✔
329

330
/*
331
* BER_Decoder Constructor
332
*/
333
BER_Decoder::BER_Decoder(const std::vector<uint8_t>& data) {
147,323✔
334
   m_data_src = std::make_unique<DataSource_Memory>(data.data(), data.size());
147,323✔
335
   m_source = m_data_src.get();
147,323✔
336
}
147,323✔
337

338
/*
339
* BER_Decoder Copy Constructor
340
*/
341
BER_Decoder::BER_Decoder(const BER_Decoder& other) {
178✔
342
   m_source = other.m_source;
178✔
343

344
   // take ownership
345
   std::swap(m_data_src, other.m_data_src);
178✔
346
   m_parent = other.m_parent;
178✔
347
}
178✔
348

349
/*
350
* Request for an object to decode itself
351
*/
352
BER_Decoder& BER_Decoder::decode(ASN1_Object& obj, ASN1_Type /*unused*/, ASN1_Class /*unused*/) {
525,164✔
353
   obj.decode_from(*this);
525,164✔
354
   return (*this);
520,063✔
355
}
356

357
/*
358
* Decode a BER encoded NULL
359
*/
360
BER_Decoder& BER_Decoder::decode_null() {
×
361
   BER_Object obj = get_next_object();
×
362
   obj.assert_is_a(ASN1_Type::Null, ASN1_Class::Universal);
×
363
   if(obj.length() > 0) {
×
364
      throw BER_Decoding_Error("NULL object had nonzero size");
×
365
   }
366
   return (*this);
×
367
}
×
368

369
BER_Decoder& BER_Decoder::decode_octet_string_bigint(BigInt& out) {
1,016✔
370
   secure_vector<uint8_t> out_vec;
1,016✔
371
   decode(out_vec, ASN1_Type::OctetString);
1,016✔
372
   out = BigInt::decode(out_vec.data(), out_vec.size());
992✔
373
   return (*this);
992✔
374
}
992✔
375

376
/*
377
* Decode a BER encoded BOOLEAN
378
*/
379
BER_Decoder& BER_Decoder::decode(bool& out, ASN1_Type type_tag, ASN1_Class class_tag) {
28,629✔
380
   BER_Object obj = get_next_object();
28,629✔
381
   obj.assert_is_a(type_tag, class_tag);
28,692✔
382

383
   if(obj.length() != 1) {
28,629✔
384
      throw BER_Decoding_Error("BER boolean value had invalid size");
63✔
385
   }
386

387
   out = (obj.bits()[0]) ? true : false;
28,566✔
388
   return (*this);
28,566✔
389
}
28,566✔
390

391
/*
392
* Decode a small BER encoded INTEGER
393
*/
394
BER_Decoder& BER_Decoder::decode(size_t& out, ASN1_Type type_tag, ASN1_Class class_tag) {
30,917✔
395
   BigInt integer;
30,917✔
396
   decode(integer, type_tag, class_tag);
30,917✔
397

398
   if(integer.is_negative()) {
30,619✔
399
      throw BER_Decoding_Error("Decoded small integer value was negative");
97✔
400
   }
401

402
   if(integer.bits() > 32) {
30,522✔
403
      throw BER_Decoding_Error("Decoded integer value larger than expected");
1,090✔
404
   }
405

406
   out = 0;
29,432✔
407
   for(size_t i = 0; i != 4; ++i) {
147,160✔
408
      out = (out << 8) | integer.byte_at(3 - i);
117,728✔
409
   }
410

411
   return (*this);
29,432✔
412
}
29,432✔
413

414
/*
415
* Decode a small BER encoded INTEGER
416
*/
417
uint64_t BER_Decoder::decode_constrained_integer(ASN1_Type type_tag, ASN1_Class class_tag, size_t T_bytes) {
3,616✔
418
   if(T_bytes > 8) {
3,616✔
419
      throw BER_Decoding_Error("Can't decode small integer over 8 bytes");
×
420
   }
421

422
   BigInt integer;
3,616✔
423
   decode(integer, type_tag, class_tag);
3,616✔
424

425
   if(integer.bits() > 8 * T_bytes) {
3,616✔
426
      throw BER_Decoding_Error("Decoded integer value larger than expected");
×
427
   }
428

429
   uint64_t out = 0;
430
   for(size_t i = 0; i != 8; ++i) {
32,544✔
431
      out = (out << 8) | integer.byte_at(7 - i);
28,928✔
432
   }
433

434
   return out;
3,616✔
435
}
3,616✔
436

437
/*
438
* Decode a BER encoded INTEGER
439
*/
440
BER_Decoder& BER_Decoder::decode(BigInt& out, ASN1_Type type_tag, ASN1_Class class_tag) {
118,580✔
441
   BER_Object obj = get_next_object();
118,580✔
442
   obj.assert_is_a(type_tag, class_tag);
117,814✔
443

444
   if(obj.length() == 0) {
116,557✔
445
      out.clear();
2,333✔
446
   } else {
447
      const bool negative = (obj.bits()[0] & 0x80) ? true : false;
114,224✔
448

449
      if(negative) {
114,224✔
450
         secure_vector<uint8_t> vec(obj.bits(), obj.bits() + obj.length());
4,500✔
451
         for(size_t i = obj.length(); i > 0; --i) {
8,821✔
452
            if(vec[i - 1]--) {
8,821✔
453
               break;
454
            }
455
         }
456
         for(size_t i = 0; i != obj.length(); ++i) {
46,736✔
457
            vec[i] = ~vec[i];
43,493✔
458
         }
459
         out = BigInt(vec.data(), vec.size());
3,243✔
460
         out.flip_sign();
6,486✔
461
      } else {
3,243✔
462
         out = BigInt(obj.bits(), obj.length());
110,981✔
463
      }
464
   }
465

466
   return (*this);
116,557✔
467
}
116,557✔
468

469
namespace {
470

471
template <typename Alloc>
472
void asn1_decode_binary_string(std::vector<uint8_t, Alloc>& buffer,
128,859✔
473
                               const BER_Object& obj,
474
                               ASN1_Type real_type,
475
                               ASN1_Type type_tag,
476
                               ASN1_Class class_tag) {
477
   obj.assert_is_a(type_tag, class_tag);
128,859✔
478

479
   if(real_type == ASN1_Type::OctetString) {
128,573✔
480
      buffer.assign(obj.bits(), obj.bits() + obj.length());
79,186✔
481
   } else {
482
      if(obj.length() == 0) {
49,387✔
483
         throw BER_Decoding_Error("Invalid BIT STRING");
11✔
484
      }
485
      if(obj.bits()[0] >= 8) {
49,376✔
486
         throw BER_Decoding_Error("Bad number of unused bits in BIT STRING");
18✔
487
      }
488

489
      buffer.resize(obj.length() - 1);
49,358✔
490

491
      if(obj.length() > 1) {
49,358✔
492
         copy_mem(buffer.data(), obj.bits() + 1, obj.length() - 1);
48,687✔
493
      }
494
   }
495
}
128,544✔
496

497
}  // namespace
498

499
/*
500
* BER decode a BIT STRING or OCTET STRING
501
*/
502
BER_Decoder& BER_Decoder::decode(secure_vector<uint8_t>& buffer,
8,376✔
503
                                 ASN1_Type real_type,
504
                                 ASN1_Type type_tag,
505
                                 ASN1_Class class_tag) {
506
   if(real_type != ASN1_Type::OctetString && real_type != ASN1_Type::BitString) {
8,376✔
507
      throw BER_Bad_Tag("Bad tag for {BIT,OCTET} STRING", static_cast<uint32_t>(real_type));
×
508
   }
509

510
   asn1_decode_binary_string(buffer, get_next_object(), real_type, type_tag, class_tag);
8,376✔
511
   return (*this);
7,782✔
512
}
513

514
BER_Decoder& BER_Decoder::decode(std::vector<uint8_t>& buffer,
123,404✔
515
                                 ASN1_Type real_type,
516
                                 ASN1_Type type_tag,
517
                                 ASN1_Class class_tag) {
518
   if(real_type != ASN1_Type::OctetString && real_type != ASN1_Type::BitString) {
123,404✔
519
      throw BER_Bad_Tag("Bad tag for {BIT,OCTET} STRING", static_cast<uint32_t>(real_type));
1,741✔
520
   }
521

522
   asn1_decode_binary_string(buffer, get_next_object(), real_type, type_tag, class_tag);
121,663✔
523
   return (*this);
120,762✔
524
}
525

526
}  // namespace Botan
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc