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

randombit / botan / 24063525848

06 Apr 2026 10:36PM UTC coverage: 89.448% (-0.007%) from 89.455%
24063525848

push

github

web-flow
Merge pull request #5521 from randombit/jack/fix-rollup

Rollup of small fixes

105878 of 118368 relevant lines covered (89.45%)

11475460.89 hits per line

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

90.91
/src/lib/asn1/ber_dec.cpp
1
/*
2
* BER Decoder
3
* (C) 1999-2008,2015,2017,2018,2026 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/data_src.h>
12
#include <botan/internal/int_utils.h>
13
#include <botan/internal/loadstor.h>
14
#include <memory>
15

16
namespace Botan {
17

18
namespace {
19

20
bool is_constructed(ASN1_Class class_tag) {
7,389,762✔
21
   return (static_cast<uint32_t>(class_tag) & static_cast<uint32_t>(ASN1_Class::Constructed)) != 0;
7,389,762✔
22
}
23

24
/*
25
* BER decode an ASN.1 type tag
26
*/
27
size_t decode_tag(DataSource* ber, ASN1_Type& type_tag, ASN1_Class& class_tag, bool der_mode) {
7,252,885✔
28
   auto b = ber->read_byte();
7,252,885✔
29

30
   if(!b) {
7,252,885✔
31
      type_tag = ASN1_Type::NoObject;
58,832✔
32
      class_tag = ASN1_Class::NoObject;
58,832✔
33
      return 0;
58,832✔
34
   }
35

36
   if((*b & 0x1F) != 0x1F) {
7,194,053✔
37
      type_tag = ASN1_Type(*b & 0x1F);
7,191,713✔
38
      class_tag = ASN1_Class(*b & 0xE0);
7,191,713✔
39
      return 1;
7,191,713✔
40
   }
41

42
   size_t tag_bytes = 1;
2,340✔
43
   class_tag = ASN1_Class(*b & 0xE0);
2,340✔
44

45
   size_t tag_buf = 0;
2,340✔
46
   while(true) {
4,028✔
47
      b = ber->read_byte();
4,028✔
48
      if(!b) {
4,028✔
49
         throw BER_Decoding_Error("Long-form tag truncated");
78✔
50
      }
51
      if((tag_buf >> 24) != 0) {
3,950✔
52
         throw BER_Decoding_Error("Long-form tag overflowed 32 bits");
6✔
53
      }
54
      // This is required even by BER (see X.690 section 8.1.2.4.2 sentence c)
55
      if(tag_bytes == 1 && b == 0x80) {
3,944✔
56
         throw BER_Decoding_Error("Long form tag with leading zero");
65✔
57
      }
58
      ++tag_bytes;
3,879✔
59
      tag_buf = (tag_buf << 7) | (*b & 0x7F);
3,879✔
60
      if((*b & 0x80) == 0) {
3,879✔
61
         break;
62
      }
63
   }
64
   // DER requires short form for tag values that fit (0-30)
65
   if(der_mode && tag_buf <= 30) {
2,191✔
66
      throw BER_Decoding_Error("Detected long-form tag for small tag value in DER structure");
29✔
67
   }
68

69
   if(tag_buf == static_cast<uint32_t>(ASN1_Type::NoObject)) {
2,162✔
70
      throw BER_Decoding_Error("Tag value collides with internal sentinel");
8✔
71
   }
72

73
   type_tag = ASN1_Type(tag_buf);
2,154✔
74
   return tag_bytes;
2,154✔
75
}
76

77
/*
78
* Find the EOC marker
79
*/
80
size_t find_eoc(DataSource* src, size_t allow_indef);
81

