Botan  2.6.0
Crypto and TLS for C++11
ber_dec.h
Go to the documentation of this file.
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>
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.length() != sizeof(T))
58  throw BER_Decoding_Error(
59  "Size mismatch. Object value size is " +
60  std::to_string(obj.length()) +
61  "; Output type size is " +
62  std::to_string(sizeof(T)));
63 
64  copy_mem(reinterpret_cast<uint8_t*>(&out), obj.bits(), obj.length());
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 
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>
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.is_a(type_tag, class_tag))
189  {
190  if((class_tag & CONSTRUCTED) && (class_tag & CONTEXT_SPECIFIC))
191  BER_Decoder(obj).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 BER_Object& obj);
214 
215  explicit BER_Decoder(const secure_vector<uint8_t>&);
216 
217  explicit BER_Decoder(const std::vector<uint8_t>& vec);
218 
219  BER_Decoder(const BER_Decoder&);
220  private:
221  BER_Decoder* m_parent = nullptr;
222  BER_Object m_pushed;
223  // either m_data_src.get() or an unowned pointer
224  DataSource* m_source;
225  mutable std::unique_ptr<DataSource> m_data_src;
226  };
227 
228 /*
229 * Decode an OPTIONAL or DEFAULT element
230 */
231 template<typename T>
233  ASN1_Tag type_tag,
234  ASN1_Tag class_tag,
235  const T& default_value)
236  {
237  BER_Object obj = get_next_object();
238 
239  if(obj.is_a(type_tag, class_tag))
240  {
241  if((class_tag & CONSTRUCTED) && (class_tag & CONTEXT_SPECIFIC))
242  BER_Decoder(obj).decode(out).verify_end();
243  else
244  {
245  push_back(obj);
246  decode(out, type_tag, class_tag);
247  }
248  }
249  else
250  {
251  out = default_value;
252  push_back(obj);
253  }
254 
255  return (*this);
256  }
257 
258 /*
259 * Decode an OPTIONAL or DEFAULT element
260 */
261 template<typename T>
263  T& out,
264  ASN1_Tag type_tag,
265  ASN1_Tag class_tag,
266  ASN1_Tag real_type,
267  ASN1_Tag real_class,
268  const T& default_value)
269  {
270  BER_Object obj = get_next_object();
271 
272  if(obj.is_a(type_tag, class_tag))
273  {
274  obj.set_tagging(real_type, real_class);
275  push_back(obj);
276  decode(out, real_type, real_class);
277  }
278  else
279  {
280  out = default_value;
281  push_back(obj);
282  }
283 
284  return (*this);
285  }
286 /*
287 * Decode a list of homogenously typed values
288 */
289 template<typename T>
291  ASN1_Tag type_tag,
292  ASN1_Tag class_tag)
293  {
294  BER_Decoder list = start_cons(type_tag, class_tag);
295 
296  while(list.more_items())
297  {
298  T value;
299  list.decode(value);
300  vec.push_back(value);
301  }
302 
303  list.end_cons();
304 
305  return (*this);
306  }
307 
308 }
309 
310 #endif
BER_Decoder & decode_integer_type(T &out)
Definition: ber_dec.h:128
BER_Decoder(DataSource &)
Definition: ber_dec.cpp:269
BER_Decoder & decode_optional_string(std::vector< uint8_t, Alloc > &out, ASN1_Tag real_type, uint16_t type_no, ASN1_Tag class_tag=CONTEXT_SPECIFIC)
Definition: ber_dec.h:179
BER_Decoder & decode_and_check(const T &expected, const std::string &error_msg)
Definition: ber_dec.h:163
bool is_a(ASN1_Tag type_tag, ASN1_Tag class_tag) const
Definition: asn1_obj.cpp:31
#define BOTAN_PUBLIC_API(maj, min)
Definition: compiler.h:27
void assert_is_a(ASN1_Tag type_tag, ASN1_Tag class_tag, const std::string &descr="object") const
Definition: asn1_obj.cpp:18
void push_back(const BER_Object &obj)
Definition: ber_dec.cpp:229
BER_Decoder & decode(bool &v)
Definition: ber_dec.cpp:338
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:145
ASN1_Tag
Definition: asn1_obj.h:22
BER_Decoder & raw_bytes(std::vector< uint8_t, Alloc > &out)
Definition: ber_dec.h:73
BER_Decoder & decode_optional(T &out, ASN1_Tag type_tag, ASN1_Tag class_tag, const T &default_value=T())
Definition: ber_dec.h:232
BER_Decoder & end_cons()
Definition: ber_dec.cpp:253
secure_vector< uint8_t > decode(DataSource &source, std::string &label)
Definition: pem.cpp:68
BER_Decoder start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition: ber_dec.cpp:239
size_t length() const
Definition: asn1_obj.h:102
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:108
Definition: alg_id.cpp:13
BER_Decoder & decode_optional_implicit(T &out, ASN1_Tag type_tag, ASN1_Tag class_tag, ASN1_Tag real_type, ASN1_Tag real_class, const T &default_value=T())
Definition: ber_dec.h:262
BER_Decoder & decode_integer_type(T &out, ASN1_Tag type_tag, ASN1_Tag class_tag=CONTEXT_SPECIFIC)
Definition: ber_dec.h:134
BER_Object get_next_object()
Definition: ber_dec.cpp:184
const uint8_t * bits() const
Definition: asn1_obj.h:100
BER_Decoder & get_next_value(T &out, ASN1_Tag type_tag, ASN1_Tag class_tag=CONTEXT_SPECIFIC)
Definition: ber_dec.h:48
BER_Decoder & verify_end()
Definition: ber_dec.cpp:163
fe T
Definition: ge.cpp:37
BER_Decoder & decode_list(std::vector< T > &out, ASN1_Tag type_tag=SEQUENCE, ASN1_Tag class_tag=UNIVERSAL)
Definition: ber_dec.h:290
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:88
bool more_items() const
Definition: ber_dec.cpp:153
BER_Decoder & decode(std::vector< uint8_t, Alloc > &out, ASN1_Tag real_type)
Definition: ber_dec.h:91