~ubuntu-branches/debian/sid/botan/sid

« back to all changes in this revision

Viewing changes to src/lib/asn1/ber_dec.h

  • Committer: Package Import Robot
  • Author(s): Laszlo Boszormenyi (GCS)
  • Date: 2018-03-01 22:23:25 UTC
  • mfrom: (1.2.2)
  • Revision ID: package-import@ubuntu.com-20180301222325-7p7vc45gu3hta34d
Tags: 2.4.0-2
* Don't remove .doctrees from the manual if it doesn't exist.
* Don't specify parallel to debhelper.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
* BER Decoder
 
3
* (C) 1999-2010 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
/**
 
17
* BER Decoding Object
 
18
*/
 
19
class BOTAN_PUBLIC_API(2,0) BER_Decoder final
 
20
   {
 
21
   public:
 
22
      BER_Object get_next_object();
 
23
 
 
24
      std::vector<uint8_t> get_next_octet_string();
 
25
 
 
26
      void push_back(const BER_Object& obj);
 
27
 
 
28
      bool more_items() const;
 
29
      BER_Decoder& verify_end();
 
30
      BER_Decoder& discard_remaining();
 
31
 
 
32
      BER_Decoder  start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag = UNIVERSAL);
 
33
      BER_Decoder& end_cons();
 
34
 
 
35
      BER_Decoder& get_next(BER_Object& ber);
 
36
 
 
37
      /**
 
38
      * Get next object and copy value to POD type
 
39
      * Asserts value length is equal to POD type sizeof.
 
40
      * Asserts Type tag and optional Class tag according to parameters.
 
41
      * Copy value to POD type (struct, union, C-style array, std::array, etc.).
 
42
      * @param out POD type reference where to copy object value
 
43
      * @param type_tag ASN1_Tag enum to assert type on object read
 
44
      * @param class_tag ASN1_Tag enum to assert class on object read (default: CONTEXT_SPECIFIC)
 
45
      * @return this reference  
 
46
      */
 
47
      template <typename T>
 
48
         BER_Decoder& get_next_value(T &out,
 
49
                                     ASN1_Tag type_tag,
 
50
                                     ASN1_Tag class_tag = CONTEXT_SPECIFIC)
 
51
         {
 
52
         static_assert(std::is_pod<T>::value, "Type must be POD");
 
53
 
 
54
         BER_Object obj = get_next_object();
 
55
         obj.assert_is_a(type_tag, class_tag);
 
56
 
 
57
         if (obj.value.size() != sizeof(T))
 
58
            throw BER_Decoding_Error(
 
59
                    "Size mismatch. Object value size is " +
 
60
                    std::to_string(obj.value.size()) +
 
61
                    "; Output type size is " +
 
62
                    std::to_string(sizeof(T)));
 
63
 
 
64
         copy_mem(reinterpret_cast<uint8_t*>(&out), obj.value.data(), obj.value.size());
 
65
 
 
66
         return (*this);
 
67
         }
 
68
 
 
69
      /*
 
70
      * Save all the bytes remaining in the source
 
71
      */
 
72
      template<typename Alloc>
 
73
      BER_Decoder& raw_bytes(std::vector<uint8_t, Alloc>& out)
 
74
         {
 
75
         out.clear();
 
76
         uint8_t buf;
 
77
         while(m_source->read_byte(buf))
 
78
            out.push_back(buf);
 
79
         return (*this);
 
80
         }
 
81
 
 
82
      BER_Decoder& decode_null();
 
83
      BER_Decoder& decode(bool& v);
 
84
      BER_Decoder& decode(size_t& v);
 
85
      BER_Decoder& decode(class BigInt& v);
 
86
 
 
87
      /*
 
88
      * BER decode a BIT STRING or OCTET STRING
 
89
      */
 
90
      template<typename Alloc>
 
91
      BER_Decoder& decode(std::vector<uint8_t, Alloc>& out, ASN1_Tag real_type)
 
92
         {
 
93
         return decode(out, real_type, real_type, UNIVERSAL);
 
94
         }
 
95
 
 
96
      BER_Decoder& decode(bool& v,
 
97
                          ASN1_Tag type_tag,
 
98
                          ASN1_Tag class_tag = CONTEXT_SPECIFIC);
 
