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