fixes in length calculation in _asn1_extract_der_octet().
[platform/upstream/libtasn1.git] / lib / ASN1.y
1 %{
2 /*
3  * Copyright (C) 2001-2014 Free Software Foundation, Inc.
4  *
5  * This file is part of LIBTASN1.
6  *
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.
11  *
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.
16  *
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
20  * 02110-1301, USA
21  */
22
23 /*****************************************************/
24 /* File: x509_ASN.y                                  */
25 /* Description: input file for 'bison' program.      */
26 /*   The output file is a parser (in C language) for */
27 /*   ASN.1 syntax                                    */
28 /*****************************************************/
29
30 #include <int.h>
31 #include <parser_aux.h>
32 #include <structure.h>
33 #include <libtasn1.h>
34
35 static FILE *file_asn1;                 /* Pointer to file to parse */
36 static int result_parse = 0;    /* result of the parser
37                                            algorithm */
38 static asn1_node p_tree;                /* pointer to the root of the
39                                            structure created by the
40                                            parser*/
41 static unsigned int line_number;        /* line number describing the
42                                            parser position inside the
43                                            file */
44 static char last_error[ASN1_MAX_ERROR_DESCRIPTION_SIZE] = "";
45 static char last_error_token[ASN1_MAX_ERROR_DESCRIPTION_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
48                                            error' */
49 extern char _asn1_identifierMissing[];
50 static const char *file_name;           /* file to parse */
51
52 static void _asn1_yyerror (const char *);
53 static int _asn1_yylex(void);
54
55 %}
56
57 /* Prefix symbols and functions with _asn1_ */
58 /* %define parse.lac full */
59 %error-verbose
60 %name-prefix="_asn1_yy"
61
62 %union {
63   unsigned int constant;
64   char str[ASN1_MAX_NAME_SIZE+1];
65   asn1_node node;
66 }
67
68
69 %token ASSIG "::="
70 %token <str> NUM
71 %token <str> IDENTIFIER
72 %token OPTIONAL
73 %token INTEGER
74 %token SIZE
75 %token OCTET
76 %token STRING
77 %token SEQUENCE
78 %token BIT
79 %token UNIVERSAL
80 %token PRIVATE
81 %token APPLICATION
82 %token DEFAULT
83 %token CHOICE
84 %token OF
85 %token OBJECT
86 %token STR_IDENTIFIER
87 %token BOOLEAN
88 %token ASN1_TRUE
89 %token ASN1_FALSE
90 %token TOKEN_NULL
91 %token ANY
92 %token DEFINED
93 %token BY
94 %token SET
95 %token EXPLICIT
96 %token IMPLICIT
97 %token DEFINITIONS
98 %token TAGS
99 %token BEGIN
100 %token END
101 %token UTCTime
102 %token GeneralizedTime
103 %token GeneralString
104 %token NumericString
105 %token IA5String
106 %token TeletexString
107 %token PrintableString
108 %token UniversalString
109 %token BMPString
110 %token UTF8String
111 %token VisibleString
112
113 %token FROM
114 %token IMPORTS
115 %token ENUMERATED
116
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 <str>  int_identifier
130 %type <constant> class explicit_implicit
131
132 %%
133
134
135 definitions:   definitions_id
136                DEFINITIONS explicit_implicit TAGS "::=" BEGIN  /* imports_def */
137                type_constant_list END
138                    {$$=_asn1_add_static_node(ASN1_ETYPE_DEFINITIONS|$3);
139                     _asn1_set_name($$,_asn1_get_name($1));
140                     _asn1_set_name($1,"");
141                     _asn1_set_right($1,$7);
142                     _asn1_set_down($$,$1);
143
144                     p_tree=$$;
145                     }
146 ;
147
148 pos_num :   NUM       {snprintf($$,sizeof($$),"%s",$1);}
149           | '+' NUM   {snprintf($$,sizeof($$),"%s",$2);}
150 ;
151
152 neg_num : '-' NUM     {snprintf($$,sizeof($$),"-%s",$2);}
153 ;
154
155 pos_neg_num :  pos_num  {snprintf($$,sizeof($$),"%s",$1);}
156              | neg_num  {snprintf($$,sizeof($$),"%s",$1);}
157 ;
158
159 num_identifier :  NUM            {snprintf($$,sizeof($$),"%s",$1);}
160                 | IDENTIFIER     {snprintf($$,sizeof($$),"%s",$1);}
161 ;
162
163 int_identifier :  NUM            {snprintf($$,sizeof($$),"%s",$1);}
164                 | '-' NUM        {snprintf($$,sizeof($$),"-%s",$2);}
165                 | IDENTIFIER     {snprintf($$,sizeof($$),"%s",$1);}
166 ;
167
168 pos_neg_identifier :  pos_neg_num    {snprintf($$,sizeof($$),"%s",$1);}
169                     | IDENTIFIER     {snprintf($$,sizeof($$),"%s",$1);}
170 ;
171
172 constant: '(' pos_neg_num ')'         {$$=_asn1_add_static_node(ASN1_ETYPE_CONSTANT);
173                                        _asn1_set_value($$,$2,strlen($2)+1);}
174         | IDENTIFIER'('pos_neg_num')' {$$=_asn1_add_static_node(ASN1_ETYPE_CONSTANT);
175                                        _asn1_set_name($$,$1);
176                                        _asn1_set_value($$,$3,strlen($3)+1);}
177 ;
178
179 constant_list:  constant                   {$$=$1;}
180               | constant_list ',' constant {$$=$1;
181                                             _asn1_set_right(_asn1_get_last_right($1),$3);}
182 ;
183
184 obj_constant:  num_identifier     {$$=_asn1_add_static_node(ASN1_ETYPE_CONSTANT);
185                                    _asn1_set_value($$,$1,strlen($1)+1);}
186              | IDENTIFIER'('NUM')' {$$=_asn1_add_static_node(ASN1_ETYPE_CONSTANT);
187                                     _asn1_set_name($$,$1);
188                                     _asn1_set_value($$,$3,strlen($3)+1);}
189 ;
190
191 obj_constant_list:  obj_constant                   {$$=$1;}
192                   | obj_constant_list obj_constant {$$=$1;
193                                                     _asn1_set_right(_asn1_get_last_right($1),$2);}
194 ;
195
196 class :  UNIVERSAL    {$$=CONST_UNIVERSAL;}
197        | PRIVATE      {$$=CONST_PRIVATE;}
198        | APPLICATION  {$$=CONST_APPLICATION;}
199 ;
200
201 tag_type :  '[' NUM ']'    {$$=_asn1_add_static_node(ASN1_ETYPE_TAG);
202                             _asn1_set_value($$,$2,strlen($2)+1);}
203           | '[' class NUM ']'  {$$=_asn1_add_static_node(ASN1_ETYPE_TAG | $2);
204                                 _asn1_set_value($$,$3,strlen($3)+1);}
205 ;
206
207 tag :  tag_type           {$$=$1;}
208      | tag_type EXPLICIT  {$$=_asn1_mod_type($1,CONST_EXPLICIT);}
209      | tag_type IMPLICIT  {$$=_asn1_mod_type($1,CONST_IMPLICIT);}
210 ;
211
212 default :  DEFAULT pos_neg_identifier {$$=_asn1_add_static_node(ASN1_ETYPE_DEFAULT);
213                                        _asn1_set_value($$,$2,strlen($2)+1);}
214          | DEFAULT ASN1_TRUE           {$$=_asn1_add_static_node(ASN1_ETYPE_DEFAULT|CONST_TRUE);}
215          | DEFAULT ASN1_FALSE          {$$=_asn1_add_static_node(ASN1_ETYPE_DEFAULT|CONST_FALSE);}
216 ;
217
218
219 pos_neg_list:  pos_neg_num
220             |  pos_neg_list '|' pos_neg_num
221 ;
222
223
224 integer_def: INTEGER                    {$$=_asn1_add_static_node(ASN1_ETYPE_INTEGER);}
225            | INTEGER'{'constant_list'}' {$$=_asn1_add_static_node(ASN1_ETYPE_INTEGER|CONST_LIST);
226                                          _asn1_set_down($$,$3);}
227            | integer_def'(' pos_neg_list ')' {$$=_asn1_add_static_node(ASN1_ETYPE_INTEGER);}
228            | integer_def'('int_identifier'.''.'int_identifier')'
229                                         {$$=_asn1_add_static_node(ASN1_ETYPE_INTEGER|CONST_MIN_MAX);
230                                          _asn1_set_down($$,_asn1_add_static_node(ASN1_ETYPE_SIZE));
231                                          _asn1_set_value(_asn1_get_down($$),$6,strlen($6)+1);
232                                          _asn1_set_name(_asn1_get_down($$),$3);}
233 ;
234
235 boolean_def: BOOLEAN   {$$=_asn1_add_static_node(ASN1_ETYPE_BOOLEAN);}
236 ;
237
238 Time:   UTCTime          {$$=_asn1_add_static_node(ASN1_ETYPE_UTC_TIME);}
239       | GeneralizedTime  {$$=_asn1_add_static_node(ASN1_ETYPE_GENERALIZED_TIME);}
240 ;
241
242 size_def2: SIZE'('num_identifier')'  {$$=_asn1_add_static_node(ASN1_ETYPE_SIZE|CONST_1_PARAM);
243                                       _asn1_set_value($$,$3,strlen($3)+1);}
244         | SIZE'('num_identifier'.''.'num_identifier')'
245                                      {$$=_asn1_add_static_node(ASN1_ETYPE_SIZE|CONST_MIN_MAX);
246                                       _asn1_set_value($$,$3,strlen($3)+1);
247                                       _asn1_set_name($$,$6);}
248 ;
249
250 size_def:   size_def2          {$$=$1;}
251           | '(' size_def2 ')'  {$$=$2;}
252 ;
253
254 generalstring_def: GeneralString {$$=_asn1_add_static_node(ASN1_ETYPE_GENERALSTRING);}
255                 | GeneralString size_def {$$=_asn1_add_static_node(ASN1_ETYPE_GENERALSTRING|CONST_SIZE);
256                                           _asn1_set_down($$,$2);}
257 ;
258
259 numericstring_def: NumericString {$$=_asn1_add_static_node(ASN1_ETYPE_NUMERIC_STRING|CONST_UNIVERSAL);}
260                 | NumericString size_def {$$=_asn1_add_static_node(ASN1_ETYPE_NUMERIC_STRING|CONST_SIZE);
261                                           _asn1_set_down($$,$2);}
262 ;
263
264 ia5string_def: IA5String {$$=_asn1_add_static_node(ASN1_ETYPE_IA5_STRING);}
265                 | IA5String size_def {$$=_asn1_add_static_node(ASN1_ETYPE_IA5_STRING|CONST_SIZE);
266                                           _asn1_set_down($$,$2);}
267 ;
268
269 teletexstring_def: TeletexString {$$=_asn1_add_static_node(ASN1_ETYPE_TELETEX_STRING);}
270                 | TeletexString size_def {$$=_asn1_add_static_node(ASN1_ETYPE_TELETEX_STRING|CONST_SIZE);
271                                           _asn1_set_down($$,$2);}
272 ;
273
274 printablestring_def: PrintableString {$$=_asn1_add_static_node(ASN1_ETYPE_PRINTABLE_STRING);}
275                 | PrintableString size_def {$$=_asn1_add_static_node(ASN1_ETYPE_PRINTABLE_STRING|CONST_SIZE);
276                                           _asn1_set_down($$,$2);}
277 ;
278
279 universalstring_def: UniversalString {$$=_asn1_add_static_node(ASN1_ETYPE_UNIVERSAL_STRING);}
280                 | UniversalString size_def {$$=_asn1_add_static_node(ASN1_ETYPE_UNIVERSAL_STRING|CONST_SIZE);
281                                           _asn1_set_down($$,$2);}
282 ;
283
284 bmpstring_def: BMPString {$$=_asn1_add_static_node(ASN1_ETYPE_BMP_STRING);}
285                 | BMPString size_def {$$=_asn1_add_static_node(ASN1_ETYPE_BMP_STRING|CONST_SIZE);
286                                           _asn1_set_down($$,$2);}
287 ;
288
289 utf8string_def: UTF8String {$$=_asn1_add_static_node(ASN1_ETYPE_UTF8_STRING);}
290                 | UTF8String size_def {$$=_asn1_add_static_node(ASN1_ETYPE_UTF8_STRING|CONST_SIZE);
291                                           _asn1_set_down($$,$2);}
292 ;
293
294 visiblestring_def: VisibleString {$$=_asn1_add_static_node(ASN1_ETYPE_VISIBLE_STRING);}
295                 | VisibleString size_def {$$=_asn1_add_static_node(ASN1_ETYPE_VISIBLE_STRING|CONST_SIZE);
296                                           _asn1_set_down($$,$2);}
297 ;
298
299 octet_string_def : OCTET STRING           {$$=_asn1_add_static_node(ASN1_ETYPE_OCTET_STRING);}
300                  | OCTET STRING size_def  {$$=_asn1_add_static_node(ASN1_ETYPE_OCTET_STRING|CONST_SIZE);
301                                            _asn1_set_down($$,$3);}
302 ;
303
304 bit_element :  IDENTIFIER'('NUM')' {$$=_asn1_add_static_node(ASN1_ETYPE_CONSTANT);
305                                    _asn1_set_name($$,$1);
306                                     _asn1_set_value($$,$3,strlen($3)+1);}
307 ;
308
309 bit_element_list :  bit_element   {$$=$1;}
310                   | bit_element_list ',' bit_element  {$$=$1;
311                                                        _asn1_set_right(_asn1_get_last_right($1),$3);}
312 ;
313
314 bit_string_def : BIT STRING    {$$=_asn1_add_static_node(ASN1_ETYPE_BIT_STRING);}
315                | BIT STRING size_def {$$=_asn1_add_static_node(ASN1_ETYPE_BIT_STRING|CONST_SIZE);}
316                | BIT STRING'{'bit_element_list'}'
317                                {$$=_asn1_add_static_node(ASN1_ETYPE_BIT_STRING|CONST_LIST);
318                                 _asn1_set_down($$,$4);}
319 ;
320
321 enumerated_def : ENUMERATED'{'bit_element_list'}'
322                                {$$=_asn1_add_static_node(ASN1_ETYPE_ENUMERATED|CONST_LIST);
323                                 _asn1_set_down($$,$3);}
324 ;
325
326
327 object_def :  OBJECT STR_IDENTIFIER {$$=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID);}
328 ;
329
330 type_assig_right: IDENTIFIER          {$$=_asn1_add_static_node(ASN1_ETYPE_IDENTIFIER);
331                                        _asn1_set_value($$,$1,strlen($1)+1);}
332                 | IDENTIFIER size_def {$$=_asn1_add_static_node(ASN1_ETYPE_IDENTIFIER|CONST_SIZE);
333                                        _asn1_set_value($$,$1,strlen($1)+1);
334                                        _asn1_set_down($$,$2);}
335                 | integer_def         {$$=$1;}
336                 | enumerated_def      {$$=$1;}
337                 | boolean_def         {$$=$1;}
338                 | Time
339                 | octet_string_def    {$$=$1;}
340                 | bit_string_def      {$$=$1;}
341                 | generalstring_def   {$$=$1;}
342                 | numericstring_def   {$$=$1;}
343                 | ia5string_def       {$$=$1;}
344                 | teletexstring_def   {$$=$1;}
345                 | printablestring_def {$$=$1;}
346                 | universalstring_def {$$=$1;}
347                 | bmpstring_def       {$$=$1;}
348                 | utf8string_def      {$$=$1;}
349                 | visiblestring_def   {$$=$1;}
350                 | sequence_def        {$$=$1;}
351                 | object_def          {$$=$1;}
352                 | choise_def          {$$=$1;}
353                 | any_def             {$$=$1;}
354                 | set_def             {$$=$1;}
355                 | TOKEN_NULL          {$$=_asn1_add_static_node(ASN1_ETYPE_NULL);}
356 ;
357
358 type_assig_right_tag :   type_assig_right     {$$=$1;}
359                        | tag type_assig_right {$$=_asn1_mod_type($2,CONST_TAG);
360                                                _asn1_set_right($1,_asn1_get_down($$));
361                                                _asn1_set_down($$,$1);}
362 ;
363
364 type_assig_right_tag_default : type_assig_right_tag   {$$=$1;}
365                       | type_assig_right_tag default  {$$=_asn1_mod_type($1,CONST_DEFAULT);
366                                                        _asn1_set_right($2,_asn1_get_down($$));
367                                                        _asn1_set_down($$,$2);}
368                       | type_assig_right_tag OPTIONAL {$$=_asn1_mod_type($1,CONST_OPTION);}
369 ;
370
371 type_assig : IDENTIFIER type_assig_right_tag_default  {$$=_asn1_set_name($2,$1);}
372 ;
373
374 type_assig_list : type_assig                   {$$=$1;}
375                 | type_assig_list','type_assig {$$=$1;
376                                                 _asn1_set_right(_asn1_get_last_right($1),$3);}
377 ;
378
379 sequence_def : SEQUENCE'{'type_assig_list'}' {$$=_asn1_add_static_node(ASN1_ETYPE_SEQUENCE);
380                                               _asn1_set_down($$,$3);}
381    | SEQUENCE OF type_assig_right            {$$=_asn1_add_static_node(ASN1_ETYPE_SEQUENCE_OF);
382                                               _asn1_set_down($$,$3);}
383    | SEQUENCE size_def OF type_assig_right {$$=_asn1_add_static_node(ASN1_ETYPE_SEQUENCE_OF|CONST_SIZE);
384                                             _asn1_set_right($2,$4);
385                                             _asn1_set_down($$,$2);}
386 ;
387
388 set_def :  SET'{'type_assig_list'}' {$$=_asn1_add_static_node(ASN1_ETYPE_SET);
389                                      _asn1_set_down($$,$3);}
390    | SET OF type_assig_right        {$$=_asn1_add_static_node(ASN1_ETYPE_SET_OF);
391                                      _asn1_set_down($$,$3);}
392    | SET size_def OF type_assig_right {$$=_asn1_add_static_node(ASN1_ETYPE_SET_OF|CONST_SIZE);
393                                        _asn1_set_right($2,$4);
394                                        _asn1_set_down($$,$2);}
395 ;
396
397 choise_def :   CHOICE'{'type_assig_list'}'  {$$=_asn1_add_static_node(ASN1_ETYPE_CHOICE);
398                                              _asn1_set_down($$,$3);}
399 ;
400
401 any_def :  ANY                         {$$=_asn1_add_static_node(ASN1_ETYPE_ANY);}
402          | ANY DEFINED BY IDENTIFIER   {$$=_asn1_add_static_node(ASN1_ETYPE_ANY|CONST_DEFINED_BY);
403                                         _asn1_set_down($$,_asn1_add_static_node(ASN1_ETYPE_CONSTANT));
404                                         _asn1_set_name(_asn1_get_down($$),$4);}
405 ;
406
407 type_def : IDENTIFIER "::=" type_assig_right_tag  {$$=_asn1_set_name($3,$1);}
408               /* below should match: BMPString ::= [UNIVERSAL 30] IMPLICIT OCTET STRING etc*/
409               | error "::=" type_assig_right_tag {$$=_asn1_set_name($3, last_error_token);}
410 ;
411
412 constant_def :  IDENTIFIER OBJECT STR_IDENTIFIER "::=" '{'obj_constant_list'}'
413                         {$$=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID|CONST_ASSIGN);
414                          _asn1_set_name($$,$1);
415                          _asn1_set_down($$,$6);}
416               | IDENTIFIER IDENTIFIER "::=" '{' obj_constant_list '}'
417                         {$$=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID|CONST_ASSIGN|CONST_1_PARAM);
418                          _asn1_set_name($$,$1);
419                          _asn1_set_value($$,$2,strlen($2)+1);
420                          _asn1_set_down($$,$5);}
421               | IDENTIFIER INTEGER "::=" pos_neg_num
422                         {$$=_asn1_add_static_node(ASN1_ETYPE_INTEGER|CONST_ASSIGN);
423                          _asn1_set_name($$,$1);
424                          _asn1_set_value($$,$4,strlen($4)+1);}
425 ;
426
427 type_constant:   type_def     {$$=$1;}
428                | constant_def {$$=$1;}
429 ;
430
431 type_constant_list :   type_constant    {$$=$1;}
432                      | type_constant_list type_constant  {$$=$1;
433                                                           _asn1_set_right(_asn1_get_last_right($1),$2);}
434 ;
435
436 definitions_id  :  IDENTIFIER  '{' obj_constant_list '}' {$$=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID);
437                                                           _asn1_set_down($$,$3);
438                                                           _asn1_set_name($$,$1);}
439                  | IDENTIFIER  '{' '}'                   {$$=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID);
440                                                           _asn1_set_name($$,$1);}
441                  | IDENTIFIER                            {$$=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID);
442                                                           _asn1_set_name($$,$1);}
443 ;
444
445 /*
446 identifier_list  :  IDENTIFIER  {$$=_asn1_add_static_node(ASN1_ETYPE_IDENTIFIER);
447                                  _asn1_set_name($$,$1);}
448                   | identifier_list IDENTIFIER
449                                 {$$=$1;
450                                  _asn1_set_right(_asn1_get_last_right($$),_asn1_add_static_node(ASN1_ETYPE_IDENTIFIER));
451                                  _asn1_set_name(_asn1_get_last_right($$),$2);}
452 ;
453
454
455 imports_def :    empty   {$$=NULL;}
456               | IMPORTS identifier_list FROM IDENTIFIER obj_constant_list
457                         {$$=_asn1_add_static_node(ASN1_ETYPE_IMPORTS);
458                          _asn1_set_down($$,_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID));
459                          _asn1_set_name(_asn1_get_down($$),$4);
460                          _asn1_set_down(_asn1_get_down($$),$5);
461                          _asn1_set_right($$,$2);}
462 ;
463 */
464
465 explicit_implicit :  EXPLICIT  {$$=CONST_EXPLICIT;}
466                    | IMPLICIT  {$$=CONST_IMPLICIT;}
467 ;
468
469
470 %%
471
472
473
474 static const char *key_word[] = {
475   "::=","OPTIONAL","INTEGER","SIZE","OCTET","STRING",
476   "SEQUENCE","BIT","UNIVERSAL","PRIVATE","OPTIONAL",
477   "DEFAULT","CHOICE","OF","OBJECT","IDENTIFIER",
478   "BOOLEAN","TRUE","FALSE","APPLICATION","ANY","DEFINED",
479   "SET","BY","EXPLICIT","IMPLICIT","DEFINITIONS","TAGS",
480   "BEGIN","END","UTCTime","GeneralizedTime",
481   "GeneralString","FROM","IMPORTS","NULL","ENUMERATED",
482   "NumericString", "IA5String", "TeletexString", "PrintableString",
483   "UniversalString", "BMPString", "UTF8String", "VisibleString"};
484
485 static const int key_word_token[] = {
486   ASSIG, OPTIONAL, INTEGER, SIZE, OCTET, STRING, SEQUENCE, BIT, UNIVERSAL,
487       PRIVATE, OPTIONAL, DEFAULT, CHOICE, OF, OBJECT, STR_IDENTIFIER,
488       BOOLEAN, ASN1_TRUE, ASN1_FALSE, APPLICATION, ANY, DEFINED, SET, BY,
489       EXPLICIT, IMPLICIT, DEFINITIONS, TAGS, BEGIN, END, UTCTime,
490       GeneralizedTime, GeneralString, FROM, IMPORTS, TOKEN_NULL,
491       ENUMERATED, NumericString, IA5String, TeletexString, PrintableString,
492       UniversalString, BMPString, UTF8String, VisibleString
493 };
494
495 /*************************************************************/
496 /*  Function: _asn1_yylex                                    */
497 /*  Description: looks for tokens in file_asn1 pointer file. */
498 /*  Return: int                                              */
499 /*    Token identifier or ASCII code or 0(zero: End Of File) */
500 /*************************************************************/
501 static int
502 _asn1_yylex ()
503 {
504   int c, counter = 0, k, lastc;
505   char string[ASN1_MAX_NAME_SIZE + 1];  /* will contain the next token */
506   size_t i;
507
508   while (1)
509     {
510       while ((c = fgetc (file_asn1)) == ' ' || c == '\t' || c == '\n')
511         if (c == '\n')
512           line_number++;
513
514       if (c == EOF)
515         {
516           snprintf (last_token, sizeof(last_token), "End Of File");
517           return 0;
518         }
519
520       if (c == '(' || c == ')' || c == '[' || c == ']' ||
521           c == '{' || c == '}' || c == ',' || c == '.' ||
522           c == '+' || c == '|')
523         {
524           last_token[0] = c;
525           last_token[1] = 0;
526           return c;
527         }
528       if (c == '-')
529         {                       /* Maybe the first '-' of a comment */
530           if ((c = fgetc (file_asn1)) != '-')
531             {
532               ungetc (c, file_asn1);
533               last_token[0] = '-';
534               last_token[1] = 0;
535               return '-';
536             }
537           else
538             {                   /* Comments */
539               lastc = 0;
540               counter = 0;
541               /* A comment finishes at the next double hypen or the end of line */
542               while ((c = fgetc (file_asn1)) != EOF && c != '\n' &&
543                      (lastc != '-' || (lastc == '-' && c != '-')))
544                 lastc = c;
545               if (c == EOF)
546                 {
547                   snprintf (last_token, sizeof(last_token), "End Of File");
548                   return 0;
549                 }
550               else
551                 {
552                   if (c == '\n')
553                     line_number++;
554                   continue;     /* next char, please! (repeat the search) */
555                 }
556             }
557         }
558       string[counter++] = c;
559       /* Till the end of the token */
560       while (!
561              ((c = fgetc (file_asn1)) == EOF || c == ' ' || c == '\t'
562               || c == '\n' || c == '(' || c == ')' || c == '[' || c == ']'
563               || c == '{' || c == '}' || c == ',' || c == '.'))
564         {
565           if (counter >= ASN1_MAX_NAME_SIZE)
566             {
567               result_parse = ASN1_NAME_TOO_LONG;
568               return 0;
569             }
570           string[counter++] = c;
571         }
572       ungetc (c, file_asn1);
573       string[counter] = 0;
574       snprintf (last_token, sizeof(last_token), "%s", string);
575
576       /* Is STRING a number? */
577       for (k = 0; k < counter; k++)
578         if (!isdigit (string[k]))
579           break;
580       if (k >= counter)
581         {
582           snprintf (yylval.str, sizeof(yylval.str), "%s", string);
583           return NUM;           /* return the number */
584         }
585
586       /* Is STRING a keyword? */
587       for (i = 0; i < (sizeof (key_word) / sizeof (char *)); i++)
588         if (!strcmp (string, key_word[i]))
589           return key_word_token[i];
590
591       /* STRING is an IDENTIFIER */
592       snprintf (yylval.str, sizeof(yylval.str), "%s", string);
593       return IDENTIFIER;
594     }
595 }
596
597 /*************************************************************/
598 /*  Function: _asn1_create_errorDescription                  */
599 /*  Description: creates a string with the description of the*/
600 /*    error.                                                 */
601 /*  Parameters:                                              */
602 /*    error : error to describe.                             */
603 /*    error_desc: string that will contain the         */
604 /*                      description.                         */
605 /*************************************************************/
606 static void
607 _asn1_create_errorDescription (int error, char *error_desc)
608 {
609   if (error_desc == NULL)
610     return;
611
612
613   switch (error)
614     {
615     case ASN1_FILE_NOT_FOUND:
616       snprintf(error_desc, ASN1_MAX_ERROR_DESCRIPTION_SIZE, "%s file was not found", file_name);
617       break;
618     case ASN1_SYNTAX_ERROR:
619       snprintf(error_desc, ASN1_MAX_ERROR_DESCRIPTION_SIZE, "%s", last_error);
620       break;
621     case ASN1_NAME_TOO_LONG:
622       snprintf (error_desc, ASN1_MAX_ERROR_DESCRIPTION_SIZE,
623                 "%s:%u: name too long (more than %u characters)", file_name,
624                 line_number, ASN1_MAX_NAME_SIZE);
625       break;
626     case ASN1_IDENTIFIER_NOT_FOUND:
627       snprintf (error_desc, ASN1_MAX_ERROR_DESCRIPTION_SIZE,
628                 "%s:: identifier '%s' not found", file_name,
629                 _asn1_identifierMissing);
630       break;
631     default:
632       error_desc[0] = 0;
633       break;
634     }
635
636 }
637
638 /**
639  * asn1_parser2tree:
640  * @file: specify the path and the name of file that contains
641  *   ASN.1 declarations.
642  * @definitions: return the pointer to the structure created from
643  *   "file" ASN.1 declarations.
644  * @error_desc: return the error description or an empty
645  * string if success.
646  *
647  * Function used to start the parse algorithm.  Creates the structures
648  * needed to manage the definitions included in @file file.
649  *
650  * Returns: %ASN1_SUCCESS if the file has a correct syntax and every
651  *   identifier is known, %ASN1_ELEMENT_NOT_EMPTY if @definitions not
652  *   %NULL, %ASN1_FILE_NOT_FOUND if an error occured while
653  *   opening @file, %ASN1_SYNTAX_ERROR if the syntax is not
654  *   correct, %ASN1_IDENTIFIER_NOT_FOUND if in the file there is an
655  *   identifier that is not defined, %ASN1_NAME_TOO_LONG if in the
656  *   file there is an identifier whith more than %ASN1_MAX_NAME_SIZE
657  *   characters.
658  **/
659 int
660 asn1_parser2tree (const char *file, asn1_node * definitions,
661                   char *error_desc)
662 {
663
664   p_tree = NULL;
665
666   if (*definitions != NULL)
667     return ASN1_ELEMENT_NOT_EMPTY;
668
669   *definitions = NULL;
670
671   file_name = file;
672
673   /* open the file to parse */
674   file_asn1 = fopen (file, "r");
675
676   if (file_asn1 == NULL)
677     {
678       result_parse = ASN1_FILE_NOT_FOUND;
679     }
680   else
681     {
682       result_parse = ASN1_SUCCESS;
683
684       line_number = 1;
685       yyparse ();
686
687       fclose (file_asn1);
688
689       if (result_parse == ASN1_SUCCESS)
690         {                       /* syntax OK */
691           /* set IMPLICIT or EXPLICIT property */
692           _asn1_set_default_tag (p_tree);
693           /* set CONST_SET and CONST_NOT_USED */
694           _asn1_type_set_config (p_tree);
695           /* check the identifier definitions */
696           result_parse = _asn1_check_identifier (p_tree);
697           if (result_parse == ASN1_SUCCESS)
698             {                   /* all identifier defined */
699               /* Delete the list and keep the ASN1 structure */
700               _asn1_delete_list ();
701               /* Convert into DER coding the value assign to INTEGER constants */
702               _asn1_change_integer_value (p_tree);
703               /* Expand the IDs of OBJECT IDENTIFIER constants */
704               _asn1_expand_object_id (p_tree);
705
706               *definitions = p_tree;
707             }
708           else                  /* some identifiers not defined */
709             /* Delete the list and the ASN1 structure */
710             _asn1_delete_list_and_nodes ();
711         }
712       else                      /* syntax error */
713         /* Delete the list and the ASN1 structure */
714         _asn1_delete_list_and_nodes ();
715     }
716
717   _asn1_create_errorDescription (result_parse, error_desc);
718
719   return result_parse;
720 }
721
722 /**
723  * asn1_parser2array:
724  * @inputFileName: specify the path and the name of file that
725  *   contains ASN.1 declarations.
726  * @outputFileName: specify the path and the name of file that will
727  *   contain the C vector definition.
728  * @vectorName: specify the name of the C vector.
729  * @error_desc: return the error description or an empty
730  *   string if success.
731  *
732  * Function that generates a C structure from an ASN1 file.  Creates a
733  * file containing a C vector to use to manage the definitions
734  * included in @inputFileName file. If @inputFileName is
735  * "/aa/bb/xx.yy" and @outputFileName is %NULL, the file created is
736  * "/aa/bb/xx_asn1_tab.c".  If @vectorName is %NULL the vector name
737  * will be "xx_asn1_tab".
738  *
739  * Returns: %ASN1_SUCCESS if the file has a correct syntax and every
740  *   identifier is known, %ASN1_FILE_NOT_FOUND if an error occured
741  *   while opening @inputFileName, %ASN1_SYNTAX_ERROR if the syntax is
742  *   not correct, %ASN1_IDENTIFIER_NOT_FOUND if in the file there is
743  *   an identifier that is not defined, %ASN1_NAME_TOO_LONG if in the
744  *   file there is an identifier whith more than %ASN1_MAX_NAME_SIZE
745  *   characters.
746  **/
747 int
748 asn1_parser2array (const char *inputFileName, const char *outputFileName,
749                    const char *vectorName, char *error_desc)
750 {
751   char *file_out_name = NULL;
752   char *vector_name = NULL;
753   const char *char_p, *slash_p, *dot_p;
754
755   p_tree = NULL;
756
757   file_name = inputFileName;
758
759   /* open the file to parse */
760   file_asn1 = fopen (inputFileName, "r");
761
762   if (file_asn1 == NULL)
763     result_parse = ASN1_FILE_NOT_FOUND;
764   else
765     {
766       result_parse = ASN1_SUCCESS;
767
768       line_number = 1;
769       yyparse ();
770
771       fclose (file_asn1);
772
773       if (result_parse == ASN1_SUCCESS)
774         {                       /* syntax OK */
775           /* set IMPLICIT or EXPLICIT property */
776           _asn1_set_default_tag (p_tree);
777           /* set CONST_SET and CONST_NOT_USED */
778           _asn1_type_set_config (p_tree);
779           /* check the identifier definitions */
780           result_parse = _asn1_check_identifier (p_tree);
781
782           if (result_parse == ASN1_SUCCESS)
783             {                   /* all identifier defined */
784
785               /* searching the last '/' and '.' in inputFileName */
786               char_p = inputFileName;
787               slash_p = inputFileName;
788               while ((char_p = strchr (char_p, '/')))
789                 {
790                   char_p++;
791                   slash_p = char_p;
792                 }
793
794               char_p = slash_p;
795               dot_p = inputFileName + strlen (inputFileName);
796
797               while ((char_p = strchr (char_p, '.')))
798                 {
799                   dot_p = char_p;
800                   char_p++;
801                 }
802
803               if (outputFileName == NULL)
804                 {
805                   /* file_out_name = inputFileName + _asn1_tab.c */
806                   file_out_name = malloc (dot_p - inputFileName + 1 +
807                                           strlen ("_asn1_tab.c"));
808                   memcpy (file_out_name, inputFileName,
809                           dot_p - inputFileName);
810                   file_out_name[dot_p - inputFileName] = 0;
811                   strcat (file_out_name, "_asn1_tab.c");
812                 }
813               else
814                 {
815                   /* file_out_name = inputFileName */
816                   file_out_name =
817                       (char *) malloc (strlen (outputFileName) + 1);
818                   strcpy (file_out_name, outputFileName);
819                 }
820
821               if (vectorName == NULL)
822                 {
823                   /* vector_name = file name + _asn1_tab */
824                   vector_name = malloc (dot_p - slash_p + 1 +
825                                         strlen ("_asn1_tab"));
826                   memcpy (vector_name, slash_p, dot_p - slash_p);
827                   vector_name[dot_p - slash_p] = 0;
828                   strcat (vector_name, "_asn1_tab");
829                 }
830               else
831                 {
832                   /* vector_name = vectorName */
833                   vector_name = (char *) malloc (strlen (vectorName) + 1);
834                   strcpy (vector_name, vectorName);
835                 }
836
837               /* Save structure in a file */
838               _asn1_create_static_structure (p_tree,
839                                              file_out_name, vector_name);
840
841               free (file_out_name);
842               free (vector_name);
843             }                   /* result == OK */
844         }                       /* result == OK */
845
846       /* Delete the list and the ASN1 structure */
847       _asn1_delete_list_and_nodes ();
848     }                           /* inputFile exist */
849
850   _asn1_create_errorDescription (result_parse, error_desc);
851
852   return result_parse;
853 }
854
855 /*************************************************************/
856 /*  Function: _asn1_yyerror                                  */
857 /*  Description: function called when there are syntax errors*/
858 /*  Parameters:                                              */
859 /*    char *s : error description                            */
860 /*  Return: int                                              */
861 /*                                                           */
862 /*************************************************************/
863 static void
864 _asn1_yyerror (const char *s)
865 {
866   /* Sends the error description to the std_out */
867
868   if (strcmp (last_token, "VisibleString") == 0 ||
869       strcmp (last_token, "PrintableString") == 0 ||
870       strcmp (last_token, "UniversalString") == 0 ||
871       strcmp (last_token, "IA5String") == 0 ||
872       strcmp (last_token, "UTF8String") == 0 ||
873       strcmp (last_token, "NumericString") == 0 ||
874       strcmp (last_token, "TeletexString") == 0 ||
875       strcmp (last_token, "BMPString") == 0)
876     {
877       snprintf (last_error_token, sizeof(last_error_token),
878                 "%s", last_token);
879       fprintf(stderr, "%s:%u: Warning: %s is a built-in ASN.1 type.\n",
880                file_name, line_number, last_token);
881       return;
882     }
883   last_error_token[0] = 0;
884
885   if (result_parse != ASN1_NAME_TOO_LONG)
886     {
887       snprintf (last_error, sizeof(last_error),
888                 "%s:%u: Error: %s near '%s'", file_name,
889                 line_number, s, last_token);
890       result_parse = ASN1_SYNTAX_ERROR;
891     }
892
893   return;
894 }