summaryrefslogtreecommitdiff
path: root/lib/ASN1.y
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ASN1.y')
-rw-r--r--lib/ASN1.y348
1 files changed, 174 insertions, 174 deletions
diff --git a/lib/ASN1.y b/lib/ASN1.y
index cd783fe..a8c9718 100644
--- a/lib/ASN1.y
+++ b/lib/ASN1.y
@@ -1,6 +1,6 @@
%{
/*
- * Copyright (C) 2001-2014 Free Software Foundation, Inc.
+ * Copyright (C) 2001-2022 Free Software Foundation, Inc.
*
* This file is part of LIBTASN1.
*
@@ -31,6 +31,7 @@
#include <parser_aux.h>
#include <structure.h>
#include <libtasn1.h>
+#include "c-ctype.h"
static list_type *e_list = NULL;
static FILE *file_asn1; /* Pointer to file to parse */
@@ -53,6 +54,9 @@ static const char *file_name; /* file to parse */
static void _asn1_yyerror (const char *);
static int _asn1_yylex(void);
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+#define SAFE_COPY(dst, dst_size, fmt, ...) { snprintf(dst, dst_size, fmt, __VA_ARGS__); }
+#else
#define SAFE_COPY(dst, dst_size, fmt, ...) { \
int _ret = snprintf(dst, dst_size, fmt, __VA_ARGS__); \
if (_ret != (int)strlen(dst)) \
@@ -62,12 +66,13 @@ static int _asn1_yylex(void);
exit(1); \
} \
}
+#endif
%}
/* Prefix symbols and functions with _asn1_ */
/* %define parse.lac full */
-%error-verbose
-%name-prefix "_asn1_yy"
+%define parse.error verbose
+%define api.prefix {_asn1_yy}
%union {
unsigned int constant;
@@ -138,6 +143,7 @@ static int _asn1_yylex(void);
%type <str> num_identifier
%type <str> int_identifier
%type <constant> class explicit_implicit
+%type <str> known_string
%%
@@ -234,12 +240,9 @@ pos_neg_list: pos_neg_num
integer_def: INTEGER {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_INTEGER);}
| INTEGER'{'constant_list'}' {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_INTEGER|CONST_LIST);
_asn1_set_down($$,$3);}
- | integer_def'(' pos_neg_list ')' {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_INTEGER);}
+ | integer_def'(' pos_neg_list ')' {$$=$1;}
| integer_def'('int_identifier'.''.'int_identifier')'
- {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_INTEGER|CONST_MIN_MAX);
- _asn1_set_down($$,_asn1_add_static_node(&e_list, ASN1_ETYPE_SIZE));
- _asn1_set_value(_asn1_get_down($$),$6,strlen($6)+1);
- _asn1_set_name(_asn1_get_down($$),$3);}
+ {$$=$1;}
;
boolean_def: BOOLEAN {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_BOOLEAN);}
@@ -322,7 +325,8 @@ bit_element_list : bit_element {$$=$1;}
;
bit_string_def : BIT STRING {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_BIT_STRING);}
- | BIT STRING size_def {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_BIT_STRING|CONST_SIZE);}
+ | BIT STRING size_def {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_BIT_STRING|CONST_SIZE);
+ _asn1_set_down($$,$3);}
| BIT STRING'{'bit_element_list'}'
{$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_BIT_STRING|CONST_LIST);
_asn1_set_down($$,$4);}
@@ -414,9 +418,24 @@ any_def : ANY {$$=_asn1_add_static_node(&e_list, ASN1_E
_asn1_set_name(_asn1_get_down($$),$4);}
;
-type_def : IDENTIFIER "::=" type_assig_right_tag {$$=_asn1_set_name($3,$1);}
- /* below should match: BMPString ::= [UNIVERSAL 30] IMPLICIT OCTET STRING etc*/
- | error "::=" type_assig_right_tag {$$=_asn1_set_name($3, last_error_token);}
+known_string: UTF8String { SAFE_COPY($$,sizeof($$),"%s",last_token); }
+ | VisibleString { SAFE_COPY($$,sizeof($$),"%s",last_token); }
+ | PrintableString { SAFE_COPY($$,sizeof($$),"%s",last_token); }
+ | UniversalString { SAFE_COPY($$,sizeof($$),"%s",last_token); }
+ | IA5String { SAFE_COPY($$,sizeof($$),"%s",last_token); }
+ | NumericString { SAFE_COPY($$,sizeof($$),"%s",last_token); }
+ | TeletexString { SAFE_COPY($$,sizeof($$),"%s",last_token); }
+ | BMPString { SAFE_COPY($$,sizeof($$),"%s",last_token); }
+
+/* This matches build-in types which are redefined */
+type_invalid : known_string "::=" '[' class NUM ']' IMPLICIT OCTET STRING {
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ fprintf(stderr, "%s:%u: Warning: %s is a built-in ASN.1 type.\n", file_name, line_number, $1);
+#endif
+}
+;
+
+type_def : IDENTIFIER "::=" type_assig_right_tag { $$=_asn1_set_name($3,$1);}
;
constant_def : IDENTIFIER OBJECT STR_IDENTIFIER "::=" '{'obj_constant_list'}'
@@ -435,12 +454,20 @@ constant_def : IDENTIFIER OBJECT STR_IDENTIFIER "::=" '{'obj_constant_list'}'
;
type_constant: type_def {$$=$1;}
+ | type_invalid {$$=NULL;}
| constant_def {$$=$1;}
;
type_constant_list : type_constant {$$=$1;}
- | type_constant_list type_constant {$$=$1;
- _asn1_set_right(_asn1_get_last_right($1),$2);}
+ | type_constant_list type_constant {if (!$1)
+ {
+ $$ = $2;
+ }
+ else
+ {
+ $$=$1;
+ if ($2) _asn1_set_right(_asn1_get_last_right($1),$2);
+ }}
;
definitions_id : IDENTIFIER '{' obj_constant_list '}' {$$=_asn1_add_static_node(&e_list, ASN1_ETYPE_OBJECT_ID);
@@ -509,7 +536,7 @@ static const int key_word_token[] = {
/* Token identifier or ASCII code or 0(zero: End Of File) */
/*************************************************************/
static int
-_asn1_yylex ()
+_asn1_yylex (void)
{
int c, counter = 0, k, lastc;
char string[ASN1_MAX_NAME_SIZE + 1]; /* will contain the next token */
@@ -565,7 +592,7 @@ _asn1_yylex ()
}
}
}
- string[counter++] = c;
+ string[counter++] = (char) c;
/* Till the end of the token */
while (!
((c = fgetc (file_asn1)) == EOF || c == ' ' || c == '\t'
@@ -577,7 +604,7 @@ _asn1_yylex ()
result_parse = ASN1_NAME_TOO_LONG;
return 0;
}
- string[counter++] = c;
+ string[counter++] = (char) c;
}
ungetc (c, file_asn1);
string[counter] = 0;
@@ -585,7 +612,7 @@ _asn1_yylex ()
/* Is STRING a number? */
for (k = 0; k < counter; k++)
- if (!isdigit ((int)string[k]))
+ if (!c_isdigit ((int)string[k]))
break;
if (k >= counter)
{
@@ -663,20 +690,18 @@ _asn1_create_errorDescription (int error, char *error_desc)
* opening @file, %ASN1_SYNTAX_ERROR if the syntax is not
* correct, %ASN1_IDENTIFIER_NOT_FOUND if in the file there is an
* identifier that is not defined, %ASN1_NAME_TOO_LONG if in the
- * file there is an identifier whith more than %ASN1_MAX_NAME_SIZE
+ * file there is an identifier with more than %ASN1_MAX_NAME_SIZE
* characters.
**/
int
asn1_parser2tree (const char *file, asn1_node * definitions,
char *error_desc)
{
-
- p_tree = NULL;
-
if (*definitions != NULL)
- return ASN1_ELEMENT_NOT_EMPTY;
-
- *definitions = NULL;
+ {
+ result_parse = ASN1_ELEMENT_NOT_EMPTY;
+ goto error;
+ }
file_name = file;
@@ -686,54 +711,48 @@ asn1_parser2tree (const char *file, asn1_node * definitions,
if (file_asn1 == NULL)
{
result_parse = ASN1_FILE_NOT_FOUND;
- }
- else
- {
- result_parse = ASN1_SUCCESS;
-
- line_number = 1;
- yyparse ();
-
- fclose (file_asn1);
-
- if (result_parse == ASN1_SUCCESS)
- { /* syntax OK */
- /* set IMPLICIT or EXPLICIT property */
- _asn1_set_default_tag (p_tree);
- /* set CONST_SET and CONST_NOT_USED */
- _asn1_type_set_config (p_tree);
- /* check the identifier definitions */
- result_parse = _asn1_check_identifier (p_tree);
- if (result_parse == ASN1_SUCCESS)
- { /* all identifier defined */
- /* Delete the list and keep the ASN1 structure */
- _asn1_delete_list (e_list);
- e_list = NULL;
- /* Convert into DER coding the value assign to INTEGER constants */
- _asn1_change_integer_value (p_tree);
- /* Expand the IDs of OBJECT IDENTIFIER constants */
- result_parse = _asn1_expand_object_id (e_list, p_tree);
- if (result_parse != ASN1_SUCCESS)
- goto error;
-
- *definitions = p_tree;
- }
- else /* some identifiers not defined */
- {
- /* Delete the list and the ASN1 structure */
- _asn1_delete_list_and_nodes (e_list);
- e_list = NULL;
- }
- }
- else /* syntax error */
- {
- /* Delete the list and the ASN1 structure */
- _asn1_delete_list_and_nodes (e_list);
- e_list = NULL;
- }
+ goto error;
}
- error:
+ result_parse = ASN1_SUCCESS;
+
+ line_number = 1;
+ yyparse ();
+
+ fclose (file_asn1);
+
+ if (result_parse != ASN1_SUCCESS)
+ goto error;
+
+ /* set IMPLICIT or EXPLICIT property */
+ _asn1_set_default_tag (p_tree);
+ /* set CONST_SET and CONST_NOT_USED */
+ _asn1_type_set_config (p_tree);
+ /* check the identifier definitions */
+ result_parse = _asn1_check_identifier (p_tree);
+ if (result_parse != ASN1_SUCCESS)
+ goto error;
+
+ /* Convert into DER coding the value assign to INTEGER constants */
+ _asn1_change_integer_value (p_tree);
+ /* Expand the IDs of OBJECT IDENTIFIER constants */
+ result_parse = _asn1_expand_object_id (&e_list, p_tree);
+ if (result_parse != ASN1_SUCCESS)
+ goto error;
+
+ /* success */
+ *definitions = p_tree;
+ _asn1_delete_list (e_list);
+ e_list = NULL;
+ p_tree = NULL;
+ *error_desc = 0;
+ return result_parse;
+
+error:
+ _asn1_delete_list_and_nodes (e_list);
+ e_list = NULL;
+ p_tree = NULL;
+
_asn1_create_errorDescription (result_parse, error_desc);
return result_parse;
@@ -761,7 +780,7 @@ asn1_parser2tree (const char *file, asn1_node * definitions,
* while opening @inputFileName, %ASN1_SYNTAX_ERROR if the syntax is
* not correct, %ASN1_IDENTIFIER_NOT_FOUND if in the file there is
* an identifier that is not defined, %ASN1_NAME_TOO_LONG if in the
- * file there is an identifier whith more than %ASN1_MAX_NAME_SIZE
+ * file there is an identifier with more than %ASN1_MAX_NAME_SIZE
* characters.
**/
int
@@ -780,102 +799,99 @@ asn1_parser2array (const char *inputFileName, const char *outputFileName,
file_asn1 = fopen (inputFileName, "r");
if (file_asn1 == NULL)
- result_parse = ASN1_FILE_NOT_FOUND;
- else
{
- result_parse = ASN1_SUCCESS;
-
- line_number = 1;
- yyparse ();
-
- fclose (file_asn1);
-
- if (result_parse == ASN1_SUCCESS)
- { /* syntax OK */
- /* set IMPLICIT or EXPLICIT property */
- _asn1_set_default_tag (p_tree);
- /* set CONST_SET and CONST_NOT_USED */
- _asn1_type_set_config (p_tree);
- /* check the identifier definitions */
- result_parse = _asn1_check_identifier (p_tree);
-
- if (result_parse == ASN1_SUCCESS)
- { /* all identifier defined */
+ result_parse = ASN1_FILE_NOT_FOUND;
+ goto error2;
+ }
- /* searching the last '/' and '.' in inputFileName */
- char_p = inputFileName;
- slash_p = inputFileName;
- while ((char_p = strchr (char_p, '/')))
- {
- char_p++;
- slash_p = char_p;
- }
+ result_parse = ASN1_SUCCESS;
+
+ line_number = 1;
+ yyparse ();
+
+ fclose (file_asn1);
+ if (result_parse != ASN1_SUCCESS)
+ goto error1;
+
+ /* set IMPLICIT or EXPLICIT property */
+ _asn1_set_default_tag (p_tree);
+ /* set CONST_SET and CONST_NOT_USED */
+ _asn1_type_set_config (p_tree);
+ /* check the identifier definitions */
+ result_parse = _asn1_check_identifier (p_tree);
+ if (result_parse != ASN1_SUCCESS)
+ goto error2;
+
+ /* all identifier defined */
+ /* searching the last '/' and '.' in inputFileName */
+ char_p = inputFileName;
+ slash_p = inputFileName;
+ while ((char_p = strchr (char_p, '/')))
+ {
+ char_p++;
+ slash_p = char_p;
+ }
- char_p = slash_p;
- dot_p = inputFileName + strlen (inputFileName);
+ char_p = slash_p;
+ dot_p = inputFileName + strlen (inputFileName);
- while ((char_p = strchr (char_p, '.')))
- {
- dot_p = char_p;
- char_p++;
- }
+ while ((char_p = strchr (char_p, '.')))
+ {
+ dot_p = char_p;
+ char_p++;
+ }
- if (outputFileName == NULL)
- {
- /* file_out_name = inputFileName + _asn1_tab.c */
- file_out_name = malloc (dot_p - inputFileName + 1 +
- sizeof ("_asn1_tab.c")-1);
- memcpy (file_out_name, inputFileName,
- dot_p - inputFileName);
- file_out_name[dot_p - inputFileName] = 0;
- strcat (file_out_name, "_asn1_tab.c");
- }
- else
- {
- /* file_out_name = inputFileName */
- file_out_name =
- (char *) malloc (strlen (outputFileName) + 1);
- strcpy (file_out_name, outputFileName);
- }
+ if (outputFileName == NULL)
+ {
+ /* file_out_name = inputFileName + _asn1_tab.c */
+ file_out_name = malloc (dot_p - inputFileName + 1 +
+ sizeof ("_asn1_tab.c")-1);
+ memcpy (file_out_name, inputFileName,
+ dot_p - inputFileName);
+ file_out_name[dot_p - inputFileName] = 0;
+ strcat (file_out_name, "_asn1_tab.c");
+ }
+ else
+ {
+ /* file_out_name = inputFileName */
+ file_out_name = strdup(outputFileName);
+ }
- if (vectorName == NULL)
- {
- unsigned len, i;
- /* vector_name = file name + _asn1_tab */
- vector_name = malloc (dot_p - slash_p + 1 +
- sizeof("_asn1_tab") - 1);
- memcpy (vector_name, slash_p, dot_p - slash_p);
- vector_name[dot_p - slash_p] = 0;
- strcat (vector_name, "_asn1_tab");
-
- len = strlen(vector_name);
- for (i=0;i<len;i++)
- {
- if (vector_name[i] == '-')
- vector_name[i] = '_';
- }
- }
- else
- {
- /* vector_name = vectorName */
- vector_name = (char *) malloc (strlen (vectorName) + 1);
- strcpy (vector_name, vectorName);
- }
+ if (vectorName == NULL)
+ {
+ unsigned len, i;
+ /* vector_name = file name + _asn1_tab */
+ vector_name = malloc (dot_p - slash_p + 1 +
+ sizeof("_asn1_tab") - 1);
+ memcpy (vector_name, slash_p, dot_p - slash_p);
+ vector_name[dot_p - slash_p] = 0;
+ strcat (vector_name, "_asn1_tab");
+
+ len = strlen(vector_name);
+ for (i=0;i<len;i++)
+ {
+ if (vector_name[i] == '-')
+ vector_name[i] = '_';
+ }
+ }
+ else
+ {
+ /* vector_name = vectorName */
+ vector_name = strdup(vectorName);
+ }
- /* Save structure in a file */
- _asn1_create_static_structure (p_tree,
- file_out_name, vector_name);
+ /* Save structure in a file */
+ _asn1_create_static_structure (p_tree,
+ file_out_name, vector_name);
- free (file_out_name);
- free (vector_name);
- } /* result == OK */
- } /* result == OK */
+ free (file_out_name);
+ free (vector_name);
- /* Delete the list and the ASN1 structure */
- _asn1_delete_list_and_nodes (e_list);
- e_list = NULL;
- } /* inputFile exist */
+ error1:
+ _asn1_delete_list_and_nodes (e_list);
+ e_list = NULL;
+ error2:
_asn1_create_errorDescription (result_parse, error_desc);
return result_parse;
@@ -893,22 +909,6 @@ static void
_asn1_yyerror (const char *s)
{
/* Sends the error description to the std_out */
-
- if (strcmp (last_token, "VisibleString") == 0 ||
- strcmp (last_token, "PrintableString") == 0 ||
- strcmp (last_token, "UniversalString") == 0 ||
- strcmp (last_token, "IA5String") == 0 ||
- strcmp (last_token, "UTF8String") == 0 ||
- strcmp (last_token, "NumericString") == 0 ||
- strcmp (last_token, "TeletexString") == 0 ||
- strcmp (last_token, "BMPString") == 0)
- {
- snprintf (last_error_token, sizeof(last_error_token),
- "%s", last_token);
- fprintf(stderr, "%s:%u: Warning: %s is a built-in ASN.1 type.\n",
- file_name, line_number, last_token);
- return;
- }
last_error_token[0] = 0;
if (result_parse != ASN1_NAME_TOO_LONG)