Coverage Report

Created: 2020-02-14 15:38

/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.5k
         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
10.8k
         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
26.5k
         {
68
26.5k
         ber = get_next_object();
69
26.5k
         return (*this);
70
26.5k
         }
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
      /**
110
      * Start decoding a constructed data (sequence or set)
111
      */
112
      BER_Decoder start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag = UNIVERSAL);
113
114
      /**
115
      * Finish decoding a constructed data, throws if any data remains.
116
      * Returns the parent of *this (ie the object on which start_cons was called).
117
      */
118
      BER_Decoder& end_cons();
119
120
      /**
121
      * Get next object and copy value to POD type
122
      * Asserts value length is equal to POD type sizeof.
123
      * Asserts Type tag and optional Class tag according to parameters.
124
      * Copy value to POD type (struct, union, C-style array, std::array, etc.).
125
      * @param out POD type reference where to copy object value
126
      * @param type_tag ASN1_Tag enum to assert type on object read
127
      * @param class_tag ASN1_Tag enum to assert class on object read (default: CONTEXT_SPECIFIC)
128
      * @return this reference
129
      */
130
      template <typename T>
131
         BER_Decoder& get_next_value(T &out,
132
                                     ASN1_Tag type_tag,
133
                                     ASN1_Tag class_tag = CONTEXT_SPECIFIC)
134
         {
135
         static_assert(std::is_pod<T>::value, "Type must be POD");
136
137
         BER_Object obj = get_next_object();
138
         obj.assert_is_a(type_tag, class_tag);
139
140
         if (obj.length() != sizeof(T))
141
            throw BER_Decoding_Error(
142
                    "Size mismatch. Object value size is " +
143
                    std::to_string(obj.length()) +
144
                    "; Output type size is " +
145
                    std::to_string(sizeof(T)));
146
147
         copy_mem(reinterpret_cast<uint8_t*>(&out), obj.bits(), obj.length());
148
149
         return (*this);
150
         }
151
152
      /*
153
      * Save all the bytes remaining in the source
154
      */
155
      template<typename Alloc>
156
      BER_Decoder& raw_bytes(std::vector<uint8_t, Alloc>& out)
157
130k
         {
158
130k
         out.clear();
159
130k
         uint8_t buf;
160
12.1M
         while(m_source->read_byte(buf))
161
12.0M
            out.push_back(buf);
162
130k
         return (*this);
163
130k
         }
164
165
      BER_Decoder& decode_null();
166
167
      /**
168
      * Decode a BER encoded BOOLEAN
169
      */
170
      BER_Decoder& decode(bool& out)
171
630
         {
172
630
         return decode(out, BOOLEAN, UNIVERSAL);
173
630
         }
174
175
      /*
176
      * Decode a small BER encoded INTEGER
177
      */
178
      BER_Decoder& decode(size_t& out)
179
12.1k
         {
180
12.1k
         return decode(out, INTEGER, UNIVERSAL);
181
12.1k
         }
182
183
      /*
184
      * Decode a BER encoded INTEGER
185
      */
186
      BER_Decoder& decode(BigInt& out)
187
48.1k
         {
188
48.1k
         return decode(out, INTEGER, UNIVERSAL);
189
48.1k
         }
190
191
      std::vector<uint8_t> get_next_octet_string()
192
2.48k
         {
193
2.48k
         std::vector<uint8_t> out_vec;
194
2.48k
         decode(out_vec, OCTET_STRING);
195
2.48k
         return out_vec;
196
2.48k
         }
197
198
      /*
199
      * BER decode a BIT STRING or OCTET STRING
200
      */
201
      template<typename Alloc>
202
      BER_Decoder& decode(std::vector<uint8_t, Alloc>& out, ASN1_Tag real_type)
203
108k
         {
204
108k
         return decode(out, real_type, real_type, UNIVERSAL);
205
108k
         }
Botan::BER_Decoder& Botan::BER_Decoder::decode<Botan::secure_allocator<unsigned char> >(std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >&, Botan::ASN1_Tag)
Line
Count
Source
203
4.59k
         {
204
4.59k
         return decode(out, real_type, real_type, UNIVERSAL);
205
4.59k
         }
Botan::BER_Decoder& Botan::BER_Decoder::decode<std::__1::allocator<unsigned char> >(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&, Botan::ASN1_Tag)
Line
Count
Source
203
104k
         {
204
104k
         return decode(out, real_type, real_type, UNIVERSAL);
205
104k
         }
