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.18 2002/08/09 15:37:34 joda 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, 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");
121 if (t
->members
== NULL
)
125 "e = der_match_tag_and_length (p, len, UNIV, CONS, UT_Sequence,"
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
) {
136 asprintf (&s
, "%s(%s)->%s", m
->optional
? "" : "&", name
, m
->gen_name
);
137 if (0 && m
->type
->type
== TType
){
140 "%s = malloc(sizeof(*%s));\n"
141 "if(%s == NULL) return ENOMEM;\n", s
, s
, s
);
143 "e = decode_seq_%s(p, len, %d, %d, %s, &l);\n",
144 m
->type
->symbol
->gen_name
,
150 "if (e == ASN1_MISSING_FIELD) {\n"
157 fprintf (codefile
, "FORW;\n");
160 fprintf (codefile
, "{\n"
161 "size_t newlen, oldlen;\n\n"
162 "e = der_match_tag (p, len, CONTEXT, CONS, %d, &l);\n",
167 /* XXX should look at e */
179 "e = der_get_length (p, len, &newlen, &l);\n"
185 "if((dce_fix = fix_dce(newlen, &len)) < 0)"
186 "return ASN1_BAD_FORMAT;\n");
189 "%s = malloc(sizeof(*%s));\n"
190 "if(%s == NULL) return ENOMEM;\n", s
, s
, s
);
191 decode_type (s
, m
->type
);
194 "e = der_match_tag_and_length (p, len, "
195 "(Der_class)0, (Der_type)0, 0, &reallen, &l);\n"
198 "len = oldlen - newlen;\n"
210 "e = der_match_tag_and_length (p, len, "
211 "(Der_class)0, (Der_type)0, 0, &reallen, &l);\n"
222 "e = der_match_tag_and_length (p, len, UNIV, CONS, UT_Sequence,"
225 "if(len < reallen)\n"
226 "return ASN1_OVERRUN;\n"
231 "size_t origlen = len;\n"
232 "int oldret = ret;\n"
235 "(%s)->val = NULL;\n"
236 "while(ret < origlen) {\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
);
243 "len = origlen - ret;\n"
250 case TGeneralizedTime
:
251 decode_primitive ("generalized_time", name
);
254 decode_primitive ("general_string", name
);
258 "e = der_match_tag_and_length (p, len, APPL, CONS, %d, "
263 "if((dce_fix = fix_dce(reallen, &len)) < 0)\n"
264 "return ASN1_BAD_FORMAT;\n",
266 decode_type (name
, t
->subtype
);
269 "e = der_match_tag_and_length (p, len, "
270 "(Der_class)0, (Der_type)0, 0, &reallen, &l);\n"
282 generate_type_decode (const Symbol
*s
)
286 "decode_%s(const unsigned char *, size_t, %s *, size_t *);\n",
287 s
->gen_name
, s
->gen_name
);
289 fprintf (codefile
, "#define FORW "
296 fprintf (codefile
, "int\n"
297 "decode_%s(const unsigned char *p,"
298 " size_t len, %s *data, size_t *size)\n"
300 s
->gen_name
, s
->gen_name
);
302 switch (s
->type
->type
) {
307 case TGeneralizedTime
:
315 "size_t ret = 0, reallen;\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
);
323 "if(size) *size = ret;\n"
334 fprintf (codefile
, "}\n\n");
338 generate_seq_type_decode (const Symbol
*s
)
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"
349 s
->gen_name
, s
->gen_name
);
352 "size_t newlen, oldlen;\n"
353 "size_t l, ret = 0;\n"
358 "e = der_match_tag(p, len, CONTEXT, CONS, tag, &l);\n"
365 "e = der_get_length(p, len, &newlen, &l);\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"
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"
390 "if(size) *size = ret;\n"
393 fprintf (codefile
, "}\n\n");