99
 
 
100
      BER_Decoder& decode(size_t& v,
 
101
                          ASN1_Tag type_tag,
 
102
                          ASN1_Tag class_tag = CONTEXT_SPECIFIC);
 
103
 
 
104
      BER_Decoder& decode(class BigInt& v,
 
105
                          ASN1_Tag type_tag,
 
106
                          ASN1_Tag class_tag = CONTEXT_SPECIFIC);
 
107
 
 
108
      BER_Decoder& decode(std::vector<uint8_t>& v,
 
109
                          ASN1_Tag real_type,
 
110
                          ASN1_Tag type_tag,
 
111
                          ASN1_Tag class_tag = CONTEXT_SPECIFIC);
 
112
 
 
113
      BER_Decoder& decode(secure_vector<uint8_t>& v,
 
114
                          ASN1_Tag real_type,
 
115
                          ASN1_Tag type_tag,
 
116
                          ASN1_Tag class_tag = CONTEXT_SPECIFIC);
 
117
 
 
118
      BER_Decoder& decode(class ASN1_Object& obj,
 
119
                          ASN1_Tag type_tag = NO_OBJECT,
 
120
                          ASN1_Tag class_tag = NO_OBJECT);
 
121
 
 
122
      BER_Decoder& decode_octet_string_bigint(class BigInt& b);
 
123
 
 
124
      uint64_t decode_constrained_integer(ASN1_Tag type_tag,
 
125
                                        ASN1_Tag class_tag,
 
126
                                        size_t T_bytes);
 
127
 
 
128
      template<typename T> BER_Decoder& decode_integer_type(T& out)
 
129
         {
 
130
         return decode_integer_type<T>(out, INTEGER, UNIVERSAL);
 
131
         }
 
132
 
 
133
      template<typename T>
 
134
         BER_Decoder& decode_integer_type(T& out,
 
135
                                          ASN1_Tag type_tag,
 
136
                                          ASN1_Tag class_tag = CONTEXT_SPECIFIC)
 
137
         {
 
138
         out = static_cast<T>(decode_constrained_integer(type_tag, class_tag, sizeof(out)));
 
139
         return (*this);
 
140
         }
 
141
 
 
142
      template<typename T>
 
143
         BER_Decoder& decode_optional(T& out,
 
144
                                      ASN1_Tag type_tag,
 
145
                                      ASN1_Tag class_tag,
 
146
                                      const T& default_value = T());
 
147
 
 
148
      template<typename T>
 
149
         BER_Decoder& decode_optional_implicit(
 
150
            T& out,
 
151
            ASN1_Tag type_tag,
 
152
            ASN1_Tag class_tag,
 
153
            ASN1_Tag real_type,
 
154
            ASN1_Tag real_class,
 
155
            const T& default_value = T());
 
156
 
 
157
      template<typename T>
 
158
         BER_Decoder& decode_list(std::vector<T>& out,
 
159
                                  ASN1_Tag type_tag = SEQUENCE,
 
160
                                  ASN1_Tag class_tag = UNIVERSAL);
 
161
 
 
162
      template<typename T>
 
163
         BER_Decoder& decode_and_check(const T& expected,
 
164
                                       const std::string& error_msg)
 
165
         {
 
166
         T actual;
 
167
         decode(actual);
 
168
 
 
169
         if(actual != expected)
 
170
            throw Decoding_Error(error_msg);
 
171
 
 
172
         return (*this);
 
173
         }
 
174
 
 
175
      /*
 
176
      * Decode an OPTIONAL string type
 
177
      */
 
178
      template<typename Alloc>
 
179
      BER_Decoder& decode_optional_string(std::vector<uint8_t, Alloc>& out,
 
180
                                          ASN1_Tag real_type,
 
181
                                          uint16_t type_no,
 
182
                                          ASN1_Tag class_tag = CONTEXT_SPECIFIC)
 