82
/*
83
* BER decode an ASN.1 length field
84
*/
85
size_t decode_length(DataSource* ber, size_t& field_size, size_t allow_indef, bool der_mode, bool constructed) {
7,193,867✔
86
   uint8_t b = 0;
7,193,867✔
87
   if(ber->read_byte(b) == 0) {
7,193,867✔
88
      throw BER_Decoding_Error("Length field not found");
431✔
89
   }
90
   field_size = 1;
7,193,436✔
91
   if((b & 0x80) == 0) {
7,193,436✔
92
      return b;
6,915,865✔
93
   }
94

95
   const size_t num_length_bytes = (b & 0x7F);
277,571✔
96

97
   field_size += num_length_bytes;
277,571✔
98
   if(field_size > 5) {
277,571✔
99
      throw BER_Decoding_Error("Length field is too large");
619✔
100
   }
101

102
   if(num_length_bytes == 0) {
276,952✔
103
      if(der_mode) {
82,670✔
104
         throw BER_Decoding_Error("Detected indefinite-length encoding in DER structure");
6,735✔
105
      } else if(!constructed) {
75,935✔
106
         // Indefinite length is only valid for constructed types (X.690 8.1.3.2)
107
         throw BER_Decoding_Error("Indefinite-length encoding used with non-constructed type");
159✔
108
      } else if(allow_indef == 0) {
75,776✔
109
         throw BER_Decoding_Error("Nested EOC markers too deep, rejecting to avoid stack exhaustion");
9✔
110
      } else {
111
         return find_eoc(ber, allow_indef - 1);
75,767✔
112
      }
113
   }
114

115
   size_t length = 0;
116

117
   for(size_t i = 0; i != num_length_bytes; ++i) {
532,331✔
118
      if(get_byte<0>(length) != 0) {
338,101✔
119
         throw BER_Decoding_Error("Field length overflow");
×
120
      }
121
      if(ber->read_byte(b) == 0) {
338,101✔
122
         throw BER_Decoding_Error("Corrupted length field");
52✔
123
      }
124
      length = (length << 8) | b;
338,049✔
125
   }
126

127
   // DER requires shortest possible length encoding
128
   if(der_mode) {
194,230✔
129
      if(length < 128) {
192,741✔
130
         throw BER_Decoding_Error("Detected non-canonical length encoding in DER structure");
436✔
131
      }
132
      if(num_length_bytes > 1 && length < (size_t(1) << ((num_length_bytes - 1) * 8))) {
192,305✔
133
         throw BER_Decoding_Error("Detected non-canonical length encoding in DER structure");
137✔
134
      }
135
   }
136

137
   return length;
138
}
139

140
/*
141
* Find the EOC marker
142
*/
143
size_t find_eoc(DataSource* ber, size_t allow_indef) {
75,767✔
144
   secure_vector<uint8_t> buffer(DefaultBufferSize);
75,767✔
145
   secure_vector<uint8_t> data;
75,767✔
146

147
   while(true) {
153,154✔
148
      const size_t got = ber->peek(buffer.data(), buffer.size(), data.size());
306,308✔
149
      if(got == 0) {
153,154✔
150
         break;
151
      }
152

153
      data += std::make_pair(buffer.data(), got);
230,541✔
154
   }
155

156
   DataSource_Memory source(data);
76,464✔
157
   data.clear();
75,767✔
158

159
   size_t length = 0;
160
   while(true) {
394,379✔
161
      ASN1_Type type_tag = ASN1_Type::NoObject;
235,073✔
162
      ASN1_Class class_tag = ASN1_Class::NoObject;
235,073✔
163
      // der_mode is false because if we're in this function at all it's BER
164
      const size_t tag_size = decode_tag(&source, type_tag, class_tag, false);
235,073✔
165
      if(type_tag == ASN1_Type::NoObject) {
235,001✔
166
         break;
167
      }
168

169
      size_t length_size = 0;
233,763✔
170
      const size_t item_size =
233,763✔
171
         decode_length(&source, length_size, allow_indef, /*der_mode=*/false, is_constructed(class_tag));
233,763✔
172
      source.discard_next(item_size);
233,138✔
173

174
      if(auto new_len = checked_add(length, item_size, tag_size, length_size)) {
466,276✔
175
         length = new_len.value();
233,138✔
176
      } else {
177
         throw Decoding_Error("Integer overflow while decoding DER");
×
178
      }
179

180
      if(type_tag == ASN1_Type::Eoc && class_tag == ASN1_Class::Universal) {
233,138✔
181
         break;
182
      }
183
   }
159,306✔
184
   return length;
75,070✔
185
}
226,385✔
186

