1 /* 2 * Copyright (c) 1997 - 2000 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 <sys/types.h> 36 #include <sys/stat.h> 37 #include <getarg.h> 38 #include <err.h> 39 40 RCSID("$Id: asn1_print.c,v 1.7 2001/02/20 01:44:52 assar Exp $"); 41 42 static struct et_list *et_list; 43 44 const char *class_names[] = { 45 "UNIV", /* 0 */ 46 "APPL", /* 1 */ 47 "CONTEXT", /* 2 */ 48 "PRIVATE" /* 3 */ 49 }; 50 51 const char *type_names[] = { 52 "PRIM", /* 0 */ 53 "CONS" /* 1 */ 54 }; 55 56 const char *tag_names[] = { 57 NULL, /* 0 */ 58 NULL, /* 1 */ 59 "Integer", /* 2 */ 60 "BitString", /* 3 */ 61 "OctetString", /* 4 */ 62 "Null", /* 5 */ 63 "ObjectID", /* 6 */ 64 NULL, /* 7 */ 65 NULL, /* 8 */ 66 NULL, /* 9 */ 67 NULL, /* 10 */ 68 NULL, /* 11 */ 69 NULL, /* 12 */ 70 NULL, /* 13 */ 71 NULL, /* 14 */ 72 NULL, /* 15 */ 73 "Sequence", /* 16 */ 74 "Set", /* 17 */ 75 NULL, /* 18 */ 76 "PrintableString", /* 19 */ 77 NULL, /* 20 */ 78 NULL, /* 21 */ 79 "IA5String", /* 22 */ 80 "UTCTime", /* 23 */ 81 "GeneralizedTime", /* 24 */ 82 NULL, /* 25 */ 83 "VisibleString", /* 26 */ 84 "GeneralString" /* 27 */ 85 }; 86 87 static int 88 loop (unsigned char *buf, size_t len, int indent) 89 { 90 while (len > 0) { 91 int ret; 92 Der_class class; 93 Der_type type; 94 int tag; 95 size_t sz; 96 size_t length; 97 int i; 98 99 ret = der_get_tag (buf, len, &class, &type, &tag, &sz); 100 if (ret) 101 errx (1, "der_get_tag: %s", com_right (et_list, ret)); 102 if (sz > len) 103 errx (1, "unreasonable length (%u) > %u", 104 (unsigned)sz, (unsigned)len); 105 buf += sz; 106 len -= sz; 107 for (i = 0; i < indent; ++i) 108 printf (" "); 109 printf ("%s %s ", class_names[class], type_names[type]); 110 if (tag_names[tag]) 111 printf ("%s = ", tag_names[tag]); 112 else 113 printf ("tag %d = ", tag); 114 ret = der_get_length (buf, len, &length, &sz); 115 if (ret) 116 errx (1, "der_get_tag: %s", com_right (et_list, ret)); 117 buf += sz; 118 len -= sz; 119 120 if (class == CONTEXT) { 121 printf ("[%d]\n", tag); 122 loop (buf, length, indent); 123 } else if (class == UNIV) { 124 switch (tag) { 125 case UT_Sequence : 126 printf ("{\n"); 127 loop (buf, length, indent + 2); 128 for (i = 0; i < indent; ++i) 129 printf (" "); 130 printf ("}\n"); 131 break; 132 case UT_Integer : { 133 int val; 134 135 ret = der_get_int (buf, length, &val, NULL); 136 if (ret) 137 errx (1, "der_get_int: %s", com_right (et_list, ret)); 138 printf ("integer %d\n", val); 139 break; 140 } 141 case UT_OctetString : { 142 octet_string str; 143 int i; 144 unsigned char *uc; 145 146 ret = der_get_octet_string (buf, length, &str, NULL); 147 if (ret) 148 errx (1, "der_get_octet_string: %s", 149 com_right (et_list, ret)); 150 printf ("(length %d), ", length); 151 uc = (unsigned char *)str.data; 152 for (i = 0; i < 16; ++i) 153 printf ("%02x", uc[i]); 154 printf ("\n"); 155 free (str.data); 156 break; 157 } 158 case UT_GeneralizedTime : 159 case UT_GeneralString : { 160 general_string str; 161 162 ret = der_get_general_string (buf, length, &str, NULL); 163 if (ret) 164 errx (1, "der_get_general_string: %s", 165 com_right (et_list, ret)); 166 printf ("\"%s\"\n", str); 167 free (str); 168 break; 169 } 170 default : 171 printf ("%d bytes\n", length); 172 break; 173 } 174 } 175 buf += length; 176 len -= length; 177 } 178 return 0; 179 } 180 181 static int 182 doit (const char *filename) 183 { 184 int fd = open (filename, O_RDONLY); 185 struct stat sb; 186 unsigned char *buf; 187 size_t len; 188 int ret; 189 190 if(fd < 0) 191 err (1, "opening %s for read", filename); 192 if (fstat (fd, &sb) < 0) 193 err (1, "stat %s", filename); 194 len = sb.st_size; 195 buf = malloc (len); 196 if (buf == NULL) 197 err (1, "malloc %u", len); 198 if (read (fd, buf, len) != len) 199 errx (1, "read failed"); 200 close (fd); 201 ret = loop (buf, len, 0); 202 free (buf); 203 return ret; 204 } 205 206 207 static int version_flag; 208 static int help_flag; 209 struct getargs args[] = { 210 { "version", 0, arg_flag, &version_flag }, 211 { "help", 0, arg_flag, &help_flag } 212 }; 213 int num_args = sizeof(args) / sizeof(args[0]); 214 215 static void 216 usage(int code) 217 { 218 arg_printusage(args, num_args, NULL, "dump-file"); 219 exit(code); 220 } 221 222 int 223 main(int argc, char **argv) 224 { 225 int optind = 0; 226 227 setprogname (argv[0]); 228 initialize_asn1_error_table_r (&et_list); 229 if(getarg(args, num_args, argc, argv, &optind)) 230 usage(1); 231 if(help_flag) 232 usage(0); 233 if(version_flag) { 234 print_version(NULL); 235 exit(0); 236 } 237 argv += optind; 238 argc -= optind; 239 if (argc != 1) 240 usage (1); 241 return doit (argv[0]); 242 } 243