Botan 3.0.0-alpha0
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/data_src.h>
13
14namespace Botan {
15
16class BigInt;
17
18/**
19* BER Decoding Object
20*/
22 {
23 public:
24 /**
25 * Set up to BER decode the data in buf of length len
26 */
27 BER_Decoder(const uint8_t buf[], size_t len);
28
29 /**
30 * Set up to BER decode the data in vec
31 */
32 explicit BER_Decoder(const secure_vector<uint8_t>& vec);
33
34 /**
35 * Set up to BER decode the data in vec
36 */
37 explicit BER_Decoder(const std::vector<uint8_t>& vec);
38
39 /**
40 * Set up to BER decode the data in src
41 */
42 explicit BER_Decoder(DataSource& src);
43
44 /**
45 * Set up to BER decode the data in obj
46 */
47 BER_Decoder(const BER_Object& obj) :
48 BER_Decoder(obj.bits(), obj.length()) {}
49
50 /**
51 * Set up to BER decode the data in obj
52 */
54 BER_Decoder(std::move(obj), nullptr) {}
55
56 BER_Decoder(const BER_Decoder& other);
57
59
60 /**
61 * Get the next object in the data stream.
62 * If EOF, returns an object with type NO_OBJECT.
63 */
64 BER_Object get_next_object();
65
67 {
68 ber = get_next_object();
69 return (*this);
70 }
71
72 /**
73 * Push an object back onto the stream. Throws if another
74 * object was previously pushed and has not been subsequently
75 * read out.
76 */
77 void push_back(const BER_Object& obj);
78
79 /**
80 * Push an object back onto the stream. Throws if another
81 * object was previously pushed and has not been subsequently
82 * read out.
83 */
84 void push_back(BER_Object&& obj);
85
86 /**
87 * Return true if there is at least one more item remaining
88 */
89 bool more_items() const;
90
91 /**
92 * Verify the stream is concluded, throws otherwise.
93 * Returns (*this)
94 */
95 BER_Decoder& verify_end();
96
97 /**
98 * Verify the stream is concluded, throws otherwise.
99 * Returns (*this)
100 */
101 BER_Decoder& verify_end(const std::string& err_msg);
102
103 /**
104 * Discard any data that remains unread
105 * Returns (*this)
106 */
107 BER_Decoder& discard_remaining();
108
109 BER_Decoder start_cons(ASN1_Type type_tag, ASN1_Class class_tag);
110
112 {
113 return start_cons(ASN1_Type::Sequence, ASN1_Class::Universal);
114 }
115
117 {
118 return start_cons(ASN1_Type::Set, ASN1_Class::Universal);
119 }
120
122 {
123 return start_cons(ASN1_Type(tag), ASN1_Class::ContextSpecific);
124 }
125
127 {
128 return start_cons(ASN1_Type(tag), ASN1_Class::ExplicitContextSpecific);
129 }
130
131 /**
132 * Finish decoding a constructed data, throws if any data remains.
133 * Returns the parent of *this (ie the object on which start_cons was called).
134 */
135 BER_Decoder& end_cons();
136
137 /**
138 * Get next object and copy value to POD type
139 * Asserts value length is equal to POD type sizeof.
140 * Asserts Type tag and optional Class tag according to parameters.
141 * Copy value to POD type (struct, union, C-style array, std::array, etc.).
142 * @param out POD type reference where to copy object value
143 * @param type_tag ASN1_Type enum to assert type on object read
144 * @param class_tag ASN1_Type enum to assert class on object read (default: CONTEXT_SPECIFIC)
145 * @return this reference
146 */
147 template <typename T>
149 ASN1_Type type_tag,
151 {
152 static_assert(std::is_standard_layout<T>::value && std::is_trivial<T>::value, "Type must be POD");
153
154 BER_Object obj = get_next_object();
155 obj.assert_is_a(type_tag, class_tag);
156
157 if (obj.length() != sizeof(T))
158 throw BER_Decoding_Error(
159 "Size mismatch. Object value size is " +
160 std::to_string(obj.length()) +
161 "; Output type size is " +
162 std::to_string(sizeof(T)));
163
164 copy_mem(reinterpret_cast<uint8_t*>(&out), obj.bits(), obj.length());
165
166 return (*this);
167 }
168
169 /*
170 * Save all the bytes remaining in the source
171 */
172 template<typename Alloc>
173 BER_Decoder& raw_bytes(std::vector<uint8_t, Alloc>& out)
174 {
175 out.clear();
176 uint8_t buf;
177 while(m_source->read_byte(buf))
178 out.push_back(buf);
179 return (*this);
180 }
181
182 BER_Decoder& decode_null();
183
184 /**
185 * Decode a BER encoded BOOLEAN
186 */
187 BER_Decoder& decode(bool& out)
188 {
190 }
191
192 /*
193 * Decode a small BER encoded INTEGER
194 */
195 BER_Decoder& decode(size_t& out)
196 {
198 }
199
200 /*
201 * Decode a BER encoded INTEGER
202 */
204 {
206 }
207
208 std::vector<uint8_t> get_next_octet_string()
209 {
210 std::vector<uint8_t> out_vec;
212 return out_vec;
213 }
214
215 /*
216 * BER decode a BIT STRING or OCTET STRING
217 */
218 template<typename Alloc>
219 BER_Decoder& decode(std::vector<uint8_t, Alloc>& out, ASN1_Type real_type)
220 {
221 return decode(out, real_type, real_type, ASN1_Class::Universal);
222 }
223
224 BER_Decoder& decode(bool& v,
225 ASN1_Type type_tag,
227
228 BER_Decoder& decode(size_t& v,
229 ASN1_Type type_tag,
231
233 ASN1_Type type_tag,
235
236 BER_Decoder& decode(std::vector<uint8_t>& v,
237 ASN1_Type real_type,
238 ASN1_Type type_tag,
240
242 ASN1_Type real_type,
243 ASN1_Type type_tag,
245
248 ASN1_Class class_tag = ASN1_Class::NoObject);
249
250 /**
251 * Decode an integer value which is typed as an octet string
252 */
253 BER_Decoder& decode_octet_string_bigint(BigInt& b);
254
255 uint64_t decode_constrained_integer(ASN1_Type type_tag,
256 ASN1_Class class_tag,
257 size_t T_bytes);
258
259 template<typename T> BER_Decoder& decode_integer_type(T& out)
260 {
261 return decode_integer_type<T>(out, ASN1_Type::Integer, ASN1_Class::Universal);
262 }
263
264 template<typename T>
266 ASN1_Type type_tag,
268 {
269 out = static_cast<T>(decode_constrained_integer(type_tag, class_tag, sizeof(out)));
270 return (*this);
271 }
272
273 template<typename T>
274 BER_Decoder& decode_optional(T& out,
275 ASN1_Type type_tag,
276 ASN1_Class class_tag,
277 const T& default_value = T());
278
279 template<typename T>
280 BER_Decoder& decode_optional_implicit(
281 T& out,
282 ASN1_Type type_tag,
283 ASN1_Class class_tag,
284 ASN1_Type real_type,
285 ASN1_Class real_class,
286 const T& default_value = T());
287
288 template<typename T>
289 BER_Decoder& decode_list(std::vector<T>& out,
292
293 template<typename T>
295 const std::string& error_msg)
296 {
297 T actual;
298 decode(actual);
299
300 if(actual != expected)
301 throw Decoding_Error(error_msg);
302
303 return (*this);
304 }
305
306 /*
307 * Decode an OPTIONAL string type
308 */
309 template<typename Alloc>
310 BER_Decoder& decode_optional_string(std::vector<uint8_t, Alloc>& out,
311 ASN1_Type real_type,
312 uint32_t expected_tag,
314 {
315 BER_Object obj = get_next_object();
316
317 ASN1_Type type_tag = static_cast<ASN1_Type>(expected_tag);
318
319 if(obj.is_a(type_tag, class_tag))
320 {
322 {
323 BER_Decoder(std::move(obj)).decode(out, real_type).verify_end();
324 }
325 else
326 {
327 push_back(std::move(obj));
328 decode(out, real_type, type_tag, class_tag);
329 }
330 }
331 else
332 {
333 out.clear();
334 push_back(std::move(obj));
335 }
336
337 return (*this);
338 }
339
340 template<typename Alloc>
341 BER_Decoder& decode_optional_string(std::vector<uint8_t, Alloc>& out,
342 ASN1_Type real_type,
343 ASN1_Type expected_tag,
345 {
346 return decode_optional_string(out, real_type,
347 static_cast<uint32_t>(expected_tag),
348 class_tag);
349 }
350
351 private:
352 BER_Decoder(BER_Object&& obj, BER_Decoder* parent);
353
354 BER_Decoder* m_parent = nullptr;
355 BER_Object m_pushed;
356 // either m_data_src.get() or an unowned pointer
357 DataSource* m_source;
358 mutable std::unique_ptr<DataSource> m_data_src;
359 };
360
361/*
362* Decode an OPTIONAL or DEFAULT element
363*/
364template<typename T>
366 ASN1_Type type_tag,
367 ASN1_Class class_tag,
368 const T& default_value)
369 {
371
372 if(obj.is_a(type_tag, class_tag))
373 {
375 {
376 BER_Decoder(std::move(obj)).decode(out).verify_end();
377 }
378 else
379 {
380 push_back(std::move(obj));
381 decode(out, type_tag, class_tag);
382 }
383 }
384 else
385 {
386 out = default_value;
387 push_back(std::move(obj));
388 }
389
390 return (*this);
391 }
392
393/*
394* Decode an OPTIONAL or DEFAULT element
395*/
396template<typename T>
398 T& out,
399 ASN1_Type type_tag,
400 ASN1_Class class_tag,
401 ASN1_Type real_type,
402 ASN1_Class real_class,
403 const T& default_value)
404 {
406
407 if(obj.is_a(type_tag, class_tag))
408 {
409 obj.set_tagging(real_type, real_class);
410 push_back(std::move(obj));
411 decode(out, real_type, real_class);
412 }
413 else
414 {
415 // Not what we wanted, push it back on the stream
416 out = default_value;
417 push_back(std::move(obj));
418 }
419
420 return (*this);
421 }
422/*
423* Decode a list of homogenously typed values
424*/
425template<typename T>
427 ASN1_Type type_tag,
428 ASN1_Class class_tag)
429 {
430 BER_Decoder list = start_cons(type_tag, class_tag);
431
432 while(list.more_items())
433 {
434 T value;
435 list.decode(value);
436 vec.push_back(std::move(value));
437 }
438
439 list.end_cons();
440
441 return (*this);
442 }
443
444}
445
446#endif
BER_Decoder start_set()
Definition: ber_dec.h:116
BER_Decoder(const uint8_t buf[], size_t len)
Definition: ber_dec.cpp:330
void push_back(const BER_Object &obj)
Definition: ber_dec.cpp:279
BER_Decoder & get_next_value(T &out, ASN1_Type type_tag, ASN1_Class class_tag=ASN1_Class::ContextSpecific)
Definition: ber_dec.h:148
BER_Object get_next_object()
Definition: ber_dec.cpp:239
BER_Decoder & decode(bool &out)
Definition: ber_dec.h:187
bool more_items() const
Definition: ber_dec.cpp:200
BER_Decoder & decode(BigInt &out)
Definition: ber_dec.h:203
BER_Decoder(BER_Object &&obj)
Definition: ber_dec.h:53
BER_Decoder & decode_and_check(const T &expected, const std::string &error_msg)
Definition: ber_dec.h:294
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:341
BER_Decoder & raw_bytes(std::vector< uint8_t, Alloc > &out)
Definition: ber_dec.h:173
BER_Decoder & decode_integer_type(T &out, ASN1_Type type_tag, ASN1_Class class_tag=ASN1_Class::ContextSpecific)
Definition: ber_dec.h:265
std::vector< uint8_t > get_next_octet_string()
Definition: ber_dec.h:208
BER_Decoder & verify_end()
Definition: ber_dec.cpp:210
BER_Decoder & decode(std::vector< uint8_t, Alloc > &out, ASN1_Type real_type)
Definition: ber_dec.h:219
BER_Decoder start_explicit_context_specific(uint32_t tag)
Definition: ber_dec.h:126
BER_Decoder & end_cons()
Definition: ber_dec.cpp:303
BER_Decoder start_cons(ASN1_Type type_tag, ASN1_Class class_tag)
Definition: ber_dec.cpp:293
BER_Decoder(const BER_Object &obj)
Definition: ber_dec.h:47
BER_Decoder & decode_list(std::vector< T > &out, ASN1_Type type_tag=ASN1_Type::Sequence, ASN1_Class class_tag=ASN1_Class::Universal)
Definition: ber_dec.h:426
BER_Decoder start_sequence()
Definition: ber_dec.h:111
BER_Decoder start_context_specific(uint32_t tag)
Definition: ber_dec.h:121
BER_Decoder & decode_optional(T &out, ASN1_Type type_tag, ASN1_Class class_tag, const T &default_value=T())
Definition: ber_dec.h:365
BER_Decoder & decode(size_t &out)
Definition: ber_dec.h:195
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:310
BER_Decoder & decode_integer_type(T &out)
Definition: ber_dec.h:259
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:397
BER_Decoder & operator=(const BER_Decoder &)=delete
BER_Decoder & get_next(BER_Object &ber)
Definition: ber_dec.h:66
size_t length() const
Definition: asn1_obj.h:153
const uint8_t * bits() const
Definition: asn1_obj.h:151
void assert_is_a(ASN1_Type type_tag, ASN1_Class class_tag, const std::string &descr="object") const
Definition: asn1_obj.cpp:27
bool is_a(ASN1_Type type_tag, ASN1_Class class_tag) const
Definition: asn1_obj.cpp:71
int(* final)(unsigned char *, CTX *)
#define BOTAN_PUBLIC_API(maj, min)
Definition: compiler.h:31
fe T
Definition: ge.cpp:36
Polynomial v
Definition: kyber.cpp:822
PolynomialVector b
Definition: kyber.cpp:821
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:209
secure_vector< uint8_t > decode(DataSource &source, std::string &label)
Definition: pem.cpp:66
Definition: alg_id.cpp:13
ASN1_Class
Definition: asn1_obj.h:24
ASN1_Type
Definition: asn1_obj.h:39
constexpr void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:126
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:65
Definition: bigint.h:1077