187
class DataSource_BERObject final : public DataSource {
188
   public:
189
      size_t read(uint8_t out[], size_t length) override {
25,876,342✔
190
         BOTAN_ASSERT_NOMSG(m_offset <= m_obj.length());
25,876,342✔
191
         const size_t got = std::min<size_t>(m_obj.length() - m_offset, length);
25,876,342✔
192
         copy_mem(out, m_obj.bits() + m_offset, got);
25,876,342✔
193
         m_offset += got;
25,876,342✔
194
         return got;
25,876,342✔
195
      }
196

197
      size_t peek(uint8_t out[], size_t length, size_t peek_offset) const override {
×
198
         BOTAN_ASSERT_NOMSG(m_offset <= m_obj.length());
×
199
         const size_t bytes_left = m_obj.length() - m_offset;
×
200

201
         if(peek_offset >= bytes_left) {
×
202
            return 0;
203
         }
204

205
         const size_t got = std::min(bytes_left - peek_offset, length);
×
206
         copy_mem(out, m_obj.bits() + m_offset + peek_offset, got);
×
207
         return got;
×
208
      }
209

210
      bool check_available(size_t n) override {
1,225,491✔
211
         BOTAN_ASSERT_NOMSG(m_offset <= m_obj.length());
1,225,491✔
212
         return (n <= (m_obj.length() - m_offset));
1,225,491✔
213
      }
214

215
      bool end_of_data() const override { return get_bytes_read() == m_obj.length(); }
1,101,151✔
216

217
      size_t get_bytes_read() const override { return m_offset; }
1,101,151✔
218

219
      explicit DataSource_BERObject(BER_Object&& obj) : m_obj(std::move(obj)) {}
788,542✔
220

221
   private:
222
      BER_Object m_obj;
223
      size_t m_offset = 0;
224
};
225

226
}  // namespace
227

228
BER_Decoder::~BER_Decoder() = default;
2,353,853✔
229

230
/*
231
* Check if more objects are there
232
*/
233
bool BER_Decoder::more_items() const {
725,236✔
234
   if(m_source->end_of_data() && !m_pushed.is_set()) {
725,236✔
235
      return false;
260,702✔
236
   }
237
   return true;
238
}
239

240
/*
241
* Verify that no bytes remain in the source
242
*/
243
BER_Decoder& BER_Decoder::verify_end() {
215,197✔
244
   return verify_end("BER_Decoder::verify_end called, but data remains");
215,197✔
245
}
246

247
/*
248
* Verify that no bytes remain in the source
249
*/
250
BER_Decoder& BER_Decoder::verify_end(std::string_view err) {
236,279✔
251
   if(!m_source->end_of_data() || m_pushed.is_set()) {
236,279✔
252
      throw Decoding_Error(err);
233✔
253
   }
254
   return (*this);
236,046✔
255
}
256

257
/*
258
* Discard all the bytes remaining in the source
259
*/
260
BER_Decoder& BER_Decoder::discard_remaining() {
14,755✔
261
   uint8_t buf = 0;
14,755✔
262
   while(m_source->read_byte(buf) != 0) {}
151,385✔
263
   return (*this);
14,755✔
264
}
265

266
std::optional<uint8_t> BER_Decoder::read_next_byte() {
21,867,092✔
267
   BOTAN_ASSERT_NOMSG(m_source != nullptr);
21,867,092✔
268
   uint8_t b = 0;
21,867,092✔
269
   if(m_source->read_byte(b) != 0) {
21,867,092✔
270
      return b;
21,693,236✔
271
   } else {
272
      return {};
173,856✔
273
   }
274
}
275

276
const BER_Object& BER_Decoder::peek_next_object() {
17,483✔
277
   if(!m_pushed.is_set()) {
17,483✔
278
      m_pushed = get_next_object();
17,304✔
279
   }
280

281
   return m_pushed;
17,466✔
282
}
283

