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

randombit / botan / 25457312714

06 May 2026 07:43PM UTC coverage: 89.331% (-2.3%) from 91.667%
25457312714

push

github

randombit
In TLS 1.3 verification of client certs, check the correct extension for OCSP

This was checking if the client asked us (the server) for OCSP, instead of
checking if we asked the client for OCSP when we sent the CertificateRequest.

107574 of 120422 relevant lines covered (89.33%)

11482758.98 hits per line

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

92.86
/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,215,563✔
21
   return (static_cast<uint32_t>(class_tag) & static_cast<uint32_t>(ASN1_Class::Constructed)) != 0;
7,215,563✔
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) {
6,853,255✔
28
   auto b = ber->read_byte();
6,853,255✔
29

30
   if(!b) {
6,853,255✔
31
      type_tag = ASN1_Type::NoObject;
46,750✔
32
      class_tag = ASN1_Class::NoObject;
46,750✔
33
      return 0;
46,750✔
34
   }
35

36
   if((*b & 0x1F) != 0x1F) {
6,806,505✔
37
      type_tag = ASN1_Type(*b & 0x1F);
6,805,287✔
38
      class_tag = ASN1_Class(*b & 0xE0);
6,805,287✔
39
      return 1;
6,805,287✔
40
   }
41

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

45
   uint32_t tag_buf = 0;
1,218✔
46
   while(true) {
2,362✔
47
      b = ber->read_byte();
2,362✔
48
      if(!b) {
2,362✔
49
         throw BER_Decoding_Error("Long-form tag truncated");
69✔
50
      }
51
      if((tag_buf >> 24) != 0) {
2,293✔
52
         throw BER_Decoding_Error("Long-form tag overflowed 32 bits");
5✔
53
      }
54
      // This is required even by BER (see X.690 section 8.1.2.4.2 sentence c).
55
      // Bits 7-1 of the first subsequent octet must not be all zero; this rules
56
      // out both 0x80 (continuation with no data) and 0x00 (a long-form encoding
57
      // of tag value 0, which collides with the EOC marker).
58
      if(tag_bytes == 1 && (*b & 0x7F) == 0) {
2,288✔
59
         throw BER_Decoding_Error("Long form tag with leading zero");
8✔
60
      }
61
      ++tag_bytes;
2,280✔
62
      tag_buf = (tag_buf << 7) | (*b & 0x7F);
2,280✔
63
      if((*b & 0x80) == 0) {
2,280✔
64
         break;
65
      }
66
   }
67
   // Per X.690 8.1.2.2, tag values 0-30 shall be encoded in the short form.
68
   // Long-form encoding is reserved for tag values >= 31 (X.690 8.1.2.3).
69
   // This is unconditional and applies to BER as well as DER.
70
   if(tag_buf <= 30) {
1,136✔
71
      throw BER_Decoding_Error("Long-form tag encoding used for small tag value");
35✔
72
   }
73

74
   if(tag_buf == static_cast<uint32_t>(ASN1_Type::NoObject)) {
1,101✔
75
      throw BER_Decoding_Error("Tag value collides with internal sentinel");
8✔
76
   }
77

78
   // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
79
   type_tag = ASN1_Type(tag_buf);
1,093✔
80
   return tag_bytes;
1,093✔
81
}
82

83
/*
84
* Find the EOC marker by scanning TLVs via peek, without buffering.
85
* Returns the number of bytes before and including the EOC marker.
86
*/
87
size_t find_eoc(DataSource* src, size_t base_offset, size_t allow_indef);
88

89
/*
90
* Result of decoding a BER length field.
91
*
92
* If indefinite is true, indefinite-length encoding was used: content_length
93
* is the number of content bytes (excluding the 2-byte EOC marker) and the
94
* caller must consume the EOC bytes after reading the content.
95
*/
96
class BerDecodedLength final {
97
   public:
98
      BerDecodedLength(size_t content_length, size_t field_length) :
6,783,521✔
99
            BerDecodedLength(content_length, field_length, false) {}
6,783,521✔
100

101
      static BerDecodedLength indefinite(size_t content_length, size_t field_length) {
14,009✔
102
         return BerDecodedLength(content_length, field_length, true);
14,009✔
103
      }
104

105
      size_t content_length() const { return m_content_length; }
11,797,733✔
106

107
      // Length plus the EOC bytes if an indefinite length field
108
      size_t total_length() const { return m_indefinite ? m_content_length + 2 : m_content_length; }
6,796,546✔
109

110
      size_t field_length() const { return m_field_length; }
111

112
      bool indefinite_length() const { return m_indefinite; }
5,002,435✔
113

114
   private:
115
      BerDecodedLength(size_t content_length, size_t field_length, bool indefinite) :
6,797,530✔
116
            m_content_length(content_length), m_field_length(field_length), m_indefinite(indefinite) {}
6,797,530✔
117

118
      size_t m_content_length;
119
      size_t m_field_length;
120
      bool m_indefinite;
121
};
122