206
207
      BER_Decoder& decode(bool& v,
208
                          ASN1_Tag type_tag,
209
                          ASN1_Tag class_tag = CONTEXT_SPECIFIC);
210
211
      BER_Decoder& decode(size_t& v,
212
                          ASN1_Tag type_tag,
213
                          ASN1_Tag class_tag = CONTEXT_SPECIFIC);
214
215
      BER_Decoder& decode(BigInt& v,
216
                          ASN1_Tag type_tag,
217
                          ASN1_Tag class_tag = CONTEXT_SPECIFIC);
218
219
      BER_Decoder& decode(std::vector<uint8_t>& v,
220
                          ASN1_Tag real_type,
221
                          ASN1_Tag type_tag,
222
                          ASN1_Tag class_tag = CONTEXT_SPECIFIC);
223
224
      BER_Decoder& decode(secure_vector<uint8_t>& v,
225
                          ASN1_Tag real_type,
226
                          ASN1_Tag type_tag,
227
                          ASN1_Tag class_tag = CONTEXT_SPECIFIC);
228
229
      BER_Decoder& decode(class ASN1_Object& obj,
230
                          ASN1_Tag type_tag = NO_OBJECT,
231
                          ASN1_Tag class_tag = NO_OBJECT);
232
233
      /**
234
      * Decode an integer value which is typed as an octet string
235
      */
236
      BER_Decoder& decode_octet_string_bigint(BigInt& b);
237
238
      uint64_t decode_constrained_integer(ASN1_Tag type_tag,
239
                                          ASN1_Tag class_tag,
240
                                          size_t T_bytes);
241
242
      template<typename T> BER_Decoder& decode_integer_type(T& out)
243
0
         {
244
0
         return decode_integer_type<T>(out, INTEGER, UNIVERSAL);
245
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&)
246
247
      template<typename T>
248
         BER_Decoder& decode_integer_type(T& out,
249
                                          ASN1_Tag type_tag,
250
                                          ASN1_Tag class_tag = CONTEXT_SPECIFIC)
251
0
         {
252
0
         out = static_cast<T>(decode_constrained_integer(type_tag, class_tag, sizeof(out)));
253
0
         return (*this);
254
0
         }
Unexecuted instantiation: Botan::BER_Decoder& Botan::BER_Decoder::decode_integer_type<unsigned long>(unsigned long&, Botan::ASN1_Tag, Botan::ASN1_Tag)
Unexecuted instantiation: Botan::BER_Decoder& Botan::BER_Decoder::decode_integer_type<unsigned char>(unsigned char&, Botan::ASN1_Tag, Botan::ASN1_Tag)
Unexecuted instantiation: Botan::BER_Decoder& Botan::BER_Decoder::decode_integer_type<unsigned short>(unsigned short&, Botan::ASN1_Tag, Botan::ASN1_Tag)
255
256
      template<typename T>
257
         BER_Decoder& decode_optional(T& out,
258
                                      ASN1_Tag type_tag,
259
                                      ASN1_Tag class_tag,
260
                                      const T& default_value = T());
261
262
      template<typename T>
263
         BER_Decoder& decode_optional_implicit(
264
            T& out,
265
            ASN1_Tag type_tag,
266
            ASN1_Tag class_tag,
267
            ASN1_Tag real_type,
268
            ASN1_Tag real_class,
269
            const T& default_value = T());
270
271
      template<typename T>
272
         BER_Decoder& decode_list(std::vector<T>& out,
273
                                  ASN1_Tag type_tag = SEQUENCE,
274
                                  ASN1_Tag class_tag = UNIVERSAL);
275
276
      template<typename T>
277
         BER_Decoder& decode_and_check(const T& expected,
278
                                       const std::string& error_msg)
279
7.40k
         {
280
7.40k
         T actual;
281
7.40k
         decode(actual);
282
7.40k
283
7.40k
         if(actual != expected)
284
315
            throw Decoding_Error(error_msg);
285
7.08k
286
7.08k
         return (*this);
287
7.08k
         }
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
279
4.28k
         {
280
4.28k
         T actual;
281
4.28k
         decode(actual);
282
4.28k
283
4.28k
         if(actual != expected)
284
142
            throw Decoding_Error(error_msg);
285
4.14k
286
4.14k
         return (*this);
287
4.14k
         }
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
279
3.11k
         {
280
3.11k
         T actual;
281
3.11k
         decode(actual);
282
3.11k
283
3.11k
         if(actual != expected)
284
173
            throw Decoding_Error(error_msg);
285
2.94k
286
2.94k
         return (*this);
287
2.94k
         }
