3 * Copyright (C) 2001-2012 Free Software Foundation, Inc.
5 * This file is part of LIBTASN1.
7 * The LIBTASN1 library is free software; you can redistribute it
8 * and/or modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 /*****************************************************/
24 /* File: x509_ASN.y */
25 /* Description: input file for 'bison' program. */
26 /* The output file is a parser (in C language) for */
28 /*****************************************************/
31 #include <parser_aux.h>
32 #include <structure.h>
35 static FILE *file_asn1; /* Pointer to file to parse */
36 static int result_parse = 0; /* result of the parser
38 static asn1_node p_tree; /* pointer to the root of the
39 structure created by the
41 static unsigned int line_number; /* line number describing the
42 parser position inside the
44 static char last_error[ASN1_MAX_ERROR_DESCRIPTION_SIZE] = "";
45 static char last_error_token[ASN1_MAX_NAME_SIZE+1] = ""; /* used when expected errors occur */
46 static char last_token[ASN1_MAX_NAME_SIZE+1] = ""; /* last token find in the file
47 to parse before the 'parse
49 extern char _asn1_identifierMissing[];
50 static const char *file_name; /* file to parse */
52 static void _asn1_yyerror (const char *);
53 static int _asn1_yylex(void);
57 /* Prefix symbols and functions with _asn1_ */
58 /* %define parse.lac full */
60 %name-prefix="_asn1_yy"
63 unsigned int constant;
64 char str[ASN1_MAX_NAME_SIZE+1];
71 %token <str> IDENTIFIER
102 %token GeneralizedTime
107 %token PrintableString
108 %token UniversalString
117 %type <node> octet_string_def constant constant_list type_assig_right
118 %type <node> integer_def type_assig type_assig_list sequence_def type_def
119 %type <node> bit_string_def default size_def choise_def object_def
120 %type <node> boolean_def any_def size_def2 obj_constant obj_constant_list
121 %type <node> constant_def type_constant type_constant_list definitions
122 %type <node> definitions_id Time bit_element bit_element_list set_def
123 %type <node> tag_type tag type_assig_right_tag generalstring_def
124 %type <node> numericstring_def ia5string_def printablestring_def universalstring_def
125 %type <node> bmpstring_def utf8string_def visiblestring_def teletexstring_def
126 %type <node> type_assig_right_tag_default enumerated_def
127 %type <str> pos_num neg_num pos_neg_num pos_neg_identifier pos_neg_list
128 %type <str> num_identifier
129 %type <constant> class explicit_implicit
134 definitions: definitions_id
135 DEFINITIONS explicit_implicit TAGS "::=" BEGIN /* imports_def */
136 type_constant_list END
137 {$$=_asn1_add_static_node(ASN1_ETYPE_DEFINITIONS|$3);
138 _asn1_set_name($$,_asn1_get_name($1));
139 _asn1_set_name($1,"");
140 _asn1_set_right($1,$7);
141 _asn1_set_down($$,$1);
147 pos_num : NUM {strcpy($$,$1);}
148 | '+' NUM {strcpy($$,$2);}
151 neg_num : '-' NUM {strcpy($$,"-");
155 pos_neg_num : pos_num {strcpy($$,$1);}
156 | neg_num {strcpy($$,$1);}
159 num_identifier : NUM {strcpy($$,$1);}
160 | IDENTIFIER {strcpy($$,$1);}
163 pos_neg_identifier : pos_neg_num {strcpy($$,$1);}
164 | IDENTIFIER {strcpy($$,$1);}
167 constant: '(' pos_neg_num ')' {$$=_asn1_add_static_node(ASN1_ETYPE_CONSTANT);
168 _asn1_set_value($$,$2,strlen($2)+1);}
169 | IDENTIFIER'('pos_neg_num')' {$$=_asn1_add_static_node(ASN1_ETYPE_CONSTANT);
170 _asn1_set_name($$,$1);
171 _asn1_set_value($$,$3,strlen($3)+1);}
174 constant_list: constant {$$=$1;}
175 | constant_list ',' constant {$$=$1;
176 _asn1_set_right(_asn1_get_last_right($1),$3);}
179 obj_constant: num_identifier {$$=_asn1_add_static_node(ASN1_ETYPE_CONSTANT);
180 _asn1_set_value($$,$1,strlen($1)+1);}
181 | IDENTIFIER'('NUM')' {$$=_asn1_add_static_node(ASN1_ETYPE_CONSTANT);
182 _asn1_set_name($$,$1);
183 _asn1_set_value($$,$3,strlen($3)+1);}
186 obj_constant_list: obj_constant {$$=$1;}
187 | obj_constant_list obj_constant {$$=$1;
188 _asn1_set_right(_asn1_get_last_right($1),$2);}
191 class : UNIVERSAL {$$=CONST_UNIVERSAL;}
192 | PRIVATE {$$=CONST_PRIVATE;}
193 | APPLICATION {$$=CONST_APPLICATION;}
196 tag_type : '[' NUM ']' {$$=_asn1_add_static_node(ASN1_ETYPE_TAG);
197 _asn1_set_value($$,$2,strlen($2)+1);}
198 | '[' class NUM ']' {$$=_asn1_add_static_node(ASN1_ETYPE_TAG | $2);
199 _asn1_set_value($$,$3,strlen($3)+1);}
202 tag : tag_type {$$=$1;}
203 | tag_type EXPLICIT {$$=_asn1_mod_type($1,CONST_EXPLICIT);}
204 | tag_type IMPLICIT {$$=_asn1_mod_type($1,CONST_IMPLICIT);}
207 default : DEFAULT pos_neg_identifier {$$=_asn1_add_static_node(ASN1_ETYPE_DEFAULT);
208 _asn1_set_value($$,$2,strlen($2)+1);}
209 | DEFAULT ASN1_TRUE {$$=_asn1_add_static_node(ASN1_ETYPE_DEFAULT|CONST_TRUE);}
210 | DEFAULT ASN1_FALSE {$$=_asn1_add_static_node(ASN1_ETYPE_DEFAULT|CONST_FALSE);}
214 pos_neg_list: pos_neg_num
215 | pos_neg_list '|' pos_neg_num
219 integer_def: INTEGER {$$=_asn1_add_static_node(ASN1_ETYPE_INTEGER);}
220 | INTEGER'{'constant_list'}' {$$=_asn1_add_static_node(ASN1_ETYPE_INTEGER|CONST_LIST);
221 _asn1_set_down($$,$3);}
222 | integer_def'(' pos_neg_list ')' {$$=_asn1_add_static_node(ASN1_ETYPE_INTEGER);}
223 | integer_def'('num_identifier'.''.'num_identifier')'
224 {$$=_asn1_add_static_node(ASN1_ETYPE_INTEGER|CONST_MIN_MAX);
225 _asn1_set_down($$,_asn1_add_static_node(ASN1_ETYPE_SIZE));
226 _asn1_set_value(_asn1_get_down($$),$6,strlen($6)+1);
227 _asn1_set_name(_asn1_get_down($$),$3);}
230 boolean_def: BOOLEAN {$$=_asn1_add_static_node(ASN1_ETYPE_BOOLEAN);}
233 Time: UTCTime {$$=_asn1_add_static_node(ASN1_ETYPE_UTC_TIME);}
234 | GeneralizedTime {$$=_asn1_add_static_node(ASN1_ETYPE_GENERALIZED_TIME);}
237 size_def2: SIZE'('num_identifier')' {$$=_asn1_add_static_node(ASN1_ETYPE_SIZE|CONST_1_PARAM);
238 _asn1_set_value($$,$3,strlen($3)+1);}
239 | SIZE'('num_identifier'.''.'num_identifier')'
240 {$$=_asn1_add_static_node(ASN1_ETYPE_SIZE|CONST_MIN_MAX);
241 _asn1_set_value($$,$3,strlen($3)+1);
242 _asn1_set_name($$,$6);}
245 size_def: size_def2 {$$=$1;}
246 | '(' size_def2 ')' {$$=$2;}
249 generalstring_def: GeneralString {$$=_asn1_add_static_node(ASN1_ETYPE_GENERALSTRING);}
250 | GeneralString size_def {$$=_asn1_add_static_node(ASN1_ETYPE_GENERALSTRING|CONST_SIZE);
251 _asn1_set_down($$,$2);}
254 numericstring_def: NumericString {$$=_asn1_add_static_node(ASN1_ETYPE_NUMERIC_STRING|CONST_UNIVERSAL);}
255 | NumericString size_def {$$=_asn1_add_static_node(ASN1_ETYPE_NUMERIC_STRING|CONST_SIZE);
256 _asn1_set_down($$,$2);}
259 ia5string_def: IA5String {$$=_asn1_add_static_node(ASN1_ETYPE_IA5_STRING);}
260 | IA5String size_def {$$=_asn1_add_static_node(ASN1_ETYPE_IA5_STRING|CONST_SIZE);
261 _asn1_set_down($$,$2);}
264 teletexstring_def: TeletexString {$$=_asn1_add_static_node(ASN1_ETYPE_TELETEX_STRING);}
265 | TeletexString size_def {$$=_asn1_add_static_node(ASN1_ETYPE_TELETEX_STRING|CONST_SIZE);
266 _asn1_set_down($$,$2);}
269 printablestring_def: PrintableString {$$=_asn1_add_static_node(ASN1_ETYPE_PRINTABLE_STRING);}
270 | PrintableString size_def {$$=_asn1_add_static_node(ASN1_ETYPE_PRINTABLE_STRING|CONST_SIZE);
271 _asn1_set_down($$,$2);}
274 universalstring_def: UniversalString {$$=_asn1_add_static_node(ASN1_ETYPE_UNIVERSAL_STRING);}
275 | UniversalString size_def {$$=_asn1_add_static_node(ASN1_ETYPE_UNIVERSAL_STRING|CONST_SIZE);
276 _asn1_set_down($$,$2);}
279 bmpstring_def: BMPString {$$=_asn1_add_static_node(ASN1_ETYPE_BMP_STRING);}
280 | BMPString size_def {$$=_asn1_add_static_node(ASN1_ETYPE_BMP_STRING|CONST_SIZE);
281 _asn1_set_down($$,$2);}
284 utf8string_def: UTF8String {$$=_asn1_add_static_node(ASN1_ETYPE_UTF8_STRING);}
285 | UTF8String size_def {$$=_asn1_add_static_node(ASN1_ETYPE_UTF8_STRING|CONST_SIZE);
286 _asn1_set_down($$,$2);}
289 visiblestring_def: VisibleString {$$=_asn1_add_static_node(ASN1_ETYPE_VISIBLE_STRING);}
290 | VisibleString size_def {$$=_asn1_add_static_node(ASN1_ETYPE_VISIBLE_STRING|CONST_SIZE);
291 _asn1_set_down($$,$2);}
294 octet_string_def : OCTET STRING {$$=_asn1_add_static_node(ASN1_ETYPE_OCTET_STRING);}
295 | OCTET STRING size_def {$$=_asn1_add_static_node(ASN1_ETYPE_OCTET_STRING|CONST_SIZE);
296 _asn1_set_down($$,$3);}
299 bit_element : IDENTIFIER'('NUM')' {$$=_asn1_add_static_node(ASN1_ETYPE_CONSTANT);
300 _asn1_set_name($$,$1);
301 _asn1_set_value($$,$3,strlen($3)+1);}
304 bit_element_list : bit_element {$$=$1;}
305 | bit_element_list ',' bit_element {$$=$1;
306 _asn1_set_right(_asn1_get_last_right($1),$3);}
309 bit_string_def : BIT STRING {$$=_asn1_add_static_node(ASN1_ETYPE_BIT_STRING);}
310 | BIT STRING size_def {$$=_asn1_add_static_node(ASN1_ETYPE_BIT_STRING|CONST_SIZE);}
311 | BIT STRING'{'bit_element_list'}'
312 {$$=_asn1_add_static_node(ASN1_ETYPE_BIT_STRING|CONST_LIST);
313 _asn1_set_down($$,$4);}
316 enumerated_def : ENUMERATED'{'bit_element_list'}'
317 {$$=_asn1_add_static_node(ASN1_ETYPE_ENUMERATED|CONST_LIST);
318 _asn1_set_down($$,$3);}
322 object_def : OBJECT STR_IDENTIFIER {$$=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID);}
325 type_assig_right: IDENTIFIER {$$=_asn1_add_static_node(ASN1_ETYPE_IDENTIFIER);
326 _asn1_set_value($$,$1,strlen($1)+1);}
327 | IDENTIFIER size_def {$$=_asn1_add_static_node(ASN1_ETYPE_IDENTIFIER|CONST_SIZE);
328 _asn1_set_value($$,$1,strlen($1)+1);
329 _asn1_set_down($$,$2);}
330 | integer_def {$$=$1;}
331 | enumerated_def {$$=$1;}
332 | boolean_def {$$=$1;}
334 | octet_string_def {$$=$1;}
335 | bit_string_def {$$=$1;}
336 | generalstring_def {$$=$1;}
337 | numericstring_def {$$=$1;}
338 | ia5string_def {$$=$1;}
339 | teletexstring_def {$$=$1;}
340 | printablestring_def {$$=$1;}
341 | universalstring_def {$$=$1;}
342 | bmpstring_def {$$=$1;}
343 | utf8string_def {$$=$1;}
344 | visiblestring_def {$$=$1;}
345 | sequence_def {$$=$1;}
346 | object_def {$$=$1;}
347 | choise_def {$$=$1;}
350 | TOKEN_NULL {$$=_asn1_add_static_node(ASN1_ETYPE_NULL);}
353 type_assig_right_tag : type_assig_right {$$=$1;}
354 | tag type_assig_right {$$=_asn1_mod_type($2,CONST_TAG);
355 _asn1_set_right($1,_asn1_get_down($$));
356 _asn1_set_down($$,$1);}
359 type_assig_right_tag_default : type_assig_right_tag {$$=$1;}
360 | type_assig_right_tag default {$$=_asn1_mod_type($1,CONST_DEFAULT);
361 _asn1_set_right($2,_asn1_get_down($$));
362 _asn1_set_down($$,$2);}
363 | type_assig_right_tag OPTIONAL {$$=_asn1_mod_type($1,CONST_OPTION);}
366 type_assig : IDENTIFIER type_assig_right_tag_default {$$=_asn1_set_name($2,$1);}
369 type_assig_list : type_assig {$$=$1;}
370 | type_assig_list','type_assig {$$=$1;
371 _asn1_set_right(_asn1_get_last_right($1),$3);}
374 sequence_def : SEQUENCE'{'type_assig_list'}' {$$=_asn1_add_static_node(ASN1_ETYPE_SEQUENCE);
375 _asn1_set_down($$,$3);}
376 | SEQUENCE OF type_assig_right {$$=_asn1_add_static_node(ASN1_ETYPE_SEQUENCE_OF);
377 _asn1_set_down($$,$3);}
378 | SEQUENCE size_def OF type_assig_right {$$=_asn1_add_static_node(ASN1_ETYPE_SEQUENCE_OF|CONST_SIZE);
379 _asn1_set_right($2,$4);
380 _asn1_set_down($$,$2);}
383 set_def : SET'{'type_assig_list'}' {$$=_asn1_add_static_node(ASN1_ETYPE_SET);
384 _asn1_set_down($$,$3);}
385 | SET OF type_assig_right {$$=_asn1_add_static_node(ASN1_ETYPE_SET_OF);
386 _asn1_set_down($$,$3);}
387 | SET size_def OF type_assig_right {$$=_asn1_add_static_node(ASN1_ETYPE_SET_OF|CONST_SIZE);
388 _asn1_set_right($2,$4);
389 _asn1_set_down($$,$2);}
392 choise_def : CHOICE'{'type_assig_list'}' {$$=_asn1_add_static_node(ASN1_ETYPE_CHOICE);
393 _asn1_set_down($$,$3);}
396 any_def : ANY {$$=_asn1_add_static_node(ASN1_ETYPE_ANY);}
397 | ANY DEFINED BY IDENTIFIER {$$=_asn1_add_static_node(ASN1_ETYPE_ANY|CONST_DEFINED_BY);
398 _asn1_set_down($$,_asn1_add_static_node(ASN1_ETYPE_CONSTANT));
399 _asn1_set_name(_asn1_get_down($$),$4);}
402 type_def : IDENTIFIER "::=" type_assig_right_tag {$$=_asn1_set_name($3,$1);}
403 /* below should match: BMPString ::= [UNIVERSAL 30] IMPLICIT OCTET STRING etc*/
404 | error "::=" type_assig_right_tag {$$=_asn1_set_name($3, last_error_token);}
407 constant_def : IDENTIFIER OBJECT STR_IDENTIFIER "::=" '{'obj_constant_list'}'
408 {$$=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID|CONST_ASSIGN);
409 _asn1_set_name($$,$1);
410 _asn1_set_down($$,$6);}
411 | IDENTIFIER IDENTIFIER "::=" '{' obj_constant_list '}'
412 {$$=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID|CONST_ASSIGN|CONST_1_PARAM);
413 _asn1_set_name($$,$1);
414 _asn1_set_value($$,$2,strlen($2)+1);
415 _asn1_set_down($$,$5);}
416 | IDENTIFIER INTEGER "::=" pos_neg_num
417 {$$=_asn1_add_static_node(ASN1_ETYPE_INTEGER|CONST_ASSIGN);
418 _asn1_set_name($$,$1);
419 _asn1_set_value($$,$4,strlen($4)+1);}
422 type_constant: type_def {$$=$1;}
423 | constant_def {$$=$1;}
426 type_constant_list : type_constant {$$=$1;}
427 | type_constant_list type_constant {$$=$1;
428 _asn1_set_right(_asn1_get_last_right($1),$2);}
431 definitions_id : IDENTIFIER '{' obj_constant_list '}' {$$=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID);
432 _asn1_set_down($$,$3);
433 _asn1_set_name($$,$1);}
434 | IDENTIFIER '{' '}' {$$=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID);
435 _asn1_set_name($$,$1);}
436 | IDENTIFIER {$$=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID);
437 _asn1_set_name($$,$1);}
441 identifier_list : IDENTIFIER {$$=_asn1_add_static_node(ASN1_ETYPE_IDENTIFIER);
442 _asn1_set_name($$,$1);}
443 | identifier_list IDENTIFIER
445 _asn1_set_right(_asn1_get_last_right($$),_asn1_add_static_node(ASN1_ETYPE_IDENTIFIER));
446 _asn1_set_name(_asn1_get_last_right($$),$2);}
450 imports_def : empty {$$=NULL;}
451 | IMPORTS identifier_list FROM IDENTIFIER obj_constant_list
452 {$$=_asn1_add_static_node(ASN1_ETYPE_IMPORTS);
453 _asn1_set_down($$,_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID));
454 _asn1_set_name(_asn1_get_down($$),$4);
455 _asn1_set_down(_asn1_get_down($$),$5);
456 _asn1_set_right($$,$2);}
460 explicit_implicit : EXPLICIT {$$=CONST_EXPLICIT;}
461 | IMPLICIT {$$=CONST_IMPLICIT;}
469 static const char *key_word[] = {
470 "::=","OPTIONAL","INTEGER","SIZE","OCTET","STRING",
471 "SEQUENCE","BIT","UNIVERSAL","PRIVATE","OPTIONAL",
472 "DEFAULT","CHOICE","OF","OBJECT","IDENTIFIER",
473 "BOOLEAN","TRUE","FALSE","APPLICATION","ANY","DEFINED",
474 "SET","BY","EXPLICIT","IMPLICIT","DEFINITIONS","TAGS",
475 "BEGIN","END","UTCTime","GeneralizedTime",
476 "GeneralString","FROM","IMPORTS","NULL","ENUMERATED",
477 "NumericString", "IA5String", "TeletexString", "PrintableString",
478 "UniversalString", "BMPString", "UTF8String", "VisibleString"};
480 static const int key_word_token[] = {
481 ASSIG, OPTIONAL, INTEGER, SIZE, OCTET, STRING, SEQUENCE, BIT, UNIVERSAL,
482 PRIVATE, OPTIONAL, DEFAULT, CHOICE, OF, OBJECT, STR_IDENTIFIER,
483 BOOLEAN, ASN1_TRUE, ASN1_FALSE, APPLICATION, ANY, DEFINED, SET, BY,
484 EXPLICIT, IMPLICIT, DEFINITIONS, TAGS, BEGIN, END, UTCTime,
485 GeneralizedTime, GeneralString, FROM, IMPORTS, TOKEN_NULL,
486 ENUMERATED, NumericString, IA5String, TeletexString, PrintableString,
487 UniversalString, BMPString, UTF8String, VisibleString
490 /*************************************************************/
491 /* Function: _asn1_yylex */
492 /* Description: looks for tokens in file_asn1 pointer file. */
494 /* Token identifier or ASCII code or 0(zero: End Of File) */
495 /*************************************************************/
499 int c, counter = 0, k, lastc;
500 char string[ASN1_MAX_NAME_SIZE + 1]; /* will contain the next token */
505 while ((c = fgetc (file_asn1)) == ' ' || c == '\t' || c == '\n')
511 strcpy (last_token, "End Of File");
515 if (c == '(' || c == ')' || c == '[' || c == ']' ||
516 c == '{' || c == '}' || c == ',' || c == '.' ||
517 c == '+' || c == '|')
524 { /* Maybe the first '-' of a comment */
525 if ((c = fgetc (file_asn1)) != '-')
527 ungetc (c, file_asn1);
536 /* A comment finishes at the next double hypen or the end of line */
537 while ((c = fgetc (file_asn1)) != EOF && c != '\n' &&
538 (lastc != '-' || (lastc == '-' && c != '-')))
542 strcpy (last_token, "End Of File");
549 continue; /* next char, please! (repeat the search) */
553 string[counter++] = c;
554 /* Till the end of the token */
556 ((c = fgetc (file_asn1)) == EOF || c == ' ' || c == '\t'
557 || c == '\n' || c == '(' || c == ')' || c == '[' || c == ']'
558 || c == '{' || c == '}' || c == ',' || c == '.'))
560 if (counter >= ASN1_MAX_NAME_SIZE)
562 result_parse = ASN1_NAME_TOO_LONG;
565 string[counter++] = c;
567 ungetc (c, file_asn1);
569 strcpy (last_token, string);
571 /* Is STRING a number? */
572 for (k = 0; k < counter; k++)
573 if (!isdigit (string[k]))
577 strcpy (yylval.str, string);
578 return NUM; /* return the number */
581 /* Is STRING a keyword? */
582 for (i = 0; i < (sizeof (key_word) / sizeof (char *)); i++)
583 if (!strcmp (string, key_word[i]))
584 return key_word_token[i];
586 /* STRING is an IDENTIFIER */
587 strcpy (yylval.str, string);
592 /*************************************************************/
593 /* Function: _asn1_create_errorDescription */
594 /* Description: creates a string with the description of the*/
597 /* error : error to describe. */
598 /* error_desc: string that will contain the */
600 /*************************************************************/
602 _asn1_create_errorDescription (int error, char *error_desc)
604 if (error_desc == NULL)
610 case ASN1_FILE_NOT_FOUND:
611 snprintf(error_desc, ASN1_MAX_ERROR_DESCRIPTION_SIZE, "%s file was not found", file_name);
613 case ASN1_SYNTAX_ERROR:
614 strcpy(error_desc, last_error);
616 case ASN1_NAME_TOO_LONG:
617 snprintf (error_desc, ASN1_MAX_ERROR_DESCRIPTION_SIZE,
618 "%s:%u: name too long (more than %u characters)", file_name,
619 line_number, ASN1_MAX_NAME_SIZE);
621 case ASN1_IDENTIFIER_NOT_FOUND:
622 snprintf (error_desc, ASN1_MAX_ERROR_DESCRIPTION_SIZE,
623 "%s:: identifier '%s' not found", file_name,
624 _asn1_identifierMissing);
635 * @file: specify the path and the name of file that contains
636 * ASN.1 declarations.
637 * @definitions: return the pointer to the structure created from
638 * "file" ASN.1 declarations.
639 * @error_desc: return the error description or an empty
642 * Function used to start the parse algorithm. Creates the structures
643 * needed to manage the definitions included in @file file.
645 * Returns: %ASN1_SUCCESS if the file has a correct syntax and every
646 * identifier is known, %ASN1_ELEMENT_NOT_EMPTY if @definitions not
647 * %NULL, %ASN1_FILE_NOT_FOUND if an error occured while
648 * opening @file, %ASN1_SYNTAX_ERROR if the syntax is not
649 * correct, %ASN1_IDENTIFIER_NOT_FOUND if in the file there is an
650 * identifier that is not defined, %ASN1_NAME_TOO_LONG if in the
651 * file there is an identifier whith more than %ASN1_MAX_NAME_SIZE
655 asn1_parser2tree (const char *file, asn1_node * definitions,
661 if (*definitions != NULL)
662 return ASN1_ELEMENT_NOT_EMPTY;
668 /* open the file to parse */
669 file_asn1 = fopen (file, "r");
671 if (file_asn1 == NULL)
673 result_parse = ASN1_FILE_NOT_FOUND;
677 result_parse = ASN1_SUCCESS;
684 if (result_parse == ASN1_SUCCESS)
686 /* set IMPLICIT or EXPLICIT property */
687 _asn1_set_default_tag (p_tree);
688 /* set CONST_SET and CONST_NOT_USED */
689 _asn1_type_set_config (p_tree);
690 /* check the identifier definitions */
691 result_parse = _asn1_check_identifier (p_tree);
692 if (result_parse == ASN1_SUCCESS)
693 { /* all identifier defined */
694 /* Delete the list and keep the ASN1 structure */
695 _asn1_delete_list ();
696 /* Convert into DER coding the value assign to INTEGER constants */
697 _asn1_change_integer_value (p_tree);
698 /* Expand the IDs of OBJECT IDENTIFIER constants */
699 _asn1_expand_object_id (p_tree);
701 *definitions = p_tree;
703 else /* some identifiers not defined */
704 /* Delete the list and the ASN1 structure */
705 _asn1_delete_list_and_nodes ();
707 else /* syntax error */
708 /* Delete the list and the ASN1 structure */
709 _asn1_delete_list_and_nodes ();
712 _asn1_create_errorDescription (result_parse, error_desc);
719 * @inputFileName: specify the path and the name of file that
720 * contains ASN.1 declarations.
721 * @outputFileName: specify the path and the name of file that will
722 * contain the C vector definition.
723 * @vectorName: specify the name of the C vector.
724 * @error_desc : return the error description or an empty
727 * Function that generates a C structure from an ASN1 file. Creates a
728 * file containing a C vector to use to manage the definitions
729 * included in @inputFileName file. If @inputFileName is
730 * "/aa/bb/xx.yy" and @outputFileName is %NULL, the file created is
731 * "/aa/bb/xx_asn1_tab.c". If @vectorName is %NULL the vector name
732 * will be "xx_asn1_tab".
734 * Returns: %ASN1_SUCCESS if the file has a correct syntax and every
735 * identifier is known, %ASN1_FILE_NOT_FOUND if an error occured
736 * while opening @inputFileName, %ASN1_SYNTAX_ERROR if the syntax is
737 * not correct, %ASN1_IDENTIFIER_NOT_FOUND if in the file there is
738 * an identifier that is not defined, %ASN1_NAME_TOO_LONG if in the
739 * file there is an identifier whith more than %ASN1_MAX_NAME_SIZE
743 asn1_parser2array (const char *inputFileName, const char *outputFileName,
744 const char *vectorName, char *error_desc)
746 char *file_out_name = NULL;
747 char *vector_name = NULL;
748 const char *char_p, *slash_p, *dot_p;
752 file_name = inputFileName;
754 /* open the file to parse */
755 file_asn1 = fopen (inputFileName, "r");
757 if (file_asn1 == NULL)
758 result_parse = ASN1_FILE_NOT_FOUND;
761 result_parse = ASN1_SUCCESS;
768 if (result_parse == ASN1_SUCCESS)
770 /* set IMPLICIT or EXPLICIT property */
771 _asn1_set_default_tag (p_tree);
772 /* set CONST_SET and CONST_NOT_USED */
773 _asn1_type_set_config (p_tree);
774 /* check the identifier definitions */
775 result_parse = _asn1_check_identifier (p_tree);
777 if (result_parse == ASN1_SUCCESS)
778 { /* all identifier defined */
780 /* searching the last '/' and '.' in inputFileName */
781 char_p = inputFileName;
782 slash_p = inputFileName;
783 while ((char_p = strchr (char_p, '/')))
790 dot_p = inputFileName + strlen (inputFileName);
792 while ((char_p = strchr (char_p, '.')))
798 if (outputFileName == NULL)
800 /* file_out_name = inputFileName + _asn1_tab.c */
801 file_out_name = malloc (dot_p - inputFileName + 1 +
802 strlen ("_asn1_tab.c"));
803 memcpy (file_out_name, inputFileName,
804 dot_p - inputFileName);
805 file_out_name[dot_p - inputFileName] = 0;
806 strcat (file_out_name, "_asn1_tab.c");
810 /* file_out_name = inputFileName */
812 (char *) malloc (strlen (outputFileName) + 1);
813 strcpy (file_out_name, outputFileName);
816 if (vectorName == NULL)
818 /* vector_name = file name + _asn1_tab */
819 vector_name = malloc (dot_p - slash_p + 1 +
820 strlen ("_asn1_tab"));
821 memcpy (vector_name, slash_p, dot_p - slash_p);
822 vector_name[dot_p - slash_p] = 0;
823 strcat (vector_name, "_asn1_tab");
827 /* vector_name = vectorName */
828 vector_name = (char *) malloc (strlen (vectorName) + 1);
829 strcpy (vector_name, vectorName);
832 /* Save structure in a file */
833 _asn1_create_static_structure (p_tree,
834 file_out_name, vector_name);
836 free (file_out_name);
841 /* Delete the list and the ASN1 structure */
842 _asn1_delete_list_and_nodes ();
843 } /* inputFile exist */
845 _asn1_create_errorDescription (result_parse, error_desc);
850 /*************************************************************/
851 /* Function: _asn1_yyerror */
852 /* Description: function called when there are syntax errors*/
854 /* char *s : error description */
857 /*************************************************************/
859 _asn1_yyerror (const char *s)
861 /* Sends the error description to the std_out */
863 if (strcmp (last_token, "VisibleString") == 0 ||
864 strcmp (last_token, "PrintableString") == 0 ||
865 strcmp (last_token, "UniversalString") == 0 ||
866 strcmp (last_token, "IA5String") == 0 ||
867 strcmp (last_token, "UTF8String") == 0 ||
868 strcmp (last_token, "NumericString") == 0 ||
869 strcmp (last_token, "TeletexString") == 0 ||
870 strcmp (last_token, "BMPString") == 0)
872 snprintf (last_error_token, ASN1_MAX_ERROR_DESCRIPTION_SIZE,
875 "%s:%u: Warning: %s is a built-in ASN.1 type.\n",
876 file_name, line_number, last_token);
879 last_error_token[0] = 0;
881 if (result_parse != ASN1_NAME_TOO_LONG)
883 snprintf (last_error, ASN1_MAX_ERROR_DESCRIPTION_SIZE,
884 "%s:%u: Error: %s near '%s'", file_name,
885 line_number, s, last_token);
886 result_parse = ASN1_SYNTAX_ERROR;