284
/*
285
* Return the BER encoding of the next object
286
*/
287
BER_Object BER_Decoder::get_next_object() {
2,170,953✔
288
   BER_Object next;
2,170,953✔
289

290
   if(m_pushed.is_set()) {
2,170,953✔
291
      std::swap(next, m_pushed);
174,018✔
292
      return next;
174,018✔
293
   }
294

295
   for(;;) {
12,038,689✔
296
      ASN1_Type type_tag = ASN1_Type::NoObject;
7,017,812✔
297
      ASN1_Class class_tag = ASN1_Class::NoObject;
7,017,812✔
298
      decode_tag(m_source, type_tag, class_tag, m_limits.require_der_encoding());
7,017,812✔
299
      next.set_tagging(type_tag, class_tag);
7,017,698✔
300
      if(next.is_set() == false) {  // no more objects
7,017,698✔
301
         return next;
57,594✔
302
      }
303

304
      size_t field_size = 0;
6,960,104✔
305
      const size_t allow_indef = m_limits.allow_ber_encoding() ? m_limits.max_nested_indefinite_length() : 0;
6,960,104✔
306
      const bool der_mode = m_limits.require_der_encoding();
6,960,104✔
307
      const size_t length = decode_length(m_source, field_size, allow_indef, der_mode, is_constructed(class_tag));
6,960,104✔
308
      if(!m_source->check_available(length)) {
6,951,454✔
309
         throw BER_Decoding_Error("Value truncated");
3,375✔
310
      }
311

312
      uint8_t* out = next.mutable_bits(length);
6,948,079✔
313
      if(m_source->read(out, length) != length) {
6,948,079✔
314
         throw BER_Decoding_Error("Value truncated");
×
315
      }
316

317
      if(next.tagging() == static_cast<uint32_t>(ASN1_Type::Eoc)) {
6,948,079✔
318
         if(m_limits.require_der_encoding()) {
5,023,077✔
319
            throw BER_Decoding_Error("Detected EOC marker in DER structure");
2,200✔
320
         }
321
         continue;
5,020,877✔
322
      } else {
323
         break;
324
      }
325
   }
326

327
   return next;
1,925,002✔
328
}
14,339✔
329

330
BER_Object BER_Decoder::get_next_value(size_t sizeofT, ASN1_Type type_tag, ASN1_Class class_tag) {
×
331
   const BER_Object obj = get_next_object();
×
332
   obj.assert_is_a(type_tag, class_tag);
×
333

334
   if(obj.length() != sizeofT) {
×
335
      throw BER_Decoding_Error("Size mismatch. Object value size is " + std::to_string(obj.length()) +
×
336
                               "; Output type size is " + std::to_string(sizeofT));
×
337
   }
338

339
   return obj;
×
340
}
×
341

342
/*
343
* Push a object back into the stream
344
*/
345
void BER_Decoder::push_back(const BER_Object& obj) {
24✔
346
   if(m_pushed.is_set()) {
24✔
347
      throw Invalid_State("BER_Decoder: Only one push back is allowed");
×
348
   }
349
   m_pushed = obj;
24✔
350
}
24✔
351

352
void BER_Decoder::push_back(BER_Object&& obj) {
183,657✔
353
   if(m_pushed.is_set()) {
183,657✔
354
      throw Invalid_State("BER_Decoder: Only one push back is allowed");
×
355
   }
356
   m_pushed = std::move(obj);
183,657✔
357
}
183,657✔
358

359
BER_Decoder BER_Decoder::start_cons(ASN1_Type type_tag, ASN1_Class class_tag) {
797,901✔
360
   BER_Object obj = get_next_object();
797,901✔
361
   obj.assert_is_a(type_tag, class_tag | ASN1_Class::Constructed);
789,394✔
362
   BER_Decoder child(std::move(obj), this);
788,542✔
363
   return child;
788,542✔
364
}
789,394✔
365

366
/*
367
* Finish decoding a CONSTRUCTED type
368
*/
369
BER_Decoder& BER_Decoder::end_cons() {
574,181✔
370
   if(m_parent == nullptr) {
574,181✔
371
      throw Invalid_State("BER_Decoder::end_cons called with null parent");
×
372
   }
373
   if(!m_source->end_of_data()) {
574,181✔
374
      throw Decoding_Error("BER_Decoder::end_cons called with data left");
135✔
375
   }
376
   return (*m_parent);
574,046✔
377
}
378