123
/*
124
* BER decode an ASN.1 length field
125
*/
126
BerDecodedLength decode_length(DataSource* ber, size_t allow_indef, bool der_mode, bool constructed) {
6,806,380✔
127
   uint8_t b = 0;
6,806,380✔
128
   if(ber->read_byte(b) == 0) {
6,806,380✔
129
      throw BER_Decoding_Error("Length field not found");
324✔
130
   }
131
   if((b & 0x80) == 0) {
6,806,056✔
132
      return BerDecodedLength(b, 1);
6,580,991✔
133
   }
134

135
   const size_t num_length_bytes = (b & 0x7F);
225,065✔
136
   if(num_length_bytes > 4) {
225,065✔
137
      throw BER_Decoding_Error("Length field is too large");
502✔
138
   }
139

140
   const size_t field_size = 1 + num_length_bytes;
224,563✔
141

142
   if(num_length_bytes == 0) {
224,563✔
143
      if(der_mode) {
21,443✔
144
         throw BER_Decoding_Error("Detected indefinite-length encoding in DER structure");
6,718✔
145
      } else if(!constructed) {
14,725✔
146
         // Indefinite length is only valid for constructed types (X.690 8.1.3.2)
147
         throw BER_Decoding_Error("Indefinite-length encoding used with non-constructed type");
108✔
148
      } else if(allow_indef == 0) {
14,617✔
149
         throw BER_Decoding_Error("Nested EOC markers too deep, rejecting to avoid stack exhaustion");
×
150
      } else {
151
         // find_eoc returns bytes up to and including the EOC marker.
152
         // Return the content length; the caller consumes the EOC separately.
153
         const size_t eoc_len = find_eoc(ber, /*base_offset=*/0, allow_indef - 1);
14,617✔
154
         if(eoc_len < 2) {
14,009✔
155
            throw BER_Decoding_Error("Invalid EOC encoding");
×
156
         }
157
         return BerDecodedLength::indefinite(eoc_len - 2, field_size);
14,009✔
158
      }
159
   }
160

161
   size_t length = 0;
162

163
   for(size_t i = 0; i != num_length_bytes; ++i) {
559,597✔
164
      if(ber->read_byte(b) == 0) {
356,529✔
165
         throw BER_Decoding_Error("Corrupted length field");
52✔
166
      }
167
      // Can't overflow since we already checked that num_length_bytes <= 4
168
      length = (length << 8) | b;
356,477✔
169
   }
170

171
   // DER requires shortest possible length encoding
172
   if(der_mode) {
203,068✔
173
      if(length < 128) {
202,489✔
174
         throw BER_Decoding_Error("Detected non-canonical length encoding in DER structure");
401✔
175
      }
176
      if(num_length_bytes > 1 && length < (size_t(1) << ((num_length_bytes - 1) * 8))) {
202,088✔
177
         throw BER_Decoding_Error("Detected non-canonical length encoding in DER structure");
137✔
178
      }
179
   }
180

181
   return BerDecodedLength(length, field_size);
202,530✔
182
}
183

