Botan 1.10.17
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
13namespace Botan {
14
15namespace {
16
17/*
18* BER decode an ASN.1 type tag
19*/
20size_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*/
57size_t find_eoc(DataSource*);
58
59/*
60* BER decode an ASN.1 length field
61*/
62size_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*/
92size_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*/
101size_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*/
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*/
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*/
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*/
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*/
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*/
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*/
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*/
239 ASN1_Tag class_tag)
240 {
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*/
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*/
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 */
275BER_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*/
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*/
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*/
314 {
315 if(owns)
316 delete source;
317 source = 0;
318 }
319
320/*
321* Request for an object to decode itself
322*/
324 {
325 obj.decode_from(*this);
326 return (*this);
327 }
328
329/*
330* Decode a BER encoded NULL
331*/
333 {
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*/
345 {
346 return decode(out, BOOLEAN, UNIVERSAL);
347 }
348
349/*
350* Decode a small BER encoded INTEGER
351*/
353 {
354 return decode(out, INTEGER, UNIVERSAL);
355 }
356
357/*
358* Decode a BER encoded INTEGER
359*/
361 {
362 return decode(out, INTEGER, UNIVERSAL);
363 }
364
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*/
377 ASN1_Tag type_tag, ASN1_Tag class_tag)
378 {
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*/
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*/
412 ASN1_Tag type_tag, ASN1_Tag class_tag)
413 {
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*/
445 {
446 return decode(out, real_type, real_type, UNIVERSAL);
447 }
448
449/*
450* BER decode a BIT STRING or OCTET STRING
451*/
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
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*/
481 ASN1_Tag real_type,
482 u16bit type_no)
483 {
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}
virtual void decode_from(class BER_Decoder &from)=0
BER_Object get_next_object()
Definition ber_dec.cpp:196
BER_Decoder start_cons(ASN1_Tag, ASN1_Tag=UNIVERSAL)
Definition ber_dec.cpp:238
bool more_items() const
Definition ber_dec.cpp:153
BER_Decoder & raw_bytes(MemoryRegion< byte > &)
Definition ber_dec.cpp:173
BER_Decoder & decode_optional_string(MemoryRegion< byte > &, ASN1_Tag, u16bit)
Definition ber_dec.cpp:480
BER_Decoder & decode(bool &)
Definition ber_dec.cpp:344
BER_Decoder & verify_end()
Definition ber_dec.cpp:163
BER_Decoder & end_cons()
Definition ber_dec.cpp:252
BER_Decoder & decode_octet_string_bigint(class BigInt &)
Definition ber_dec.cpp:365
BER_Decoder & discard_remaining()
Definition ber_dec.cpp:185
BER_Decoder & decode_null()
Definition ber_dec.cpp:332
void push_back(const BER_Object &)
Definition ber_dec.cpp:228
BER_Decoder(DataSource &)
Definition ber_dec.cpp:264
SecureVector< byte > value
Definition asn1_int.h:83
ASN1_Tag class_tag
Definition asn1_int.h:82
void assert_is_a(ASN1_Tag, ASN1_Tag)
Definition ber_dec.cpp:144
ASN1_Tag type_tag
Definition asn1_int.h:82
static BigInt decode(const byte buf[], size_t length, Base base=Binary)
Definition big_code.cpp:102
void flip_sign()
Definition bigint.cpp:303
size_t bits() const
Definition bigint.cpp:254
byte byte_at(size_t n) const
Definition bigint.cpp:148
DataSource_Memory(const std::string &in)
Definition data_src.cpp:98
size_t size() const
Definition secmem.h:29
void push_back(T x)
Definition secmem.h:149
bool empty() const
Definition secmem.h:35
void resize(size_t n)
Definition secmem.h:217
byte get_byte(size_t byte_num, T input)
Definition get_byte.h:21
void copy_mem(T *out, const T *in, size_t n)
Definition mem_ops.h:22
ASN1_Tag
Definition asn1_int.h:19
@ CONSTRUCTED
Definition asn1_int.h:25
@ BIT_STRING
Definition asn1_int.h:30
@ BOOLEAN
Definition asn1_int.h:28
@ CONTEXT_SPECIFIC
Definition asn1_int.h:22
@ NO_OBJECT
Definition asn1_int.h:49
@ OCTET_STRING
Definition asn1_int.h:31
@ NULL_TAG
Definition asn1_int.h:32
@ UNIVERSAL
Definition asn1_int.h:20
@ EOC
Definition asn1_int.h:27
@ INTEGER
Definition asn1_int.h:29
unsigned short u16bit
Definition types.h:27
#define BOTAN_CHECKED_ADD(x, y)
Definition safeint.h:35
BER_Bad_Tag(const std::string &msg, ASN1_Tag tag)
Definition asn1_int.cpp:22
BER_Decoding_Error(const std::string &)
Definition asn1_int.cpp:19
Decoding_Error(const std::string &name)
Definition exceptn.h:140
Invalid_State(const std::string &err)
Definition exceptn.h:27