Botan  2.19.1
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 
19 /**
20 * General DER Encoding Object
21 */
23  {
24  public:
25  typedef std::function<void (const uint8_t[], size_t)> append_fn;
26 
27  /**
28  * DER encode, writing to an internal buffer
29  * Use get_contents or get_contents_unlocked to read the results
30  * after all encoding is completed.
31  */
32  DER_Encoder() = default;
33 
34  /**
35  * DER encode, writing to @param vec
36  * If this constructor is used, get_contents* may not be called.
37  */
39 
40  /**
41  * DER encode, writing to @param vec
42  * If this constructor is used, get_contents* may not be called.
43  */
44  DER_Encoder(std::vector<uint8_t>& vec);
45 
46  /**
47  * DER encode, calling append to write output
48  * If this constructor is used, get_contents* may not be called.
49  */
50  DER_Encoder(append_fn append) : m_append_output(append) {}
51 
52  secure_vector<uint8_t> get_contents();
53 
54  /**
55  * Return the encoded contents as a std::vector
56  *
57  * If using this function, instead pass a std::vector to the
58  * contructor of DER_Encoder where the output will be placed. This
59  * avoids several unecessary copies.
60  */
61  std::vector<uint8_t> BOTAN_DEPRECATED("Use DER_Encoder(vector) instead") get_contents_unlocked();
62 
63  DER_Encoder& start_cons(ASN1_Tag type_tag,
64  ASN1_Tag class_tag = UNIVERSAL);
65  DER_Encoder& end_cons();
66 
67  DER_Encoder& start_explicit(uint16_t type_tag);
68  DER_Encoder& end_explicit();
69 
70  /**
71  * Insert raw bytes directly into the output stream
72  */
73  DER_Encoder& raw_bytes(const uint8_t val[], size_t len);
74 
75  template<typename Alloc>
76  DER_Encoder& raw_bytes(const std::vector<uint8_t, Alloc>& val)
77  {
78  return raw_bytes(val.data(), val.size());
79  }
80 
81  DER_Encoder& encode_null();
82  DER_Encoder& encode(bool b);
83  DER_Encoder& encode(size_t s);
84  DER_Encoder& encode(const BigInt& n);
85  DER_Encoder& encode(const uint8_t val[], size_t len, ASN1_Tag real_type);
86 
87  template<typename Alloc>
88  DER_Encoder& encode(const std::vector<uint8_t, Alloc>& vec, ASN1_Tag real_type)
89  {
90  return encode(vec.data(), vec.size(), real_type);
91  }
92 
93  DER_Encoder& encode(bool b,
94  ASN1_Tag type_tag,
95  ASN1_Tag class_tag = CONTEXT_SPECIFIC);
96 
97  DER_Encoder& encode(size_t s,
98  ASN1_Tag type_tag,
99  ASN1_Tag class_tag = CONTEXT_SPECIFIC);
100 
101  DER_Encoder& encode(const BigInt& n,
102  ASN1_Tag type_tag,
103  ASN1_Tag class_tag = CONTEXT_SPECIFIC);
104 
105  DER_Encoder& encode(const uint8_t v[], size_t len,
106  ASN1_Tag real_type,
107  ASN1_Tag type_tag,
108  ASN1_Tag class_tag = CONTEXT_SPECIFIC);
109 
110  template<typename Alloc>
111  DER_Encoder& encode(const std::vector<uint8_t, Alloc>& bytes,
112  ASN1_Tag real_type,
113  ASN1_Tag type_tag, ASN1_Tag class_tag)
114  {
115  return encode(bytes.data(), bytes.size(),
116  real_type, type_tag, class_tag);
117  }
118 
119  template<typename T>
120  DER_Encoder& encode_optional(const T& value, const T& default_value)
121  {
122  if(value != default_value)
123  encode(value);
124  return (*this);
125  }
126 
127  template<typename T>
128  DER_Encoder& encode_list(const std::vector<T>& values)
129  {
130  for(size_t i = 0; i != values.size(); ++i)
131  encode(values[i]);
132  return (*this);
133  }
134 
135  /*
136  * Request for an object to encode itself to this stream
137  */
138  DER_Encoder& encode(const ASN1_Object& obj);
139 
140  /*
141  * Conditionally write some values to the stream
142  */
144  {
145  if(pred)
146  return raw_bytes(enc.get_contents());
147  return (*this);
148  }
149 
150  DER_Encoder& encode_if(bool pred, const ASN1_Object& obj)
151  {
152  if(pred)
153  encode(obj);
154  return (*this);
155  }
156 
157  DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag,
158  const uint8_t rep[], size_t length);
159 
160  DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag,
161  const std::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 secure_vector<uint8_t>& rep)
168  {
169  return add_object(type_tag, class_tag, rep.data(), rep.size());
170  }
171 
172  DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag,
173  const std::string& str);
174 
175  DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag,
176  uint8_t val);
177 
178  private:
179  class DER_Sequence final
180  {
181  public:
182  ASN1_Tag tag_of() const;
183 
184  void push_contents(DER_Encoder& der);
185 
186  void add_bytes(const uint8_t val[], size_t len);
187 
188  void add_bytes(const uint8_t hdr[], size_t hdr_len,
189  const uint8_t val[], size_t val_len);
190 
191  DER_Sequence(ASN1_Tag, ASN1_Tag);
192 
193  DER_Sequence(DER_Sequence&& seq)
194  {
195  std::swap(m_type_tag, seq.m_type_tag);
196  std::swap(m_class_tag, seq.m_class_tag);
197  std::swap(m_contents, seq.m_contents);
198  std::swap(m_set_contents, seq.m_set_contents);
199  }
200 
201  DER_Sequence& operator=(DER_Sequence&& seq)
202  {
203  std::swap(m_type_tag, seq.m_type_tag);
204  std::swap(m_class_tag, seq.m_class_tag);
205  std::swap(m_contents, seq.m_contents);
206  std::swap(m_set_contents, seq.m_set_contents);
207  return (*this);
208  }
209 
210  DER_Sequence(const DER_Sequence& seq) = default;
211 
212  DER_Sequence& operator=(const DER_Sequence& seq) = default;
213 
214  private:
215  ASN1_Tag m_type_tag, m_class_tag;
216  secure_vector<uint8_t> m_contents;
217  std::vector< secure_vector<uint8_t> > m_set_contents;
218  };
219 
220  append_fn m_append_output;
221  secure_vector<uint8_t> m_default_outbuf;
222  std::vector<DER_Sequence> m_subsequences;
223  };
224 
225 }
226 
227 #endif
DER_Encoder & add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, const std::vector< uint8_t > &rep)
Definition: der_enc.h:160
DER_Encoder(append_fn append)
Definition: der_enc.h:50
DER_Encoder & encode_list(const std::vector< T > &values)
Definition: der_enc.h:128
DER_Encoder & encode_optional(const T &value, const T &default_value)
Definition: der_enc.h:120
DER_Encoder & encode(const std::vector< uint8_t, Alloc > &vec, ASN1_Tag real_type)
Definition: der_enc.h:88
DER_Encoder & encode_if(bool pred, const ASN1_Object &obj)
Definition: der_enc.h:150
std::function< void(const uint8_t[], size_t)> append_fn
Definition: der_enc.h:25
int(* final)(unsigned char *, CTX *)
#define BOTAN_PUBLIC_API(maj, min)
Definition: compiler.h:31
secure_vector< uint8_t > get_contents()
Definition: der_enc.cpp:152
Definition: bigint.h:1143
ASN1_Tag
Definition: asn1_obj.h:25
DER_Encoder & encode_if(bool pred, DER_Encoder &enc)
Definition: der_enc.h:143
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:65
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:111
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:166
fe T
Definition: ge.cpp:37