*** empty log message ***
[gnutls.git] / lib / x509_ASN.y
blob74bc5fb9ed336254d61260554b9801c82f26f271
1 /*
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 */
26 /* ASN.1 syntax */
27 /*****************************************************/
30 %{
31 #include <defines.h>
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*/
42 int yyerror (char *);
43 int yylex(void);
48 %union {
49 unsigned int constant;
50 char str[129];
51 node_asn* node;
55 %token ASSIG "::="
56 %token <str> NUM
57 %token <str> IDENTIFIER
58 %token OPTIONAL
59 %token INTEGER
60 %token SIZE
61 %token OCTET
62 %token STRING
63 %token SEQUENCE
64 %token BIT
65 %token UNIVERSAL
66 %token PRIVATE
67 %token APPLICATION
68 %token OPTIONAL
69 %token DEFAULT
70 %token CHOICE
71 %token OF
72 %token OBJECT
73 %token STR_IDENTIFIER
74 %token BOOLEAN
75 %token TRUE
76 %token FALSE
77 %token TOKEN_NULL
78 %token ANY
79 %token DEFINED
80 %token BY
81 %token SET
82 %token EXPLICIT
83 %token IMPLICIT
84 %token DEFINITIONS
85 %token TAGS
86 %token BEGIN
87 %token END
88 %token UTCTime
89 %token GeneralizedTime
90 %token FROM
91 %token IMPORTS
92 %token ENUMERATED
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
107 input: /* empty */
108 | input definitions
111 pos_num : NUM {strcpy($$,$1);}
112 | '+' NUM {strcpy($$,$2);}
115 neg_num : '-' NUM {strcpy($$,"-");
116 strcat($$,$2);}
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
146 {$$=$1;
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;}
251 | Time
252 | octet_string_def {$$=$1;}
253 | bit_string_def {$$=$1;}
254 | sequence_def {$$=$1;}
255 | object_def {$$=$1;}
256 | choise_def {$$=$1;}
257 | any_def {$$=$1;}
258 | set_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($$);
373 else p_tree=$$;
380 #include <ctype.h>
381 #include <string.h>
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. */
401 /* Return: int */
402 /* Token identifier or ASCII code or 0(zero: End Of File) */
403 /*************************************************************/
404 int
405 yylex()
407 int c,counter=0,k;
408 char string[129]; /* will contain the next token */
409 while(1)
411 while((c=fgetc(file_asn1))==' ' || c=='\t' || c=='\n');
412 if(c==EOF) return 0;
413 if(c=='(' || c==')' || c=='[' || c==']' ||
414 c=='{' || c=='}' || c==',' || c=='.' ||
415 c=='+') return c;
416 if(c=='-'){ /* Maybe the first '-' of a comment */
417 if((c=fgetc(file_asn1))!='-'){
418 ungetc(c,file_asn1);
419 return '-';
421 else{ /* Comments */
422 counter=0;
423 /* A comment finishes at the end of line */
424 while((c=fgetc(file_asn1))!=EOF && c!='\n');
425 if(c==EOF) return 0;
426 else continue; /* next char, please! (repeat the search) */
429 string[counter++]=c;
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=='.'))
435 string[counter++]=c;
437 ungetc(c,file_asn1);
438 string[counter]=0;
440 /* Is STRING a number? */
441 for(k=0;k<counter;k++)
442 if(!isdigit(string[k])) break;
443 if(k>=counter)
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);
455 return IDENTIFIER;
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.
465 * Description:
467 * Creates the structures needed to manage the definitions included in *FILE_NAME file.
469 * Returns:
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){
480 p_tree=NULL;
481 *pointer=NULL;
483 /* open the file to parse */
484 file_asn1=fopen(file_name,"r");
485 if(file_asn1==NULL) return ASN_FILE_NOT_FOUND;
487 result_parse=ASN_OK;
489 /* only syntax check */
490 parse_mode=PARSE_MODE_CHECK;
491 yyparse();
493 if(result_parse==ASN_OK){ /* syntax OK */
494 fclose(file_asn1);
495 file_asn1=fopen(file_name,"r");
497 /* structure creation */
498 parse_mode=PARSE_MODE_CREATE;
499 yyparse();
501 _asn1_change_integer_value(p_tree);
502 _asn1_expand_object_id(p_tree);
505 fclose(file_asn1);
507 parse_mode=PARSE_MODE_CREATE;
509 *pointer=p_tree;
511 return result_parse;
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.
518 * Description:
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".
524 * Returns:
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){
535 int result;
537 p_tree=NULL;
539 /* open the file to parse */
540 file_asn1=fopen(file_name,"r");
541 if(file_asn1==NULL) return ASN_FILE_NOT_FOUND;
543 result_parse=ASN_OK;
545 /* syntax check */
546 parse_mode=PARSE_MODE_CHECK;
547 yyparse();
549 if(result_parse==ASN_OK){ /* syntax OK */
550 fclose(file_asn1);
551 file_asn1=fopen(file_name,"r");
553 /* structure creation */
554 parse_mode=PARSE_MODE_CREATE;
555 yyparse();
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);
564 fclose(file_asn1);
566 parse_mode=PARSE_MODE_CREATE;
568 return result_parse;
572 /*************************************************************/
573 /* Function: yyerror */
574 /* Description: function called when there are syntax errors*/
575 /* Parameters: */
576 /* char *s : error description */
577 /* Return: int */
578 /* */
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;
585 return 0;