288
289
      /*
290
      * Decode an OPTIONAL string type
291
      */
292
      template<typename Alloc>
293
      BER_Decoder& decode_optional_string(std::vector<uint8_t, Alloc>& out,
294
                                          ASN1_Tag real_type,
295
                                          uint16_t type_no,
296
                                          ASN1_Tag class_tag = CONTEXT_SPECIFIC)
297
30.3k
         {
298
30.3k
         BER_Object obj = get_next_object();
299
30.3k
300
30.3k
         ASN1_Tag type_tag = static_cast<ASN1_Tag>(type_no);
301
30.3k
302
30.3k
         if(obj.is_a(type_tag, class_tag))
303
1.83k
            {
304
1.83k
            if((class_tag & CONSTRUCTED) && (class_tag & CONTEXT_SPECIFIC))
305
1.08k
               {
306
1.08k
               BER_Decoder(std::move(obj)).decode(out, real_type).verify_end();
307
1.08k
               }
308
746
            else
309
746
               {
310
746
               push_back(std::move(obj));
311
746
               decode(out, real_type, type_tag, class_tag);
312
746
               }
313
1.83k
            }
314
28.4k
         else
315
28.4k
            {
316
28.4k
            out.clear();
317
28.4k
            push_back(std::move(obj));
318
28.4k
            }
319
30.3k
320
30.3k
         return (*this);
321
30.3k
         }
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_Tag, unsigned short, Botan::ASN1_Tag)
Line
Count
Source
297
29.2k
         {
298
29.2k
         BER_Object obj = get_next_object();
299
29.2k
300
29.2k
         ASN1_Tag type_tag = static_cast<ASN1_Tag>(type_no);
301
29.2k
302
29.2k
         if(obj.is_a(type_tag, class_tag))
303
1.12k
            {
304
1.12k
            if((class_tag & CONSTRUCTED) && (class_tag & CONTEXT_SPECIFIC))
305
377
               {
306
377
               BER_Decoder(std::move(obj)).decode(out, real_type).verify_end();
307
377
               }
308
746
            else
309
746
               {
310
746
               push_back(std::move(obj));
311
746
               decode(out, real_type, type_tag, class_tag);
312
746
               }
313
1.12k
            }
314
28.1k
         else
315
28.1k
            {
316
28.1k
            out.clear();
317
28.1k
            push_back(std::move(obj));
318
28.1k
            }
319
29.2k
320
29.2k
         return (*this);
321
29.2k
         }
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_Tag, unsigned short, Botan::ASN1_Tag)
Line
Count
Source
297
1.08k
         {
298
1.08k
         BER_Object obj = get_next_object();
299
1.08k
300
1.08k
         ASN1_Tag type_tag = static_cast<ASN1_Tag>(type_no);
301
1.08k
302
1.08k
         if(obj.is_a(type_tag, class_tag))
303
707
            {
304
707
            if((class_tag & CONSTRUCTED) && (class_tag & CONTEXT_SPECIFIC))
305
707
               {
306
707
               BER_Decoder(std::move(obj)).decode(out, real_type).verify_end();
307
707
               }
308
0
            else
309
0
               {
310
0
               push_back(std::move(obj));
311
0
               decode(out, real_type, type_tag, class_tag);
312
0
               }
313
707
            }
314
376
         else
315
376
            {
316
376
            out.clear();
317
376
            push_back(std::move(obj));
318
376
            }
319
1.08k
320
1.08k
         return (*this);
321
1.08k
         }
322
323
   private:
324
      BER_Decoder(BER_Object&& obj, BER_Decoder* parent);
325
326
      BER_Decoder* m_parent = nullptr;
327
      BER_Object m_pushed;
328
      // either m_data_src.get() or an unowned pointer
329
      DataSource* m_source;
330
      mutable std::unique_ptr<DataSource> m_data_src;
331
   };
332
333
/*
334
* Decode an OPTIONAL or DEFAULT element
335
*/
336
template<typename T>
337
BER_Decoder& BER_Decoder::decode_optional(T& out,
338
                                          ASN1_Tag type_tag,
339
                                          ASN1_Tag class_tag,
340
                                          const T& default_value)
