Fix -I, reported by Bernard Leak <bernard@brenda-arkle.demon.co.uk>.
[libtasn1.git] / src / asn1Coding.c
blob5a7ad07d2325094c2ec5385a24425c54c5e41af2
1 /*
2 * Copyright (C) 2002 Fabio Fiorina
4 * This file is part of LIBTASN1.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * 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, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 * 02110-1301, USA
23 /*****************************************************/
24 /* File: asn1Coding.c */
25 /* Description: program to generate a DER coding */
26 /* of an ASN1 definition. */
27 /*****************************************************/
29 #include <stdio.h>
30 #include <string.h>
31 #include <libtasn1.h>
32 #include <stdlib.h>
33 #include <config.h>
35 #ifdef HAVE_UNISTD_H
36 #include <unistd.h>
37 #endif
39 #ifdef HAVE_GETOPT_H
40 #include <getopt.h>
41 #endif
43 char version_man[] = "asn1Coding (GNU libtasn1) " VERSION;
45 char help_man[] = "asn1Coding generates a DER encoding from a file\n"
46 "with ASN1 definitions and another one with assignments.\n"
47 "\n"
48 "Usage: asn1Coding [options] <file1> <file2>\n"
49 " <file1> file with ASN1 definitions.\n"
50 " <file2> file with assignments.\n"
51 "\n"
52 #ifdef HAVE_GETOPT_LONG
53 "Operation modes:\n"
54 " -h, --help shows this message and exit.\n"
55 " -v, --version shows version information and exit.\n"
56 " -c, --check checks the syntax only.\n"
57 "\n"
58 "Output:\n"
59 " -o <file>, --output <file> output file.\n";
60 #else
61 "Operation modes:\n"
62 " -h shows this message and exit.\n"
63 " -v shows version information and exit.\n"
64 " -c checks the syntax only.\n"
65 "\n"
66 "Output:\n"
67 " -o <file> output file.\n";
68 #endif
71 #define ASSIGNMENT_SUCCESS 1
72 #define ASSIGNMENT_ERROR 2
73 #define ASSIGNMENT_EOF 3
75 int readAssignment(FILE *file,char *varName, char *value){
77 int ret;
79 ret=fscanf(file,"%s",varName);
80 if(ret==EOF) return ASSIGNMENT_EOF;
81 if(!strcmp(varName,"''")) varName[0]=0;
83 ret=fscanf(file,"%s",value);
84 if(ret==EOF) return ASSIGNMENT_ERROR;
86 return ASSIGNMENT_SUCCESS;
91 void createFileName(char *inputFileName, char **outputFileName)
93 char *char_p,*slash_p,*dot_p;
95 /* searching the last '/' and '.' in inputFileAssignmentName */
96 char_p=inputFileName;
97 slash_p=inputFileName;
98 while((char_p=strchr(char_p,'/'))){
99 char_p++;
100 slash_p=char_p;
103 char_p=slash_p;
104 dot_p=inputFileName+strlen(inputFileName);
106 while((char_p=strchr(char_p,'.'))){
107 dot_p=char_p;
108 char_p++;
111 /* outputFileName= inputFileName + .out */
112 *outputFileName=(char *)malloc(dot_p-inputFileName+1+
113 strlen(".out"));
114 memcpy(*outputFileName,inputFileName,
115 dot_p-inputFileName);
116 (*outputFileName)[dot_p-inputFileName]=0;
117 strcat(*outputFileName,".out");
118 return;
122 /********************************************************/
123 /* Function : main */
124 /* Description: */
125 /********************************************************/
127 main(int argc,char *argv[])
130 #ifdef HAVE_GETOPT_LONG
131 static struct option long_options[] =
133 {"help", no_argument, 0, 'h'},
134 {"version", no_argument, 0, 'v'},
135 {"check", no_argument, 0, 'c'},
136 {"output", required_argument, 0, 'o'},
137 {0, 0, 0, 0}
139 int option_index=0;
140 #endif
142 int option_result;
143 char *outputFileName=NULL;
144 char *inputFileAsnName=NULL;
145 char *inputFileAssignmentName=NULL;
146 int checkSyntaxOnly=0;
147 ASN1_TYPE definitions=ASN1_TYPE_EMPTY;
148 ASN1_TYPE structure=ASN1_TYPE_EMPTY;
149 char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
150 int asn1_result=ASN1_SUCCESS;
151 FILE *outputFile;
152 FILE *inputFile;
153 char varName[1024];
154 char value[1024];
155 unsigned char der[1024];
156 int der_len;
157 int k;
159 opterr=0; /* disable error messages from getopt */
161 printf("\n");
163 while(1){
165 #ifdef HAVE_GETOPT_LONG
166 option_result=getopt_long(argc,argv,"hvco:",long_options,&option_index);
167 #else
168 option_result=getopt(argc,argv,"hvco:");
169 #endif
171 if(option_result == -1) break;
173 switch(option_result){
174 case 'h': /* HELP */
175 printf("%s\n",help_man);
177 if(outputFileName) free(outputFileName);
178 exit(0);
179 break;
180 case 'v': /* VERSION */
181 printf("%s\n",version_man);
183 if(outputFileName) free(outputFileName);
184 exit(0);
185 break;
186 case 'c': /* CHECK SYNTAX */
187 checkSyntaxOnly = 1;
188 break;
189 case 'o': /* OUTPUT */
190 outputFileName=(char *)malloc(strlen(optarg)+1);
191 strcpy(outputFileName,optarg);
192 break;
193 case '?': /* UNKNOW OPTION */
194 fprintf(stderr,"asn1Coding: option '%s' not recognized or without argument.\n\n",argv[optind-1]);
195 printf("%s\n",help_man);
197 if(outputFileName) free(outputFileName);
198 exit(1);
199 break;
200 default:
201 fprintf(stderr,"asn1Coding: ?? getopt returned character code Ox%x ??\n",option_result);
205 if(optind == argc){
206 fprintf(stderr,"asn1Coding: input file with ASN1 definitions missing.\n");
207 fprintf(stderr," input file with assignments missing.\n\n");
208 printf("%s\n",help_man);
210 if(outputFileName) free(outputFileName);
211 exit(1);
214 if(optind == argc-1){
215 fprintf(stderr,"asn1Coding: input file with assignments missing.\n\n");
216 printf("%s\n",help_man);
218 if(outputFileName) free(outputFileName);
219 exit(1);
222 inputFileAsnName=(char *)malloc(strlen(argv[optind])+1);
223 strcpy(inputFileAsnName,argv[optind]);
225 inputFileAssignmentName=(char *)malloc(strlen(argv[optind+1])+1);
226 strcpy(inputFileAssignmentName,argv[optind+1]);
228 asn1_result=asn1_parser2tree(inputFileAsnName,&definitions,errorDescription);
230 switch(asn1_result){
231 case ASN1_SUCCESS:
232 printf("Parse: done.\n");
233 break;
234 case ASN1_FILE_NOT_FOUND:
235 printf("asn1Coding: FILE %s NOT FOUND\n",inputFileAsnName);
236 break;
237 case ASN1_SYNTAX_ERROR:
238 case ASN1_IDENTIFIER_NOT_FOUND:
239 case ASN1_NAME_TOO_LONG:
240 printf("asn1Coding: %s\n",errorDescription);
241 break;
242 default:
243 printf("libtasn1 ERROR: %s\n",libtasn1_strerror(asn1_result));
246 if(asn1_result != ASN1_SUCCESS){
247 free(inputFileAsnName);
248 free(inputFileAssignmentName);
249 exit(1);
253 inputFile=fopen(inputFileAssignmentName,"r");
255 if(inputFile==NULL){
256 printf("asn1Coding: file '%s' not found\n",inputFileAssignmentName);
257 free(inputFileAsnName);
258 free(inputFileAssignmentName);
259 exit(1);
263 printf("\n");
265 while(readAssignment(inputFile,varName,value) == ASSIGNMENT_SUCCESS){
266 printf("var=%s, value=%s\n",varName,value);
267 if(structure==ASN1_TYPE_EMPTY){
268 asn1_result=asn1_create_element(definitions,value,&structure);
270 else
271 asn1_result=asn1_write_value(structure,varName,value,0);
273 if(asn1_result != ASN1_SUCCESS){
274 printf("libtasn1 ERROR: %s\n",libtasn1_strerror(asn1_result));
276 asn1_delete_structure(&definitions);
277 asn1_delete_structure(&structure);
279 free(inputFileAsnName);
280 free(inputFileAssignmentName);
282 fclose(inputFile);
283 exit(1);
286 fclose(inputFile);
288 printf("\n");
289 asn1_print_structure(stdout,structure,"",ASN1_PRINT_NAME_TYPE_VALUE);
291 der_len=1024;
292 asn1_result=asn1_der_coding(structure,"",der,&der_len,
293 errorDescription);
294 printf("\nCoding: %s\n\n",libtasn1_strerror(asn1_result));
295 if(asn1_result!=ASN1_SUCCESS){
296 printf("asn1Coding: %s\n",errorDescription);
298 asn1_delete_structure(&definitions);
299 asn1_delete_structure(&structure);
301 free(inputFileAsnName);
302 free(inputFileAssignmentName);
304 exit(1);
307 /* Print the 'Certificate1' DER encoding */
308 printf("-----------------\nNumber of bytes=%i\n",der_len);
309 for(k=0;k<der_len;k++) printf("%02x ",der[k]);
310 printf("\n-----------------\n");
312 asn1_delete_structure(&definitions);
313 asn1_delete_structure(&structure);
316 if(outputFileName==NULL)
317 createFileName(inputFileAssignmentName,&outputFileName);
319 printf("\nOutputFile=%s\n",outputFileName);
321 outputFile=fopen(outputFileName,"w");
323 if(outputFile==NULL){
324 printf("asn1Coding: output file '%s' not available\n",outputFileName);
325 free(inputFileAsnName);
326 free(inputFileAssignmentName);
327 free(outputFileName);
328 exit(1);
331 for(k=0;k<der_len;k++)
332 fprintf(outputFile,"%c",der[k]);
333 fclose(outputFile);
334 printf("\nWriting: done.\n");
337 free(inputFileAsnName);
338 free(inputFileAssignmentName);
339 free(outputFileName);
341 exit(0);