Botan  2.1.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_oid.h>
12 #include <botan/data_src.h>
13 
14 namespace Botan {
15 
16 /**
17 * BER Decoding Object
18 */
19 class BOTAN_DLL BER_Decoder
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.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  BER_Decoder& raw_bytes(secure_vector<uint8_t>& v);
70  BER_Decoder& raw_bytes(std::vector<uint8_t>& v);
71 
72  BER_Decoder& decode_null();
73  BER_Decoder& decode(bool& v);
74  BER_Decoder& decode(size_t& v);
75  BER_Decoder& decode(class BigInt& v);
76  BER_Decoder& decode(std::vector<uint8_t>& v, ASN1_Tag type_tag);
78 
79  BER_Decoder& decode(bool& v,
80  ASN1_Tag type_tag,
81  ASN1_Tag class_tag = CONTEXT_SPECIFIC);
82 
83  BER_Decoder& decode(size_t& v,
84  ASN1_Tag type_tag,
85  ASN1_Tag class_tag = CONTEXT_SPECIFIC);
86 
87  BER_Decoder& decode(class BigInt& v,
88  ASN1_Tag type_tag,
89  ASN1_Tag class_tag = CONTEXT_SPECIFIC);
90 
91  BER_Decoder& decode(std::vector<uint8_t>& v,
92  ASN1_Tag real_type,
93  ASN1_Tag type_tag,
94  ASN1_Tag class_tag = CONTEXT_SPECIFIC);
95 
97  ASN1_Tag real_type,
98  ASN1_Tag type_tag,
99  ASN1_Tag class_tag = CONTEXT_SPECIFIC);
100 
101  BER_Decoder& decode(class ASN1_Object& obj,
102  ASN1_Tag type_tag = NO_OBJECT,
103  ASN1_Tag class_tag = NO_OBJECT);
104 
105  BER_Decoder& decode_octet_string_bigint(class BigInt& b);
106 
107  uint64_t decode_constrained_integer(ASN1_Tag type_tag,
108  ASN1_Tag class_tag,
109  size_t T_bytes);
110 
111  template<typename T> BER_Decoder& decode_integer_type(T& out)
112  {
113  return decode_integer_type<T>(out, INTEGER, UNIVERSAL);
114  }
115 
116  template<typename T>
118  ASN1_Tag type_tag,
119  ASN1_Tag class_tag = CONTEXT_SPECIFIC)
120  {
121  out = static_cast<T>(decode_constrained_integer(type_tag, class_tag, sizeof(out)));
122  return (*this);
123  }
124 
125  template<typename T>
126  BER_Decoder& decode_optional(T& out,
127  ASN1_Tag type_tag,
128  ASN1_Tag class_tag,
129  const T& default_value = T());
130 
131  template<typename T>
132  BER_Decoder& decode_optional_implicit(
133  T& out,
134  ASN1_Tag type_tag,
135  ASN1_Tag class_tag,
136  ASN1_Tag real_type,
137  ASN1_Tag real_class,
138  const T& default_value = T());
139 
140  template<typename T>
141  BER_Decoder& decode_list(std::vector<T>& out,
142  ASN1_Tag type_tag = SEQUENCE,
143  ASN1_Tag class_tag = UNIVERSAL);
144 
145  template<typename T>
146  BER_Decoder& decode_and_check(const T& expected,
147  const std::string& error_msg)
148  {
149  T actual;
150  decode(actual);
151 
152  if(actual != expected)
153  throw Decoding_Error(error_msg);
154 
155  return (*this);
156  }
157 
158  /*
159  * Decode an OPTIONAL string type
160  */
161  template<typename Alloc>
162  BER_Decoder& decode_optional_string(std::vector<uint8_t, Alloc>& out,
163  ASN1_Tag real_type,
164  uint16_t type_no,
165  ASN1_Tag class_tag = CONTEXT_SPECIFIC)
166  {
167  BER_Object obj = get_next_object();
168 
169  ASN1_Tag type_tag = static_cast<ASN1_Tag>(type_no);
170 
171  if(obj.type_tag == type_tag && obj.class_tag == class_tag)
172  {
173  if((class_tag & CONSTRUCTED) && (class_tag & CONTEXT_SPECIFIC))
174  BER_Decoder(obj.value).decode(out, real_type).verify_end();
175  else
176  {
177  push_back(obj);
178  decode(out, real_type, type_tag, class_tag);
179  }
180  }
181  else
182  {
183  out.clear();
184  push_back(obj);
185  }
186 
187  return (*this);
188  }
189 
190  BER_Decoder& operator=(const BER_Decoder&) = delete;
191 
192  explicit BER_Decoder(DataSource&);
193 
194  BER_Decoder(const uint8_t[], size_t);
195 
196  explicit BER_Decoder(const secure_vector<uint8_t>&);
197 
198  explicit BER_Decoder(const std::vector<uint8_t>& vec);
199 
200  BER_Decoder(const BER_Decoder&);
201  ~BER_Decoder();
202  private:
203  BER_Decoder* m_parent;
204  DataSource* m_source;
205  BER_Object m_pushed;
206  mutable bool m_owns;
207  };
208 
209 /*
210 * Decode an OPTIONAL or DEFAULT element
211 */
212 template<typename T>
214  ASN1_Tag type_tag,
215  ASN1_Tag class_tag,
216  const T& default_value)
217  {
218  BER_Object obj = get_next_object();
219 
220  if(obj.type_tag == type_tag && obj.class_tag == class_tag)
221  {
222  if((class_tag & CONSTRUCTED) && (class_tag & CONTEXT_SPECIFIC))
223  BER_Decoder(obj.value).decode(out).verify_end();
224  else
225  {
226  push_back(obj);
227  decode(out, type_tag, class_tag);
228  }
229  }
230  else
231  {
232  out = default_value;
233  push_back(obj);
234  }
235 
236  return (*this);
237  }
238 
239 /*
240 * Decode an OPTIONAL or DEFAULT element
241 */
242 template<typename T>
244  T& out,
245  ASN1_Tag type_tag,
246  ASN1_Tag class_tag,
247  ASN1_Tag real_type,
248  ASN1_Tag real_class,
249  const T& default_value)
250  {
251  BER_Object obj = get_next_object();
252 
253  if(obj.type_tag == type_tag && obj.class_tag == class_tag)
254  {
255  obj.type_tag = real_type;
256  obj.class_tag = real_class;
257  push_back(obj);
258  decode(out, real_type, real_class);
259  }
260  else
261  {
262  out = default_value;
263  push_back(obj);
264  }
265 
266  return (*this);
267  }
268 /*
269 * Decode a list of homogenously typed values
270 */
271 template<typename T>
273  ASN1_Tag type_tag,
274  ASN1_Tag class_tag)
275  {
276  BER_Decoder list = start_cons(type_tag, class_tag);
277 
278  while(list.more_items())
279  {
280  T value;
281  list.decode(value);
282  vec.push_back(value);
283  }
284 
285  list.end_cons();
286 
287  return (*this);
288  }
289 
290 }
291 
292 #endif
secure_vector< uint8_t > decode(DataSource &source, std::string &label)
Definition: pem.cpp:68
BER_Decoder & decode_integer_type(T &out)
Definition: ber_dec.h:111
BER_Decoder(DataSource &)
Definition: ber_dec.cpp:284
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:162
BER_Decoder & decode_and_check(const T &expected, const std::string &error_msg)
Definition: ber_dec.h:146
void push_back(const BER_Object &obj)
Definition: ber_dec.cpp:248
BER_Decoder & decode(bool &v)
Definition: ber_dec.cpp:376
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:47
BER_Decoder & decode_optional(T &out, ASN1_Tag type_tag, ASN1_Tag class_tag, const T &default_value=T())
Definition: ber_dec.h:213
void assert_is_a(ASN1_Tag, ASN1_Tag)
Definition: ber_dec.cpp:145
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:121
secure_vector< uint8_t > value
Definition: asn1_obj.h:94
BER_Decoder & end_cons()
Definition: ber_dec.cpp:272
bool more_items() const
Definition: ber_dec.cpp:158
ASN1_Tag
Definition: asn1_obj.h:22
BER_Decoder start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition: ber_dec.cpp:258
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:68
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:243
BER_Decoder & decode_integer_type(T &out, ASN1_Tag type_tag, ASN1_Tag class_tag=CONTEXT_SPECIFIC)
Definition: ber_dec.h:117
BER_Object get_next_object()
Definition: ber_dec.cpp:210
ASN1_Tag class_tag
Definition: asn1_obj.h:91
ASN1_Tag type_tag
Definition: asn1_obj.h:91
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:168
BER_Decoder & decode_list(std::vector< T > &out, ASN1_Tag type_tag=SEQUENCE, ASN1_Tag class_tag=UNIVERSAL)
Definition: ber_dec.h:272