xref: /freebsd/crypto/heimdal/lib/asn1/asn1_print.c (revision 1e413cf93298b5b97441a21d9a50fdcd0ee9945e)
1 /*
2  * Copyright (c) 1997 - 2002 Kungliga Tekniska H�gskolan
3  * (Royal Institute of Technology, Stockholm, Sweden).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of the Institute nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 #include "der_locl.h"
35 #include <com_err.h>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #include <getarg.h>
39 #include <err.h>
40 
41 RCSID("$Id: asn1_print.c,v 1.11 2002/08/29 20:45:35 assar Exp $");
42 
43 const char *class_names[] = {
44     "UNIV",			/* 0 */
45     "APPL",			/* 1 */
46     "CONTEXT",			/* 2 */
47     "PRIVATE"			/* 3 */
48 };
49 
50 const char *type_names[] = {
51     "PRIM",			/* 0 */
52     "CONS"			/* 1 */
53 };
54 
55 const char *tag_names[] = {
56     NULL,			/* 0 */
57     NULL,			/* 1 */
58     "Integer",			/* 2 */
59     "BitString",		/* 3 */
60     "OctetString",		/* 4 */
61     "Null",			/* 5 */
62     "ObjectID",			/* 6 */
63     NULL,			/* 7 */
64     NULL,			/* 8 */
65     NULL,			/* 9 */
66     NULL,			/* 10 */
67     NULL,			/* 11 */
68     NULL,			/* 12 */
69     NULL,			/* 13 */
70     NULL,			/* 14 */
71     NULL,			/* 15 */
72     "Sequence",			/* 16 */
73     "Set",			/* 17 */
74     NULL,			/* 18 */
75     "PrintableString",		/* 19 */
76     NULL,			/* 20 */
77     NULL,			/* 21 */
78     "IA5String",		/* 22 */
79     "UTCTime",			/* 23 */
80     "GeneralizedTime",		/* 24 */
81     NULL,			/* 25 */
82     "VisibleString",		/* 26 */
83     "GeneralString"		/* 27 */
84 };
85 
86 static int
87 loop (unsigned char *buf, size_t len, int indent)
88 {
89     while (len > 0) {
90 	int ret;
91 	Der_class class;
92 	Der_type type;
93 	int tag;
94 	size_t sz;
95 	size_t length;
96 	int i;
97 
98 	ret = der_get_tag (buf, len, &class, &type, &tag, &sz);
99 	if (ret)
100 	    errx (1, "der_get_tag: %s", error_message (ret));
101 	if (sz > len)
102 	    errx (1, "unreasonable length (%u) > %u",
103 		  (unsigned)sz, (unsigned)len);
104 	buf += sz;
105 	len -= sz;
106 	for (i = 0; i < indent; ++i)
107 	    printf (" ");
108 	printf ("%s %s ", class_names[class], type_names[type]);
109 	if (tag_names[tag])
110 	    printf ("%s = ", tag_names[tag]);
111 	else
112 	    printf ("tag %d = ", tag);
113 	ret = der_get_length (buf, len, &length, &sz);
114 	if (ret)
115 	    errx (1, "der_get_tag: %s", error_message (ret));
116 	buf += sz;
117 	len -= sz;
118 
119 	if (class == CONTEXT) {
120 	    printf ("[%d]\n", tag);
121 	    loop (buf, length, indent);
122 	} else if (class == UNIV) {
123 	    switch (tag) {
124 	    case UT_Sequence :
125 		printf ("{\n");
126 		loop (buf, length, indent + 2);
127 		for (i = 0; i < indent; ++i)
128 		    printf (" ");
129 		printf ("}\n");
130 		break;
131 	    case UT_Integer : {
132 		int val;
133 
134 		ret = der_get_int (buf, length, &val, NULL);
135 		if (ret)
136 		    errx (1, "der_get_int: %s", error_message (ret));
137 		printf ("integer %d\n", val);
138 		break;
139 	    }
140 	    case UT_OctetString : {
141 		octet_string str;
142 		int i;
143 		unsigned char *uc;
144 
145 		ret = der_get_octet_string (buf, length, &str, NULL);
146 		if (ret)
147 		    errx (1, "der_get_octet_string: %s", error_message (ret));
148 		printf ("(length %lu), ", (unsigned long)length);
149 		uc = (unsigned char *)str.data;
150 		for (i = 0; i < 16; ++i)
151 		    printf ("%02x", uc[i]);
152 		printf ("\n");
153 		free (str.data);
154 		break;
155 	    }
156 	    case UT_GeneralizedTime :
157 	    case UT_GeneralString : {
158 		general_string str;
159 
160 		ret = der_get_general_string (buf, length, &str, NULL);
161 		if (ret)
162 		    errx (1, "der_get_general_string: %s",
163 			  error_message (ret));
164 		printf ("\"%s\"\n", str);
165 		free (str);
166 		break;
167 	    }
168 	    case UT_OID: {
169 		oid o;
170 		int i;
171 
172 		ret = der_get_oid(buf, length, &o, NULL);
173 		if (ret)
174 		    errx (1, "der_get_oid: %s", error_message (ret));
175 
176 		for (i = 0; i < o.length ; i++)
177 		    printf("%d%s", o.components[i],
178 			   i < o.length - 1 ? "." : "");
179 		printf("\n");
180 		free_oid(&o);
181 		break;
182 	    }
183 	    default :
184 		printf ("%lu bytes\n", (unsigned long)length);
185 		break;
186 	    }
187 	}
188 	buf += length;
189 	len -= length;
190     }
191     return 0;
192 }
193 
194 static int
195 doit (const char *filename)
196 {
197     int fd = open (filename, O_RDONLY);
198     struct stat sb;
199     unsigned char *buf;
200     size_t len;
201     int ret;
202 
203     if(fd < 0)
204 	err (1, "opening %s for read", filename);
205     if (fstat (fd, &sb) < 0)
206 	err (1, "stat %s", filename);
207     len = sb.st_size;
208     buf = malloc (len);
209     if (buf == NULL)
210 	err (1, "malloc %u", (unsigned)len);
211     if (read (fd, buf, len) != len)
212 	errx (1, "read failed");
213     close (fd);
214     ret = loop (buf, len, 0);
215     free (buf);
216     return ret;
217 }
218 
219 
220 static int version_flag;
221 static int help_flag;
222 struct getargs args[] = {
223     { "version", 0, arg_flag, &version_flag },
224     { "help", 0, arg_flag, &help_flag }
225 };
226 int num_args = sizeof(args) / sizeof(args[0]);
227 
228 static void
229 usage(int code)
230 {
231     arg_printusage(args, num_args, NULL, "dump-file");
232     exit(code);
233 }
234 
235 int
236 main(int argc, char **argv)
237 {
238     int optind = 0;
239 
240     setprogname (argv[0]);
241     initialize_asn1_error_table ();
242     if(getarg(args, num_args, argc, argv, &optind))
243 	usage(1);
244     if(help_flag)
245 	usage(0);
246     if(version_flag) {
247 	print_version(NULL);
248 	exit(0);
249     }
250     argv += optind;
251     argc -= optind;
252     if (argc != 1)
253 	usage (1);
254     return doit (argv[0]);
255 }
256