Botan 3.9.0
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 <functional>
13#include <optional>
14#include <vector>
15
16namespace Botan {
17
18class BigInt;
19
20/**
21* General DER Encoding Object
22*/
23class BOTAN_PUBLIC_API(2, 0) DER_Encoder final {
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 BOTAN_FUTURE_EXPLICIT 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 BOTAN_FUTURE_EXPLICIT DER_Encoder(append_fn append) : m_append_output(std::move(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") std::vector<uint8_t> get_contents_unlocked();
62
63 DER_Encoder& start_cons(ASN1_Type type_tag, ASN1_Class class_tag);
64
66
68
72
76
77 DER_Encoder& end_cons();
78
79 DER_Encoder& start_explicit(uint16_t type_tag);
80 DER_Encoder& end_explicit();
81
82 /**
83 * Insert raw bytes directly into the output stream
84 */
85 DER_Encoder& raw_bytes(const uint8_t val[], size_t len);
86
87 template <typename Alloc>
88 DER_Encoder& raw_bytes(const std::vector<uint8_t, Alloc>& val) {
89 return raw_bytes(val.data(), val.size());
90 }
91
92 DER_Encoder& encode_null();
93 DER_Encoder& encode(bool b);
94 DER_Encoder& encode(size_t s);
95 DER_Encoder& encode(const BigInt& n);
96 DER_Encoder& encode(const uint8_t val[], size_t len, ASN1_Type real_type);
97
98 template <typename Alloc>
99 DER_Encoder& encode(const std::vector<uint8_t, Alloc>& vec, ASN1_Type real_type) {
100 return encode(vec.data(), vec.size(), real_type);
101 }
102
103 DER_Encoder& encode(bool b, ASN1_Type type_tag, ASN1_Class class_tag = ASN1_Class::ContextSpecific);
104
105 DER_Encoder& encode(size_t s, ASN1_Type type_tag, ASN1_Class class_tag = ASN1_Class::ContextSpecific);
106
107 DER_Encoder& encode(const BigInt& n, ASN1_Type type_tag, ASN1_Class class_tag = ASN1_Class::ContextSpecific);
108
109 DER_Encoder& encode(const uint8_t v[],
110 size_t len,
111 ASN1_Type real_type,
112 ASN1_Type type_tag,
114
115 template <typename Alloc>
116 DER_Encoder& encode(const std::vector<uint8_t, Alloc>& bytes,
117 ASN1_Type real_type,
118 ASN1_Type type_tag,
119 ASN1_Class class_tag) {
120 return encode(bytes.data(), bytes.size(), real_type, type_tag, class_tag);
121 }
122
123 template <typename T>
124 BOTAN_DEPRECATED("Use the version that takes a std::optional")
125 DER_Encoder& encode_optional(const T& value, const T& default_value) {
126 if(value != default_value) {
127 encode(value);
128 }
129 return (*this);
130 }
131
132 template <typename T>
133 DER_Encoder& encode_optional(const std::optional<T>& value) {
134 if(value) {
135 encode(*value);
136 }
137 return (*this);
138 }
139
140 template <typename T>
141 DER_Encoder& encode_list(const std::vector<T>& values) {
142 for(size_t i = 0; i != values.size(); ++i) {
143 encode(values[i]);
144 }
145 return (*this);
146 }
147
148 /*
149 * Request for an object to encode itself to this stream
150 */
151 DER_Encoder& encode(const ASN1_Object& obj);
152
153 /*
154 * Conditionally write some values to the stream
155 */
157 if(pred) {
158 return raw_bytes(enc.get_contents());
159 }
160 return (*this);
161 }
162
163 DER_Encoder& encode_if(bool pred, const ASN1_Object& obj) {
164 if(pred) {
165 encode(obj);
166 }
167 return (*this);
168 }
169
170 DER_Encoder& encode_if(bool pred, size_t num) {
171 if(pred) {
172 encode(num);
173 }
174 return (*this);
175 }
176
177 DER_Encoder& encode_if(bool pred, bool num) {
178 if(pred) {
179 encode(num);
180 }
181 return (*this);
182 }
183
184 DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag, const uint8_t rep[], size_t length);
185
186 DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag, std::span<const uint8_t> rep) {
187 return add_object(type_tag, class_tag, rep.data(), rep.size());
188 }
189
190 DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag, const std::vector<uint8_t>& rep) {
191 return add_object(type_tag, class_tag, std::span{rep});
192 }
193
195 return add_object(type_tag, class_tag, std::span{rep});
196 }
197
198 DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag, std::string_view str);
199
200 DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag, uint8_t val);
201
202 private:
203 class DER_Sequence final {
204 public:
205 uint32_t tag_of() const;
206
207 void push_contents(DER_Encoder& der);
208
209 void add_bytes(const uint8_t val[], size_t len);
210
211 void add_bytes(const uint8_t hdr[], size_t hdr_len, const uint8_t val[], size_t val_len);
212
213 DER_Sequence(ASN1_Type type_tag, ASN1_Class class_tag);
214
215 DER_Sequence(DER_Sequence&& seq) noexcept :
216 m_type_tag(seq.m_type_tag),
217 m_class_tag(seq.m_class_tag),
218 m_contents(std::move(seq.m_contents)),
219 m_set_contents(std::move(seq.m_set_contents)) {}
220
221 DER_Sequence& operator=(DER_Sequence&& seq) noexcept {
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 DER_Sequence& operator=(const DER_Sequence& seq) = default;
231 ~DER_Sequence() = 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} // namespace Botan
246
247#endif
#define BOTAN_PUBLIC_API(maj, min)
Definition api.h:21
#define BOTAN_DEPRECATED(msg)
Definition api.h:73
#define BOTAN_FUTURE_EXPLICIT
Definition api.h:52
DER_Encoder & add_object(ASN1_Type type_tag, ASN1_Class class_tag, const uint8_t rep[], size_t length)
Definition der_enc.cpp:224
DER_Encoder & start_set()
Definition der_enc.h:67
DER_Encoder & encode_if(bool pred, bool num)
Definition der_enc.h:177
DER_Encoder & add_object(ASN1_Type type_tag, ASN1_Class class_tag, const std::vector< uint8_t > &rep)
Definition der_enc.h:190
DER_Encoder & raw_bytes(const std::vector< uint8_t, Alloc > &val)
Definition der_enc.h:88
DER_Encoder & encode_optional(const T &value, const T &default_value)
Definition der_enc.h:125
DER_Encoder & encode_list(const std::vector< T > &values)
Definition der_enc.h:141
DER_Encoder & add_object(ASN1_Type type_tag, ASN1_Class class_tag, std::span< const uint8_t > rep)
Definition der_enc.h:186
DER_Encoder & encode_if(bool pred, const ASN1_Object &obj)
Definition der_enc.h:163
DER_Encoder & encode(const std::vector< uint8_t, Alloc > &vec, ASN1_Type real_type)
Definition der_enc.h:99
DER_Encoder & start_explicit_context_specific(uint32_t tag)
Definition der_enc.h:73
DER_Encoder & start_context_specific(uint32_t tag)
Definition der_enc.h:69
DER_Encoder & encode_optional(const std::optional< T > &value)
Definition der_enc.h:133
DER_Encoder & add_object(ASN1_Type type_tag, ASN1_Class class_tag, const secure_vector< uint8_t > &rep)
Definition der_enc.h:194
DER_Encoder & start_sequence()
Definition der_enc.h:65
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:116
DER_Encoder & encode_if(bool pred, DER_Encoder &enc)
Definition der_enc.h:156
DER_Encoder & start_cons(ASN1_Type type_tag, ASN1_Class class_tag)
Definition der_enc.cpp:165
DER_Encoder & raw_bytes(const uint8_t val[], size_t len)
Definition der_enc.cpp:209
DER_Encoder & encode_if(bool pred, size_t num)
Definition der_enc.h:170
BOTAN_FUTURE_EXPLICIT DER_Encoder(append_fn append)
Definition der_enc.h:50
DER_Encoder & encode(bool b)
Definition der_enc.cpp:252
DER_Encoder()=default
std::function< void(const uint8_t[], size_t)> append_fn
Definition der_enc.h:25
ASN1_Class
Definition asn1_obj.h:28
ASN1_Type
Definition asn1_obj.h:43
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:69