184
/*
185
* Peek a tag from the source at the given offset without consuming any data.
186
* Returns the number of bytes consumed by the tag, or 0 on EOF.
187
*/
188
size_t peek_tag(DataSource* src, size_t offset, ASN1_Type& type_tag, ASN1_Class& class_tag) {
198,709✔
189
   uint8_t b = 0;
198,709✔
190
   if(src->peek(&b, 1, offset) == 0) {
198,709✔
191
      type_tag = ASN1_Type::NoObject;
225✔
192
      class_tag = ASN1_Class::NoObject;
225✔
193
      return 0;
225✔
194
   }
195

196
   if((b & 0x1F) != 0x1F) {
198,484✔
197
      type_tag = ASN1_Type(b & 0x1F);
197,955✔
198
      class_tag = ASN1_Class(b & 0xE0);
197,955✔
199
      return 1;
197,955✔
200
   }
201

202
   class_tag = ASN1_Class(b & 0xE0);
529✔
203
   size_t tag_bytes = 1;
529✔
204
   uint32_t tag_buf = 0;
529✔
205

206
   while(true) {
867✔
207
      if(src->peek(&b, 1, offset + tag_bytes) == 0) {
867✔
208
         throw BER_Decoding_Error("Long-form tag truncated");
6✔
209
      }
210
      if((tag_buf >> 24) != 0) {
861✔
211
         throw BER_Decoding_Error("Long-form tag overflowed 32 bits");
×
212
      }
213
      // Required even by BER (X.690 section 8.1.2.4.2 sentence c).
214
      // Bits 7-1 of the first subsequent octet must not be all zero; this rules
215
      // out both 0x80 (continuation with no data) and 0x00 (a long-form encoding
216
      // of tag value 0, which collides with the EOC marker).
217
      if(tag_bytes == 1 && (b & 0x7F) == 0) {
861✔
218
         throw BER_Decoding_Error("Long form tag with leading zero");
67✔
219
      }
220
      ++tag_bytes;
794✔
221
      tag_buf = (tag_buf << 7) | (b & 0x7F);
794✔
222
      if((b & 0x80) == 0) {
794✔
223
         break;
224
      }
225
   }
226

227
   // Per X.690 8.1.2.2, tag values 0-30 shall be encoded in the short form.
228
   // Long-form encoding is reserved for tag values >= 31 (X.690 8.1.2.3).
229
   // This is unconditional and applies to BER as well as DER.
230
   if(tag_buf <= 30) {
456✔
231
      throw BER_Decoding_Error("Long-form tag encoding used for small tag value");
10✔
232
   }
233

234
   if(tag_buf == static_cast<uint32_t>(ASN1_Type::NoObject)) {
446✔
235
      throw BER_Decoding_Error("Tag value collides with internal sentinel");
×
236
   }
237

238
   // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
239
   type_tag = ASN1_Type(tag_buf);
446✔
240
   return tag_bytes;
446✔
241
}
242

243
/*
244
* Peek a length from the source at the given offset without consuming any data.
245
* Returns the decoded length and sets field_size to the number of bytes consumed.
246
* For indefinite-length encoding, recursively scans ahead to find the EOC marker.
247
*/
248
size_t peek_length(DataSource* src, size_t offset, size_t& field_size, size_t allow_indef, bool constructed) {
198,401✔
249
   uint8_t b = 0;
198,401✔
250
   if(src->peek(&b, 1, offset) == 0) {
198,401✔
251
      throw BER_Decoding_Error("Length field not found");
71✔
252
   }
253

254
   field_size = 1;
198,330✔
255
   if((b & 0x80) == 0) {
198,330✔
256
      return b;
145,518✔
257
   }
258

259
   const size_t num_length_bytes = (b & 0x7F);
52,812✔
260
   field_size += num_length_bytes;
52,812✔
261
   if(field_size > 5) {
52,812✔
262
      throw BER_Decoding_Error("Length field is too large");
58✔
263
   }
264

265
   if(num_length_bytes == 0) {
52,754✔
266
      // Indefinite length is only valid for constructed types (X.690 8.1.3.2)
267
      if(!constructed) {
52,061✔
268
         throw BER_Decoding_Error("Indefinite-length encoding used with non-constructed type");
32✔
269
      }
270
      if(allow_indef == 0) {
52,029✔
271
         throw BER_Decoding_Error("Nested EOC markers too deep, rejecting to avoid stack exhaustion");
8✔
272
      }
273
      return find_eoc(src, offset + 1, allow_indef - 1);
52,021✔
274
   }
275

276
   size_t length = 0;
277
   for(size_t i = 0; i < num_length_bytes; ++i) {
1,417✔
278
      if(src->peek(&b, 1, offset + 1 + i) == 0) {
724✔
279
         throw BER_Decoding_Error("Corrupted length field");
×
280
      }
281
      if(get_byte<0>(length) != 0) {
724✔
282
         throw BER_Decoding_Error("Field length overflow");
×
283
      }
284
      length = (length << 8) | b;
724✔
285
   }
286
   return length;
287
}
288

