remove gcc34
[dragonfly.git] / crypto / heimdal-0.6.3 / lib / asn1 / gen_decode.c
blob7237e4e421adecddabe9ee6586404f00aa98ae49
1 /*
2 * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
34 #include "gen_locl.h"
36 RCSID("$Id: gen_decode.c,v 1.18 2002/08/09 15:37:34 joda Exp $");
38 static void
39 decode_primitive (const char *typename, const char *name)
41 fprintf (codefile,
42 "e = decode_%s(p, len, %s, &l);\n"
43 "FORW;\n",
44 typename,
45 name);
48 static void
49 decode_type (const char *name, const Type *t)
51 switch (t->type) {
52 case TType:
53 #if 0
54 decode_type (name, t->symbol->type);
55 #endif
56 fprintf (codefile,
57 "e = decode_%s(p, len, %s, &l);\n"
58 "FORW;\n",
59 t->symbol->gen_name, name);
60 break;
61 case TInteger:
62 if(t->members == NULL)
63 decode_primitive ("integer", name);
64 else {
65 char *s;
66 asprintf(&s, "(int*)%s", name);
67 if(s == NULL)
68 errx (1, "out of memory");
69 decode_primitive ("integer", s);
70 free(s);
72 break;
73 case TUInteger:
74 decode_primitive ("unsigned", name);
75 break;
76 case TEnumerated:
77 decode_primitive ("enumerated", name);
78 break;
79 case TOctetString:
80 decode_primitive ("octet_string", name);
81 break;
82 case TOID :
83 decode_primitive ("oid", name);
84 break;
85 case TBitString: {
86 Member *m;
87 int tag = -1;
88 int pos;
90 fprintf (codefile,
91 "e = der_match_tag_and_length (p, len, UNIV, PRIM, UT_BitString,"
92 "&reallen, &l);\n"
93 "FORW;\n"
94 "if(len < reallen)\n"
95 "return ASN1_OVERRUN;\n"
96 "p++;\n"
97 "len--;\n"
98 "reallen--;\n"
99 "ret++;\n");
100 pos = 0;
101 for (m = t->members; m && tag != m->val; m = m->next) {
102 while (m->val / 8 > pos / 8) {
103 fprintf (codefile,
104 "p++; len--; reallen--; ret++;\n");
105 pos += 8;
107 fprintf (codefile,
108 "%s->%s = (*p >> %d) & 1;\n",
109 name, m->gen_name, 7 - m->val % 8);
110 if (tag == -1)
111 tag = m->val;
113 fprintf (codefile,
114 "p += reallen; len -= reallen; ret += reallen;\n");
115 break;
117 case TSequence: {
118 Member *m;
119 int tag = -1;
121 if (t->members == NULL)
122 break;
124 fprintf (codefile,
125 "e = der_match_tag_and_length (p, len, UNIV, CONS, UT_Sequence,"
126 "&reallen, &l);\n"
127 "FORW;\n"
128 "{\n"
129 "int dce_fix;\n"
130 "if((dce_fix = fix_dce(reallen, &len)) < 0)\n"
131 "return ASN1_BAD_FORMAT;\n");
133 for (m = t->members; m && tag != m->val; m = m->next) {
134 char *s;
136 asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name);
137 if (0 && m->type->type == TType){
138 if(m->optional)
139 fprintf (codefile,
140 "%s = malloc(sizeof(*%s));\n"
141 "if(%s == NULL) return ENOMEM;\n", s, s, s);
142 fprintf (codefile,
143 "e = decode_seq_%s(p, len, %d, %d, %s, &l);\n",
144 m->type->symbol->gen_name,
145 m->val,
146 m->optional,
148 if(m->optional)
149 fprintf (codefile,
150 "if (e == ASN1_MISSING_FIELD) {\n"
151 "free(%s);\n"
152 "%s = NULL;\n"
153 "e = l = 0;\n"
154 "}\n",
155 s, s);
157 fprintf (codefile, "FORW;\n");
159 }else{
160 fprintf (codefile, "{\n"
161 "size_t newlen, oldlen;\n\n"
162 "e = der_match_tag (p, len, CONTEXT, CONS, %d, &l);\n",
163 m->val);
164 fprintf (codefile,
165 "if (e)\n");
166 if(m->optional)
167 /* XXX should look at e */
168 fprintf (codefile,
169 "%s = NULL;\n", s);
170 else
171 fprintf (codefile,
172 "return e;\n");
173 fprintf (codefile,
174 "else {\n");
175 fprintf (codefile,
176 "p += l;\n"
177 "len -= l;\n"
178 "ret += l;\n"
179 "e = der_get_length (p, len, &newlen, &l);\n"
180 "FORW;\n"
181 "{\n"
183 "int dce_fix;\n"
184 "oldlen = len;\n"
185 "if((dce_fix = fix_dce(newlen, &len)) < 0)"
186 "return ASN1_BAD_FORMAT;\n");
187 if (m->optional)
188 fprintf (codefile,
189 "%s = malloc(sizeof(*%s));\n"
190 "if(%s == NULL) return ENOMEM;\n", s, s, s);
191 decode_type (s, m->type);
192 fprintf (codefile,
193 "if(dce_fix){\n"
194 "e = der_match_tag_and_length (p, len, "
195 "(Der_class)0, (Der_type)0, 0, &reallen, &l);\n"
196 "FORW;\n"
197 "}else \n"
198 "len = oldlen - newlen;\n"
199 "}\n"
200 "}\n");
201 fprintf (codefile,
202 "}\n");
204 if (tag == -1)
205 tag = m->val;
206 free (s);
208 fprintf(codefile,
209 "if(dce_fix){\n"
210 "e = der_match_tag_and_length (p, len, "
211 "(Der_class)0, (Der_type)0, 0, &reallen, &l);\n"
212 "FORW;\n"
213 "}\n"
214 "}\n");
216 break;
218 case TSequenceOf: {
219 char *n;
221 fprintf (codefile,
222 "e = der_match_tag_and_length (p, len, UNIV, CONS, UT_Sequence,"
223 "&reallen, &l);\n"
224 "FORW;\n"
225 "if(len < reallen)\n"
226 "return ASN1_OVERRUN;\n"
227 "len = reallen;\n");
229 fprintf (codefile,
230 "{\n"
231 "size_t origlen = len;\n"
232 "int oldret = ret;\n"
233 "ret = 0;\n"
234 "(%s)->len = 0;\n"
235 "(%s)->val = NULL;\n"
236 "while(ret < origlen) {\n"
237 "(%s)->len++;\n"
238 "(%s)->val = realloc((%s)->val, sizeof(*((%s)->val)) * (%s)->len);\n",
239 name, name, name, name, name, name, name);
240 asprintf (&n, "&(%s)->val[(%s)->len-1]", name, name);
241 decode_type (n, t->subtype);
242 fprintf (codefile,
243 "len = origlen - ret;\n"
244 "}\n"
245 "ret += oldret;\n"
246 "}\n");
247 free (n);
248 break;
250 case TGeneralizedTime:
251 decode_primitive ("generalized_time", name);
252 break;
253 case TGeneralString:
254 decode_primitive ("general_string", name);
255 break;
256 case TApplication:
257 fprintf (codefile,
258 "e = der_match_tag_and_length (p, len, APPL, CONS, %d, "
259 "&reallen, &l);\n"
260 "FORW;\n"
261 "{\n"
262 "int dce_fix;\n"
263 "if((dce_fix = fix_dce(reallen, &len)) < 0)\n"
264 "return ASN1_BAD_FORMAT;\n",
265 t->application);
266 decode_type (name, t->subtype);
267 fprintf(codefile,
268 "if(dce_fix){\n"
269 "e = der_match_tag_and_length (p, len, "
270 "(Der_class)0, (Der_type)0, 0, &reallen, &l);\n"
271 "FORW;\n"
272 "}\n"
273 "}\n");
275 break;
276 default :
277 abort ();
281 void
282 generate_type_decode (const Symbol *s)
284 fprintf (headerfile,
285 "int "
286 "decode_%s(const unsigned char *, size_t, %s *, size_t *);\n",
287 s->gen_name, s->gen_name);
289 fprintf (codefile, "#define FORW "
290 "if(e) goto fail; "
291 "p += l; "
292 "len -= l; "
293 "ret += l\n\n");
296 fprintf (codefile, "int\n"
297 "decode_%s(const unsigned char *p,"
298 " size_t len, %s *data, size_t *size)\n"
299 "{\n",
300 s->gen_name, s->gen_name);
302 switch (s->type->type) {
303 case TInteger:
304 case TUInteger:
305 case TOctetString:
306 case TOID:
307 case TGeneralizedTime:
308 case TGeneralString:
309 case TBitString:
310 case TSequence:
311 case TSequenceOf:
312 case TApplication:
313 case TType:
314 fprintf (codefile,
315 "size_t ret = 0, reallen;\n"
316 "size_t l;\n"
317 "int e;\n\n");
318 fprintf (codefile, "memset(data, 0, sizeof(*data));\n");
319 fprintf (codefile, "reallen = 0;\n"); /* hack to avoid `unused variable' */
321 decode_type ("data", s->type);
322 fprintf (codefile,
323 "if(size) *size = ret;\n"
324 "return 0;\n");
325 fprintf (codefile,
326 "fail:\n"
327 "free_%s(data);\n"
328 "return e;\n",
329 s->gen_name);
330 break;
331 default:
332 abort ();
334 fprintf (codefile, "}\n\n");
337 void
338 generate_seq_type_decode (const Symbol *s)
340 fprintf (headerfile,
341 "int decode_seq_%s(const unsigned char *, size_t, int, int, "
342 "%s *, size_t *);\n",
343 s->gen_name, s->gen_name);
345 fprintf (codefile, "int\n"
346 "decode_seq_%s(const unsigned char *p, size_t len, int tag, "
347 "int optional, %s *data, size_t *size)\n"
348 "{\n",
349 s->gen_name, s->gen_name);
351 fprintf (codefile,
352 "size_t newlen, oldlen;\n"
353 "size_t l, ret = 0;\n"
354 "int e;\n"
355 "int dce_fix;\n");
357 fprintf (codefile,
358 "e = der_match_tag(p, len, CONTEXT, CONS, tag, &l);\n"
359 "if (e)\n"
360 "return e;\n");
361 fprintf (codefile,
362 "p += l;\n"
363 "len -= l;\n"
364 "ret += l;\n"
365 "e = der_get_length(p, len, &newlen, &l);\n"
366 "if (e)\n"
367 "return e;\n"
368 "p += l;\n"
369 "len -= l;\n"
370 "ret += l;\n"
371 "oldlen = len;\n"
372 "if ((dce_fix = fix_dce(newlen, &len)) < 0)\n"
373 "return ASN1_BAD_FORMAT;\n"
374 "e = decode_%s(p, len, data, &l);\n"
375 "if (e)\n"
376 "return e;\n"
377 "p += l;\n"
378 "len -= l;\n"
379 "ret += l;\n"
380 "if (dce_fix) {\n"
381 "size_t reallen;\n\n"
382 "e = der_match_tag_and_length(p, len, "
383 "(Der_class)0, (Der_type)0, 0, &reallen, &l);\n"
384 "if (e)\n"
385 "return e;\n"
386 "ret += l;\n"
387 "}\n",
388 s->gen_name);
389 fprintf (codefile,
390 "if(size) *size = ret;\n"
391 "return 0;\n");
393 fprintf (codefile, "}\n\n");