341
67.6k
   {
342
67.6k
   BER_Object obj = get_next_object();
343
67.6k
344
67.6k
   if(obj.is_a(type_tag, class_tag))
345
13.6k
      {
346
13.6k
      if((class_tag & CONSTRUCTED) && (class_tag & CONTEXT_SPECIFIC))
347
8.18k
         {
348
8.18k
         BER_Decoder(std::move(obj)).decode(out).verify_end();
349
8.18k
         }
350
5.43k
      else
351
5.43k
         {
352
5.43k
         push_back(std::move(obj));
353
5.43k
         decode(out, type_tag, class_tag);
354
5.43k
         }
355
13.6k
      }
356
54.0k
   else
357
54.0k
      {
358
54.0k
      out = default_value;
359
54.0k
      push_back(std::move(obj));
360
54.0k
      }
361
67.6k
362
67.6k
   return (*this);
363
67.6k
   }
Botan::BER_Decoder& Botan::BER_Decoder::decode_optional<unsigned long>(unsigned long&, Botan::ASN1_Tag, Botan::ASN1_Tag, unsigned long const&)
Line
Count
Source
341
23.4k
   {
342
23.4k
   BER_Object obj = get_next_object();
343
23.4k
344
23.4k
   if(obj.is_a(type_tag, class_tag))
345
8.46k
      {
346
8.46k
      if((class_tag & CONSTRUCTED) && (class_tag & CONTEXT_SPECIFIC))
347
7.20k
         {
348
7.20k
         BER_Decoder(std::move(obj)).decode(out).verify_end();
349
7.20k
         }
350
1.26k
      else
351
1.26k
         {
352
1.26k
         push_back(std::move(obj));
353
1.26k
         decode(out, type_tag, class_tag);
354
1.26k
         }
355
8.46k
      }
356
15.0k
   else
357
15.0k
      {
358
15.0k
      out = default_value;
359
15.0k
      push_back(std::move(obj));
360
15.0k
      }
361
23.4k
362
23.4k
   return (*this);
363
23.4k
   }
Botan::BER_Decoder& Botan::BER_Decoder::decode_optional<Botan::X509_DN>(Botan::X509_DN&, Botan::ASN1_Tag, Botan::ASN1_Tag, Botan::X509_DN const&)
Line
Count
Source
341
1.36k
   {
342
1.36k
   BER_Object obj = get_next_object();
343
1.36k
344
1.36k
   if(obj.is_a(type_tag, class_tag))
345
39
      {
346
39
      if((class_tag & CONSTRUCTED) && (class_tag & CONTEXT_SPECIFIC))
347
39
         {
348
39
         BER_Decoder(std::move(obj)).decode(out).verify_end();
349
39
         }
350
0
      else
351
0
         {
352
0
         push_back(std::move(obj));
353
0
         decode(out, type_tag, class_tag);
354
0
         }
355
39
      }
356
1.32k
   else
357
1.32k
      {
358
1.32k
      out = default_value;
359
1.32k
      push_back(std::move(obj));
360
1.32k
      }
361
1.36k
362
1.36k
   return (*this);
363
1.36k
   }
Botan::BER_Decoder& Botan::BER_Decoder::decode_optional<Botan::Extensions>(Botan::Extensions&, Botan::ASN1_Tag, Botan::ASN1_Tag, Botan::Extensions const&)
Line
Count
Source
341
768
   {
342
768
   BER_Object obj = get_next_object();
343
768
344
768
   if(obj.is_a(type_tag, class_tag))
345
741
      {
346
741
      if((class_tag & CONSTRUCTED) && (class_tag & CONTEXT_SPECIFIC))
347
741
         {
348
741
         BER_Decoder(std::move(obj)).decode(out).verify_end();
349
741
         }
350
0
      else
351
0
         {
352
0
         push_back(std::move(obj));
353
0
         decode(out, type_tag, class_tag);
354
0
         }
355
741
      }
356
27
   else
357
27
      {
358
27
      out = default_value;
359
27
      push_back(std::move(obj));
360
27
      }
361
768
362
768
   return (*this);
363
768
   }
