
This brings our tree to NetBSD 7.0, as found on -current on the 10-10-2015. This updates: - LLVM to 3.6.1 - GCC to GCC 5.1 - Replace minix/commands/zdump with usr.bin/zdump - external/bsd/libelf has moved to /external/bsd/elftoolchain/ - Import ctwm - Drop sprintf from libminc Change-Id: I149836ac18e9326be9353958bab9b266efb056f0
1040 lines
21 KiB
Plaintext
1040 lines
21 KiB
Plaintext
/* $NetBSD: asn1parse.y,v 1.1.1.3 2014/04/24 12:45:28 pettai Exp $ */
|
|
|
|
/*
|
|
* Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan
|
|
* (Royal Institute of Technology, Stockholm, Sweden).
|
|
* All rights reserved.
|
|
*
|
|
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
*
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* 3. Neither the name of the Institute nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*/
|
|
|
|
/* Id */
|
|
|
|
%{
|
|
|
|
#include <config.h>
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "symbol.h"
|
|
#include "lex.h"
|
|
#include "gen_locl.h"
|
|
#include "der.h"
|
|
|
|
__RCSID("NetBSD");
|
|
|
|
static Type *new_type (Typetype t);
|
|
static struct constraint_spec *new_constraint_spec(enum ctype);
|
|
static Type *new_tag(int tagclass, int tagvalue, int tagenv, Type *oldtype);
|
|
void yyerror (const char *);
|
|
static struct objid *new_objid(const char *label, int value);
|
|
static void add_oid_to_tail(struct objid *, struct objid *);
|
|
static void fix_labels(Symbol *s);
|
|
|
|
struct string_list {
|
|
char *string;
|
|
struct string_list *next;
|
|
};
|
|
|
|
/* Declarations for Bison */
|
|
#define YYMALLOC malloc
|
|
#define YYFREE free
|
|
|
|
%}
|
|
|
|
%union {
|
|
int constant;
|
|
struct value *value;
|
|
struct range *range;
|
|
char *name;
|
|
Type *type;
|
|
Member *member;
|
|
struct objid *objid;
|
|
char *defval;
|
|
struct string_list *sl;
|
|
struct tagtype tag;
|
|
struct memhead *members;
|
|
struct constraint_spec *constraint_spec;
|
|
}
|
|
|
|
%token kw_ABSENT
|
|
%token kw_ABSTRACT_SYNTAX
|
|
%token kw_ALL
|
|
%token kw_APPLICATION
|
|
%token kw_AUTOMATIC
|
|
%token kw_BEGIN
|
|
%token kw_BIT
|
|
%token kw_BMPString
|
|
%token kw_BOOLEAN
|
|
%token kw_BY
|
|
%token kw_CHARACTER
|
|
%token kw_CHOICE
|
|
%token kw_CLASS
|
|
%token kw_COMPONENT
|
|
%token kw_COMPONENTS
|
|
%token kw_CONSTRAINED
|
|
%token kw_CONTAINING
|
|
%token kw_DEFAULT
|
|
%token kw_DEFINITIONS
|
|
%token kw_EMBEDDED
|
|
%token kw_ENCODED
|
|
%token kw_END
|
|
%token kw_ENUMERATED
|
|
%token kw_EXCEPT
|
|
%token kw_EXPLICIT
|
|
%token kw_EXPORTS
|
|
%token kw_EXTENSIBILITY
|
|
%token kw_EXTERNAL
|
|
%token kw_FALSE
|
|
%token kw_FROM
|
|
%token kw_GeneralString
|
|
%token kw_GeneralizedTime
|
|
%token kw_GraphicString
|
|
%token kw_IA5String
|
|
%token kw_IDENTIFIER
|
|
%token kw_IMPLICIT
|
|
%token kw_IMPLIED
|
|
%token kw_IMPORTS
|
|
%token kw_INCLUDES
|
|
%token kw_INSTANCE
|
|
%token kw_INTEGER
|
|
%token kw_INTERSECTION
|
|
%token kw_ISO646String
|
|
%token kw_MAX
|
|
%token kw_MIN
|
|
%token kw_MINUS_INFINITY
|
|
%token kw_NULL
|
|
%token kw_NumericString
|
|
%token kw_OBJECT
|
|
%token kw_OCTET
|
|
%token kw_OF
|
|
%token kw_OPTIONAL
|
|
%token kw_ObjectDescriptor
|
|
%token kw_PATTERN
|
|
%token kw_PDV
|
|
%token kw_PLUS_INFINITY
|
|
%token kw_PRESENT
|
|
%token kw_PRIVATE
|
|
%token kw_PrintableString
|
|
%token kw_REAL
|
|
%token kw_RELATIVE_OID
|
|
%token kw_SEQUENCE
|
|
%token kw_SET
|
|
%token kw_SIZE
|
|
%token kw_STRING
|
|
%token kw_SYNTAX
|
|
%token kw_T61String
|
|
%token kw_TAGS
|
|
%token kw_TRUE
|
|
%token kw_TYPE_IDENTIFIER
|
|
%token kw_TeletexString
|
|
%token kw_UNION
|
|
%token kw_UNIQUE
|
|
%token kw_UNIVERSAL
|
|
%token kw_UTCTime
|
|
%token kw_UTF8String
|
|
%token kw_UniversalString
|
|
%token kw_VideotexString
|
|
%token kw_VisibleString
|
|
%token kw_WITH
|
|
|
|
%token RANGE
|
|
%token EEQUAL
|
|
%token ELLIPSIS
|
|
|
|
%token <name> IDENTIFIER referencename
|
|
%token <name> STRING
|
|
|
|
%token <constant> NUMBER
|
|
%type <constant> SignedNumber
|
|
%type <constant> Class tagenv
|
|
|
|
%type <value> Value
|
|
%type <value> BuiltinValue
|
|
%type <value> IntegerValue
|
|
%type <value> BooleanValue
|
|
%type <value> ObjectIdentifierValue
|
|
%type <value> CharacterStringValue
|
|
%type <value> NullValue
|
|
%type <value> DefinedValue
|
|
%type <value> ReferencedValue
|
|
%type <value> Valuereference
|
|
|
|
%type <type> Type
|
|
%type <type> BuiltinType
|
|
%type <type> BitStringType
|
|
%type <type> BooleanType
|
|
%type <type> ChoiceType
|
|
%type <type> ConstrainedType
|
|
%type <type> EnumeratedType
|
|
%type <type> IntegerType
|
|
%type <type> NullType
|
|
%type <type> OctetStringType
|
|
%type <type> SequenceType
|
|
%type <type> SequenceOfType
|
|
%type <type> SetType
|
|
%type <type> SetOfType
|
|
%type <type> TaggedType
|
|
%type <type> ReferencedType
|
|
%type <type> DefinedType
|
|
%type <type> UsefulType
|
|
%type <type> ObjectIdentifierType
|
|
%type <type> CharacterStringType
|
|
%type <type> RestrictedCharactedStringType
|
|
|
|
%type <tag> Tag
|
|
|
|
%type <member> ComponentType
|
|
%type <member> NamedBit
|
|
%type <member> NamedNumber
|
|
%type <member> NamedType
|
|
%type <members> ComponentTypeList
|
|
%type <members> Enumerations
|
|
%type <members> NamedBitList
|
|
%type <members> NamedNumberList
|
|
|
|
%type <objid> objid objid_list objid_element objid_opt
|
|
%type <range> range size
|
|
|
|
%type <sl> referencenames
|
|
|
|
%type <constraint_spec> Constraint
|
|
%type <constraint_spec> ConstraintSpec
|
|
%type <constraint_spec> GeneralConstraint
|
|
%type <constraint_spec> ContentsConstraint
|
|
%type <constraint_spec> UserDefinedConstraint
|
|
|
|
|
|
|
|
%start ModuleDefinition
|
|
|
|
%%
|
|
|
|
ModuleDefinition: IDENTIFIER objid_opt kw_DEFINITIONS TagDefault ExtensionDefault
|
|
EEQUAL kw_BEGIN ModuleBody kw_END
|
|
{
|
|
checkundefined();
|
|
}
|
|
;
|
|
|
|
TagDefault : kw_EXPLICIT kw_TAGS
|
|
| kw_IMPLICIT kw_TAGS
|
|
{ lex_error_message("implicit tagging is not supported"); }
|
|
| kw_AUTOMATIC kw_TAGS
|
|
{ lex_error_message("automatic tagging is not supported"); }
|
|
| /* empty */
|
|
;
|
|
|
|
ExtensionDefault: kw_EXTENSIBILITY kw_IMPLIED
|
|
{ lex_error_message("no extensibility options supported"); }
|
|
| /* empty */
|
|
;
|
|
|
|
ModuleBody : Exports Imports AssignmentList
|
|
| /* empty */
|
|
;
|
|
|
|
Imports : kw_IMPORTS SymbolsImported ';'
|
|
| /* empty */
|
|
;
|
|
|
|
SymbolsImported : SymbolsFromModuleList
|
|
| /* empty */
|
|
;
|
|
|
|
SymbolsFromModuleList: SymbolsFromModule
|
|
| SymbolsFromModuleList SymbolsFromModule
|
|
;
|
|
|
|
SymbolsFromModule: referencenames kw_FROM IDENTIFIER objid_opt
|
|
{
|
|
struct string_list *sl;
|
|
for(sl = $1; sl != NULL; sl = sl->next) {
|
|
Symbol *s = addsym(sl->string);
|
|
s->stype = Stype;
|
|
gen_template_import(s);
|
|
}
|
|
add_import($3);
|
|
}
|
|
;
|
|
|
|
Exports : kw_EXPORTS referencenames ';'
|
|
{
|
|
struct string_list *sl;
|
|
for(sl = $2; sl != NULL; sl = sl->next)
|
|
add_export(sl->string);
|
|
}
|
|
| kw_EXPORTS kw_ALL
|
|
| /* empty */
|
|
;
|
|
|
|
AssignmentList : Assignment
|
|
| Assignment AssignmentList
|
|
;
|
|
|
|
Assignment : TypeAssignment
|
|
| ValueAssignment
|
|
;
|
|
|
|
referencenames : IDENTIFIER ',' referencenames
|
|
{
|
|
$$ = emalloc(sizeof(*$$));
|
|
$$->string = $1;
|
|
$$->next = $3;
|
|
}
|
|
| IDENTIFIER
|
|
{
|
|
$$ = emalloc(sizeof(*$$));
|
|
$$->string = $1;
|
|
$$->next = NULL;
|
|
}
|
|
;
|
|
|
|
TypeAssignment : IDENTIFIER EEQUAL Type
|
|
{
|
|
Symbol *s = addsym ($1);
|
|
s->stype = Stype;
|
|
s->type = $3;
|
|
fix_labels(s);
|
|
generate_type (s);
|
|
}
|
|
;
|
|
|
|
Type : BuiltinType
|
|
| ReferencedType
|
|
| ConstrainedType
|
|
;
|
|
|
|
BuiltinType : BitStringType
|
|
| BooleanType
|
|
| CharacterStringType
|
|
| ChoiceType
|
|
| EnumeratedType
|
|
| IntegerType
|
|
| NullType
|
|
| ObjectIdentifierType
|
|
| OctetStringType
|
|
| SequenceType
|
|
| SequenceOfType
|
|
| SetType
|
|
| SetOfType
|
|
| TaggedType
|
|
;
|
|
|
|
BooleanType : kw_BOOLEAN
|
|
{
|
|
$$ = new_tag(ASN1_C_UNIV, UT_Boolean,
|
|
TE_EXPLICIT, new_type(TBoolean));
|
|
}
|
|
;
|
|
|
|
range : '(' Value RANGE Value ')'
|
|
{
|
|
if($2->type != integervalue)
|
|
lex_error_message("Non-integer used in first part of range");
|
|
if($2->type != integervalue)
|
|
lex_error_message("Non-integer in second part of range");
|
|
$$ = ecalloc(1, sizeof(*$$));
|
|
$$->min = $2->u.integervalue;
|
|
$$->max = $4->u.integervalue;
|
|
}
|
|
| '(' Value RANGE kw_MAX ')'
|
|
{
|
|
if($2->type != integervalue)
|
|
lex_error_message("Non-integer in first part of range");
|
|
$$ = ecalloc(1, sizeof(*$$));
|
|
$$->min = $2->u.integervalue;
|
|
$$->max = $2->u.integervalue - 1;
|
|
}
|
|
| '(' kw_MIN RANGE Value ')'
|
|
{
|
|
if($4->type != integervalue)
|
|
lex_error_message("Non-integer in second part of range");
|
|
$$ = ecalloc(1, sizeof(*$$));
|
|
$$->min = $4->u.integervalue + 2;
|
|
$$->max = $4->u.integervalue;
|
|
}
|
|
| '(' Value ')'
|
|
{
|
|
if($2->type != integervalue)
|
|
lex_error_message("Non-integer used in limit");
|
|
$$ = ecalloc(1, sizeof(*$$));
|
|
$$->min = $2->u.integervalue;
|
|
$$->max = $2->u.integervalue;
|
|
}
|
|
;
|
|
|
|
|
|
IntegerType : kw_INTEGER
|
|
{
|
|
$$ = new_tag(ASN1_C_UNIV, UT_Integer,
|
|
TE_EXPLICIT, new_type(TInteger));
|
|
}
|
|
| kw_INTEGER range
|
|
{
|
|
$$ = new_type(TInteger);
|
|
$$->range = $2;
|
|
$$ = new_tag(ASN1_C_UNIV, UT_Integer, TE_EXPLICIT, $$);
|
|
}
|
|
| kw_INTEGER '{' NamedNumberList '}'
|
|
{
|
|
$$ = new_type(TInteger);
|
|
$$->members = $3;
|
|
$$ = new_tag(ASN1_C_UNIV, UT_Integer, TE_EXPLICIT, $$);
|
|
}
|
|
;
|
|
|
|
NamedNumberList : NamedNumber
|
|
{
|
|
$$ = emalloc(sizeof(*$$));
|
|
ASN1_TAILQ_INIT($$);
|
|
ASN1_TAILQ_INSERT_HEAD($$, $1, members);
|
|
}
|
|
| NamedNumberList ',' NamedNumber
|
|
{
|
|
ASN1_TAILQ_INSERT_TAIL($1, $3, members);
|
|
$$ = $1;
|
|
}
|
|
| NamedNumberList ',' ELLIPSIS
|
|
{ $$ = $1; } /* XXX used for Enumerations */
|
|
;
|
|
|
|
NamedNumber : IDENTIFIER '(' SignedNumber ')'
|
|
{
|
|
$$ = emalloc(sizeof(*$$));
|
|
$$->name = $1;
|
|
$$->gen_name = estrdup($1);
|
|
output_name ($$->gen_name);
|
|
$$->val = $3;
|
|
$$->optional = 0;
|
|
$$->ellipsis = 0;
|
|
$$->type = NULL;
|
|
}
|
|
;
|
|
|
|
EnumeratedType : kw_ENUMERATED '{' Enumerations '}'
|
|
{
|
|
$$ = new_type(TInteger);
|
|
$$->members = $3;
|
|
$$ = new_tag(ASN1_C_UNIV, UT_Enumerated, TE_EXPLICIT, $$);
|
|
}
|
|
;
|
|
|
|
Enumerations : NamedNumberList /* XXX */
|
|
;
|
|
|
|
BitStringType : kw_BIT kw_STRING
|
|
{
|
|
$$ = new_type(TBitString);
|
|
$$->members = emalloc(sizeof(*$$->members));
|
|
ASN1_TAILQ_INIT($$->members);
|
|
$$ = new_tag(ASN1_C_UNIV, UT_BitString, TE_EXPLICIT, $$);
|
|
}
|
|
| kw_BIT kw_STRING '{' NamedBitList '}'
|
|
{
|
|
$$ = new_type(TBitString);
|
|
$$->members = $4;
|
|
$$ = new_tag(ASN1_C_UNIV, UT_BitString, TE_EXPLICIT, $$);
|
|
}
|
|
;
|
|
|
|
ObjectIdentifierType: kw_OBJECT kw_IDENTIFIER
|
|
{
|
|
$$ = new_tag(ASN1_C_UNIV, UT_OID,
|
|
TE_EXPLICIT, new_type(TOID));
|
|
}
|
|
;
|
|
OctetStringType : kw_OCTET kw_STRING size
|
|
{
|
|
Type *t = new_type(TOctetString);
|
|
t->range = $3;
|
|
$$ = new_tag(ASN1_C_UNIV, UT_OctetString,
|
|
TE_EXPLICIT, t);
|
|
}
|
|
;
|
|
|
|
NullType : kw_NULL
|
|
{
|
|
$$ = new_tag(ASN1_C_UNIV, UT_Null,
|
|
TE_EXPLICIT, new_type(TNull));
|
|
}
|
|
;
|
|
|
|
size :
|
|
{ $$ = NULL; }
|
|
| kw_SIZE range
|
|
{ $$ = $2; }
|
|
;
|
|
|
|
|
|
SequenceType : kw_SEQUENCE '{' /* ComponentTypeLists */ ComponentTypeList '}'
|
|
{
|
|
$$ = new_type(TSequence);
|
|
$$->members = $3;
|
|
$$ = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, $$);
|
|
}
|
|
| kw_SEQUENCE '{' '}'
|
|
{
|
|
$$ = new_type(TSequence);
|
|
$$->members = NULL;
|
|
$$ = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, $$);
|
|
}
|
|
;
|
|
|
|
SequenceOfType : kw_SEQUENCE size kw_OF Type
|
|
{
|
|
$$ = new_type(TSequenceOf);
|
|
$$->range = $2;
|
|
$$->subtype = $4;
|
|
$$ = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, $$);
|
|
}
|
|
;
|
|
|
|
SetType : kw_SET '{' /* ComponentTypeLists */ ComponentTypeList '}'
|
|
{
|
|
$$ = new_type(TSet);
|
|
$$->members = $3;
|
|
$$ = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, $$);
|
|
}
|
|
| kw_SET '{' '}'
|
|
{
|
|
$$ = new_type(TSet);
|
|
$$->members = NULL;
|
|
$$ = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, $$);
|
|
}
|
|
;
|
|
|
|
SetOfType : kw_SET kw_OF Type
|
|
{
|
|
$$ = new_type(TSetOf);
|
|
$$->subtype = $3;
|
|
$$ = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, $$);
|
|
}
|
|
;
|
|
|
|
ChoiceType : kw_CHOICE '{' /* AlternativeTypeLists */ ComponentTypeList '}'
|
|
{
|
|
$$ = new_type(TChoice);
|
|
$$->members = $3;
|
|
}
|
|
;
|
|
|
|
ReferencedType : DefinedType
|
|
| UsefulType
|
|
;
|
|
|
|
DefinedType : IDENTIFIER
|
|
{
|
|
Symbol *s = addsym($1);
|
|
$$ = new_type(TType);
|
|
if(s->stype != Stype && s->stype != SUndefined)
|
|
lex_error_message ("%s is not a type\n", $1);
|
|
else
|
|
$$->symbol = s;
|
|
}
|
|
;
|
|
|
|
UsefulType : kw_GeneralizedTime
|
|
{
|
|
$$ = new_tag(ASN1_C_UNIV, UT_GeneralizedTime,
|
|
TE_EXPLICIT, new_type(TGeneralizedTime));
|
|
}
|
|
| kw_UTCTime
|
|
{
|
|
$$ = new_tag(ASN1_C_UNIV, UT_UTCTime,
|
|
TE_EXPLICIT, new_type(TUTCTime));
|
|
}
|
|
;
|
|
|
|
ConstrainedType : Type Constraint
|
|
{
|
|
/* if (Constraint.type == contentConstrant) {
|
|
assert(Constraint.u.constraint.type == octetstring|bitstring-w/o-NamedBitList); // remember to check type reference too
|
|
if (Constraint.u.constraint.type) {
|
|
assert((Constraint.u.constraint.type.length % 8) == 0);
|
|
}
|
|
}
|
|
if (Constraint.u.constraint.encoding) {
|
|
type == der-oid|ber-oid
|
|
}
|
|
*/
|
|
}
|
|
;
|
|
|
|
|
|
Constraint : '(' ConstraintSpec ')'
|
|
{
|
|
$$ = $2;
|
|
}
|
|
;
|
|
|
|
ConstraintSpec : GeneralConstraint
|
|
;
|
|
|
|
GeneralConstraint: ContentsConstraint
|
|
| UserDefinedConstraint
|
|
;
|
|
|
|
ContentsConstraint: kw_CONTAINING Type
|
|
{
|
|
$$ = new_constraint_spec(CT_CONTENTS);
|
|
$$->u.content.type = $2;
|
|
$$->u.content.encoding = NULL;
|
|
}
|
|
| kw_ENCODED kw_BY Value
|
|
{
|
|
if ($3->type != objectidentifiervalue)
|
|
lex_error_message("Non-OID used in ENCODED BY constraint");
|
|
$$ = new_constraint_spec(CT_CONTENTS);
|
|
$$->u.content.type = NULL;
|
|
$$->u.content.encoding = $3;
|
|
}
|
|
| kw_CONTAINING Type kw_ENCODED kw_BY Value
|
|
{
|
|
if ($5->type != objectidentifiervalue)
|
|
lex_error_message("Non-OID used in ENCODED BY constraint");
|
|
$$ = new_constraint_spec(CT_CONTENTS);
|
|
$$->u.content.type = $2;
|
|
$$->u.content.encoding = $5;
|
|
}
|
|
;
|
|
|
|
UserDefinedConstraint: kw_CONSTRAINED kw_BY '{' '}'
|
|
{
|
|
$$ = new_constraint_spec(CT_USER);
|
|
}
|
|
;
|
|
|
|
TaggedType : Tag tagenv Type
|
|
{
|
|
$$ = new_type(TTag);
|
|
$$->tag = $1;
|
|
$$->tag.tagenv = $2;
|
|
if($3->type == TTag && $2 == TE_IMPLICIT) {
|
|
$$->subtype = $3->subtype;
|
|
free($3);
|
|
} else
|
|
$$->subtype = $3;
|
|
}
|
|
;
|
|
|
|
Tag : '[' Class NUMBER ']'
|
|
{
|
|
$$.tagclass = $2;
|
|
$$.tagvalue = $3;
|
|
$$.tagenv = TE_EXPLICIT;
|
|
}
|
|
;
|
|
|
|
Class : /* */
|
|
{
|
|
$$ = ASN1_C_CONTEXT;
|
|
}
|
|
| kw_UNIVERSAL
|
|
{
|
|
$$ = ASN1_C_UNIV;
|
|
}
|
|
| kw_APPLICATION
|
|
{
|
|
$$ = ASN1_C_APPL;
|
|
}
|
|
| kw_PRIVATE
|
|
{
|
|
$$ = ASN1_C_PRIVATE;
|
|
}
|
|
;
|
|
|
|
tagenv : /* */
|
|
{
|
|
$$ = TE_EXPLICIT;
|
|
}
|
|
| kw_EXPLICIT
|
|
{
|
|
$$ = TE_EXPLICIT;
|
|
}
|
|
| kw_IMPLICIT
|
|
{
|
|
$$ = TE_IMPLICIT;
|
|
}
|
|
;
|
|
|
|
|
|
ValueAssignment : IDENTIFIER Type EEQUAL Value
|
|
{
|
|
Symbol *s;
|
|
s = addsym ($1);
|
|
|
|
s->stype = SValue;
|
|
s->value = $4;
|
|
generate_constant (s);
|
|
}
|
|
;
|
|
|
|
CharacterStringType: RestrictedCharactedStringType
|
|
;
|
|
|
|
RestrictedCharactedStringType: kw_GeneralString
|
|
{
|
|
$$ = new_tag(ASN1_C_UNIV, UT_GeneralString,
|
|
TE_EXPLICIT, new_type(TGeneralString));
|
|
}
|
|
| kw_TeletexString
|
|
{
|
|
$$ = new_tag(ASN1_C_UNIV, UT_TeletexString,
|
|
TE_EXPLICIT, new_type(TTeletexString));
|
|
}
|
|
| kw_UTF8String
|
|
{
|
|
$$ = new_tag(ASN1_C_UNIV, UT_UTF8String,
|
|
TE_EXPLICIT, new_type(TUTF8String));
|
|
}
|
|
| kw_PrintableString
|
|
{
|
|
$$ = new_tag(ASN1_C_UNIV, UT_PrintableString,
|
|
TE_EXPLICIT, new_type(TPrintableString));
|
|
}
|
|
| kw_VisibleString
|
|
{
|
|
$$ = new_tag(ASN1_C_UNIV, UT_VisibleString,
|
|
TE_EXPLICIT, new_type(TVisibleString));
|
|
}
|
|
| kw_IA5String
|
|
{
|
|
$$ = new_tag(ASN1_C_UNIV, UT_IA5String,
|
|
TE_EXPLICIT, new_type(TIA5String));
|
|
}
|
|
| kw_BMPString
|
|
{
|
|
$$ = new_tag(ASN1_C_UNIV, UT_BMPString,
|
|
TE_EXPLICIT, new_type(TBMPString));
|
|
}
|
|
| kw_UniversalString
|
|
{
|
|
$$ = new_tag(ASN1_C_UNIV, UT_UniversalString,
|
|
TE_EXPLICIT, new_type(TUniversalString));
|
|
}
|
|
|
|
;
|
|
|
|
ComponentTypeList: ComponentType
|
|
{
|
|
$$ = emalloc(sizeof(*$$));
|
|
ASN1_TAILQ_INIT($$);
|
|
ASN1_TAILQ_INSERT_HEAD($$, $1, members);
|
|
}
|
|
| ComponentTypeList ',' ComponentType
|
|
{
|
|
ASN1_TAILQ_INSERT_TAIL($1, $3, members);
|
|
$$ = $1;
|
|
}
|
|
| ComponentTypeList ',' ELLIPSIS
|
|
{
|
|
struct member *m = ecalloc(1, sizeof(*m));
|
|
m->name = estrdup("...");
|
|
m->gen_name = estrdup("asn1_ellipsis");
|
|
m->ellipsis = 1;
|
|
ASN1_TAILQ_INSERT_TAIL($1, m, members);
|
|
$$ = $1;
|
|
}
|
|
;
|
|
|
|
NamedType : IDENTIFIER Type
|
|
{
|
|
$$ = emalloc(sizeof(*$$));
|
|
$$->name = $1;
|
|
$$->gen_name = estrdup($1);
|
|
output_name ($$->gen_name);
|
|
$$->type = $2;
|
|
$$->ellipsis = 0;
|
|
}
|
|
;
|
|
|
|
ComponentType : NamedType
|
|
{
|
|
$$ = $1;
|
|
$$->optional = 0;
|
|
$$->defval = NULL;
|
|
}
|
|
| NamedType kw_OPTIONAL
|
|
{
|
|
$$ = $1;
|
|
$$->optional = 1;
|
|
$$->defval = NULL;
|
|
}
|
|
| NamedType kw_DEFAULT Value
|
|
{
|
|
$$ = $1;
|
|
$$->optional = 0;
|
|
$$->defval = $3;
|
|
}
|
|
;
|
|
|
|
NamedBitList : NamedBit
|
|
{
|
|
$$ = emalloc(sizeof(*$$));
|
|
ASN1_TAILQ_INIT($$);
|
|
ASN1_TAILQ_INSERT_HEAD($$, $1, members);
|
|
}
|
|
| NamedBitList ',' NamedBit
|
|
{
|
|
ASN1_TAILQ_INSERT_TAIL($1, $3, members);
|
|
$$ = $1;
|
|
}
|
|
;
|
|
|
|
NamedBit : IDENTIFIER '(' NUMBER ')'
|
|
{
|
|
$$ = emalloc(sizeof(*$$));
|
|
$$->name = $1;
|
|
$$->gen_name = estrdup($1);
|
|
output_name ($$->gen_name);
|
|
$$->val = $3;
|
|
$$->optional = 0;
|
|
$$->ellipsis = 0;
|
|
$$->type = NULL;
|
|
}
|
|
;
|
|
|
|
objid_opt : objid
|
|
| /* empty */ { $$ = NULL; }
|
|
;
|
|
|
|
objid : '{' objid_list '}'
|
|
{
|
|
$$ = $2;
|
|
}
|
|
;
|
|
|
|
objid_list : /* empty */
|
|
{
|
|
$$ = NULL;
|
|
}
|
|
| objid_element objid_list
|
|
{
|
|
if ($2) {
|
|
$$ = $2;
|
|
add_oid_to_tail($2, $1);
|
|
} else {
|
|
$$ = $1;
|
|
}
|
|
}
|
|
;
|
|
|
|
objid_element : IDENTIFIER '(' NUMBER ')'
|
|
{
|
|
$$ = new_objid($1, $3);
|
|
}
|
|
| IDENTIFIER
|
|
{
|
|
Symbol *s = addsym($1);
|
|
if(s->stype != SValue ||
|
|
s->value->type != objectidentifiervalue) {
|
|
lex_error_message("%s is not an object identifier\n",
|
|
s->name);
|
|
exit(1);
|
|
}
|
|
$$ = s->value->u.objectidentifiervalue;
|
|
}
|
|
| NUMBER
|
|
{
|
|
$$ = new_objid(NULL, $1);
|
|
}
|
|
;
|
|
|
|
Value : BuiltinValue
|
|
| ReferencedValue
|
|
;
|
|
|
|
BuiltinValue : BooleanValue
|
|
| CharacterStringValue
|
|
| IntegerValue
|
|
| ObjectIdentifierValue
|
|
| NullValue
|
|
;
|
|
|
|
ReferencedValue : DefinedValue
|
|
;
|
|
|
|
DefinedValue : Valuereference
|
|
;
|
|
|
|
Valuereference : IDENTIFIER
|
|
{
|
|
Symbol *s = addsym($1);
|
|
if(s->stype != SValue)
|
|
lex_error_message ("%s is not a value\n",
|
|
s->name);
|
|
else
|
|
$$ = s->value;
|
|
}
|
|
;
|
|
|
|
CharacterStringValue: STRING
|
|
{
|
|
$$ = emalloc(sizeof(*$$));
|
|
$$->type = stringvalue;
|
|
$$->u.stringvalue = $1;
|
|
}
|
|
;
|
|
|
|
BooleanValue : kw_TRUE
|
|
{
|
|
$$ = emalloc(sizeof(*$$));
|
|
$$->type = booleanvalue;
|
|
$$->u.booleanvalue = 0;
|
|
}
|
|
| kw_FALSE
|
|
{
|
|
$$ = emalloc(sizeof(*$$));
|
|
$$->type = booleanvalue;
|
|
$$->u.booleanvalue = 0;
|
|
}
|
|
;
|
|
|
|
IntegerValue : SignedNumber
|
|
{
|
|
$$ = emalloc(sizeof(*$$));
|
|
$$->type = integervalue;
|
|
$$->u.integervalue = $1;
|
|
}
|
|
;
|
|
|
|
SignedNumber : NUMBER
|
|
;
|
|
|
|
NullValue : kw_NULL
|
|
{
|
|
}
|
|
;
|
|
|
|
ObjectIdentifierValue: objid
|
|
{
|
|
$$ = emalloc(sizeof(*$$));
|
|
$$->type = objectidentifiervalue;
|
|
$$->u.objectidentifiervalue = $1;
|
|
}
|
|
;
|
|
|
|
%%
|
|
|
|
void
|
|
yyerror (const char *s)
|
|
{
|
|
lex_error_message ("%s\n", s);
|
|
}
|
|
|
|
static Type *
|
|
new_tag(int tagclass, int tagvalue, int tagenv, Type *oldtype)
|
|
{
|
|
Type *t;
|
|
if(oldtype->type == TTag && oldtype->tag.tagenv == TE_IMPLICIT) {
|
|
t = oldtype;
|
|
oldtype = oldtype->subtype; /* XXX */
|
|
} else
|
|
t = new_type (TTag);
|
|
|
|
t->tag.tagclass = tagclass;
|
|
t->tag.tagvalue = tagvalue;
|
|
t->tag.tagenv = tagenv;
|
|
t->subtype = oldtype;
|
|
return t;
|
|
}
|
|
|
|
static struct objid *
|
|
new_objid(const char *label, int value)
|
|
{
|
|
struct objid *s;
|
|
s = emalloc(sizeof(*s));
|
|
s->label = label;
|
|
s->value = value;
|
|
s->next = NULL;
|
|
return s;
|
|
}
|
|
|
|
static void
|
|
add_oid_to_tail(struct objid *head, struct objid *tail)
|
|
{
|
|
struct objid *o;
|
|
o = head;
|
|
while (o->next)
|
|
o = o->next;
|
|
o->next = tail;
|
|
}
|
|
|
|
static Type *
|
|
new_type (Typetype tt)
|
|
{
|
|
Type *t = ecalloc(1, sizeof(*t));
|
|
t->type = tt;
|
|
return t;
|
|
}
|
|
|
|
static struct constraint_spec *
|
|
new_constraint_spec(enum ctype ct)
|
|
{
|
|
struct constraint_spec *c = ecalloc(1, sizeof(*c));
|
|
c->ctype = ct;
|
|
return c;
|
|
}
|
|
|
|
static void fix_labels2(Type *t, const char *prefix);
|
|
static void fix_labels1(struct memhead *members, const char *prefix)
|
|
{
|
|
Member *m;
|
|
|
|
if(members == NULL)
|
|
return;
|
|
ASN1_TAILQ_FOREACH(m, members, members) {
|
|
if (asprintf(&m->label, "%s_%s", prefix, m->gen_name) < 0)
|
|
errx(1, "malloc");
|
|
if (m->label == NULL)
|
|
errx(1, "malloc");
|
|
if(m->type != NULL)
|
|
fix_labels2(m->type, m->label);
|
|
}
|
|
}
|
|
|
|
static void fix_labels2(Type *t, const char *prefix)
|
|
{
|
|
for(; t; t = t->subtype)
|
|
fix_labels1(t->members, prefix);
|
|
}
|
|
|
|
static void
|
|
fix_labels(Symbol *s)
|
|
{
|
|
char *p = NULL;
|
|
if (asprintf(&p, "choice_%s", s->gen_name) < 0 || p == NULL)
|
|
errx(1, "malloc");
|
|
fix_labels2(s->type, p);
|
|
free(p);
|
|
}
|