Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/heimdal/lib/asn1/gen_length.c
34878 views
1
/*
2
* Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
3
* (Royal Institute of Technology, Stockholm, Sweden).
4
* All rights reserved.
5
*
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions
8
* are met:
9
*
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
*
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.
16
*
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.
20
*
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.
32
*/
33
34
#include "gen_locl.h"
35
36
RCSID("$Id$");
37
38
static void
39
length_primitive (const char *typename,
40
const char *name,
41
const char *variable)
42
{
43
fprintf (codefile, "%s += der_length_%s(%s);\n", variable, typename, name);
44
}
45
46
/* XXX same as der_length_tag */
47
static size_t
48
length_tag(unsigned int tag)
49
{
50
size_t len = 0;
51
52
if(tag <= 30)
53
return 1;
54
while(tag) {
55
tag /= 128;
56
len++;
57
}
58
return len + 1;
59
}
60
61
62
static int
63
length_type (const char *name, const Type *t,
64
const char *variable, const char *tmpstr)
65
{
66
switch (t->type) {
67
case TType:
68
#if 0
69
length_type (name, t->symbol->type);
70
#endif
71
fprintf (codefile, "%s += length_%s(%s);\n",
72
variable, t->symbol->gen_name, name);
73
break;
74
case TInteger:
75
if(t->members) {
76
fprintf(codefile,
77
"{\n"
78
"int enumint = *%s;\n", name);
79
length_primitive ("integer", "&enumint", variable);
80
fprintf(codefile, "}\n");
81
} else if (t->range == NULL) {
82
length_primitive ("heim_integer", name, variable);
83
} else if (t->range->min < INT_MIN && t->range->max <= INT64_MAX) {
84
length_primitive ("integer64", name, variable);
85
} else if (t->range->min >= 0 && t->range->max > UINT_MAX) {
86
length_primitive ("unsigned64", name, variable);
87
} else if (t->range->min >= INT_MIN && t->range->max <= INT_MAX) {
88
length_primitive ("integer", name, variable);
89
} else if (t->range->min >= 0 && t->range->max <= UINT_MAX) {
90
length_primitive ("unsigned", name, variable);
91
} else
92
errx(1, "%s: unsupported range %" PRId64 " -> %" PRId64,
93
name, t->range->min, t->range->max);
94
95
break;
96
case TBoolean:
97
fprintf (codefile, "%s += 1;\n", variable);
98
break;
99
case TEnumerated :
100
length_primitive ("enumerated", name, variable);
101
break;
102
case TOctetString:
103
length_primitive ("octet_string", name, variable);
104
break;
105
case TBitString: {
106
if (ASN1_TAILQ_EMPTY(t->members))
107
length_primitive("bit_string", name, variable);
108
else {
109
if (!rfc1510_bitstring) {
110
Member *m;
111
int pos = ASN1_TAILQ_LAST(t->members, memhead)->val;
112
113
fprintf(codefile,
114
"do {\n");
115
ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
116
while (m->val / 8 < pos / 8) {
117
pos -= 8;
118
}
119
fprintf (codefile,
120
"if((%s)->%s) { %s += %d; break; }\n",
121
name, m->gen_name, variable, (pos + 8) / 8);
122
}
123
fprintf(codefile,
124
"} while(0);\n");
125
fprintf (codefile, "%s += 1;\n", variable);
126
} else {
127
fprintf (codefile, "%s += 5;\n", variable);
128
}
129
}
130
break;
131
}
132
case TSet:
133
case TSequence:
134
case TChoice: {
135
Member *m, *have_ellipsis = NULL;
136
137
if (t->members == NULL)
138
break;
139
140
if(t->type == TChoice)
141
fprintf (codefile, "switch((%s)->element) {\n", name);
142
143
ASN1_TAILQ_FOREACH(m, t->members, members) {
144
char *s;
145
146
if (m->ellipsis) {
147
have_ellipsis = m;
148
continue;
149
}
150
151
if(t->type == TChoice)
152
fprintf(codefile, "case %s:\n", m->label);
153
154
if (asprintf (&s, "%s(%s)->%s%s",
155
m->optional ? "" : "&", name,
156
t->type == TChoice ? "u." : "", m->gen_name) < 0 || s == NULL)
157
errx(1, "malloc");
158
if (m->optional)
159
fprintf (codefile, "if(%s)", s);
160
else if(m->defval)
161
gen_compare_defval(s + 1, m->defval);
162
fprintf (codefile, "{\n"
163
"size_t %s_oldret = %s;\n"
164
"%s = 0;\n", tmpstr, variable, variable);
165
length_type (s, m->type, "ret", m->gen_name);
166
fprintf (codefile, "ret += %s_oldret;\n", tmpstr);
167
fprintf (codefile, "}\n");
168
free (s);
169
if(t->type == TChoice)
170
fprintf(codefile, "break;\n");
171
}
172
if(t->type == TChoice) {
173
if (have_ellipsis)
174
fprintf(codefile,
175
"case %s:\n"
176
"ret += (%s)->u.%s.length;\n"
177
"break;\n",
178
have_ellipsis->label,
179
name,
180
have_ellipsis->gen_name);
181
fprintf (codefile, "}\n"); /* switch */
182
}
183
break;
184
}
185
case TSetOf:
186
case TSequenceOf: {
187
char *n = NULL;
188
char *sname = NULL;
189
190
fprintf (codefile,
191
"{\n"
192
"size_t %s_oldret = %s;\n"
193
"int i;\n"
194
"%s = 0;\n",
195
tmpstr, variable, variable);
196
197
fprintf (codefile, "for(i = (%s)->len - 1; i >= 0; --i){\n", name);
198
fprintf (codefile, "size_t %s_for_oldret = %s;\n"
199
"%s = 0;\n", tmpstr, variable, variable);
200
if (asprintf (&n, "&(%s)->val[i]", name) < 0 || n == NULL)
201
errx(1, "malloc");
202
if (asprintf (&sname, "%s_S_Of", tmpstr) < 0 || sname == NULL)
203
errx(1, "malloc");
204
length_type(n, t->subtype, variable, sname);
205
fprintf (codefile, "%s += %s_for_oldret;\n",
206
variable, tmpstr);
207
fprintf (codefile, "}\n");
208
209
fprintf (codefile,
210
"%s += %s_oldret;\n"
211
"}\n", variable, tmpstr);
212
free(n);
213
free(sname);
214
break;
215
}
216
case TGeneralizedTime:
217
length_primitive ("generalized_time", name, variable);
218
break;
219
case TGeneralString:
220
length_primitive ("general_string", name, variable);
221
break;
222
case TTeletexString:
223
length_primitive ("general_string", name, variable);
224
break;
225
case TUTCTime:
226
length_primitive ("utctime", name, variable);
227
break;
228
case TUTF8String:
229
length_primitive ("utf8string", name, variable);
230
break;
231
case TPrintableString:
232
length_primitive ("printable_string", name, variable);
233
break;
234
case TIA5String:
235
length_primitive ("ia5_string", name, variable);
236
break;
237
case TBMPString:
238
length_primitive ("bmp_string", name, variable);
239
break;
240
case TUniversalString:
241
length_primitive ("universal_string", name, variable);
242
break;
243
case TVisibleString:
244
length_primitive ("visible_string", name, variable);
245
break;
246
case TNull:
247
fprintf (codefile, "/* NULL */\n");
248
break;
249
case TTag:{
250
char *tname = NULL;
251
if (asprintf(&tname, "%s_tag", tmpstr) < 0 || tname == NULL)
252
errx(1, "malloc");
253
length_type (name, t->subtype, variable, tname);
254
fprintf (codefile, "ret += %lu + der_length_len (ret);\n",
255
(unsigned long)length_tag(t->tag.tagvalue));
256
free(tname);
257
break;
258
}
259
case TOID:
260
length_primitive ("oid", name, variable);
261
break;
262
default :
263
abort ();
264
}
265
return 0;
266
}
267
268
void
269
generate_type_length (const Symbol *s)
270
{
271
fprintf (codefile,
272
"size_t ASN1CALL\n"
273
"length_%s(const %s *data)\n"
274
"{\n"
275
"size_t ret = 0;\n",
276
s->gen_name, s->gen_name);
277
278
length_type ("data", s->type, "ret", "Top");
279
fprintf (codefile, "return ret;\n}\n\n");
280
}
281
282
283