289
/*
290
* Find the EOC marker by scanning TLVs via peek, without buffering.
291
* Returns the number of bytes before and including the EOC marker.
292
*/
293
size_t find_eoc(DataSource* src, size_t base_offset, size_t allow_indef) {
66,638✔
294
   size_t offset = base_offset;
66,638✔
295

296
   while(true) {
330,780✔
297
      ASN1_Type type_tag = ASN1_Type::NoObject;
198,709✔
298
      ASN1_Class class_tag = ASN1_Class::NoObject;
198,709✔
299
      const size_t tag_size = peek_tag(src, offset, type_tag, class_tag);
198,709✔
300
      if(type_tag == ASN1_Type::NoObject) {
198,626✔
301
         throw BER_Decoding_Error("Missing EOC marker in indefinite-length encoding");
225✔
302
      }
303

304
      size_t length_size = 0;
198,401✔
305
      const size_t item_size = peek_length(src, offset + tag_size, length_size, allow_indef, is_constructed(class_tag));
198,401✔
306

307
      if(auto new_offset = checked_add(offset, tag_size, length_size, item_size)) {
394,636✔
308
         offset = new_offset.value();
197,318✔
309
      } else {
310
         throw Decoding_Error("Integer overflow while scanning for EOC");
×
311
      }
312

313
      if(type_tag == ASN1_Type::Eoc && class_tag == ASN1_Class::Universal) {
197,318✔
314
         // Per X.690 8.1.5 the EOC marker is exactly two zero octets
315
         if(length_size != 1 || item_size != 0) {
65,247✔
316
            throw BER_Decoding_Error("EOC marker with non-zero length");
131✔
317
         }
318
         break;
65,116✔
319
      }
320
   }
132,071✔
321

322
   return offset - base_offset;
65,116✔
323
}
324

325
class DataSource_BERObject final : public DataSource {
326
   public:
327
      size_t read(uint8_t out[], size_t length) override {
24,528,609✔
328
         BOTAN_ASSERT_NOMSG(m_offset <= m_obj.length());
24,528,609✔
329
         const size_t got = std::min<size_t>(m_obj.length() - m_offset, length);
24,528,609✔
330
         copy_mem(out, m_obj.bits() + m_offset, got);
24,528,609✔
331
         m_offset += got;
24,528,609✔
332
         return got;
24,528,609✔
333
      }
334

335
      size_t peek(uint8_t out[], size_t length, size_t peek_offset) const override {
4✔
336
         BOTAN_ASSERT_NOMSG(m_offset <= m_obj.length());
4✔
337
         const size_t bytes_left = m_obj.length() - m_offset;
4✔
338

339
         if(peek_offset >= bytes_left) {
4✔
340
            return 0;
341
         }
342

343
         const size_t got = std::min(bytes_left - peek_offset, length);
4✔
344
         copy_mem(out, m_obj.bits() + m_offset + peek_offset, got);
4✔
345
         return got;
4✔
346
      }
347

348
      bool check_available(size_t n) override {
1,138,407✔
349
         BOTAN_ASSERT_NOMSG(m_offset <= m_obj.length());
1,138,407✔
350
         return (n <= (m_obj.length() - m_offset));
1,138,407✔
351
      }
352

353
      bool end_of_data() const override { return get_bytes_read() == m_obj.length(); }
1,012,255✔
354

355
      size_t get_bytes_read() const override { return m_offset; }
1,012,255✔
356

357
      explicit DataSource_BERObject(BER_Object&& obj) : m_obj(std::move(obj)) {}
735,445✔
358

359
   private:
360
      BER_Object m_obj;
361
      size_t m_offset = 0;
362
};
363

364
}  // namespace
365

366
BER_Decoder::~BER_Decoder() = default;
2,200,739✔
367

368
/*
369
* Check if more objects are there
370
*/
371
bool BER_Decoder::more_items() const {
629,823✔
372
   if(m_source->end_of_data() && !m_pushed.is_set()) {
629,823✔
373
      return false;
230,025✔
374
   }
375
   return true;
376
}
377

378
/*
379
* Verify that no bytes remain in the source
380
*/
381
BER_Decoder& BER_Decoder::verify_end() {
221,981✔
382
   return verify_end("BER_Decoder::verify_end called, but data remains");
221,981✔
383
}
384

385
/*
386
* Verify that no bytes remain in the source
387
*/
388
BER_Decoder& BER_Decoder::verify_end(std::string_view err) {
243,082✔
389
   if(!m_source->end_of_data() || m_pushed.is_set()) {
243,082✔
390
      throw Decoding_Error(err);
434✔
391
   }
392
   return (*this);
242,648✔
393
}
394

395
/*
396
* Discard all the bytes remaining in the source
397
*/
398
BER_Decoder& BER_Decoder::discard_remaining() {
18,824✔
399
   m_pushed = BER_Object();
18,824✔
400
   uint8_t buf = 0;
18,824✔
401
   while(m_source->read_byte(buf) != 0) {}
147,154✔
402
   return (*this);
18,824✔
403
}
404

