2 * Copyright (C) 2000,2001 Fabio Fiorina
4 * This file is part of GNUTLS.
6 * GNUTLS is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * GNUTLS is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
22 /*****************************************************/
23 /* File: x509_ASN.y */
24 /* Description: input file for 'bison' program. */
25 /* The output file is a parser (in C language) for */
27 /*****************************************************/
32 #include <x509_asn1.h>
33 #include <gnutls_errors_int.h>
35 FILE *file_asn1
; /* Pointer to file to parse */
36 extern
int parse_mode
; /* PARSE_MODE_CHECK = only syntax check
37 PARSE_MODE_CREATE = structure creation */
38 int result_parse
; /* result of the parser algorithm */
39 node_asn
*p_tree
; /* pointer to the root of the structure
40 created by the parser*/
49 unsigned int constant
;
57 %token
<str
> IDENTIFIER
89 %token GeneralizedTime
94 %type
<node
> octet_string_def constant constant_list type_assig_right
95 %type
<node
> integer_def type_assig type_assig_list sequence_def type_def
96 %type
<node
> bit_string_def default size_def choise_def object_def
97 %type
<node
> boolean_def any_def size_def2 obj_constant obj_constant_list
98 %type
<node
> constant_def type_constant type_constant_list definitions
99 %type
<node
> definitions_id Time bit_element bit_element_list set_def
100 %type
<node
> identifier_list imports_def tag_type tag type_assig_right_tag
101 %type
<node
> type_assig_right_tag_default enumerated_def
102 %type
<str
> pos_num neg_num pos_neg_num pos_neg_identifier num_identifier
103 %type
<constant
> class explicit_implicit
111 pos_num
: NUM
{strcpy
($$
,$1);}
112 |
'+' NUM
{strcpy
($$
,$2);}
115 neg_num
: '-' NUM
{strcpy
($$
,"-");
119 pos_neg_num
: pos_num
{strcpy
($$
,$1);}
120 | neg_num
{strcpy
($$
,$1);}
123 num_identifier
: NUM
{strcpy
($$
,$1);}
124 | IDENTIFIER
{strcpy
($$
,$1);}
127 pos_neg_identifier
: pos_neg_num
{strcpy
($$
,$1);}
128 | IDENTIFIER
{strcpy
($$
,$1);}
131 constant: '(' pos_neg_num
')' {$$
=_asn1_add_node
(TYPE_CONSTANT
);
132 _asn1_set_value
($$
,$2,strlen
($2)+1);}
133 | IDENTIFIER
'('pos_neg_num
')' {$$
=_asn1_add_node
(TYPE_CONSTANT
);
134 _asn1_set_name
($$
,$1);
135 _asn1_set_value
($$
,$3,strlen
($3)+1);}
138 constant_list: constant
{$$
=$1;}
139 | constant_list
',' constant
{$$
=$1;
140 _asn1_set_right
(_asn1_get_last_right
($1),$3);}
143 identifier_list
: IDENTIFIER
{$$
=_asn1_add_node
(TYPE_IDENTIFIER
);
144 _asn1_set_name
($$
,$1);}
145 | identifier_list IDENTIFIER
147 _asn1_set_right
(_asn1_get_last_right
($$
),_asn1_add_node
(TYPE_IDENTIFIER
));
148 _asn1_set_name
(_asn1_get_last_right
($$
),$2);}
151 obj_constant: num_identifier
{$$
=_asn1_add_node
(TYPE_CONSTANT
);
152 _asn1_set_value
($$
,$1,strlen
($1)+1);}
153 | IDENTIFIER
'('NUM
')' {$$
=_asn1_add_node
(TYPE_CONSTANT
);
154 _asn1_set_name
($$
,$1);
155 _asn1_set_value
($$
,$3,strlen
($3)+1);}
158 obj_constant_list: obj_constant
{$$
=$1;}
159 | obj_constant_list obj_constant
{$$
=$1;
160 _asn1_set_right
(_asn1_get_last_right
($1),$2);}
163 class
: UNIVERSAL
{$$
=CONST_UNIVERSAL
;}
164 | PRIVATE
{$$
=CONST_PRIVATE
;}
165 | APPLICATION
{$$
=CONST_APPLICATION
;}
168 tag_type
: '[' NUM
']' {$$
=_asn1_add_node
(TYPE_TAG
);
169 _asn1_set_value
($$
,$2,strlen
($2)+1);}
170 |
'[' class NUM
']' {$$
=_asn1_add_node
(TYPE_TAG |
$2);
171 _asn1_set_value
($$
,$3,strlen
($3)+1);}
174 tag
: tag_type
{$$
=$1;}
175 | tag_type EXPLICIT
{$$
=_asn1_mod_type
($1,CONST_EXPLICIT
);}
176 | tag_type IMPLICIT
{$$
=_asn1_mod_type
($1,CONST_IMPLICIT
);}
179 default
: DEFAULT pos_neg_identifier
{$$
=_asn1_add_node
(TYPE_DEFAULT
);
180 _asn1_set_value
($$
,$2,strlen
($2)+1);}
181 | DEFAULT TRUE
{$$
=_asn1_add_node
(TYPE_DEFAULT|CONST_TRUE
);}
182 | DEFAULT FALSE
{$$
=_asn1_add_node
(TYPE_DEFAULT|CONST_FALSE
);}
185 integer_def: INTEGER
{$$
=_asn1_add_node
(TYPE_INTEGER
);}
186 | INTEGER
'{'constant_list
'}' {$$
=_asn1_add_node
(TYPE_INTEGER|CONST_LIST
);
187 _asn1_set_down
($$
,$3);}
188 | integer_def
'('num_identifier
'.''.'num_identifier
')'
189 {$$
=_asn1_add_node
(TYPE_INTEGER|CONST_MIN_MAX
);
190 _asn1_set_down
($$
,_asn1_add_node
(TYPE_SIZE
));
191 _asn1_set_value
(_asn1_get_down
($$
),$6,strlen
($6)+1);
192 _asn1_set_name
(_asn1_get_down
($$
),$3);}
195 boolean_def: BOOLEAN
{$$
=_asn1_add_node
(TYPE_BOOLEAN
);}
198 Time: UTCTime
{$$
=_asn1_add_node
(TYPE_TIME|CONST_UTC
);}
199 | GeneralizedTime
{$$
=_asn1_add_node
(TYPE_TIME|CONST_GENERALIZED
);}
202 size_def2: SIZE
'('num_identifier
')' {$$
=_asn1_add_node
(TYPE_SIZE|CONST_1_PARAM
);
203 _asn1_set_value
($$
,$3,strlen
($3)+1);}
204 | SIZE
'('num_identifier
'.''.'num_identifier
')'
205 {$$
=_asn1_add_node
(TYPE_SIZE|CONST_MIN_MAX
);
206 _asn1_set_value
($$
,$3,strlen
($3)+1);
207 _asn1_set_name
($$
,$6);}
210 size_def: size_def2
{$$
=$1;}
211 |
'(' size_def2
')' {$$
=$2;}
214 octet_string_def
: OCTET STRING
{$$
=_asn1_add_node
(TYPE_OCTET_STRING
);}
215 | OCTET STRING size_def
{$$
=_asn1_add_node
(TYPE_OCTET_STRING|CONST_SIZE
);
216 _asn1_set_down
($$
,$3);}
219 bit_element
: IDENTIFIER
'('NUM
')' {$$
=_asn1_add_node
(TYPE_CONSTANT
);
220 _asn1_set_name
($$
,$1);
221 _asn1_set_value
($$
,$3,strlen
($3)+1);}
224 bit_element_list
: bit_element
{$$
=$1;}
225 | bit_element_list
',' bit_element
{$$
=$1;
226 _asn1_set_right
(_asn1_get_last_right
($1),$3);}
229 bit_string_def
: BIT STRING
{$$
=_asn1_add_node
(TYPE_BIT_STRING
);}
230 | BIT STRING
'{'bit_element_list
'}'
231 {$$
=_asn1_add_node
(TYPE_BIT_STRING|CONST_LIST
);
232 _asn1_set_down
($$
,$4);}
235 enumerated_def
: ENUMERATED
'{'bit_element_list
'}'
236 {$$
=_asn1_add_node
(TYPE_ENUMERATED|CONST_LIST
);
237 _asn1_set_down
($$
,$3);}
240 object_def
: OBJECT STR_IDENTIFIER
{$$
=_asn1_add_node
(TYPE_OBJECT_ID
);}
243 type_assig_right: IDENTIFIER
{$$
=_asn1_add_node
(TYPE_IDENTIFIER
);
244 _asn1_set_value
($$
,$1,strlen
($1)+1);}
245 | IDENTIFIER size_def
{$$
=_asn1_add_node
(TYPE_IDENTIFIER|CONST_SIZE
);
246 _asn1_set_value
($$
,$1,strlen
($1)+1);
247 _asn1_set_down
($$
,$2);}
248 | integer_def
{$$
=$1;}
249 | enumerated_def
{$$
=$1;}
250 | boolean_def
{$$
=$1;}
252 | octet_string_def
{$$
=$1;}
253 | bit_string_def
{$$
=$1;}
254 | sequence_def
{$$
=$1;}
255 | object_def
{$$
=$1;}
256 | choise_def
{$$
=$1;}
259 | TOKEN_NULL
{$$
=_asn1_add_node
(TYPE_NULL
);}
262 type_assig_right_tag
: type_assig_right
{$$
=$1;}
263 | tag type_assig_right
{$$
=_asn1_mod_type
($2,CONST_TAG
);
264 _asn1_set_right
($1,_asn1_get_down
($$
));
265 _asn1_set_down
($$
,$1);}
268 type_assig_right_tag_default
: type_assig_right_tag
{$$
=$1;}
269 | type_assig_right_tag default
{$$
=_asn1_mod_type
($1,CONST_DEFAULT
);
270 _asn1_set_right
($2,_asn1_get_down
($$
));
271 _asn1_set_down
($$
,$2);}
272 | type_assig_right_tag OPTIONAL
{$$
=_asn1_mod_type
($1,CONST_OPTION
);}
275 type_assig
: IDENTIFIER type_assig_right_tag_default
{$$
=_asn1_set_name
($2,$1);}
278 type_assig_list
: type_assig
{$$
=$1;}
279 | type_assig_list
','type_assig
{$$
=$1;
280 _asn1_set_right
(_asn1_get_last_right
($1),$3);}
283 sequence_def
: SEQUENCE
'{'type_assig_list
'}' {$$
=_asn1_add_node
(TYPE_SEQUENCE
);
284 _asn1_set_down
($$
,$3);}
285 | SEQUENCE OF type_assig_right
{$$
=_asn1_add_node
(TYPE_SEQUENCE_OF
);
286 _asn1_set_down
($$
,$3);}
287 | SEQUENCE size_def OF type_assig_right
{$$
=_asn1_add_node
(TYPE_SEQUENCE_OF|CONST_SIZE
);
288 _asn1_set_right
($2,$4);
289 _asn1_set_down
($$
,$2);}
292 set_def
: SET
'{'type_assig_list
'}' {$$
=_asn1_add_node
(TYPE_SET
);
293 _asn1_set_down
($$
,$3);}
294 | SET OF type_assig_right
{$$
=_asn1_add_node
(TYPE_SET_OF
);
295 _asn1_set_down
($$
,$3);}
296 | SET size_def OF type_assig_right
{$$
=_asn1_add_node
(TYPE_SET_OF|CONST_SIZE
);
297 _asn1_set_right
($2,$4);
298 _asn1_set_down
($$
,$2);}
301 choise_def
: CHOICE
'{'type_assig_list
'}' {$$
=_asn1_add_node
(TYPE_CHOICE
);
302 _asn1_set_down
($$
,$3);}
305 any_def
: ANY
{$$
=_asn1_add_node
(TYPE_ANY
);}
306 | ANY DEFINED BY IDENTIFIER
{$$
=_asn1_add_node
(TYPE_ANY|CONST_DEFINED_BY
);
307 _asn1_set_down
($$
,_asn1_add_node
(TYPE_CONSTANT
));
308 _asn1_set_name
(_asn1_get_down
($$
),$4);}
311 type_def
: IDENTIFIER
"::=" type_assig_right_tag
{$$
=_asn1_set_name
($3,$1);}
314 constant_def
: IDENTIFIER OBJECT STR_IDENTIFIER
"::=" '{'obj_constant_list
'}'
315 {$$
=_asn1_add_node
(TYPE_OBJECT_ID|CONST_ASSIGN
);
316 _asn1_set_name
($$
,$1);
317 _asn1_set_down
($$
,$6);}
318 | IDENTIFIER IDENTIFIER
"::=" '{' obj_constant_list
'}'
319 {$$
=_asn1_add_node
(TYPE_OBJECT_ID|CONST_ASSIGN|CONST_1_PARAM
);
320 _asn1_set_name
($$
,$1);
321 _asn1_set_value
($$
,$2,strlen
($2)+1);
322 _asn1_set_down
($$
,$5);}
323 | IDENTIFIER INTEGER
"::=" NUM
324 {$$
=_asn1_add_node
(TYPE_INTEGER|CONST_ASSIGN
);
325 _asn1_set_name
($$
,$1);
326 _asn1_set_value
($$
,$4,strlen
($4)+1);}
329 type_constant: type_def
{$$
=$1;}
330 | constant_def
{$$
=$1;}
333 type_constant_list
: type_constant
{$$
=$1;}
334 | type_constant_list type_constant
{$$
=$1;
335 _asn1_set_right
(_asn1_get_last_right
($1),$2);}
338 definitions_id
: IDENTIFIER
'{' obj_constant_list
'}' {$$
=_asn1_add_node
(TYPE_OBJECT_ID
);
339 _asn1_set_down
($$
,$3);
340 _asn1_set_name
($$
,$1);}
341 | IDENTIFIER
'{' '}' {$$
=_asn1_add_node
(TYPE_OBJECT_ID
);
342 _asn1_set_name
($$
,$1);}
345 imports_def
: /* empty */ {$$
=NULL
;}
346 | IMPORTS identifier_list FROM IDENTIFIER obj_constant_list
347 {$$
=_asn1_add_node
(TYPE_IMPORTS
);
348 _asn1_set_down
($$
,_asn1_add_node
(TYPE_OBJECT_ID
));
349 _asn1_set_name
(_asn1_get_down
($$
),$4);
350 _asn1_set_down
(_asn1_get_down
($$
),$5);
351 _asn1_set_right
($$
,$2);}
354 explicit_implicit
: EXPLICIT
{$$
=CONST_EXPLICIT
;}
355 | IMPLICIT
{$$
=CONST_IMPLICIT
;}
358 definitions: definitions_id
359 DEFINITIONS explicit_implicit TAGS
"::=" BEGIN imports_def
360 type_constant_list END
361 {$$
=_asn1_add_node
(TYPE_DEFINITIONS|
$3|
(($7==NULL
)?
0:CONST_IMPORTS
));
362 _asn1_set_name
($$
,_asn1_get_name
($1));
363 _asn1_set_name
($1,"");
364 if
($7==NULL
) _asn1_set_right
($1,$8);
365 else
{_asn1_set_right
($7,$8);_asn1_set_right
($1,$7);}
366 _asn1_set_down
($$
,$1);
367 if
(parse_mode
==PARSE_MODE_CREATE
){
368 _asn1_set_default_tag
($$
);
369 _asn1_type_set_config
($$
);
370 result_parse
=_asn1_check_identifier
($$
);
371 if
(result_parse
==ASN_IDENTIFIER_NOT_FOUND
)
372 asn1_delete_structure
($$
);
383 const char *key_word
[]={"::=","OPTIONAL","INTEGER","SIZE","OCTET","STRING"
384 ,"SEQUENCE","BIT","UNIVERSAL","PRIVATE","OPTIONAL"
385 ,"DEFAULT","CHOICE","OF","OBJECT","IDENTIFIER"
386 ,"BOOLEAN","TRUE","FALSE","APPLICATION","ANY","DEFINED"
387 ,"SET","BY","EXPLICIT","IMPLICIT","DEFINITIONS","TAGS"
388 ,"BEGIN","END","UTCTime","GeneralizedTime","FROM"
389 ,"IMPORTS","NULL","ENUMERATED"};
390 const int key_word_token
[]={ASSIG
,OPTIONAL
,INTEGER
,SIZE
,OCTET
,STRING
391 ,SEQUENCE
,BIT
,UNIVERSAL
,PRIVATE
,OPTIONAL
392 ,DEFAULT
,CHOICE
,OF
,OBJECT
,STR_IDENTIFIER
393 ,BOOLEAN
,TRUE
,FALSE
,APPLICATION
,ANY
,DEFINED
394 ,SET
,BY
,EXPLICIT
,IMPLICIT
,DEFINITIONS
,TAGS
395 ,BEGIN
,END
,UTCTime
,GeneralizedTime
,FROM
396 ,IMPORTS
,TOKEN_NULL
,ENUMERATED
};
398 /*************************************************************/
399 /* Function: yylex */
400 /* Description: looks for tokens in file_asn1 pointer file. */
402 /* Token identifier or ASCII code or 0(zero: End Of File) */
403 /*************************************************************/
408 char string[129]; /* will contain the next token */
411 while
((c
=fgetc
(file_asn1
))==' ' || c
=='\t' || c
=='\n');
413 if
(c
=='(' || c
==')' || c
=='[' || c
==']' ||
414 c
=='{' || c
=='}' || c
==',' || c
=='.' ||
416 if
(c
=='-'){ /* Maybe the first '-' of a comment */
417 if
((c
=fgetc
(file_asn1
))!='-'){
423 /* A comment finishes at the end of line */
424 while
((c
=fgetc
(file_asn1
))!=EOF
&& c
!='\n');
426 else continue
; /* next char, please! (repeat the search) */
430 /* Till the end of the token */
431 while
(!((c
=fgetc
(file_asn1
))==EOF || c
==' '|| c
=='\t' || c
=='\n' ||
432 c
=='(' || c
==')' || c
=='[' || c
==']' ||
433 c
=='{' || c
=='}' || c
==',' || c
=='.'))
440 /* Is STRING a number? */
441 for
(k
=0;k
<counter
;k
++)
442 if
(!isdigit
(string[k
])) break
;
445 strcpy
(yylval.str
,string);
446 return NUM
; /* return the number */
449 /* Is STRING a keyword? */
450 for
(k
=0;k
<(sizeof
(key_word
)/sizeof
(char*));k
++)
451 if
(!strcmp
(string,key_word
[k
])) return key_word_token
[k
];
453 /* STRING is an IDENTIFIER */
454 strcpy
(yylval.str
,string);
461 * asn1_parser_asn1 - function used to start the parse algorithm.
462 * @file_name: specify the path and the name of file that contains ASN.1 declarations.
463 * @pointer: return the pointer to the structure created from
464 * "file_name" ASN.1 declarations.
467 * Creates the structures needed to manage the definitions included in *FILE_NAME file.
471 * ASN_OK\: the file has a correct syntax and every identifier is known.
473 * ASN_FILE_NOT_FOUND\: an error occured while opening FILE_NAME.
475 * ASN_SYNTAX_ERROR\: the syntax is not correct.
477 * ASN_IDENTIFIER_NOT_FOUND\: in the file there is an identifier that is not defined.
479 int asn1_parser_asn1
(char *file_name
,node_asn
**pointer
){
483 /* open the file to parse */
484 file_asn1
=fopen
(file_name
,"r");
485 if
(file_asn1
==NULL
) return ASN_FILE_NOT_FOUND
;
489 /* only syntax check */
490 parse_mode
=PARSE_MODE_CHECK
;
493 if
(result_parse
==ASN_OK
){ /* syntax OK */
495 file_asn1
=fopen
(file_name
,"r");
497 /* structure creation */
498 parse_mode
=PARSE_MODE_CREATE
;
501 _asn1_change_integer_value
(p_tree
);
502 _asn1_expand_object_id
(p_tree
);
507 parse_mode
=PARSE_MODE_CREATE
;
516 * asn1_parser_asn1_file_c - function that generates a C structure from an ASN1 file
517 * @file_name: specify the path and the name of file that contains ASN.1 declarations.
520 * Creates a file containing a C vector to use to manage the definitions included in
521 * *FILE_NAME file. If *FILE_NAME is "/aa/bb/xx.yy" the file created is "/aa/bb/xx_asn1_tab.c",
522 * and the vector is "xx_asn1_tab".
526 * ASN_OK\: the file has a correct syntax and every identifier is known.
528 * ASN_FILE_NOT_FOUND\: an error occured while opening FILE_NAME.
530 * ASN_SYNTAX_ERROR\: the syntax is not correct.
532 * ASN_IDENTIFIER_NOT_FOUND\: in the file there is an identifier that is not defined.
534 int asn1_parser_asn1_file_c
(char *file_name
){
539 /* open the file to parse */
540 file_asn1
=fopen
(file_name
,"r");
541 if
(file_asn1
==NULL
) return ASN_FILE_NOT_FOUND
;
546 parse_mode
=PARSE_MODE_CHECK
;
549 if
(result_parse
==ASN_OK
){ /* syntax OK */
551 file_asn1
=fopen
(file_name
,"r");
553 /* structure creation */
554 parse_mode
=PARSE_MODE_CREATE
;
557 /* structure saved in a file */
558 result
=_asn1_create_static_structure
(p_tree
,file_name
,NULL
);
560 /* delete structure in memory */
561 asn1_delete_structure
(p_tree
);
566 parse_mode
=PARSE_MODE_CREATE
;
572 /*************************************************************/
573 /* Function: yyerror */
574 /* Description: function called when there are syntax errors*/
576 /* char *s : error description */
579 /*************************************************************/
580 int yyerror (char *s
)
582 /* Sends the error description to the std_out */
583 /* printf("%s\n",s); */
584 result_parse
=ASN_SYNTAX_ERROR
;