Botan  2.7.0
Crypto and TLS for C++11
der_enc.h
Go to the documentation of this file.
1 /*
2 * DER Encoder
3 * (C) 1999-2007,2018 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #ifndef BOTAN_DER_ENCODER_H_
9 #define BOTAN_DER_ENCODER_H_
10 
11 #include <botan/asn1_obj.h>
12 #include <vector>
13 #include <functional>
14 
15 namespace Botan {
16 
17 class BigInt;
18 class ASN1_Object;
19 
20 /**
21 * General DER Encoding Object
22 */
23 class BOTAN_PUBLIC_API(2,0) DER_Encoder final
24  {
25  public:
26  typedef std::function<void (const uint8_t[], size_t)> append_fn;
27 
28  /**
29  * DER encode, writing to an internal buffer
30  * Use get_contents or get_contents_unlocked to read the results
31  * after all encoding is completed.
32  */
33  DER_Encoder() = default;
34 
35  /**
36  * DER encode, writing to @param vec
37  * If this constructor is used, get_contents* may not be called.
38  */
40 
41  /**
42  * DER encode, writing to @param vec
43  * If this constructor is used, get_contents* may not be called.
44  */
45  DER_Encoder(std::vector<uint8_t>& vec);
46 
47  /**
48  * DER encode, calling append to write output
49  * If this constructor is used, get_contents* may not be called.
50  */
51  DER_Encoder(append_fn append) : m_append_output(append) {}
52 
53  secure_vector<uint8_t> get_contents();
54 
55  std::vector<uint8_t> get_contents_unlocked();
56 
57  DER_Encoder& start_cons(ASN1_Tag type_tag,
58  ASN1_Tag class_tag = UNIVERSAL);
59  DER_Encoder& end_cons();
60 
61  DER_Encoder& start_explicit(uint16_t type_tag);
62  DER_Encoder& end_explicit();
63 
64  /**
65  * Insert raw bytes directly into the output stream
66  */
67  DER_Encoder& raw_bytes(const uint8_t val[], size_t len);
68 
69  template<typename Alloc>
70  DER_Encoder& raw_bytes(const std::vector<uint8_t, Alloc>& val)
71  {
72  return raw_bytes(val.data(), val.size());
73  }
74 
75  DER_Encoder& encode_null();
76  DER_Encoder& encode(bool b);
77  DER_Encoder& encode(size_t s);
78  DER_Encoder& encode(const BigInt& n);
79  DER_Encoder& encode(const uint8_t val[], size_t len, ASN1_Tag real_type);
80 
81  template<typename Alloc>
82  DER_Encoder& encode(const std::vector<uint8_t, Alloc>& vec, ASN1_Tag real_type)
83  {
84  return encode(vec.data(), vec.size(), real_type);
85  }
86 
87  DER_Encoder& encode(bool b,
88  ASN1_Tag type_tag,
89  ASN1_Tag class_tag = CONTEXT_SPECIFIC);
90 
91  DER_Encoder& encode(size_t s,
92  ASN1_Tag type_tag,
93  ASN1_Tag class_tag = CONTEXT_SPECIFIC);
94 
95  DER_Encoder& encode(const BigInt& n,
96  ASN1_Tag type_tag,
97  ASN1_Tag class_tag = CONTEXT_SPECIFIC);
98 
99  DER_Encoder& encode(const uint8_t v[], size_t len,
100  ASN1_Tag real_type,
101  ASN1_Tag type_tag,
102  ASN1_Tag class_tag = CONTEXT_SPECIFIC);
103 
104  template<typename Alloc>
105  DER_Encoder& encode(const std::vector<uint8_t, Alloc>& bytes,
106  ASN1_Tag real_type,
107  ASN1_Tag type_tag, ASN1_Tag class_tag)
108  {
109  return encode(bytes.data(), bytes.size(),
110  real_type, type_tag, class_tag);
111  }
112 
113  template<typename T>
114  DER_Encoder& encode_optional(const T& value, const T& default_value)
115  {
116  if(value != default_value)
117  encode(value);
118  return (*this);
119  }
120 
121  template<typename T>
122  DER_Encoder& encode_list(const std::vector<T>& values)
123  {
124  for(size_t i = 0; i != values.size(); ++i)
125  encode(values[i]);
126  return (*this);
127  }
128 
129  /*
130  * Request for an object to encode itself to this stream
131  */
132  DER_Encoder& encode(const ASN1_Object& obj);
133 
134  /*
135  * Conditionally write some values to the stream
136  */
138  {
139  if(pred)
140  return raw_bytes(enc.get_contents());
141  return (*this);
142  }
143 
144  DER_Encoder& encode_if(bool pred, const ASN1_Object& obj)
145  {
146  if(pred)
147  encode(obj);
148  return (*this);
149  }
150 
151  DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag,
152  const uint8_t rep[], size_t length);
153 
154  DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag,
155  const std::vector<uint8_t>& rep)
156  {
157  return add_object(type_tag, class_tag, rep.data(), rep.size());
158  }
159 
160  DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag,
161  const secure_vector<uint8_t>& rep)
162  {
163  return add_object(type_tag, class_tag, rep.data(), rep.size());
164  }
165 
166  DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag,
167  const std::string& str);
168 
169  DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag,
170  uint8_t val);
171 
172  private:
173  class DER_Sequence final
174  {
175  public:
176  ASN1_Tag tag_of() const;
177 
178  void push_contents(DER_Encoder& der);
179 
180  void add_bytes(const uint8_t val[], size_t len);
181 
182  void add_bytes(const uint8_t hdr[], size_t hdr_len,
183  const uint8_t val[], size_t val_len);
184 
185  DER_Sequence(ASN1_Tag, ASN1_Tag);
186 
187  DER_Sequence(DER_Sequence&& seq)
188  {
189  std::swap(m_type_tag, seq.m_type_tag);
190  std::swap(m_class_tag, seq.m_class_tag);
191  std::swap(m_contents, seq.m_contents);
192  std::swap(m_set_contents, seq.m_set_contents);
193  }
194 
195  DER_Sequence& operator=(DER_Sequence&& seq)
196  {
197  std::swap(m_type_tag, seq.m_type_tag);
198  std::swap(m_class_tag, seq.m_class_tag);
199  std::swap(m_contents, seq.m_contents);
200  std::swap(m_set_contents, seq.m_set_contents);
201  return (*this);
202  }
203 
204  DER_Sequence(const DER_Sequence& seq) = default;
205 
206  DER_Sequence& operator=(const DER_Sequence& seq) = default;
207 
208  private:
209  ASN1_Tag m_type_tag, m_class_tag;
210  secure_vector<uint8_t> m_contents;
211  std::vector< secure_vector<uint8_t> > m_set_contents;
212  };
213 
214  append_fn m_append_output;
215  secure_vector<uint8_t> m_default_outbuf;
216  std::vector<DER_Sequence> m_subsequences;
217  };
218 
219 }
220 
221 #endif
DER_Encoder & add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, const std::vector< uint8_t > &rep)
Definition: der_enc.h:154
DER_Encoder(append_fn append)
Definition: der_enc.h:51
DER_Encoder & encode_list(const std::vector< T > &values)
Definition: der_enc.h:122
DER_Encoder & encode_optional(const T &value, const T &default_value)
Definition: der_enc.h:114
DER_Encoder & encode(const std::vector< uint8_t, Alloc > &vec, ASN1_Tag real_type)
Definition: der_enc.h:82
DER_Encoder & encode_if(bool pred, const ASN1_Object &obj)
Definition: der_enc.h:144
std::function< void(const uint8_t[], size_t)> append_fn
Definition: der_enc.h:26
#define BOTAN_PUBLIC_API(maj, min)
Definition: compiler.h:27
secure_vector< uint8_t > get_contents()
Definition: der_enc.cpp:152
ASN1_Tag
Definition: asn1_obj.h:22
DER_Encoder & encode_if(bool pred, DER_Encoder &enc)
Definition: der_enc.h:137
DER_Encoder & raw_bytes(const std::vector< uint8_t, Alloc > &val)
Definition: der_enc.h:70
DER_Encoder & encode(const std::vector< uint8_t, Alloc > &bytes, ASN1_Tag real_type, ASN1_Tag type_tag, ASN1_Tag class_tag)
Definition: der_enc.h:105
std::string encode(const uint8_t der[], size_t length, const std::string &label, size_t width)
Definition: pem.cpp:43
Definition: alg_id.cpp:13
DER_Encoder & add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, const secure_vector< uint8_t > &rep)
Definition: der_enc.h:160
fe T
Definition: ge.cpp:37
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:88