Botan: src/asn1/ber_dec.cpp Source File

Botan 1.10.12

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

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