Botan  2.7.0
Crypto and TLS for C++11
der_enc.cpp
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 #include <botan/der_enc.h>
9 #include <botan/asn1_obj.h>
10 #include <botan/bigint.h>
11 #include <botan/loadstor.h>
12 #include <botan/internal/bit_ops.h>
13 #include <algorithm>
14 
15 namespace Botan {
16 
17 namespace {
18 
19 /*
20 * DER encode an ASN.1 type tag
21 */
22 void encode_tag(std::vector<uint8_t>& encoded_tag,
23  ASN1_Tag type_tag, ASN1_Tag class_tag)
24  {
25  if((class_tag | 0xE0) != 0xE0)
26  throw Encoding_Error("DER_Encoder: Invalid class tag " +
27  std::to_string(class_tag));
28 
29  if(type_tag <= 30)
30  {
31  encoded_tag.push_back(static_cast<uint8_t>(type_tag | class_tag));
32  }
33  else
34  {
35  size_t blocks = high_bit(type_tag) + 6;
36  blocks = (blocks - (blocks % 7)) / 7;
37 
38  BOTAN_ASSERT_NOMSG(blocks > 0);
39 
40  encoded_tag.push_back(static_cast<uint8_t>(class_tag | 0x1F));
41  for(size_t i = 0; i != blocks - 1; ++i)
42  encoded_tag.push_back(0x80 | ((type_tag >> 7*(blocks-i-1)) & 0x7F));
43  encoded_tag.push_back(type_tag & 0x7F);
44  }
45  }
46 
47 /*
48 * DER encode an ASN.1 length field
49 */
50 void encode_length(std::vector<uint8_t>& encoded_length, size_t length)
51  {
52  if(length <= 127)
53  {
54  encoded_length.push_back(static_cast<uint8_t>(length));
55  }
56  else
57  {
58  const size_t bytes_needed = significant_bytes(length);
59 
60  encoded_length.push_back(static_cast<uint8_t>(0x80 | bytes_needed));
61 
62  for(size_t i = sizeof(length) - bytes_needed; i < sizeof(length); ++i)
63  encoded_length.push_back(get_byte(i, length));
64  }
65  }
66 
67 }
68 
70  {
71  m_append_output = [&vec](const uint8_t b[], size_t l)
72  {
73  vec.insert(vec.end(), b, b + l);
74  };
75  }
76 
77 DER_Encoder::DER_Encoder(std::vector<uint8_t>& vec)
78  {
79  m_append_output = [&vec](const uint8_t b[], size_t l)
80  {
81  vec.insert(vec.end(), b, b + l);
82  };
83  }
84 
85 /*
86 * Push the encoded SEQUENCE/SET to the encoder stream
87 */
88 void DER_Encoder::DER_Sequence::push_contents(DER_Encoder& der)
89  {
90  const ASN1_Tag real_class_tag = ASN1_Tag(m_class_tag | CONSTRUCTED);
91 
92  if(m_type_tag == SET)
93  {
94  std::sort(m_set_contents.begin(), m_set_contents.end());
95  for(size_t i = 0; i != m_set_contents.size(); ++i)
96  m_contents += m_set_contents[i];
97  m_set_contents.clear();
98  }
99 
100  der.add_object(m_type_tag, real_class_tag, m_contents.data(), m_contents.size());
101  m_contents.clear();
102  }
103 
104 /*
105 * Add an encoded value to the SEQUENCE/SET
106 */
107 void DER_Encoder::DER_Sequence::add_bytes(const uint8_t data[], size_t length)
108  {
109  if(m_type_tag == SET)
110  m_set_contents.push_back(secure_vector<uint8_t>(data, data + length));
111  else
112  m_contents += std::make_pair(data, length);
113  }
114 
115 void DER_Encoder::DER_Sequence::add_bytes(const uint8_t hdr[], size_t hdr_len,
116  const uint8_t val[], size_t val_len)
117  {
118  if(m_type_tag == SET)
119  {
120  secure_vector<uint8_t> m;
121  m.reserve(hdr_len + val_len);
122  m += std::make_pair(hdr, hdr_len);
123  m += std::make_pair(val, val_len);
124  m_set_contents.push_back(std::move(m));
125  }
126  else
127  {
128  m_contents += std::make_pair(hdr, hdr_len);
129  m_contents += std::make_pair(val, val_len);
130  }
131  }
132 
133 /*
134 * Return the type and class taggings
135 */
136 ASN1_Tag DER_Encoder::DER_Sequence::tag_of() const
137  {
138  return ASN1_Tag(m_type_tag | m_class_tag);
139  }
140 
141 /*
142 * DER_Sequence Constructor
143 */
144 DER_Encoder::DER_Sequence::DER_Sequence(ASN1_Tag t1, ASN1_Tag t2) :
145  m_type_tag(t1), m_class_tag(t2)
146  {
147  }
148 
149 /*
150 * Return the encoded contents
151 */
153  {
154  if(m_subsequences.size() != 0)
155  throw Invalid_State("DER_Encoder: Sequence hasn't been marked done");
156 
157  if(m_append_output)
158  throw Invalid_State("DER_Encoder Cannot get contents when using output vector");
159 
160  secure_vector<uint8_t> output;
161  std::swap(output, m_default_outbuf);
162  return output;
163  }
164 
166  {
167  if(m_subsequences.size() != 0)
168  throw Invalid_State("DER_Encoder: Sequence hasn't been marked done");
169 
170  if(m_append_output)
171  throw Invalid_State("DER_Encoder Cannot get contents when using output vector");
172 
173  std::vector<uint8_t> output(m_default_outbuf.begin(), m_default_outbuf.end());
174  m_default_outbuf.clear();
175  return output;
176  }
177 
178 /*
179 * Start a new ASN.1 SEQUENCE/SET/EXPLICIT
180 */
182  ASN1_Tag class_tag)
183  {
184  m_subsequences.push_back(DER_Sequence(type_tag, class_tag));
185  return (*this);
186  }
187 
188 /*
189 * Finish the current ASN.1 SEQUENCE/SET/EXPLICIT
190 */
192  {
193  if(m_subsequences.empty())
194  throw Invalid_State("DER_Encoder::end_cons: No such sequence");
195 
196  DER_Sequence last_seq = std::move(m_subsequences[m_subsequences.size()-1]);
197  m_subsequences.pop_back();
198  last_seq.push_contents(*this);
199 
200  return (*this);
201  }
202 
203 /*
204 * Start a new ASN.1 EXPLICIT encoding
205 */
207  {
208  ASN1_Tag type_tag = static_cast<ASN1_Tag>(type_no);
209 
210  // This would confuse DER_Sequence
211  if(type_tag == SET)
212  throw Internal_Error("DER_Encoder.start_explicit(SET) not supported");
213 
214  return start_cons(type_tag, CONTEXT_SPECIFIC);
215  }
216 
217 /*
218 * Finish the current ASN.1 EXPLICIT encoding
219 */
221  {
222  return end_cons();
223  }
224 
225 /*
226 * Write raw bytes into the stream
227 */
228 DER_Encoder& DER_Encoder::raw_bytes(const uint8_t bytes[], size_t length)
229  {
230  if(m_subsequences.size())
231  {
232  m_subsequences[m_subsequences.size()-1].add_bytes(bytes, length);
233  }
234  else if(m_append_output)
235  {
236  m_append_output(bytes, length);
237  }
238  else
239  {
240  m_default_outbuf += std::make_pair(bytes, length);
241  }
242 
243  return (*this);
244  }
245 
246 /*
247 * Write the encoding of the byte(s)
248 */
250  const uint8_t rep[], size_t length)
251  {
252  std::vector<uint8_t> hdr;
253  encode_tag(hdr, type_tag, class_tag);
254  encode_length(hdr, length);
255 
256  if(m_subsequences.size())
257  {
258  m_subsequences[m_subsequences.size()-1].add_bytes(hdr.data(), hdr.size(), rep, length);
259  }
260  else if(m_append_output)
261  {
262  m_append_output(hdr.data(), hdr.size());
263  m_append_output(rep, length);
264  }
265  else
266  {
267  m_default_outbuf += hdr;
268  m_default_outbuf += std::make_pair(rep, length);
269  }
270 
271  return (*this);
272  }
273 
274 /*
275 * Encode a NULL object
276 */
278  {
279  return add_object(NULL_TAG, UNIVERSAL, nullptr, 0);
280  }
281 
282 /*
283 * DER encode a BOOLEAN
284 */
286  {
287  return encode(is_true, BOOLEAN, UNIVERSAL);
288  }
289 
290 /*
291 * DER encode a small INTEGER
292 */
294  {
295  return encode(BigInt(n), INTEGER, UNIVERSAL);
296  }
297 
298 /*
299 * DER encode a small INTEGER
300 */
302  {
303  return encode(n, INTEGER, UNIVERSAL);
304  }
305 
306 /*
307 * Encode this object
308 */
309 DER_Encoder& DER_Encoder::encode(const uint8_t bytes[], size_t length,
310  ASN1_Tag real_type)
311  {
312  return encode(bytes, length, real_type, real_type, UNIVERSAL);
313  }
314 
315 /*
316 * DER encode a BOOLEAN
317 */
319  ASN1_Tag type_tag, ASN1_Tag class_tag)
320  {
321  uint8_t val = is_true ? 0xFF : 0x00;
322  return add_object(type_tag, class_tag, &val, 1);
323  }
324 
325 /*
326 * DER encode a small INTEGER
327 */
329  ASN1_Tag type_tag, ASN1_Tag class_tag)
330  {
331  return encode(BigInt(n), type_tag, class_tag);
332  }
333 
334 /*
335 * DER encode an INTEGER
336 */
338  ASN1_Tag type_tag, ASN1_Tag class_tag)
339  {
340  if(n == 0)
341  return add_object(type_tag, class_tag, 0);
342 
343  const size_t extra_zero = (n.bits() % 8 == 0) ? 1 : 0;
344  secure_vector<uint8_t> contents(extra_zero + n.bytes());
345  BigInt::encode(&contents[extra_zero], n);
346  if(n < 0)
347  {
348  for(size_t i = 0; i != contents.size(); ++i)
349  contents[i] = ~contents[i];
350  for(size_t i = contents.size(); i > 0; --i)
351  if(++contents[i-1])
352  break;
353  }
354 
355  return add_object(type_tag, class_tag, contents);
356  }
357 
358 /*
359 * DER encode an OCTET STRING or BIT STRING
360 */
361 DER_Encoder& DER_Encoder::encode(const uint8_t bytes[], size_t length,
362  ASN1_Tag real_type,
363  ASN1_Tag type_tag, ASN1_Tag class_tag)
364  {
365  if(real_type != OCTET_STRING && real_type != BIT_STRING)
366  throw Invalid_Argument("DER_Encoder: Invalid tag for byte/bit string");
367 
368  if(real_type == BIT_STRING)
369  {
370  secure_vector<uint8_t> encoded;
371  encoded.push_back(0);
372  encoded += std::make_pair(bytes, length);
373  return add_object(type_tag, class_tag, encoded);
374  }
375  else
376  return add_object(type_tag, class_tag, bytes, length);
377  }
378 
380  {
381  obj.encode_into(*this);
382  return (*this);
383  }
384 
385 /*
386 * Write the encoding of the byte(s)
387 */
389  const std::string& rep_str)
390  {
391  const uint8_t* rep = cast_char_ptr_to_uint8(rep_str.data());
392  const size_t rep_len = rep_str.size();
393  return add_object(type_tag, class_tag, rep, rep_len);
394  }
395 
396 /*
397 * Write the encoding of the byte
398 */
400  ASN1_Tag class_tag, uint8_t rep)
401  {
402  return add_object(type_tag, class_tag, &rep, 1);
403  }
404 
405 }
std::vector< uint8_t > get_contents_unlocked()
Definition: der_enc.cpp:165
DER_Encoder & add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, const uint8_t rep[], size_t length)
Definition: der_enc.cpp:249
size_t bits() const
Definition: bigint.cpp:228
DER_Encoder()=default
size_t significant_bytes(T n)
Definition: bit_ops.h:66
secure_vector< uint8_t > get_contents()
Definition: der_enc.cpp:152
const uint8_t * cast_char_ptr_to_uint8(const char *s)
Definition: mem_ops.h:131
#define BOTAN_ASSERT_NOMSG(expr)
Definition: assert.h:56
DER_Encoder & end_explicit()
Definition: der_enc.cpp:220
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:210
ASN1_Tag
Definition: asn1_obj.h:22
DER_Encoder & end_cons()
Definition: der_enc.cpp:191
DER_Encoder & raw_bytes(const uint8_t val[], size_t len)
Definition: der_enc.cpp:228
DER_Encoder & encode(bool b)
Definition: der_enc.cpp:285
DER_Encoder & encode_null()
Definition: der_enc.cpp:277
size_t high_bit(T n)
Definition: bit_ops.h:37
Definition: alg_id.cpp:13
size_t bytes() const
Definition: bigint.cpp:220
virtual void encode_into(DER_Encoder &to) const =0
DER_Encoder & start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition: der_enc.cpp:181
uint8_t get_byte(size_t byte_num, T input)
Definition: loadstor.h:39
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:88
static std::vector< uint8_t > encode(const BigInt &n, Base base=Binary)
Definition: big_code.cpp:54
DER_Encoder & start_explicit(uint16_t type_tag)
Definition: der_enc.cpp:206