Botan: src/asn1/ber_dec.cpp Source File

Botan 1.10.16

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