Botan 3.13.0
Crypto and TLS for C&
ber_dec.cpp
Go to the documentation of this file.
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/asn1_utils.h>
13#include <botan/internal/int_utils.h>
14#include <botan/internal/loadstor.h>
15#include <algorithm>
16#include <memory>
17
18namespace Botan {
19
20namespace {
21
22bool is_constructed(ASN1_Class class_tag) {
23 return (static_cast<uint32_t>(class_tag) & static_cast<uint32_t>(ASN1_Class::Constructed)) != 0;
24}
25
26/*
27* BER decode an ASN.1 type tag
28*/
29size_t decode_tag(DataSource* ber, ASN1_Type& type_tag, ASN1_Class& class_tag) {
30 auto b = ber->read_byte();
31
32 if(!b) {
33 type_tag = ASN1_Type::NoObject;
34 class_tag = ASN1_Class::NoObject;
35 return 0;
36 }
37
38 if((*b & 0x1F) != 0x1F) {
39 type_tag = ASN1_Type(*b & 0x1F);
40 class_tag = ASN1_Class(*b & 0xE0);
41 // The EOC marker is primitive; a constructed universal tag 0 has no
42 // valid meaning and would otherwise bypass the EOC handling, which
43 // matches on (Eoc, Universal) exactly
44 if(type_tag == ASN1_Type::Eoc && class_tag == ASN1_Class::Constructed) {
45 throw BER_Decoding_Error("EOC tag with constructed encoding");
46 }
47 return 1;
48 }
49
50 size_t tag_bytes = 1;
51 class_tag = ASN1_Class(*b & 0xE0);
52
53 uint32_t tag_buf = 0;
54 while(true) {
55 b = ber->read_byte();
56 if(!b) {
57 throw BER_Decoding_Error("Long-form tag truncated");
58 }
59 // Reject if shifting in another 7 bits would overflow the uint32_t tag
60 if((tag_buf >> 25) != 0) {
61 throw BER_Decoding_Error("Long-form tag overflowed 32 bits");
62 }
63 // This is required even by BER (see X.690 section 8.1.2.4.2 sentence c).
64 // Bits 7-1 of the first subsequent octet must not be all zero; this rules
65 // out both 0x80 (continuation with no data) and 0x00 (a long-form encoding
66 // of tag value 0, which collides with the EOC marker).
67 if(tag_bytes == 1 && (*b & 0x7F) == 0) {
68 throw BER_Decoding_Error("Long form tag with leading zero");
69 }
70 ++tag_bytes;
71 tag_buf = (tag_buf << 7) | (*b & 0x7F);
72 if((*b & 0x80) == 0) {
73 break;
74 }
75 }
76 // Per X.690 8.1.2.2, tag values 0-30 shall be encoded in the short form.
77 // Long-form encoding is reserved for tag values >= 31 (X.690 8.1.2.3).
78 // This is unconditional and applies to BER as well as DER.
79 if(tag_buf <= 30) {
80 throw BER_Decoding_Error("Long-form tag encoding used for small tag value");
81 }
82
83 if(tag_buf == static_cast<uint32_t>(ASN1_Type::NoObject)) {
84 throw BER_Decoding_Error("Tag value collides with internal sentinel");
85 }
86
87 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
88 type_tag = ASN1_Type(tag_buf);
89 return tag_bytes;
90}
91
92/*
93* Find the EOC marker by scanning TLVs via peek, without buffering.
94* Returns the number of bytes before and including the EOC marker.
95*/
96size_t find_eoc(DataSource* src, size_t base_offset, size_t allow_indef);
97
98/*
99* Result of decoding a BER length field.
100*
101* If indefinite is true, indefinite-length encoding was used: content_length
102* is the number of content bytes (excluding the 2-byte EOC marker) and the
103* caller must consume the EOC bytes after reading the content.
104*/
105class BerDecodedLength final {
106 public:
107 BerDecodedLength(size_t content_length, size_t field_length) :
108 BerDecodedLength(content_length, field_length, false) {}
109
110 static BerDecodedLength indefinite(size_t content_length, size_t field_length) {
111 return BerDecodedLength(content_length, field_length, true);
112 }
113
114 size_t content_length() const { return m_content_length; }
115
116 // Length plus the EOC bytes if an indefinite length field
117 size_t total_length() const { return m_indefinite ? m_content_length + 2 : m_content_length; }
118
119 size_t field_length() const { return m_field_length; }
120
121 bool indefinite_length() const { return m_indefinite; }
122
123 private:
124 BerDecodedLength(size_t content_length, size_t field_length, bool indefinite) :
125 m_content_length(content_length), m_field_length(field_length), m_indefinite(indefinite) {}
126
127 size_t m_content_length;
128 size_t m_field_length;
129 bool m_indefinite;
130};
131
132/*
133* BER decode an ASN.1 length field
134*/
135BerDecodedLength decode_length(DataSource* ber, size_t allow_indef, bool der_mode, bool constructed) {
136 uint8_t b = 0;
137 if(ber->read_byte(b) == 0) {
138 throw BER_Decoding_Error("Length field not found");
139 }
140 if((b & 0x80) == 0) {
141 return BerDecodedLength(b, 1);
142 }
143
144 const size_t num_length_bytes = (b & 0x7F);
145 if(num_length_bytes > 4) {
146 throw BER_Decoding_Error("Length field is too large");
147 }
148
149 const size_t field_size = 1 + num_length_bytes;
150
151 if(num_length_bytes == 0) {
152 if(der_mode) {
153 throw BER_Decoding_Error("Detected indefinite-length encoding in DER structure");
154 } else if(!constructed) {
155 // Indefinite length is only valid for constructed types (X.690 8.1.3.2)
156 throw BER_Decoding_Error("Indefinite-length encoding used with non-constructed type");
157 } else if(allow_indef == 0) {
158 throw BER_Decoding_Error("Nested EOC markers too deep, rejecting to avoid stack exhaustion");
159 } else {
160 // find_eoc returns bytes up to and including the EOC marker.
161 // Return the content length; the caller consumes the EOC separately.
162 const size_t eoc_len = find_eoc(ber, /*base_offset=*/0, allow_indef - 1);
163 if(eoc_len < 2) {
164 throw BER_Decoding_Error("Invalid EOC encoding");
165 }
166 return BerDecodedLength::indefinite(eoc_len - 2, field_size);
167 }
168 }
169
170 size_t length = 0;
171
172 for(size_t i = 0; i != num_length_bytes; ++i) {
173 if(ber->read_byte(b) == 0) {
174 throw BER_Decoding_Error("Corrupted length field");
175 }
176 // Can't overflow since we already checked that num_length_bytes <= 4
177 length = (length << 8) | b;
178 }
179
180 // DER requires shortest possible length encoding
181 if(der_mode) {
182 if(length < 128) {
183 throw BER_Decoding_Error("Detected non-canonical length encoding in DER structure");
184 }
185 if(num_length_bytes > 1 && length < (size_t(1) << ((num_length_bytes - 1) * 8))) {
186 throw BER_Decoding_Error("Detected non-canonical length encoding in DER structure");
187 }
188 }
189
190 return BerDecodedLength(length, field_size);
191}
192
193/*
194* Peek a tag from the source at the given offset without consuming any data.
195* Returns the number of bytes consumed by the tag, or 0 on EOF.
196*/
197size_t peek_tag(DataSource* src, size_t offset, ASN1_Type& type_tag, ASN1_Class& class_tag) {
198 uint8_t b = 0;
199 if(src->peek(&b, 1, offset) == 0) {
200 type_tag = ASN1_Type::NoObject;
201 class_tag = ASN1_Class::NoObject;
202 return 0;
203 }
204
205 if((b & 0x1F) != 0x1F) {
206 type_tag = ASN1_Type(b & 0x1F);
207 class_tag = ASN1_Class(b & 0xE0);
208 // The EOC marker is primitive; a constructed universal tag 0 has no
209 // valid meaning and would otherwise bypass the EOC handling, which
210 // matches on (Eoc, Universal) exactly
211 if(type_tag == ASN1_Type::Eoc && class_tag == ASN1_Class::Constructed) {
212 throw BER_Decoding_Error("EOC tag with constructed encoding");
213 }
214 return 1;
215 }
216
217 class_tag = ASN1_Class(b & 0xE0);
218 size_t tag_bytes = 1;
219 uint32_t tag_buf = 0;
220
221 while(true) {
222 if(src->peek(&b, 1, offset + tag_bytes) == 0) {
223 throw BER_Decoding_Error("Long-form tag truncated");
224 }
225 // Reject if shifting in another 7 bits would overflow the uint32_t tag
226 if((tag_buf >> 25) != 0) {
227 throw BER_Decoding_Error("Long-form tag overflowed 32 bits");
228 }
229 // Required even by BER (X.690 section 8.1.2.4.2 sentence c).
230 // Bits 7-1 of the first subsequent octet must not be all zero; this rules
231 // out both 0x80 (continuation with no data) and 0x00 (a long-form encoding
232 // of tag value 0, which collides with the EOC marker).
233 if(tag_bytes == 1 && (b & 0x7F) == 0) {
234 throw BER_Decoding_Error("Long form tag with leading zero");
235 }
236 ++tag_bytes;
237 tag_buf = (tag_buf << 7) | (b & 0x7F);
238 if((b & 0x80) == 0) {
239 break;
240 }
241 }
242
243 // Per X.690 8.1.2.2, tag values 0-30 shall be encoded in the short form.
244 // Long-form encoding is reserved for tag values >= 31 (X.690 8.1.2.3).
245 // This is unconditional and applies to BER as well as DER.
246 if(tag_buf <= 30) {
247 throw BER_Decoding_Error("Long-form tag encoding used for small tag value");
248 }
249
250 if(tag_buf == static_cast<uint32_t>(ASN1_Type::NoObject)) {
251 throw BER_Decoding_Error("Tag value collides with internal sentinel");
252 }
253
254 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
255 type_tag = ASN1_Type(tag_buf);
256 return tag_bytes;
257}
258
259/*
260* Peek a length from the source at the given offset without consuming any data.
261* Returns the decoded length and sets field_size to the number of bytes consumed.
262* For indefinite-length encoding, recursively scans ahead to find the EOC marker.
263*/
264size_t peek_length(
265 DataSource* src, size_t offset, size_t& field_size, size_t allow_indef, bool constructed, bool der_mode) {
266 uint8_t b = 0;
267 if(src->peek(&b, 1, offset) == 0) {
268 throw BER_Decoding_Error("Length field not found");
269 }
270
271 field_size = 1;
272 if((b & 0x80) == 0) {
273 return b;
274 }
275
276 const size_t num_length_bytes = (b & 0x7F);
277 field_size += num_length_bytes;
278 if(field_size > 5) {
279 throw BER_Decoding_Error("Length field is too large");
280 }
281
282 if(num_length_bytes == 0) {
283 // Indefinite length is not allowed in DER
284 if(der_mode) {
285 throw BER_Decoding_Error("Detected indefinite-length encoding in DER structure");
286 }
287 // Indefinite length is only valid for constructed types (X.690 8.1.3.2)
288 if(!constructed) {
289 throw BER_Decoding_Error("Indefinite-length encoding used with non-constructed type");
290 }
291 if(allow_indef == 0) {
292 throw BER_Decoding_Error("Nested EOC markers too deep, rejecting to avoid stack exhaustion");
293 }
294 return find_eoc(src, offset + 1, allow_indef - 1);
295 }
296
297 size_t length = 0;
298 for(size_t i = 0; i < num_length_bytes; ++i) {
299 if(src->peek(&b, 1, offset + 1 + i) == 0) {
300 throw BER_Decoding_Error("Corrupted length field");
301 }
302 if(get_byte<0>(length) != 0) {
303 throw BER_Decoding_Error("Field length overflow");
304 }
305 length = (length << 8) | b;
306 }
307 return length;
308}
309
310/*
311* Find the EOC marker by scanning TLVs via peek, without buffering.
312* Returns the number of bytes before and including the EOC marker.
313*/
314size_t find_eoc(DataSource* src, size_t base_offset, size_t allow_indef) {
315 size_t offset = base_offset;
316
317 while(true) {
320 const size_t tag_size = peek_tag(src, offset, type_tag, class_tag);
321 if(type_tag == ASN1_Type::NoObject) {
322 throw BER_Decoding_Error("Missing EOC marker in indefinite-length encoding");
323 }
324
325 size_t length_size = 0;
326 const size_t item_size =
327 peek_length(src, offset + tag_size, length_size, allow_indef, is_constructed(class_tag), false);
328
329 if(auto new_offset = checked_add(offset, tag_size, length_size, item_size)) {
330 offset = new_offset.value();
331 } else {
332 throw Decoding_Error("Integer overflow while scanning for EOC");
333 }
334
335 if(type_tag == ASN1_Type::Eoc && class_tag == ASN1_Class::Universal) {
336 // Per X.690 8.1.5 the EOC marker is exactly two zero octets
337 if(length_size != 1 || item_size != 0) {
338 throw BER_Decoding_Error("EOC marker with non-zero length");
339 }
340 break;
341 }
342 }
343
344 return offset - base_offset;
345}
346
347class DataSource_BERObject final : public DataSource {
348 public:
349 size_t read(uint8_t out[], size_t length) override {
350 BOTAN_ASSERT_NOMSG(m_offset <= m_obj.length());
351 const size_t got = std::min<size_t>(m_obj.length() - m_offset, length);
352 copy_mem(out, m_obj.bits() + m_offset, got);
353 m_offset += got;
354 return got;
355 }
356
357 size_t peek(uint8_t out[], size_t length, size_t peek_offset) const override {
358 BOTAN_ASSERT_NOMSG(m_offset <= m_obj.length());
359 const size_t bytes_left = m_obj.length() - m_offset;
360
361 if(peek_offset >= bytes_left) {
362 return 0;
363 }
364
365 const size_t got = std::min(bytes_left - peek_offset, length);
366 copy_mem(out, m_obj.bits() + m_offset + peek_offset, got);
367 return got;
368 }
369
370 bool check_available(size_t n) override {
371 BOTAN_ASSERT_NOMSG(m_offset <= m_obj.length());
372 return (n <= (m_obj.length() - m_offset));
373 }
374
375 bool end_of_data() const override { return get_bytes_read() == m_obj.length(); }
376
377 size_t get_bytes_read() const override { return m_offset; }
378
379 explicit DataSource_BERObject(BER_Object&& obj) : m_obj(std::move(obj)) {}
380
381 private:
382 BER_Object m_obj;
383 size_t m_offset = 0;
384};
385
386/*
387* A non-owning DataSource over a span, used to drive tag/length decoding
388* without copying the underlying buffer.
389*/
390class DataSource_Span final : public DataSource {
391 public:
392 size_t read(uint8_t out[], size_t length) override {
393 const size_t got = std::min(m_buf.size() - m_offset, length);
394 copy_mem(out, m_buf.data() + m_offset, got);
395 m_offset += got;
396 return got;
397 }
398
399 size_t peek(uint8_t out[], size_t length, size_t peek_offset) const override {
400 if(peek_offset >= m_buf.size() - m_offset) {
401 return 0;
402 }
403 const size_t got = std::min(m_buf.size() - m_offset - peek_offset, length);
404 copy_mem(out, m_buf.data() + m_offset + peek_offset, got);
405 return got;
406 }
407
408 bool check_available(size_t n) override { return n <= (m_buf.size() - m_offset); }
409
410 bool end_of_data() const override { return m_offset == m_buf.size(); }
411
412 size_t get_bytes_read() const override { return m_offset; }
413
414 explicit DataSource_Span(std::span<const uint8_t> buf) : m_buf(buf) {}
415
416 private:
417 std::span<const uint8_t> m_buf;
418 size_t m_offset = 0;
419};
420
421/*
422* Verify that the elements of a SET appear in sorted order, comparing the full
423* encoding of each element as an octet string. DER requires this canonical
424* ordering. Throws if the elements are not sorted.
425*/
426void verify_set_is_sorted(std::span<const uint8_t> content) {
427 DataSource_Span src(content);
428 size_t offset = 0;
429 std::optional<std::span<const uint8_t>> prev;
430
431 while(offset < content.size()) {
434 const size_t tag_size = peek_tag(&src, offset, type_tag, class_tag);
435
436 size_t length_size = 0;
437 const size_t item_size =
438 peek_length(&src, offset + tag_size, length_size, /*allow_indef=*/0, is_constructed(class_tag), true);
439
440 const auto end = checked_add(offset, tag_size, length_size, item_size);
441 if(!end || *end > content.size()) {
442 throw BER_Decoding_Error("SET element exceeds available data");
443 }
444
445 const auto elem = content.subspan(offset, *end - offset);
446 if(prev && std::lexicographical_compare(elem.begin(), elem.end(), prev->begin(), prev->end())) {
447 throw BER_Decoding_Error("Detected unsorted SET in DER structure");
448 }
449 prev = elem;
450 offset = *end;
451 }
452}
453
454} // namespace
455
456BER_Decoder::~BER_Decoder() = default;
457
458/*
459* Check if more objects are there
460*/
462 if(m_source->end_of_data() && !m_pushed.is_set()) {
463 return false;
464 }
465 return true;
466}
467
468/*
469* Verify that no bytes remain in the source
470*/
472 return verify_end("BER_Decoder::verify_end called, but data remains");
473}
474
475/*
476* Verify that no bytes remain in the source
477*/
478BER_Decoder& BER_Decoder::verify_end(std::string_view err) {
479 if(!m_source->end_of_data() || m_pushed.is_set()) {
480 throw Decoding_Error(err);
481 }
482 return (*this);
483}
484
485/*
486* Discard all the bytes remaining in the source
487*/
489 m_pushed = BER_Object();
490 uint8_t buf = 0;
491 while(m_source->read_byte(buf) != 0) {}
492 return (*this);
493}
494
495std::optional<uint8_t> BER_Decoder::read_next_byte() {
496 BOTAN_ASSERT_NOMSG(m_source != nullptr);
497 uint8_t b = 0;
498 if(m_source->read_byte(b) != 0) {
499 return b;
500 } else {
501 return {};
502 }
503}
504
506 if(!m_pushed.is_set()) {
507 m_pushed = get_next_object();
508 }
509
510 return m_pushed;
511}
512
513/*
514* Return the BER encoding of the next object
515*/
517 BER_Object next;
518
519 if(m_pushed.is_set()) {
520 std::swap(next, m_pushed);
521 return next;
522 }
523
524 for(;;) {
527 decode_tag(m_source, type_tag, class_tag);
528 next.set_tagging(type_tag, class_tag);
529 if(next.is_set() == false) { // no more objects
530 return next;
531 }
532
533 const size_t allow_indef = m_limits.allow_ber_encoding() ? m_limits.max_nested_indefinite_length() : 0;
534 const bool der_mode = m_limits.require_der_encoding();
535 const auto dl = decode_length(m_source, allow_indef, der_mode, is_constructed(class_tag));
536
537 // Per X.690 8.1.5 the only valid EOC encoding is the two-octet
538 // sequence 0x00 0x00. Reject any other length encoding on a tag of
539 // (Eoc, Universal) before we consume the "content" bytes.
540 if(type_tag == ASN1_Type::Eoc && class_tag == ASN1_Class::Universal &&
541 (dl.content_length() != 0 || dl.indefinite_length())) {
542 throw BER_Decoding_Error("EOC marker with non-zero length");
543 }
544
545 if(const auto max_size = m_limits.max_object_size(); max_size && dl.content_length() > *max_size) {
546 throw BER_Decoding_Error("Encoded object exceeds maximum size");
547 }
548
549 if(!m_source->check_available(dl.total_length())) {
550 throw BER_Decoding_Error("Value truncated");
551 }
552
553 uint8_t* out = next.mutable_bits(dl.content_length());
554 if(m_source->read(out, dl.content_length()) != dl.content_length()) {
555 throw BER_Decoding_Error("Value truncated");
556 }
557
558 if(dl.indefinite_length()) {
559 // After reading the data consume the 2-byte EOC
560 uint8_t eoc[2] = {0xFF, 0xFF};
561 if(m_source->read(eoc, 2) != 2 || eoc[0] != 0x00 || eoc[1] != 0x00) {
562 throw BER_Decoding_Error("Missing or malformed EOC marker");
563 }
564 }
565
566 if(next.tagging() == static_cast<uint32_t>(ASN1_Type::Eoc)) {
567 if(m_limits.require_der_encoding()) {
568 throw BER_Decoding_Error("Detected EOC marker in DER structure");
569 }
570 // An EOC marker is only valid as an indefinite-length terminator, which
571 // is consumed above when reading the indefinite-length object. A
572 // standalone EOC is rejected unless the caller opted to tolerate it.
573 if(m_limits.allow_standalone_eoc()) {
574 continue;
575 }
576 throw BER_Decoding_Error("Encountered EOC marker outside of indefinite-length encoding");
577 }
578
579 break;
580 }
581
582 return next;
583}
584
585BER_Object BER_Decoder::get_next_value(size_t sizeofT, ASN1_Type type_tag, ASN1_Class class_tag) {
586 const BER_Object obj = get_next_object();
587 obj.assert_is_a(type_tag, class_tag);
588
589 if(obj.length() != sizeofT) {
590 throw BER_Decoding_Error("Size mismatch. Object value size is " + std::to_string(obj.length()) +
591 "; Output type size is " + std::to_string(sizeofT));
592 }
593
594 return obj;
595}
596
597/*
598* Push a object back into the stream
599*/
601 if(m_pushed.is_set()) {
602 throw Invalid_State("BER_Decoder: Only one push back is allowed");
603 }
604 m_pushed = obj;
605}
606
608 if(m_pushed.is_set()) {
609 throw Invalid_State("BER_Decoder: Only one push back is allowed");
610 }
611 m_pushed = std::move(obj);
612}
613
616 obj.assert_is_a(type_tag, class_tag | ASN1_Class::Constructed);
617
618 // In DER mode the elements of a universal SET must appear in sorted order
619 if(m_limits.require_der_encoding() && type_tag == ASN1_Type::Set && class_tag == ASN1_Class::Universal) {
620 verify_set_is_sorted(std::span<const uint8_t>{obj.bits(), obj.length()});
621 }
622
623 BER_Decoder child(std::move(obj), this);
624 return child;
625}
626
627/*
628* Finish decoding a CONSTRUCTED type
629*/
631 if(m_parent == nullptr) {
632 throw Invalid_State("BER_Decoder::end_cons called with null parent");
633 }
634 if(!m_source->end_of_data() || m_pushed.is_set()) {
635 throw Decoding_Error("BER_Decoder::end_cons called with data left");
636 }
637 return (*m_parent);
638}
639
641 m_limits(parent != nullptr ? parent->limits() : BER_Decoder::Limits::BER()), m_parent(parent) {
642 m_data_src = std::make_unique<DataSource_BERObject>(std::move(obj));
643 m_source = m_data_src.get();
644}
645
647 m_data_src = std::make_unique<DataSource_BERObject>(std::move(obj));
648 m_source = m_data_src.get();
649}
650
651/*
652* BER_Decoder Constructor
653*/
654BER_Decoder::BER_Decoder(DataSource& src, Limits limits) : m_limits(limits), m_source(&src) {}
655
656/*
657* BER_Decoder Constructor
658 */
659BER_Decoder::BER_Decoder(std::span<const uint8_t> buf, Limits limits) : m_limits(limits) {
660 m_data_src = std::make_unique<DataSource_Memory>(buf);
661 m_source = m_data_src.get();
662}
663
664BER_Decoder::BER_Decoder(BER_Decoder&& other) noexcept = default;
665
666BER_Decoder& BER_Decoder::operator=(BER_Decoder&&) noexcept = default;
667
668/*
669* Request for an object to decode itself
670*/
672 // TODO support this case properly
673 if(type_tag != ASN1_Type::NoObject || class_tag != ASN1_Class::NoObject) {
674 throw Not_Implemented("BER_Decoder::decode(ASN1_Object) does not support implicit tagged decoding");
675 }
676 obj.decode_from(*this);
677 return (*this);
678}
679
680/*
681* Decode a BER encoded NULL
682*/
684 const BER_Object obj = get_next_object();
686 if(obj.length() > 0) {
687 throw BER_Decoding_Error("NULL object had nonzero size");
688 }
689 return (*this);
690}
691
695 out = BigInt::from_bytes(out_vec);
696 return (*this);
697}
698
699/*
700* Decode a BER encoded BOOLEAN
701*/
702BER_Decoder& BER_Decoder::decode(bool& out, ASN1_Type type_tag, ASN1_Class class_tag) {
703 const BER_Object obj = get_next_object();
704 obj.assert_is_a(type_tag, class_tag);
705
706 if(obj.length() != 1) {
707 throw BER_Decoding_Error("BER boolean value had invalid size");
708 }
709
710 const uint8_t val = obj.bits()[0];
711
712 // DER requires boolean values to be exactly 0x00 or 0xFF
713 if(m_limits.require_der_encoding() && val != 0x00 && val != 0xFF) {
714 throw BER_Decoding_Error("Detected non-canonical boolean encoding in DER structure");
715 }
716
717 out = (val != 0) ? true : false;
718
719 return (*this);
720}
721
722/*
723* Decode a small BER encoded INTEGER
724*/
725BER_Decoder& BER_Decoder::decode(size_t& out, ASN1_Type type_tag, ASN1_Class class_tag) {
726 BigInt integer;
727 decode(integer, type_tag, class_tag);
728
729 if(integer.signum() < 0) {
730 throw BER_Decoding_Error("Decoded small integer value was negative");
731 }
732
733 if(integer.bits() > 32) {
734 throw BER_Decoding_Error("Decoded integer value larger than expected");
735 }
736
737 out = 0;
738 for(size_t i = 0; i != 4; ++i) {
739 out = (out << 8) | integer.byte_at(3 - i);
740 }
741
742 return (*this);
743}
744
745/*
746* Decode a small BER encoded INTEGER
747*/
748uint64_t BER_Decoder::decode_constrained_integer(ASN1_Type type_tag, ASN1_Class class_tag, size_t T_bytes) {
749 if(T_bytes > 8) {
750 throw BER_Decoding_Error("Can't decode small integer over 8 bytes");
751 }
752
753 BigInt integer;
754 decode(integer, type_tag, class_tag);
755
756 if(integer.is_negative()) {
757 throw BER_Decoding_Error("Decoded small integer value was negative");
758 }
759
760 if(integer.bits() > 8 * T_bytes) {
761 throw BER_Decoding_Error("Decoded integer value larger than expected");
762 }
763
764 uint64_t out = 0;
765 for(size_t i = 0; i != 8; ++i) {
766 out = (out << 8) | integer.byte_at(7 - i);
767 }
768
769 return out;
770}
771
772/*
773* Decode a BER encoded INTEGER
774*/
776 const BER_Object obj = get_next_object();
777 obj.assert_is_a(type_tag, class_tag);
778
779 // An INTEGER must have at least one content octet (X.690 section 8.3.1)
780 if(obj.length() == 0) {
781 throw BER_Decoding_Error("INTEGER encoding has no content octets");
782 }
783
784 // DER requires minimal INTEGER encoding (X.690 section 8.3.2)
785 if(m_limits.require_der_encoding()) {
786 if(obj.length() > 1) {
787 if(obj.bits()[0] == 0x00 && (obj.bits()[1] & 0x80) == 0) {
788 throw BER_Decoding_Error("Detected non-minimal INTEGER encoding in DER structure");
789 }
790 if(obj.bits()[0] == 0xFF && (obj.bits()[1] & 0x80) != 0) {
791 throw BER_Decoding_Error("Detected non-minimal INTEGER encoding in DER structure");
792 }
793 }
794 }
795
797
798 return (*this);
799}
800
801BigInt ASN1::integer_from_contents(std::span<const uint8_t> contents) {
802 if(contents.empty()) {
803 throw BER_Decoding_Error("INTEGER encoding has no content octets");
804 }
805
806 BigInt out;
807
808 const bool negative = (contents[0] & 0x80) == 0x80;
809
810 if(negative) {
811 secure_vector<uint8_t> vec(contents.begin(), contents.end());
812 for(size_t i = vec.size(); i > 0; --i) {
813 const bool gt0 = (vec[i - 1] > 0);
814 vec[i - 1] -= 1;
815 if(gt0) {
816 break;
817 }
818 }
819 for(auto& byte : vec) {
820 byte = ~byte;
821 }
822 out._assign_from_bytes(vec);
824 } else {
825 out._assign_from_bytes(contents);
826 }
827
828 return out;
829}
830
831namespace {
832
833bool is_constructed(const BER_Object& obj) {
834 return is_constructed(obj.class_tag());
835}
836
837/*
838* Bounds the nesting of constructed OCTET STRING/BIT STRING encodings.
839*
840* It's allowed, though probably rarely used, for a BER constructed string
841* to have a segment which is itself a BER constructed string. We handle
842* this recursively, so place an explicit limit on how deep we'll go.
843*/
844constexpr size_t ALLOWED_CONSTRUCTED_STRING_NESTING = 2;
845
846/*
847* Concatenate the segments of a BER constructed OCTET STRING (X.690 sec 8.7.3)
848*
849* In the constructed form the secondary tags are always universal OCTET STRING
850* rather than any possible implicit tag. It's also allowed for any of the
851* segments to themselves be constructed.
852*/
853template <typename Alloc>
854void asn1_concat_constructed_octet_string(std::vector<uint8_t, Alloc>& buffer,
855 const BER_Object& obj,
856 const BER_Decoder::Limits& limits,
857 size_t depth) {
858 if(depth >= ALLOWED_CONSTRUCTED_STRING_NESTING) {
859 throw BER_Decoding_Error("Constructed OCTET STRING is too deeply nested");
860 }
861
862 BER_Decoder segments(obj, limits);
863 while(segments.more_items()) {
864 const BER_Object seg = segments.get_next_object();
866 buffer.insert(buffer.end(), seg.bits(), seg.bits() + seg.length());
868 asn1_concat_constructed_octet_string(buffer, seg, limits, depth + 1);
869 } else {
870 throw BER_Decoding_Error("Constructed OCTET STRING contains an invalid segment");
871 }
872 }
873}
874
875/*
876* Concatenate the segments of a BER constructed BIT STRING (X.690 sec 8.6.4)
877*
878* Returns the unused bit count of the final segment; BER requires that every
879* earlier segment must be a multiple of eight bits.
880*/
881template <typename Alloc>
882uint8_t asn1_concat_constructed_bit_string(std::vector<uint8_t, Alloc>& buffer,
883 const BER_Object& obj,
884 const BER_Decoder::Limits& limits,
885 size_t depth) {
886 if(depth >= ALLOWED_CONSTRUCTED_STRING_NESTING) {
887 throw BER_Decoding_Error("Constructed BIT STRING is too deeply nested");
888 }
889
890 uint8_t unused_bits = 0;
891
892 BER_Decoder segments(obj, limits);
893 while(segments.more_items()) {
894 if(unused_bits != 0) {
895 throw BER_Decoding_Error("Constructed BIT STRING has unused bits before the final segment");
896 }
897
898 const BER_Object seg = segments.get_next_object();
900 if(seg.length() == 0) {
901 throw BER_Decoding_Error("Invalid BIT STRING");
902 }
903 unused_bits = seg.bits()[0];
904 if(unused_bits >= 8) {
905 throw BER_Decoding_Error("Bad number of unused bits in BIT STRING");
906 }
907 if(seg.length() == 1 && unused_bits != 0) {
908 throw BER_Decoding_Error("Invalid BIT STRING");
909 }
910 buffer.insert(buffer.end(), seg.bits() + 1, seg.bits() + seg.length());
912 unused_bits = asn1_concat_constructed_bit_string(buffer, seg, limits, depth + 1);
913 } else {
914 throw BER_Decoding_Error("Constructed BIT STRING contains an invalid segment");
915 }
916 }
917
918 return unused_bits;
919}
920
921template <typename Alloc>
922void asn1_decode_binary_string(std::vector<uint8_t, Alloc>& buffer,
923 const BER_Object& obj,
924 ASN1_Type real_type,
925 ASN1_Type type_tag,
926 ASN1_Class class_tag,
927 const BER_Decoder::Limits& limits) {
928 // DER requires BIT STRING and OCTET STRING to use primitive encoding;
929 // in BER the constructed (fragmented) form is decoded by concatenation
930 if(is_constructed(obj)) {
931 obj.assert_is_a(type_tag, class_tag | ASN1_Class::Constructed);
932
933 if(limits.require_der_encoding()) {
934 throw BER_Decoding_Error("Detected constructed string encoding in DER structure");
935 }
936
937 // Concatenate into a temporary so a failed decode leaves buffer unmodified
938 std::vector<uint8_t, Alloc> concat;
939 concat.reserve(obj.length()); // upper possible bound on the output size
940 if(real_type == ASN1_Type::OctetString) {
941 asn1_concat_constructed_octet_string(concat, obj, limits, 0);
942 } else {
943 asn1_concat_constructed_bit_string(concat, obj, limits, 0);
944 }
945 buffer = std::move(concat);
946 return;
947 }
948
949 obj.assert_is_a(type_tag, class_tag);
950
951 if(real_type == ASN1_Type::OctetString) {
952 buffer.assign(obj.bits(), obj.bits() + obj.length());
953 } else {
954 if(obj.length() == 0) {
955 throw BER_Decoding_Error("Invalid BIT STRING");
956 }
957
958 const uint8_t unused_bits = obj.bits()[0];
959
960 if(unused_bits >= 8) {
961 throw BER_Decoding_Error("Bad number of unused bits in BIT STRING");
962 }
963
964 // Empty BIT STRING with unused bits > 0 ...
965 if(unused_bits > 0 && obj.length() < 2) {
966 throw BER_Decoding_Error("Invalid BIT STRING");
967 }
968
969 // DER requires unused bits in BIT STRING to be zero (X.690 section 11.2.2)
970 if(limits.require_der_encoding() && unused_bits > 0) {
971 const uint8_t last_byte = obj.bits()[obj.length() - 1];
972 if((last_byte & ((1 << unused_bits) - 1)) != 0) {
973 throw BER_Decoding_Error("Detected non-zero padding bits in BIT STRING in DER structure");
974 }
975 }
976
977 buffer.resize(obj.length() - 1);
978
979 if(obj.length() > 1) {
980 copy_mem(buffer.data(), obj.bits() + 1, obj.length() - 1);
981 }
982 }
983}
984
985uint8_t asn1_bitstring_unused_bits(const BER_Object& obj, ASN1_Type type_tag, ASN1_Class class_tag, bool require_der) {
986 obj.assert_is_a(type_tag, class_tag);
987 BOTAN_ASSERT_NOMSG(!is_constructed(obj));
988
989 if(obj.length() == 0) {
990 throw BER_Decoding_Error("Invalid BIT STRING");
991 }
992
993 const uint8_t unused_bits = obj.bits()[0];
994
995 if(unused_bits >= 8) {
996 throw BER_Decoding_Error("Invalid number of unused bits in BIT STRING");
997 }
998
999 if(obj.length() == 1 && unused_bits != 0) {
1000 throw BER_Decoding_Error("Invalid BIT STRING");
1001 }
1002
1003 if(require_der && unused_bits > 0) {
1004 const uint8_t last_byte = obj.bits()[obj.length() - 1];
1005 if((last_byte & ((1 << unused_bits) - 1)) != 0) {
1006 throw BER_Decoding_Error("Detected non-zero padding bits in BIT STRING in DER structure");
1007 }
1008 }
1009
1010 return unused_bits;
1011}
1012
1013} // namespace
1014
1015/*
1016* BER decode a BIT STRING or OCTET STRING
1017*/
1019 ASN1_Type real_type,
1020 ASN1_Type type_tag,
1021 ASN1_Class class_tag) {
1022 if(real_type != ASN1_Type::OctetString && real_type != ASN1_Type::BitString) {
1023 throw BER_Bad_Tag("Bad tag for {BIT,OCTET} STRING", static_cast<uint32_t>(real_type));
1024 }
1025
1026 asn1_decode_binary_string(buffer, get_next_object(), real_type, type_tag, class_tag, m_limits);
1027 return (*this);
1028}
1029
1030BER_Decoder& BER_Decoder::decode(std::vector<uint8_t>& buffer,
1031 ASN1_Type real_type,
1032 ASN1_Type type_tag,
1033 ASN1_Class class_tag) {
1034 if(real_type != ASN1_Type::OctetString && real_type != ASN1_Type::BitString) {
1035 throw BER_Bad_Tag("Bad tag for {BIT,OCTET} STRING", static_cast<uint32_t>(real_type));
1036 }
1037
1038 asn1_decode_binary_string(buffer, get_next_object(), real_type, type_tag, class_tag, m_limits);
1039 return (*this);
1040}
1041
1043 const BER_Object obj = get_next_object();
1044
1045 std::vector<uint8_t> bits;
1046 uint8_t unused_bits = 0;
1047
1048 if(is_constructed(obj.class_tag())) {
1049 obj.assert_is_a(type_tag, class_tag | ASN1_Class::Constructed);
1050 if(m_limits.require_der_encoding()) {
1051 throw BER_Decoding_Error("Detected constructed string encoding in DER structure");
1052 }
1053 bits.reserve(obj.length()); // upper possible bound on the output size
1054 unused_bits = asn1_concat_constructed_bit_string(bits, obj, m_limits, 0);
1055 } else {
1056 unused_bits = asn1_bitstring_unused_bits(obj, type_tag, class_tag, m_limits.require_der_encoding());
1057 bits.assign(obj.bits() + 1, obj.bits() + obj.length());
1058 }
1059
1060 if(unused_bits > 0 && !bits.empty()) {
1061 bits.back() &= static_cast<uint8_t>(0xFF << unused_bits);
1062 }
1063
1064 out = ASN1_BitString(std::move(bits), unused_bits);
1065 return (*this);
1066}
1067
1069 size_t width,
1070 ASN1_Type type_tag,
1071 ASN1_Class class_tag) {
1072 if(width > 64) {
1073 throw Invalid_Argument("BER_Decoder: Named BIT STRING width is too large");
1074 }
1075
1076 ASN1_BitString bits;
1077 decode_bitstring(bits, type_tag, class_tag);
1078
1079 if(bits.bit_length() > width) {
1080 throw BER_Decoding_Error("Named BIT STRING exceeds declared width");
1081 }
1082
1083 if(m_limits.require_der_encoding() && bits.bit_length() > 0 && !bits.bit_at(bits.bit_length() - 1)) {
1084 throw BER_Decoding_Error("Named BIT STRING is not minimally encoded");
1085 }
1086
1087 uint64_t decoded = 0;
1088 for(size_t bit = 0; bit != bits.bit_length(); ++bit) {
1089 if(bits.bit_at(bit)) {
1090 decoded |= uint64_t(1) << (width - 1 - bit);
1091 }
1092 }
1093
1094 out = decoded;
1095 return (*this);
1096}
1097
1098namespace ASN1 {
1099
1100bool is_single_der_object(std::span<const uint8_t> bytes, ASN1_Type expected_type, ASN1_Class expected_class) {
1101 if(bytes.empty()) {
1102 return false;
1103 }
1104
1105 try {
1106 DataSource_Span src(bytes);
1107
1108 ASN1_Type type_tag = ASN1_Type::NoObject;
1109 ASN1_Class class_tag = ASN1_Class::NoObject;
1110 const size_t tag_bytes = decode_tag(&src, type_tag, class_tag);
1111
1112 if(type_tag != expected_type || class_tag != expected_class) {
1113 return false;
1114 }
1115
1116 const auto dl = decode_length(&src, /*allow_indef=*/0, /*der_mode=*/true, is_constructed(expected_class));
1117
1118 const size_t header_bytes = tag_bytes + dl.field_length();
1119 if(header_bytes > bytes.size()) {
1120 return false;
1121 }
1122 return dl.content_length() == bytes.size() - header_bytes;
1123 } catch(Decoding_Error&) {
1124 return false;
1125 }
1126}
1127
1128bool is_der_sequence_header(std::span<const uint8_t> bytes) {
1130}
1131
1132} // namespace ASN1
1133
1134} // namespace Botan
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
bool bit_at(size_t bit) const
Definition asn1_obj.cpp:50
size_t bit_length() const
Definition asn1_obj.cpp:46
BER_Decoder & decode_named_bitstring(uint64_t &bits, size_t width, ASN1_Type type_tag=ASN1_Type::BitString, ASN1_Class class_tag=ASN1_Class::Universal)
Definition ber_dec.cpp:1068
const BER_Object & peek_next_object()
Definition ber_dec.cpp:505
void push_back(const BER_Object &obj)
Definition ber_dec.cpp:600
BER_Object get_next_object()
Definition ber_dec.cpp:516
BER_Decoder & get_next_value(T &out, ASN1_Type type_tag, ASN1_Class class_tag=ASN1_Class::ContextSpecific)
Definition ber_dec.h:322
BER_Decoder & decode_bitstring(ASN1_BitString &out, ASN1_Type type_tag=ASN1_Type::BitString, ASN1_Class class_tag=ASN1_Class::Universal)
Definition ber_dec.cpp:1042
BER_Decoder & decode(bool &out)
Definition ber_dec.h:358
uint64_t decode_constrained_integer(ASN1_Type type_tag, ASN1_Class class_tag, size_t T_bytes)
Definition ber_dec.cpp:748
bool more_items() const
Definition ber_dec.cpp:461
Limits limits() const
Definition ber_dec.h:197
BER_Decoder & verify_end()
Definition ber_dec.cpp:471
BER_Decoder(const uint8_t buf[], size_t len, Limits limits=Limits::BER())
Definition ber_dec.h:150
BER_Decoder & end_cons()
Definition ber_dec.cpp:630
BER_Decoder start_cons(ASN1_Type type_tag, ASN1_Class class_tag)
Definition ber_dec.cpp:614
BER_Decoder & discard_remaining()
Definition ber_dec.cpp:488
BER_Decoder & decode_octet_string_bigint(BigInt &b)
Definition ber_dec.cpp:692
BER_Decoder & decode_null()
Definition ber_dec.cpp:683
BER_Decoder & operator=(const BER_Decoder &)=delete
size_t length() const
Definition asn1_obj.h:303
const uint8_t * bits() const
Definition asn1_obj.h:298
void assert_is_a(ASN1_Type type_tag, ASN1_Class class_tag, std::string_view descr="object") const
Definition asn1_obj.cpp:65
uint32_t tagging() const
Definition asn1_obj.h:272
bool is_set() const
Definition asn1_obj.h:267
std::span< const uint8_t > data() const
Definition asn1_obj.h:308
ASN1_Class class_tag() const
Definition asn1_obj.h:282
int signum() const
Definition bigint.h:493
static BigInt from_bytes(std::span< const uint8_t > bytes)
Definition bigint.cpp:83
size_t bits() const
Definition bigint.cpp:307
uint8_t byte_at(size_t n) const
Definition bigint.cpp:118
void _assign_from_bytes(std::span< const uint8_t > bytes)
Definition bigint.h:1044
bool is_negative() const
Definition bigint.h:623
void set_sign(Sign sign)
Definition bigint.h:663
size_t read_byte(uint8_t &out)
Definition data_src.cpp:27
bool is_single_der_object(std::span< const uint8_t > bytes, ASN1_Type expected_type, ASN1_Class expected_class)
Definition ber_dec.cpp:1100
BigInt integer_from_contents(std::span< const uint8_t > contents)
Definition ber_dec.cpp:801
bool is_der_sequence_header(std::span< const uint8_t > bytes)
Definition ber_dec.cpp:1128
constexpr uint8_t get_byte(T input)
Definition loadstor.h:79
constexpr std::optional< T > checked_add(T a, T b)
Definition int_utils.h:19
ASN1_Class
Definition asn1_obj.h:32
ASN1_Type
Definition asn1_obj.h:47
constexpr void copy_mem(T *out, const T *in, size_t n)
Definition mem_ops.h:144
constexpr auto concat(Rs &&... ranges)
Definition concat_util.h:90
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:128
std::uint8_t byte
Unsigned 8 bit integer; retained for compatibility with older versions.
Definition types.h:112