2 * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
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.
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.
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
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
);
62 struct string_list
*next
;
65 /* Declarations for Bison */
66 #define YYMALLOC malloc
80 struct string_list
*sl
;
82 struct memhead
*members
;
83 struct constraint_spec
*constraint_spec
;
87 %token kw_ABSTRACT_SYNTAX
101 %token kw_CONSTRAINED
104 %token kw_DEFINITIONS
112 %token kw_EXTENSIBILITY
116 %token kw_GeneralString
117 %token kw_GeneralizedTime
118 %token kw_GraphicString
127 %token kw_INTERSECTION
128 %token kw_ISO646String
131 %token kw_MINUS_INFINITY
133 %token kw_NumericString
138 %token kw_ObjectDescriptor
141 %token kw_PLUS_INFINITY
144 %token kw_PrintableString
146 %token kw_RELATIVE_OID
155 %token kw_TYPE_IDENTIFIER
156 %token kw_TeletexString
162 %token kw_UniversalString
163 %token kw_VideotexString
164 %token kw_VisibleString
171 %token
<name
> IDENTIFIER referencename
174 %token
<constant
> NUMBER
175 %type
<constant
> SignedNumber
176 %type
<constant
> Class tagenv
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
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
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
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
222 %type
<objid
> objid objid_list objid_element objid_opt
223 %type
<range
> range size
225 %type
<sl
> referencenames
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
235 %start ModuleDefinition
239 ModuleDefinition: IDENTIFIER objid_opt kw_DEFINITIONS TagDefault ExtensionDefault
240 EEQUAL kw_BEGIN ModuleBody kw_END
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"); }
254 ExtensionDefault: kw_EXTENSIBILITY kw_IMPLIED
255 { lex_error_message
("no extensibility options supported"); }
259 ModuleBody
: Exports Imports AssignmentList
263 Imports
: kw_IMPORTS SymbolsImported
';'
267 SymbolsImported
: SymbolsFromModuleList
271 SymbolsFromModuleList: SymbolsFromModule
272 | SymbolsFromModuleList SymbolsFromModule
275 SymbolsFromModule: referencenames kw_FROM IDENTIFIER objid_opt
277 struct string_list
*sl
;
278 for
(sl
= $1; sl
!= NULL
; sl
= sl
->next
) {
279 Symbol
*s
= addsym
(sl
->string);
281 gen_template_import
(s
);
287 Exports
: kw_EXPORTS referencenames
';'
289 struct string_list
*sl
;
290 for
(sl
= $2; sl
!= NULL
; sl
= sl
->next
)
291 add_export
(sl
->string);
297 AssignmentList
: Assignment
298 | Assignment AssignmentList
301 Assignment
: TypeAssignment
305 referencenames
: IDENTIFIER
',' referencenames
307 $$
= emalloc
(sizeof
(*$$
));
313 $$
= emalloc
(sizeof
(*$$
));
319 TypeAssignment
: IDENTIFIER EEQUAL Type
321 Symbol
*s
= addsym
($1);
334 BuiltinType
: BitStringType
336 | CharacterStringType
341 | ObjectIdentifierType
350 BooleanType
: kw_BOOLEAN
352 $$
= new_tag
(ASN1_C_UNIV
, UT_Boolean
,
353 TE_EXPLICIT
, new_type
(TBoolean
));
357 range
: '(' Value RANGE Value
')'
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
;
367 |
'(' Value RANGE kw_MAX
')'
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;
375 |
'(' kw_MIN RANGE Value
')'
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
;
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
;
394 IntegerType
: kw_INTEGER
396 $$
= new_tag
(ASN1_C_UNIV
, UT_Integer
,
397 TE_EXPLICIT
, new_type
(TInteger
));
401 $$
= new_type
(TInteger
);
403 $$
= new_tag
(ASN1_C_UNIV
, UT_Integer
, TE_EXPLICIT
, $$
);
405 | kw_INTEGER
'{' NamedNumberList
'}'
407 $$
= new_type
(TInteger
);
409 $$
= new_tag
(ASN1_C_UNIV
, UT_Integer
, TE_EXPLICIT
, $$
);
413 NamedNumberList
: NamedNumber
415 $$
= emalloc
(sizeof
(*$$
));
417 ASN1_TAILQ_INSERT_HEAD
($$
, $1, members
);
419 | NamedNumberList
',' NamedNumber
421 ASN1_TAILQ_INSERT_TAIL
($1, $3, members
);
424 | NamedNumberList
',' ELLIPSIS
425 { $$
= $1; } /* XXX used for Enumerations */
428 NamedNumber
: IDENTIFIER
'(' SignedNumber
')'
430 $$
= emalloc
(sizeof
(*$$
));
432 $$
->gen_name
= estrdup
($1);
433 output_name
($$
->gen_name
);
441 EnumeratedType
: kw_ENUMERATED
'{' Enumerations
'}'
443 $$
= new_type
(TInteger
);
445 $$
= new_tag
(ASN1_C_UNIV
, UT_Enumerated
, TE_EXPLICIT
, $$
);
449 Enumerations
: NamedNumberList
/* XXX */
452 BitStringType
: kw_BIT kw_STRING
454 $$
= new_type
(TBitString
);
455 $$
->members
= emalloc
(sizeof
(*$$
->members
));
456 ASN1_TAILQ_INIT
($$
->members
);
457 $$
= new_tag
(ASN1_C_UNIV
, UT_BitString
, TE_EXPLICIT
, $$
);
459 | kw_BIT kw_STRING
'{' NamedBitList
'}'
461 $$
= new_type
(TBitString
);
463 $$
= new_tag
(ASN1_C_UNIV
, UT_BitString
, TE_EXPLICIT
, $$
);
467 ObjectIdentifierType: kw_OBJECT kw_IDENTIFIER
469 $$
= new_tag
(ASN1_C_UNIV
, UT_OID
,
470 TE_EXPLICIT
, new_type
(TOID
));
473 OctetStringType
: kw_OCTET kw_STRING size
475 Type
*t
= new_type
(TOctetString
);
477 $$
= new_tag
(ASN1_C_UNIV
, UT_OctetString
,
484 $$
= new_tag
(ASN1_C_UNIV
, UT_Null
,
485 TE_EXPLICIT
, new_type
(TNull
));
496 SequenceType
: kw_SEQUENCE
'{' /* ComponentTypeLists */ ComponentTypeList
'}'
498 $$
= new_type
(TSequence
);
500 $$
= new_tag
(ASN1_C_UNIV
, UT_Sequence
, TE_EXPLICIT
, $$
);
502 | kw_SEQUENCE
'{' '}'
504 $$
= new_type
(TSequence
);
506 $$
= new_tag
(ASN1_C_UNIV
, UT_Sequence
, TE_EXPLICIT
, $$
);
510 SequenceOfType
: kw_SEQUENCE size kw_OF Type
512 $$
= new_type
(TSequenceOf
);
515 $$
= new_tag
(ASN1_C_UNIV
, UT_Sequence
, TE_EXPLICIT
, $$
);
519 SetType
: kw_SET
'{' /* ComponentTypeLists */ ComponentTypeList
'}'
523 $$
= new_tag
(ASN1_C_UNIV
, UT_Set
, TE_EXPLICIT
, $$
);
529 $$
= new_tag
(ASN1_C_UNIV
, UT_Set
, TE_EXPLICIT
, $$
);
533 SetOfType
: kw_SET kw_OF Type
535 $$
= new_type
(TSetOf
);
537 $$
= new_tag
(ASN1_C_UNIV
, UT_Set
, TE_EXPLICIT
, $$
);
541 ChoiceType
: kw_CHOICE
'{' /* AlternativeTypeLists */ ComponentTypeList
'}'
543 $$
= new_type
(TChoice
);
548 ReferencedType
: DefinedType
552 DefinedType
: IDENTIFIER
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);
563 UsefulType
: kw_GeneralizedTime
565 $$
= new_tag
(ASN1_C_UNIV
, UT_GeneralizedTime
,
566 TE_EXPLICIT
, new_type
(TGeneralizedTime
));
570 $$
= new_tag
(ASN1_C_UNIV
, UT_UTCTime
,
571 TE_EXPLICIT
, new_type
(TUTCTime
));
575 ConstrainedType
: Type Constraint
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);
583 if (Constraint.u.constraint.encoding) {
584 type == der-oid|ber-oid
591 Constraint
: '(' ConstraintSpec
')'
597 ConstraintSpec
: GeneralConstraint
600 GeneralConstraint: ContentsConstraint
601 | UserDefinedConstraint
604 ContentsConstraint: kw_CONTAINING Type
606 $$
= new_constraint_spec
(CT_CONTENTS
);
607 $$
->u.content.type
= $2;
608 $$
->u.content.encoding
= NULL
;
610 | kw_ENCODED kw_BY Value
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;
618 | kw_CONTAINING Type kw_ENCODED kw_BY Value
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;
628 UserDefinedConstraint: kw_CONSTRAINED kw_BY
'{' '}'
630 $$
= new_constraint_spec
(CT_USER
);
634 TaggedType
: Tag tagenv Type
639 if
($3->type
== TTag
&& $2 == TE_IMPLICIT
) {
640 $$
->subtype
= $3->subtype
;
647 Tag
: '[' Class NUMBER
']'
651 $$.tagenv
= TE_EXPLICIT
;
688 ValueAssignment
: IDENTIFIER Type EEQUAL Value
695 generate_constant
(s
);
699 CharacterStringType: RestrictedCharactedStringType
702 RestrictedCharactedStringType: kw_GeneralString
704 $$
= new_tag
(ASN1_C_UNIV
, UT_GeneralString
,
705 TE_EXPLICIT
, new_type
(TGeneralString
));
709 $$
= new_tag
(ASN1_C_UNIV
, UT_TeletexString
,
710 TE_EXPLICIT
, new_type
(TTeletexString
));
714 $$
= new_tag
(ASN1_C_UNIV
, UT_UTF8String
,
715 TE_EXPLICIT
, new_type
(TUTF8String
));
719 $$
= new_tag
(ASN1_C_UNIV
, UT_PrintableString
,
720 TE_EXPLICIT
, new_type
(TPrintableString
));
724 $$
= new_tag
(ASN1_C_UNIV
, UT_VisibleString
,
725 TE_EXPLICIT
, new_type
(TVisibleString
));
729 $$
= new_tag
(ASN1_C_UNIV
, UT_IA5String
,
730 TE_EXPLICIT
, new_type
(TIA5String
));
734 $$
= new_tag
(ASN1_C_UNIV
, UT_BMPString
,
735 TE_EXPLICIT
, new_type
(TBMPString
));
739 $$
= new_tag
(ASN1_C_UNIV
, UT_UniversalString
,
740 TE_EXPLICIT
, new_type
(TUniversalString
));
745 ComponentTypeList: ComponentType
747 $$
= emalloc
(sizeof
(*$$
));
749 ASN1_TAILQ_INSERT_HEAD
($$
, $1, members
);
751 | ComponentTypeList
',' ComponentType
753 ASN1_TAILQ_INSERT_TAIL
($1, $3, members
);
756 | ComponentTypeList
',' ELLIPSIS
758 struct member
*m
= ecalloc
(1, sizeof
(*m
));
759 m
->name
= estrdup
("...");
760 m
->gen_name
= estrdup
("asn1_ellipsis");
762 ASN1_TAILQ_INSERT_TAIL
($1, m
, members
);
767 NamedType
: IDENTIFIER Type
769 $$
= emalloc
(sizeof
(*$$
));
771 $$
->gen_name
= estrdup
($1);
772 output_name
($$
->gen_name
);
778 ComponentType
: NamedType
784 | NamedType kw_OPTIONAL
790 | NamedType kw_DEFAULT Value
798 NamedBitList
: NamedBit
800 $$
= emalloc
(sizeof
(*$$
));
802 ASN1_TAILQ_INSERT_HEAD
($$
, $1, members
);
804 | NamedBitList
',' NamedBit
806 ASN1_TAILQ_INSERT_TAIL
($1, $3, members
);
811 NamedBit
: IDENTIFIER
'(' NUMBER
')'
813 $$
= emalloc
(sizeof
(*$$
));
815 $$
->gen_name
= estrdup
($1);
816 output_name
($$
->gen_name
);
825 |
/* empty */ { $$
= NULL
; }
828 objid
: '{' objid_list
'}'
834 objid_list
: /* empty */
838 | objid_element objid_list
842 add_oid_to_tail
($2, $1);
849 objid_element
: IDENTIFIER
'(' NUMBER
')'
851 $$
= new_objid
($1, $3);
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",
862 $$
= s
->value
->u.objectidentifiervalue
;
866 $$
= new_objid
(NULL
, $1);
874 BuiltinValue
: BooleanValue
875 | CharacterStringValue
877 | ObjectIdentifierValue
881 ReferencedValue
: DefinedValue
884 DefinedValue
: Valuereference
887 Valuereference
: IDENTIFIER
889 Symbol
*s
= addsym
($1);
890 if
(s
->stype
!= SValue
)
891 lex_error_message
("%s is not a value\n",
898 CharacterStringValue: STRING
900 $$
= emalloc
(sizeof
(*$$
));
901 $$
->type
= stringvalue
;
902 $$
->u.stringvalue
= $1;
906 BooleanValue
: kw_TRUE
908 $$
= emalloc
(sizeof
(*$$
));
909 $$
->type
= booleanvalue
;
910 $$
->u.booleanvalue
= 0;
914 $$
= emalloc
(sizeof
(*$$
));
915 $$
->type
= booleanvalue
;
916 $$
->u.booleanvalue
= 0;
920 IntegerValue
: SignedNumber
922 $$
= emalloc
(sizeof
(*$$
));
923 $$
->type
= integervalue
;
924 $$
->u.integervalue
= $1;
928 SignedNumber
: NUMBER
936 ObjectIdentifierValue: objid
938 $$
= emalloc
(sizeof
(*$$
));
939 $$
->type
= objectidentifiervalue
;
940 $$
->u.objectidentifiervalue
= $1;
947 yyerror (const char *s
)
949 lex_error_message
("%s\n", s
);
953 new_tag
(int tagclass
, int tagvalue
, int tagenv
, Type
*oldtype
)
956 if
(oldtype
->type
== TTag
&& oldtype
->tag.tagenv
== TE_IMPLICIT
) {
958 oldtype
= oldtype
->subtype
; /* XXX */
962 t
->tag.tagclass
= tagclass
;
963 t
->tag.tagvalue
= tagvalue
;
964 t
->tag.tagenv
= tagenv
;
965 t
->subtype
= oldtype
;
969 static struct objid
*
970 new_objid
(const char *label
, int value
)
973 s
= emalloc
(sizeof
(*s
));
981 add_oid_to_tail
(struct objid
*head
, struct objid
*tail
)
991 new_type
(Typetype tt
)
993 Type
*t
= ecalloc
(1, sizeof
(*t
));
998 static struct constraint_spec
*
999 new_constraint_spec
(enum ctype ct
)
1001 struct constraint_spec
*c
= ecalloc
(1, sizeof
(*c
));
1006 static void fix_labels2
(Type
*t
, const char *prefix
);
1007 static void fix_labels1
(struct memhead
*members
, const char *prefix
)
1013 ASN1_TAILQ_FOREACH
(m
, members
, members
) {
1014 if
(asprintf
(&m
->label
, "%s_%s", prefix
, m
->gen_name
) < 0)
1016 if
(m
->label
== NULL
)
1019 fix_labels2
(m
->type
, m
->label
);
1023 static void fix_labels2
(Type
*t
, const char *prefix
)
1025 for
(; t
; t
= t
->subtype
)
1026 fix_labels1
(t
->members
, prefix
);
1030 fix_labels
(Symbol
*s
)
1033 if
(asprintf
(&p
, "choice_%s", s
->gen_name
) < 0 || p
== NULL
)
1035 fix_labels2
(s
->type
, p
);