405
std::optional<uint8_t> BER_Decoder::read_next_byte() {
20,776,348✔
406
   BOTAN_ASSERT_NOMSG(m_source != nullptr);
20,776,348✔
407
   uint8_t b = 0;
20,776,348✔
408
   if(m_source->read_byte(b) != 0) {
20,776,348✔
409
      return b;
20,598,403✔
410
   } else {
411
      return {};
177,945✔
412
   }
413
}
414

415
const BER_Object& BER_Decoder::peek_next_object() {
30,084✔
416
   if(!m_pushed.is_set()) {
30,084✔
417
      m_pushed = get_next_object();
30,017✔
418
   }
419

420
   return m_pushed;
30,053✔
421
}
422

423
/*
424
* Return the BER encoding of the next object
425
*/
426
BER_Object BER_Decoder::get_next_object() {
2,035,994✔
427
   BER_Object next;
2,035,994✔
428

429
   if(m_pushed.is_set()) {
2,035,994✔
430
      std::swap(next, m_pushed);
184,182✔
431
      return next;
184,182✔
432
   }
433

434
   for(;;) {
11,854,698✔
435
      ASN1_Type type_tag = ASN1_Type::NoObject;
6,853,255✔
436
      ASN1_Class class_tag = ASN1_Class::NoObject;
6,853,255✔
437
      decode_tag(m_source, type_tag, class_tag);
6,853,255✔
438
      next.set_tagging(type_tag, class_tag);
6,853,130✔
439
      if(next.is_set() == false) {  // no more objects
6,853,130✔
440
         return next;
46,750✔
441
      }
442

443
      const size_t allow_indef = m_limits.allow_ber_encoding() ? m_limits.max_nested_indefinite_length() : 0;
6,806,380✔
444
      const bool der_mode = m_limits.require_der_encoding();
6,806,380✔
445
      const auto dl = decode_length(m_source, allow_indef, der_mode, is_constructed(class_tag));
6,806,380✔
446

447
      // Per X.690 8.1.5 the only valid EOC encoding is the two-octet
448
      // sequence 0x00 0x00. Reject any other length encoding on a tag of
449
      // (Eoc, Universal) before we consume the "content" bytes.
450
      if(type_tag == ASN1_Type::Eoc && class_tag == ASN1_Class::Universal &&
6,797,530✔
451
         (dl.content_length() != 0 || dl.indefinite_length())) {
5,003,419✔
452
         throw BER_Decoding_Error("EOC marker with non-zero length");
984✔
453
      }
454

455
      if(!m_source->check_available(dl.total_length())) {
13,593,092✔
456
         throw BER_Decoding_Error("Value truncated");
2,232✔
457
      }
458

459
      uint8_t* out = next.mutable_bits(dl.content_length());
6,794,314✔
460
      if(m_source->read(out, dl.content_length()) != dl.content_length()) {
6,794,314✔
461
         throw BER_Decoding_Error("Value truncated");
×
462
      }
463

464
      if(dl.indefinite_length()) {
6,794,314✔
465
         // After reading the data consume the 2-byte EOC
466
         uint8_t eoc[2] = {0xFF, 0xFF};
14,009✔
467
         if(m_source->read(eoc, 2) != 2 || eoc[0] != 0x00 || eoc[1] != 0x00) {
14,009✔
468
            throw BER_Decoding_Error("Missing or malformed EOC marker");
×
469
         }
470
      }
471

472
      if(next.tagging() == static_cast<uint32_t>(ASN1_Type::Eoc)) {
6,794,314✔
473
         if(m_limits.require_der_encoding()) {
5,002,435✔
474
            throw BER_Decoding_Error("Detected EOC marker in DER structure");
992✔
475
         }
476
         continue;
5,001,443✔
477
      } else {
478
         break;
479
      }
480
   }
481

482
   return next;
1,791,879✔
483
}
13,183✔
484

485
BER_Object BER_Decoder::get_next_value(size_t sizeofT, ASN1_Type type_tag, ASN1_Class class_tag) {
×
486
   const BER_Object obj = get_next_object();
×
487
   obj.assert_is_a(type_tag, class_tag);
×
488

489
   if(obj.length() != sizeofT) {
×
490
      throw BER_Decoding_Error("Size mismatch. Object value size is " + std::to_string(obj.length()) +
×
491
                               "; Output type size is " + std::to_string(sizeofT));
×
492
   }
493

494
   return obj;
×
495
}
×
496

