/src/botan/build/include/public/botan/der_enc.h
Line | Count | Source |
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 <botan/secmem.h> |
13 | | #include <functional> |
14 | | #include <optional> |
15 | | #include <span> |
16 | | #include <vector> |
17 | | |
18 | | namespace Botan { |
19 | | |
20 | | class BigInt; |
21 | | |
22 | | /** |
23 | | * General DER Encoding Object |
24 | | */ |
25 | | class BOTAN_PUBLIC_API(2, 0) DER_Encoder final { |
26 | | public: |
27 | | /** |
28 | | * Callback type invoked with each chunk of encoded output |
29 | | */ |
30 | | typedef std::function<void(const uint8_t[], size_t)> append_fn; |
31 | | |
32 | | /** |
33 | | * DER encode, writing to an internal buffer |
34 | | * Use get_contents or get_contents_unlocked to read the results |
35 | | * after all encoding is completed. |
36 | | */ |
37 | 0 | DER_Encoder() = default; |
38 | | |
39 | | /** |
40 | | * DER encode, writing to @param vec |
41 | | * If this constructor is used, get_contents* may not be called. |
42 | | */ |
43 | | BOTAN_FUTURE_EXPLICIT DER_Encoder(secure_vector<uint8_t>& vec); |
44 | | |
45 | | /** |
46 | | * DER encode, writing to @param vec |
47 | | * If this constructor is used, get_contents* may not be called. |
48 | | */ |
49 | | BOTAN_FUTURE_EXPLICIT DER_Encoder(std::vector<uint8_t>& vec); |
50 | | |
51 | | /** |
52 | | * DER encode, calling append to write output |
53 | | * If this constructor is used, get_contents* may not be called. |
54 | | */ |
55 | 0 | BOTAN_FUTURE_EXPLICIT DER_Encoder(append_fn append) : m_append_output(std::move(append)) {} |
56 | | |
57 | | /** |
58 | | * Return the encoded contents |
59 | | * |
60 | | * Throws Invalid_State if any constructed encoding is still open, or if |
61 | | * this encoder was constructed with an output vector or append function. |
62 | | */ |
63 | | secure_vector<uint8_t> get_contents(); |
64 | | |
65 | | /** |
66 | | * Return the encoded contents as a std::vector |
67 | | * |
68 | | * If using this function, instead pass a std::vector to the |
69 | | * constructor of DER_Encoder where the output will be placed. This |
70 | | * avoids several unnecessary copies. |
71 | | */ |
72 | | BOTAN_DEPRECATED("Use DER_Encoder(vector) instead") std::vector<uint8_t> get_contents_unlocked(); |
73 | | |
74 | | /** |
75 | | * Start a constructed encoding with the given tagging. Must be closed with |
76 | | * end_cons(). Contents are emitted in the order they are encoded. |
77 | | * |
78 | | * @param type_tag the type tag of the constructed encoding |
79 | | * @param class_tag the class tag of the constructed encoding |
80 | | */ |
81 | | DER_Encoder& start_cons(ASN1_Type type_tag, ASN1_Class class_tag); |
82 | | |
83 | | /** |
84 | | * Start a SEQUENCE. Must be closed with end_cons(). |
85 | | */ |
86 | 100k | DER_Encoder& start_sequence() { return start_cons(ASN1_Type::Sequence, ASN1_Class::Universal); } |
87 | | |
88 | | /** |
89 | | * Start a SET/SET OF. Must be closed with end_cons(). Contents are DER sorted. |
90 | | */ |
91 | 0 | DER_Encoder& start_set() { return start_cons(ASN1_Type::Set, ASN1_Class::Universal); } |
92 | | |
93 | | /** |
94 | | * Start a SET/SET OF with an alternate tag. Contents are still DER sorted. |
95 | | * |
96 | | * @param type_tag the type tag of the constructed encoding |
97 | | * @param class_tag the class tag of the constructed encoding |
98 | | */ |
99 | | DER_Encoder& start_set(ASN1_Type type_tag, ASN1_Class class_tag); |
100 | | |
101 | | /** |
102 | | * Start a SET/SET OF with a context specific tag. Contents are still DER sorted. |
103 | | * |
104 | | * @param tag the context specific tag number |
105 | | */ |
106 | 0 | DER_Encoder& start_set(uint32_t tag) { return start_set(ASN1_Type(tag), ASN1_Class::ContextSpecific); } |
107 | | |
108 | | /** |
109 | | * Start an IMPLICIT context specific constructed encoding |
110 | | * |
111 | | * @param tag the context specific tag number |
112 | | */ |
113 | 35.0k | DER_Encoder& start_context_specific(uint32_t tag) { |
114 | 35.0k | return start_cons(ASN1_Type(tag), ASN1_Class::ContextSpecific); |
115 | 35.0k | } |
116 | | |
117 | | /** |
118 | | * Start an EXPLICIT context specific constructed encoding |
119 | | * |
120 | | * @param tag the context specific tag number |
121 | | */ |
122 | 0 | DER_Encoder& start_explicit_context_specific(uint32_t tag) { |
123 | 0 | return start_cons(ASN1_Type(tag), ASN1_Class::ExplicitContextSpecific); |
124 | 0 | } |
125 | | |
126 | | /** |
127 | | * Finish the innermost open constructed encoding |
128 | | * |
129 | | * Throws Invalid_State if no constructed encoding is open. |
130 | | */ |
131 | | DER_Encoder& end_cons(); |
132 | | |
133 | | /** |
134 | | * Start a context specific constructed encoding, an alias for |
135 | | * start_context_specific() |
136 | | * |
137 | | * @param type_tag the context specific tag number |
138 | | */ |
139 | | DER_Encoder& start_explicit(uint16_t type_tag); |
140 | | |
141 | | /** |
142 | | * Finish the innermost open constructed encoding, an alias for end_cons() |
143 | | */ |
144 | | DER_Encoder& end_explicit(); |
145 | | |
146 | | /** |
147 | | * Insert raw bytes directly into the output stream |
148 | | */ |
149 | | DER_Encoder& raw_bytes(const uint8_t val[], size_t len); |
150 | | |
151 | | /** |
152 | | * Insert raw bytes directly into the output stream |
153 | | */ |
154 | 69.6k | DER_Encoder& raw_bytes(std::span<const uint8_t> val) { return raw_bytes(val.data(), val.size()); } |
155 | | |
156 | | /** |
157 | | * Encode a NULL |
158 | | */ |
159 | | DER_Encoder& encode_null(); |
160 | | |
161 | | /** |
162 | | * Encode a BOOLEAN |
163 | | */ |
164 | | DER_Encoder& encode(bool b); |
165 | | |
166 | | /** |
167 | | * Encode an INTEGER |
168 | | */ |
169 | | DER_Encoder& encode(size_t s); |
170 | | |
171 | | /** |
172 | | * Encode an INTEGER |
173 | | */ |
174 | | DER_Encoder& encode(const BigInt& n); |
175 | | |
176 | | /** |
177 | | * Encode an OCTET STRING or an octet aligned BIT STRING |
178 | | * |
179 | | * @param val the contents of the object |
180 | | * @param real_type either ASN1_Type::OctetString or ASN1_Type::BitString |
181 | | */ |
182 | | DER_Encoder& encode(std::span<const uint8_t> val, ASN1_Type real_type); |
183 | | |
184 | | /** |
185 | | * Encode a BIT STRING, with `bits` not including the initial unused-bits octet. |
186 | | */ |
187 | | DER_Encoder& encode_bitstring(std::span<const uint8_t> bits, |
188 | | size_t unused_bits = 0, |
189 | | ASN1_Type type_tag = ASN1_Type::BitString, |
190 | | ASN1_Class class_tag = ASN1_Class::Universal); |
191 | | |
192 | | /** |
193 | | * Encode a BIT STRING |
194 | | * |
195 | | * @param bits the value to encode |
196 | | * @param type_tag the type tag to encode with |
197 | | * @param class_tag the class tag to encode with |
198 | | */ |
199 | | DER_Encoder& encode_bitstring(const ASN1_BitString& bits, |
200 | | ASN1_Type type_tag = ASN1_Type::BitString, |
201 | | ASN1_Class class_tag = ASN1_Class::Universal); |
202 | | |
203 | | /** |
204 | | * Encode a BIT STRING with no unused bits |
205 | | * |
206 | | * @param bytes the bits to encode |
207 | | * @param type_tag the type tag to encode with |
208 | | * @param class_tag the class tag to encode with |
209 | | */ |
210 | | DER_Encoder& encode_octet_aligned_bitstring(std::span<const uint8_t> bytes, |
211 | | ASN1_Type type_tag = ASN1_Type::BitString, |
212 | 17.2k | ASN1_Class class_tag = ASN1_Class::Universal) { |
213 | 17.2k | return encode_bitstring(bytes, 0, type_tag, class_tag); |
214 | 17.2k | } |
215 | | |
216 | | /** |
217 | | * Helper for encoding BIT STRING elements that are actually bit sets, rather |
218 | | * than being OCTET STRINGS with the wrong type. |
219 | | */ |
220 | | DER_Encoder& encode_named_bitstring(uint64_t bits, |
221 | | size_t width, |
222 | | ASN1_Type type_tag = ASN1_Type::BitString, |
223 | | ASN1_Class class_tag = ASN1_Class::Universal); |
224 | | |
225 | | /** |
226 | | * Encode an OCTET STRING or an octet aligned BIT STRING |
227 | | * |
228 | | * @param val the contents of the object |
229 | | * @param len the length of val in bytes |
230 | | * @param real_type either ASN1_Type::OctetString or ASN1_Type::BitString |
231 | | */ |
232 | 0 | DER_Encoder& encode(const uint8_t val[], size_t len, ASN1_Type real_type) { |
233 | 0 | return this->encode(std::span{val, len}, real_type); |
234 | 0 | } |
235 | | |
236 | | /** |
237 | | * Encode a BOOLEAN with an IMPLICIT tagging |
238 | | * |
239 | | * @param b the value to encode |
240 | | * @param type_tag the type tag to encode with |
241 | | * @param class_tag the class tag to encode with |
242 | | */ |
243 | | DER_Encoder& encode(bool b, ASN1_Type type_tag, ASN1_Class class_tag = ASN1_Class::ContextSpecific); |
244 | | |
245 | | /** |
246 | | * Encode an INTEGER with an IMPLICIT tagging |
247 | | * |
248 | | * @param s the value to encode |
249 | | * @param type_tag the type tag to encode with |
250 | | * @param class_tag the class tag to encode with |
251 | | */ |
252 | | DER_Encoder& encode(size_t s, ASN1_Type type_tag, ASN1_Class class_tag = ASN1_Class::ContextSpecific); |
253 | | |
254 | | /** |
255 | | * Encode an INTEGER with an IMPLICIT tagging |
256 | | * |
257 | | * @param n the value to encode |
258 | | * @param type_tag the type tag to encode with |
259 | | * @param class_tag the class tag to encode with |
260 | | */ |
261 | | DER_Encoder& encode(const BigInt& n, ASN1_Type type_tag, ASN1_Class class_tag = ASN1_Class::ContextSpecific); |
262 | | |
263 | | /** |
264 | | * Encode an OCTET STRING or octet aligned BIT STRING with an IMPLICIT tagging |
265 | | * |
266 | | * @param value the contents of the object |
267 | | * @param real_type either ASN1_Type::OctetString or ASN1_Type::BitString |
268 | | * @param type_tag the type tag to encode with |
269 | | * @param class_tag the class tag to encode with |
270 | | */ |
271 | | DER_Encoder& encode(std::span<const uint8_t> value, |
272 | | ASN1_Type real_type, |
273 | | ASN1_Type type_tag, |
274 | | ASN1_Class class_tag = ASN1_Class::ContextSpecific); |
275 | | |
276 | | /** |
277 | | * Encode an OCTET STRING or octet aligned BIT STRING with an IMPLICIT tagging |
278 | | * |
279 | | * @param v the contents of the object |
280 | | * @param len the length of v in bytes |
281 | | * @param real_type either ASN1_Type::OctetString or ASN1_Type::BitString |
282 | | * @param type_tag the type tag to encode with |
283 | | * @param class_tag the class tag to encode with |
284 | | */ |
285 | | DER_Encoder& encode(const uint8_t v[], |
286 | | size_t len, |
287 | | ASN1_Type real_type, |
288 | | ASN1_Type type_tag, |
289 | 0 | ASN1_Class class_tag = ASN1_Class::ContextSpecific) { |
290 | 0 | return encode(std::span{v, len}, real_type, type_tag, class_tag); |
291 | 0 | } |
292 | | |
293 | | /** |
294 | | * Encode a value unless it is equal to the DEFAULT |
295 | | * |
296 | | * @param value the value to encode |
297 | | * @param default_value the value which should be omitted |
298 | | */ |
299 | | template <typename T> |
300 | | BOTAN_DEPRECATED("Use the version that takes a std::optional") |
301 | | DER_Encoder& encode_optional(const T& value, const T& default_value) { |
302 | | if(value != default_value) { |
303 | | encode(value); |
304 | | } |
305 | | return (*this); |
306 | | } |
307 | | |
308 | | /** |
309 | | * Encode a value if it is set, otherwise write nothing |
310 | | * |
311 | | * @param value the value to encode |
312 | | */ |
313 | | template <typename T> |
314 | 0 | DER_Encoder& encode_optional(const std::optional<T>& value) { |
315 | 0 | if(value) { |
316 | 0 | encode(*value); |
317 | 0 | } |
318 | 0 | return (*this); |
319 | 0 | } Unexecuted instantiation: Botan::DER_Encoder& Botan::DER_Encoder::encode_optional<bool>(std::__1::optional<bool> const&) Unexecuted instantiation: Botan::DER_Encoder& Botan::DER_Encoder::encode_optional<unsigned long>(std::__1::optional<unsigned long> const&) |
320 | | |
321 | | /** |
322 | | * Encode each element of the vector in turn |
323 | | * |
324 | | * @param values the values to encode |
325 | | */ |
326 | | template <typename T> |
327 | 0 | DER_Encoder& encode_list(const std::vector<T>& values) { |
328 | 0 | for(size_t i = 0; i != values.size(); ++i) { |
329 | 0 | encode(values[i]); |
330 | 0 | } |
331 | 0 | return (*this); |
332 | 0 | } Unexecuted instantiation: Botan::DER_Encoder& Botan::DER_Encoder::encode_list<Botan::BigInt>(std::__1::vector<Botan::BigInt, std::__1::allocator<Botan::BigInt> > const&) Unexecuted instantiation: Botan::DER_Encoder& Botan::DER_Encoder::encode_list<Botan::OID>(std::__1::vector<Botan::OID, std::__1::allocator<Botan::OID> > const&) Unexecuted instantiation: Botan::DER_Encoder& Botan::DER_Encoder::encode_list<Botan::GeneralSubtree>(std::__1::vector<Botan::GeneralSubtree, std::__1::allocator<Botan::GeneralSubtree> > const&) Unexecuted instantiation: x509_ext.cpp:Botan::DER_Encoder& Botan::DER_Encoder::encode_list<Botan::Cert_Extension::(anonymous namespace)::Policy_Information>(std::__1::vector<Botan::Cert_Extension::(anonymous namespace)::Policy_Information, std::__1::allocator<Botan::Cert_Extension::(anonymous namespace)::Policy_Information> > const&) Unexecuted instantiation: Botan::DER_Encoder& Botan::DER_Encoder::encode_list<Botan::Cert_Extension::CRL_Distribution_Points::Distribution_Point>(std::__1::vector<Botan::Cert_Extension::CRL_Distribution_Points::Distribution_Point, std::__1::allocator<Botan::Cert_Extension::CRL_Distribution_Points::Distribution_Point> > const&) Unexecuted instantiation: Botan::DER_Encoder& Botan::DER_Encoder::encode_list<Botan::Cert_Extension::IPAddressBlocks::IPAddressFamily>(std::__1::vector<Botan::Cert_Extension::IPAddressBlocks::IPAddressFamily, std::__1::allocator<Botan::Cert_Extension::IPAddressBlocks::IPAddressFamily> > const&) Unexecuted instantiation: Botan::DER_Encoder& Botan::DER_Encoder::encode_list<Botan::Cert_Extension::IPAddressBlocks::IPAddressOrRange<(Botan::Cert_Extension::IPAddressBlocks::Version)4> >(std::__1::vector<Botan::Cert_Extension::IPAddressBlocks::IPAddressOrRange<(Botan::Cert_Extension::IPAddressBlocks::Version)4>, std::__1::allocator<Botan::Cert_Extension::IPAddressBlocks::IPAddressOrRange<(Botan::Cert_Extension::IPAddressBlocks::Version)4> > > const&) Unexecuted instantiation: Botan::DER_Encoder& Botan::DER_Encoder::encode_list<Botan::Cert_Extension::IPAddressBlocks::IPAddressOrRange<(Botan::Cert_Extension::IPAddressBlocks::Version)16> >(std::__1::vector<Botan::Cert_Extension::IPAddressBlocks::IPAddressOrRange<(Botan::Cert_Extension::IPAddressBlocks::Version)16>, std::__1::allocator<Botan::Cert_Extension::IPAddressBlocks::IPAddressOrRange<(Botan::Cert_Extension::IPAddressBlocks::Version)16> > > const&) Unexecuted instantiation: Botan::DER_Encoder& Botan::DER_Encoder::encode_list<Botan::Cert_Extension::ASBlocks::ASIdOrRange>(std::__1::vector<Botan::Cert_Extension::ASBlocks::ASIdOrRange, std::__1::allocator<Botan::Cert_Extension::ASBlocks::ASIdOrRange> > const&) Unexecuted instantiation: Botan::DER_Encoder& Botan::DER_Encoder::encode_list<Botan::X509_Certificate>(std::__1::vector<Botan::X509_Certificate, std::__1::allocator<Botan::X509_Certificate> > const&) |
333 | | |
334 | | /** |
335 | | * Request for an object to encode itself to this stream |
336 | | * |
337 | | * @param obj the object to encode |
338 | | */ |
339 | | DER_Encoder& encode(const ASN1_Object& obj); |
340 | | |
341 | | /** |
342 | | * Write the contents of another encoder to this stream if pred is true |
343 | | * |
344 | | * @param pred if false nothing is written |
345 | | * @param enc the encoder whose contents are written |
346 | | */ |
347 | 0 | DER_Encoder& encode_if(bool pred, DER_Encoder& enc) { |
348 | 0 | if(pred) { |
349 | 0 | return raw_bytes(enc.get_contents()); |
350 | 0 | } |
351 | 0 | return (*this); |
352 | 0 | } |
353 | | |
354 | | /** |
355 | | * Encode an object if pred is true |
356 | | * |
357 | | * @param pred if false nothing is written |
358 | | * @param obj the object to encode |
359 | | */ |
360 | 0 | DER_Encoder& encode_if(bool pred, const ASN1_Object& obj) { |
361 | 0 | if(pred) { |
362 | 0 | encode(obj); |
363 | 0 | } |
364 | 0 | return (*this); |
365 | 0 | } |
366 | | |
367 | | /** |
368 | | * Encode an INTEGER if pred is true |
369 | | * |
370 | | * @param pred if false nothing is written |
371 | | * @param num the value to encode |
372 | | */ |
373 | 0 | DER_Encoder& encode_if(bool pred, size_t num) { |
374 | 0 | if(pred) { |
375 | 0 | encode(num); |
376 | 0 | } |
377 | 0 | return (*this); |
378 | 0 | } |
379 | | |
380 | | /** |
381 | | * Encode a BOOLEAN if pred is true |
382 | | * |
383 | | * @param pred if false nothing is written |
384 | | * @param num the value to encode |
385 | | */ |
386 | 0 | DER_Encoder& encode_if(bool pred, bool num) { |
387 | 0 | if(pred) { |
388 | 0 | encode(num); |
389 | 0 | } |
390 | 0 | return (*this); |
391 | 0 | } |
392 | | |
393 | | /** |
394 | | * Write a tag and length header followed by the given contents |
395 | | * |
396 | | * @param type_tag the type tag to encode with |
397 | | * @param class_tag the class tag to encode with |
398 | | * @param rep the contents of the object |
399 | | * @param length the length of rep in bytes |
400 | | */ |
401 | | DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag, const uint8_t rep[], size_t length); |
402 | | |
403 | | /** |
404 | | * Write a tag and length header followed by the given contents |
405 | | * |
406 | | * @param type_tag the type tag to encode with |
407 | | * @param class_tag the class tag to encode with |
408 | | * @param rep the contents of the object |
409 | | */ |
410 | 250k | DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag, std::span<const uint8_t> rep) { |
411 | 250k | return add_object(type_tag, class_tag, rep.data(), rep.size()); |
412 | 250k | } |
413 | | |
414 | | /** |
415 | | * Write a tag and length header followed by the given contents |
416 | | * |
417 | | * @param type_tag the type tag to encode with |
418 | | * @param class_tag the class tag to encode with |
419 | | * @param rep the contents of the object |
420 | | */ |
421 | 224k | DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag, const std::vector<uint8_t>& rep) { |
422 | 224k | return add_object(type_tag, class_tag, std::span{rep}); |
423 | 224k | } |
424 | | |
425 | | /** |
426 | | * Write a tag and length header followed by the given contents |
427 | | * |
428 | | * @param type_tag the type tag to encode with |
429 | | * @param class_tag the class tag to encode with |
430 | | * @param rep the contents of the object |
431 | | */ |
432 | 17.2k | DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag, const secure_vector<uint8_t>& rep) { |
433 | 17.2k | return add_object(type_tag, class_tag, std::span{rep}); |
434 | 17.2k | } |
435 | | |
436 | | /** |
437 | | * Write a tag and length header followed by the given contents |
438 | | * |
439 | | * @param type_tag the type tag to encode with |
440 | | * @param class_tag the class tag to encode with |
441 | | * @param str the contents of the object |
442 | | */ |
443 | | DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag, std::string_view str); |
444 | | |
445 | | /** |
446 | | * Write a tag and length header followed by a single byte of contents |
447 | | * |
448 | | * @param type_tag the type tag to encode with |
449 | | * @param class_tag the class tag to encode with |
450 | | * @param val the contents of the object |
451 | | */ |
452 | | DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag, uint8_t val); |
453 | | |
454 | | /** |
455 | | * Encode `value` and emit just its body bytes under an IMPLICIT |
456 | | * `type_tag`/`class_tag` (e.g. for `[N] IMPLICIT OBJECT IDENTIFIER` where the |
457 | | * body is an OID's arc bytes but the tag must be `[N]`). The |
458 | | * primitive/constructed bit is copied from `value`. |
459 | | */ |
460 | | template <typename T> |
461 | | DER_Encoder& encode_implicit(const T& value, |
462 | | ASN1_Type type_tag, |
463 | 0 | ASN1_Class class_tag = ASN1_Class::ContextSpecific) { |
464 | 0 | std::vector<uint8_t> tlv; |
465 | 0 | DER_Encoder(tlv).encode(value); |
466 | 0 | return add_object_tlv(type_tag, class_tag, std::move(tlv)); |
467 | 0 | } Unexecuted instantiation: Botan::DER_Encoder& Botan::DER_Encoder::encode_implicit<Botan::AlternativeName>(Botan::AlternativeName const&, Botan::ASN1_Type, Botan::ASN1_Class) Unexecuted instantiation: Botan::DER_Encoder& Botan::DER_Encoder::encode_implicit<Botan::OID>(Botan::OID const&, Botan::ASN1_Type, Botan::ASN1_Class) |
468 | | |
469 | | private: |
470 | | DER_Encoder& add_object_tlv(ASN1_Type type_tag, ASN1_Class class_tag, std::vector<uint8_t> tlv); |
471 | | |
472 | | DER_Encoder& start_cons(ASN1_Type type_tag, ASN1_Class class_tag, bool sort_contents); |
473 | | |
474 | | class DER_Sequence final { |
475 | | public: |
476 | | uint32_t tag_of() const; |
477 | | |
478 | | void push_contents(DER_Encoder& der); |
479 | | |
480 | | void add_bytes(const uint8_t val[], size_t len); |
481 | | |
482 | | void add_bytes(const uint8_t hdr[], size_t hdr_len, const uint8_t val[], size_t val_len); |
483 | | |
484 | | DER_Sequence(ASN1_Type type_tag, ASN1_Class class_tag, bool sort_contents); |
485 | | |
486 | | DER_Sequence(DER_Sequence&& seq) noexcept : |
487 | 322k | m_type_tag(seq.m_type_tag), |
488 | 322k | m_class_tag(seq.m_class_tag), |
489 | 322k | m_sort_contents(seq.m_sort_contents), |
490 | 322k | m_contents(std::move(seq.m_contents)), |
491 | 322k | m_set_contents(std::move(seq.m_set_contents)) {} |
492 | | |
493 | 0 | DER_Sequence& operator=(DER_Sequence&& seq) noexcept { |
494 | 0 | std::swap(m_type_tag, seq.m_type_tag); |
495 | 0 | std::swap(m_class_tag, seq.m_class_tag); |
496 | 0 | std::swap(m_sort_contents, seq.m_sort_contents); |
497 | 0 | std::swap(m_contents, seq.m_contents); |
498 | 0 | std::swap(m_set_contents, seq.m_set_contents); |
499 | 0 | return (*this); |
500 | 0 | } |
501 | | |
502 | | DER_Sequence(const DER_Sequence& seq) = default; |
503 | | DER_Sequence& operator=(const DER_Sequence& seq) = default; |
504 | 458k | ~DER_Sequence() = default; |
505 | | |
506 | | private: |
507 | | ASN1_Type m_type_tag; |
508 | | ASN1_Class m_class_tag; |
509 | | bool m_sort_contents; |
510 | | secure_vector<uint8_t> m_contents; |
511 | | std::vector<secure_vector<uint8_t>> m_set_contents; |
512 | | }; |
513 | | |
514 | | append_fn m_append_output; |
515 | | secure_vector<uint8_t> m_default_outbuf; |
516 | | std::vector<DER_Sequence> m_subsequences; |
517 | | }; |
518 | | |
519 | | } // namespace Botan |
520 | | |
521 | | #endif |