monotone

monotone Mtn Source Tree

Root/botan/ber_dec.cpp

1/*************************************************
2* BER Decoder Source File *
3* (C) 1999-2006 The Botan Project *
4*************************************************/
5
6#include <botan/ber_dec.h>
7#include <botan/bigint.h>
8#include <botan/bit_ops.h>
9
10namespace Botan {
11
12namespace {
13
14/*************************************************
15* BER decode an ASN.1 type tag *
16*************************************************/
17u32bit decode_tag(DataSource* ber, ASN1_Tag& type_tag, ASN1_Tag& class_tag)
18 {
19 byte b;
20 if(!ber->read_byte(b))
21 {
22 class_tag = type_tag = NO_OBJECT;
23 return 0;
24 }
25
26 if((b & 0x1F) != 0x1F)
27 {
28 type_tag = ASN1_Tag(b & 0x1F);
29 class_tag = ASN1_Tag(b & 0xE0);
30 return 1;
31 }
32
33 u32bit tag_bytes = 1;
34 class_tag = ASN1_Tag(b & 0xE0);
35
36 u32bit tag_buf = 0;
37 while(true)
38 {
39 if(!ber->read_byte(b))
40 throw BER_Decoding_Error("Long-form tag truncated");
41 if(tag_buf & 0xFF000000)
42 throw BER_Decoding_Error("Long-form tag overflowed 32 bits");
43 ++tag_bytes;
44 tag_buf = (tag_buf << 7) | (b & 0x7F);
45 if((b & 0x80) == 0) break;
46 }
47 type_tag = ASN1_Tag(tag_buf);
48 return tag_bytes;
49 }
50
51/*************************************************
52* Find the EOC marker *
53*************************************************/
54u32bit find_eoc(DataSource*);
55
56/*************************************************
57* BER decode an ASN.1 length field *
58*************************************************/
59u32bit decode_length(DataSource* ber, u32bit& field_size)
60 {
61 byte b;
62 if(!ber->read_byte(b))
63 throw BER_Decoding_Error("Length field not found");
64 field_size = 1;
65 if((b & 0x80) == 0)
66 return b;
67
68 field_size += (b & 0x7F);
69 if(field_size == 1) return find_eoc(ber);
70 if(field_size > 5)
71 throw BER_Decoding_Error("Length field is too large");
72
73 u32bit length = 0;
74
75 for(u32bit j = 0; j != field_size - 1; ++j)
76 {
77 if(get_byte(0, length) != 0)
78 throw BER_Decoding_Error("Field length overflow");
79 if(!ber->read_byte(b))
80 throw BER_Decoding_Error("Corrupted length field");
81 length = (length << 8) | b;
82 }
83 return length;
84 }
85
86/*************************************************
87* BER decode an ASN.1 length field *
88*************************************************/
89u32bit decode_length(DataSource* ber)
90 {
91 u32bit dummy;
92 return decode_length(ber, dummy);
93 }
94
95/*************************************************
96* Find the EOC marker *
97*************************************************/
98u32bit find_eoc(DataSource* ber)
99 {
100 SecureVector<byte> buffer(DEFAULT_BUFFERSIZE), data;
101
102 while(true)
103 {
104 const u32bit got = ber->peek(buffer, buffer.size(), data.size());
105 if(got == 0)
106 break;
107 data.append(buffer, got);
108 }
109
110 DataSource_Memory source(data);
111 data.destroy();
112
113 u32bit length = 0;
114 while(true)
115 {
116 ASN1_Tag type_tag, class_tag;
117 u32bit tag_size = decode_tag(&source, type_tag, class_tag);
118 if(type_tag == NO_OBJECT)
119 break;
120
121 u32bit length_size = 0;
122 u32bit item_size = decode_length(&source, length_size);
123 source.discard_next(item_size);
124
125 length += item_size + length_size + tag_size;
126
127 if(type_tag == EOC)
128 break;
129 }
130 return length;
131 }
132
133}
134
135/*************************************************
136* Check a type invariant on BER data *
137*************************************************/
138void BER_Object::assert_is_a(ASN1_Tag type_tag, ASN1_Tag class_tag)
139 {
140 if(this->type_tag != type_tag || this->class_tag != class_tag)
141 throw BER_Decoding_Error("Tag mismatch when decoding");
142 }
143
144/*************************************************
145* Check if more objects are there *
146*************************************************/
147bool BER_Decoder::more_items() const
148 {
149 if(source->end_of_data() && (pushed.type_tag == NO_OBJECT))
150 return false;
151 return true;
152 }
153
154/*************************************************
155* Verify that no bytes remain in the source *
156*************************************************/
157BER_Decoder& BER_Decoder::verify_end()
158 {
159 if(!source->end_of_data() || (pushed.type_tag != NO_OBJECT))
160 throw Invalid_State("BER_Decoder::verify_end called, but data remains");
161 return (*this);
162 }
163
164/*************************************************
165* Save all the bytes remaining in the source *
166*************************************************/
167BER_Decoder& BER_Decoder::raw_bytes(MemoryRegion<byte>& out)
168 {
169 out.destroy();
170 byte buf;
171 while(source->read_byte(buf))
172 out.append(buf);
173 return (*this);
174 }
175
176/*************************************************
177* Discard all the bytes remaining in the source *
178*************************************************/
179BER_Decoder& BER_Decoder::discard_remaining()
180 {
181 byte buf;
182 while(source->read_byte(buf))
183 ;
184 return (*this);
185 }
186
187/*************************************************
188* Return the BER encoding of the next object *
189*************************************************/
190BER_Object BER_Decoder::get_next_object()
191 {
192 BER_Object next;
193
194 if(pushed.type_tag != NO_OBJECT)
195 {
196 next = pushed;
197 pushed.class_tag = pushed.type_tag = NO_OBJECT;
198 return next;
199 }
200
201 decode_tag(source, next.type_tag, next.class_tag);
202 if(next.type_tag == NO_OBJECT)
203 return next;
204
205 u32bit length = decode_length(source);
206 next.value.create(length);
207 if(source->read(next.value, length) != length)
208 throw BER_Decoding_Error("Value truncated");
209
210 if(next.type_tag == EOC && next.class_tag == UNIVERSAL)
211 return get_next_object();
212
213 return next;
214 }
215
216/*************************************************
217* Push a object back into the stream *
218*************************************************/
219void BER_Decoder::push_back(const BER_Object& obj)
220 {
221 if(pushed.type_tag != NO_OBJECT)
222 throw Invalid_State("BER_Decoder: Only one push back is allowed");
223 pushed = obj;
224 }
225
226/*************************************************
227* Begin decoding a CONSTRUCTED type *
228*************************************************/
229BER_Decoder BER_Decoder::start_cons(ASN1_Tag type_tag)
230 {
231 BER_Object obj = get_next_object();
232 obj.assert_is_a(type_tag, CONSTRUCTED);
233 BER_Decoder result(obj.value, obj.value.size());
234 result.parent = this;
235 return result;
236 }
237
238/*************************************************
239* Finish decoding a CONSTRUCTED type *
240*************************************************/
241BER_Decoder& BER_Decoder::end_cons()
242 {
243 if(!parent)
244 throw Invalid_State("BER_Decoder::end_cons called with NULL parent");
245 if(!source->end_of_data())
246 throw Decoding_Error("BER_Decoder::end_cons called with data left");
247 return (*parent);
248 }
249
250/*************************************************
251* BER_Decoder Constructor *
252*************************************************/
253BER_Decoder::BER_Decoder(DataSource& src)
254 {
255 source = &src;
256 owns = false;
257 pushed.type_tag = pushed.class_tag = NO_OBJECT;
258 parent = 0;
259 }
260
261/*************************************************
262* BER_Decoder Constructor *
263 *************************************************/
264BER_Decoder::BER_Decoder(const byte data[], u32bit length)
265 {
266 source = new DataSource_Memory(data, length);
267 owns = true;
268 pushed.type_tag = pushed.class_tag = NO_OBJECT;
269 parent = 0;
270 }
271
272/*************************************************
273* BER_Decoder Constructor *
274*************************************************/
275BER_Decoder::BER_Decoder(const MemoryRegion<byte>& data)
276 {
277 source = new DataSource_Memory(data);
278 owns = true;
279 pushed.type_tag = pushed.class_tag = NO_OBJECT;
280 parent = 0;
281 }
282
283/*************************************************
284* BER_Decoder Copy Constructor *
285*************************************************/
286BER_Decoder::BER_Decoder(const BER_Decoder& other)
287 {
288 source = other.source;
289 owns = false;
290 if(other.owns)
291 {
292 other.owns = false;
293 owns = true;
294 }
295 pushed.type_tag = pushed.class_tag = NO_OBJECT;
296 parent = other.parent;
297 }
298
299/*************************************************
300* BER_Decoder Destructor *
301*************************************************/
302BER_Decoder::~BER_Decoder()
303 {
304 if(owns)
305 delete source;
306 source = 0;
307 }
308
309/*************************************************
310* Request for an object to decode itself *
311*************************************************/
312BER_Decoder& BER_Decoder::decode(ASN1_Object& obj)
313 {
314 obj.decode_from(*this);
315 return (*this);
316 }
317
318/*************************************************
319* Decode a BER encoded NULL *
320*************************************************/
321BER_Decoder& BER_Decoder::decode_null()
322 {
323 BER_Object obj = get_next_object();
324 obj.assert_is_a(NULL_TAG, UNIVERSAL);
325 if(obj.value.size())
326 throw BER_Decoding_Error("NULL object had nonzero size");
327 return (*this);
328 }
329
330/*************************************************
331* Decode a BER encoded BOOLEAN *
332*************************************************/
333BER_Decoder& BER_Decoder::decode(bool& out)
334 {
335 return decode(out, BOOLEAN, UNIVERSAL);
336 }
337
338/*************************************************
339* Decode a small BER encoded INTEGER *
340*************************************************/
341BER_Decoder& BER_Decoder::decode(u32bit& out)
342 {
343 return decode(out, INTEGER, UNIVERSAL);
344 }
345
346/*************************************************
347* Decode a BER encoded INTEGER *
348*************************************************/
349BER_Decoder& BER_Decoder::decode(BigInt& out)
350 {
351 return decode(out, INTEGER, UNIVERSAL);
352 }
353
354/*************************************************
355* Decode a BER encoded BOOLEAN *
356*************************************************/
357BER_Decoder& BER_Decoder::decode(bool& out,
358 ASN1_Tag type_tag, ASN1_Tag class_tag)
359 {
360 BER_Object obj = get_next_object();
361 obj.assert_is_a(type_tag, class_tag);
362
363 if(obj.value.size() != 1)
364 throw BER_Decoding_Error("BER boolean value had invalid size");
365
366 out = (obj.value[0]) ? true : false;
367 return (*this);
368 }
369
370/*************************************************
371* Decode a small BER encoded INTEGER *
372*************************************************/
373BER_Decoder& BER_Decoder::decode(u32bit& out,
374 ASN1_Tag type_tag, ASN1_Tag class_tag)
375 {
376 BigInt integer;
377 decode(integer, type_tag, class_tag);
378 out = integer.to_u32bit();
379 return (*this);
380 }
381
382/*************************************************
383* Decode a BER encoded INTEGER *
384*************************************************/
385BER_Decoder& BER_Decoder::decode(BigInt& out,
386 ASN1_Tag type_tag, ASN1_Tag class_tag)
387 {
388 BER_Object obj = get_next_object();
389 obj.assert_is_a(type_tag, class_tag);
390
391 if(obj.value.is_empty())
392 out = 0;
393 else
394 {
395 const bool negative = (obj.value[0] & 0x80) ? true : false;
396
397 if(negative)
398 {
399 for(u32bit j = obj.value.size(); j > 0; --j)
400 if(obj.value[j-1]--)
401 break;
402 for(u32bit j = 0; j != obj.value.size(); ++j)
403 obj.value[j] = ~obj.value[j];
404 }
405
406 out = BigInt(obj.value, obj.value.size());
407
408 if(negative)
409 out.flip_sign();
410 }
411
412 return (*this);
413 }
414
415/*************************************************
416* BER decode a BIT STRING or OCTET STRING *
417*************************************************/
418BER_Decoder& BER_Decoder::decode(MemoryRegion<byte>& out, ASN1_Tag real_type)
419 {
420 return decode(out, real_type, real_type, UNIVERSAL);
421 }
422
423/*************************************************
424* BER decode a BIT STRING or OCTET STRING *
425*************************************************/
426BER_Decoder& BER_Decoder::decode(MemoryRegion<byte>& buffer,
427 ASN1_Tag real_type,
428 ASN1_Tag type_tag, ASN1_Tag class_tag)
429 {
430 if(real_type != OCTET_STRING && real_type != BIT_STRING)
431 throw BER_Bad_Tag("Bad tag for {BIT,OCTET} STRING", real_type);
432
433 BER_Object obj = get_next_object();
434 obj.assert_is_a(type_tag, class_tag);
435
436 if(real_type == OCTET_STRING)
437 buffer = obj.value;
438 else
439 {
440 if(obj.value[0] >= 8)
441 throw BER_Decoding_Error("Bad number of unused bits in BIT STRING");
442 buffer.set(obj.value + 1, obj.value.size() - 1);
443 }
444 return (*this);
445 }
446
447/*************************************************
448* Decode an OPTIONAL string type *
449*************************************************/
450BER_Decoder& BER_Decoder::decode_optional_string(MemoryRegion<byte>& out,
451 ASN1_Tag real_type,
452 u16bit type_no)
453 {
454 BER_Object obj = get_next_object();
455
456 ASN1_Tag type_tag = (ASN1_Tag)type_no;
457
458 out.clear();
459 push_back(obj);
460
461 if(obj.type_tag == type_tag && obj.class_tag == CONTEXT_SPECIFIC)
462 decode(out, real_type, type_tag, CONTEXT_SPECIFIC);
463
464 return (*this);
465 }
466
467}

Archive Download this file

Branches

Tags

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