1 /* $NetBSD: asn1parse.y,v 1.1.1.3 2014/04/24 12:45:28 pettai Exp $ */
4 * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
8 * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
21 * 3. Neither the name of the Institute nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
25 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54 static Type
*new_type
(Typetype t
);
55 static struct constraint_spec
*new_constraint_spec
(enum ctype
);
56 static Type
*new_tag
(int tagclass
, int tagvalue
, int tagenv
, Type
*oldtype
);
57 void yyerror (const char *);
58 static struct objid
*new_objid
(const char *label
, int value
);
59 static void add_oid_to_tail
(struct objid
*, struct objid
*);
60 static void fix_labels
(Symbol
*s
);
64 struct string_list
*next
;
67 /* Declarations for Bison */
68 #define YYMALLOC malloc
82 struct string_list
*sl
;
84 struct memhead
*members
;
85 struct constraint_spec
*constraint_spec
;
89 %token kw_ABSTRACT_SYNTAX
103 %token kw_CONSTRAINED
106 %token kw_DEFINITIONS
114 %token kw_EXTENSIBILITY
118 %token kw_GeneralString
119 %token kw_GeneralizedTime
120 %token kw_GraphicString
129 %token kw_INTERSECTION
130 %token kw_ISO646String
133 %token kw_MINUS_INFINITY
135 %token kw_NumericString
140 %token kw_ObjectDescriptor
143 %token kw_PLUS_INFINITY
146 %token kw_PrintableString
148 %token kw_RELATIVE_OID
157 %token kw_TYPE_IDENTIFIER
158 %token kw_TeletexString
164 %token kw_UniversalString
165 %token kw_VideotexString
166 %token kw_VisibleString
173 %token
<name
> IDENTIFIER referencename
176 %token
<constant
> NUMBER
177 %type
<constant
> SignedNumber
178 %type
<constant
> Class tagenv
181 %type
<value
> BuiltinValue
182 %type
<value
> IntegerValue
183 %type
<value
> BooleanValue
184 %type
<value
> ObjectIdentifierValue
185 %type
<value
> CharacterStringValue
186 %type
<value
> NullValue
187 %type
<value
> DefinedValue
188 %type
<value
> ReferencedValue
189 %type
<value
> Valuereference
192 %type
<type
> BuiltinType
193 %type
<type
> BitStringType
194 %type
<type
> BooleanType
195 %type
<type
> ChoiceType
196 %type
<type
> ConstrainedType
197 %type
<type
> EnumeratedType
198 %type
<type
> IntegerType
199 %type
<type
> NullType
200 %type
<type
> OctetStringType
201 %type
<type
> SequenceType
202 %type
<type
> SequenceOfType
204 %type
<type
> SetOfType
205 %type
<type
> TaggedType
206 %type
<type
> ReferencedType
207 %type
<type
> DefinedType
208 %type
<type
> UsefulType
209 %type
<type
> ObjectIdentifierType
210 %type
<type
> CharacterStringType
211 %type
<type
> RestrictedCharactedStringType
215 %type
<member
> ComponentType
216 %type
<member
> NamedBit
217 %type
<member
> NamedNumber
218 %type
<member
> NamedType
219 %type
<members
> ComponentTypeList
220 %type
<members
> Enumerations
221 %type
<members
> NamedBitList
222 %type
<members
> NamedNumberList
224 %type
<objid
> objid objid_list objid_element objid_opt
225 %type
<range
> range size
227 %type
<sl
> referencenames
229 %type
<constraint_spec
> Constraint
230 %type
<constraint_spec
> ConstraintSpec
231 %type
<constraint_spec
> GeneralConstraint
232 %type
<constraint_spec
> ContentsConstraint
233 %type
<constraint_spec
> UserDefinedConstraint
237 %start ModuleDefinition
241 ModuleDefinition: IDENTIFIER objid_opt kw_DEFINITIONS TagDefault ExtensionDefault
242 EEQUAL kw_BEGIN ModuleBody kw_END
248 TagDefault
: kw_EXPLICIT kw_TAGS
249 | kw_IMPLICIT kw_TAGS
250 { lex_error_message
("implicit tagging is not supported"); }
251 | kw_AUTOMATIC kw_TAGS
252 { lex_error_message
("automatic tagging is not supported"); }
256 ExtensionDefault: kw_EXTENSIBILITY kw_IMPLIED
257 { lex_error_message
("no extensibility options supported"); }
261 ModuleBody
: Exports Imports AssignmentList
265 Imports
: kw_IMPORTS SymbolsImported
';'
269 SymbolsImported
: SymbolsFromModuleList
273 SymbolsFromModuleList: SymbolsFromModule
274 | SymbolsFromModuleList SymbolsFromModule
277 SymbolsFromModule: referencenames kw_FROM IDENTIFIER objid_opt
279 struct string_list
*sl
;
280 for
(sl
= $1; sl
!= NULL
; sl
= sl
->next
) {
281 Symbol
*s
= addsym
(sl
->string);
283 gen_template_import
(s
);
289 Exports
: kw_EXPORTS referencenames
';'
291 struct string_list
*sl
;
292 for
(sl
= $2; sl
!= NULL
; sl
= sl
->next
)
293 add_export
(sl
->string);
299 AssignmentList
: Assignment
300 | Assignment AssignmentList
303 Assignment
: TypeAssignment
307 referencenames
: IDENTIFIER
',' referencenames
309 $$
= emalloc
(sizeof
(*$$
));
315 $$
= emalloc
(sizeof
(*$$
));
321 TypeAssignment
: IDENTIFIER EEQUAL Type
323 Symbol
*s
= addsym
($1);
336 BuiltinType
: BitStringType
338 | CharacterStringType
343 | ObjectIdentifierType
352 BooleanType
: kw_BOOLEAN
354 $$
= new_tag
(ASN1_C_UNIV
, UT_Boolean
,
355 TE_EXPLICIT
, new_type
(TBoolean
));
359 range
: '(' Value RANGE Value
')'
361 if
($2->type
!= integervalue
)
362 lex_error_message
("Non-integer used in first part of range");
363 if
($2->type
!= integervalue
)
364 lex_error_message
("Non-integer in second part of range");
365 $$
= ecalloc
(1, sizeof
(*$$
));
366 $$
->min
= $2->u.integervalue
;
367 $$
->max
= $4->u.integervalue
;
369 |
'(' Value RANGE kw_MAX
')'
371 if
($2->type
!= integervalue
)
372 lex_error_message
("Non-integer in first part of range");
373 $$
= ecalloc
(1, sizeof
(*$$
));
374 $$
->min
= $2->u.integervalue
;
375 $$
->max
= $2->u.integervalue
- 1;
377 |
'(' kw_MIN RANGE Value
')'
379 if
($4->type
!= integervalue
)
380 lex_error_message
("Non-integer in second part of range");
381 $$
= ecalloc
(1, sizeof
(*$$
));
382 $$
->min
= $4->u.integervalue
+ 2;
383 $$
->max
= $4->u.integervalue
;
387 if
($2->type
!= integervalue
)
388 lex_error_message
("Non-integer used in limit");
389 $$
= ecalloc
(1, sizeof
(*$$
));
390 $$
->min
= $2->u.integervalue
;
391 $$
->max
= $2->u.integervalue
;
396 IntegerType
: kw_INTEGER
398 $$
= new_tag
(ASN1_C_UNIV
, UT_Integer
,
399 TE_EXPLICIT
, new_type
(TInteger
));
403 $$
= new_type
(TInteger
);
405 $$
= new_tag
(ASN1_C_UNIV
, UT_Integer
, TE_EXPLICIT
, $$
);
407 | kw_INTEGER
'{' NamedNumberList
'}'
409 $$
= new_type
(TInteger
);
411 $$
= new_tag
(ASN1_C_UNIV
, UT_Integer
, TE_EXPLICIT
, $$
);
415 NamedNumberList
: NamedNumber
417 $$
= emalloc
(sizeof
(*$$
));
419 ASN1_TAILQ_INSERT_HEAD
($$
, $1, members
);
421 | NamedNumberList
',' NamedNumber
423 ASN1_TAILQ_INSERT_TAIL
($1, $3, members
);
426 | NamedNumberList
',' ELLIPSIS
427 { $$
= $1; } /* XXX used for Enumerations */
430 NamedNumber
: IDENTIFIER
'(' SignedNumber
')'
432 $$
= emalloc
(sizeof
(*$$
));
434 $$
->gen_name
= estrdup
($1);
435 output_name
($$
->gen_name
);
443 EnumeratedType
: kw_ENUMERATED
'{' Enumerations
'}'
445 $$
= new_type
(TInteger
);
447 $$
= new_tag
(ASN1_C_UNIV
, UT_Enumerated
, TE_EXPLICIT
, $$
);
451 Enumerations
: NamedNumberList
/* XXX */
454 BitStringType
: kw_BIT kw_STRING
456 $$
= new_type
(TBitString
);
457 $$
->members
= emalloc
(sizeof
(*$$
->members
));
458 ASN1_TAILQ_INIT
($$
->members
);
459 $$
= new_tag
(ASN1_C_UNIV
, UT_BitString
, TE_EXPLICIT
, $$
);
461 | kw_BIT kw_STRING
'{' NamedBitList
'}'
463 $$
= new_type
(TBitString
);
465 $$
= new_tag
(ASN1_C_UNIV
, UT_BitString
, TE_EXPLICIT
, $$
);
469 ObjectIdentifierType: kw_OBJECT kw_IDENTIFIER
471 $$
= new_tag
(ASN1_C_UNIV
, UT_OID
,
472 TE_EXPLICIT
, new_type
(TOID
));
475 OctetStringType
: kw_OCTET kw_STRING size
477 Type
*t
= new_type
(TOctetString
);
479 $$
= new_tag
(ASN1_C_UNIV
, UT_OctetString
,
486 $$
= new_tag
(ASN1_C_UNIV
, UT_Null
,
487 TE_EXPLICIT
, new_type
(TNull
));
498 SequenceType
: kw_SEQUENCE
'{' /* ComponentTypeLists */ ComponentTypeList
'}'
500 $$
= new_type
(TSequence
);
502 $$
= new_tag
(ASN1_C_UNIV
, UT_Sequence
, TE_EXPLICIT
, $$
);
504 | kw_SEQUENCE
'{' '}'
506 $$
= new_type
(TSequence
);
508 $$
= new_tag
(ASN1_C_UNIV
, UT_Sequence
, TE_EXPLICIT
, $$
);
512 SequenceOfType
: kw_SEQUENCE size kw_OF Type
514 $$
= new_type
(TSequenceOf
);
517 $$
= new_tag
(ASN1_C_UNIV
, UT_Sequence
, TE_EXPLICIT
, $$
);
521 SetType
: kw_SET
'{' /* ComponentTypeLists */ ComponentTypeList
'}'
525 $$
= new_tag
(ASN1_C_UNIV
, UT_Set
, TE_EXPLICIT
, $$
);
531 $$
= new_tag
(ASN1_C_UNIV
, UT_Set
, TE_EXPLICIT
, $$
);
535 SetOfType
: kw_SET kw_OF Type
537 $$
= new_type
(TSetOf
);
539 $$
= new_tag
(ASN1_C_UNIV
, UT_Set
, TE_EXPLICIT
, $$
);
543 ChoiceType
: kw_CHOICE
'{' /* AlternativeTypeLists */ ComponentTypeList
'}'
545 $$
= new_type
(TChoice
);
550 ReferencedType
: DefinedType
554 DefinedType
: IDENTIFIER
556 Symbol
*s
= addsym
($1);
557 $$
= new_type
(TType
);
558 if
(s
->stype
!= Stype
&& s
->stype
!= SUndefined
)
559 lex_error_message
("%s is not a type\n", $1);
565 UsefulType
: kw_GeneralizedTime
567 $$
= new_tag
(ASN1_C_UNIV
, UT_GeneralizedTime
,
568 TE_EXPLICIT
, new_type
(TGeneralizedTime
));
572 $$
= new_tag
(ASN1_C_UNIV
, UT_UTCTime
,
573 TE_EXPLICIT
, new_type
(TUTCTime
));
577 ConstrainedType
: Type Constraint
579 /* if (Constraint.type == contentConstrant) {
580 assert(Constraint.u.constraint.type == octetstring|bitstring-w/o-NamedBitList); // remember to check type reference too
581 if (Constraint.u.constraint.type) {
582 assert((Constraint.u.constraint.type.length % 8) == 0);
585 if (Constraint.u.constraint.encoding) {
586 type == der-oid|ber-oid
593 Constraint
: '(' ConstraintSpec
')'
599 ConstraintSpec
: GeneralConstraint
602 GeneralConstraint: ContentsConstraint
603 | UserDefinedConstraint
606 ContentsConstraint: kw_CONTAINING Type
608 $$
= new_constraint_spec
(CT_CONTENTS
);
609 $$
->u.content.type
= $2;
610 $$
->u.content.encoding
= NULL
;
612 | kw_ENCODED kw_BY Value
614 if
($3->type
!= objectidentifiervalue
)
615 lex_error_message
("Non-OID used in ENCODED BY constraint");
616 $$
= new_constraint_spec
(CT_CONTENTS
);
617 $$
->u.content.type
= NULL
;
618 $$
->u.content.encoding
= $3;
620 | kw_CONTAINING Type kw_ENCODED kw_BY Value
622 if
($5->type
!= objectidentifiervalue
)
623 lex_error_message
("Non-OID used in ENCODED BY constraint");
624 $$
= new_constraint_spec
(CT_CONTENTS
);
625 $$
->u.content.type
= $2;
626 $$
->u.content.encoding
= $5;
630 UserDefinedConstraint: kw_CONSTRAINED kw_BY
'{' '}'
632 $$
= new_constraint_spec
(CT_USER
);
636 TaggedType
: Tag tagenv Type
641 if
($3->type
== TTag
&& $2 == TE_IMPLICIT
) {
642 $$
->subtype
= $3->subtype
;
649 Tag
: '[' Class NUMBER
']'
653 $$.tagenv
= TE_EXPLICIT
;
690 ValueAssignment
: IDENTIFIER Type EEQUAL Value
697 generate_constant
(s
);
701 CharacterStringType: RestrictedCharactedStringType
704 RestrictedCharactedStringType: kw_GeneralString
706 $$
= new_tag
(ASN1_C_UNIV
, UT_GeneralString
,
707 TE_EXPLICIT
, new_type
(TGeneralString
));
711 $$
= new_tag
(ASN1_C_UNIV
, UT_TeletexString
,
712 TE_EXPLICIT
, new_type
(TTeletexString
));
716 $$
= new_tag
(ASN1_C_UNIV
, UT_UTF8String
,
717 TE_EXPLICIT
, new_type
(TUTF8String
));
721 $$
= new_tag
(ASN1_C_UNIV
, UT_PrintableString
,
722 TE_EXPLICIT
, new_type
(TPrintableString
));
726 $$
= new_tag
(ASN1_C_UNIV
, UT_VisibleString
,
727 TE_EXPLICIT
, new_type
(TVisibleString
));
731 $$
= new_tag
(ASN1_C_UNIV
, UT_IA5String
,
732 TE_EXPLICIT
, new_type
(TIA5String
));
736 $$
= new_tag
(ASN1_C_UNIV
, UT_BMPString
,
737 TE_EXPLICIT
, new_type
(TBMPString
));
741 $$
= new_tag
(ASN1_C_UNIV
, UT_UniversalString
,
742 TE_EXPLICIT
, new_type
(TUniversalString
));
747 ComponentTypeList: ComponentType
749 $$
= emalloc
(sizeof
(*$$
));
751 ASN1_TAILQ_INSERT_HEAD
($$
, $1, members
);
753 | ComponentTypeList
',' ComponentType
755 ASN1_TAILQ_INSERT_TAIL
($1, $3, members
);
758 | ComponentTypeList
',' ELLIPSIS
760 struct member
*m
= ecalloc
(1, sizeof
(*m
));
761 m
->name
= estrdup
("...");
762 m
->gen_name
= estrdup
("asn1_ellipsis");
764 ASN1_TAILQ_INSERT_TAIL
($1, m
, members
);
769 NamedType
: IDENTIFIER Type
771 $$
= emalloc
(sizeof
(*$$
));
773 $$
->gen_name
= estrdup
($1);
774 output_name
($$
->gen_name
);
780 ComponentType
: NamedType
786 | NamedType kw_OPTIONAL
792 | NamedType kw_DEFAULT Value
800 NamedBitList
: NamedBit
802 $$
= emalloc
(sizeof
(*$$
));
804 ASN1_TAILQ_INSERT_HEAD
($$
, $1, members
);
806 | NamedBitList
',' NamedBit
808 ASN1_TAILQ_INSERT_TAIL
($1, $3, members
);
813 NamedBit
: IDENTIFIER
'(' NUMBER
')'
815 $$
= emalloc
(sizeof
(*$$
));
817 $$
->gen_name
= estrdup
($1);
818 output_name
($$
->gen_name
);
827 |
/* empty */ { $$
= NULL
; }
830 objid
: '{' objid_list
'}'
836 objid_list
: /* empty */
840 | objid_element objid_list
844 add_oid_to_tail
($2, $1);
851 objid_element
: IDENTIFIER
'(' NUMBER
')'
853 $$
= new_objid
($1, $3);
857 Symbol
*s
= addsym
($1);
858 if
(s
->stype
!= SValue ||
859 s
->value
->type
!= objectidentifiervalue
) {
860 lex_error_message
("%s is not an object identifier\n",
864 $$
= s
->value
->u.objectidentifiervalue
;
868 $$
= new_objid
(NULL
, $1);
876 BuiltinValue
: BooleanValue
877 | CharacterStringValue
879 | ObjectIdentifierValue
883 ReferencedValue
: DefinedValue
886 DefinedValue
: Valuereference
889 Valuereference
: IDENTIFIER
891 Symbol
*s
= addsym
($1);
892 if
(s
->stype
!= SValue
)
893 lex_error_message
("%s is not a value\n",
900 CharacterStringValue: STRING
902 $$
= emalloc
(sizeof
(*$$
));
903 $$
->type
= stringvalue
;
904 $$
->u.stringvalue
= $1;
908 BooleanValue
: kw_TRUE
910 $$
= emalloc
(sizeof
(*$$
));
911 $$
->type
= booleanvalue
;
912 $$
->u.booleanvalue
= 0;
916 $$
= emalloc
(sizeof
(*$$
));
917 $$
->type
= booleanvalue
;
918 $$
->u.booleanvalue
= 0;
922 IntegerValue
: SignedNumber
924 $$
= emalloc
(sizeof
(*$$
));
925 $$
->type
= integervalue
;
926 $$
->u.integervalue
= $1;
930 SignedNumber
: NUMBER
938 ObjectIdentifierValue: objid
940 $$
= emalloc
(sizeof
(*$$
));
941 $$
->type
= objectidentifiervalue
;
942 $$
->u.objectidentifiervalue
= $1;
949 yyerror (const char *s
)
951 lex_error_message
("%s\n", s
);
955 new_tag
(int tagclass
, int tagvalue
, int tagenv
, Type
*oldtype
)
958 if
(oldtype
->type
== TTag
&& oldtype
->tag.tagenv
== TE_IMPLICIT
) {
960 oldtype
= oldtype
->subtype
; /* XXX */
964 t
->tag.tagclass
= tagclass
;
965 t
->tag.tagvalue
= tagvalue
;
966 t
->tag.tagenv
= tagenv
;
967 t
->subtype
= oldtype
;
971 static struct objid
*
972 new_objid
(const char *label
, int value
)
975 s
= emalloc
(sizeof
(*s
));
983 add_oid_to_tail
(struct objid
*head
, struct objid
*tail
)
993 new_type
(Typetype tt
)
995 Type
*t
= ecalloc
(1, sizeof
(*t
));
1000 static struct constraint_spec
*
1001 new_constraint_spec
(enum ctype ct
)
1003 struct constraint_spec
*c
= ecalloc
(1, sizeof
(*c
));
1008 static void fix_labels2
(Type
*t
, const char *prefix
);
1009 static void fix_labels1
(struct memhead
*members
, const char *prefix
)
1015 ASN1_TAILQ_FOREACH
(m
, members
, members
) {
1016 if
(asprintf
(&m
->label
, "%s_%s", prefix
, m
->gen_name
) < 0)
1018 if
(m
->label
== NULL
)
1021 fix_labels2
(m
->type
, m
->label
);
1025 static void fix_labels2
(Type
*t
, const char *prefix
)
1027 for
(; t
; t
= t
->subtype
)
1028 fix_labels1
(t
->members
, prefix
);
1032 fix_labels
(Symbol
*s
)
1035 if
(asprintf
(&p
, "choice_%s", s
->gen_name
) < 0 || p
== NULL
)
1037 fix_labels2
(s
->type
, p
);