2 * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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
36 RCSID("$Id: gen_decode.c,v 1.21 2005/05/29 14:23:01 lha Exp $");
39 decode_primitive (const char *typename, const char *name)
42 "e = decode_%s(p, len, %s, &l);\n"
49 decode_type (const char *name, const Type *t)
54 decode_type (name, t->symbol->type);
57 "e = decode_%s(p, len, %s, &l);\n"
59 t->symbol->gen_name, name);
62 if(t->members == NULL)
63 decode_primitive ("integer", name);
66 asprintf(&s, "(int*)%s", name);
68 errx (1, "out of memory");
69 decode_primitive ("integer", s);
74 decode_primitive ("unsigned", name);
77 decode_primitive ("enumerated", name);
80 decode_primitive ("octet_string", name);
83 decode_primitive ("oid", name);
91 "e = der_match_tag_and_length (p, len, ASN1_C_UNIV, PRIM, UT_BitString,"
95 "return ASN1_OVERRUN;\n"
101 for (m = t->members; m && tag != m->val; m = m->next) {
102 while (m->val / 8 > pos / 8) {
104 "p++; len--; reallen--; ret++;\n");
108 "%s->%s = (*p >> %d) & 1;\n",
109 name, m->gen_name, 7 - m->val % 8);
114 "p += reallen; len -= reallen; ret += reallen;\n");
120 int fd_counter = unique_get_next();
121 int fd_counter_inner = unique_get_next();
123 if (t->members == NULL)
127 "e = der_match_tag_and_length (p, len, ASN1_C_UNIV, CONS, UT_Sequence,"
132 "if((dce_fix%d = fix_dce(reallen, &len)) < 0)\n"
133 "return ASN1_BAD_FORMAT;\n",
134 fd_counter, fd_counter);
136 for (m = t->members; m && tag != m->val; m = m->next) {
139 asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name);
140 if (0 && m->type->type == TType){
143 "%s = malloc(sizeof(*%s));\n"
144 "if(%s == NULL) return ENOMEM;\n", s, s, s);
146 "e = decode_seq_%s(p, len, %d, %d, %s, &l);\n",
147 m->type->symbol->gen_name,
153 "if (e == ASN1_MISSING_FIELD) {\n"
160 fprintf (codefile, "FORW;\n");
163 fprintf (codefile, "{\n"
164 "size_t newlen, oldlen;\n\n"
165 "e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, %d, &l);\n",
170 /* XXX should look at e */
182 "e = der_get_length (p, len, &newlen, &l);\n"
188 "if((dce_fix%d = fix_dce(newlen, &len)) < 0)"
189 "return ASN1_BAD_FORMAT;\n",
194 "%s = malloc(sizeof(*%s));\n"
195 "if(%s == NULL) return ENOMEM;\n", s, s, s);
196 decode_type (s, m->type);
199 "e = der_match_tag_and_length (p, len, "
200 "(Der_class)0, (Der_type)0, 0, &reallen, &l);\n"
203 "len = oldlen - newlen;\n"
216 "e = der_match_tag_and_length (p, len, "
217 "(Der_class)0, (Der_type)0, 0, &reallen, &l);\n"
227 int oldret_counter = unique_get_next();
230 "e = der_match_tag_and_length (p, len, ASN1_C_UNIV, CONS, UT_Sequence,"
233 "if(len < reallen)\n"
234 "return ASN1_OVERRUN;\n"
239 "size_t origlen = len;\n"
240 "int oldret%d = ret;\n"
243 "(%s)->val = NULL;\n"
244 "while(ret < origlen) {\n"
246 "(%s)->val = realloc((%s)->val, sizeof(*((%s)->val)) * (%s)->len);\n",
247 oldret_counter, name, name, name, name, name, name, name);
248 asprintf (&n, "&(%s)->val[(%s)->len-1]", name, name);
249 decode_type (n, t->subtype);
251 "len = origlen - ret;\n"
259 case TGeneralizedTime:
260 decode_primitive ("generalized_time", name);
263 decode_primitive ("general_string", name);
266 decode_primitive ("utf8string", name);
270 "e = decode_nulltype(p, len, &l);\n"
275 "e = der_match_tag_and_length (p, len, ASN1_C_APPL, CONS, %d, "
280 "if((dce_fix = fix_dce(reallen, &len)) < 0)\n"
281 "return ASN1_BAD_FORMAT;\n",
283 decode_type (name, t->subtype);
286 "e = der_match_tag_and_length (p, len, "
287 "(Der_class)0, (Der_type)0, 0, &reallen, &l);\n"
294 decode_primitive ("boolean", name);
302 generate_type_decode (const Symbol *s)
307 "decode_%s(const unsigned char *, size_t, %s *, size_t *);\n",
308 s->gen_name, s->gen_name);
310 fprintf (codefile, "#define FORW "
317 fprintf (codefile, "int\n"
318 "decode_%s(const unsigned char *p,"
319 " size_t len, %s *data, size_t *size)\n"
321 s->gen_name, s->gen_name);
323 switch (s->type->type) {
329 case TGeneralizedTime:
340 "size_t ret = 0, reallen;\n"
343 fprintf (codefile, "memset(data, 0, sizeof(*data));\n");
344 fprintf (codefile, "reallen = 0;\n"); /* hack to avoid `unused variable' */
346 decode_type ("data", s->type);
348 "if(size) *size = ret;\n"
359 fprintf (codefile, "}\n\n");
363 generate_seq_type_decode (const Symbol *s)
366 "int decode_seq_%s(const unsigned char *, size_t, int, int, "
367 "%s *, size_t *);\n",
368 s->gen_name, s->gen_name);
370 fprintf (codefile, "int\n"
371 "decode_seq_%s(const unsigned char *p, size_t len, int tag, "
372 "int optional, %s *data, size_t *size)\n"
374 s->gen_name, s->gen_name);
377 "size_t newlen, oldlen;\n"
378 "size_t l, ret = 0;\n"
383 "e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, tag, &l);\n"
390 "e = der_get_length(p, len, &newlen, &l);\n"
397 "if ((dce_fix = fix_dce(newlen, &len)) < 0)\n"
398 "return ASN1_BAD_FORMAT;\n"
399 "e = decode_%s(p, len, data, &l);\n"
406 "size_t reallen;\n\n"
407 "e = der_match_tag_and_length(p, len, "
408 "(Der_class)0, (Der_type)0, 0, &reallen, &l);\n"
415 "if(size) *size = ret;\n"
418 fprintf (codefile, "}\n\n");