379
BER_Decoder::BER_Decoder(BER_Object&& obj, BER_Decoder* parent) :
788,542✔
380
      m_limits(parent != nullptr ? parent->limits() : BER_Decoder::Limits::BER()), m_parent(parent) {
788,542✔
381
   m_data_src = std::make_unique<DataSource_BERObject>(std::move(obj));
788,542✔
382
   m_source = m_data_src.get();
788,542✔
383
}
788,542✔
384

385
/*
386
* BER_Decoder Constructor
387
*/
388
BER_Decoder::BER_Decoder(DataSource& src, Limits limits) : m_limits(limits), m_source(&src) {}
46,009✔
389

390
/*
391
* BER_Decoder Constructor
392
 */
393
BER_Decoder::BER_Decoder(std::span<const uint8_t> buf, Limits limits) : m_limits(limits) {
365,291✔
394
   m_data_src = std::make_unique<DataSource_Memory>(buf);
365,291✔
395
   m_source = m_data_src.get();
365,291✔
396
}
365,291✔
397

398
/*
399
* BER_Decoder Copy Constructor
400
*/
401
BER_Decoder::BER_Decoder(const BER_Decoder& other) :
178✔
402
      m_limits(other.m_limits), m_parent(other.m_parent), m_source(other.m_source) {
178✔
403
   // take ownership of other's data source
404
   std::swap(m_data_src, other.m_data_src);
178✔
405
}
178✔
406

407
BER_Decoder::BER_Decoder(BER_Decoder&& other) noexcept = default;
×
408

409
BER_Decoder& BER_Decoder::operator=(BER_Decoder&&) noexcept = default;
×
410

411
/*
412
* Request for an object to decode itself
413
*/
414
BER_Decoder& BER_Decoder::decode(ASN1_Object& obj, ASN1_Type /*unused*/, ASN1_Class /*unused*/) {
791,050✔
415
   obj.decode_from(*this);
791,050✔
416
   return (*this);
785,463✔
417
}
418

419
/*
420
* Decode a BER encoded NULL
421
*/
422
BER_Decoder& BER_Decoder::decode_null() {
111✔
423
   const BER_Object obj = get_next_object();
111✔
424
   obj.assert_is_a(ASN1_Type::Null, ASN1_Class::Universal);
111✔
425
   if(obj.length() > 0) {
111✔
426
      throw BER_Decoding_Error("NULL object had nonzero size");
×
427
   }
428
   return (*this);
111✔
429
}
111✔
430

431
BER_Decoder& BER_Decoder::decode_octet_string_bigint(BigInt& out) {
314✔
432
   secure_vector<uint8_t> out_vec;
314✔
433
   decode(out_vec, ASN1_Type::OctetString);
314✔
434
   out = BigInt::from_bytes(out_vec);
314✔
435
   return (*this);
267✔
436
}
267✔
437

438
/*
439
* Decode a BER encoded BOOLEAN
440
*/
441
BER_Decoder& BER_Decoder::decode(bool& out, ASN1_Type type_tag, ASN1_Class class_tag) {
48,148✔
442
   const BER_Object obj = get_next_object();
48,148✔
443
   obj.assert_is_a(type_tag, class_tag);
48,148✔
444

445
   if(obj.length() != 1) {
48,148✔
446
      throw BER_Decoding_Error("BER boolean value had invalid size");
61✔
447
   }
448

449
   const uint8_t val = obj.bits()[0];
48,087✔
450

451
   // DER requires boolean values to be exactly 0x00 or 0xFF
452
   if(m_limits.require_der_encoding() && val != 0x00 && val != 0xFF) {
48,087✔
453
      throw BER_Decoding_Error("Detected non-canonical boolean encoding in DER structure");
54✔
454
   }
455

456
   out = (val != 0) ? true : false;
48,033✔
457

458
   return (*this);
48,033✔
459
}
48,148✔
460

