Botan 3.0.0-alpha0
Crypto and TLS for C&
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
15namespace Botan {
16
17class 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 BOTAN_DEPRECATED("Use DER_Encoder(vector) instead")
62 std::vector<uint8_t> get_contents_unlocked();
63
64 DER_Encoder& start_cons(ASN1_Type type_tag, ASN1_Class class_tag);
65
66 DER_Encoder& start_sequence()
67 {
69 }
70
72 {
73 return start_cons(ASN1_Type::Set, ASN1_Class::Universal);
74 }
75
77 {
78 return start_cons(ASN1_Type(tag), ASN1_Class::ContextSpecific);
79 }
80
82 {
83 return start_cons(ASN1_Type(tag), ASN1_Class::ExplicitContextSpecific);
84 }
85
86 DER_Encoder& end_cons();
87
88 DER_Encoder& start_explicit(uint16_t type_tag);
89 DER_Encoder& end_explicit();
90
91 /**
92 * Insert raw bytes directly into the output stream
93 */
94 DER_Encoder& raw_bytes(const uint8_t val[], size_t len);
95
96 template<typename Alloc>
97 DER_Encoder& raw_bytes(const std::vector<uint8_t, Alloc>& val)
98 {
99 return raw_bytes(val.data(), val.size());
100 }
101
102 DER_Encoder& encode_null();
103 DER_Encoder& encode(bool b);
104 DER_Encoder& encode(size_t s);
105 DER_Encoder& encode(const BigInt& n);
106 DER_Encoder& encode(const uint8_t val[], size_t len, ASN1_Type real_type);
107
108 template<typename Alloc>
109 DER_Encoder& encode(const std::vector<uint8_t, Alloc>& vec, ASN1_Type real_type)
110 {
111 return encode(vec.data(), vec.size(), real_type);
112 }
113
114 DER_Encoder& encode(bool b,
115 ASN1_Type type_tag,
117
118 DER_Encoder& encode(size_t s,
119 ASN1_Type type_tag,
121
122 DER_Encoder& encode(const BigInt& n,
123 ASN1_Type type_tag,
125
126 DER_Encoder& encode(const uint8_t v[], size_t len,
127 ASN1_Type real_type,
128 ASN1_Type type_tag,
130
131 template<typename Alloc>
132 DER_Encoder& encode(const std::vector<uint8_t, Alloc>& bytes,
133 ASN1_Type real_type,
134 ASN1_Type type_tag, ASN1_Class class_tag)
135 {
136 return encode(bytes.data(), bytes.size(),
137 real_type, type_tag, class_tag);
138 }
139
140 template<typename T>
141 DER_Encoder& encode_optional(const T& value, const T& default_value)
142 {
143 if(value != default_value)
144 encode(value);
145 return (*this);
146 }
147
148 template<typename T>
149 DER_Encoder& encode_list(const std::vector<T>& values)
150 {
151 for(size_t i = 0; i != values.size(); ++i)
152 encode(values[i]);
153 return (*this);
154 }
155
156 /*
157 * Request for an object to encode itself to this stream
158 */
159 DER_Encoder& encode(const ASN1_Object& obj);
160
161 /*
162 * Conditionally write some values to the stream
163 */
165 {
166 if(pred)
167 return raw_bytes(enc.get_contents());
168 return (*this);
169 }
170
171 DER_Encoder& encode_if(bool pred, const ASN1_Object& obj)
172 {
173 if(pred)
174 encode(obj);
175 return (*this);
176 }
177
178 DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag,
179 const uint8_t rep[], size_t length);
180
182 const std::vector<uint8_t>& rep)
183 {
184 return add_object(type_tag, class_tag, rep.data(), rep.size());
185 }
186
188 const secure_vector<uint8_t>& rep)
189 {
190 return add_object(type_tag, class_tag, rep.data(), rep.size());
191 }
192
193 DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag,
194 const std::string& str);
195
196 DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag,
197 uint8_t val);
198
199 private:
200 class DER_Sequence final
201 {
202 public:
203 uint32_t tag_of() const;
204
205 void push_contents(DER_Encoder& der);
206
207 void add_bytes(const uint8_t val[], size_t len);
208
209 void add_bytes(const uint8_t hdr[], size_t hdr_len,
210 const uint8_t val[], size_t val_len);
211
212 DER_Sequence(ASN1_Type, ASN1_Class);
213
214 DER_Sequence(DER_Sequence&& seq) :
215 m_type_tag(std::move(seq.m_type_tag)),
216 m_class_tag(std::move(seq.m_class_tag)),
217 m_contents(std::move(seq.m_contents)),
218 m_set_contents(std::move(seq.m_set_contents)) {}
219
220 DER_Sequence& operator=(DER_Sequence&& seq)
221 {
222 std::swap(m_type_tag, seq.m_type_tag);
223 std::swap(m_class_tag, seq.m_class_tag);
224 std::swap(m_contents, seq.m_contents);
225 std::swap(m_set_contents, seq.m_set_contents);
226 return (*this);
227 }
228
229 DER_Sequence(const DER_Sequence& seq) = default;
230
231 DER_Sequence& operator=(const DER_Sequence& seq) = default;
232
233 private:
234 ASN1_Type m_type_tag;
235 ASN1_Class m_class_tag;
236 secure_vector<uint8_t> m_contents;
237 std::vector< secure_vector<uint8_t> > m_set_contents;
238 };
239
240 append_fn m_append_output;
241 secure_vector<uint8_t> m_default_outbuf;
242 std::vector<DER_Sequence> m_subsequences;
243 };
244
245}
246
247#endif
secure_vector< uint8_t > get_contents()
Definition: der_enc.cpp:155
DER_Encoder & start_set()
Definition: der_enc.h:71
DER_Encoder & add_object(ASN1_Type type_tag, ASN1_Class class_tag, const std::vector< uint8_t > &rep)
Definition: der_enc.h:181
DER_Encoder & raw_bytes(const std::vector< uint8_t, Alloc > &val)
Definition: der_enc.h:97
DER_Encoder & encode_optional(const T &value, const T &default_value)
Definition: der_enc.h:141
DER_Encoder & encode_list(const std::vector< T > &values)
Definition: der_enc.h:149
DER_Encoder & encode_if(bool pred, const ASN1_Object &obj)
Definition: der_enc.h:171
DER_Encoder & encode(const std::vector< uint8_t, Alloc > &vec, ASN1_Type real_type)
Definition: der_enc.h:109
DER_Encoder & start_explicit_context_specific(uint32_t tag)
Definition: der_enc.h:81
DER_Encoder & start_context_specific(uint32_t tag)
Definition: der_enc.h:76
std::function< void(const uint8_t[], size_t)> append_fn
Definition: der_enc.h:25
DER_Encoder & add_object(ASN1_Type type_tag, ASN1_Class class_tag, const secure_vector< uint8_t > &rep)
Definition: der_enc.h:187
DER_Encoder(append_fn append)
Definition: der_enc.h:50
DER_Encoder & encode(const std::vector< uint8_t, Alloc > &bytes, ASN1_Type real_type, ASN1_Type type_tag, ASN1_Class class_tag)
Definition: der_enc.h:132
DER_Encoder & encode_if(bool pred, DER_Encoder &enc)
Definition: der_enc.h:164
DER_Encoder()=default
int(* final)(unsigned char *, CTX *)
#define BOTAN_PUBLIC_API(maj, min)
Definition: compiler.h:31
fe T
Definition: ge.cpp:36
Polynomial v
Definition: kyber.cpp:822
PolynomialVector b
Definition: kyber.cpp:821
std::string encode(const uint8_t der[], size_t length, const std::string &label, size_t width)
Definition: pem.cpp:41
Definition: alg_id.cpp:13
ASN1_Class
Definition: asn1_obj.h:24
ASN1_Type
Definition: asn1_obj.h:39
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:65
Definition: bigint.h:1077