1 /* asn1Coding.c --- program to generate a DER coding of an ASN1 definition.
2 * Copyright (C) 2002-2022 Free Software Foundation, Inc.
4 * This file is part of LIBTASN1.
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
33 #include "version-etc.h"
35 /* This feature is available in gcc versions 2.5 and later. */
36 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
37 # define ATTR_NO_RETRUN
39 # define ATTR_NO_RETRUN __attribute__ ((__noreturn__))
42 ATTR_NO_RETRUN static void
45 if (status != EXIT_SUCCESS)
46 fprintf (stderr, "Try `%s --help' for more information.\n", program_name);
50 Usage: %s [OPTION] DEFINITIONS ASSIGNMENTS\n", program_name);
52 Generates a DER encoding of ASN.1 DEFINITIONS file\n\
53 and ASSIGNMENTS file with value assignments.\n\
56 Mandatory arguments to long options are mandatory for short options too.\n\
57 -c, --check checks the syntax only\n\
58 -o, --output=FILE output file\n\
59 -h, --help display this help and exit\n\
60 -v, --version output version information and exit\n");
61 emit_bug_reporting_address ();
66 #define ASSIGNMENT_SUCCESS 1
67 #define ASSIGNMENT_ERROR 2
68 #define ASSIGNMENT_EOF 3
71 readAssignment (FILE * file, char *varName, char *value)
76 ret = fscanf (file, "%1023s", varName);
78 return ASSIGNMENT_EOF;
79 if (!strcmp (varName, "''"))
82 ret = fscanf (file, "%1023s", value);
84 return ASSIGNMENT_ERROR;
86 return ASSIGNMENT_SUCCESS;
90 createFileName (char *inputFileName, char **outputFileName)
92 char *char_p, *slash_p, *dot_p;
94 /* searching the last '/' and '.' in inputFileAssignmentName */
95 char_p = inputFileName;
96 slash_p = inputFileName;
97 while ((char_p = strchr (char_p, '/')))
104 dot_p = inputFileName + strlen (inputFileName);
106 while ((char_p = strchr (char_p, '.')))
112 /* outputFileName= inputFileName + .out */
113 *outputFileName = (char *) malloc (dot_p - inputFileName + 1 +
115 if (*outputFileName == NULL)
117 fprintf (stderr, "Memory error\n");
121 memcpy (*outputFileName, inputFileName, dot_p - inputFileName);
122 (*outputFileName)[dot_p - inputFileName] = 0;
123 strcat (*outputFileName, ".out");
128 main (int argc, char *argv[])
130 static const struct option long_options[] = {
131 {"help", no_argument, 0, 'h'},
132 {"version", no_argument, 0, 'v'},
133 {"check", no_argument, 0, 'c'},
134 {"output", required_argument, 0, 'o'},
137 int option_index = 0;
139 char *outputFileName = NULL;
140 char *inputFileAsnName = NULL;
141 char *inputFileAssignmentName = NULL;
142 int checkSyntaxOnly = 0;
143 asn1_node definitions = NULL;
144 asn1_node structure = NULL;
145 char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
146 int asn1_result = ASN1_SUCCESS;
151 unsigned char *der = NULL;
156 set_program_name (argv[0]);
158 opterr = 0; /* disable error messages from getopt */
164 getopt_long (argc, argv, "hvco:", long_options, &option_index);
166 if (option_result == -1)
169 switch (option_result)
172 free (outputFileName);
173 usage (EXIT_SUCCESS);
175 case 'v': /* VERSION */
176 version_etc (stdout, program_name, PACKAGE, VERSION,
177 "Fabio Fiorina", NULL);
178 free (outputFileName);
181 case 'c': /* CHECK SYNTAX */
184 case 'o': /* OUTPUT */
185 assert (optarg != NULL);
186 outputFileName = strdup (optarg);
187 if (outputFileName == NULL)
189 fprintf (stderr, "Memory error\n");
193 case '?': /* UNKNOW OPTION */
194 free (outputFileName);
196 "asn1Coding: option '%s' not recognized or without argument.\n\n",
198 usage (EXIT_FAILURE);
202 "asn1Coding: ?? getopt returned character code Ox%x ??\n",
203 (unsigned) option_result);
207 if (optind == argc || optind == argc - 1)
209 free (outputFileName);
210 fputs ("asn1Coding: input files missing\n", stderr);
211 usage (EXIT_FAILURE);
214 inputFileAsnName = strdup (argv[optind]);
215 if (inputFileAsnName == NULL)
217 fprintf (stderr, "Memory error\n");
221 inputFileAssignmentName = strdup (argv[optind + 1]);
222 if (inputFileAssignmentName == NULL)
224 fprintf (stderr, "Memory error\n");
229 asn1_parser2tree (inputFileAsnName, &definitions, errorDescription);
234 fputs ("Parse: done.\n", stderr);
236 case ASN1_FILE_NOT_FOUND:
237 fprintf (stderr, "asn1Coding: FILE %s NOT FOUND\n", inputFileAsnName);
239 case ASN1_SYNTAX_ERROR:
240 case ASN1_IDENTIFIER_NOT_FOUND:
241 case ASN1_NAME_TOO_LONG:
242 fprintf (stderr, "asn1Coding: %s\n", errorDescription);
245 fprintf (stderr, "libtasn1 ERROR: %s\n", asn1_strerror (asn1_result));
248 if (asn1_result != ASN1_SUCCESS)
250 free (inputFileAsnName);
251 free (inputFileAssignmentName);
256 inputFile = fopen (inputFileAssignmentName, "r");
258 if (inputFile == NULL)
260 fprintf (stderr, "asn1Coding: file '%s' not found\n",
261 inputFileAssignmentName);
262 free (inputFileAsnName);
263 free (inputFileAssignmentName);
270 while ((last_ra = readAssignment (inputFile, varName, value))
271 == ASSIGNMENT_SUCCESS)
273 fprintf (stderr, "var=%s, value=%s\n", varName, value);
274 if (structure == NULL)
276 asn1_result = asn1_create_element (definitions, value, &structure);
280 if (strcmp (value, "(NULL)") == 0)
281 asn1_result = asn1_write_value (structure, varName, NULL, 0);
283 asn1_result = asn1_write_value (structure, varName, value, 0);
286 if (asn1_result != ASN1_SUCCESS)
288 fprintf (stderr, "libtasn1 ERROR: %s\n",
289 asn1_strerror (asn1_result));
291 asn1_delete_structure (&definitions);
292 asn1_delete_structure (&structure);
294 free (inputFileAsnName);
295 free (inputFileAssignmentName);
301 if (last_ra != ASSIGNMENT_EOF)
303 fprintf (stderr, "asn1Coding: error reading assignment file\n");
309 asn1_print_structure (stderr, structure, "", ASN1_PRINT_NAME_TYPE_VALUE);
312 asn1_result = asn1_der_coding (structure, "", NULL, &der_len,
314 if (asn1_result == ASN1_MEM_ERROR)
316 der = malloc (der_len);
319 fprintf (stderr, "Memory error\n");
322 asn1_result = asn1_der_coding (structure, "", der, &der_len,
325 fprintf (stderr, "\nCoding: %s\n\n", asn1_strerror (asn1_result));
326 if (asn1_result != ASN1_SUCCESS)
328 fprintf (stderr, "asn1Coding: %s\n", errorDescription);
332 asn1_delete_structure (&definitions);
333 asn1_delete_structure (&structure);
335 free (inputFileAsnName);
336 free (inputFileAssignmentName);
341 /* Print the 'Certificate1' DER encoding */
342 fprintf (stderr, "-----------------\nNumber of bytes=%i\n", der_len);
343 for (k = 0; k < der_len; k++)
344 fprintf (stderr, "%02x ", der[k]);
345 fputs ("\n-----------------\n", stderr);
347 asn1_delete_structure (&definitions);
348 asn1_delete_structure (&structure);
350 if (!checkSyntaxOnly)
352 if (outputFileName == NULL)
353 createFileName (inputFileAssignmentName, &outputFileName);
355 fprintf (stderr, "\nOutputFile=%s\n", outputFileName);
357 outputFile = fopen (outputFileName, "w");
359 if (outputFile == NULL)
362 "asn1Coding: output file '%s' not available\n",
365 free (inputFileAsnName);
366 free (inputFileAssignmentName);
367 free (outputFileName);
371 for (k = 0; k < der_len; k++)
372 fprintf (outputFile, "%c", der[k]);
374 fputs ("\nWriting: done.\n", stderr);
379 free (inputFileAsnName);
380 free (inputFileAssignmentName);
381 free (outputFileName);