461
/*
462
* Decode a small BER encoded INTEGER
463
*/
464
BER_Decoder& BER_Decoder::decode(size_t& out, ASN1_Type type_tag, ASN1_Class class_tag) {
40,856✔
465
   BigInt integer;
40,856✔
466
   decode(integer, type_tag, class_tag);
40,856✔
467

468
   if(integer.signum() < 0) {
40,759✔
469
      throw BER_Decoding_Error("Decoded small integer value was negative");
31✔
470
   }
471

472
   if(integer.bits() > 32) {
40,728✔
473
      throw BER_Decoding_Error("Decoded integer value larger than expected");
10✔
474
   }
475

476
   out = 0;
40,718✔
477
   for(size_t i = 0; i != 4; ++i) {
203,590✔
478
      out = (out << 8) | integer.byte_at(3 - i);
162,872✔
479
   }
480

481
   return (*this);
40,718✔
482
}
40,856✔
483

484
/*
485
* Decode a small BER encoded INTEGER
486
*/
487
uint64_t BER_Decoder::decode_constrained_integer(ASN1_Type type_tag, ASN1_Class class_tag, size_t T_bytes) {
3,608✔
488
   if(T_bytes > 8) {
3,608✔
489
      throw BER_Decoding_Error("Can't decode small integer over 8 bytes");
×
490
   }
491

492
   BigInt integer;
3,608✔
493
   decode(integer, type_tag, class_tag);
3,608✔
494

495
   if(integer.is_negative()) {
3,608✔
496
      throw BER_Decoding_Error("Decoded small integer value was negative");
×
497
   }
498

499
   if(integer.bits() > 8 * T_bytes) {
3,608✔
500
      throw BER_Decoding_Error("Decoded integer value larger than expected");
×
501
   }
502

503
   uint64_t out = 0;
504
   for(size_t i = 0; i != 8; ++i) {
32,472✔
505
      out = (out << 8) | integer.byte_at(7 - i);
28,864✔
506
   }
507

508
   return out;
3,608✔
509
}
3,608✔
510

511
/*
512
* Decode a BER encoded INTEGER
513
*/
514
BER_Decoder& BER_Decoder::decode(BigInt& out, ASN1_Type type_tag, ASN1_Class class_tag) {
126,109✔
515
   const BER_Object obj = get_next_object();
126,109✔
516
   obj.assert_is_a(type_tag, class_tag);
125,348✔
517

518
   // DER requires minimal INTEGER encoding (X.690 section 8.3.2)
519
   if(m_limits.require_der_encoding()) {
124,353✔
520
      if(obj.length() == 0) {
116,957✔
521
         throw BER_Decoding_Error("Detected empty INTEGER encoding in DER structure");
76✔
522
      }
523
      if(obj.length() > 1) {
116,881✔
524
         if(obj.bits()[0] == 0x00 && (obj.bits()[1] & 0x80) == 0) {
71,545✔
525
            throw BER_Decoding_Error("Detected non-minimal INTEGER encoding in DER structure");
292✔
526
         }
527
         if(obj.bits()[0] == 0xFF && (obj.bits()[1] & 0x80) != 0) {
71,253✔
528
            throw BER_Decoding_Error("Detected non-minimal INTEGER encoding in DER structure");
31✔
529
         }
530
      }
531
   }
532

533
   if(obj.length() == 0) {
123,954✔
534
      out.clear();
693✔
535
   } else {
536
      const uint8_t first = obj.bits()[0];
123,261✔
537
      const bool negative = (first & 0x80) == 0x80;
123,261✔
538

539
      if(negative) {
123,261✔
540
         secure_vector<uint8_t> vec(obj.bits(), obj.bits() + obj.length());
5,144✔
541
         for(size_t i = obj.length(); i > 0; --i) {
8,961✔
542
            const bool gt0 = (vec[i - 1] > 0);
8,961✔
543
            vec[i - 1] -= 1;
8,961✔
544
            if(gt0) {
8,961✔
545
               break;
546
            }
547
         }
548
         for(size_t i = 0; i != obj.length(); ++i) {
34,896✔
549
            vec[i] = ~vec[i];
29,752✔
550
         }
551
         out._assign_from_bytes(vec);
5,144✔
552
         out.flip_sign();
10,288✔
553
      } else {
5,144✔
554
         out._assign_from_bytes(obj.data());
118,117✔
555
      }
556
   }
557

558
   return (*this);
123,954✔
559
}
125,348✔
560

