1 | #include <list> |
---|
2 | #include <vector> |
---|
3 | #include <stdint.h> |
---|
4 | #include <assert.h> |
---|
5 | #include <ctype.h> |
---|
6 | #include <string> |
---|
7 | #ifdef TEST |
---|
8 | #include <stdio.h> |
---|
9 | #endif |
---|
10 | #include "asn1.h" |
---|
11 | |
---|
12 | |
---|
13 | const char *const ASN_type_class_t_names[] = { |
---|
14 | "Universal", |
---|
15 | "Application", |
---|
16 | "Context Specific", |
---|
17 | "Private", |
---|
18 | }; |
---|
19 | |
---|
20 | ASN_type::ASN_type(uint8_t _type) : type(_type){ |
---|
21 | /* Not implemented multibyte tags yet */ |
---|
22 | assert(getTag() != 0x1F); |
---|
23 | } |
---|
24 | |
---|
25 | ASN_type_class_t ASN_type::getClass(void) const { |
---|
26 | return (ASN_type_class_t) (type >> 6); |
---|
27 | } |
---|
28 | |
---|
29 | bool ASN_type::isPrimative(void) const { |
---|
30 | return !((type >> 5) & 0x01); |
---|
31 | } |
---|
32 | |
---|
33 | int ASN_type::getTag(void) const { |
---|
34 | return (type & 0x1F); |
---|
35 | } |
---|
36 | |
---|
37 | ASN_data::ASN_data(ASN_type _type,uint64_t _len) : type(_type), |
---|
38 | len(_len) |
---|
39 | { |
---|
40 | }; |
---|
41 | |
---|
42 | void ASN_data::parse(void) |
---|
43 | { |
---|
44 | }; |
---|
45 | |
---|
46 | void ASN_data::toString(void) { |
---|
47 | printf(" ASN: %s %s 0x%x\n", |
---|
48 | ASN_type_class_t_names[(int)type.getClass()], |
---|
49 | type.isPrimative() |
---|
50 | ? "Primative" |
---|
51 | : "Constructed", |
---|
52 | type.getTag() |
---|
53 | ); |
---|
54 | buffer_t::const_iterator it=buffer.begin(); |
---|
55 | while(it!=buffer.end()) { |
---|
56 | printf(" ASN:"); |
---|
57 | |
---|
58 | buffer_t::const_iterator hexit=it; |
---|
59 | for(uint64_t i=0;i<8;i++) { |
---|
60 | if (hexit!=buffer.end()) { |
---|
61 | printf(" %02x",*hexit); |
---|
62 | hexit++; |
---|
63 | } |
---|
64 | else |
---|
65 | printf(" "); |
---|
66 | } |
---|
67 | printf("\t"); |
---|
68 | for(uint64_t i=0;i<8;i++) { |
---|
69 | if (it!=buffer.end()) { |
---|
70 | printf("%c", |
---|
71 | isprint(*it) |
---|
72 | ? *it |
---|
73 | : '.'); |
---|
74 | it++; |
---|
75 | } |
---|
76 | } |
---|
77 | printf("\n"); |
---|
78 | } |
---|
79 | }; // toString |
---|
80 | ASN_data::~ASN_data() {}; |
---|
81 | |
---|
82 | |
---|
83 | bool ASN::eof(void) const { |
---|
84 | return buffer.size()<=0; |
---|
85 | } |
---|
86 | |
---|
87 | // Type 0 - End of contents |
---|
88 | // Type 1 - Bool |
---|
89 | class ASN_bool : public ASN_data { |
---|
90 | public: |
---|
91 | ASN_bool(ASN_type t,uint64_t l) : ASN_data(t,l) {}; |
---|
92 | bool getValue(void) const { |
---|
93 | return *buffer.begin()!=0; |
---|
94 | } |
---|
95 | void toString(void) const { |
---|
96 | printf(" ASN: Bool:\t%s\n",getValue() |
---|
97 | ?"True": |
---|
98 | "False"); |
---|
99 | } |
---|
100 | }; |
---|
101 | |
---|
102 | // Type 2 - Integer |
---|
103 | class ASN_int : public ASN_data { |
---|
104 | public: |
---|
105 | ASN_int(ASN_type t,uint64_t l) : ASN_data(t,l) {}; |
---|
106 | uint64_t getValue(void) { |
---|
107 | uint64_t val=0; |
---|
108 | for(buffer_t::const_iterator i=buffer.begin(); |
---|
109 | i!=buffer.end(); |
---|
110 | i++) { |
---|
111 | val=(val<<8)+*i; |
---|
112 | } |
---|
113 | return val; |
---|
114 | } |
---|
115 | void toString(void) { |
---|
116 | printf(" ASN: Int:\t0x"); |
---|
117 | // Yeah, this is a dirty trick |
---|
118 | for(buffer_t::const_iterator i=buffer.begin(); |
---|
119 | i!=buffer.end(); |
---|
120 | i++) { |
---|
121 | printf("%02x",*i); |
---|
122 | } |
---|
123 | printf("\n"); |
---|
124 | } |
---|
125 | }; |
---|
126 | |
---|
127 | // Types - Simple Strings |
---|
128 | class ASN_string : public ASN_data { |
---|
129 | public: |
---|
130 | ASN_string(ASN_type t,uint64_t l) : ASN_data(t,l) {}; |
---|
131 | std::string getValue(void) { |
---|
132 | std::string s; |
---|
133 | for(buffer_t::const_iterator i=buffer.begin(); |
---|
134 | i!=buffer.end(); |
---|
135 | i++) { |
---|
136 | s=s+(char)*i; |
---|
137 | } |
---|
138 | return s; |
---|
139 | } |
---|
140 | void toString(void) { |
---|
141 | printf(" ASN: String:\t%s\n",getValue().c_str()); |
---|
142 | } |
---|
143 | }; |
---|
144 | // Type 5 - Null |
---|
145 | class ASN_null : public ASN_data { |
---|
146 | public: |
---|
147 | ASN_null(ASN_type t,uint64_t l) : ASN_data(t,l) {}; |
---|
148 | void toString(void) { printf(" ASN: NULL\n"); } |
---|
149 | }; |
---|
150 | |
---|
151 | // Abstract Container for sets and sequences |
---|
152 | class ASN_container : public ASN_data { |
---|
153 | private: |
---|
154 | std::vector<ASN_data *> subencodings; |
---|
155 | public: |
---|
156 | typedef std::vector<ASN_data *>::const_iterator const_iterator; |
---|
157 | ASN_container(ASN_type t,uint64_t l) : ASN_data(t,l) {}; |
---|
158 | void parse() { |
---|
159 | ASN n; |
---|
160 | n.feed(buffer,len); |
---|
161 | while (!n.eof()) { |
---|
162 | subencodings.push_back(n.getEncoding()); |
---|
163 | } |
---|
164 | }; |
---|
165 | const_iterator begin(void) { return (const_iterator)subencodings.begin(); } |
---|
166 | const_iterator end(void) { return (const_iterator)subencodings.end(); } |
---|
167 | }; |
---|
168 | |
---|
169 | // Type 16 - Sequence |
---|
170 | class ASN_sequence : public ASN_container { |
---|
171 | public: |
---|
172 | ASN_sequence(ASN_type t,uint64_t l) : ASN_container(t,l) {}; |
---|
173 | void toString(void) { |
---|
174 | printf(" ASN: Sequence begin\n"); |
---|
175 | for(const_iterator i=begin(); |
---|
176 | i!=end(); |
---|
177 | i++) |
---|
178 | (*i)->toString(); |
---|
179 | printf(" ASN: Sequence end\n"); |
---|
180 | } |
---|
181 | }; |
---|
182 | // Type 17 - Set |
---|
183 | class ASN_set : public ASN_container { |
---|
184 | public: |
---|
185 | ASN_set(ASN_type t,uint64_t l) : ASN_container(t,l) {}; |
---|
186 | void toString(void) { |
---|
187 | printf(" ASN: Set begin\n"); |
---|
188 | for(const_iterator i=begin(); |
---|
189 | i!=end(); |
---|
190 | i++) |
---|
191 | (*i)->toString(); |
---|
192 | printf(" ASN: Set end\n"); |
---|
193 | } |
---|
194 | }; |
---|
195 | |
---|
196 | // Type 6 - Object Identifier |
---|
197 | class ASN_oid : public ASN_data { |
---|
198 | private: |
---|
199 | std::vector<uint64_t> oid; |
---|
200 | uint64_t decodeInt(void) { |
---|
201 | uint64_t x=0; |
---|
202 | while(*buffer.begin()&0x80) { |
---|
203 | x=(x<<7)|(*buffer.begin()&~0x80); |
---|
204 | buffer.pop_front(); |
---|
205 | } |
---|
206 | x=(x<<7)|(*buffer.begin()); |
---|
207 | buffer.pop_front(); |
---|
208 | return x; |
---|
209 | } |
---|
210 | public: |
---|
211 | ASN_oid(ASN_type t,uint64_t l) : ASN_data(t,l) {}; |
---|
212 | void parse(void) { |
---|
213 | uint64_t first = decodeInt(); |
---|
214 | oid.push_back(first/40); |
---|
215 | oid.push_back(first%40); |
---|
216 | while(buffer.size()!=0) |
---|
217 | oid.push_back(decodeInt()); |
---|
218 | }; |
---|
219 | void toString(void) { |
---|
220 | printf(" ASN: OID"); |
---|
221 | for(std::vector<uint64_t>::const_iterator i=oid.begin(); |
---|
222 | i!=oid.end(); |
---|
223 | i++) { |
---|
224 | printf(" %lli",*i); |
---|
225 | } |
---|
226 | printf("\n"); |
---|
227 | }; |
---|
228 | }; |
---|
229 | |
---|
230 | |
---|
231 | void ASN::feed(char *buff,int size) |
---|
232 | { |
---|
233 | while(size-->0) |
---|
234 | buffer.push_back(*(buff++)); |
---|
235 | } |
---|
236 | |
---|
237 | |
---|
238 | ASN_type ASN::getType(void) |
---|
239 | { |
---|
240 | ASN_type t(*buffer.begin()); |
---|
241 | buffer.pop_front(); |
---|
242 | return t; |
---|
243 | } |
---|
244 | |
---|
245 | uint64_t ASN::getLength(void) |
---|
246 | { |
---|
247 | // TODO Only supports definite encodings |
---|
248 | uint64_t len=0; |
---|
249 | uint8_t x = *buffer.begin(); |
---|
250 | buffer.pop_front(); |
---|
251 | assert(x != 0x80); // Indefinate encoding |
---|
252 | // Short form |
---|
253 | if ((x&0x80)==0) { |
---|
254 | return x; |
---|
255 | } |
---|
256 | x&=~0x80; |
---|
257 | // Long form |
---|
258 | while(x-->0) { |
---|
259 | len=(len<<8)|*buffer.begin(); |
---|
260 | buffer.pop_front(); |
---|
261 | } |
---|
262 | return len; |
---|
263 | } |
---|
264 | |
---|
265 | ASN_data *ASN::getEncoding(void) |
---|
266 | { |
---|
267 | ASN_type t=getType(); |
---|
268 | uint64_t l=getLength(); |
---|
269 | ASN_data *ret; |
---|
270 | switch(t.getTag()) { |
---|
271 | case 1: |
---|
272 | ret=new ASN_bool(t,l); |
---|
273 | break; |
---|
274 | case 2: |
---|
275 | ret=new ASN_int(t,l); |
---|
276 | break; |
---|
277 | case 5: |
---|
278 | ret=new ASN_null(t,l); |
---|
279 | break; |
---|
280 | case 6: |
---|
281 | ret=new ASN_oid(t,l); |
---|
282 | break; |
---|
283 | case 16: |
---|
284 | ret=new ASN_sequence(t,l); |
---|
285 | break; |
---|
286 | case 17: |
---|
287 | ret=new ASN_set(t,l); |
---|
288 | break; |
---|
289 | case 18: |
---|
290 | case 19: |
---|
291 | case 20: |
---|
292 | case 21: |
---|
293 | case 22: |
---|
294 | case 25: |
---|
295 | case 26: |
---|
296 | case 27: |
---|
297 | ret=new ASN_string(t,l); |
---|
298 | break; |
---|
299 | default: |
---|
300 | ret=new ASN_data(t,l); |
---|
301 | break; |
---|
302 | } |
---|
303 | ret->feed(buffer,l); |
---|
304 | ret->parse(); |
---|
305 | return ret; |
---|
306 | } |
---|
307 | |
---|
308 | void ASN_data::feed(std::list<uint8_t> &buff,uint64_t len) |
---|
309 | { |
---|
310 | while(len-->0) { |
---|
311 | buffer.push_back(*buff.begin()); |
---|
312 | buff.pop_front(); |
---|
313 | } |
---|
314 | } |
---|
315 | |
---|
316 | void ASN::feed(std::list<uint8_t> &buff,uint64_t len) |
---|
317 | { |
---|
318 | while(len-->0) { |
---|
319 | buffer.push_back(*buff.begin()); |
---|
320 | buff.pop_front(); |
---|
321 | } |
---|
322 | } |
---|
323 | #ifdef TEST |
---|
324 | int main(int argc, char **argv) |
---|
325 | { |
---|
326 | FILE *f=fopen(argv[1],"r"); |
---|
327 | ASN *asn = new ASN();; |
---|
328 | char buffer[1024]; |
---|
329 | int size; |
---|
330 | |
---|
331 | size=fread(buffer,1,sizeof(buffer),f); |
---|
332 | printf("Read %i bytes\n",size); |
---|
333 | |
---|
334 | asn->feed(buffer,size); |
---|
335 | |
---|
336 | ASN_data *data= asn->getEncoding(); |
---|
337 | |
---|
338 | data->toString(); |
---|
339 | data->toString(); |
---|
340 | |
---|
341 | return 0; |
---|
342 | } |
---|
343 | #endif |
---|