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_encode.c,v 1.12 2001/09/25 13:39:26 assar Exp $");
39 encode_primitive (const char *typename
, const char *name
)
42 "e = encode_%s(p, len, %s, &l);\n"
49 encode_type (const char *name
, const Type
*t
)
54 encode_type (name
, t
->symbol
->type
);
57 "e = encode_%s(p, len, %s, &l);\n"
59 t
->symbol
->gen_name
, name
);
62 if(t
->members
== NULL
)
63 encode_primitive ("integer", name
);
66 asprintf(&s
, "(const int*)%s", name
);
68 errx(1, "out of memory");
69 encode_primitive ("integer", s
);
74 encode_primitive ("unsigned", name
);
77 encode_primitive ("octet_string", name
);
80 encode_primitive ("oid", name
);
88 if (t
->members
== NULL
)
91 fprintf (codefile
, "{\n"
92 "unsigned char c = 0;\n");
93 pos
= t
->members
->prev
->val
;
94 /* fix for buggy MIT (and OSF?) code */
98 * It seems that if we do not always set pos to 31 here, the MIT
99 * code will do the wrong thing.
101 * I hate ASN.1 (and DER), but I hate it even more when everybody
102 * has to screw it up differently.
105 rest
= 7 - (pos
% 8);
107 for (m
= t
->members
->prev
; m
&& tag
!= m
->val
; m
= m
->prev
) {
108 while (m
->val
/ 8 < pos
/ 8) {
110 "*p-- = c; len--; ret++;\n"
115 "if(%s->%s) c |= 1<<%d;\n", name
, m
->gen_name
,
128 "e = der_put_length_and_tag (p, len, ret, UNIV, PRIM,"
129 "UT_BitString, &l);\n"
135 encode_primitive ("enumerated", name
);
142 if (t
->members
== NULL
)
145 for (m
= t
->members
->prev
; m
&& tag
!= m
->val
; m
= m
->prev
) {
148 asprintf (&s
, "%s(%s)->%s", m
->optional
? "" : "&", name
, m
->gen_name
);
154 fprintf (codefile
, "{\n"
155 "int oldret = ret;\n"
158 encode_type (s
, m
->type
);
160 "e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, "
174 "e = der_put_length_and_tag (p, len, ret, UNIV, CONS, UT_Sequence, &l);\n"
182 "for(i = (%s)->len - 1; i >= 0; --i) {\n"
184 "int oldret = ret;\n"
190 asprintf (&n
, "&(%s)->val[i]", name
);
191 encode_type (n
, t
->subtype
);
197 "e = der_put_length_and_tag (p, len, ret, UNIV, CONS, UT_Sequence, &l);\n"
202 case TGeneralizedTime
:
203 encode_primitive ("generalized_time", name
);
206 encode_primitive ("general_string", name
);
209 encode_type (name
, t
->subtype
);
211 "e = der_put_length_and_tag (p, len, ret, APPL, CONS, %d, &l);\n"
221 generate_type_encode (const Symbol
*s
)
225 "encode_%s(unsigned char *, size_t, const %s *, size_t *);\n",
226 s
->gen_name
, s
->gen_name
);
228 fprintf (codefile
, "#define BACK if (e) return e; p -= l; len -= l; ret += l\n\n");
231 fprintf (codefile
, "int\n"
232 "encode_%s(unsigned char *p, size_t len,"
233 " const %s *data, size_t *size)\n"
235 s
->gen_name
, s
->gen_name
);
237 switch (s
->type
->type
) {
241 case TGeneralizedTime
:
254 fprintf(codefile
, "i = 0;\n"); /* hack to avoid `unused variable' */
256 encode_type("data", s
->type
);
258 fprintf (codefile
, "*size = ret;\n"
264 fprintf (codefile
, "}\n\n");