Botan  1.10.9
der_enc.cpp
Go to the documentation of this file.
1 /*
2 * DER Encoder
3 * (C) 1999-2007 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7 
8 #include <botan/der_enc.h>
9 #include <botan/asn1_int.h>
10 #include <botan/bigint.h>
11 #include <botan/get_byte.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 SecureVector<byte> 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  to_string(class_tag));
28 
29  SecureVector<byte> encoded_tag;
30  if(type_tag <= 30)
31  encoded_tag.push_back(static_cast<byte>(type_tag | class_tag));
32  else
33  {
34  size_t blocks = high_bit(type_tag) + 6;
35  blocks = (blocks - (blocks % 7)) / 7;
36 
37  encoded_tag.push_back(class_tag | 0x1F);
38  for(size_t i = 0; i != blocks - 1; ++i)
39  encoded_tag.push_back(0x80 | ((type_tag >> 7*(blocks-i-1)) & 0x7F));
40  encoded_tag.push_back(type_tag & 0x7F);
41  }
42 
43  return encoded_tag;
44  }
45 
46 /*
47 * DER encode an ASN.1 length field
48 */
49 SecureVector<byte> encode_length(size_t length)
50  {
51  SecureVector<byte> encoded_length;
52  if(length <= 127)
53  encoded_length.push_back(static_cast<byte>(length));
54  else
55  {
56  const size_t top_byte = significant_bytes(length);
57 
58  encoded_length.push_back(static_cast<byte>(0x80 | top_byte));
59 
60  for(size_t i = sizeof(length) - top_byte; i != sizeof(length); ++i)
61  encoded_length.push_back(get_byte(i, length));
62  }
63  return encoded_length;
64  }
65 
66 }
67 
68 /*
69 * Return the encoded SEQUENCE/SET
70 */
71 SecureVector<byte> DER_Encoder::DER_Sequence::get_contents()
72  {
73  const ASN1_Tag real_class_tag = ASN1_Tag(class_tag | CONSTRUCTED);
74 
75  if(type_tag == SET)
76  {
77  std::sort(set_contents.begin(), set_contents.end());
78  for(size_t i = 0; i != set_contents.size(); ++i)
79  contents += set_contents[i];
80  set_contents.clear();
81  }
82 
83  SecureVector<byte> result;
84  result += encode_tag(type_tag, real_class_tag);
85  result += encode_length(contents.size());
86  result += contents;
87  contents.clear();
88 
89  return result;
90  }
91 
92 /*
93 * Add an encoded value to the SEQUENCE/SET
94 */
95 void DER_Encoder::DER_Sequence::add_bytes(const byte data[], size_t length)
96  {
97  if(type_tag == SET)
98  set_contents.push_back(SecureVector<byte>(data, length));
99  else
100  contents += std::make_pair(data, length);
101  }
102 
103 /*
104 * Return the type and class taggings
105 */
106 ASN1_Tag DER_Encoder::DER_Sequence::tag_of() const
107  {
108  return ASN1_Tag(type_tag | class_tag);
109  }
110 
111 /*
112 * DER_Sequence Constructor
113 */
114 DER_Encoder::DER_Sequence::DER_Sequence(ASN1_Tag t1, ASN1_Tag t2) :
115  type_tag(t1), class_tag(t2)
116  {
117  }
118 
119 /*
120 * Return the encoded contents
121 */
123  {
124  if(subsequences.size() != 0)
125  throw Invalid_State("DER_Encoder: Sequence hasn't been marked done");
126 
127  SecureVector<byte> output;
128  std::swap(output, contents);
129  return output;
130  }
131 
132 /*
133 * Start a new ASN.1 SEQUENCE/SET/EXPLICIT
134 */
136  ASN1_Tag class_tag)
137  {
138  subsequences.push_back(DER_Sequence(type_tag, class_tag));
139  return (*this);
140  }
141 
142 /*
143 * Finish the current ASN.1 SEQUENCE/SET/EXPLICIT
144 */
146  {
147  if(subsequences.empty())
148  throw Invalid_State("DER_Encoder::end_cons: No such sequence");
149 
150  SecureVector<byte> seq = subsequences[subsequences.size()-1].get_contents();
151  subsequences.pop_back();
152  raw_bytes(seq);
153  return (*this);
154  }
155 
156 /*
157 * Start a new ASN.1 EXPLICIT encoding
158 */
160  {
161  ASN1_Tag type_tag = static_cast<ASN1_Tag>(type_no);
162 
163  if(type_tag == SET)
164  throw Internal_Error("DER_Encoder.start_explicit(SET); cannot perform");
165 
166  return start_cons(type_tag, CONTEXT_SPECIFIC);
167  }
168 
169 /*
170 * Finish the current ASN.1 EXPLICIT encoding
171 */
173  {
174  return end_cons();
175  }
176 
177 /*
178 * Write raw bytes into the stream
179 */
181  {
182  return raw_bytes(&val[0], val.size());
183  }
184 
185 /*
186 * Write raw bytes into the stream
187 */
188 DER_Encoder& DER_Encoder::raw_bytes(const byte bytes[], size_t length)
189  {
190  if(subsequences.size())
191  subsequences[subsequences.size()-1].add_bytes(bytes, length);
192  else
193  contents += std::make_pair(bytes, length);
194 
195  return (*this);
196  }
197 
198 /*
199 * Encode a NULL object
200 */
202  {
203  return add_object(NULL_TAG, UNIVERSAL, 0, 0);
204  }
205 
206 /*
207 * DER encode a BOOLEAN
208 */
210  {
211  return encode(is_true, BOOLEAN, UNIVERSAL);
212  }
213 
214 /*
215 * DER encode a small INTEGER
216 */
218  {
219  return encode(BigInt(n), INTEGER, UNIVERSAL);
220  }
221 
222 /*
223 * DER encode a small INTEGER
224 */
226  {
227  return encode(n, INTEGER, UNIVERSAL);
228  }
229 
230 /*
231 * DER encode an OCTET STRING or BIT STRING
232 */
234  ASN1_Tag real_type)
235  {
236  return encode(&bytes[0], bytes.size(),
237  real_type, real_type, UNIVERSAL);
238  }
239 
240 /*
241 * Encode this object
242 */
243 DER_Encoder& DER_Encoder::encode(const byte bytes[], size_t length,
244  ASN1_Tag real_type)
245  {
246  return encode(bytes, length, real_type, real_type, UNIVERSAL);
247  }
248 
249 /*
250 * DER encode a BOOLEAN
251 */
253  ASN1_Tag type_tag, ASN1_Tag class_tag)
254  {
255  byte val = is_true ? 0xFF : 0x00;
256  return add_object(type_tag, class_tag, &val, 1);
257  }
258 
259 /*
260 * DER encode a small INTEGER
261 */
263  ASN1_Tag type_tag, ASN1_Tag class_tag)
264  {
265  return encode(BigInt(n), type_tag, class_tag);
266  }
267 
268 /*
269 * DER encode an INTEGER
270 */
272  ASN1_Tag type_tag, ASN1_Tag class_tag)
273  {
274  if(n == 0)
275  return add_object(type_tag, class_tag, 0);
276 
277  bool extra_zero = (n.bits() % 8 == 0);
278  SecureVector<byte> contents(extra_zero + n.bytes());
279  BigInt::encode(&contents[extra_zero], n);
280  if(n < 0)
281  {
282  for(size_t i = 0; i != contents.size(); ++i)
283  contents[i] = ~contents[i];
284  for(size_t i = contents.size(); i > 0; --i)
285  if(++contents[i-1])
286  break;
287  }
288 
289  return add_object(type_tag, class_tag, contents);
290  }
291 
292 /*
293 * DER encode an OCTET STRING or BIT STRING
294 */
296  ASN1_Tag real_type,
297  ASN1_Tag type_tag, ASN1_Tag class_tag)
298  {
299  return encode(&bytes[0], bytes.size(),
300  real_type, type_tag, class_tag);
301  }
302 
303 /*
304 * DER encode an OCTET STRING or BIT STRING
305 */
306 DER_Encoder& DER_Encoder::encode(const byte bytes[], size_t length,
307  ASN1_Tag real_type,
308  ASN1_Tag type_tag, ASN1_Tag class_tag)
309  {
310  if(real_type != OCTET_STRING && real_type != BIT_STRING)
311  throw Invalid_Argument("DER_Encoder: Invalid tag for byte/bit string");
312 
313  if(real_type == BIT_STRING)
314  {
315  SecureVector<byte> encoded;
316  encoded.push_back(0);
317  encoded += std::make_pair(bytes, length);
318  return add_object(type_tag, class_tag, encoded);
319  }
320  else
321  return add_object(type_tag, class_tag, bytes, length);
322  }
323 
324 /*
325 * Conditionally write some values to the stream
326 */
328  {
329  if(cond)
330  return raw_bytes(codec.get_contents());
331  return (*this);
332  }
333 
334 /*
335 * Request for an object to encode itself
336 */
338  {
339  obj.encode_into(*this);
340  return (*this);
341  }
342 
343 /*
344 * Write the encoding of the byte(s)
345 */
347  const byte rep[], size_t length)
348  {
349  SecureVector<byte> buffer;
350  buffer += encode_tag(type_tag, class_tag);
351  buffer += encode_length(length);
352  buffer += std::make_pair(rep, length);
353 
354  return raw_bytes(buffer);
355  }
356 
357 /*
358 * Write the encoding of the byte(s)
359 */
361  const MemoryRegion<byte>& rep_buf)
362  {
363  const byte* rep = &rep_buf[0];
364  const size_t rep_len = rep_buf.size();
365  return add_object(type_tag, class_tag, rep, rep_len);
366  }
367 
368 /*
369 * Write the encoding of the byte(s)
370 */
372  const std::string& rep_str)
373  {
374  const byte* rep = reinterpret_cast<const byte*>(rep_str.data());
375  const size_t rep_len = rep_str.size();
376  return add_object(type_tag, class_tag, rep, rep_len);
377  }
378 
379 /*
380 * Write the encoding of the byte
381 */
383  ASN1_Tag class_tag, byte rep)
384  {
385  return add_object(type_tag, class_tag, &rep, 1);
386  }
387 
388 }
SecureVector< byte > get_contents()
Definition: der_enc.cpp:122
BigInt n
Definition: numthry.cpp:26
DER_Encoder & raw_bytes(const byte val[], size_t len)
Definition: der_enc.cpp:188
size_t significant_bytes(T n)
Definition: bit_ops.h:62
void push_back(T x)
Definition: secmem.h:143
std::invalid_argument Invalid_Argument
Definition: exceptn.h:20
DER_Encoder & end_explicit()
Definition: der_enc.cpp:172
static SecureVector< byte > encode(const BigInt &n, Base base=Binary)
Definition: big_code.cpp:64
DER_Encoder & start_explicit(u16bit type_tag)
Definition: der_enc.cpp:159
byte get_byte(size_t byte_num, T input)
Definition: get_byte.h:21
DER_Encoder & end_cons()
Definition: der_enc.cpp:145
unsigned char byte
Definition: types.h:22
DER_Encoder & encode(bool b)
Definition: der_enc.cpp:209
size_t bits() const
Definition: bigint.cpp:253
ASN1_Tag
Definition: asn1_int.h:19
unsigned short u16bit
Definition: types.h:27
DER_Encoder & encode_null()
Definition: der_enc.cpp:201
size_t high_bit(T n)
Definition: bit_ops.h:33
size_t size() const
Definition: secmem.h:29
DER_Encoder & encode_if(bool pred, DER_Encoder &enc)
Definition: der_enc.cpp:327
DER_Encoder & start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition: der_enc.cpp:135
std::string to_string(u64bit n, size_t min_len)
Definition: parsing.cpp:42
void swap(Botan::MemoryRegion< T > &x, Botan::MemoryRegion< T > &y)
Definition: secmem.h:425
virtual void encode_into(class DER_Encoder &to) const =0
DER_Encoder & add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, const byte rep[], size_t length)
Definition: der_enc.cpp:346
size_t bytes() const
Definition: bigint.cpp:245