497
/*
498
* Push a object back into the stream
499
*/
500
void BER_Decoder::push_back(const BER_Object& obj) {
26✔
501
   if(m_pushed.is_set()) {
26✔
502
      throw Invalid_State("BER_Decoder: Only one push back is allowed");
×
503
   }
504
   m_pushed = obj;
26✔
505
}
26✔
506

507
void BER_Decoder::push_back(BER_Object&& obj) {
178,779✔
508
   if(m_pushed.is_set()) {
178,779✔
509
      throw Invalid_State("BER_Decoder: Only one push back is allowed");
×
510
   }
511
   m_pushed = std::move(obj);
178,779✔
512
}
178,779✔
513

514
BER_Decoder BER_Decoder::start_cons(ASN1_Type type_tag, ASN1_Class class_tag) {
744,507✔
515
   BER_Object obj = get_next_object();
744,507✔
516
   obj.assert_is_a(type_tag, class_tag | ASN1_Class::Constructed);
736,234✔
517
   BER_Decoder child(std::move(obj), this);
735,445✔
518
   return child;
735,445✔
519
}
736,234✔
520

521
/*
522
* Finish decoding a CONSTRUCTED type
523
*/
524
BER_Decoder& BER_Decoder::end_cons() {
552,061✔
525
   if(m_parent == nullptr) {
552,061✔
526
      throw Invalid_State("BER_Decoder::end_cons called with null parent");
×
527
   }
528
   if(!m_source->end_of_data() || m_pushed.is_set()) {
552,061✔
529
      throw Decoding_Error("BER_Decoder::end_cons called with data left");
240✔
530
   }
531
   return (*m_parent);
551,821✔
532
}
533

534
BER_Decoder::BER_Decoder(BER_Object&& obj, BER_Decoder* parent) :
735,445✔
535
      m_limits(parent != nullptr ? parent->limits() : BER_Decoder::Limits::BER()), m_parent(parent) {
735,445✔
536
   m_data_src = std::make_unique<DataSource_BERObject>(std::move(obj));
735,445✔
537
   m_source = m_data_src.get();
735,445✔
538
}
735,445✔
539

540
/*
541
* BER_Decoder Constructor
542
*/
543
BER_Decoder::BER_Decoder(DataSource& src, Limits limits) : m_limits(limits), m_source(&src) {}
48,813✔
544

545
/*
546
* BER_Decoder Constructor
547
 */
548
BER_Decoder::BER_Decoder(std::span<const uint8_t> buf, Limits limits) : m_limits(limits) {
340,518✔
549
   m_data_src = std::make_unique<DataSource_Memory>(buf);
340,518✔
550
   m_source = m_data_src.get();
340,518✔
551
}
340,518✔
552

553
BER_Decoder::BER_Decoder(BER_Decoder&& other) noexcept = default;
×
554

555
BER_Decoder& BER_Decoder::operator=(BER_Decoder&&) noexcept = default;
×
556

557
/*
558
* Request for an object to decode itself
559
*/
560
BER_Decoder& BER_Decoder::decode(ASN1_Object& obj, ASN1_Type /*unused*/, ASN1_Class /*unused*/) {
732,174✔
561
   obj.decode_from(*this);
732,174✔
562
   return (*this);
726,085✔
563
}
564

565
/*
566
* Decode a BER encoded NULL
567
*/
568
BER_Decoder& BER_Decoder::decode_null() {
205✔
569
   const BER_Object obj = get_next_object();
205✔
570
   obj.assert_is_a(ASN1_Type::Null, ASN1_Class::Universal);
205✔
571
   if(obj.length() > 0) {
205✔
572
      throw BER_Decoding_Error("NULL object had nonzero size");
2✔
573
   }
574
   return (*this);
203✔
575
}
205✔
576

577
BER_Decoder& BER_Decoder::decode_octet_string_bigint(BigInt& out) {
224✔
578
   secure_vector<uint8_t> out_vec;
224✔
579
   decode(out_vec, ASN1_Type::OctetString);
224✔
580
   out = BigInt::from_bytes(out_vec);
224✔
581
   return (*this);
206✔
582
}
206✔
583

