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