Coverage Report

Created: 2021-05-04 09:02

/src/botan/build/include/botan/ber_dec.h
Line
Count
Source (jump to first uncovered line)
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
14
namespace Botan {
15
16
class BigInt;
17
18
/**
19
* BER Decoding Object
20
*/
21
class BOTAN_PUBLIC_API(2,0) BER_Decoder final
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
27.8k
         BER_Decoder(obj.bits(), obj.length()) {}
49
50
      /**
51
      * Set up to BER decode the data in obj
52
      */
53
      BER_Decoder(BER_Object&& obj) :
54
7.37k
         BER_Decoder(std::move(obj), nullptr) {}
55
56
      BER_Decoder(const BER_Decoder& other);
57
58
      BER_Decoder& operator=(const BER_Decoder&) = delete;
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
66
      BER_Decoder& get_next(BER_Object& ber)
67
20.1k
         {
68
20.1k
         ber = get_next_object();
69
20.1k
         return (*this);
70
20.1k
         }
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
111
      BER_Decoder start_sequence()
112
369k
         {
113
369k
         return start_cons(ASN1_Type::Sequence, ASN1_Class::Universal);
114
369k
         }
115
116
      BER_Decoder start_set()
117
89.4k
         {
118
89.4k
         return start_cons(ASN1_Type::Set, ASN1_Class::Universal);
119
89.4k
         }
120
121
      BER_Decoder start_context_specific(uint32_t tag)
122
7.08k
         {
123
7.08k
         return start_cons(ASN1_Type(tag), ASN1_Class::ContextSpecific);
124
7.08k
         }
125
126
      BER_Decoder start_explicit_context_specific(uint32_t tag)
127
0
         {
128
0
         return start_cons(ASN1_Type(tag), ASN1_Class::ExplicitContextSpecific);
129
0
         }
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>
148
         BER_Decoder& get_next_value(T &out,
149
                                     ASN1_Type type_tag,
150
                                     ASN1_Class class_tag = ASN1_Class::ContextSpecific)
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
108k
         {
175
108k
         out.clear();
176
108k
         uint8_t buf;
177
11.3M
         while(m_source->read_byte(buf))
178
11.2M
            out.push_back(buf);
179
108k
         return (*this);
180
108k
         }
181
182
      BER_Decoder& decode_null();
183
184
      /**
185
      * Decode a BER encoded BOOLEAN
186
      */
187
      BER_Decoder& decode(bool& out)
188
627
         {
189
627
         return decode(out, ASN1_Type::Boolean, ASN1_Class::Universal);
190
627
         }
191
192
      /*
193
      * Decode a small BER encoded INTEGER
194
      */
195
      BER_Decoder& decode(size_t& out)
196
9.05k
         {
197
9.05k
         return decode(out, ASN1_Type::Integer, ASN1_Class::Universal);
198
9.05k
         }
199
200
      /*
201
      * Decode a BER encoded INTEGER
202
      */
203
      BER_Decoder& decode(BigInt& out)
204
45.7k
         {
205
45.7k
         return decode(out, ASN1_Type::Integer, ASN1_Class::Universal);
206
45.7k
         }
207
208
      std::vector<uint8_t> get_next_octet_string()
209
2.97k
         {
210
2.97k
         std::vector<uint8_t> out_vec;
211
2.97k
         decode(out_vec, ASN1_Type::OctetString);
212
2.97k
         return out_vec;
213
2.97k
         }
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
104k
         {
221
104k
         return decode(out, real_type, real_type, ASN1_Class::Universal);
222
104k
         }
Botan::BER_Decoder& Botan::BER_Decoder::decode<std::__1::allocator<unsigned char> >(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&, Botan::ASN1_Type)
Line
Count
Source
220
99.2k
         {
221
99.2k
         return decode(out, real_type, real_type, ASN1_Class::Universal);
222
99.2k
         }
Botan::BER_Decoder& Botan::BER_Decoder::decode<Botan::secure_allocator<unsigned char> >(std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >&, Botan::ASN1_Type)
Line
Count
Source
220
5.45k
         {
221
5.45k
         return decode(out, real_type, real_type, ASN1_Class::Universal);
222
5.45k
         }
223
224
      BER_Decoder& decode(bool& v,
225
                          ASN1_Type type_tag,
226
                          ASN1_Class class_tag = ASN1_Class::ContextSpecific);
227
228
      BER_Decoder& decode(size_t& v,
229
                          ASN1_Type type_tag,
230
                          ASN1_Class class_tag = ASN1_Class::ContextSpecific);
231
232
      BER_Decoder& decode(BigInt& v,
233
                          ASN1_Type type_tag,
234
                          ASN1_Class class_tag = ASN1_Class::ContextSpecific);
235
236
      BER_Decoder& decode(std::vector<uint8_t>& v,
237
                          ASN1_Type real_type,
238
                          ASN1_Type type_tag,
239
                          ASN1_Class class_tag = ASN1_Class::ContextSpecific);
240
241
      BER_Decoder& decode(secure_vector<uint8_t>& v,
242
                          ASN1_Type real_type,
243
                          ASN1_Type type_tag,
244
                          ASN1_Class class_tag = ASN1_Class::ContextSpecific);
245
246
      BER_Decoder& decode(class ASN1_Object& obj,
247
                          ASN1_Type type_tag = ASN1_Type::NoObject,
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
0
         {
261
0
         return decode_integer_type<T>(out, ASN1_Type::Integer, ASN1_Class::Universal);
262
0
         }
Unexecuted instantiation: Botan::BER_Decoder& Botan::BER_Decoder::decode_integer_type<unsigned long>(unsigned long&)
Unexecuted instantiation: Botan::BER_Decoder& Botan::BER_Decoder::decode_integer_type<unsigned char>(unsigned char&)
Unexecuted instantiation: Botan::BER_Decoder& Botan::BER_Decoder::decode_integer_type<unsigned short>(unsigned short&)
263
264
      template<typename T>
265
         BER_Decoder& decode_integer_type(T& out,
266
                                          ASN1_Type type_tag,
267
                                          ASN1_Class class_tag = ASN1_Class::ContextSpecific)
268
0
         {
269
0
         out = static_cast<T>(decode_constrained_integer(type_tag, class_tag, sizeof(out)));
270
0
         return (*this);
271
0
         }
Unexecuted instantiation: Botan::BER_Decoder& Botan::BER_Decoder::decode_integer_type<unsigned long>(unsigned long&, Botan::ASN1_Type, Botan::ASN1_Class)
Unexecuted instantiation: Botan::BER_Decoder& Botan::BER_Decoder::decode_integer_type<unsigned char>(unsigned char&, Botan::ASN1_Type, Botan::ASN1_Class)
Unexecuted instantiation: Botan::BER_Decoder& Botan::BER_Decoder::decode_integer_type<unsigned short>(unsigned short&, Botan::ASN1_Type, Botan::ASN1_Class)
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,
290
                                  ASN1_Type type_tag = ASN1_Type::Sequence,
291
                                  ASN1_Class class_tag = ASN1_Class::Universal);
292
293
      template<typename T>
294
         BER_Decoder& decode_and_check(const T& expected,
295
                                       const std::string& error_msg)
296
8.75k
         {
297
8.75k
         T actual;
298
8.75k
         decode(actual);
299
300
8.75k
         if(actual != expected)
301
301
            throw Decoding_Error(error_msg);
302
303
8.45k
         return (*this);
304
8.45k
         }
Botan::BER_Decoder& Botan::BER_Decoder::decode_and_check<unsigned long>(unsigned long const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Line
Count
Source
296
4.94k
         {
297
4.94k
         T actual;
298
4.94k
         decode(actual);
299
300
4.94k
         if(actual != expected)
301
110
            throw Decoding_Error(error_msg);
302
303
4.83k
         return (*this);
304
4.83k
         }
Botan::BER_Decoder& Botan::BER_Decoder::decode_and_check<Botan::OID>(Botan::OID const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Line
Count
Source
296
3.81k
         {
297
3.81k
         T actual;
298
3.81k
         decode(actual);
299
300
3.81k
         if(actual != expected)
301
191
            throw Decoding_Error(error_msg);
302
303
3.62k
         return (*this);
304
3.62k
         }
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,
313
                                          ASN1_Class class_tag = ASN1_Class::ContextSpecific)
314
23.6k
         {
315
23.6k
         BER_Object obj = get_next_object();
316
317
23.6k
         ASN1_Type type_tag = static_cast<ASN1_Type>(expected_tag);
318
319
23.6k
         if(obj.is_a(type_tag, class_tag))
320
1.00k
            {
321
1.00k
            if(class_tag == ASN1_Class::ExplicitContextSpecific)
322
858
               {
323
858
               BER_Decoder(std::move(obj)).decode(out, real_type).verify_end();
324
858
               }
325
144
            else
326
144
               {
327
144
               push_back(std::move(obj));
328
144
               decode(out, real_type, type_tag, class_tag);
329
144
               }
330
1.00k
            }
331
22.6k
         else
332
22.6k
            {
333
22.6k
            out.clear();
334
22.6k
            push_back(std::move(obj));
335
22.6k
            }
336
337
23.6k
         return (*this);
338
23.6k
         }
Botan::BER_Decoder& Botan::BER_Decoder::decode_optional_string<std::__1::allocator<unsigned char> >(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&, Botan::ASN1_Type, unsigned int, Botan::ASN1_Class)
Line
Count
Source
314
22.5k
         {
315
22.5k
         BER_Object obj = get_next_object();
316
317
22.5k
         ASN1_Type type_tag = static_cast<ASN1_Type>(expected_tag);
318
319
22.5k
         if(obj.is_a(type_tag, class_tag))
320
252
            {
321
252
            if(class_tag == ASN1_Class::ExplicitContextSpecific)
322
108
               {
323
108
               BER_Decoder(std::move(obj)).decode(out, real_type).verify_end();
324
108
               }
325
144
            else
326
144
               {
327
144
               push_back(std::move(obj));
328
144
               decode(out, real_type, type_tag, class_tag);
329
144
               }
330
252
            }
331
22.3k
         else
332
22.3k
            {
333
22.3k
            out.clear();
334
22.3k
            push_back(std::move(obj));
335
22.3k
            }
336
337
22.5k
         return (*this);
338
22.5k
         }
Botan::BER_Decoder& Botan::BER_Decoder::decode_optional_string<Botan::secure_allocator<unsigned char> >(std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >&, Botan::ASN1_Type, unsigned int, Botan::ASN1_Class)
Line
Count
Source
314
1.12k
         {
315
1.12k
         BER_Object obj = get_next_object();
316
317
1.12k
         ASN1_Type type_tag = static_cast<ASN1_Type>(expected_tag);
318
319
1.12k
         if(obj.is_a(type_tag, class_tag))
320
750
            {
321
750
            if(class_tag == ASN1_Class::ExplicitContextSpecific)
322
750
               {
323
750
               BER_Decoder(std::move(obj)).decode(out, real_type).verify_end();
324
750
               }
325
0
            else
326
0
               {
327
0
               push_back(std::move(obj));
328
0
               decode(out, real_type, type_tag, class_tag);
329
0
               }
330
750
            }
331
378
         else
332
378
            {
333
378
            out.clear();
334
378
            push_back(std::move(obj));
335
378
            }
336
337
1.12k
         return (*this);
338
1.12k
         }
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,
344
                                          ASN1_Class class_tag = ASN1_Class::ContextSpecific)
345
535
         {
346
535
         return decode_optional_string(out, real_type,
347
535
                                       static_cast<uint32_t>(expected_tag),
348
535
                                       class_tag);
349
535
         }
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
*/
364
template<typename T>
365
BER_Decoder& BER_Decoder::decode_optional(T& out,
366
                                          ASN1_Type type_tag,
367
                                          ASN1_Class class_tag,
368
                                          const T& default_value)
369
68.2k
   {
370
68.2k
   BER_Object obj = get_next_object();
371
372
68.2k
   if(obj.is_a(type_tag, class_tag))
373
7.99k
      {
374
7.99k
      if(class_tag == ASN1_Class::ExplicitContextSpecific)
375
4.68k
         {
376
4.68k
         BER_Decoder(std::move(obj)).decode(out).verify_end();
377
4.68k
         }
378
3.30k
      else
379
3.30k
         {
380
3.30k
         push_back(std::move(obj));
381
3.30k
         decode(out, type_tag, class_tag);
382
3.30k
         }
383
7.99k
      }
384
60.2k
   else
385
60.2k
      {
386
60.2k
      out = default_value;
387
60.2k
      push_back(std::move(obj));
388
60.2k
      }
389
390
68.2k
   return (*this);
391
68.2k
   }
Botan::BER_Decoder& Botan::BER_Decoder::decode_optional<Botan::ASN1_Time>(Botan::ASN1_Time&, Botan::ASN1_Type, Botan::ASN1_Class, Botan::ASN1_Time const&)
Line
Count
Source
369
18
   {
370
18
   BER_Object obj = get_next_object();
371
372
18
   if(obj.is_a(type_tag, class_tag))
373
9
      {
374
9
      if(class_tag == ASN1_Class::ExplicitContextSpecific)
375
9
         {
376
9
         BER_Decoder(std::move(obj)).decode(out).verify_end();
377
9
         }
378
0
      else
379
0
         {
380
0
         push_back(std::move(obj));
381
0
         decode(out, type_tag, class_tag);
382
0
         }
383
9
      }
384
9
   else
385
9
      {
386
9
      out = default_value;
387
9
      push_back(std::move(obj));
388
9
      }
389
390
18
   return (*this);
391
18
   }
Botan::BER_Decoder& Botan::BER_Decoder::decode_optional<Botan::Extensions>(Botan::Extensions&, Botan::ASN1_Type, Botan::ASN1_Class, Botan::Extensions const&)
Line
Count
Source
369
891
   {
370
891
   BER_Object obj = get_next_object();
371
372
891
   if(obj.is_a(type_tag, class_tag))
373
872
      {
374
872
      if(class_tag == ASN1_Class::ExplicitContextSpecific)
375
872
         {
376
872
         BER_Decoder(std::move(obj)).decode(out).verify_end();
377
872
         }
378
0
      else
379
0
         {
380
0
         push_back(std::move(obj));
381
0
         decode(out, type_tag, class_tag);
382
0
         }
383
872
      }
384
19
   else
385
19
      {
386
19
      out = default_value;
387
19
      push_back(std::move(obj));
388
19
      }
389
390
891
   return (*this);
391
891
   }
Botan::BER_Decoder& Botan::BER_Decoder::decode_optional<bool>(bool&, Botan::ASN1_Type, Botan::ASN1_Class, bool const&)
Line
Count
Source
369
43.8k
   {
370
43.8k
   BER_Object obj = get_next_object();
371
372
43.8k
   if(obj.is_a(type_tag, class_tag))
373
1.91k
      {
374
1.91k
      if(class_tag == ASN1_Class::ExplicitContextSpecific)
375
0
         {
376
0
         BER_Decoder(std::move(obj)).decode(out).verify_end();
377
0
         }
378
1.91k
      else
379
1.91k
         {
380
1.91k
         push_back(std::move(obj));
381
1.91k
         decode(out, type_tag, class_tag);
382
1.91k
         }
383
1.91k
      }
384
41.9k
   else
385
41.9k
      {
386
41.9k
      out = default_value;
387
41.9k
      push_back(std::move(obj));
388
41.9k
      }
389
390
43.8k
   return (*this);
391
43.8k
   }
Botan::BER_Decoder& Botan::BER_Decoder::decode_optional<unsigned long>(unsigned long&, Botan::ASN1_Type, Botan::ASN1_Class, unsigned long const&)
Line
Count
Source
369
20.3k
   {
370
20.3k
   BER_Object obj = get_next_object();
371
372
20.3k
   if(obj.is_a(type_tag, class_tag))
373
4.71k
      {
374
4.71k
      if(class_tag == ASN1_Class::ExplicitContextSpecific)
375
3.32k
         {
376
3.32k
         BER_Decoder(std::move(obj)).decode(out).verify_end();
377
3.32k
         }
378
1.39k
      else
379
1.39k
         {
380
1.39k
         push_back(std::move(obj));
381
1.39k
         decode(out, type_tag, class_tag);
382
1.39k
         }
383
4.71k
      }
384
15.6k
   else
385
15.6k
      {
386
15.6k
      out = default_value;
387
15.6k
      push_back(std::move(obj));
388
15.6k
      }
389
390
20.3k
   return (*this);
391
20.3k
   }
Botan::BER_Decoder& Botan::BER_Decoder::decode_optional<Botan::AlgorithmIdentifier>(Botan::AlgorithmIdentifier&, Botan::ASN1_Type, Botan::ASN1_Class, Botan::AlgorithmIdentifier const&)
Line
Count
Source
369
147
   {
370
147
   BER_Object obj = get_next_object();
371
372
147
   if(obj.is_a(type_tag, class_tag))
373
145
      {
374
145
      if(class_tag == ASN1_Class::ExplicitContextSpecific)
375
145
         {
376
145
         BER_Decoder(std::move(obj)).decode(out).verify_end();
377
145
         }
378
0
      else
379
0
         {
380
0
         push_back(std::move(obj));
381
0
         decode(out, type_tag, class_tag);
382
0
         }
383
145
      }
384
2
   else
385
2
      {
386
2
      out = default_value;
387
2
      push_back(std::move(obj));
388
2
      }
389
390
147
   return (*this);
391
147
   }
Botan::BER_Decoder& Botan::BER_Decoder::decode_optional<Botan::OID>(Botan::OID&, Botan::ASN1_Type, Botan::ASN1_Class, Botan::OID const&)
Line
Count
Source
369
1.13k
   {
370
1.13k
   BER_Object obj = get_next_object();
371
372
1.13k
   if(obj.is_a(type_tag, class_tag))
373
34
      {
374
34
      if(class_tag == ASN1_Class::ExplicitContextSpecific)
375
34
         {
376
34
         BER_Decoder(std::move(obj)).decode(out).verify_end();
377
34
         }
378
0
      else
379
0
         {
380
0
         push_back(std::move(obj));
381
0
         decode(out, type_tag, class_tag);
382
0
         }
383
34
      }
384
1.10k
   else
385
1.10k
      {
386
1.10k
      out = default_value;
387
1.10k
      push_back(std::move(obj));
388
1.10k
      }
389
390
1.13k
   return (*this);
391
1.13k
   }
Botan::BER_Decoder& Botan::BER_Decoder::decode_optional<Botan::X509_DN>(Botan::X509_DN&, Botan::ASN1_Type, Botan::ASN1_Class, Botan::X509_DN const&)
Line
Count
Source
369
1.84k
   {
370
1.84k
   BER_Object obj = get_next_object();
371
372
1.84k
   if(obj.is_a(type_tag, class_tag))
373
301
      {
374
301
      if(class_tag == ASN1_Class::ExplicitContextSpecific)
375
301
         {
376
301
         BER_Decoder(std::move(obj)).decode(out).verify_end();
377
301
         }
378
0
      else
379
0
         {
380
0
         push_back(std::move(obj));
381
0
         decode(out, type_tag, class_tag);
382
0
         }
383
301
      }
384
1.54k
   else
385
1.54k
      {
386
1.54k
      out = default_value;
387
1.54k
      push_back(std::move(obj));
388
1.54k
      }
389
390
1.84k
   return (*this);
391
1.84k
   }
392
393
/*
394
* Decode an OPTIONAL or DEFAULT element
395
*/
396
template<typename T>
397
BER_Decoder& BER_Decoder::decode_optional_implicit(
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
3.31k
   {
405
3.31k
   BER_Object obj = get_next_object();
406
407
3.31k
   if(obj.is_a(type_tag, class_tag))
408
850
      {
409
850
      obj.set_tagging(real_type, real_class);
410
850
      push_back(std::move(obj));
411
850
      decode(out, real_type, real_class);
412
850
      }
413
2.46k
   else
414
2.46k
      {
415
      // Not what we wanted, push it back on the stream
416
2.46k
      out = default_value;
417
2.46k
      push_back(std::move(obj));
418
2.46k
      }
419
420
3.31k
   return (*this);
421
3.31k
   }
422
/*
423
* Decode a list of homogenously typed values
424
*/
425
template<typename T>
426
BER_Decoder& BER_Decoder::decode_list(std::vector<T>& vec,
427
                                      ASN1_Type type_tag,
428
                                      ASN1_Class class_tag)
429
9.80k
   {
430
9.80k
   BER_Decoder list = start_cons(type_tag, class_tag);
431
432
22.5k
   while(list.more_items())
433
12.6k
      {
434
12.6k
      T value;
435
12.6k
      list.decode(value);
436
12.6k
      vec.push_back(std::move(value));
437
12.6k
      }
438
439
9.80k
   list.end_cons();
440
441
9.80k
   return (*this);
442
9.80k
   }
Botan::BER_Decoder& Botan::BER_Decoder::decode_list<Botan::OID>(std::__1::vector<Botan::OID, std::__1::allocator<Botan::OID> >&, Botan::ASN1_Type, Botan::ASN1_Class)
Line
Count
Source
429
1.36k
   {
430
1.36k
   BER_Decoder list = start_cons(type_tag, class_tag);
431
432
2.98k
   while(list.more_items())
433
1.62k
      {
434
1.62k
      T value;
435
1.62k
      list.decode(value);
436
1.62k
      vec.push_back(std::move(value));
437
1.62k
      }
438
439
1.36k
   list.end_cons();
440
441
1.36k
   return (*this);
442
1.36k
   }
Botan::BER_Decoder& Botan::BER_Decoder::decode_list<Botan::GeneralSubtree>(std::__1::vector<Botan::GeneralSubtree, std::__1::allocator<Botan::GeneralSubtree> >&, Botan::ASN1_Type, Botan::ASN1_Class)
Line
Count
Source
429
2.89k
   {
430
2.89k
   BER_Decoder list = start_cons(type_tag, class_tag);
431
432
8.87k
   while(list.more_items())
433
5.98k
      {
434
5.98k
      T value;
435
5.98k
      list.decode(value);
436
5.98k
      vec.push_back(std::move(value));
437
5.98k
      }
438
439
2.89k
   list.end_cons();
440
441
2.89k
   return (*this);
442
2.89k
   }
x509_ext.cpp:Botan::BER_Decoder& Botan::BER_Decoder::decode_list<Botan::Cert_Extension::(anonymous namespace)::Policy_Information>(std::__1::vector<Botan::Cert_Extension::(anonymous namespace)::Policy_Information, std::__1::allocator<Botan::Cert_Extension::(anonymous namespace)::Policy_Information> >&, Botan::ASN1_Type, Botan::ASN1_Class)
Line
Count
Source
429
2.23k
   {
430
2.23k
   BER_Decoder list = start_cons(type_tag, class_tag);
431
432
3.36k
   while(list.more_items())
433
1.13k
      {
434
1.13k
      T value;
435
1.13k
      list.decode(value);
436
1.13k
      vec.push_back(std::move(value));
437
1.13k
      }
438
439
2.23k
   list.end_cons();
440
441
2.23k
   return (*this);
442
2.23k
   }
Botan::BER_Decoder& Botan::BER_Decoder::decode_list<Botan::Cert_Extension::CRL_Distribution_Points::Distribution_Point>(std::__1::vector<Botan::Cert_Extension::CRL_Distribution_Points::Distribution_Point, std::__1::allocator<Botan::Cert_Extension::CRL_Distribution_Points::Distribution_Point> >&, Botan::ASN1_Type, Botan::ASN1_Class)
Line
Count
Source
429
2.40k
   {
430
2.40k
   BER_Decoder list = start_cons(type_tag, class_tag);
431
432
6.33k
   while(list.more_items())
433
3.93k
      {
434
3.93k
      T value;
435
3.93k
      list.decode(value);
436
3.93k
      vec.push_back(std::move(value));
437
3.93k
      }
438
439
2.40k
   list.end_cons();
440
441
2.40k
   return (*this);
442
2.40k
   }
Botan::BER_Decoder& Botan::BER_Decoder::decode_list<Botan::OCSP::SingleResponse>(std::__1::vector<Botan::OCSP::SingleResponse, std::__1::allocator<Botan::OCSP::SingleResponse> >&, Botan::ASN1_Type, Botan::ASN1_Class)
Line
Count
Source
429
910
   {
430
910
   BER_Decoder list = start_cons(type_tag, class_tag);
431
432
937
   while(list.more_items())
433
27
      {
434
27
      T value;
435
27
      list.decode(value);
436
27
      vec.push_back(std::move(value));
437
27
      }
438
439
910
   list.end_cons();
440
441
910
   return (*this);
442
910
   }
443
444
}
445
446
#endif