584
/*
585
* Decode a BER encoded BOOLEAN
586
*/
587
BER_Decoder& BER_Decoder::decode(bool& out, ASN1_Type type_tag, ASN1_Class class_tag) {
42,761✔
588
   const BER_Object obj = get_next_object();
42,761✔
589
   obj.assert_is_a(type_tag, class_tag);
42,761✔
590

591
   if(obj.length() != 1) {
42,761✔
592
      throw BER_Decoding_Error("BER boolean value had invalid size");
47✔
593
   }
594

595
   const uint8_t val = obj.bits()[0];
42,714✔
596

597
   // DER requires boolean values to be exactly 0x00 or 0xFF
598
   if(m_limits.require_der_encoding() && val != 0x00 && val != 0xFF) {
42,714✔
599
      throw BER_Decoding_Error("Detected non-canonical boolean encoding in DER structure");
44✔
600
   }
601

602
   out = (val != 0) ? true : false;
42,670✔
603

604
   return (*this);
42,670✔
605
}
42,761✔
606

607
/*
608
* Decode a small BER encoded INTEGER
609
*/
610
BER_Decoder& BER_Decoder::decode(size_t& out, ASN1_Type type_tag, ASN1_Class class_tag) {
41,325✔
611
   BigInt integer;
41,325✔
612
   decode(integer, type_tag, class_tag);
41,325✔
613

614
   if(integer.signum() < 0) {
41,235✔
615
      throw BER_Decoding_Error("Decoded small integer value was negative");
29✔
616
   }
617

618
   if(integer.bits() > 32) {
41,206✔
619
      throw BER_Decoding_Error("Decoded integer value larger than expected");
10✔
620
   }
621

622
   out = 0;
41,196✔
623
   for(size_t i = 0; i != 4; ++i) {
205,980✔
624
      out = (out << 8) | integer.byte_at(3 - i);
164,784✔
625
   }
626

627
   return (*this);
41,196✔
628
}
41,325✔
629

630
/*
631
* Decode a small BER encoded INTEGER
632
*/
633
uint64_t BER_Decoder::decode_constrained_integer(ASN1_Type type_tag, ASN1_Class class_tag, size_t T_bytes) {
4,352✔
634
   if(T_bytes > 8) {
4,352✔
635
      throw BER_Decoding_Error("Can't decode small integer over 8 bytes");
×
636
   }
637

638
   BigInt integer;
4,352✔
639
   decode(integer, type_tag, class_tag);
4,352✔
640

641
   if(integer.is_negative()) {
4,352✔
642
      throw BER_Decoding_Error("Decoded small integer value was negative");
×
643
   }
644

645
   if(integer.bits() > 8 * T_bytes) {
4,352✔
646
      throw BER_Decoding_Error("Decoded integer value larger than expected");
×
647
   }
648

649
   uint64_t out = 0;
650
   for(size_t i = 0; i != 8; ++i) {
39,168✔
651
      out = (out << 8) | integer.byte_at(7 - i);
34,816✔
652
   }
653

654
   return out;
4,352✔
655
}
4,352✔
656

657
/*
658
* Decode a BER encoded INTEGER
659
*/
660
BER_Decoder& BER_Decoder::decode(BigInt& out, ASN1_Type type_tag, ASN1_Class class_tag) {
133,364✔
661
   const BER_Object obj = get_next_object();
133,364✔
662
   obj.assert_is_a(type_tag, class_tag);
132,652✔
663

664
   // DER requires minimal INTEGER encoding (X.690 section 8.3.2)
665
   if(m_limits.require_der_encoding()) {
131,660✔
666
      if(obj.length() == 0) {
126,263✔
667
         throw BER_Decoding_Error("Detected empty INTEGER encoding in DER structure");
80✔
668
      }
669
      if(obj.length() > 1) {
126,183✔
670
         if(obj.bits()[0] == 0x00 && (obj.bits()[1] & 0x80) == 0) {
74,461✔
671
            throw BER_Decoding_Error("Detected non-minimal INTEGER encoding in DER structure");
121✔
672
         }
673
         if(obj.bits()[0] == 0xFF && (obj.bits()[1] & 0x80) != 0) {
74,340✔
674
            throw BER_Decoding_Error("Detected non-minimal INTEGER encoding in DER structure");
33✔
675
         }
676
      }
677
   }
678

679
   if(obj.length() == 0) {
131,426✔
680
      out.clear();
659✔
681
   } else {
682
      const uint8_t first = obj.bits()[0];
130,767✔
683
      const bool negative = (first & 0x80) == 0x80;
130,767✔
684

685
      if(negative) {
130,767✔
686
         secure_vector<uint8_t> vec(obj.bits(), obj.bits() + obj.length());
4,764✔
687
         for(size_t i = obj.length(); i > 0; --i) {
8,448✔
688
            const bool gt0 = (vec[i - 1] > 0);
8,448✔
689
            vec[i - 1] -= 1;
8,448✔
690
            if(gt0) {
8,448✔
691
               break;
692
            }
693
         }
694
         for(size_t i = 0; i != obj.length(); ++i) {
33,699✔
695
            vec[i] = ~vec[i];
28,935✔
696
         }
697
         out._assign_from_bytes(vec);
4,764✔
698
         out.flip_sign();
9,528✔
699
      } else {
4,764✔
700
         out._assign_from_bytes(obj.data());
126,003✔
701
      }
702
   }
703

704
   return (*this);
131,426✔
705
}
132,652✔
706

