monotone

monotone Mtn Source Tree

Root/botan/der_enc.cpp

1/*************************************************
2* DER Encoder Source File *
3* (C) 1999-2007 The Botan Project *
4*************************************************/
5
6#include <botan/der_enc.h>
7#include <botan/asn1_int.h>
8#include <botan/bigint.h>
9#include <botan/loadstor.h>
10#include <botan/bit_ops.h>
11#include <botan/parsing.h>
12#include <algorithm>
13
14namespace Botan {
15
16namespace {
17
18/*************************************************
19* DER encode an ASN.1 type tag *
20*************************************************/
21SecureVector<byte> encode_tag(ASN1_Tag type_tag, ASN1_Tag class_tag)
22 {
23 if((class_tag | 0xE0) != 0xE0)
24 throw Encoding_Error("DER_Encoder: Invalid class tag " +
25 to_string(class_tag));
26
27 SecureVector<byte> encoded_tag;
28 if(type_tag <= 30)
29 encoded_tag.append(static_cast<byte>(type_tag | class_tag));
30 else
31 {
32 u32bit blocks = high_bit(type_tag) + 6;
33 blocks = (blocks - (blocks % 7)) / 7;
34
35 encoded_tag.append(class_tag | 0x1F);
36 for(u32bit k = 0; k != blocks - 1; ++k)
37 encoded_tag.append(0x80 | ((type_tag >> 7*(blocks-k-1)) & 0x7F));
38 encoded_tag.append(type_tag & 0x7F);
39 }
40
41 return encoded_tag;
42 }
43
44/*************************************************
45* DER encode an ASN.1 length field *
46*************************************************/
47SecureVector<byte> encode_length(u32bit length)
48 {
49 SecureVector<byte> encoded_length;
50 if(length <= 127)
51 encoded_length.append(static_cast<byte>(length));
52 else
53 {
54 const u32bit top_byte = significant_bytes(length);
55 encoded_length.append(static_cast<byte>(0x80 | top_byte));
56 for(u32bit j = 4-top_byte; j != 4; ++j)
57 encoded_length.append(get_byte(j, length));
58 }
59 return encoded_length;
60 }
61
62}
63
64/*************************************************
65* Return the encoded SEQUENCE/SET *
66*************************************************/
67SecureVector<byte> DER_Encoder::DER_Sequence::get_contents()
68 {
69 const ASN1_Tag real_class_tag = ASN1_Tag(class_tag | CONSTRUCTED);
70
71 SecureVector<byte> encoded_tag = encode_tag(type_tag, real_class_tag);
72
73 if(type_tag == SET)
74 {
75 std::sort(set_contents.begin(), set_contents.end());
76 for(u32bit j = 0; j != set_contents.size(); ++j)
77 contents.append(set_contents[j]);
78 set_contents.clear();
79 }
80
81 SecureVector<byte> encoded_length = encode_length(contents.size());
82
83 SecureVector<byte> retval;
84 retval.append(encoded_tag);
85 retval.append(encoded_length);
86 retval.append(contents);
87 contents.destroy();
88 return retval;
89 }
90
91/*************************************************
92* Add an encoded value to the SEQUENCE/SET *
93*************************************************/
94void DER_Encoder::DER_Sequence::add_bytes(const byte data[], u32bit length)
95 {
96 if(type_tag == SET)
97 set_contents.push_back(SecureVector<byte>(data, length));
98 else
99 contents.append(data, length);
100 }
101
102/*************************************************
103* Return the type and class taggings *
104*************************************************/
105ASN1_Tag DER_Encoder::DER_Sequence::tag_of() const
106 {
107 return ASN1_Tag(type_tag | class_tag);
108 }
109
110/*************************************************
111* DER_Sequence Constructor *
112*************************************************/
113DER_Encoder::DER_Sequence::DER_Sequence(ASN1_Tag t1, ASN1_Tag t2) :
114 type_tag(t1), class_tag(t2)
115 {
116 }
117
118/*************************************************
119* Return the encoded contents *
120*************************************************/
121SecureVector<byte> DER_Encoder::get_contents()
122 {
123 if(subsequences.size() != 0)
124 throw Invalid_State("DER_Encoder: Sequence hasn't been marked done");
125
126 SecureVector<byte> retval;
127 retval = contents;
128 contents.destroy();
129 return retval;
130 }
131
132/*************************************************
133* Start a new ASN.1 SEQUENCE/SET/EXPLICIT *
134*************************************************/
135DER_Encoder& DER_Encoder::start_cons(ASN1_Tag type_tag,
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*************************************************/
145DER_Encoder& DER_Encoder::end_cons()
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*************************************************/
159DER_Encoder& DER_Encoder::start_explicit(u16bit type_no)
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*************************************************/
172DER_Encoder& DER_Encoder::end_explicit()
173 {
174 return end_cons();
175 }
176
177/*************************************************
178* Write raw bytes into the stream *
179*************************************************/
180DER_Encoder& DER_Encoder::raw_bytes(const MemoryRegion<byte>& val)
181 {
182 return raw_bytes(val.begin(), val.size());
183 }
184
185/*************************************************
186* Write raw bytes into the stream *
187*************************************************/
188DER_Encoder& DER_Encoder::raw_bytes(const byte bytes[], u32bit length)
189 {
190 if(subsequences.size())
191 subsequences[subsequences.size()-1].add_bytes(bytes, length);
192 else
193 contents.append(bytes, length);
194
195 return (*this);
196 }
197
198/*************************************************
199* Encode a NULL object *
200*************************************************/
201DER_Encoder& DER_Encoder::encode_null()
202 {
203 return add_object(NULL_TAG, UNIVERSAL, 0, 0);
204 }
205
206/*************************************************
207* DER encode a BOOLEAN *
208*************************************************/
209DER_Encoder& DER_Encoder::encode(bool is_true)
210 {
211 return encode(is_true, BOOLEAN, UNIVERSAL);
212 }
213
214/*************************************************
215* DER encode a small INTEGER *
216*************************************************/
217DER_Encoder& DER_Encoder::encode(u32bit n)
218 {
219 return encode(BigInt(n), INTEGER, UNIVERSAL);
220 }
221
222/*************************************************
223* DER encode a small INTEGER *
224*************************************************/
225DER_Encoder& DER_Encoder::encode(const BigInt& n)
226 {
227 return encode(n, INTEGER, UNIVERSAL);
228 }
229
230/*************************************************
231* DER encode an OCTET STRING or BIT STRING *
232*************************************************/
233DER_Encoder& DER_Encoder::encode(const MemoryRegion<byte>& bytes,
234 ASN1_Tag real_type)
235 {
236 return encode(bytes.begin(), bytes.size(),
237 real_type, real_type, UNIVERSAL);
238 }
239
240/*************************************************
241* Encode this object *
242*************************************************/
243DER_Encoder& DER_Encoder::encode(const byte bytes[], u32bit 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*************************************************/
252DER_Encoder& DER_Encoder::encode(bool is_true,
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*************************************************/
262DER_Encoder& DER_Encoder::encode(u32bit n,
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*************************************************/
271DER_Encoder& DER_Encoder::encode(const BigInt& n,
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.begin() + extra_zero, n);
280 if(n < 0)
281 {
282 for(u32bit j = 0; j != contents.size(); ++j)
283 contents[j] = ~contents[j];
284 for(u32bit j = contents.size(); j > 0; --j)
285 if(++contents[j-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*************************************************/
295DER_Encoder& DER_Encoder::encode(const MemoryRegion<byte>& bytes,
296 ASN1_Tag real_type,
297 ASN1_Tag type_tag, ASN1_Tag class_tag)
298 {
299 return encode(bytes.begin(), bytes.size(),
300 real_type, type_tag, class_tag);
301 }
302
303/*************************************************
304* DER encode an OCTET STRING or BIT STRING *
305*************************************************/
306DER_Encoder& DER_Encoder::encode(const byte bytes[], u32bit 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.append(0);
317 encoded.append(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*************************************************/
327DER_Encoder& DER_Encoder::encode_if(bool cond, DER_Encoder& codec)
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*************************************************/
337DER_Encoder& DER_Encoder::encode(const ASN1_Object& obj)
338 {
339 obj.encode_into(*this);
340 return (*this);
341 }
342
343/*************************************************
344* Write the encoding of the byte(s) *
345*************************************************/
346DER_Encoder& DER_Encoder::add_object(ASN1_Tag type_tag, ASN1_Tag class_tag,
347 const byte rep[], u32bit length)
348 {
349 SecureVector<byte> encoded_tag = encode_tag(type_tag, class_tag);
350 SecureVector<byte> encoded_length = encode_length(length);
351
352 SecureVector<byte> buffer;
353 buffer.append(encoded_tag);
354 buffer.append(encoded_length);
355 buffer.append(rep, length);
356
357 return raw_bytes(buffer);
358 }
359
360/*************************************************
361* Write the encoding of the byte(s) *
362*************************************************/
363DER_Encoder& DER_Encoder::add_object(ASN1_Tag type_tag, ASN1_Tag class_tag,
364 const MemoryRegion<byte>& rep_buf)
365 {
366 const byte* rep = rep_buf.begin();
367 const u32bit rep_len = rep_buf.size();
368 return add_object(type_tag, class_tag, rep, rep_len);
369 }
370
371/*************************************************
372* Write the encoding of the byte(s) *
373*************************************************/
374DER_Encoder& DER_Encoder::add_object(ASN1_Tag type_tag, ASN1_Tag class_tag,
375 const std::string& rep_str)
376 {
377 const byte* rep = reinterpret_cast<const byte*>(rep_str.data());
378 const u32bit rep_len = rep_str.size();
379 return add_object(type_tag, class_tag, rep, rep_len);
380 }
381
382/*************************************************
383* Write the encoding of the byte *
384*************************************************/
385DER_Encoder& DER_Encoder::add_object(ASN1_Tag type_tag,
386 ASN1_Tag class_tag, byte rep)
387 {
388 return add_object(type_tag, class_tag, &rep, 1);
389 }
390
391}

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status