monotone

monotone Mtn Source Tree

Root/botan/ber_code.cpp

1/*************************************************
2* BER Decoding Source File *
3* (C) 1999-2005 The Botan Project *
4*************************************************/
5
6#include <botan/asn1.h>
7#include <botan/parsing.h>
8
9namespace Botan {
10
11/*************************************************
12* BER Decoding Exceptions *
13*************************************************/
14BER_Decoding_Error::BER_Decoding_Error(const std::string& str) :
15 Decoding_Error("BER: " + str) {}
16
17BER_Bad_Tag::BER_Bad_Tag(const std::string& str, ASN1_Tag tag) :
18 BER_Decoding_Error(str + ": " + to_string(tag)) {}
19
20BER_Bad_Tag::BER_Bad_Tag(const std::string& str,
21 ASN1_Tag tag1, ASN1_Tag tag2) :
22 BER_Decoding_Error(str + ": " + to_string(tag1) + "/" + to_string(tag2)) {}
23
24namespace {
25
26/*************************************************
27* Check an object's type and size *
28*************************************************/
29void check_object(const BER_Object& obj,
30 ASN1_Tag type_tag, ASN1_Tag class_tag,
31 u32bit length = 0, bool check_length = false)
32 {
33 if(obj.type_tag != type_tag || obj.class_tag != class_tag)
34 throw BER_Decoding_Error("Tag mismatch when decoding");
35 if(check_length && obj.value.size() != length)
36 throw BER_Decoding_Error("Incorrect size for type");
37 }
38
39}
40
41namespace BER {
42
43/*************************************************
44* Decode a BER encoded NULL *
45*************************************************/
46void decode_null(BER_Decoder& decoder)
47 {
48 BER_Object obj = decoder.get_next_object();
49 check_object(obj, NULL_TAG, UNIVERSAL, 0, true);
50 }
51
52/*************************************************
53* Decode a BER encoded BOOLEAN *
54*************************************************/
55void decode(BER_Decoder& decoder, bool& out)
56 {
57 decode(decoder, out, BOOLEAN, UNIVERSAL);
58 }
59
60/*************************************************
61* Decode a small BER encoded INTEGER *
62*************************************************/
63void decode(BER_Decoder& decoder, u32bit& out)
64 {
65 decode(decoder, out, INTEGER, UNIVERSAL);
66 }
67
68/*************************************************
69* Decode a BER encoded INTEGER *
70*************************************************/
71void decode(BER_Decoder& decoder, BigInt& out)
72 {
73 decode(decoder, out, INTEGER, UNIVERSAL);
74 }
75
76/*************************************************
77* BER decode a BIT STRING or OCTET STRING *
78*************************************************/
79void decode(BER_Decoder& decoder, MemoryRegion<byte>& out, ASN1_Tag real_type)
80 {
81 decode(decoder, out, real_type, real_type, UNIVERSAL);
82 }
83
84/*************************************************
85* Decode a BER encoded BOOLEAN *
86*************************************************/
87void decode(BER_Decoder& decoder, bool& out,
88 ASN1_Tag type_tag, ASN1_Tag class_tag)
89 {
90 BER_Object obj = decoder.get_next_object();
91 check_object(obj, type_tag, class_tag, 1, true);
92 out = (obj.value[0]) ? true : false;
93 }
94
95/*************************************************
96* Decode a small BER encoded INTEGER *
97*************************************************/
98void decode(BER_Decoder& decoder, u32bit& out,
99 ASN1_Tag type_tag, ASN1_Tag class_tag)
100 {
101 BigInt integer;
102 decode(decoder, integer, type_tag, class_tag);
103 out = integer.to_u32bit();
104 }
105
106/*************************************************
107* Decode a BER encoded INTEGER *
108*************************************************/
109void decode(BER_Decoder& decoder, BigInt& out,
110 ASN1_Tag type_tag, ASN1_Tag class_tag)
111 {
112 BER_Object obj = decoder.get_next_object();
113 check_object(obj, type_tag, class_tag);
114
115 out = 0;
116 if(obj.value.is_empty())
117 return;
118
119 const bool negative = (obj.value[0] & 0x80) ? true : false;
120
121 if(negative)
122 {
123 for(u32bit j = obj.value.size(); j > 0; j--)
124 if(obj.value[j-1]--)
125 break;
126 for(u32bit j = 0; j != obj.value.size(); j++)
127 obj.value[j] = ~obj.value[j];
128 }
129
130 out = BigInt(obj.value, obj.value.size());
131
132 if(negative)
133 out.flip_sign();
134 }
135
136/*************************************************
137* BER decode a BIT STRING or OCTET STRING *
138*************************************************/
139void decode(BER_Decoder& decoder, MemoryRegion<byte>& buffer,
140 ASN1_Tag real_type, ASN1_Tag type_tag, ASN1_Tag class_tag)
141 {
142 if(real_type != OCTET_STRING && real_type != BIT_STRING)
143 throw BER_Bad_Tag("Bad tag for {BIT,OCTET} STRING", real_type);
144
145 BER_Object obj = decoder.get_next_object();
146 check_object(obj, type_tag, class_tag);
147
148 if(real_type == OCTET_STRING)
149 buffer = obj.value;
150 else
151 {
152 if(obj.value[0] >= 8)
153 throw BER_Decoding_Error("Bad number of unused bits in BIT STRING");
154 buffer.set(obj.value + 1, obj.value.size() - 1);
155 }
156 }
157
158/*************************************************
159* Decode and return a BER encoded SEQUENCE *
160*************************************************/
161BER_Decoder get_subsequence(BER_Decoder& decoder)
162 {
163 return get_subsequence(decoder, SEQUENCE, CONSTRUCTED);
164 }
165
166/*************************************************
167* Decode and return a BER encoded SET *
168*************************************************/
169BER_Decoder get_subset(BER_Decoder& decoder)
170 {
171 return get_subset(decoder, SET, CONSTRUCTED);
172 }
173
174/*************************************************
175* Decode and return a BER encoded SEQUENCE *
176*************************************************/
177BER_Decoder get_subsequence(BER_Decoder& decoder,
178 ASN1_Tag type_tag, ASN1_Tag class_tag)
179 {
180 BER_Object obj = decoder.get_next_object();
181 check_object(obj, type_tag, ASN1_Tag(class_tag | CONSTRUCTED));
182 return BER_Decoder(obj.value, obj.value.size());
183 }
184
185/*************************************************
186* Decode and return a BER encoded SET *
187*************************************************/
188BER_Decoder get_subset(BER_Decoder& decoder,
189 ASN1_Tag type_tag, ASN1_Tag class_tag)
190 {
191 BER_Object obj = decoder.get_next_object();
192 check_object(obj, type_tag, ASN1_Tag(class_tag | CONSTRUCTED));
193 return BER_Decoder(obj.value, obj.value.size());
194 }
195
196/*************************************************
197* Convert a BER object into a string object *
198*************************************************/
199std::string to_string(const BER_Object& obj)
200 {
201 std::string str((const char*)obj.value.begin(), obj.value.size());
202 return str;
203 }
204
205/*************************************************
206* Decode an OPTIONAL string type *
207*************************************************/
208bool decode_optional_string(BER_Decoder& in, MemoryRegion<byte>& out,
209 ASN1_Tag real_type,
210 ASN1_Tag type_tag, ASN1_Tag class_tag)
211 {
212 BER_Object obj = in.get_next_object();
213
214 if(obj.type_tag == type_tag && obj.class_tag == class_tag)
215 {
216 if(class_tag & CONSTRUCTED)
217 {
218 BER_Decoder stored_value(obj.value);
219 BER::decode(stored_value, out, real_type);
220 stored_value.verify_end();
221 }
222 else
223 {
224 in.push_back(obj);
225 BER::decode(in, out, real_type, type_tag, class_tag);
226 }
227 return true;
228 }
229 else
230 {
231 out.clear();
232 in.push_back(obj);
233 return false;
234 }
235 }
236
237/*************************************************
238* Do heuristic tests for BER data *
239*************************************************/
240bool maybe_BER(DataSource& source)
241 {
242 byte first_byte;
243 if(!source.peek_byte(first_byte))
244 throw Stream_IO_Error("BER::maybe_BER: Source was empty");
245
246 if(first_byte == (SEQUENCE | CONSTRUCTED))
247 return true;
248 return false;
249 }
250
251}
252
253}

Archive Download this file

Branches

Tags

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