183
         {
 
184
         BER_Object obj = get_next_object();
 
185
 
 
186
         ASN1_Tag type_tag = static_cast<ASN1_Tag>(type_no);
 
187
 
 
188
         if(obj.type_tag == type_tag && obj.class_tag == class_tag)
 
189
            {
 
190
            if((class_tag & CONSTRUCTED) && (class_tag & CONTEXT_SPECIFIC))
 
191
               BER_Decoder(obj.value).decode(out, real_type).verify_end();
 
192
            else
 
193
               {
 
194
               push_back(obj);
 
195
               decode(out, real_type, type_tag, class_tag);
 
196
               }
 
197
            }
 
198
         else
 
199
            {
 
200
            out.clear();
 
201
            push_back(obj);
 
202
            }
 
203
 
 
204
         return (*this);
 
205
         }
 
206
 
 
207
      BER_Decoder& operator=(const BER_Decoder&) = delete;
 
208
 
 
209
      explicit BER_Decoder(DataSource&);
 
210
 
 
211
      BER_Decoder(const uint8_t[], size_t);
 
212
 
 
213
      explicit BER_Decoder(const secure_vector<uint8_t>&);
 
214
 
 
215
      explicit BER_Decoder(const std::vector<uint8_t>& vec);
 
216
 
 
217
      BER_Decoder(const BER_Decoder&);
 
218
   private:
 
219
      BER_Decoder* m_parent;
 
220
      BER_Object m_pushed;
 
221
      // either m_data_src.get() or an unowned pointer
 
222
      DataSource* m_source;
 
223
      mutable std::unique_ptr<DataSource> m_data_src;
 
224
   };
 
225
 
 
226
/*
 
227
* Decode an OPTIONAL or DEFAULT element
 
228
*/
 
229
template<typename T>
 
230
BER_Decoder& BER_Decoder::decode_optional(T& out,
 
231
                                          ASN1_Tag type_tag,
 
232
                                          ASN1_Tag class_tag,
 
233
                                          const T& default_value)
 
234
   {
 
235
   BER_Object obj = get_next_object();
 
236
 
 
237
   if(obj.type_tag == type_tag && obj.class_tag == class_tag)
 
238
      {
 
239
      if((class_tag & CONSTRUCTED) && (class_tag & CONTEXT_SPECIFIC))
 
240
         BER_Decoder(obj.value).decode(out).verify_end();
 
241
      else
 
242
         {
 
243
         push_back(obj);
 
244
         decode(out, type_tag, class_tag);
 
245
         }
 
246
      }
 
247
   else
 
248
      {
 
249
      out = default_value;
 
250
      push_back(obj);
 
251
      }
 
252
 
 
253
   return (*this);
 
254
   }
 
255
 
 
256
/*
 
257
* Decode an OPTIONAL or DEFAULT element
 
258
*/
 
259
template<typename T>
 
260
BER_Decoder& BER_Decoder::decode_optional_implicit(
 
261
   T& out,
 
262
   ASN1_Tag type_tag,
 
263
   ASN1_Tag class_tag,
 
264
   ASN1_Tag real_type,
 
265
   ASN1_Tag real_class,
 
266
   const T& default_value)
 
267
   {
 
268
   BER_Object obj = get_next_object();
 
269
 
 
270
   if(obj.type_tag == type_tag && obj.class_tag == class_tag)
 
271
      {
 
272
      obj.type_tag = real_type;
 
273
      obj.class_tag = real_class;
 
274
      push_back(obj);
 
275
      decode(out, real_type, real_class);
 
276
      }
 
277
   else
 
278
      {
 
279
      out = default_value;
 
280
      push_back(obj);
 
281
      }
 
282
 
 
283
   return (*this);
 
284
   }
 
285
/*
 
286
* Decode a list of homogenously typed values
 
287
*/
 
288
template<typename T>
 
289
BER_Decoder& BER_Decoder::decode_list(std::vector<T>& vec,
 
290
                                      ASN1_Tag type_tag,
 
291
                                      ASN1_Tag class_tag)
 
292
   {
 
293
   BER_Decoder list = start_cons(type_tag, class_tag);
 
294
 
 
295
   while(list.more_items())
 
296
      {
 
297
      T value;
 
298
      list.decode(value);
 
299
      vec.push_back(value);
 
300
      }
 
301
 
 
302
   list.end_cons();
 
303
 
 
304
   return (*this);
 
305
   }
 
306
 
 
307
}
 
308
 
 
309
#endif