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