Botan::BER_Decoder& Botan::BER_Decoder::decode_optional<Botan::X509_Time>(Botan::X509_Time&, Botan::ASN1_Tag, Botan::ASN1_Tag, Botan::X509_Time const&)
Line
Count
Source
341
38
   {
342
38
   BER_Object obj = get_next_object();
343
38
344
38
   if(obj.is_a(type_tag, class_tag))
345
21
      {
346
21
      if((class_tag & CONSTRUCTED) && (class_tag & CONTEXT_SPECIFIC))
347
21
         {
348
21
         BER_Decoder(std::move(obj)).decode(out).verify_end();
349
21
         }
350
0
      else
351
0
         {
352
0
         push_back(std::move(obj));
353
0
         decode(out, type_tag, class_tag);
354
0
         }
355
21
      }
356
17
   else
357
17
      {
358
17
      out = default_value;
359
17
      push_back(std::move(obj));
360
17
      }
361
38
362
38
   return (*this);
363
38
   }
Botan::BER_Decoder& Botan::BER_Decoder::decode_optional<bool>(bool&, Botan::ASN1_Tag, Botan::ASN1_Tag, bool const&)
Line
Count
Source
341
40.7k
   {
342
40.7k
   BER_Object obj = get_next_object();
343
40.7k
344
40.7k
   if(obj.is_a(type_tag, class_tag))
345
4.17k
      {
346
4.17k
      if((class_tag & CONSTRUCTED) && (class_tag & CONTEXT_SPECIFIC))
347
0
         {
348
0
         BER_Decoder(std::move(obj)).decode(out).verify_end();
349
0
         }
350
4.17k
      else
351
4.17k
         {
352
4.17k
         push_back(std::move(obj));
353
4.17k
         decode(out, type_tag, class_tag);
354
4.17k
         }
355
4.17k
      }
356
36.5k
   else
357
36.5k
      {
358
36.5k
      out = default_value;
359
36.5k
      push_back(std::move(obj));
360
36.5k
      }
361
40.7k
362
40.7k
   return (*this);
363
40.7k
   }
Botan::BER_Decoder& Botan::BER_Decoder::decode_optional<Botan::AlgorithmIdentifier>(Botan::AlgorithmIdentifier&, Botan::ASN1_Tag, Botan::ASN1_Tag, Botan::AlgorithmIdentifier const&)
Line
Count
Source
341
137
   {
342
137
   BER_Object obj = get_next_object();
343
137
344
137
   if(obj.is_a(type_tag, class_tag))
345
137
      {
346
137
      if((class_tag & CONSTRUCTED) && (class_tag & CONTEXT_SPECIFIC))
347
137
         {
348
137
         BER_Decoder(std::move(obj)).decode(out).verify_end();
349
137
         }
350
0
      else
351
0
         {
352
0
         push_back(std::move(obj));
353
0
         decode(out, type_tag, class_tag);
354
0
         }
355
137
      }
356
0
   else
357
0
      {
358
0
      out = default_value;
359
0
      push_back(std::move(obj));
360
0
      }
361
137
362
137
   return (*this);
363
137
   }
Botan::BER_Decoder& Botan::BER_Decoder::decode_optional<Botan::OID>(Botan::OID&, Botan::ASN1_Tag, Botan::ASN1_Tag, Botan::OID const&)
Line
Count
Source
341
1.08k
   {
342
1.08k
   BER_Object obj = get_next_object();
343
1.08k
344
1.08k
   if(obj.is_a(type_tag, class_tag))
345
36
      {
346
36
      if((class_tag & CONSTRUCTED) && (class_tag & CONTEXT_SPECIFIC))
347
36
         {
348
36
         BER_Decoder(std::move(obj)).decode(out).verify_end();
349
36
         }
350
0
      else
351
0
         {
352
0
         push_back(std::move(obj));
353
0
         decode(out, type_tag, class_tag);
354
0
         }
355
36
      }
356
1.05k
   else
357
1.05k
      {
358
1.05k
      out = default_value;
359
1.05k
      push_back(std::move(obj));
360
1.05k
      }
361
1.08k
362
1.08k
   return (*this);
363
1.08k
   }
364
365
/*
366
* Decode an OPTIONAL or DEFAULT element
367
*/
368
template<typename T>
369
BER_Decoder& BER_Decoder::decode_optional_implicit(
370
   T& out,
371
   ASN1_Tag type_tag,
372
   ASN1_Tag class_tag,
373
   ASN1_Tag real_type,
374
   ASN1_Tag real_class,
375
   const T& default_value)
