Botan 3.13.0
Crypto and TLS for C&
ber_dec.h
Go to the documentation of this file.
1/*
2* BER Decoder
3* (C) 1999-2010,2018 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#ifndef BOTAN_BER_DECODER_H_
9#define BOTAN_BER_DECODER_H_
10
11#include <botan/asn1_obj.h>
12#include <botan/secmem.h>
13#include <cstring>
14#include <memory>
15#include <optional>
16#include <type_traits>
17#include <utility>
18
19namespace Botan {
20
21class BigInt;
22class DataSource;
23
24/**
25* BER Decoding Object
26*/
27class BOTAN_PUBLIC_API(2, 0) BER_Decoder final {
28 public:
29 /**
30 * Controls what encoding rules the decoder accepts.
31 */
32 class BOTAN_PUBLIC_API(3, 12) Limits final {
33 public:
34 /**
35 * The default maximum size in bytes of a single decoded object.
36 */
37 static constexpr size_t DefaultMaxObjectSize = 128 * 1024 * 1024;
38
39 /**
40 * Accept only DER encodings
41 */
42 static Limits DER() { return Limits(false, 0, false, DefaultMaxObjectSize, false); }
43
44 /**
45 * Accept non-canonical BER encodings.
46 *
47 * @param max_nested_indef maximum number of nested indefinite-length encodings accepted
48 */
49 static Limits BER(size_t max_nested_indef = 16) {
50 return Limits(true, max_nested_indef, false, DefaultMaxObjectSize, false);
51 }
52
53 /**
54 * If true, non-canonical BER encodings are accepted
55 */
56 bool allow_ber_encoding() const { return m_allow_ber; }
57
58 /**
59 * If true, only DER encodings are accepted
60 */
61 bool require_der_encoding() const { return !allow_ber_encoding(); }
62
63 /**
64 * The maximum number of nested indefinite-length encodings accepted
65 */
66 size_t max_nested_indefinite_length() const { return m_max_nested_indef; }
67
68 /**
69 * If true, a standalone EOC marker (one that does not terminate an
70 * indefinite-length encoding) is skipped rather than rejected. Some
71 * BER producers emit trailing EOC markers; accepting them is needed to
72 * parse such data (eg CMS signatures in PDFs). Off by default.
73 */
74 bool allow_standalone_eoc() const { return m_allow_standalone_eoc; }
75
76 /**
77 * The maximum size in bytes of a single decoded object, or nullopt if
78 * no object size limit is enforced.
79 */
80 std::optional<size_t> max_object_size() const { return m_max_object_size; }
81
82 /**
83 * If true, a DER component that is explicitly encoded with a value
84 * equal to its DEFAULT is rejected (such components must be omitted in
85 * DER). Only applies in DER mode and only to fields decoded via
86 * decode_default(). Off by default, since Botan and many other
87 * implementations emit such components. See decode_default().
88 */
89 bool reject_default_value_encoding() const { return m_reject_default_value_encoding; }
90
91 /**
92 * Return a copy of these limits that tolerates standalone EOC markers.
93 * See allow_standalone_eoc().
94 */
96 Limits copy = *this;
97 copy.m_allow_standalone_eoc = true;
98 return copy;
99 }
100
101 /**
102 * Return a copy of these limits with the given maximum object size.
103 * A value of nullopt disables the object size limit. See
104 * max_object_size().
105 */
106 Limits with_max_object_size(std::optional<size_t> max_object_size) const {
107 Limits copy = *this;
108 copy.m_max_object_size = max_object_size;
109 return copy;
110 }
111
112 /**
113 * Return a copy of these limits that rejects DER components encoded
114 * equal to their DEFAULT value. See reject_default_value_encoding().
115 */
117 Limits copy = *this;
118 copy.m_reject_default_value_encoding = true;
119 return copy;
120 }
121
122 /**
123 * Compare two sets of limits for equality
124 */
125 bool operator==(const Limits&) const = default;
126
127 private:
128 Limits(bool allow_ber,
129 size_t max_nested_indef,
131 std::optional<size_t> max_object_size,
133 m_allow_ber(allow_ber),
134 m_max_nested_indef(max_nested_indef),
135 m_allow_standalone_eoc(allow_standalone_eoc),
136 m_max_object_size(max_object_size),
137 m_reject_default_value_encoding(reject_default_value_encoding) {}
138
139 bool m_allow_ber;
140 size_t m_max_nested_indef;
141 bool m_allow_standalone_eoc;
142 std::optional<size_t> m_max_object_size;
143 bool m_reject_default_value_encoding;
144 };
145
146 /**
147 * Set up to BER decode the data in buf of length len
148 */
149 BOTAN_DEPRECATED("Use BER_Decoder(span) constructor")
150 BER_Decoder(const uint8_t buf[], size_t len, Limits limits = Limits::BER()) :
151 BER_Decoder(std::span{buf, len}, limits) {}
152
153 /**
154 * Set up to BER decode the data in buf
155 */
156 explicit BER_Decoder(std::span<const uint8_t> buf, Limits limits = Limits::BER());
157
158 /**
159 * Set up to BER decode the data in src
160 */
161 explicit BER_Decoder(DataSource& src, Limits limits = Limits::BER());
162
163 /**
164 * Set up to BER decode the data in obj
165 */
168
169 /**
170 * Set up to BER decode the data in obj
171 * TODO(Botan4) remove this?
172 */
173 BOTAN_FUTURE_EXPLICIT BER_Decoder(BER_Object&& obj) : BER_Decoder(std::move(obj), nullptr) {}
174
175 /**
176 * Set up to BER decode the data in obj, taking ownership of its contents
177 */
178 BER_Decoder(BER_Object&& obj, Limits limits);
179
180 BER_Decoder(const BER_Decoder& other) = delete;
181
182 /**
183 * Move constructor
184 */
185 BER_Decoder(BER_Decoder&& other) noexcept;
186
188
189 /**
190 * Move assignment
191 */
193
194 /**
195 * Returns the limits currently applied to this decoder
196 */
197 Limits limits() const { return m_limits; }
198
199 /**
200 * Get the next object in the data stream.
201 * If EOF, returns an object with type NO_OBJECT.
202 */
203 BER_Object get_next_object();
204
205 /**
206 * Get the next object in the data stream, storing it in @p ber
207 *
208 * If EOF, @p ber is set to an object with type NO_OBJECT.
209 */
211 ber = get_next_object();
212 return (*this);
213 }
214
215 /**
216 * Peek at the next object without removing it from the stream
217 *
218 * If an object has been pushed, then it returns that object.
219 * Otherwise it reads the next object and pushes it. Thus, a you
220 * call peek_next_object followed by push_back without a
221 * subsequent read, it will fail.
222 */
223 const BER_Object& peek_next_object();
224
225 /**
226 * Push an object back onto the stream. Throws if another
227 * object was previously pushed and has not been subsequently
228 * read out.
229 */
230 void push_back(const BER_Object& obj);
231
232 /**
233 * Push an object back onto the stream. Throws if another
234 * object was previously pushed and has not been subsequently
235 * read out.
236 */
237 void push_back(BER_Object&& obj);
238
239 /**
240 * Return true if there is at least one more item remaining
241 */
242 bool more_items() const;
243
244 /**
245 * Verify the stream is concluded, throws otherwise.
246 * Returns (*this)
247 */
248 BER_Decoder& verify_end();
249
250 /**
251 * Verify the stream is concluded, throws otherwise.
252 * Returns (*this)
253 */
254 BER_Decoder& verify_end(std::string_view err_msg);
255
256 /**
257 * Discard any data that remains unread
258 * Returns (*this)
259 */
260 BER_Decoder& discard_remaining();
261
262 /**
263 * Start decoding a constructed object, returning a decoder for its contents.
264 * The returned decoder must be closed with end_cons().
265 *
266 * @param type_tag the expected type tag
267 * @param class_tag the expected class tag
268 */
269 BER_Decoder start_cons(ASN1_Type type_tag, ASN1_Class class_tag);
270
271 /**
272 * Start decoding a SEQUENCE, returning a decoder for its contents.
273 * The returned decoder must be closed with end_cons().
274 */
276
277 /**
278 * Start decoding a SET, returning a decoder for its contents.
279 * The returned decoder must be closed with end_cons().
280 */
282
283 /**
284 * Start decoding an IMPLICIT context specific constructed object, returning
285 * a decoder for its contents. The returned decoder must be closed with
286 * end_cons().
287 *
288 * @param tag the expected context specific tag number
289 */
293
294 /**
295 * Start decoding an EXPLICIT context specific constructed object, returning
296 * a decoder for its contents. The returned decoder must be closed with
297 * end_cons().
298 *
299 * @param tag the expected context specific tag number
300 */
304
305 /**
306 * Finish decoding a constructed data, throws if any data remains.
307 * Returns the parent of *this (ie the object on which start_cons was called).
308 */
309 BER_Decoder& end_cons();
310
311 /**
312 * Get next object and copy value to POD type
313 * Asserts value length is equal to POD type sizeof.
314 * Asserts Type tag and optional Class tag according to parameters.
315 * Copy value to POD type (struct, union, C-style array, std::array, etc.).
316 * @param out POD type reference where to copy object value
317 * @param type_tag ASN1_Type enum to assert type on object read
318 * @param class_tag ASN1_Type enum to assert class on object read (default: CONTEXT_SPECIFIC)
319 * @return this reference
320 */
321 template <typename T>
323 requires std::is_standard_layout_v<T> && std::is_trivial_v<T>
324 {
325 const BER_Object obj = get_next_value(sizeof(T), type_tag, class_tag);
326
327 std::memcpy(reinterpret_cast<uint8_t*>(&out), obj.bits(), obj.length());
328
329 return (*this);
330 }
331
332 /**
333 * Save all the bytes remaining in the source
334 *
335 * @param out where the remaining bytes are written
336 */
337 template <typename Alloc>
338 BER_Decoder& raw_bytes(std::vector<uint8_t, Alloc>& out) {
339 out.clear();
340 for(;;) {
341 if(auto next = this->read_next_byte()) {
342 out.push_back(*next);
343 } else {
344 break;
345 }
346 }
347 return (*this);
348 }
349
350 /**
351 * Decode a BER encoded NULL, throwing if the next object is anything else
352 */
353 BER_Decoder& decode_null();
354
355 /**
356 * Decode a BER encoded BOOLEAN
357 */
359
360 /**
361 * Decode a small BER encoded INTEGER
362 */
364
365 /**
366 * Decode a BER encoded INTEGER
367 */
369
370 /**
371 * Decode the next object as an OCTET STRING and return its contents
372 */
373 std::vector<uint8_t> get_next_octet_string() {
374 std::vector<uint8_t> out_vec;
376 return out_vec;
377 }
378
379 /**
380 * BER decode a BIT STRING or OCTET STRING
381 *
382 * @param out where the contents are written
383 * @param real_type either ASN1_Type::OctetString or ASN1_Type::BitString
384 */
385 template <typename Alloc>
386 BER_Decoder& decode(std::vector<uint8_t, Alloc>& out, ASN1_Type real_type) {
387 return decode(out, real_type, real_type, ASN1_Class::Universal);
388 }
389
390 /**
391 * Decode a BOOLEAN with an IMPLICIT tagging
392 *
393 * @param v where the value is written
394 * @param type_tag the expected type tag
395 * @param class_tag the expected class tag
396 */
397 BER_Decoder& decode(bool& v, ASN1_Type type_tag, ASN1_Class class_tag = ASN1_Class::ContextSpecific);
398
399 /**
400 * Decode a small INTEGER with an IMPLICIT tagging
401 *
402 * @param v where the value is written
403 * @param type_tag the expected type tag
404 * @param class_tag the expected class tag
405 */
406 BER_Decoder& decode(size_t& v, ASN1_Type type_tag, ASN1_Class class_tag = ASN1_Class::ContextSpecific);
407
408 /**
409 * Decode an INTEGER with an IMPLICIT tagging
410 *
411 * @param v where the value is written
412 * @param type_tag the expected type tag
413 * @param class_tag the expected class tag
414 */
415 BER_Decoder& decode(BigInt& v, ASN1_Type type_tag, ASN1_Class class_tag = ASN1_Class::ContextSpecific);
416
417 /**
418 * Decode a BIT STRING or OCTET STRING with an IMPLICIT tagging
419 *
420 * @param v where the contents are written
421 * @param real_type either ASN1_Type::OctetString or ASN1_Type::BitString
422 * @param type_tag the expected type tag
423 * @param class_tag the expected class tag
424 */
425 BER_Decoder& decode(std::vector<uint8_t>& v,
426 ASN1_Type real_type,
427 ASN1_Type type_tag,
429
430 /**
431 * Decode a BIT STRING or OCTET STRING with an IMPLICIT tagging
432 *
433 * @param v where the contents are written
434 * @param real_type either ASN1_Type::OctetString or ASN1_Type::BitString
435 * @param type_tag the expected type tag
436 * @param class_tag the expected class tag
437 */
439 ASN1_Type real_type,
440 ASN1_Type type_tag,
442
443 /**
444 * Decode a BIT STRING, retaining the count of unused bits
445 *
446 * @param out where the value is written
447 * @param type_tag the expected type tag
448 * @param class_tag the expected class tag
449 */
450 BER_Decoder& decode_bitstring(ASN1_BitString& out,
453
454 /**
455 * Decode a BIT STRING, throwing unless it has no unused bits
456 *
457 * @param out where the bits are written
458 * @param type_tag the expected type tag
459 * @param class_tag the expected class tag
460 */
461 template <typename Alloc>
462 BER_Decoder& decode_octet_aligned_bitstring(std::vector<uint8_t, Alloc>& out,
464 ASN1_Class class_tag = ASN1_Class::Universal) {
465 ASN1_BitString bits;
466 decode_bitstring(bits, type_tag, class_tag);
467
468 if(bits.unused_bits() != 0) {
469 throw Decoding_Error("Expected octet-aligned BIT STRING");
470 }
471
472 out.assign(bits.bytes().begin(), bits.bytes().end());
473 return (*this);
474 }
475
476 /**
477 * Decode a BIT STRING that is actually a bit set, such as X.509 KeyUsage
478 *
479 * The first bit of the encoding becomes the most significant of the @p width
480 * bits of @p bits. Throws if more than @p width bits are encoded, or in DER
481 * mode if the encoding is not minimal (ie the final bit is unset).
482 *
483 * @param bits where the bit set is written
484 * @param width the number of named bits, at most 64
485 * @param type_tag the expected type tag
486 * @param class_tag the expected class tag
487 */
488 BER_Decoder& decode_named_bitstring(uint64_t& bits,
489 size_t width,
492
493 /**
494 * Request an object decode itself from this stream
495 *
496 * @param obj the object to decode into
497 * @param type_tag must be NoObject; implicit tagging is not supported here
498 * @param class_tag must be NoObject; implicit tagging is not supported here
499 */
500 BER_Decoder& decode(ASN1_Object& obj,
502 ASN1_Class class_tag = ASN1_Class::NoObject);
503
504 /**
505 * Decode an integer value which is typed as an octet string
506 */
507 BER_Decoder& decode_octet_string_bigint(BigInt& b);
508
509 /**
510 * Decode a non-negative INTEGER that fits in at most @p T_bytes bytes
511 *
512 * Throws BER_Decoding_Error if the value is negative or too large.
513 *
514 * @param type_tag the expected type tag
515 * @param class_tag the expected class tag
516 * @param T_bytes the maximum size of the value in bytes, at most 8
517 */
518 uint64_t decode_constrained_integer(ASN1_Type type_tag, ASN1_Class class_tag, size_t T_bytes);
519
520 /**
521 * Decode an INTEGER into an integral type, throwing if it does not fit
522 *
523 * @param out where the value is written
524 */
525 template <typename T>
529
530 /**
531 * Decode an INTEGER with an IMPLICIT tagging into an integral type,
532 * throwing if it does not fit
533 *
534 * @param out where the value is written
535 * @param type_tag the expected type tag
536 * @param class_tag the expected class tag
537 */
538 template <typename T>
540 out = static_cast<T>(decode_constrained_integer(type_tag, class_tag, sizeof(out)));
541 return (*this);
542 }
543
544 /**
545 * Decode an OPTIONAL field, setting @p out to @p default_value if absent
546 *
547 * @param out where the value is written
548 * @param type_tag the expected type tag
549 * @param class_tag the expected class tag
550 * @param default_value the value used if the field is not present
551 */
552 template <typename T>
553 BER_Decoder& decode_optional(T& out, ASN1_Type type_tag, ASN1_Class class_tag, const T& default_value = T()) {
554 std::optional<T> optval;
555 this->decode_optional(optval, type_tag, class_tag);
556 out = optval ? *optval : default_value;
557 return (*this);
558 }
559
560 /**
561 * Decode a field carrying an ASN.1 DEFAULT value: if the field is absent
562 * @p out is set to @p default_value. Unlike decode_optional this is only
563 * for fields with a DEFAULT (not bare OPTIONAL fields): when the decoder is
564 * configured with Limits::with_default_value_encoding_rejected() and is in
565 * DER mode, a field that is present but equal to @p default_value is
566 * rejected, since DER requires such components to be omitted.
567 */
568 template <typename T>
569 BER_Decoder& decode_default(T& out, ASN1_Type type_tag, ASN1_Class class_tag, const T& default_value) {
570 std::optional<T> optval;
571 this->decode_optional(optval, type_tag, class_tag);
572 if(optval.has_value()) {
573 if(m_limits.require_der_encoding() && m_limits.reject_default_value_encoding() &&
574 *optval == default_value) {
575 throw BER_Decoding_Error("DER component encoded with its DEFAULT value");
576 }
577 out = std::move(*optval);
578 } else {
579 out = default_value;
580 }
581 return (*this);
582 }
583
584 /**
585 * Decode an OPTIONAL field, setting @p optval to nullopt if absent
586 *
587 * @param optval where the value is written
588 * @param type_tag the expected type tag
589 * @param class_tag the expected class tag
590 */
591 template <typename T>
592 BER_Decoder& decode_optional(std::optional<T>& optval, ASN1_Type type_tag, ASN1_Class class_tag);
593
594 /**
595 * Decode an OPTIONAL IMPLICIT tagged field, setting @p out to
596 * @p default_value if absent
597 *
598 * @param out where the value is written
599 * @param type_tag the expected type tag
600 * @param class_tag the expected class tag
601 * @param real_type the type tag the contents should be parsed as
602 * @param real_class the class tag the contents should be parsed as
603 * @param default_value the value used if the field is not present
604 */
605 template <typename T>
606 BER_Decoder& decode_optional_implicit(T& out,
607 ASN1_Type type_tag,
608 ASN1_Class class_tag,
609 ASN1_Type real_type,
610 ASN1_Class real_class,
611 const T& default_value = T());
612
613 /**
614 * Decode an OPTIONAL field identified by a context-specific tag number.
615 *
616 * If the next object is tagged [tag_no] with class @p class_tag, @p fn is
617 * invoked to decode it (fn must consume exactly that object). Otherwise the
618 * stream is left unchanged and fn is not called.
619 *
620 * For a SEQUENCE of optional tagged fields that (per DER) appear at most
621 * once and in increasing tag order: call this once per field in tag order,
622 * then end_cons(), which rejects any unconsumed object (i.e. a duplicate,
623 * out-of-order, or unknown-tag field).
624 */
625 template <typename F>
626 BER_Decoder& decode_optional_field(uint32_t tag_no, ASN1_Class class_tag, F&& fn) {
627 if(peek_next_object().is_a(tag_no, class_tag)) {
628 std::forward<F>(fn)(*this);
629 }
630 return (*this);
631 }
632
633 /**
634 * Decode an already-extracted BER_Object as if its tag were
635 * `real_type`/`real_class`. Used to consume IMPLICIT-tagged values
636 * whose body matches a different universal type (e.g. a
637 * context-specific [8] body that should be parsed as an OID).
638 */
639 template <typename T>
640 BER_Decoder& decode_implicit(BER_Object obj, T& out, ASN1_Type real_type, ASN1_Class real_class) {
641 obj.set_tagging(real_type, real_class);
642 push_back(std::move(obj));
643 if constexpr(std::is_base_of_v<ASN1_Object, T>) {
644 // The object was re-tagged above; decode_from checks the real tag itself
645 return decode(out);
646 } else {
647 return decode(out, real_type, real_class);
648 }
649 }
650
651 /**
652 * Read the next object, requiring it be tagged `type_tag`/`class_tag`, and
653 * decode it as if its tag were `real_type`/`real_class`.
654 *
655 * @param out where the value is written
656 * @param type_tag the expected type tag
657 * @param class_tag the expected class tag
658 * @param real_type the type tag the contents should be parsed as
659 * @param real_class the class tag the contents should be parsed as
660 */
661 template <typename T>
663 T& out, ASN1_Type type_tag, ASN1_Class class_tag, ASN1_Type real_type, ASN1_Class real_class) {
665 obj.assert_is_a(type_tag, class_tag);
666 return decode_implicit(std::move(obj), out, real_type, real_class);
667 }
668
669 /**
670 * Decode a constructed object containing a list of homogeneously typed values
671 *
672 * @param vec where the values are appended
673 * @param type_tag the expected type tag of the constructed object
674 * @param class_tag the expected class tag of the constructed object
675 */
676 template <typename T>
677 BER_Decoder& decode_list(std::vector<T>& vec,
680
681 /**
682 * Decode a list of homogeneously typed values if one is present
683 *
684 * @param vec where the values are appended
685 * @param type_tag the expected type tag of the constructed object
686 * @param class_tag the expected class tag of the constructed object
687 * @return true if the list was present
688 */
689 template <typename T>
690 bool decode_optional_list(std::vector<T>& vec,
693
694 /**
695 * Decode a value and throw unless it equals the expected value
696 *
697 * @param expected the value the encoding must have
698 * @param error_msg the message of the exception thrown on a mismatch
699 */
700 template <typename T>
701 BER_Decoder& decode_and_check(const T& expected, std::string_view error_msg) {
702 T actual;
703 decode(actual);
704
705 if(actual != expected) {
706 throw Decoding_Error(error_msg);
707 }
708
709 return (*this);
710 }
711
712 /**
713 * Decode an OPTIONAL string type, clearing @p out if it is absent
714 *
715 * @param out where the contents are written
716 * @param real_type the type tag the contents should be parsed as
717 * @param expected_tag the expected tag number
718 * @param class_tag the expected class tag
719 */
720 template <typename Alloc>
721 BER_Decoder& decode_optional_string(std::vector<uint8_t, Alloc>& out,
722 ASN1_Type real_type,
723 uint32_t expected_tag,
726
727 const ASN1_Type type_tag = static_cast<ASN1_Type>(expected_tag);
728
729 if(obj.is_a(type_tag, class_tag)) {
730 if(class_tag == ASN1_Class::ExplicitContextSpecific) {
731 BER_Decoder(obj, m_limits).decode(out, real_type).verify_end();
732 } else {
733 push_back(std::move(obj));
734 decode(out, real_type, type_tag, class_tag);
735 }
736 } else {
737 out.clear();
738 push_back(std::move(obj));
739 }
740
741 return (*this);
742 }
743
744 /**
745 * Decode an OPTIONAL string type, clearing @p out if it is absent
746 *
747 * @param out where the contents are written
748 * @param real_type the type tag the contents should be parsed as
749 * @param expected_tag the expected type tag
750 * @param class_tag the expected class tag
751 */
752 template <typename Alloc>
753 BER_Decoder& decode_optional_string(std::vector<uint8_t, Alloc>& out,
754 ASN1_Type real_type,
755 ASN1_Type expected_tag,
757 return decode_optional_string(out, real_type, static_cast<uint32_t>(expected_tag), class_tag);
758 }
759
760 /**
761 * Decode an OPTIONAL BIT STRING with no unused bits, clearing @p out if it
762 * is absent
763 *
764 * @param out where the bits are written
765 * @param expected_tag the expected tag number
766 * @param class_tag the expected class tag
767 */
768 template <typename Alloc>
769 BER_Decoder& decode_optional_octet_aligned_bitstring(std::vector<uint8_t, Alloc>& out,
770 uint32_t expected_tag,
773
774 const ASN1_Type type_tag = static_cast<ASN1_Type>(expected_tag);
775
776 if(obj.is_a(type_tag, class_tag)) {
777 if(class_tag == ASN1_Class::ExplicitContextSpecific) {
778 BER_Decoder(obj, m_limits).decode_octet_aligned_bitstring(out).verify_end();
779 } else {
780 push_back(std::move(obj));
781 decode_octet_aligned_bitstring(out, type_tag, class_tag);
782 }
783 } else {
784 out.clear();
785 push_back(std::move(obj));
786 }
787
788 return (*this);
789 }
790
791 /**
792 * Decode an OPTIONAL BIT STRING with no unused bits, clearing @p out if it
793 * is absent
794 *
795 * @param out where the bits are written
796 * @param expected_tag the expected type tag
797 * @param class_tag the expected class tag
798 */
799 template <typename Alloc>
800 BER_Decoder& decode_optional_octet_aligned_bitstring(std::vector<uint8_t, Alloc>& out,
801 ASN1_Type expected_tag,
803 return decode_optional_octet_aligned_bitstring(out, static_cast<uint32_t>(expected_tag), class_tag);
804 }
805
807
808 private:
809 BER_Decoder(BER_Object&& obj, BER_Decoder* parent);
810
811 std::optional<uint8_t> read_next_byte();
812
813 BER_Object get_next_value(size_t sizeofT, ASN1_Type type_tag, ASN1_Class class_tag);
814
815 Limits m_limits;
816 BER_Decoder* m_parent = nullptr;
817 BER_Object m_pushed;
818 // either m_data_src.get() or an unowned pointer
819 DataSource* m_source;
820 std::unique_ptr<DataSource> m_data_src;
821};
822
823/**
824* Decode an OPTIONAL or DEFAULT element
825*/
826template <typename T>
827BER_Decoder& BER_Decoder::decode_optional(std::optional<T>& optval, ASN1_Type type_tag, ASN1_Class class_tag) {
829
830 if(obj.is_a(type_tag, class_tag)) {
831 T out{};
832 if(class_tag == ASN1_Class::ExplicitContextSpecific) {
833 BER_Decoder(obj, m_limits).decode(out).verify_end();
834 } else {
835 this->push_back(std::move(obj));
836 if constexpr(std::is_base_of_v<ASN1_Object, T>) {
837 // Object types check the tag in decode_from; a re-tagging
838 // implicit override of an object is not supported here
839 this->decode(out);
840 } else {
841 this->decode(out, type_tag, class_tag);
842 }
843 }
844 optval = std::move(out);
845 } else {
846 this->push_back(std::move(obj));
847 optval = std::nullopt;
848 }
849
850 return (*this);
851}
852
853/**
854* Decode an OPTIONAL or DEFAULT element with an IMPLICIT tagging
855*/
856template <typename T>
858 ASN1_Type type_tag,
859 ASN1_Class class_tag,
860 ASN1_Type real_type,
861 ASN1_Class real_class,
862 const T& default_value) {
864
865 if(obj.is_a(type_tag, class_tag)) {
866 decode_implicit(std::move(obj), out, real_type, real_class);
867 } else {
868 // Not what we wanted, push it back on the stream
869 out = default_value;
870 push_back(std::move(obj));
871 }
872
873 return (*this);
874}
875
876/**
877* Decode a list of homogeneously typed values
878*/
879template <typename T>
880BER_Decoder& BER_Decoder::decode_list(std::vector<T>& vec, ASN1_Type type_tag, ASN1_Class class_tag) {
881 BER_Decoder list = start_cons(type_tag, class_tag);
882
883 while(list.more_items()) {
884 T value;
885 list.decode(value);
886 vec.push_back(std::move(value));
887 }
888
889 list.end_cons();
890
891 return (*this);
892}
893
894/**
895* Decode an optional list of homogeneously typed values
896*/
897template <typename T>
898bool BER_Decoder::decode_optional_list(std::vector<T>& vec, ASN1_Type type_tag, ASN1_Class class_tag) {
899 if(peek_next_object().is_a(type_tag, class_tag)) {
900 decode_list(vec, type_tag, class_tag);
901 return true;
902 }
903
904 return false;
905}
906
907} // namespace Botan
908
909#endif
#define BOTAN_PUBLIC_API(maj, min)
Definition api.h:21
#define BOTAN_DEPRECATED(msg)
Definition api.h:73
#define BOTAN_FUTURE_EXPLICIT
Definition api.h:52
size_t unused_bits() const
Definition asn1_obj.h:211
std::span< const uint8_t > bytes() const
Definition asn1_obj.h:206
bool operator==(const Limits &) const =default
static Limits BER(size_t max_nested_indef=16)
Definition ber_dec.h:49
Limits with_default_value_encoding_rejected() const
Definition ber_dec.h:116
static constexpr size_t DefaultMaxObjectSize
Definition ber_dec.h:37
bool reject_default_value_encoding() const
Definition ber_dec.h:89
Limits with_standalone_eoc_allowed() const
Definition ber_dec.h:95
static Limits DER()
Definition ber_dec.h:42
Limits with_max_object_size(std::optional< size_t > max_object_size) const
Definition ber_dec.h:106
size_t max_nested_indefinite_length() const
Definition ber_dec.h:66
bool allow_ber_encoding() const
Definition ber_dec.h:56
std::optional< size_t > max_object_size() const
Definition ber_dec.h:80
bool allow_standalone_eoc() const
Definition ber_dec.h:74
bool require_der_encoding() const
Definition ber_dec.h:61
BOTAN_FUTURE_EXPLICIT BER_Decoder(BER_Object &&obj)
Definition ber_dec.h:173
BER_Decoder start_set()
Definition ber_dec.h:281
BER_Decoder(BER_Decoder &&other) noexcept
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_optional_octet_aligned_bitstring(std::vector< uint8_t, Alloc > &out, ASN1_Type expected_tag, ASN1_Class class_tag=ASN1_Class::ContextSpecific)
Definition ber_dec.h:800
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
BER_Decoder & decode_implicit(T &out, ASN1_Type type_tag, ASN1_Class class_tag, ASN1_Type real_type, ASN1_Class real_class)
Definition ber_dec.h:662
Limits limits() const
Definition ber_dec.h:197
BER_Decoder & decode(BigInt &out)
Definition ber_dec.h:368
BER_Decoder & decode_optional_string(std::vector< uint8_t, Alloc > &out, ASN1_Type real_type, ASN1_Type expected_tag, ASN1_Class class_tag=ASN1_Class::ContextSpecific)
Definition ber_dec.h:753
BER_Decoder & raw_bytes(std::vector< uint8_t, Alloc > &out)
Definition ber_dec.h:338
BER_Decoder & decode_integer_type(T &out, ASN1_Type type_tag, ASN1_Class class_tag=ASN1_Class::ContextSpecific)
Definition ber_dec.h:539
std::vector< uint8_t > get_next_octet_string()
Definition ber_dec.h:373
BOTAN_FUTURE_EXPLICIT BER_Decoder(const BER_Object &obj, Limits limits=Limits::BER())
Definition ber_dec.h:166
BER_Decoder & decode(std::vector< uint8_t, Alloc > &out, ASN1_Type real_type)
Definition ber_dec.h:386
BER_Decoder start_explicit_context_specific(uint32_t tag)
Definition ber_dec.h:301
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 & decode_optional_octet_aligned_bitstring(std::vector< uint8_t, Alloc > &out, uint32_t expected_tag, ASN1_Class class_tag=ASN1_Class::ContextSpecific)
Definition ber_dec.h:769
BER_Decoder(const BER_Decoder &other)=delete
BER_Decoder start_cons(ASN1_Type type_tag, ASN1_Class class_tag)
Definition ber_dec.cpp:614
BER_Decoder start_sequence()
Definition ber_dec.h:275
BER_Decoder & operator=(BER_Decoder &&) noexcept
bool decode_optional_list(std::vector< T > &vec, ASN1_Type type_tag=ASN1_Type::Sequence, ASN1_Class class_tag=ASN1_Class::Universal)
Definition ber_dec.h:898
BER_Decoder start_context_specific(uint32_t tag)
Definition ber_dec.h:290
BER_Decoder & decode_optional(T &out, ASN1_Type type_tag, ASN1_Class class_tag, const T &default_value=T())
Definition ber_dec.h:553
BER_Decoder & decode_implicit(BER_Object obj, T &out, ASN1_Type real_type, ASN1_Class real_class)
Definition ber_dec.h:640
BER_Decoder & decode_and_check(const T &expected, std::string_view error_msg)
Definition ber_dec.h:701
BER_Decoder & decode(size_t &out)
Definition ber_dec.h:363
BER_Decoder & decode_optional_string(std::vector< uint8_t, Alloc > &out, ASN1_Type real_type, uint32_t expected_tag, ASN1_Class class_tag=ASN1_Class::ContextSpecific)
Definition ber_dec.h:721
BER_Decoder & decode_integer_type(T &out)
Definition ber_dec.h:526
BER_Decoder & decode_optional_implicit(T &out, ASN1_Type type_tag, ASN1_Class class_tag, ASN1_Type real_type, ASN1_Class real_class, const T &default_value=T())
Definition ber_dec.h:857
BER_Decoder & decode_default(T &out, ASN1_Type type_tag, ASN1_Class class_tag, const T &default_value)
Definition ber_dec.h:569
BER_Decoder & decode_optional_field(uint32_t tag_no, ASN1_Class class_tag, F &&fn)
Definition ber_dec.h:626
BER_Decoder & operator=(const BER_Decoder &)=delete
BER_Decoder & get_next(BER_Object &ber)
Definition ber_dec.h:210
BER_Decoder & decode_list(std::vector< T > &vec, ASN1_Type type_tag=ASN1_Type::Sequence, ASN1_Class class_tag=ASN1_Class::Universal)
Definition ber_dec.h:880
BER_Decoder & decode_octet_aligned_bitstring(std::vector< uint8_t, Alloc > &out, ASN1_Type type_tag=ASN1_Type::BitString, ASN1_Class class_tag=ASN1_Class::Universal)
Definition ber_dec.h:462
size_t length() const
Definition asn1_obj.h:303
const uint8_t * bits() const
Definition asn1_obj.h:298
bool is_a(ASN1_Type type_tag, ASN1_Class class_tag) const
Definition asn1_obj.cpp:97
void assert_is_a(ASN1_Type type_tag, ASN1_Class class_tag, std::string_view descr="object") const
Definition asn1_obj.cpp:65
ASN1_Class
Definition asn1_obj.h:32
ASN1_Type
Definition asn1_obj.h:47
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:128