xref: /freebsd/crypto/heimdal/lib/asn1/asn1parse.y (revision 0afa8e065e14bb8fd338d75690e0238c00167d40)
1 /*
2  * Copyright (c) 1997 - 2007 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 /* $Id$ */
37 
38 %{
39 
40 #include <config.h>
41 
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include "symbol.h"
46 #include "lex.h"
47 #include "gen_locl.h"
48 #include "der.h"
49 
50 RCSID("$Id$");
51 
52 static Type *new_type (Typetype t);
53 static struct constraint_spec *new_constraint_spec(enum ctype);
54 static Type *new_tag(int tagclass, int tagvalue, int tagenv, Type *oldtype);
55 void yyerror (const char *);
56 static struct objid *new_objid(const char *label, int value);
57 static void add_oid_to_tail(struct objid *, struct objid *);
58 static void fix_labels(Symbol *s);
59 
60 struct string_list {
61     char *string;
62     struct string_list *next;
63 };
64 
65 /* Declarations for Bison */
66 #define YYMALLOC malloc
67 #define YYFREE   free
68 
69 %}
70 
71 %union {
72     int constant;
73     struct value *value;
74     struct range *range;
75     char *name;
76     Type *type;
77     Member *member;
78     struct objid *objid;
79     char *defval;
80     struct string_list *sl;
81     struct tagtype tag;
82     struct memhead *members;
83     struct constraint_spec *constraint_spec;
84 }
85 
86 %token kw_ABSENT
87 %token kw_ABSTRACT_SYNTAX
88 %token kw_ALL
89 %token kw_APPLICATION
90 %token kw_AUTOMATIC
91 %token kw_BEGIN
92 %token kw_BIT
93 %token kw_BMPString
94 %token kw_BOOLEAN
95 %token kw_BY
96 %token kw_CHARACTER
97 %token kw_CHOICE
98 %token kw_CLASS
99 %token kw_COMPONENT
100 %token kw_COMPONENTS
101 %token kw_CONSTRAINED
102 %token kw_CONTAINING
103 %token kw_DEFAULT
104 %token kw_DEFINITIONS
105 %token kw_EMBEDDED
106 %token kw_ENCODED
107 %token kw_END
108 %token kw_ENUMERATED
109 %token kw_EXCEPT
110 %token kw_EXPLICIT
111 %token kw_EXPORTS
112 %token kw_EXTENSIBILITY
113 %token kw_EXTERNAL
114 %token kw_FALSE
115 %token kw_FROM
116 %token kw_GeneralString
117 %token kw_GeneralizedTime
118 %token kw_GraphicString
119 %token kw_IA5String
120 %token kw_IDENTIFIER
121 %token kw_IMPLICIT
122 %token kw_IMPLIED
123 %token kw_IMPORTS
124 %token kw_INCLUDES
125 %token kw_INSTANCE
126 %token kw_INTEGER
127 %token kw_INTERSECTION
128 %token kw_ISO646String
129 %token kw_MAX
130 %token kw_MIN
131 %token kw_MINUS_INFINITY
132 %token kw_NULL
133 %token kw_NumericString
134 %token kw_OBJECT
135 %token kw_OCTET
136 %token kw_OF
137 %token kw_OPTIONAL
138 %token kw_ObjectDescriptor
139 %token kw_PATTERN
140 %token kw_PDV
141 %token kw_PLUS_INFINITY
142 %token kw_PRESENT
143 %token kw_PRIVATE
144 %token kw_PrintableString
145 %token kw_REAL
146 %token kw_RELATIVE_OID
147 %token kw_SEQUENCE
148 %token kw_SET
149 %token kw_SIZE
150 %token kw_STRING
151 %token kw_SYNTAX
152 %token kw_T61String
153 %token kw_TAGS
154 %token kw_TRUE
155 %token kw_TYPE_IDENTIFIER
156 %token kw_TeletexString
157 %token kw_UNION
158 %token kw_UNIQUE
159 %token kw_UNIVERSAL
160 %token kw_UTCTime
161 %token kw_UTF8String
162 %token kw_UniversalString
163 %token kw_VideotexString
164 %token kw_VisibleString
165 %token kw_WITH
166 
167 %token RANGE
168 %token EEQUAL
169 %token ELLIPSIS
170 
171 %token <name> IDENTIFIER  referencename
172 %token <name> STRING
173 
174 %token <constant> NUMBER
175 %type <constant> SignedNumber
176 %type <constant> Class tagenv
177 
178 %type <value> Value
179 %type <value> BuiltinValue
180 %type <value> IntegerValue
181 %type <value> BooleanValue
182 %type <value> ObjectIdentifierValue
183 %type <value> CharacterStringValue
184 %type <value> NullValue
185 %type <value> DefinedValue
186 %type <value> ReferencedValue
187 %type <value> Valuereference
188 
189 %type <type> Type
190 %type <type> BuiltinType
191 %type <type> BitStringType
192 %type <type> BooleanType
193 %type <type> ChoiceType
194 %type <type> ConstrainedType
195 %type <type> EnumeratedType
196 %type <type> IntegerType
197 %type <type> NullType
198 %type <type> OctetStringType
199 %type <type> SequenceType
200 %type <type> SequenceOfType
201 %type <type> SetType
202 %type <type> SetOfType
203 %type <type> TaggedType
204 %type <type> ReferencedType
205 %type <type> DefinedType
206 %type <type> UsefulType
207 %type <type> ObjectIdentifierType
208 %type <type> CharacterStringType
209 %type <type> RestrictedCharactedStringType
210 
211 %type <tag> Tag
212 
213 %type <member> ComponentType
214 %type <member> NamedBit
215 %type <member> NamedNumber
216 %type <member> NamedType
217 %type <members> ComponentTypeList
218 %type <members> Enumerations
219 %type <members> NamedBitList
220 %type <members> NamedNumberList
221 
222 %type <objid> objid objid_list objid_element objid_opt
223 %type <range> range size
224 
225 %type <sl> referencenames
226 
227 %type <constraint_spec> Constraint
228 %type <constraint_spec> ConstraintSpec
229 %type <constraint_spec> GeneralConstraint
230 %type <constraint_spec> ContentsConstraint
231 %type <constraint_spec> UserDefinedConstraint
232 
233 
234 
235 %start ModuleDefinition
236 
237 %%
238 
239 ModuleDefinition: IDENTIFIER objid_opt kw_DEFINITIONS TagDefault ExtensionDefault
240 			EEQUAL kw_BEGIN ModuleBody kw_END
241 		{
242 			checkundefined();
243 		}
244 		;
245 
246 TagDefault	: kw_EXPLICIT kw_TAGS
247 		| kw_IMPLICIT kw_TAGS
248 		      { lex_error_message("implicit tagging is not supported"); }
249 		| kw_AUTOMATIC kw_TAGS
250 		      { lex_error_message("automatic tagging is not supported"); }
251 		| /* empty */
252 		;
253 
254 ExtensionDefault: kw_EXTENSIBILITY kw_IMPLIED
255 		      { lex_error_message("no extensibility options supported"); }
256 		| /* empty */
257 		;
258 
259 ModuleBody	: Exports Imports AssignmentList
260 		| /* empty */
261 		;
262 
263 Imports		: kw_IMPORTS SymbolsImported ';'
264 		| /* empty */
265 		;
266 
267 SymbolsImported	: SymbolsFromModuleList
268 		| /* empty */
269 		;
270 
271 SymbolsFromModuleList: SymbolsFromModule
272 		| SymbolsFromModuleList SymbolsFromModule
273 		;
274 
275 SymbolsFromModule: referencenames kw_FROM IDENTIFIER objid_opt
276 		{
277 		    struct string_list *sl;
278 		    for(sl = $1; sl != NULL; sl = sl->next) {
279 			Symbol *s = addsym(sl->string);
280 			s->stype = Stype;
281 			gen_template_import(s);
282 		    }
283 		    add_import($3);
284 		}
285 		;
286 
287 Exports		: kw_EXPORTS referencenames ';'
288 		{
289 		    struct string_list *sl;
290 		    for(sl = $2; sl != NULL; sl = sl->next)
291 			add_export(sl->string);
292 		}
293 		| kw_EXPORTS kw_ALL
294 		| /* empty */
295 		;
296 
297 AssignmentList	: Assignment
298 		| Assignment AssignmentList
299 		;
300 
301 Assignment	: TypeAssignment
302 		| ValueAssignment
303 		;
304 
305 referencenames	: IDENTIFIER ',' referencenames
306 		{
307 		    $$ = emalloc(sizeof(*$$));
308 		    $$->string = $1;
309 		    $$->next = $3;
310 		}
311 		| IDENTIFIER
312 		{
313 		    $$ = emalloc(sizeof(*$$));
314 		    $$->string = $1;
315 		    $$->next = NULL;
316 		}
317 		;
318 
319 TypeAssignment	: IDENTIFIER EEQUAL Type
320 		{
321 		    Symbol *s = addsym ($1);
322 		    s->stype = Stype;
323 		    s->type = $3;
324 		    fix_labels(s);
325 		    generate_type (s);
326 		}
327 		;
328 
329 Type		: BuiltinType
330 		| ReferencedType
331 		| ConstrainedType
332 		;
333 
334 BuiltinType	: BitStringType
335 		| BooleanType
336 		| CharacterStringType
337 		| ChoiceType
338 		| EnumeratedType
339 		| IntegerType
340 		| NullType
341 		| ObjectIdentifierType
342 		| OctetStringType
343 		| SequenceType
344 		| SequenceOfType
345 		| SetType
346 		| SetOfType
347 		| TaggedType
348 		;
349 
350 BooleanType	: kw_BOOLEAN
351 		{
352 			$$ = new_tag(ASN1_C_UNIV, UT_Boolean,
353 				     TE_EXPLICIT, new_type(TBoolean));
354 		}
355 		;
356 
357 range		: '(' Value RANGE Value ')'
358 		{
359 		    if($2->type != integervalue)
360 			lex_error_message("Non-integer used in first part of range");
361 		    if($2->type != integervalue)
362 			lex_error_message("Non-integer in second part of range");
363 		    $$ = ecalloc(1, sizeof(*$$));
364 		    $$->min = $2->u.integervalue;
365 		    $$->max = $4->u.integervalue;
366 		}
367 		| '(' Value RANGE kw_MAX ')'
368 		{
369 		    if($2->type != integervalue)
370 			lex_error_message("Non-integer in first part of range");
371 		    $$ = ecalloc(1, sizeof(*$$));
372 		    $$->min = $2->u.integervalue;
373 		    $$->max = $2->u.integervalue - 1;
374 		}
375 		| '(' kw_MIN RANGE Value ')'
376 		{
377 		    if($4->type != integervalue)
378 			lex_error_message("Non-integer in second part of range");
379 		    $$ = ecalloc(1, sizeof(*$$));
380 		    $$->min = $4->u.integervalue + 2;
381 		    $$->max = $4->u.integervalue;
382 		}
383 		| '(' Value ')'
384 		{
385 		    if($2->type != integervalue)
386 			lex_error_message("Non-integer used in limit");
387 		    $$ = ecalloc(1, sizeof(*$$));
388 		    $$->min = $2->u.integervalue;
389 		    $$->max = $2->u.integervalue;
390 		}
391 		;
392 
393 
394 IntegerType	: kw_INTEGER
395 		{
396 			$$ = new_tag(ASN1_C_UNIV, UT_Integer,
397 				     TE_EXPLICIT, new_type(TInteger));
398 		}
399 		| kw_INTEGER range
400 		{
401 			$$ = new_type(TInteger);
402 			$$->range = $2;
403 			$$ = new_tag(ASN1_C_UNIV, UT_Integer, TE_EXPLICIT, $$);
404 		}
405 		| kw_INTEGER '{' NamedNumberList '}'
406 		{
407 		  $$ = new_type(TInteger);
408 		  $$->members = $3;
409 		  $$ = new_tag(ASN1_C_UNIV, UT_Integer, TE_EXPLICIT, $$);
410 		}
411 		;
412 
413 NamedNumberList	: NamedNumber
414 		{
415 			$$ = emalloc(sizeof(*$$));
416 			ASN1_TAILQ_INIT($$);
417 			ASN1_TAILQ_INSERT_HEAD($$, $1, members);
418 		}
419 		| NamedNumberList ',' NamedNumber
420 		{
421 			ASN1_TAILQ_INSERT_TAIL($1, $3, members);
422 			$$ = $1;
423 		}
424 		| NamedNumberList ',' ELLIPSIS
425 			{ $$ = $1; } /* XXX used for Enumerations */
426 		;
427 
428 NamedNumber	: IDENTIFIER '(' SignedNumber ')'
429 		{
430 			$$ = emalloc(sizeof(*$$));
431 			$$->name = $1;
432 			$$->gen_name = estrdup($1);
433 			output_name ($$->gen_name);
434 			$$->val = $3;
435 			$$->optional = 0;
436 			$$->ellipsis = 0;
437 			$$->type = NULL;
438 		}
439 		;
440 
441 EnumeratedType	: kw_ENUMERATED '{' Enumerations '}'
442 		{
443 		  $$ = new_type(TInteger);
444 		  $$->members = $3;
445 		  $$ = new_tag(ASN1_C_UNIV, UT_Enumerated, TE_EXPLICIT, $$);
446 		}
447 		;
448 
449 Enumerations	: NamedNumberList /* XXX */
450 		;
451 
452 BitStringType	: kw_BIT kw_STRING
453 		{
454 		  $$ = new_type(TBitString);
455 		  $$->members = emalloc(sizeof(*$$->members));
456 		  ASN1_TAILQ_INIT($$->members);
457 		  $$ = new_tag(ASN1_C_UNIV, UT_BitString, TE_EXPLICIT, $$);
458 		}
459 		| kw_BIT kw_STRING '{' NamedBitList '}'
460 		{
461 		  $$ = new_type(TBitString);
462 		  $$->members = $4;
463 		  $$ = new_tag(ASN1_C_UNIV, UT_BitString, TE_EXPLICIT, $$);
464 		}
465 		;
466 
467 ObjectIdentifierType: kw_OBJECT kw_IDENTIFIER
468 		{
469 			$$ = new_tag(ASN1_C_UNIV, UT_OID,
470 				     TE_EXPLICIT, new_type(TOID));
471 		}
472 		;
473 OctetStringType	: kw_OCTET kw_STRING size
474 		{
475 		    Type *t = new_type(TOctetString);
476 		    t->range = $3;
477 		    $$ = new_tag(ASN1_C_UNIV, UT_OctetString,
478 				 TE_EXPLICIT, t);
479 		}
480 		;
481 
482 NullType	: kw_NULL
483 		{
484 			$$ = new_tag(ASN1_C_UNIV, UT_Null,
485 				     TE_EXPLICIT, new_type(TNull));
486 		}
487 		;
488 
489 size		:
490 		{ $$ = NULL; }
491 		| kw_SIZE range
492 		{ $$ = $2; }
493 		;
494 
495 
496 SequenceType	: kw_SEQUENCE '{' /* ComponentTypeLists */ ComponentTypeList '}'
497 		{
498 		  $$ = new_type(TSequence);
499 		  $$->members = $3;
500 		  $$ = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, $$);
501 		}
502 		| kw_SEQUENCE '{' '}'
503 		{
504 		  $$ = new_type(TSequence);
505 		  $$->members = NULL;
506 		  $$ = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, $$);
507 		}
508 		;
509 
510 SequenceOfType	: kw_SEQUENCE size kw_OF Type
511 		{
512 		  $$ = new_type(TSequenceOf);
513 		  $$->range = $2;
514 		  $$->subtype = $4;
515 		  $$ = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, $$);
516 		}
517 		;
518 
519 SetType		: kw_SET '{' /* ComponentTypeLists */ ComponentTypeList '}'
520 		{
521 		  $$ = new_type(TSet);
522 		  $$->members = $3;
523 		  $$ = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, $$);
524 		}
525 		| kw_SET '{' '}'
526 		{
527 		  $$ = new_type(TSet);
528 		  $$->members = NULL;
529 		  $$ = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, $$);
530 		}
531 		;
532 
533 SetOfType	: kw_SET kw_OF Type
534 		{
535 		  $$ = new_type(TSetOf);
536 		  $$->subtype = $3;
537 		  $$ = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, $$);
538 		}
539 		;
540 
541 ChoiceType	: kw_CHOICE '{' /* AlternativeTypeLists */ ComponentTypeList '}'
542 		{
543 		  $$ = new_type(TChoice);
544 		  $$->members = $3;
545 		}
546 		;
547 
548 ReferencedType	: DefinedType
549 		| UsefulType
550 		;
551 
552 DefinedType	: IDENTIFIER
553 		{
554 		  Symbol *s = addsym($1);
555 		  $$ = new_type(TType);
556 		  if(s->stype != Stype && s->stype != SUndefined)
557 		    lex_error_message ("%s is not a type\n", $1);
558 		  else
559 		    $$->symbol = s;
560 		}
561 		;
562 
563 UsefulType	: kw_GeneralizedTime
564 		{
565 			$$ = new_tag(ASN1_C_UNIV, UT_GeneralizedTime,
566 				     TE_EXPLICIT, new_type(TGeneralizedTime));
567 		}
568 		| kw_UTCTime
569 		{
570 			$$ = new_tag(ASN1_C_UNIV, UT_UTCTime,
571 				     TE_EXPLICIT, new_type(TUTCTime));
572 		}
573 		;
574 
575 ConstrainedType	: Type Constraint
576 		{
577 		    /* if (Constraint.type == contentConstrant) {
578 		       assert(Constraint.u.constraint.type == octetstring|bitstring-w/o-NamedBitList); // remember to check type reference too
579 		       if (Constraint.u.constraint.type) {
580 		         assert((Constraint.u.constraint.type.length % 8) == 0);
581 		       }
582 		      }
583 		      if (Constraint.u.constraint.encoding) {
584 		        type == der-oid|ber-oid
585 		      }
586 		    */
587 		}
588 		;
589 
590 
591 Constraint	: '(' ConstraintSpec ')'
592 		{
593 		    $$ = $2;
594 		}
595 		;
596 
597 ConstraintSpec	: GeneralConstraint
598 		;
599 
600 GeneralConstraint: ContentsConstraint
601 		| UserDefinedConstraint
602 		;
603 
604 ContentsConstraint: kw_CONTAINING Type
605 		{
606 		    $$ = new_constraint_spec(CT_CONTENTS);
607 		    $$->u.content.type = $2;
608 		    $$->u.content.encoding = NULL;
609 		}
610 		| kw_ENCODED kw_BY Value
611 		{
612 		    if ($3->type != objectidentifiervalue)
613 			lex_error_message("Non-OID used in ENCODED BY constraint");
614 		    $$ = new_constraint_spec(CT_CONTENTS);
615 		    $$->u.content.type = NULL;
616 		    $$->u.content.encoding = $3;
617 		}
618 		| kw_CONTAINING Type kw_ENCODED kw_BY Value
619 		{
620 		    if ($5->type != objectidentifiervalue)
621 			lex_error_message("Non-OID used in ENCODED BY constraint");
622 		    $$ = new_constraint_spec(CT_CONTENTS);
623 		    $$->u.content.type = $2;
624 		    $$->u.content.encoding = $5;
625 		}
626 		;
627 
628 UserDefinedConstraint: kw_CONSTRAINED kw_BY '{' '}'
629 		{
630 		    $$ = new_constraint_spec(CT_USER);
631 		}
632 		;
633 
634 TaggedType	: Tag tagenv Type
635 		{
636 			$$ = new_type(TTag);
637 			$$->tag = $1;
638 			$$->tag.tagenv = $2;
639 			if($3->type == TTag && $2 == TE_IMPLICIT) {
640 				$$->subtype = $3->subtype;
641 				free($3);
642 			} else
643 				$$->subtype = $3;
644 		}
645 		;
646 
647 Tag		: '[' Class NUMBER ']'
648 		{
649 			$$.tagclass = $2;
650 			$$.tagvalue = $3;
651 			$$.tagenv = TE_EXPLICIT;
652 		}
653 		;
654 
655 Class		: /* */
656 		{
657 			$$ = ASN1_C_CONTEXT;
658 		}
659 		| kw_UNIVERSAL
660 		{
661 			$$ = ASN1_C_UNIV;
662 		}
663 		| kw_APPLICATION
664 		{
665 			$$ = ASN1_C_APPL;
666 		}
667 		| kw_PRIVATE
668 		{
669 			$$ = ASN1_C_PRIVATE;
670 		}
671 		;
672 
673 tagenv		: /* */
674 		{
675 			$$ = TE_EXPLICIT;
676 		}
677 		| kw_EXPLICIT
678 		{
679 			$$ = TE_EXPLICIT;
680 		}
681 		| kw_IMPLICIT
682 		{
683 			$$ = TE_IMPLICIT;
684 		}
685 		;
686 
687 
688 ValueAssignment	: IDENTIFIER Type EEQUAL Value
689 		{
690 			Symbol *s;
691 			s = addsym ($1);
692 
693 			s->stype = SValue;
694 			s->value = $4;
695 			generate_constant (s);
696 		}
697 		;
698 
699 CharacterStringType: RestrictedCharactedStringType
700 		;
701 
702 RestrictedCharactedStringType: kw_GeneralString
703 		{
704 			$$ = new_tag(ASN1_C_UNIV, UT_GeneralString,
705 				     TE_EXPLICIT, new_type(TGeneralString));
706 		}
707 		| kw_TeletexString
708 		{
709 			$$ = new_tag(ASN1_C_UNIV, UT_TeletexString,
710 				     TE_EXPLICIT, new_type(TTeletexString));
711 		}
712 		| kw_UTF8String
713 		{
714 			$$ = new_tag(ASN1_C_UNIV, UT_UTF8String,
715 				     TE_EXPLICIT, new_type(TUTF8String));
716 		}
717 		| kw_PrintableString
718 		{
719 			$$ = new_tag(ASN1_C_UNIV, UT_PrintableString,
720 				     TE_EXPLICIT, new_type(TPrintableString));
721 		}
722 		| kw_VisibleString
723 		{
724 			$$ = new_tag(ASN1_C_UNIV, UT_VisibleString,
725 				     TE_EXPLICIT, new_type(TVisibleString));
726 		}
727 		| kw_IA5String
728 		{
729 			$$ = new_tag(ASN1_C_UNIV, UT_IA5String,
730 				     TE_EXPLICIT, new_type(TIA5String));
731 		}
732 		| kw_BMPString
733 		{
734 			$$ = new_tag(ASN1_C_UNIV, UT_BMPString,
735 				     TE_EXPLICIT, new_type(TBMPString));
736 		}
737 		| kw_UniversalString
738 		{
739 			$$ = new_tag(ASN1_C_UNIV, UT_UniversalString,
740 				     TE_EXPLICIT, new_type(TUniversalString));
741 		}
742 
743 		;
744 
745 ComponentTypeList: ComponentType
746 		{
747 			$$ = emalloc(sizeof(*$$));
748 			ASN1_TAILQ_INIT($$);
749 			ASN1_TAILQ_INSERT_HEAD($$, $1, members);
750 		}
751 		| ComponentTypeList ',' ComponentType
752 		{
753 			ASN1_TAILQ_INSERT_TAIL($1, $3, members);
754 			$$ = $1;
755 		}
756 		| ComponentTypeList ',' ELLIPSIS
757 		{
758 		        struct member *m = ecalloc(1, sizeof(*m));
759 			m->name = estrdup("...");
760 			m->gen_name = estrdup("asn1_ellipsis");
761 			m->ellipsis = 1;
762 			ASN1_TAILQ_INSERT_TAIL($1, m, members);
763 			$$ = $1;
764 		}
765 		;
766 
767 NamedType	: IDENTIFIER Type
768 		{
769 		  $$ = emalloc(sizeof(*$$));
770 		  $$->name = $1;
771 		  $$->gen_name = estrdup($1);
772 		  output_name ($$->gen_name);
773 		  $$->type = $2;
774 		  $$->ellipsis = 0;
775 		}
776 		;
777 
778 ComponentType	: NamedType
779 		{
780 			$$ = $1;
781 			$$->optional = 0;
782 			$$->defval = NULL;
783 		}
784 		| NamedType kw_OPTIONAL
785 		{
786 			$$ = $1;
787 			$$->optional = 1;
788 			$$->defval = NULL;
789 		}
790 		| NamedType kw_DEFAULT Value
791 		{
792 			$$ = $1;
793 			$$->optional = 0;
794 			$$->defval = $3;
795 		}
796 		;
797 
798 NamedBitList	: NamedBit
799 		{
800 			$$ = emalloc(sizeof(*$$));
801 			ASN1_TAILQ_INIT($$);
802 			ASN1_TAILQ_INSERT_HEAD($$, $1, members);
803 		}
804 		| NamedBitList ',' NamedBit
805 		{
806 			ASN1_TAILQ_INSERT_TAIL($1, $3, members);
807 			$$ = $1;
808 		}
809 		;
810 
811 NamedBit	: IDENTIFIER '(' NUMBER ')'
812 		{
813 		  $$ = emalloc(sizeof(*$$));
814 		  $$->name = $1;
815 		  $$->gen_name = estrdup($1);
816 		  output_name ($$->gen_name);
817 		  $$->val = $3;
818 		  $$->optional = 0;
819 		  $$->ellipsis = 0;
820 		  $$->type = NULL;
821 		}
822 		;
823 
824 objid_opt	: objid
825 		| /* empty */ { $$ = NULL; }
826 		;
827 
828 objid		: '{' objid_list '}'
829 		{
830 			$$ = $2;
831 		}
832 		;
833 
834 objid_list	:  /* empty */
835 		{
836 			$$ = NULL;
837 		}
838 		| objid_element objid_list
839 		{
840 		        if ($2) {
841 				$$ = $2;
842 				add_oid_to_tail($2, $1);
843 			} else {
844 				$$ = $1;
845 			}
846 		}
847 		;
848 
849 objid_element	: IDENTIFIER '(' NUMBER ')'
850 		{
851 			$$ = new_objid($1, $3);
852 		}
853 		| IDENTIFIER
854 		{
855 		    Symbol *s = addsym($1);
856 		    if(s->stype != SValue ||
857 		       s->value->type != objectidentifiervalue) {
858 			lex_error_message("%s is not an object identifier\n",
859 				      s->name);
860 			exit(1);
861 		    }
862 		    $$ = s->value->u.objectidentifiervalue;
863 		}
864 		| NUMBER
865 		{
866 		    $$ = new_objid(NULL, $1);
867 		}
868 		;
869 
870 Value		: BuiltinValue
871 		| ReferencedValue
872 		;
873 
874 BuiltinValue	: BooleanValue
875 		| CharacterStringValue
876 		| IntegerValue
877 		| ObjectIdentifierValue
878 		| NullValue
879 		;
880 
881 ReferencedValue	: DefinedValue
882 		;
883 
884 DefinedValue	: Valuereference
885 		;
886 
887 Valuereference	: IDENTIFIER
888 		{
889 			Symbol *s = addsym($1);
890 			if(s->stype != SValue)
891 				lex_error_message ("%s is not a value\n",
892 						s->name);
893 			else
894 				$$ = s->value;
895 		}
896 		;
897 
898 CharacterStringValue: STRING
899 		{
900 			$$ = emalloc(sizeof(*$$));
901 			$$->type = stringvalue;
902 			$$->u.stringvalue = $1;
903 		}
904 		;
905 
906 BooleanValue	: kw_TRUE
907 		{
908 			$$ = emalloc(sizeof(*$$));
909 			$$->type = booleanvalue;
910 			$$->u.booleanvalue = 0;
911 		}
912 		| kw_FALSE
913 		{
914 			$$ = emalloc(sizeof(*$$));
915 			$$->type = booleanvalue;
916 			$$->u.booleanvalue = 0;
917 		}
918 		;
919 
920 IntegerValue	: SignedNumber
921 		{
922 			$$ = emalloc(sizeof(*$$));
923 			$$->type = integervalue;
924 			$$->u.integervalue = $1;
925 		}
926 		;
927 
928 SignedNumber	: NUMBER
929 		;
930 
931 NullValue	: kw_NULL
932 		{
933 		}
934 		;
935 
936 ObjectIdentifierValue: objid
937 		{
938 			$$ = emalloc(sizeof(*$$));
939 			$$->type = objectidentifiervalue;
940 			$$->u.objectidentifiervalue = $1;
941 		}
942 		;
943 
944 %%
945 
946 void
947 yyerror (const char *s)
948 {
949      lex_error_message ("%s\n", s);
950 }
951 
952 static Type *
953 new_tag(int tagclass, int tagvalue, int tagenv, Type *oldtype)
954 {
955     Type *t;
956     if(oldtype->type == TTag && oldtype->tag.tagenv == TE_IMPLICIT) {
957 	t = oldtype;
958 	oldtype = oldtype->subtype; /* XXX */
959     } else
960 	t = new_type (TTag);
961 
962     t->tag.tagclass = tagclass;
963     t->tag.tagvalue = tagvalue;
964     t->tag.tagenv = tagenv;
965     t->subtype = oldtype;
966     return t;
967 }
968 
969 static struct objid *
970 new_objid(const char *label, int value)
971 {
972     struct objid *s;
973     s = emalloc(sizeof(*s));
974     s->label = label;
975     s->value = value;
976     s->next = NULL;
977     return s;
978 }
979 
980 static void
981 add_oid_to_tail(struct objid *head, struct objid *tail)
982 {
983     struct objid *o;
984     o = head;
985     while (o->next)
986 	o = o->next;
987     o->next = tail;
988 }
989 
990 static Type *
991 new_type (Typetype tt)
992 {
993     Type *t = ecalloc(1, sizeof(*t));
994     t->type = tt;
995     return t;
996 }
997 
998 static struct constraint_spec *
999 new_constraint_spec(enum ctype ct)
1000 {
1001     struct constraint_spec *c = ecalloc(1, sizeof(*c));
1002     c->ctype = ct;
1003     return c;
1004 }
1005 
1006 static void fix_labels2(Type *t, const char *prefix);
1007 static void fix_labels1(struct memhead *members, const char *prefix)
1008 {
1009     Member *m;
1010 
1011     if(members == NULL)
1012 	return;
1013     ASN1_TAILQ_FOREACH(m, members, members) {
1014 	if (asprintf(&m->label, "%s_%s", prefix, m->gen_name) < 0)
1015 	    errx(1, "malloc");
1016 	if (m->label == NULL)
1017 	    errx(1, "malloc");
1018 	if(m->type != NULL)
1019 	    fix_labels2(m->type, m->label);
1020     }
1021 }
1022 
1023 static void fix_labels2(Type *t, const char *prefix)
1024 {
1025     for(; t; t = t->subtype)
1026 	fix_labels1(t->members, prefix);
1027 }
1028 
1029 static void
1030 fix_labels(Symbol *s)
1031 {
1032     char *p = NULL;
1033     if (asprintf(&p, "choice_%s", s->gen_name) < 0 || p == NULL)
1034 	errx(1, "malloc");
1035     fix_labels2(s->type, p);
1036     free(p);
1037 }
1038