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