Line data Source code
1 : /* asn1-parse.y - ASN.1 grammar
2 : * Copyright (C) 2000, 2001 Fabio Fiorina
3 : * Copyright (C) 2001 Free Software Foundation, Inc.
4 : * Copyright (C) 2002, 2003, 2006, 2007, 2010, 2012 g10 Code GmbH
5 : *
6 : * This file is part of KSBA.
7 : *
8 : * KSBA is free software; you can redistribute it and/or modify
9 : * it under the terms of either
10 : *
11 : * - the GNU Lesser General Public License as published by the Free
12 : * Software Foundation; either version 3 of the License, or (at
13 : * your option) any later version.
14 : *
15 : * or
16 : *
17 : * - the GNU General Public License as published by the Free
18 : * Software Foundation; either version 2 of the License, or (at
19 : * your option) any later version.
20 : *
21 : * or both in parallel, as here.
22 : *
23 : * KSBA is distributed in the hope that it will be useful, but WITHOUT
24 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
25 : * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
26 : * License for more details.
27 : *
28 : * You should have received a copies of the GNU General Public License
29 : * and the GNU Lesser General Public License along with this program;
30 : * if not, see <http://www.gnu.org/licenses/>.
31 : */
32 :
33 :
34 : /*****************************************************/
35 : /* File: x509_ASN.y */
36 : /* Description: input file for 'bison' program. */
37 : /* The output file is a parser (in C language) for */
38 : /* ASN.1 syntax */
39 : /*****************************************************/
40 :
41 :
42 : %{
43 : #ifndef BUILD_GENTOOLS
44 : # include <config.h>
45 : #endif
46 : #include <stdlib.h>
47 : #include <stdio.h>
48 : #include <string.h>
49 : #include <assert.h>
50 : #include <ctype.h>
51 : #include <errno.h>
52 :
53 : #ifdef BUILD_GENTOOLS
54 : # include "gen-help.h"
55 : #else
56 : # include "util.h"
57 : # include "ksba.h"
58 : #endif
59 :
60 : #include "asn1-func.h"
61 :
62 : /* It would be better to make yyparse static but there is no way to do
63 : this. Let's hope that this macros works. */
64 : #define yyparse _ksba_asn1_yyparse
65 :
66 : /* #define YYDEBUG 1 */
67 : #define MAX_STRING_LENGTH 129
68 :
69 : /* Dummy print so that yytoknum will be defined. */
70 : #define YYPRINT(F, N, L) do { } while (0);
71 :
72 :
73 : /* constants used in the grammar */
74 : enum {
75 : CONST_EXPLICIT = 1,
76 : CONST_IMPLICIT
77 : };
78 :
79 : struct parser_control_s {
80 : FILE *fp;
81 : int lineno;
82 : int debug;
83 : int result_parse;
84 : AsnNode parse_tree;
85 : AsnNode all_nodes;
86 : };
87 : #define PARSECTL ((struct parser_control_s *)parm)
88 :
89 : %}
90 :
91 :
92 : %param {void *parm}
93 : %define api.pure full
94 : %define parse.error verbose
95 : %expect 1
96 :
97 : %union {
98 : unsigned int constant;
99 : char str[MAX_STRING_LENGTH];
100 : AsnNode node;
101 : }
102 :
103 : %{
104 : static AsnNode new_node (struct parser_control_s *parsectl, node_type_t type);
105 : #define NEW_NODE(a) (new_node (PARSECTL, (a)))
106 : static void set_name (AsnNode node, const char *name);
107 : static void set_str_value (AsnNode node, const char *text);
108 : static void set_ulong_value (AsnNode node, const char *text);
109 : static void set_right (AsnNode node, AsnNode right);
110 : static void append_right (AsnNode node, AsnNode right);
111 : static void set_down (AsnNode node, AsnNode down);
112 :
113 :
114 : static int yylex (YYSTYPE *lvalp, void *parm);
115 : static void yyerror (void *parm, const char *s);
116 : %}
117 :
118 : %token-table
119 :
120 : %token ASSIG "::="
121 : %token <str> NUM
122 : %token <str> IDENTIFIER
123 : %token OPTIONAL "OPTIONAL"
124 : %token INTEGER "INTEGER"
125 : %token SIZE "SIZE"
126 : %token OCTET "OCTET"
127 : %token STRING "STRING"
128 : %token SEQUENCE "SEQUENCE"
129 : %token BIT "BIT"
130 : %token UNIVERSAL "UNIVERSAL"
131 : %token PRIVATE "PRIVATE"
132 : %token DEFAULT "DEFAULT"
133 : %token CHOICE "CHOICE"
134 : %token OF "OF"
135 : %token OBJECT "OBJECT"
136 : %token STR_IDENTIFIER "IDENTIFIER"
137 : %token ksba_BOOLEAN "BOOLEAN"
138 : %token ksba_TRUE "TRUE"
139 : %token ksba_FALSE "FALSE"
140 : %token APPLICATION "APPLICATION"
141 : %token ANY "ANY"
142 : %token DEFINED "DEFINED"
143 : %token SET "SET"
144 : %token BY "BY"
145 : %token EXPLICIT "EXPLICIT"
146 : %token IMPLICIT "IMPLICIT"
147 : %token DEFINITIONS "DEFINITIONS"
148 : %token TAGS "TAGS"
149 : %token ksba_BEGIN "BEGIN"
150 : %token ksba_END "END"
151 : %token UTCTime "UTCTime"
152 : %token GeneralizedTime "GeneralizedTime"
153 : %token FROM "FROM"
154 : %token IMPORTS "IMPORTS"
155 : %token TOKEN_NULL "NULL"
156 : %token ENUMERATED "ENUMERATED"
157 : %token UTF8STRING "UTF8String"
158 : %token NUMERICSTRING "NumericString"
159 : %token PRINTABLESTRING "PrintableString"
160 : %token TELETEXSTRING "TeletexString"
161 : %token IA5STRING "IA5String"
162 : %token UNIVERSALSTRING "UniversalString"
163 : %token BMPSTRING "BMPString"
164 :
165 :
166 :
167 : %type <node> octet_string_def constant constant_list type_assig_right
168 : %type <node> integer_def type_assig type_assig_list sequence_def type_def
169 : %type <node> bit_string_def default size_def choise_def object_def
170 : %type <node> boolean_def any_def size_def2 obj_constant obj_constant_list
171 : %type <node> constant_def type_constant type_constant_list definitions
172 : %type <node> definitions_id Time bit_element bit_element_list set_def
173 : %type <node> identifier_list imports_def tag_type tag type_assig_right_tag
174 : %type <node> type_assig_right_tag_default enumerated_def string_def
175 : %type <node> utf8_string_def numeric_string_def printable_string_def
176 : %type <node> teletex_string_def ia5_string_def universal_string_def
177 : %type <node> bmp_string_def
178 : %type <str> pos_num neg_num pos_neg_num pos_neg_identifier num_identifier
179 : %type <constant> class explicit_implicit
180 :
181 :
182 : %%
183 :
184 : input: /* empty */
185 : | input definitions
186 : ;
187 :
188 0 : pos_num : NUM { strcpy($$,$1); }
189 0 : | '+' NUM { strcpy($$,$2); }
190 : ;
191 :
192 : neg_num : '-' NUM
193 : {
194 0 : strcpy($$,"-");
195 0 : strcat($$,$2);
196 : }
197 : ;
198 :
199 0 : pos_neg_num : pos_num { strcpy($$,$1); }
200 0 : | neg_num { strcpy($$,$1); }
201 : ;
202 :
203 0 : num_identifier : NUM {strcpy($$,$1);}
204 0 : | IDENTIFIER {strcpy($$,$1);}
205 : ;
206 :
207 0 : pos_neg_identifier : pos_neg_num {strcpy($$,$1);}
208 0 : | IDENTIFIER {strcpy($$,$1);}
209 : ;
210 :
211 : constant: '(' pos_neg_num ')'
212 : {
213 0 : $$ = NEW_NODE (TYPE_CONSTANT);
214 0 : set_str_value ($$, $2);
215 : }
216 : | IDENTIFIER'('pos_neg_num')'
217 : {
218 0 : $$ = NEW_NODE (TYPE_CONSTANT);
219 0 : set_name ($$, $1);
220 0 : set_str_value ($$, $3);
221 : }
222 : ;
223 :
224 0 : constant_list: constant { $$=$1; }
225 : | constant_list ',' constant
226 : {
227 0 : $$ = $1;
228 0 : append_right ($1, $3);
229 : }
230 : ;
231 :
232 : identifier_list : IDENTIFIER
233 : {
234 0 : $$ = NEW_NODE (TYPE_IDENTIFIER);
235 0 : set_name($$,$1);
236 : }
237 : | identifier_list IDENTIFIER
238 : {
239 : AsnNode node;
240 :
241 0 : $$=$1;
242 0 : node = NEW_NODE (TYPE_IDENTIFIER);
243 0 : set_name (node, $2);
244 0 : append_right ($$, node);
245 : }
246 : ;
247 :
248 : obj_constant: num_identifier
249 : {
250 0 : $$ = NEW_NODE (TYPE_CONSTANT);
251 0 : set_str_value ($$, $1);
252 : }
253 : | IDENTIFIER '(' NUM ')'
254 : {
255 0 : $$ = NEW_NODE (TYPE_CONSTANT);
256 0 : set_name ($$, $1);
257 0 : set_str_value ($$, $3);
258 : }
259 : ;
260 :
261 : obj_constant_list: obj_constant
262 0 : { $$=$1;}
263 : | obj_constant_list obj_constant
264 : {
265 0 : $$=$1;
266 0 : append_right ($$, $2);
267 : }
268 : ;
269 :
270 0 : class : UNIVERSAL { $$ = CLASS_UNIVERSAL; }
271 0 : | PRIVATE { $$ = CLASS_PRIVATE; }
272 0 : | APPLICATION { $$ = CLASS_APPLICATION; }
273 : ;
274 :
275 : tag_type : '[' NUM ']'
276 : {
277 0 : $$ = NEW_NODE (TYPE_TAG);
278 0 : $$->flags.class = CLASS_CONTEXT;
279 0 : set_ulong_value ($$, $2);
280 : }
281 : | '[' class NUM ']'
282 : {
283 0 : $$ = NEW_NODE (TYPE_TAG);
284 0 : $$->flags.class = $2;
285 0 : set_ulong_value ($$, $3);
286 : }
287 : ;
288 :
289 : tag : tag_type
290 0 : { $$ = $1; }
291 : | tag_type EXPLICIT
292 : {
293 0 : $$ = $1;
294 0 : $$->flags.explicit = 1;
295 : }
296 : | tag_type IMPLICIT
297 : {
298 0 : $$ = $1;
299 0 : $$->flags.implicit = 1;
300 : }
301 : ;
302 :
303 : default : DEFAULT pos_neg_identifier
304 : {
305 0 : $$ = NEW_NODE (TYPE_DEFAULT);
306 0 : set_str_value ($$, $2);
307 : }
308 : | DEFAULT ksba_TRUE
309 : {
310 0 : $$ = NEW_NODE (TYPE_DEFAULT);
311 0 : $$->flags.is_true = 1;
312 : }
313 : | DEFAULT ksba_FALSE
314 : {
315 0 : $$ = NEW_NODE (TYPE_DEFAULT);
316 0 : $$->flags.is_false = 1;
317 : }
318 : ;
319 :
320 : integer_def: INTEGER
321 : {
322 0 : $$ = NEW_NODE (TYPE_INTEGER);
323 : }
324 : | INTEGER '{' constant_list '}'
325 : {
326 0 : $$ = NEW_NODE (TYPE_INTEGER);
327 0 : $$->flags.has_list = 1;
328 0 : set_down ($$, $3);
329 : }
330 : | integer_def '(' num_identifier '.' '.' num_identifier ')'
331 : {
332 0 : $$ = NEW_NODE (TYPE_INTEGER);
333 0 : $$->flags.has_min_max = 1;
334 : /* the following is wrong. Better use a union for the value*/
335 0 : set_down ($$, NEW_NODE (TYPE_SIZE) );
336 0 : set_str_value ($$->down, $6);
337 0 : set_name ($$->down, $3);
338 : }
339 : ;
340 :
341 : boolean_def: ksba_BOOLEAN
342 : {
343 0 : $$ = NEW_NODE (TYPE_BOOLEAN);
344 : }
345 : ;
346 :
347 : Time: UTCTime
348 : {
349 0 : $$ = NEW_NODE (TYPE_UTC_TIME);
350 : }
351 : | GeneralizedTime
352 : {
353 0 : $$ = NEW_NODE (TYPE_GENERALIZED_TIME);
354 : }
355 : ;
356 :
357 : size_def2: SIZE '(' num_identifier ')'
358 : {
359 0 : $$ = NEW_NODE (TYPE_SIZE);
360 0 : $$->flags.one_param = 1;
361 0 : set_str_value ($$, $3);
362 : }
363 : | SIZE '(' num_identifier '.' '.' num_identifier ')'
364 : {
365 0 : $$ = NEW_NODE (TYPE_SIZE);
366 0 : $$->flags.has_min_max = 1;
367 0 : set_str_value ($$, $3);
368 0 : set_name ($$, $6);
369 : }
370 : ;
371 :
372 : size_def: size_def2
373 : {
374 0 : $$=$1;
375 : }
376 : | '(' size_def2 ')'
377 : {
378 0 : $$=$2;
379 : }
380 : ;
381 :
382 : octet_string_def : OCTET STRING
383 : {
384 0 : $$ = NEW_NODE (TYPE_OCTET_STRING);
385 : }
386 : | OCTET STRING size_def
387 : {
388 0 : $$ = NEW_NODE (TYPE_OCTET_STRING);
389 0 : $$->flags.has_size = 1;
390 0 : set_down ($$,$3);
391 : }
392 : ;
393 :
394 0 : utf8_string_def: UTF8STRING { $$ = NEW_NODE (TYPE_UTF8_STRING); }
395 : | UTF8STRING size_def
396 : {
397 0 : $$ = NEW_NODE (TYPE_UTF8_STRING);
398 0 : $$->flags.has_size = 1;
399 0 : set_down ($$,$2);
400 : }
401 : ;
402 0 : numeric_string_def: NUMERICSTRING { $$ = NEW_NODE (TYPE_NUMERIC_STRING); }
403 : | NUMERICSTRING size_def
404 : {
405 0 : $$ = NEW_NODE (TYPE_NUMERIC_STRING);
406 0 : $$->flags.has_size = 1;
407 0 : set_down ($$,$2);
408 : }
409 : ;
410 : printable_string_def: PRINTABLESTRING
411 0 : { $$ = NEW_NODE (TYPE_PRINTABLE_STRING); }
412 : | PRINTABLESTRING size_def
413 : {
414 0 : $$ = NEW_NODE (TYPE_PRINTABLE_STRING);
415 0 : $$->flags.has_size = 1;
416 0 : set_down ($$,$2);
417 : }
418 : ;
419 : teletex_string_def: TELETEXSTRING
420 0 : { $$ = NEW_NODE (TYPE_TELETEX_STRING); }
421 : | TELETEXSTRING size_def
422 : {
423 0 : $$ = NEW_NODE (TYPE_TELETEX_STRING);
424 0 : $$->flags.has_size = 1;
425 0 : set_down ($$,$2);
426 : }
427 : ;
428 0 : ia5_string_def: IA5STRING { $$ = NEW_NODE (TYPE_IA5_STRING); }
429 : | IA5STRING size_def
430 : {
431 0 : $$ = NEW_NODE (TYPE_IA5_STRING);
432 0 : $$->flags.has_size = 1;
433 0 : set_down ($$,$2);
434 : }
435 : ;
436 : universal_string_def: UNIVERSALSTRING
437 0 : { $$ = NEW_NODE (TYPE_UNIVERSAL_STRING); }
438 : | UNIVERSALSTRING size_def
439 : {
440 0 : $$ = NEW_NODE (TYPE_UNIVERSAL_STRING);
441 0 : $$->flags.has_size = 1;
442 0 : set_down ($$,$2);
443 : }
444 : ;
445 0 : bmp_string_def: BMPSTRING { $$ = NEW_NODE (TYPE_BMP_STRING); }
446 : | BMPSTRING size_def
447 : {
448 0 : $$ = NEW_NODE (TYPE_BMP_STRING);
449 0 : $$->flags.has_size = 1;
450 0 : set_down ($$,$2);
451 : }
452 : ;
453 :
454 :
455 : string_def: utf8_string_def
456 : | numeric_string_def
457 : | printable_string_def
458 : | teletex_string_def
459 : | ia5_string_def
460 : | universal_string_def
461 : | bmp_string_def
462 : ;
463 :
464 :
465 :
466 :
467 : bit_element : IDENTIFIER'('NUM')'
468 : {
469 0 : $$ = NEW_NODE (TYPE_CONSTANT);
470 0 : set_name ($$, $1);
471 0 : set_str_value ($$, $3);
472 : }
473 : ;
474 :
475 : bit_element_list : bit_element
476 : {
477 0 : $$=$1;
478 : }
479 : | bit_element_list ',' bit_element
480 : {
481 0 : $$=$1;
482 0 : append_right ($$, $3);
483 : }
484 : ;
485 :
486 : bit_string_def : BIT STRING
487 : {
488 0 : $$ = NEW_NODE (TYPE_BIT_STRING);
489 : }
490 : | BIT STRING '{' bit_element_list '}'
491 : {
492 0 : $$ = NEW_NODE (TYPE_BIT_STRING);
493 0 : $$->flags.has_list = 1;
494 0 : set_down ($$, $4);
495 : }
496 : ;
497 :
498 : enumerated_def : ENUMERATED '{' bit_element_list '}'
499 : {
500 0 : $$ = NEW_NODE (TYPE_ENUMERATED);
501 0 : $$->flags.has_list = 1;
502 0 : set_down ($$, $3);
503 : }
504 : ;
505 :
506 : object_def : OBJECT STR_IDENTIFIER
507 : {
508 0 : $$ = NEW_NODE (TYPE_OBJECT_ID);
509 : }
510 : ;
511 :
512 : type_assig_right: IDENTIFIER
513 : {
514 0 : $$ = NEW_NODE (TYPE_IDENTIFIER);
515 0 : set_str_value ($$, $1);
516 : }
517 : | IDENTIFIER size_def
518 : {
519 0 : $$ = NEW_NODE (TYPE_IDENTIFIER);
520 0 : $$->flags.has_size = 1;
521 0 : set_str_value ($$, $1);
522 0 : set_down ($$, $2);
523 : }
524 0 : | integer_def {$$=$1;}
525 0 : | enumerated_def {$$=$1;}
526 0 : | boolean_def {$$=$1;}
527 0 : | string_def {$$=$1;}
528 : | Time
529 0 : | octet_string_def {$$=$1;}
530 0 : | bit_string_def {$$=$1;}
531 0 : | sequence_def {$$=$1;}
532 0 : | object_def {$$=$1;}
533 0 : | choise_def {$$=$1;}
534 0 : | any_def {$$=$1;}
535 0 : | set_def {$$=$1;}
536 : | TOKEN_NULL
537 : {
538 0 : $$ = NEW_NODE(TYPE_NULL);
539 : }
540 : ;
541 :
542 : type_assig_right_tag : type_assig_right
543 : {
544 0 : $$ = $1;
545 : }
546 : | tag type_assig_right
547 : {
548 : /* $2->flags.has_tag = 1; */
549 : /* $$ = $2; */
550 : /* set_right ($1, $$->down ); */
551 : /* set_down ($$, $1); */
552 0 : $$ = $1;
553 0 : set_down ($$, $2);
554 : }
555 : ;
556 :
557 : type_assig_right_tag_default : type_assig_right_tag
558 : {
559 0 : $$ = $1;
560 : }
561 : | type_assig_right_tag default
562 : {
563 0 : $1->flags.has_default = 1;
564 0 : $$ = $1;
565 0 : set_right ($2, $$->down);
566 0 : set_down ($$, $2);
567 : }
568 : | type_assig_right_tag OPTIONAL
569 : {
570 0 : $1->flags.is_optional = 1;
571 0 : $$ = $1;
572 : }
573 : ;
574 :
575 : type_assig : IDENTIFIER type_assig_right_tag_default
576 : {
577 0 : set_name ($2, $1);
578 0 : $$ = $2;
579 : }
580 : ;
581 :
582 : type_assig_list : type_assig
583 0 : { $$=$1; }
584 : | type_assig_list ',' type_assig
585 : {
586 0 : $$=$1;
587 0 : append_right ($$, $3);
588 : }
589 : ;
590 :
591 : sequence_def : SEQUENCE '{' type_assig_list '}'
592 : {
593 0 : $$ = NEW_NODE (TYPE_SEQUENCE);
594 0 : set_down ($$, $3);
595 : }
596 : | SEQUENCE OF type_assig_right
597 : {
598 0 : $$ = NEW_NODE (TYPE_SEQUENCE_OF);
599 0 : set_down ($$, $3);
600 : }
601 : | SEQUENCE size_def OF type_assig_right
602 : {
603 0 : $$ = NEW_NODE (TYPE_SEQUENCE_OF);
604 0 : $$->flags.has_size = 1;
605 0 : set_right ($2,$4);
606 0 : set_down ($$,$2);
607 : }
608 : ;
609 :
610 : set_def : SET '{' type_assig_list '}'
611 : {
612 0 : $$ = NEW_NODE (TYPE_SET);
613 0 : set_down ($$, $3);
614 : }
615 : | SET OF type_assig_right
616 : {
617 0 : $$ = NEW_NODE (TYPE_SET_OF);
618 0 : set_down ($$, $3);
619 : }
620 : | SET size_def OF type_assig_right
621 : {
622 0 : $$ = NEW_NODE (TYPE_SET_OF);
623 0 : $$->flags.has_size = 1;
624 0 : set_right ($2, $4);
625 0 : set_down ($$, $2);
626 : }
627 : ;
628 :
629 : choise_def : CHOICE '{' type_assig_list '}'
630 : {
631 0 : $$ = NEW_NODE (TYPE_CHOICE);
632 0 : set_down ($$, $3);
633 : }
634 : ;
635 :
636 : any_def : ANY
637 : {
638 0 : $$ = NEW_NODE (TYPE_ANY);
639 : }
640 : | ANY DEFINED BY IDENTIFIER
641 : {
642 : AsnNode node;
643 :
644 0 : $$ = NEW_NODE (TYPE_ANY);
645 0 : $$->flags.has_defined_by = 1;
646 0 : node = NEW_NODE (TYPE_CONSTANT);
647 0 : set_name (node, $4);
648 0 : set_down($$, node);
649 : }
650 : ;
651 :
652 : type_def : IDENTIFIER "::=" type_assig_right_tag
653 : {
654 0 : set_name ($3, $1);
655 0 : $$ = $3;
656 : }
657 : ;
658 :
659 : constant_def : IDENTIFIER OBJECT STR_IDENTIFIER "::=" '{' obj_constant_list '}'
660 : {
661 0 : $$ = NEW_NODE (TYPE_OBJECT_ID);
662 0 : $$->flags.assignment = 1;
663 0 : set_name ($$, $1);
664 0 : set_down ($$, $6);
665 : }
666 : | IDENTIFIER IDENTIFIER "::=" '{' obj_constant_list '}'
667 : {
668 0 : $$ = NEW_NODE (TYPE_OBJECT_ID);
669 0 : $$->flags.assignment = 1;
670 0 : $$->flags.one_param = 1;
671 0 : set_name ($$, $1);
672 0 : set_str_value ($$, $2);
673 0 : set_down ($$, $5);
674 : }
675 : | IDENTIFIER INTEGER "::=" NUM
676 : {
677 0 : $$ = NEW_NODE (TYPE_INTEGER);
678 0 : $$->flags.assignment = 1;
679 0 : set_name ($$, $1);
680 0 : set_str_value ($$, $4);
681 : }
682 : ;
683 :
684 0 : type_constant: type_def { $$ = $1; }
685 0 : | constant_def { $$ = $1; }
686 : ;
687 :
688 : type_constant_list : type_constant
689 0 : { $$ = $1; }
690 : | type_constant_list type_constant
691 : {
692 0 : $$ = $1;
693 0 : append_right ($$, $2);
694 : }
695 : ;
696 :
697 : definitions_id : IDENTIFIER '{' obj_constant_list '}'
698 : {
699 0 : $$ = NEW_NODE (TYPE_OBJECT_ID);
700 0 : set_down ($$, $3);
701 0 : set_name ($$, $1);
702 : }
703 : ;
704 :
705 : imports_def : /* empty */
706 0 : { $$=NULL;}
707 : | IMPORTS identifier_list FROM IDENTIFIER obj_constant_list
708 : {
709 : AsnNode node;
710 :
711 0 : $$ = NEW_NODE (TYPE_IMPORTS);
712 0 : node = NEW_NODE (TYPE_OBJECT_ID);
713 0 : set_name (node, $4);
714 0 : set_down (node, $5);
715 0 : set_down ($$, node);
716 0 : set_right ($$, $2);
717 : }
718 : ;
719 :
720 0 : explicit_implicit : EXPLICIT { $$ = CONST_EXPLICIT; }
721 0 : | IMPLICIT { $$ = CONST_IMPLICIT; }
722 : ;
723 :
724 : definitions: definitions_id
725 : DEFINITIONS explicit_implicit TAGS "::=" ksba_BEGIN imports_def
726 : type_constant_list ksba_END
727 : {
728 : AsnNode node;
729 :
730 0 : $$ = node = NEW_NODE (TYPE_DEFINITIONS);
731 :
732 0 : if ($3 == CONST_EXPLICIT)
733 0 : node->flags.explicit = 1;
734 0 : else if ($3 == CONST_IMPLICIT)
735 0 : node->flags.implicit = 1;
736 :
737 0 : if ($7)
738 0 : node->flags.has_imports = 1;
739 :
740 0 : set_name ($$, $1->name);
741 0 : set_name ($1, "");
742 :
743 0 : if (!node->flags.has_imports)
744 0 : set_right ($1,$8);
745 : else
746 : {
747 0 : set_right ($7,$8);
748 0 : set_right ($1,$7);
749 : }
750 :
751 0 : set_down ($$, $1);
752 :
753 0 : _ksba_asn_set_default_tag ($$);
754 0 : _ksba_asn_type_set_config ($$);
755 0 : PARSECTL->result_parse = _ksba_asn_check_identifier($$);
756 0 : PARSECTL->parse_tree=$$;
757 : }
758 : ;
759 :
760 : %%
761 :
762 :
763 : /*************************************************************/
764 : /* Function: yylex */
765 : /* Description: looks for tokens in file_asn1 pointer file. */
766 : /* Return: int */
767 : /* Token identifier or ASCII code or 0(zero: End Of File) */
768 : /*************************************************************/
769 : static int
770 0 : yylex (YYSTYPE *lvalp, void *parm)
771 : {
772 0 : int c,counter=0,k;
773 : char string[MAX_STRING_LENGTH];
774 : size_t len;
775 0 : FILE *fp = PARSECTL->fp;
776 :
777 0 : if (!PARSECTL->lineno)
778 0 : PARSECTL->lineno++; /* start with line one */
779 :
780 : while (1)
781 : {
782 0 : while ( (c=fgetc (fp))==' ' || c=='\t')
783 : ;
784 0 : if (c =='\n')
785 : {
786 0 : PARSECTL->lineno++;
787 0 : continue;
788 : }
789 0 : if(c==EOF)
790 0 : return 0;
791 :
792 0 : if ( c=='(' || c==')' || c=='[' || c==']'
793 0 : || c=='{' || c=='}' || c==',' || c=='.' || c=='+')
794 0 : return c;
795 :
796 0 : if (c=='-')
797 : {
798 0 : if ( (c=fgetc(fp))!='-')
799 : {
800 0 : ungetc(c,fp);
801 0 : return '-';
802 : }
803 : else
804 : {
805 : /* A comment finishes at the end of line */
806 0 : counter=0;
807 0 : while ( (c=fgetc(fp))!=EOF && c != '\n' )
808 : ;
809 0 : if (c==EOF)
810 0 : return 0;
811 : else
812 0 : continue; /* repeat the search */
813 : }
814 : }
815 :
816 : do
817 : {
818 0 : if (counter >= DIM (string)-1 )
819 : {
820 0 : fprintf (stderr,"%s:%d: token too long\n", "myfile:",
821 : PARSECTL->lineno);
822 0 : return 0; /* EOF */
823 : }
824 0 : string[counter++]=c;
825 : }
826 0 : while ( !((c=fgetc(fp))==EOF
827 0 : || c==' '|| c=='\t' || c=='\n'
828 0 : || c=='(' || c==')' || c=='[' || c==']'
829 0 : || c=='{' || c=='}' || c==',' || c=='.'));
830 :
831 0 : ungetc (c,fp);
832 0 : string[counter]=0;
833 : /*fprintf (stderr, "yylex token `%s'\n", string);*/
834 :
835 : /* Is STRING a number? */
836 0 : for (k=0; k<counter; k++)
837 : {
838 0 : if(!isdigit(string[k]))
839 0 : break;
840 : }
841 0 : if (k>=counter)
842 : {
843 0 : strcpy (lvalp->str,string);
844 0 : if (PARSECTL->debug)
845 0 : fprintf (stderr,"%d: yylex found number `%s'\n",
846 : PARSECTL->lineno, string);
847 0 : return NUM;
848 : }
849 :
850 : /* Is STRING a keyword? */
851 0 : len = strlen (string);
852 0 : for (k = 0; k < YYNTOKENS; k++)
853 : {
854 0 : if (yytname[k] && yytname[k][0] == '\"'
855 0 : && !strncmp (yytname[k] + 1, string, len)
856 0 : && yytname[k][len + 1] == '\"' && !yytname[k][len + 2])
857 0 : return yytoknum[k];
858 : }
859 :
860 : /* STRING is an IDENTIFIER */
861 0 : strcpy(lvalp->str,string);
862 0 : if (PARSECTL->debug)
863 0 : fprintf (stderr,"%d: yylex found identifier `%s'\n",
864 : PARSECTL->lineno, string);
865 0 : return IDENTIFIER;
866 0 : }
867 : }
868 :
869 : static void
870 0 : yyerror (void *parm, const char *s)
871 : {
872 : (void)parm;
873 : /* Sends the error description to stderr */
874 0 : fprintf (stderr, "%s\n", s);
875 : /* Why doesn't bison provide a way to pass the parm to yyerror?
876 : Update: Newer bison versions allow for this. We need to see how
877 : we can make use of it. */
878 0 : }
879 :
880 :
881 :
882 : static AsnNode
883 0 : new_node (struct parser_control_s *parsectl, node_type_t type)
884 : {
885 : AsnNode node;
886 :
887 0 : node = xcalloc (1, sizeof *node);
888 0 : node->type = type;
889 0 : node->off = -1;
890 0 : node->link_next = parsectl->all_nodes;
891 0 : parsectl->all_nodes = node;
892 :
893 0 : return node;
894 : }
895 :
896 : static void
897 27 : release_all_nodes (AsnNode node)
898 : {
899 : AsnNode node2;
900 :
901 3804 : for (; node; node = node2)
902 : {
903 3777 : node2 = node->link_next;
904 3777 : xfree (node->name);
905 :
906 3777 : if (node->valuetype == VALTYPE_CSTR)
907 1545 : xfree (node->value.v_cstr);
908 2232 : else if (node->valuetype == VALTYPE_MEM)
909 0 : xfree (node->value.v_mem.buf);
910 :
911 3777 : xfree (node);
912 : }
913 27 : }
914 :
915 : static void
916 0 : set_name (AsnNode node, const char *name)
917 : {
918 0 : _ksba_asn_set_name (node, name);
919 0 : }
920 :
921 : static void
922 0 : set_str_value (AsnNode node, const char *text)
923 : {
924 0 : if (text && *text)
925 0 : _ksba_asn_set_value (node, VALTYPE_CSTR, text, 0);
926 : else
927 0 : _ksba_asn_set_value (node, VALTYPE_NULL, NULL, 0);
928 0 : }
929 :
930 : static void
931 0 : set_ulong_value (AsnNode node, const char *text)
932 : {
933 : unsigned long val;
934 :
935 0 : if (text && *text)
936 0 : val = strtoul (text, NULL, 10);
937 : else
938 0 : val = 0;
939 0 : _ksba_asn_set_value (node, VALTYPE_ULONG, &val, sizeof(val));
940 0 : }
941 :
942 : static void
943 0 : set_right (AsnNode node, AsnNode right)
944 : {
945 0 : return_if_fail (node);
946 :
947 0 : node->right = right;
948 0 : if (right)
949 0 : right->left = node;
950 : }
951 :
952 : static void
953 0 : append_right (AsnNode node, AsnNode right)
954 : {
955 0 : return_if_fail (node);
956 :
957 0 : while (node->right)
958 0 : node = node->right;
959 :
960 0 : node->right = right;
961 0 : if (right)
962 0 : right->left = node;
963 : }
964 :
965 :
966 : static void
967 0 : set_down (AsnNode node, AsnNode down)
968 : {
969 0 : return_if_fail (node);
970 :
971 0 : node->down = down;
972 0 : if (down)
973 0 : down->left = node;
974 : }
975 :
976 :
977 : /**
978 : * ksba_asn_parse_file:
979 : * @file_name: Filename with the ASN module
980 : * @pointer: Returns the syntax tree
981 : * @debug: Enable debug output
982 : *
983 : * Parse an ASN.1 file and return an syntax tree.
984 : *
985 : * Return value: 0 for okay or an ASN_xx error code
986 : **/
987 : int
988 0 : ksba_asn_parse_file (const char *file_name, ksba_asn_tree_t *result, int debug)
989 : {
990 : struct parser_control_s parsectl;
991 :
992 0 : *result = NULL;
993 :
994 0 : parsectl.fp = file_name? fopen (file_name, "r") : NULL;
995 0 : if ( !parsectl.fp )
996 0 : return gpg_error_from_syserror ();
997 :
998 0 : parsectl.lineno = 0;
999 0 : parsectl.debug = debug;
1000 0 : parsectl.result_parse = gpg_error (GPG_ERR_SYNTAX);
1001 0 : parsectl.parse_tree = NULL;
1002 0 : parsectl.all_nodes = NULL;
1003 : /* yydebug = 1; */
1004 0 : if ( yyparse ((void*)&parsectl) || parsectl.result_parse )
1005 : { /* error */
1006 0 : fprintf (stderr, "%s:%d: parse error\n",
1007 : file_name?file_name:"-", parsectl.lineno );
1008 0 : release_all_nodes (parsectl.all_nodes);
1009 0 : parsectl.all_nodes = NULL;
1010 : }
1011 : else
1012 : { /* okay */
1013 : ksba_asn_tree_t tree;
1014 :
1015 0 : _ksba_asn_change_integer_value (parsectl.parse_tree);
1016 0 : _ksba_asn_expand_object_id (parsectl.parse_tree);
1017 0 : tree = xmalloc ( sizeof *tree + (file_name? strlen (file_name):1) );
1018 0 : tree->parse_tree = parsectl.parse_tree;
1019 0 : tree->node_list = parsectl.all_nodes;
1020 0 : strcpy (tree->filename, file_name? file_name:"-");
1021 0 : *result = tree;
1022 : }
1023 :
1024 0 : if (file_name)
1025 0 : fclose (parsectl.fp);
1026 0 : return parsectl.result_parse;
1027 : }
1028 :
1029 : void
1030 15 : ksba_asn_tree_release (ksba_asn_tree_t tree)
1031 : {
1032 15 : if (!tree)
1033 21 : return;
1034 9 : release_all_nodes (tree->node_list);
1035 9 : tree->node_list = NULL;
1036 9 : xfree (tree);
1037 : }
1038 :
1039 :
1040 : void
1041 18 : _ksba_asn_release_nodes (AsnNode node)
1042 : {
1043 : /* FIXME: it does not work yet because the allocation function in
1044 : asn1-func.c does not link all nodes together */
1045 18 : release_all_nodes (node);
1046 18 : }
|