Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/heimdal/lib/asn1/gen.c
34879 views
1
/*
2
* Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
3
* (Royal Institute of Technology, Stockholm, Sweden).
4
* All rights reserved.
5
*
6
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
7
*
8
* Redistribution and use in source and binary forms, with or without
9
* modification, are permitted provided that the following conditions
10
* are met:
11
*
12
* 1. Redistributions of source code must retain the above copyright
13
* notice, this list of conditions and the following disclaimer.
14
*
15
* 2. Redistributions in binary form must reproduce the above copyright
16
* notice, this list of conditions and the following disclaimer in the
17
* documentation and/or other materials provided with the distribution.
18
*
19
* 3. Neither the name of the Institute nor the names of its contributors
20
* may be used to endorse or promote products derived from this software
21
* without specific prior written permission.
22
*
23
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33
* SUCH DAMAGE.
34
*/
35
36
#include "gen_locl.h"
37
38
RCSID("$Id$");
39
40
FILE *privheaderfile, *headerfile, *codefile, *logfile, *templatefile;
41
42
#define STEM "asn1"
43
44
static const char *orig_filename;
45
static char *privheader, *header, *template;
46
static const char *headerbase = STEM;
47
48
/*
49
* list of all IMPORTs
50
*/
51
52
struct import {
53
const char *module;
54
struct import *next;
55
};
56
57
static struct import *imports = NULL;
58
59
void
60
add_import (const char *module)
61
{
62
struct import *tmp = emalloc (sizeof(*tmp));
63
64
tmp->module = module;
65
tmp->next = imports;
66
imports = tmp;
67
68
fprintf (headerfile, "#include <%s_asn1.h>\n", module);
69
}
70
71
/*
72
* List of all exported symbols
73
*/
74
75
struct sexport {
76
const char *name;
77
int defined;
78
struct sexport *next;
79
};
80
81
static struct sexport *exports = NULL;
82
83
void
84
add_export (const char *name)
85
{
86
struct sexport *tmp = emalloc (sizeof(*tmp));
87
88
tmp->name = name;
89
tmp->next = exports;
90
exports = tmp;
91
}
92
93
int
94
is_export(const char *name)
95
{
96
struct sexport *tmp;
97
98
if (exports == NULL) /* no export list, all exported */
99
return 1;
100
101
for (tmp = exports; tmp != NULL; tmp = tmp->next) {
102
if (strcmp(tmp->name, name) == 0) {
103
tmp->defined = 1;
104
return 1;
105
}
106
}
107
return 0;
108
}
109
110
const char *
111
get_filename (void)
112
{
113
return orig_filename;
114
}
115
116
void
117
init_generate (const char *filename, const char *base)
118
{
119
char *fn = NULL;
120
121
orig_filename = filename;
122
if (base != NULL) {
123
headerbase = strdup(base);
124
if (headerbase == NULL)
125
errx(1, "strdup");
126
}
127
128
/* public header file */
129
if (asprintf(&header, "%s.h", headerbase) < 0 || header == NULL)
130
errx(1, "malloc");
131
if (asprintf(&fn, "%s.hx", headerbase) < 0 || fn == NULL)
132
errx(1, "malloc");
133
headerfile = fopen (fn, "w");
134
if (headerfile == NULL)
135
err (1, "open %s", fn);
136
free(fn);
137
fn = NULL;
138
139
/* private header file */
140
if (asprintf(&privheader, "%s-priv.h", headerbase) < 0 || privheader == NULL)
141
errx(1, "malloc");
142
if (asprintf(&fn, "%s-priv.hx", headerbase) < 0 || fn == NULL)
143
errx(1, "malloc");
144
privheaderfile = fopen (fn, "w");
145
if (privheaderfile == NULL)
146
err (1, "open %s", fn);
147
free(fn);
148
fn = NULL;
149
150
/* template file */
151
if (asprintf(&template, "%s-template.c", headerbase) < 0 || template == NULL)
152
errx(1, "malloc");
153
fprintf (headerfile,
154
"/* Generated from %s */\n"
155
"/* Do not edit */\n\n",
156
filename);
157
fprintf (headerfile,
158
"#ifndef __%s_h__\n"
159
"#define __%s_h__\n\n", headerbase, headerbase);
160
fprintf (headerfile,
161
"#include <stddef.h>\n"
162
"#include <time.h>\n\n");
163
fprintf (headerfile,
164
"#ifndef __asn1_common_definitions__\n"
165
"#define __asn1_common_definitions__\n\n");
166
fprintf (headerfile,
167
"typedef struct heim_integer {\n"
168
" size_t length;\n"
169
" void *data;\n"
170
" int negative;\n"
171
"} heim_integer;\n\n");
172
fprintf (headerfile,
173
"typedef struct heim_octet_string {\n"
174
" size_t length;\n"
175
" void *data;\n"
176
"} heim_octet_string;\n\n");
177
fprintf (headerfile,
178
"typedef char *heim_general_string;\n\n"
179
);
180
fprintf (headerfile,
181
"typedef char *heim_utf8_string;\n\n"
182
);
183
fprintf (headerfile,
184
"typedef struct heim_octet_string heim_printable_string;\n\n"
185
);
186
fprintf (headerfile,
187
"typedef struct heim_octet_string heim_ia5_string;\n\n"
188
);
189
fprintf (headerfile,
190
"typedef struct heim_bmp_string {\n"
191
" size_t length;\n"
192
" uint16_t *data;\n"
193
"} heim_bmp_string;\n\n");
194
fprintf (headerfile,
195
"typedef struct heim_universal_string {\n"
196
" size_t length;\n"
197
" uint32_t *data;\n"
198
"} heim_universal_string;\n\n");
199
fprintf (headerfile,
200
"typedef char *heim_visible_string;\n\n"
201
);
202
fprintf (headerfile,
203
"typedef struct heim_oid {\n"
204
" size_t length;\n"
205
" unsigned *components;\n"
206
"} heim_oid;\n\n");
207
fprintf (headerfile,
208
"typedef struct heim_bit_string {\n"
209
" size_t length;\n"
210
" void *data;\n"
211
"} heim_bit_string;\n\n");
212
fprintf (headerfile,
213
"typedef struct heim_octet_string heim_any;\n"
214
"typedef struct heim_octet_string heim_any_set;\n\n");
215
fputs("#define ASN1_MALLOC_ENCODE(T, B, BL, S, L, R) \\\n"
216
" do { \\\n"
217
" (BL) = length_##T((S)); \\\n"
218
" (B) = malloc((BL)); \\\n"
219
" if((B) == NULL) { \\\n"
220
" (R) = ENOMEM; \\\n"
221
" } else { \\\n"
222
" (R) = encode_##T(((unsigned char*)(B)) + (BL) - 1, (BL), \\\n"
223
" (S), (L)); \\\n"
224
" if((R) != 0) { \\\n"
225
" free((B)); \\\n"
226
" (B) = NULL; \\\n"
227
" } \\\n"
228
" } \\\n"
229
" } while (0)\n\n",
230
headerfile);
231
fputs("#ifdef _WIN32\n"
232
"#ifndef ASN1_LIB\n"
233
"#define ASN1EXP __declspec(dllimport)\n"
234
"#else\n"
235
"#define ASN1EXP\n"
236
"#endif\n"
237
"#define ASN1CALL __stdcall\n"
238
"#else\n"
239
"#define ASN1EXP\n"
240
"#define ASN1CALL\n"
241
"#endif\n",
242
headerfile);
243
fprintf (headerfile, "struct units;\n\n");
244
fprintf (headerfile, "#endif\n\n");
245
if (asprintf(&fn, "%s_files", base) < 0 || fn == NULL)
246
errx(1, "malloc");
247
logfile = fopen(fn, "w");
248
if (logfile == NULL)
249
err (1, "open %s", fn);
250
251
/* if one code file, write into the one codefile */
252
if (one_code_file)
253
return;
254
255
templatefile = fopen (template, "w");
256
if (templatefile == NULL)
257
err (1, "open %s", template);
258
259
fprintf (templatefile,
260
"/* Generated from %s */\n"
261
"/* Do not edit */\n\n"
262
"#include <stdio.h>\n"
263
"#include <stdlib.h>\n"
264
"#include <time.h>\n"
265
"#include <string.h>\n"
266
"#include <errno.h>\n"
267
"#include <limits.h>\n"
268
"#include <krb5-types.h>\n",
269
filename);
270
271
fprintf (templatefile,
272
"#include <%s>\n"
273
"#include <%s>\n"
274
"#include <der.h>\n"
275
"#include <der-private.h>\n"
276
"#include <asn1-template.h>\n",
277
header, privheader);
278
279
280
}
281
282
void
283
close_generate (void)
284
{
285
fprintf (headerfile, "#endif /* __%s_h__ */\n", headerbase);
286
287
if (headerfile)
288
fclose (headerfile);
289
if (privheaderfile)
290
fclose (privheaderfile);
291
if (templatefile)
292
fclose (templatefile);
293
if (logfile)
294
fprintf (logfile, "\n");
295
fclose (logfile);
296
}
297
298
void
299
gen_assign_defval(const char *var, struct value *val)
300
{
301
switch(val->type) {
302
case stringvalue:
303
fprintf(codefile, "if((%s = strdup(\"%s\")) == NULL)\nreturn ENOMEM;\n", var, val->u.stringvalue);
304
break;
305
case integervalue:
306
fprintf(codefile, "%s = %" PRId64 ";\n", var, val->u.integervalue);
307
break;
308
case booleanvalue:
309
if(val->u.booleanvalue)
310
fprintf(codefile, "%s = TRUE;\n", var);
311
else
312
fprintf(codefile, "%s = FALSE;\n", var);
313
break;
314
default:
315
abort();
316
}
317
}
318
319
void
320
gen_compare_defval(const char *var, struct value *val)
321
{
322
switch(val->type) {
323
case stringvalue:
324
fprintf(codefile, "if(strcmp(%s, \"%s\") != 0)\n", var, val->u.stringvalue);
325
break;
326
case integervalue:
327
fprintf(codefile, "if(%s != %" PRId64 ")\n", var, val->u.integervalue);
328
break;
329
case booleanvalue:
330
if(val->u.booleanvalue)
331
fprintf(codefile, "if(!%s)\n", var);
332
else
333
fprintf(codefile, "if(%s)\n", var);
334
break;
335
default:
336
abort();
337
}
338
}
339
340
void
341
generate_header_of_codefile(const char *name)
342
{
343
char *filename = NULL;
344
345
if (codefile != NULL)
346
abort();
347
348
if (asprintf (&filename, "%s_%s.x", STEM, name) < 0 || filename == NULL)
349
errx(1, "malloc");
350
codefile = fopen (filename, "w");
351
if (codefile == NULL)
352
err (1, "fopen %s", filename);
353
fprintf(logfile, "%s ", filename);
354
free(filename);
355
filename = NULL;
356
fprintf (codefile,
357
"/* Generated from %s */\n"
358
"/* Do not edit */\n\n"
359
"#define ASN1_LIB\n\n"
360
"#include <stdio.h>\n"
361
"#include <stdlib.h>\n"
362
"#include <time.h>\n"
363
"#include <string.h>\n"
364
"#include <errno.h>\n"
365
"#include <limits.h>\n"
366
"#include <krb5-types.h>\n",
367
orig_filename);
368
369
fprintf (codefile,
370
"#include <%s>\n"
371
"#include <%s>\n",
372
header, privheader);
373
fprintf (codefile,
374
"#include <asn1_err.h>\n"
375
"#include <der.h>\n"
376
"#include <der-private.h>\n"
377
"#include <asn1-template.h>\n"
378
"#include <parse_units.h>\n\n");
379
380
}
381
382
void
383
close_codefile(void)
384
{
385
if (codefile == NULL)
386
abort();
387
388
fclose(codefile);
389
codefile = NULL;
390
}
391
392
393
void
394
generate_constant (const Symbol *s)
395
{
396
switch(s->value->type) {
397
case booleanvalue:
398
break;
399
case integervalue:
400
fprintf (headerfile, "enum { %s = %" PRId64 " };\n\n",
401
s->gen_name, s->value->u.integervalue);
402
break;
403
case nullvalue:
404
break;
405
case stringvalue:
406
break;
407
case objectidentifiervalue: {
408
struct objid *o, **list;
409
unsigned int i, len;
410
char *gen_upper;
411
412
if (!one_code_file)
413
generate_header_of_codefile(s->gen_name);
414
415
len = 0;
416
for (o = s->value->u.objectidentifiervalue; o != NULL; o = o->next)
417
len++;
418
if (len == 0) {
419
printf("s->gen_name: %s",s->gen_name);
420
fflush(stdout);
421
break;
422
}
423
list = emalloc(sizeof(*list) * len);
424
425
i = 0;
426
for (o = s->value->u.objectidentifiervalue; o != NULL; o = o->next)
427
list[i++] = o;
428
429
fprintf (headerfile, "/* OBJECT IDENTIFIER %s ::= { ", s->name);
430
for (i = len ; i > 0; i--) {
431
o = list[i - 1];
432
fprintf(headerfile, "%s(%d) ",
433
o->label ? o->label : "label-less", o->value);
434
}
435
436
fprintf (codefile, "static unsigned oid_%s_variable_num[%d] = {",
437
s->gen_name, len);
438
for (i = len ; i > 0; i--) {
439
fprintf(codefile, "%d%s ", list[i - 1]->value, i > 1 ? "," : "");
440
}
441
fprintf(codefile, "};\n");
442
443
fprintf (codefile, "const heim_oid asn1_oid_%s = "
444
"{ %d, oid_%s_variable_num };\n\n",
445
s->gen_name, len, s->gen_name);
446
447
free(list);
448
449
/* header file */
450
451
gen_upper = strdup(s->gen_name);
452
len = strlen(gen_upper);
453
for (i = 0; i < len; i++)
454
gen_upper[i] = toupper((int)s->gen_name[i]);
455
456
fprintf (headerfile, "} */\n");
457
fprintf (headerfile,
458
"extern ASN1EXP const heim_oid asn1_oid_%s;\n"
459
"#define ASN1_OID_%s (&asn1_oid_%s)\n\n",
460
s->gen_name,
461
gen_upper,
462
s->gen_name);
463
464
free(gen_upper);
465
466
if (!one_code_file)
467
close_codefile();
468
469
break;
470
}
471
default:
472
abort();
473
}
474
}
475
476
int
477
is_primitive_type(int type)
478
{
479
switch(type) {
480
case TInteger:
481
case TBoolean:
482
case TOctetString:
483
case TBitString:
484
case TEnumerated:
485
case TGeneralizedTime:
486
case TGeneralString:
487
case TTeletexString:
488
case TOID:
489
case TUTCTime:
490
case TUTF8String:
491
case TPrintableString:
492
case TIA5String:
493
case TBMPString:
494
case TUniversalString:
495
case TVisibleString:
496
case TNull:
497
return 1;
498
default:
499
return 0;
500
}
501
}
502
503
static void
504
space(int level)
505
{
506
while(level-- > 0)
507
fprintf(headerfile, " ");
508
}
509
510
static const char *
511
last_member_p(struct member *m)
512
{
513
struct member *n = ASN1_TAILQ_NEXT(m, members);
514
if (n == NULL)
515
return "";
516
if (n->ellipsis && ASN1_TAILQ_NEXT(n, members) == NULL)
517
return "";
518
return ",";
519
}
520
521
static struct member *
522
have_ellipsis(Type *t)
523
{
524
struct member *m;
525
ASN1_TAILQ_FOREACH(m, t->members, members) {
526
if (m->ellipsis)
527
return m;
528
}
529
return NULL;
530
}
531
532
static void
533
define_asn1 (int level, Type *t)
534
{
535
switch (t->type) {
536
case TType:
537
fprintf (headerfile, "%s", t->symbol->name);
538
break;
539
case TInteger:
540
if(t->members == NULL) {
541
fprintf (headerfile, "INTEGER");
542
if (t->range)
543
fprintf (headerfile, " (%" PRId64 "..%" PRId64 ")",
544
t->range->min, t->range->max);
545
} else {
546
Member *m;
547
fprintf (headerfile, "INTEGER {\n");
548
ASN1_TAILQ_FOREACH(m, t->members, members) {
549
space (level + 1);
550
fprintf(headerfile, "%s(%d)%s\n", m->gen_name, m->val,
551
last_member_p(m));
552
}
553
space(level);
554
fprintf (headerfile, "}");
555
}
556
break;
557
case TBoolean:
558
fprintf (headerfile, "BOOLEAN");
559
break;
560
case TOctetString:
561
fprintf (headerfile, "OCTET STRING");
562
break;
563
case TEnumerated :
564
case TBitString: {
565
Member *m;
566
567
space(level);
568
if(t->type == TBitString)
569
fprintf (headerfile, "BIT STRING {\n");
570
else
571
fprintf (headerfile, "ENUMERATED {\n");
572
ASN1_TAILQ_FOREACH(m, t->members, members) {
573
space(level + 1);
574
fprintf (headerfile, "%s(%d)%s\n", m->name, m->val,
575
last_member_p(m));
576
}
577
space(level);
578
fprintf (headerfile, "}");
579
break;
580
}
581
case TChoice:
582
case TSet:
583
case TSequence: {
584
Member *m;
585
int max_width = 0;
586
587
if(t->type == TChoice)
588
fprintf(headerfile, "CHOICE {\n");
589
else if(t->type == TSet)
590
fprintf(headerfile, "SET {\n");
591
else
592
fprintf(headerfile, "SEQUENCE {\n");
593
ASN1_TAILQ_FOREACH(m, t->members, members) {
594
if(strlen(m->name) > max_width)
595
max_width = strlen(m->name);
596
}
597
max_width += 3;
598
if(max_width < 16) max_width = 16;
599
ASN1_TAILQ_FOREACH(m, t->members, members) {
600
int width = max_width;
601
space(level + 1);
602
if (m->ellipsis) {
603
fprintf (headerfile, "...");
604
} else {
605
width -= fprintf(headerfile, "%s", m->name);
606
fprintf(headerfile, "%*s", width, "");
607
define_asn1(level + 1, m->type);
608
if(m->optional)
609
fprintf(headerfile, " OPTIONAL");
610
}
611
if(last_member_p(m))
612
fprintf (headerfile, ",");
613
fprintf (headerfile, "\n");
614
}
615
space(level);
616
fprintf (headerfile, "}");
617
break;
618
}
619
case TSequenceOf:
620
fprintf (headerfile, "SEQUENCE OF ");
621
define_asn1 (0, t->subtype);
622
break;
623
case TSetOf:
624
fprintf (headerfile, "SET OF ");
625
define_asn1 (0, t->subtype);
626
break;
627
case TGeneralizedTime:
628
fprintf (headerfile, "GeneralizedTime");
629
break;
630
case TGeneralString:
631
fprintf (headerfile, "GeneralString");
632
break;
633
case TTeletexString:
634
fprintf (headerfile, "TeletexString");
635
break;
636
case TTag: {
637
const char *classnames[] = { "UNIVERSAL ", "APPLICATION ",
638
"" /* CONTEXT */, "PRIVATE " };
639
if(t->tag.tagclass != ASN1_C_UNIV)
640
fprintf (headerfile, "[%s%d] ",
641
classnames[t->tag.tagclass],
642
t->tag.tagvalue);
643
if(t->tag.tagenv == TE_IMPLICIT)
644
fprintf (headerfile, "IMPLICIT ");
645
define_asn1 (level, t->subtype);
646
break;
647
}
648
case TUTCTime:
649
fprintf (headerfile, "UTCTime");
650
break;
651
case TUTF8String:
652
space(level);
653
fprintf (headerfile, "UTF8String");
654
break;
655
case TPrintableString:
656
space(level);
657
fprintf (headerfile, "PrintableString");
658
break;
659
case TIA5String:
660
space(level);
661
fprintf (headerfile, "IA5String");
662
break;
663
case TBMPString:
664
space(level);
665
fprintf (headerfile, "BMPString");
666
break;
667
case TUniversalString:
668
space(level);
669
fprintf (headerfile, "UniversalString");
670
break;
671
case TVisibleString:
672
space(level);
673
fprintf (headerfile, "VisibleString");
674
break;
675
case TOID :
676
space(level);
677
fprintf(headerfile, "OBJECT IDENTIFIER");
678
break;
679
case TNull:
680
space(level);
681
fprintf (headerfile, "NULL");
682
break;
683
default:
684
abort ();
685
}
686
}
687
688
static void
689
getnewbasename(char **newbasename, int typedefp, const char *basename, const char *name)
690
{
691
if (typedefp)
692
*newbasename = strdup(name);
693
else {
694
if (name[0] == '*')
695
name++;
696
if (asprintf(newbasename, "%s_%s", basename, name) < 0)
697
errx(1, "malloc");
698
}
699
if (*newbasename == NULL)
700
err(1, "malloc");
701
}
702
703
static void
704
define_type (int level, const char *name, const char *basename, Type *t, int typedefp, int preservep)
705
{
706
char *newbasename = NULL;
707
708
switch (t->type) {
709
case TType:
710
space(level);
711
fprintf (headerfile, "%s %s;\n", t->symbol->gen_name, name);
712
break;
713
case TInteger:
714
space(level);
715
if(t->members) {
716
Member *m;
717
fprintf (headerfile, "enum %s {\n", typedefp ? name : "");
718
ASN1_TAILQ_FOREACH(m, t->members, members) {
719
space (level + 1);
720
fprintf(headerfile, "%s = %d%s\n", m->gen_name, m->val,
721
last_member_p(m));
722
}
723
fprintf (headerfile, "} %s;\n", name);
724
} else if (t->range == NULL) {
725
fprintf (headerfile, "heim_integer %s;\n", name);
726
} else if (t->range->min < INT_MIN && t->range->max <= INT64_MAX) {
727
fprintf (headerfile, "int64_t %s;\n", name);
728
} else if (t->range->min >= 0 && t->range->max > UINT_MAX) {
729
fprintf (headerfile, "uint64_t %s;\n", name);
730
} else if (t->range->min >= 0 && t->range->max <= UINT_MAX) {
731
fprintf (headerfile, "unsigned int %s;\n", name);
732
} else if (t->range->min >= INT_MIN && t->range->max <= INT_MAX) {
733
fprintf (headerfile, "int %s;\n", name);
734
} else
735
errx(1, "%s: unsupported range %" PRId64 " -> %" PRId64 "",
736
name, t->range->min, t->range->max);
737
break;
738
case TBoolean:
739
space(level);
740
fprintf (headerfile, "int %s;\n", name);
741
break;
742
case TOctetString:
743
space(level);
744
fprintf (headerfile, "heim_octet_string %s;\n", name);
745
break;
746
case TBitString: {
747
Member *m;
748
Type i;
749
struct range range = { 0, INT_MAX };
750
751
i.type = TInteger;
752
i.range = &range;
753
i.members = NULL;
754
i.constraint = NULL;
755
756
space(level);
757
if(ASN1_TAILQ_EMPTY(t->members))
758
fprintf (headerfile, "heim_bit_string %s;\n", name);
759
else {
760
int pos = 0;
761
getnewbasename(&newbasename, typedefp, basename, name);
762
763
fprintf (headerfile, "struct %s {\n", newbasename);
764
ASN1_TAILQ_FOREACH(m, t->members, members) {
765
char *n = NULL;
766
767
/* pad unused */
768
while (pos < m->val) {
769
if (asprintf (&n, "_unused%d:1", pos) < 0 || n == NULL)
770
errx(1, "malloc");
771
define_type (level + 1, n, newbasename, &i, FALSE, FALSE);
772
free(n);
773
pos++;
774
}
775
776
n = NULL;
777
if (asprintf (&n, "%s:1", m->gen_name) < 0 || n == NULL)
778
errx(1, "malloc");
779
define_type (level + 1, n, newbasename, &i, FALSE, FALSE);
780
free (n);
781
n = NULL;
782
pos++;
783
}
784
/* pad to 32 elements */
785
while (pos < 32) {
786
char *n = NULL;
787
if (asprintf (&n, "_unused%d:1", pos) < 0 || n == NULL)
788
errx(1, "malloc");
789
define_type (level + 1, n, newbasename, &i, FALSE, FALSE);
790
free(n);
791
pos++;
792
}
793
794
space(level);
795
fprintf (headerfile, "} %s;\n\n", name);
796
}
797
break;
798
}
799
case TEnumerated: {
800
Member *m;
801
802
space(level);
803
fprintf (headerfile, "enum %s {\n", typedefp ? name : "");
804
ASN1_TAILQ_FOREACH(m, t->members, members) {
805
space(level + 1);
806
if (m->ellipsis)
807
fprintf (headerfile, "/* ... */\n");
808
else
809
fprintf (headerfile, "%s = %d%s\n", m->gen_name, m->val,
810
last_member_p(m));
811
}
812
space(level);
813
fprintf (headerfile, "} %s;\n\n", name);
814
break;
815
}
816
case TSet:
817
case TSequence: {
818
Member *m;
819
820
getnewbasename(&newbasename, typedefp, basename, name);
821
822
space(level);
823
fprintf (headerfile, "struct %s {\n", newbasename);
824
if (t->type == TSequence && preservep) {
825
space(level + 1);
826
fprintf(headerfile, "heim_octet_string _save;\n");
827
}
828
ASN1_TAILQ_FOREACH(m, t->members, members) {
829
if (m->ellipsis) {
830
;
831
} else if (m->optional) {
832
char *n = NULL;
833
834
if (asprintf (&n, "*%s", m->gen_name) < 0 || n == NULL)
835
errx(1, "malloc");
836
define_type (level + 1, n, newbasename, m->type, FALSE, FALSE);
837
free (n);
838
} else
839
define_type (level + 1, m->gen_name, newbasename, m->type, FALSE, FALSE);
840
}
841
space(level);
842
fprintf (headerfile, "} %s;\n", name);
843
break;
844
}
845
case TSetOf:
846
case TSequenceOf: {
847
Type i;
848
struct range range = { 0, INT_MAX };
849
850
getnewbasename(&newbasename, typedefp, basename, name);
851
852
i.type = TInteger;
853
i.range = &range;
854
i.members = NULL;
855
i.constraint = NULL;
856
857
space(level);
858
fprintf (headerfile, "struct %s {\n", newbasename);
859
define_type (level + 1, "len", newbasename, &i, FALSE, FALSE);
860
define_type (level + 1, "*val", newbasename, t->subtype, FALSE, FALSE);
861
space(level);
862
fprintf (headerfile, "} %s;\n", name);
863
break;
864
}
865
case TGeneralizedTime:
866
space(level);
867
fprintf (headerfile, "time_t %s;\n", name);
868
break;
869
case TGeneralString:
870
space(level);
871
fprintf (headerfile, "heim_general_string %s;\n", name);
872
break;
873
case TTeletexString:
874
space(level);
875
fprintf (headerfile, "heim_general_string %s;\n", name);
876
break;
877
case TTag:
878
define_type (level, name, basename, t->subtype, typedefp, preservep);
879
break;
880
case TChoice: {
881
int first = 1;
882
Member *m;
883
884
getnewbasename(&newbasename, typedefp, basename, name);
885
886
space(level);
887
fprintf (headerfile, "struct %s {\n", newbasename);
888
if (preservep) {
889
space(level + 1);
890
fprintf(headerfile, "heim_octet_string _save;\n");
891
}
892
space(level + 1);
893
fprintf (headerfile, "enum {\n");
894
m = have_ellipsis(t);
895
if (m) {
896
space(level + 2);
897
fprintf (headerfile, "%s = 0,\n", m->label);
898
first = 0;
899
}
900
ASN1_TAILQ_FOREACH(m, t->members, members) {
901
space(level + 2);
902
if (m->ellipsis)
903
fprintf (headerfile, "/* ... */\n");
904
else
905
fprintf (headerfile, "%s%s%s\n", m->label,
906
first ? " = 1" : "",
907
last_member_p(m));
908
first = 0;
909
}
910
space(level + 1);
911
fprintf (headerfile, "} element;\n");
912
space(level + 1);
913
fprintf (headerfile, "union {\n");
914
ASN1_TAILQ_FOREACH(m, t->members, members) {
915
if (m->ellipsis) {
916
space(level + 2);
917
fprintf(headerfile, "heim_octet_string asn1_ellipsis;\n");
918
} else if (m->optional) {
919
char *n = NULL;
920
921
if (asprintf (&n, "*%s", m->gen_name) < 0 || n == NULL)
922
errx(1, "malloc");
923
define_type (level + 2, n, newbasename, m->type, FALSE, FALSE);
924
free (n);
925
} else
926
define_type (level + 2, m->gen_name, newbasename, m->type, FALSE, FALSE);
927
}
928
space(level + 1);
929
fprintf (headerfile, "} u;\n");
930
space(level);
931
fprintf (headerfile, "} %s;\n", name);
932
break;
933
}
934
case TUTCTime:
935
space(level);
936
fprintf (headerfile, "time_t %s;\n", name);
937
break;
938
case TUTF8String:
939
space(level);
940
fprintf (headerfile, "heim_utf8_string %s;\n", name);
941
break;
942
case TPrintableString:
943
space(level);
944
fprintf (headerfile, "heim_printable_string %s;\n", name);
945
break;
946
case TIA5String:
947
space(level);
948
fprintf (headerfile, "heim_ia5_string %s;\n", name);
949
break;
950
case TBMPString:
951
space(level);
952
fprintf (headerfile, "heim_bmp_string %s;\n", name);
953
break;
954
case TUniversalString:
955
space(level);
956
fprintf (headerfile, "heim_universal_string %s;\n", name);
957
break;
958
case TVisibleString:
959
space(level);
960
fprintf (headerfile, "heim_visible_string %s;\n", name);
961
break;
962
case TOID :
963
space(level);
964
fprintf (headerfile, "heim_oid %s;\n", name);
965
break;
966
case TNull:
967
space(level);
968
fprintf (headerfile, "int %s;\n", name);
969
break;
970
default:
971
abort ();
972
}
973
if (newbasename)
974
free(newbasename);
975
}
976
977
static void
978
generate_type_header (const Symbol *s)
979
{
980
int preservep = preserve_type(s->name) ? TRUE : FALSE;
981
982
fprintf (headerfile, "/*\n");
983
fprintf (headerfile, "%s ::= ", s->name);
984
define_asn1 (0, s->type);
985
fprintf (headerfile, "\n*/\n\n");
986
987
fprintf (headerfile, "typedef ");
988
define_type (0, s->gen_name, s->gen_name, s->type, TRUE, preservep);
989
990
fprintf (headerfile, "\n");
991
}
992
993
void
994
generate_type (const Symbol *s)
995
{
996
FILE *h;
997
const char * exp;
998
999
if (!one_code_file)
1000
generate_header_of_codefile(s->gen_name);
1001
1002
generate_type_header (s);
1003
1004
if (template_flag)
1005
generate_template(s);
1006
1007
if (template_flag == 0 || is_template_compat(s) == 0) {
1008
generate_type_encode (s);
1009
generate_type_decode (s);
1010
generate_type_free (s);
1011
generate_type_length (s);
1012
generate_type_copy (s);
1013
}
1014
generate_type_seq (s);
1015
generate_glue (s->type, s->gen_name);
1016
1017
/* generate prototypes */
1018
1019
if (is_export(s->name)) {
1020
h = headerfile;
1021
exp = "ASN1EXP ";
1022
} else {
1023
h = privheaderfile;
1024
exp = "";
1025
}
1026
1027
fprintf (h,
1028
"%sint ASN1CALL "
1029
"decode_%s(const unsigned char *, size_t, %s *, size_t *);\n",
1030
exp,
1031
s->gen_name, s->gen_name);
1032
fprintf (h,
1033
"%sint ASN1CALL "
1034
"encode_%s(unsigned char *, size_t, const %s *, size_t *);\n",
1035
exp,
1036
s->gen_name, s->gen_name);
1037
fprintf (h,
1038
"%ssize_t ASN1CALL length_%s(const %s *);\n",
1039
exp,
1040
s->gen_name, s->gen_name);
1041
fprintf (h,
1042
"%sint ASN1CALL copy_%s (const %s *, %s *);\n",
1043
exp,
1044
s->gen_name, s->gen_name, s->gen_name);
1045
fprintf (h,
1046
"%svoid ASN1CALL free_%s (%s *);\n",
1047
exp,
1048
s->gen_name, s->gen_name);
1049
1050
fprintf(h, "\n\n");
1051
1052
if (!one_code_file) {
1053
fprintf(codefile, "\n\n");
1054
close_codefile();
1055
}
1056
}
1057
1058