561
namespace {
562

563
bool is_constructed(const BER_Object& obj) {
195,895✔
564
   return is_constructed(obj.class_tag());
195,895✔
565
}
566

567
template <typename Alloc>
568
void asn1_decode_binary_string(std::vector<uint8_t, Alloc>& buffer,
200,404✔
569
                               const BER_Object& obj,
570
                               ASN1_Type real_type,
571
                               ASN1_Type type_tag,
572
                               ASN1_Class class_tag,
573
                               bool require_der) {
574
   obj.assert_is_a(type_tag, class_tag);
200,404✔
575

576
   // DER requires BIT STRING and OCTET STRING to use primitive encoding
577
   if(require_der && is_constructed(obj)) {
200,310✔
578
      throw BER_Decoding_Error("Detected constructed string encoding in DER structure");
×
579
   }
580

581
   if(real_type == ASN1_Type::OctetString) {
200,310✔
582
      buffer.assign(obj.bits(), obj.bits() + obj.length());
133,286✔
583
   } else {
584
      if(obj.length() == 0) {
67,024✔
585
         throw BER_Decoding_Error("Invalid BIT STRING");
6✔
586
      }
587

588
      const uint8_t unused_bits = obj.bits()[0];
67,018✔
589

590
      if(unused_bits >= 8) {
67,018✔
591
         throw BER_Decoding_Error("Bad number of unused bits in BIT STRING");
25✔
592
      }
593

594
      // Empty BIT STRING with unused bits > 0 ...
595
      if(unused_bits > 0 && obj.length() < 2) {
66,993✔
596
         throw BER_Decoding_Error("Invalid BIT STRING");
6✔
597
      }
598

599
      // DER requires unused bits in BIT STRING to be zero (X.690 section 11.2.2)
600
      if(require_der && unused_bits > 0) {
66,987✔
601
         const uint8_t last_byte = obj.bits()[obj.length() - 1];
489✔
602
         if((last_byte & ((1 << unused_bits) - 1)) != 0) {
489✔
603
            throw BER_Decoding_Error("Detected non-zero padding bits in BIT STRING in DER structure");
124✔
604
         }
605
      }
606

607
      buffer.resize(obj.length() - 1);
66,863✔
608

609
      if(obj.length() > 1) {
66,863✔
610
         copy_mem(buffer.data(), obj.bits() + 1, obj.length() - 1);
66,070✔
611
      }
612
   }
613
}
200,149✔
614

615
}  // namespace
616

617
/*
618
* BER decode a BIT STRING or OCTET STRING
619
*/
620
BER_Decoder& BER_Decoder::decode(secure_vector<uint8_t>& buffer,
11,029✔
621
                                 ASN1_Type real_type,
622
                                 ASN1_Type type_tag,
623
                                 ASN1_Class class_tag) {
624
   if(real_type != ASN1_Type::OctetString && real_type != ASN1_Type::BitString) {
11,029✔
625
      throw BER_Bad_Tag("Bad tag for {BIT,OCTET} STRING", static_cast<uint32_t>(real_type));
×
626
   }
627

628
   asn1_decode_binary_string(
10,973✔
629
      buffer, get_next_object(), real_type, type_tag, class_tag, m_limits.require_der_encoding());
22,002✔
630
   return (*this);
10,971✔
631
}
632

633
BER_Decoder& BER_Decoder::decode(std::vector<uint8_t>& buffer,
191,658✔
634
                                 ASN1_Type real_type,
635
                                 ASN1_Type type_tag,
636
                                 ASN1_Class class_tag) {
637
   if(real_type != ASN1_Type::OctetString && real_type != ASN1_Type::BitString) {
191,658✔
638
      throw BER_Bad_Tag("Bad tag for {BIT,OCTET} STRING", static_cast<uint32_t>(real_type));
1,533✔
639
   }
640

641
   asn1_decode_binary_string(
189,431✔
642
      buffer, get_next_object(), real_type, type_tag, class_tag, m_limits.require_der_encoding());
379,556✔
643
   return (*this);
189,178✔
644
}
645

646
}  // 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