376
1.16k
   {
377
1.16k
   BER_Object obj = get_next_object();
378
1.16k
379
1.16k
   if(obj.is_a(type_tag, class_tag))
380
739
      {
381
739
      obj.set_tagging(real_type, real_class);
382
739
      push_back(std::move(obj));
383
739
      decode(out, real_type, real_class);
384
739
      }
385
428
   else
386
428
      {
387
428
      // Not what we wanted, push it back on the stream
388
428
      out = default_value;
389
428
      push_back(std::move(obj));
390
428
      }
391
1.16k
392
1.16k
   return (*this);
393
1.16k
   }
394
/*
395
* Decode a list of homogenously typed values
396
*/
397
template<typename T>
398
BER_Decoder& BER_Decoder::decode_list(std::vector<T>& vec,
399
                                      ASN1_Tag type_tag,
400
                                      ASN1_Tag class_tag)
401
7.53k
   {
402
7.53k
   BER_Decoder list = start_cons(type_tag, class_tag);
403
7.53k
404
17.5k
   while(list.more_items())
405
10.0k
      {
406
10.0k
      T value;
407
10.0k
      list.decode(value);
408
10.0k
      vec.push_back(std::move(value));
409
10.0k
      }
410
7.53k
411
7.53k
   list.end_cons();
412
7.53k
413
7.53k
   return (*this);
414
7.53k
   }
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_Tag, Botan::ASN1_Tag)
Line
Count
Source
401
814
   {
402
814
   BER_Decoder list = start_cons(type_tag, class_tag);
403
814
404
875
   while(list.more_items())
405
61
      {
406
61
      T value;
407
61
      list.decode(value);
408
61
      vec.push_back(std::move(value));
409
61
      }
410
814
411
814
   list.end_cons();
412
814
413
814
   return (*this);
414
814
   }
Botan::BER_Decoder& Botan::BER_Decoder::decode_list<Botan::OID>(std::__1::vector<Botan::OID, std::__1::allocator<Botan::OID> >&, Botan::ASN1_Tag, Botan::ASN1_Tag)
Line
Count
Source
401
1.17k
   {
402
1.17k
   BER_Decoder list = start_cons(type_tag, class_tag);
403
1.17k
404
2.73k
   while(list.more_items())
405
1.56k
      {
406
1.56k
      T value;
407
1.56k
      list.decode(value);
408
1.56k
      vec.push_back(std::move(value));
409
1.56k
      }
410
1.17k
411
1.17k
   list.end_cons();
412
1.17k
413
1.17k
   return (*this);
414
1.17k
   }
Botan::BER_Decoder& Botan::BER_Decoder::decode_list<Botan::GeneralSubtree>(std::__1::vector<Botan::GeneralSubtree, std::__1::allocator<Botan::GeneralSubtree> >&, Botan::ASN1_Tag, Botan::ASN1_Tag)
Line
Count
Source
401
2.79k
   {
402
2.79k
   BER_Decoder list = start_cons(type_tag, class_tag);
403
2.79k
404
8.48k
   while(list.more_items())
405
5.69k
      {
406
5.69k
      T value;
407
5.69k
      list.decode(value);
408
5.69k
      vec.push_back(std::move(value));
409
5.69k
      }
410
2.79k
411
2.79k
   list.end_cons();
412
2.79k
413
2.79k
   return (*this);
414
2.79k
   }
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_Tag, Botan::ASN1_Tag)
Line
Count
Source
401
1.09k
   {
402
1.09k
   BER_Decoder list = start_cons(type_tag, class_tag);
403
1.09k
404
2.49k
   while(list.more_items())
405
1.40k
      {
406
1.40k
      T value;
407
1.40k
      list.decode(value);
408
1.40k
      vec.push_back(std::move(value));
409
1.40k
      }
410
1.09k
411
1.09k
   list.end_cons();
412
1.09k
413
1.09k
   return (*this);
414
1.09k
   }
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_Tag, Botan::ASN1_Tag)
Line
Count
Source
401
1.65k
   {
402
1.65k
   BER_Decoder list = start_cons(type_tag, class_tag);
403
1.65k
404
2.98k
   while(list.more_items())
405
1.32k
      {
406
1.32k
      T value;
407
1.32k
      list.decode(value);
408
1.32k
      vec.push_back(std::move(value));
409
1.32k
      }
410
1.65k
411
1.65k
   list.end_cons();
412
1.65k
413
1.65k
   return (*this);
414
1.65k
   }
415
416
}
417
418
#endif