Botan 3.6.1
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 <vector>
14
15namespace Botan {
16
17class BigInt;
18
19/**
20* General DER Encoding Object
21*/
23 public:
24 typedef std::function<void(const uint8_t[], size_t)> append_fn;
25
26 /**
27 * DER encode, writing to an internal buffer
28 * Use get_contents or get_contents_unlocked to read the results
29 * after all encoding is completed.
30 */
31 DER_Encoder() = default;
32
33 /**
34 * DER encode, writing to @param vec
35 * If this constructor is used, get_contents* may not be called.
36 */
38
39 /**
40 * DER encode, writing to @param vec
41 * If this constructor is used, get_contents* may not be called.
42 */
43 DER_Encoder(std::vector<uint8_t>& vec);
44
45 /**
46 * DER encode, calling append to write output
47 * If this constructor is used, get_contents* may not be called.
48 */
49 DER_Encoder(append_fn append) : m_append_output(std::move(append)) {}
50
51 secure_vector<uint8_t> get_contents();
52
53 /**
54 * Return the encoded contents as a std::vector
55 *
56 * If using this function, instead pass a std::vector to the
57 * contructor of DER_Encoder where the output will be placed. This
58 * avoids several unecessary copies.
59 */
60 BOTAN_DEPRECATED("Use DER_Encoder(vector) instead") std::vector<uint8_t> get_contents_unlocked();
61
62 DER_Encoder& start_cons(ASN1_Type type_tag, ASN1_Class class_tag);
63
64 DER_Encoder& start_sequence() { return start_cons(ASN1_Type::Sequence, ASN1_Class::Universal); }
65
66 DER_Encoder& start_set() { return start_cons(ASN1_Type::Set, ASN1_Class::Universal); }
67
69 return start_cons(ASN1_Type(tag), ASN1_Class::ContextSpecific);
70 }
71
73 return start_cons(ASN1_Type(tag), ASN1_Class::ExplicitContextSpecific);
74 }
75
76 DER_Encoder& end_cons();
77
78 DER_Encoder& start_explicit(uint16_t type_tag);
79 DER_Encoder& end_explicit();
80
81 /**
82 * Insert raw bytes directly into the output stream
83 */
84 DER_Encoder& raw_bytes(const uint8_t val[], size_t len);
85
86 template <typename Alloc>
87 DER_Encoder& raw_bytes(const std::vector<uint8_t, Alloc>& val) {
88 return raw_bytes(val.data(), val.size());
89 }
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,
112 ASN1_Class class_tag = ASN1_Class::ContextSpecific);
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 DER_Encoder& encode_optional(const T& value, const T& default_value) {
124 if(value != default_value) {
125 encode(value);
126 }
127 return (*this);
128 }
129
130 template <typename T>
131 DER_Encoder& encode_list(const std::vector<T>& values) {
132 for(size_t i = 0; i != values.size(); ++i) {
133 encode(values[i]);
134 }
135 return (*this);
136 }
137
138 /*
139 * Request for an object to encode itself to this stream
140 */
141 DER_Encoder& encode(const ASN1_Object& obj);
142
143 /*
144 * Conditionally write some values to the stream
145 */
147 if(pred) {
148 return raw_bytes(enc.get_contents());
149 }
150 return (*this);
151 }
152
153 DER_Encoder& encode_if(bool pred, const ASN1_Object& obj) {
154 if(pred) {
155 encode(obj);
156 }
157 return (*this);
158 }
159
160 DER_Encoder& encode_if(bool pred, size_t num) {
161 if(pred) {
162 encode(num);
163 }
164 return (*this);
165 }
166
167 DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag, const uint8_t rep[], size_t length);
168
169 DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag, const std::vector<uint8_t>& rep) {
170 return add_object(type_tag, class_tag, rep.data(), rep.size());
171 }
172
174 return add_object(type_tag, class_tag, rep.data(), rep.size());
175 }
176
177 DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag, std::string_view str);
178
179 DER_Encoder& add_object(ASN1_Type type_tag, ASN1_Class class_tag, uint8_t val);
180
181 private:
182 class DER_Sequence final {
183 public:
184 uint32_t tag_of() const;
185
186 void push_contents(DER_Encoder& der);
187
188 void add_bytes(const uint8_t val[], size_t len);
189
190 void add_bytes(const uint8_t hdr[], size_t hdr_len, const uint8_t val[], size_t val_len);
191
192 DER_Sequence(ASN1_Type, ASN1_Class);
193
194 DER_Sequence(DER_Sequence&& seq) noexcept :
195 m_type_tag(std::move(seq.m_type_tag)),
196 m_class_tag(std::move(seq.m_class_tag)),
197 m_contents(std::move(seq.m_contents)),
198 m_set_contents(std::move(seq.m_set_contents)) {}
199
200 DER_Sequence& operator=(DER_Sequence&& seq) noexcept {
201 std::swap(m_type_tag, seq.m_type_tag);
202 std::swap(m_class_tag, seq.m_class_tag);
203 std::swap(m_contents, seq.m_contents);
204 std::swap(m_set_contents, seq.m_set_contents);
205 return (*this);
206 }
207
208 DER_Sequence(const DER_Sequence& seq) = default;
209
210 DER_Sequence& operator=(const DER_Sequence& seq) = default;
211
212 private:
213 ASN1_Type m_type_tag;
214 ASN1_Class m_class_tag;
215 secure_vector<uint8_t> m_contents;
216 std::vector<secure_vector<uint8_t>> m_set_contents;
217 };
218
219 append_fn m_append_output;
220 secure_vector<uint8_t> m_default_outbuf;
221 std::vector<DER_Sequence> m_subsequences;
222};
223
224} // namespace Botan
225
226#endif
secure_vector< uint8_t > get_contents()
Definition der_enc.cpp:132
DER_Encoder & start_set()
Definition der_enc.h:66
DER_Encoder & add_object(ASN1_Type type_tag, ASN1_Class class_tag, const std::vector< uint8_t > &rep)
Definition der_enc.h:169
DER_Encoder & raw_bytes(const std::vector< uint8_t, Alloc > &val)
Definition der_enc.h:87
DER_Encoder & encode_optional(const T &value, const T &default_value)
Definition der_enc.h:123
DER_Encoder & encode_list(const std::vector< T > &values)
Definition der_enc.h:131
std::function< void(const uint8_t[], size_t)> append_fn
Definition der_enc.h:24
DER_Encoder & encode_if(bool pred, const ASN1_Object &obj)
Definition der_enc.h:153
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:72
DER_Encoder & start_context_specific(uint32_t tag)
Definition der_enc.h:68
DER_Encoder & add_object(ASN1_Type type_tag, ASN1_Class class_tag, const secure_vector< uint8_t > &rep)
Definition der_enc.h:173
DER_Encoder(append_fn append)
Definition der_enc.h:49
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:146
DER_Encoder & encode_if(bool pred, size_t num)
Definition der_enc.h:160
DER_Encoder()=default
int(* final)(unsigned char *, CTX *)
#define BOTAN_PUBLIC_API(maj, min)
Definition compiler.h:31
#define BOTAN_DEPRECATED(msg)
Definition compiler.h:125
FE_25519 T
Definition ge.cpp:34
ASN1_Class
Definition asn1_obj.h:29
ASN1_Type
Definition asn1_obj.h:44
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:61