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