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
;
76 struct string_list
*sl
;
78 struct memhead
*members
;
79 struct constraint_spec
*constraint_spec
;
83 %token kw_ABSTRACT_SYNTAX
100 %token kw_DEFINITIONS
108 %token kw_EXTENSIBILITY
112 %token kw_GeneralString
113 %token kw_GeneralizedTime
114 %token kw_GraphicString
123 %token kw_INTERSECTION
124 %token kw_ISO646String
127 %token kw_MINUS_INFINITY
129 %token kw_NumericString
134 %token kw_ObjectDescriptor
137 %token kw_PLUS_INFINITY
140 %token kw_PrintableString
142 %token kw_RELATIVE_OID
151 %token kw_TYPE_IDENTIFIER
152 %token kw_TeletexString
158 %token kw_UniversalString
159 %token kw_VideotexString
160 %token kw_VisibleString
167 %token
<name
> IDENTIFIER referencename
170 %token
<constant
> NUMBER
171 %type
<constant
> SignedNumber
172 %type
<constant
> Class tagenv
175 %type
<value
> BuiltinValue
176 %type
<value
> IntegerValue
177 %type
<value
> BooleanValue
178 %type
<value
> ObjectIdentifierValue
179 %type
<value
> CharacterStringValue
180 %type
<value
> NullValue
181 %type
<value
> DefinedValue
182 %type
<value
> ReferencedValue
183 %type
<value
> Valuereference
186 %type
<type
> BuiltinType
187 %type
<type
> BitStringType
188 %type
<type
> BooleanType
189 %type
<type
> ChoiceType
190 %type
<type
> ConstrainedType
191 %type
<type
> EnumeratedType
192 %type
<type
> IntegerType
193 %type
<type
> NullType
194 %type
<type
> OctetStringType
195 %type
<type
> SequenceType
196 %type
<type
> SequenceOfType
198 %type
<type
> SetOfType
199 %type
<type
> TaggedType
200 %type
<type
> ReferencedType
201 %type
<type
> DefinedType
202 %type
<type
> UsefulType
203 %type
<type
> ObjectIdentifierType
204 %type
<type
> CharacterStringType
205 %type
<type
> RestrictedCharactedStringType
209 %type
<member
> ComponentType
210 %type
<member
> NamedBit
211 %type
<member
> NamedNumber
212 %type
<member
> NamedType
213 %type
<members
> ComponentTypeList
214 %type
<members
> Enumerations
215 %type
<members
> NamedBitList
216 %type
<members
> NamedNumberList
218 %type
<objid
> objid objid_list objid_element objid_opt
219 %type
<range
> range size
221 %type
<sl
> referencenames
223 %type
<constraint_spec
> Constraint
224 %type
<constraint_spec
> ConstraintSpec
225 %type
<constraint_spec
> GeneralConstraint
226 %type
<constraint_spec
> ContentsConstraint
227 %type
<constraint_spec
> UserDefinedConstraint
231 %start ModuleDefinition
235 ModuleDefinition: IDENTIFIER objid_opt kw_DEFINITIONS TagDefault ExtensionDefault
236 EEQUAL kw_BEGIN ModuleBody kw_END
242 TagDefault
: kw_EXPLICIT kw_TAGS
243 | kw_IMPLICIT kw_TAGS
244 { lex_error_message
("implicit tagging is not supported"); }
245 | kw_AUTOMATIC kw_TAGS
246 { lex_error_message
("automatic tagging is not supported"); }
250 ExtensionDefault: kw_EXTENSIBILITY kw_IMPLIED
251 { lex_error_message
("no extensibility options supported"); }
255 ModuleBody
: Exports Imports AssignmentList
259 Imports
: kw_IMPORTS SymbolsImported
';'
263 SymbolsImported
: SymbolsFromModuleList
267 SymbolsFromModuleList: SymbolsFromModule
268 | SymbolsFromModuleList SymbolsFromModule
271 SymbolsFromModule: referencenames kw_FROM IDENTIFIER objid_opt
273 struct string_list
*sl
;
274 for
(sl
= $1; sl
!= NULL
; sl
= sl
->next
) {
275 Symbol
*s
= addsym
(sl
->string);
277 gen_template_import
(s
);
283 Exports
: kw_EXPORTS referencenames
';'
285 struct string_list
*sl
;
286 for
(sl
= $2; sl
!= NULL
; sl
= sl
->next
)
287 add_export
(sl
->string);
293 AssignmentList
: Assignment
294 | Assignment AssignmentList
297 Assignment
: TypeAssignment
301 referencenames
: IDENTIFIER
',' referencenames
303 $$
= emalloc
(sizeof
(*$$
));
309 $$
= emalloc
(sizeof
(*$$
));
315 TypeAssignment
: IDENTIFIER EEQUAL Type
317 Symbol
*s
= addsym
($1);
330 BuiltinType
: BitStringType
332 | CharacterStringType
337 | ObjectIdentifierType
346 BooleanType
: kw_BOOLEAN
348 $$
= new_tag
(ASN1_C_UNIV
, UT_Boolean
,
349 TE_EXPLICIT
, new_type
(TBoolean
));
353 range
: '(' Value RANGE Value
')'
355 if
($2->type
!= integervalue
)
356 lex_error_message
("Non-integer used in first part of range");
357 if
($2->type
!= integervalue
)
358 lex_error_message
("Non-integer in second part of range");
359 $$
= ecalloc
(1, sizeof
(*$$
));
360 $$
->min
= $2->u.integervalue
;
361 $$
->max
= $4->u.integervalue
;
363 |
'(' Value RANGE kw_MAX
')'
365 if
($2->type
!= integervalue
)
366 lex_error_message
("Non-integer in first part of range");
367 $$
= ecalloc
(1, sizeof
(*$$
));
368 $$
->min
= $2->u.integervalue
;
369 $$
->max
= $2->u.integervalue
- 1;
371 |
'(' kw_MIN RANGE Value
')'
373 if
($4->type
!= integervalue
)
374 lex_error_message
("Non-integer in second part of range");
375 $$
= ecalloc
(1, sizeof
(*$$
));
376 $$
->min
= $4->u.integervalue
+ 2;
377 $$
->max
= $4->u.integervalue
;
381 if
($2->type
!= integervalue
)
382 lex_error_message
("Non-integer used in limit");
383 $$
= ecalloc
(1, sizeof
(*$$
));
384 $$
->min
= $2->u.integervalue
;
385 $$
->max
= $2->u.integervalue
;
390 IntegerType
: kw_INTEGER
392 $$
= new_tag
(ASN1_C_UNIV
, UT_Integer
,
393 TE_EXPLICIT
, new_type
(TInteger
));
397 $$
= new_type
(TInteger
);
399 $$
= new_tag
(ASN1_C_UNIV
, UT_Integer
, TE_EXPLICIT
, $$
);
401 | kw_INTEGER
'{' NamedNumberList
'}'
403 $$
= new_type
(TInteger
);
405 $$
= new_tag
(ASN1_C_UNIV
, UT_Integer
, TE_EXPLICIT
, $$
);
409 NamedNumberList
: NamedNumber
411 $$
= emalloc
(sizeof
(*$$
));
413 ASN1_TAILQ_INSERT_HEAD
($$
, $1, members
);
415 | NamedNumberList
',' NamedNumber
417 ASN1_TAILQ_INSERT_TAIL
($1, $3, members
);
420 | NamedNumberList
',' ELLIPSIS
421 { $$
= $1; } /* XXX used for Enumerations */
424 NamedNumber
: IDENTIFIER
'(' SignedNumber
')'
426 $$
= emalloc
(sizeof
(*$$
));
428 $$
->gen_name
= estrdup
($1);
429 output_name
($$
->gen_name
);
437 EnumeratedType
: kw_ENUMERATED
'{' Enumerations
'}'
439 $$
= new_type
(TInteger
);
441 $$
= new_tag
(ASN1_C_UNIV
, UT_Enumerated
, TE_EXPLICIT
, $$
);
445 Enumerations
: NamedNumberList
/* XXX */
448 BitStringType
: kw_BIT kw_STRING
450 $$
= new_type
(TBitString
);
451 $$
->members
= emalloc
(sizeof
(*$$
->members
));
452 ASN1_TAILQ_INIT
($$
->members
);
453 $$
= new_tag
(ASN1_C_UNIV
, UT_BitString
, TE_EXPLICIT
, $$
);
455 | kw_BIT kw_STRING
'{' NamedBitList
'}'
457 $$
= new_type
(TBitString
);
459 $$
= new_tag
(ASN1_C_UNIV
, UT_BitString
, TE_EXPLICIT
, $$
);
463 ObjectIdentifierType: kw_OBJECT kw_IDENTIFIER
465 $$
= new_tag
(ASN1_C_UNIV
, UT_OID
,
466 TE_EXPLICIT
, new_type
(TOID
));
469 OctetStringType
: kw_OCTET kw_STRING size
471 Type
*t
= new_type
(TOctetString
);
473 $$
= new_tag
(ASN1_C_UNIV
, UT_OctetString
,
480 $$
= new_tag
(ASN1_C_UNIV
, UT_Null
,
481 TE_EXPLICIT
, new_type
(TNull
));
492 SequenceType
: kw_SEQUENCE
'{' /* ComponentTypeLists */ ComponentTypeList
'}'
494 $$
= new_type
(TSequence
);
496 $$
= new_tag
(ASN1_C_UNIV
, UT_Sequence
, TE_EXPLICIT
, $$
);
498 | kw_SEQUENCE
'{' '}'
500 $$
= new_type
(TSequence
);
502 $$
= new_tag
(ASN1_C_UNIV
, UT_Sequence
, TE_EXPLICIT
, $$
);
506 SequenceOfType
: kw_SEQUENCE size kw_OF Type
508 $$
= new_type
(TSequenceOf
);
511 $$
= new_tag
(ASN1_C_UNIV
, UT_Sequence
, TE_EXPLICIT
, $$
);
515 SetType
: kw_SET
'{' /* ComponentTypeLists */ ComponentTypeList
'}'
519 $$
= new_tag
(ASN1_C_UNIV
, UT_Set
, TE_EXPLICIT
, $$
);
525 $$
= new_tag
(ASN1_C_UNIV
, UT_Set
, TE_EXPLICIT
, $$
);
529 SetOfType
: kw_SET kw_OF Type
531 $$
= new_type
(TSetOf
);
533 $$
= new_tag
(ASN1_C_UNIV
, UT_Set
, TE_EXPLICIT
, $$
);
537 ChoiceType
: kw_CHOICE
'{' /* AlternativeTypeLists */ ComponentTypeList
'}'
539 $$
= new_type
(TChoice
);
544 ReferencedType
: DefinedType
548 DefinedType
: IDENTIFIER
550 Symbol
*s
= addsym
($1);
551 $$
= new_type
(TType
);
552 if
(s
->stype
!= Stype
&& s
->stype
!= SUndefined
)
553 lex_error_message
("%s is not a type\n", $1);
559 UsefulType
: kw_GeneralizedTime
561 $$
= new_tag
(ASN1_C_UNIV
, UT_GeneralizedTime
,
562 TE_EXPLICIT
, new_type
(TGeneralizedTime
));
566 $$
= new_tag
(ASN1_C_UNIV
, UT_UTCTime
,
567 TE_EXPLICIT
, new_type
(TUTCTime
));
571 ConstrainedType
: Type Constraint
573 /* if (Constraint.type == contentConstrant) {
574 assert(Constraint.u.constraint.type == octetstring|bitstring-w/o-NamedBitList); // remember to check type reference too
575 if (Constraint.u.constraint.type) {
576 assert((Constraint.u.constraint.type.length % 8) == 0);
579 if (Constraint.u.constraint.encoding) {
580 type == der-oid|ber-oid
587 Constraint
: '(' ConstraintSpec
')'
593 ConstraintSpec
: GeneralConstraint
596 GeneralConstraint: ContentsConstraint
597 | UserDefinedConstraint
600 ContentsConstraint: kw_CONTAINING Type
602 $$
= new_constraint_spec
(CT_CONTENTS
);
603 $$
->u.content.type
= $2;
604 $$
->u.content.encoding
= NULL
;
606 | kw_ENCODED kw_BY Value
608 if
($3->type
!= objectidentifiervalue
)
609 lex_error_message
("Non-OID used in ENCODED BY constraint");
610 $$
= new_constraint_spec
(CT_CONTENTS
);
611 $$
->u.content.type
= NULL
;
612 $$
->u.content.encoding
= $3;
614 | kw_CONTAINING Type kw_ENCODED kw_BY Value
616 if
($5->type
!= objectidentifiervalue
)
617 lex_error_message
("Non-OID used in ENCODED BY constraint");
618 $$
= new_constraint_spec
(CT_CONTENTS
);
619 $$
->u.content.type
= $2;
620 $$
->u.content.encoding
= $5;
624 UserDefinedConstraint: kw_CONSTRAINED kw_BY
'{' '}'
626 $$
= new_constraint_spec
(CT_USER
);
630 TaggedType
: Tag tagenv Type
635 if
($3->type
== TTag
&& $2 == TE_IMPLICIT
) {
636 $$
->subtype
= $3->subtype
;
643 Tag
: '[' Class NUMBER
']'
647 $$.tagenv
= TE_EXPLICIT
;
684 ValueAssignment
: IDENTIFIER Type EEQUAL Value
691 generate_constant
(s
);
695 CharacterStringType: RestrictedCharactedStringType
698 RestrictedCharactedStringType: kw_GeneralString
700 $$
= new_tag
(ASN1_C_UNIV
, UT_GeneralString
,
701 TE_EXPLICIT
, new_type
(TGeneralString
));
705 $$
= new_tag
(ASN1_C_UNIV
, UT_TeletexString
,
706 TE_EXPLICIT
, new_type
(TTeletexString
));
710 $$
= new_tag
(ASN1_C_UNIV
, UT_UTF8String
,
711 TE_EXPLICIT
, new_type
(TUTF8String
));
715 $$
= new_tag
(ASN1_C_UNIV
, UT_PrintableString
,
716 TE_EXPLICIT
, new_type
(TPrintableString
));
720 $$
= new_tag
(ASN1_C_UNIV
, UT_VisibleString
,
721 TE_EXPLICIT
, new_type
(TVisibleString
));
725 $$
= new_tag
(ASN1_C_UNIV
, UT_IA5String
,
726 TE_EXPLICIT
, new_type
(TIA5String
));
730 $$
= new_tag
(ASN1_C_UNIV
, UT_BMPString
,
731 TE_EXPLICIT
, new_type
(TBMPString
));
735 $$
= new_tag
(ASN1_C_UNIV
, UT_UniversalString
,
736 TE_EXPLICIT
, new_type
(TUniversalString
));
741 ComponentTypeList: ComponentType
743 $$
= emalloc
(sizeof
(*$$
));
745 ASN1_TAILQ_INSERT_HEAD
($$
, $1, members
);
747 | ComponentTypeList
',' ComponentType
749 ASN1_TAILQ_INSERT_TAIL
($1, $3, members
);
752 | ComponentTypeList
',' ELLIPSIS
754 struct member
*m
= ecalloc
(1, sizeof
(*m
));
755 m
->name
= estrdup
("...");
756 m
->gen_name
= estrdup
("asn1_ellipsis");
758 ASN1_TAILQ_INSERT_TAIL
($1, m
, members
);
763 NamedType
: IDENTIFIER Type
765 $$
= emalloc
(sizeof
(*$$
));
767 $$
->gen_name
= estrdup
($1);
768 output_name
($$
->gen_name
);
774 ComponentType
: NamedType
780 | NamedType kw_OPTIONAL
786 | NamedType kw_DEFAULT Value
794 NamedBitList
: NamedBit
796 $$
= emalloc
(sizeof
(*$$
));
798 ASN1_TAILQ_INSERT_HEAD
($$
, $1, members
);
800 | NamedBitList
',' NamedBit
802 ASN1_TAILQ_INSERT_TAIL
($1, $3, members
);
807 NamedBit
: IDENTIFIER
'(' NUMBER
')'
809 $$
= emalloc
(sizeof
(*$$
));
811 $$
->gen_name
= estrdup
($1);
812 output_name
($$
->gen_name
);
821 |
/* empty */ { $$
= NULL
; }
824 objid
: '{' objid_list
'}'
830 objid_list
: /* empty */
834 | objid_element objid_list
838 add_oid_to_tail
($2, $1);
845 objid_element
: IDENTIFIER
'(' NUMBER
')'
847 $$
= new_objid
($1, $3);
851 Symbol
*s
= addsym
($1);
852 if
(s
->stype
!= SValue ||
853 s
->value
->type
!= objectidentifiervalue
) {
854 lex_error_message
("%s is not an object identifier\n",
858 $$
= s
->value
->u.objectidentifiervalue
;
862 $$
= new_objid
(NULL
, $1);
870 BuiltinValue
: BooleanValue
871 | CharacterStringValue
873 | ObjectIdentifierValue
877 ReferencedValue
: DefinedValue
880 DefinedValue
: Valuereference
883 Valuereference
: IDENTIFIER
885 Symbol
*s
= addsym
($1);
886 if
(s
->stype
!= SValue
)
887 lex_error_message
("%s is not a value\n",
894 CharacterStringValue: STRING
896 $$
= emalloc
(sizeof
(*$$
));
897 $$
->type
= stringvalue
;
898 $$
->u.stringvalue
= $1;
902 BooleanValue
: kw_TRUE
904 $$
= emalloc
(sizeof
(*$$
));
905 $$
->type
= booleanvalue
;
906 $$
->u.booleanvalue
= 0;
910 $$
= emalloc
(sizeof
(*$$
));
911 $$
->type
= booleanvalue
;
912 $$
->u.booleanvalue
= 0;
916 IntegerValue
: SignedNumber
918 $$
= emalloc
(sizeof
(*$$
));
919 $$
->type
= integervalue
;
920 $$
->u.integervalue
= $1;
924 SignedNumber
: NUMBER
932 ObjectIdentifierValue: objid
934 $$
= emalloc
(sizeof
(*$$
));
935 $$
->type
= objectidentifiervalue
;
936 $$
->u.objectidentifiervalue
= $1;
943 yyerror (const char *s
)
945 lex_error_message
("%s\n", s
);
949 new_tag
(int tagclass
, int tagvalue
, int tagenv
, Type
*oldtype
)
952 if
(oldtype
->type
== TTag
&& oldtype
->tag.tagenv
== TE_IMPLICIT
) {
954 oldtype
= oldtype
->subtype
; /* XXX */
958 t
->tag.tagclass
= tagclass
;
959 t
->tag.tagvalue
= tagvalue
;
960 t
->tag.tagenv
= tagenv
;
961 t
->subtype
= oldtype
;
965 static struct objid
*
966 new_objid
(const char *label
, int value
)
969 s
= emalloc
(sizeof
(*s
));
977 add_oid_to_tail
(struct objid
*head
, struct objid
*tail
)
987 new_type
(Typetype tt
)
989 Type
*t
= ecalloc
(1, sizeof
(*t
));
994 static struct constraint_spec
*
995 new_constraint_spec
(enum ctype ct
)
997 struct constraint_spec
*c
= ecalloc
(1, sizeof
(*c
));
1002 static void fix_labels2
(Type
*t
, const char *prefix
);
1003 static void fix_labels1
(struct memhead
*members
, const char *prefix
)
1009 ASN1_TAILQ_FOREACH
(m
, members
, members
) {
1010 if
(asprintf
(&m
->label
, "%s_%s", prefix
, m
->gen_name
) < 0)
1012 if
(m
->label
== NULL
)
1015 fix_labels2
(m
->type
, m
->label
);
1019 static void fix_labels2
(Type
*t
, const char *prefix
)
1021 for
(; t
; t
= t
->subtype
)
1022 fix_labels1
(t
->members
, prefix
);
1026 fix_labels
(Symbol
*s
)
1029 if
(asprintf
(&p
, "choice_%s", s
->gen_name
) < 0 || p
== NULL
)
1031 fix_labels2
(s
->type
, p
);