Botan  2.4.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.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 
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.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>
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>
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>
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
BER_Decoder & decode_integer_type(T &out)
Definition: ber_dec.h:128
void assert_is_a(ASN1_Tag type_tag, ASN1_Tag class_tag) const
Definition: ber_dec.cpp:153
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
#define BOTAN_PUBLIC_API(maj, min)
Definition: compiler.h:27
void push_back(const BER_Object &obj)
Definition: ber_dec.cpp:241
BER_Decoder & decode(bool &v)
Definition: ber_dec.cpp:355
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:108
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:230
secure_vector< uint8_t > value
Definition: asn1_obj.h:97
BER_Decoder & end_cons()
Definition: ber_dec.cpp:265
secure_vector< uint8_t > decode(DataSource &source, std::string &label)
Definition: pem.cpp:68
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:97
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:260
BER_Decoder & decode_integer_type(T &out, ASN1_Tag type_tag, ASN1_Tag class_tag=CONTEXT_SPECIFIC)
Definition: ber_dec.h:134
ASN1_Tag class_tag
Definition: asn1_obj.h:94
ASN1_Tag type_tag
Definition: asn1_obj.h:94
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:176
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:289
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:88
bool more_items() const
Definition: ber_dec.cpp:166
BER_Decoder & decode(std::vector< uint8_t, Alloc > &out, ASN1_Tag real_type)
Definition: ber_dec.h:91