707
namespace {
708

709
bool is_constructed(const BER_Object& obj) {
210,782✔
710
   return is_constructed(obj.class_tag());
210,782✔
711
}
712

713
template <typename Alloc>
714
void asn1_decode_binary_string(std::vector<uint8_t, Alloc>& buffer,
213,962✔
715
                               const BER_Object& obj,
716
                               ASN1_Type real_type,
717
                               ASN1_Type type_tag,
718
                               ASN1_Class class_tag,
719
                               bool require_der) {
720
   obj.assert_is_a(type_tag, class_tag);
213,962✔
721

722
   // DER requires BIT STRING and OCTET STRING to use primitive encoding
723
   if(require_der && is_constructed(obj)) {
213,880✔
724
      throw BER_Decoding_Error("Detected constructed string encoding in DER structure");
×
725
   }
726

727
   if(real_type == ASN1_Type::OctetString) {
213,880✔
728
      buffer.assign(obj.bits(), obj.bits() + obj.length());
129,883✔
729
   } else {
730
      if(obj.length() == 0) {
83,997✔
731
         throw BER_Decoding_Error("Invalid BIT STRING");
3✔
732
      }
733

734
      const uint8_t unused_bits = obj.bits()[0];
83,994✔
735

736
      if(unused_bits >= 8) {
83,994✔
737
         throw BER_Decoding_Error("Bad number of unused bits in BIT STRING");
25✔
738
      }
739

740
      // Empty BIT STRING with unused bits > 0 ...
741
      if(unused_bits > 0 && obj.length() < 2) {
83,969✔
742
         throw BER_Decoding_Error("Invalid BIT STRING");
8✔
743
      }
744

745
      // DER requires unused bits in BIT STRING to be zero (X.690 section 11.2.2)
746
      if(require_der && unused_bits > 0) {
83,961✔
747
         const uint8_t last_byte = obj.bits()[obj.length() - 1];
14,617✔
748
         if((last_byte & ((1 << unused_bits) - 1)) != 0) {
14,617✔
749
            throw BER_Decoding_Error("Detected non-zero padding bits in BIT STRING in DER structure");
129✔
750
         }
751
      }
752

753
      buffer.resize(obj.length() - 1);
83,832✔
754

755
      if(obj.length() > 1) {
83,832✔
756
         copy_mem(buffer.data(), obj.bits() + 1, obj.length() - 1);
83,098✔
757
      }
758
   }
759
}
213,715✔
760

761
}  // namespace
762

763
/*
764
* BER decode a BIT STRING or OCTET STRING
765
*/
766
BER_Decoder& BER_Decoder::decode(secure_vector<uint8_t>& buffer,
11,252✔
767
                                 ASN1_Type real_type,
768
                                 ASN1_Type type_tag,
769
                                 ASN1_Class class_tag) {
770
   if(real_type != ASN1_Type::OctetString && real_type != ASN1_Type::BitString) {
11,252✔
771
      throw BER_Bad_Tag("Bad tag for {BIT,OCTET} STRING", static_cast<uint32_t>(real_type));
×
772
   }
773

774
   asn1_decode_binary_string(
11,226✔
775
      buffer, get_next_object(), real_type, type_tag, class_tag, m_limits.require_der_encoding());
22,478✔
776
   return (*this);
11,224✔
777
}
778

779
BER_Decoder& BER_Decoder::decode(std::vector<uint8_t>& buffer,
204,869✔
780
                                 ASN1_Type real_type,
781
                                 ASN1_Type type_tag,
782
                                 ASN1_Class class_tag) {
783
   if(real_type != ASN1_Type::OctetString && real_type != ASN1_Type::BitString) {
204,869✔
784
      throw BER_Bad_Tag("Bad tag for {BIT,OCTET} STRING", static_cast<uint32_t>(real_type));
1,446✔
785
   }
786

787
   asn1_decode_binary_string(
202,736✔
788
      buffer, get_next_object(), real_type, type_tag, class_tag, m_limits.require_der_encoding());
406,159✔
789
   return (*this);
202,491✔
790
}
791

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