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