monotone

monotone Mtn Source Tree

Root/botan/ber_dec.cpp

1/*************************************************
2* BER Decoder Source File *
3* (C) 1999-2005 The Botan Project *
4*************************************************/
5
6#include <botan/asn1.h>
7#include <botan/bit_ops.h>
8
9namespace Botan {
10
11namespace {
12
13/*************************************************
14* BER decode an ASN.1 type tag *
15*************************************************/
16u32bit decode_tag(DataSource* ber, ASN1_Tag& type_tag, ASN1_Tag& class_tag)
17 {
18 byte b;
19 if(!ber->read_byte(b))
20 {
21 class_tag = type_tag = NO_OBJECT;
22 return 0;
23 }
24
25 if((b & 0x1F) != 0x1F)
26 {
27 type_tag = ASN1_Tag(b & 0x1F);
28 class_tag = ASN1_Tag(b & 0xE0);
29 return 1;
30 }
31
32 u32bit tag_bytes = 1;
33 class_tag = ASN1_Tag(b & 0xE0);
34
35 u32bit tag_buf = 0;
36 while(true)
37 {
38 if(!ber->read_byte(b))
39 throw Decoding_Error("BER long-form tag truncated");
40 if(tag_buf & 0xFF000000)
41 throw Decoding_Error("BER long-form tag overflow");
42 tag_bytes++;
43 tag_buf = (tag_buf << 7) | (b & 0x7F);
44 if((b & 0x80) == 0) break;
45 }
46 type_tag = ASN1_Tag(tag_buf);
47 return tag_bytes;
48 }
49
50/*************************************************
51* Find the EOC marker *
52*************************************************/
53u32bit find_eoc(DataSource*);
54
55/*************************************************
56* BER decode an ASN.1 length field *
57*************************************************/
58u32bit decode_length(DataSource* ber, u32bit& field_size)
59 {
60 byte b;
61 if(!ber->read_byte(b))
62 throw BER_Decoding_Error("Length field not found");
63 field_size = 1;
64 if((b & 0x80) == 0)
65 return b;
66
67 field_size += (b & 0x7F);
68 if(field_size == 1) return find_eoc(ber);
69 if(field_size > 5)
70 throw BER_Decoding_Error("Length field is too large");
71
72 u32bit length = 0;
73
74 for(u32bit j = 0; j != field_size - 1; j++)
75 {
76 if(get_byte(0, length) != 0)
77 throw BER_Decoding_Error("Field length overflow");
78 if(!ber->read_byte(b))
79 throw BER_Decoding_Error("Corrupted length field");
80 length = (length << 8) | b;
81 }
82 return length;
83 }
84
85/*************************************************
86* BER decode an ASN.1 length field *
87*************************************************/
88u32bit decode_length(DataSource* ber)
89 {
90 u32bit dummy;
91 return decode_length(ber, dummy);
92 }
93
94/*************************************************
95* Find the EOC marker *
96*************************************************/
97u32bit find_eoc(DataSource* ber)
98 {
99 SecureVector<byte> data;
100
101 while(true)
102 {
103 SecureVector<byte> buffer(DEFAULT_BUFFERSIZE);
104
105 const u32bit got = ber->peek(buffer, buffer.size(), data.size());
106 if(got == 0)
107 break;
108 data.append(buffer, got);
109 }
110
111 DataSource_Memory source(data);
112 data.destroy();
113
114 u32bit length = 0;
115 while(true)
116 {
117 ASN1_Tag type_tag, class_tag;
118 u32bit tag_size = decode_tag(&source, type_tag, class_tag);
119 if(type_tag == NO_OBJECT)
120 break;
121
122 u32bit length_size = 0;
123 u32bit item_size = decode_length(&source, length_size);
124 source.discard_next(item_size);
125
126 length += item_size + length_size + tag_size;
127
128 if(type_tag == EOC)
129 break;
130 }
131 return length;
132 }
133
134}
135
136/*************************************************
137* Check if more objects are there *
138*************************************************/
139bool BER_Decoder::more_items() const
140 {
141 if(source->end_of_data() && (pushed.type_tag == NO_OBJECT))
142 return false;
143 return true;
144 }
145
146/*************************************************
147* Verify that no bytes remain in the source *
148*************************************************/
149void BER_Decoder::verify_end() const
150 {
151 if(!source->end_of_data() || (pushed.type_tag != NO_OBJECT))
152 throw Invalid_State("BER_Decoder::verify_end called, but data remains");
153 }
154
155/*************************************************
156* Return all the bytes remaining in the source *
157*************************************************/
158SecureVector<byte> BER_Decoder::get_remaining()
159 {
160 SecureVector<byte> out;
161 byte buf;
162 while(source->read_byte(buf))
163 out.append(buf);
164 return out;
165 }
166
167/*************************************************
168* Discard all the bytes remaining in the source *
169*************************************************/
170void BER_Decoder::discard_remaining()
171 {
172 byte buf;
173 while(source->read_byte(buf))
174 ;
175 }
176
177/*************************************************
178* Return the BER encoding of the next object *
179*************************************************/
180BER_Object BER_Decoder::get_next_object()
181 {
182 BER_Object next;
183
184 if(pushed.type_tag != NO_OBJECT)
185 {
186 next = pushed;
187 pushed.class_tag = pushed.type_tag = NO_OBJECT;
188 return next;
189 }
190
191 decode_tag(source, next.type_tag, next.class_tag);
192 if(next.type_tag == NO_OBJECT)
193 return next;
194
195 u32bit length = decode_length(source);
196 next.value.create(length);
197 if(source->read(next.value, length) != length)
198 throw BER_Decoding_Error("Value truncated");
199
200 if(next.type_tag == EOC && next.class_tag == UNIVERSAL)
201 return get_next_object();
202
203 return next;
204 }
205
206/*************************************************
207* Push a object back into the stream *
208*************************************************/
209void BER_Decoder::push_back(const BER_Object& obj)
210 {
211 if(pushed.type_tag != NO_OBJECT)
212 throw Invalid_State("BER_Decoder: Only one push back is allowed");
213 pushed = obj;
214 }
215
216/*************************************************
217* BER_Decoder Constructor *
218*************************************************/
219BER_Decoder::BER_Decoder(DataSource& src)
220 {
221 source = &src;
222 owns = false;
223 pushed.type_tag = pushed.class_tag = NO_OBJECT;
224 }
225
226/*************************************************
227* BER_Decoder Constructor *
228 *************************************************/
229BER_Decoder::BER_Decoder(const byte data[], u32bit length)
230 {
231 source = new DataSource_Memory(data, length);
232 owns = true;
233 pushed.type_tag = pushed.class_tag = NO_OBJECT;
234 }
235
236/*************************************************
237* BER_Decoder Constructor *
238*************************************************/
239BER_Decoder::BER_Decoder(const MemoryRegion<byte>& data)
240 {
241 source = new DataSource_Memory(data);
242 owns = true;
243 pushed.type_tag = pushed.class_tag = NO_OBJECT;
244 }
245
246/*************************************************
247* BER_Decoder Copy Constructor *
248*************************************************/
249BER_Decoder::BER_Decoder(const BER_Decoder& other)
250 {
251 source = other.source;
252 owns = false;
253 if(other.owns)
254 {
255 other.owns = false;
256 owns = true;
257 }
258 pushed.type_tag = pushed.class_tag = NO_OBJECT;
259 }
260
261/*************************************************
262* BER_Decoder Destructor *
263*************************************************/
264BER_Decoder::~BER_Decoder()
265 {
266 if(owns)
267 delete source;
268 source = 0;
269 }
270
271}

Archive Download this file

Branches

Tags

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