1 /* 2 * Copyright (c) 1997, 1998, 1999 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.5 1999/12/02 17:05:01 joda 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 buf += sz; 103 len -= sz; 104 for (i = 0; i < indent; ++i) 105 printf (" "); 106 printf ("%s %s ", class_names[class], type_names[type]); 107 if (tag_names[tag]) 108 printf ("%s = ", tag_names[tag]); 109 else 110 printf ("tag %d = ", tag); 111 ret = der_get_length (buf, len, &length, &sz); 112 if (ret) 113 errx (1, "der_get_tag: %s", com_right (et_list, ret)); 114 buf += sz; 115 len -= sz; 116 117 if (class == CONTEXT) { 118 printf ("[%d]\n", tag); 119 loop (buf, length, indent); 120 } else if (class == UNIV) { 121 switch (tag) { 122 case UT_Sequence : 123 printf ("{\n"); 124 loop (buf, length, indent + 2); 125 for (i = 0; i < indent; ++i) 126 printf (" "); 127 printf ("}\n"); 128 break; 129 case UT_Integer : { 130 int val; 131 132 ret = der_get_int (buf, length, &val, NULL); 133 if (ret) 134 errx (1, "der_get_int: %s", com_right (et_list, ret)); 135 printf ("integer %d\n", val); 136 break; 137 } 138 case UT_OctetString : { 139 octet_string str; 140 int i; 141 unsigned char *uc; 142 143 ret = der_get_octet_string (buf, length, &str, NULL); 144 if (ret) 145 errx (1, "der_get_octet_string: %s", 146 com_right (et_list, ret)); 147 printf ("(length %d), ", length); 148 uc = (unsigned char *)str.data; 149 for (i = 0; i < 16; ++i) 150 printf ("%02x", uc[i]); 151 printf ("\n"); 152 free (str.data); 153 break; 154 } 155 case UT_GeneralizedTime : 156 case UT_GeneralString : { 157 general_string str; 158 159 ret = der_get_general_string (buf, length, &str, NULL); 160 if (ret) 161 errx (1, "der_get_general_string: %s", 162 com_right (et_list, ret)); 163 printf ("\"%s\"\n", str); 164 free (str); 165 break; 166 } 167 default : 168 printf ("%d bytes\n", length); 169 break; 170 } 171 } 172 buf += length; 173 len -= length; 174 } 175 return 0; 176 } 177 178 static int 179 doit (const char *filename) 180 { 181 int fd = open (filename, O_RDONLY); 182 struct stat sb; 183 unsigned char *buf; 184 size_t len; 185 int ret; 186 187 if(fd < 0) 188 err (1, "opening %s for read", filename); 189 if (fstat (fd, &sb) < 0) 190 err (1, "stat %s", filename); 191 len = sb.st_size; 192 buf = malloc (len); 193 if (buf == NULL) 194 err (1, "malloc %u", len); 195 if (read (fd, buf, len) != len) 196 errx (1, "read failed"); 197 close (fd); 198 ret = loop (buf, len, 0); 199 free (buf); 200 return ret; 201 } 202 203 204 static int version_flag; 205 static int help_flag; 206 struct getargs args[] = { 207 { "version", 0, arg_flag, &version_flag }, 208 { "help", 0, arg_flag, &help_flag } 209 }; 210 int num_args = sizeof(args) / sizeof(args[0]); 211 212 static void 213 usage(int code) 214 { 215 arg_printusage(args, num_args, NULL, "dump-file"); 216 exit(code); 217 } 218 219 int 220 main(int argc, char **argv) 221 { 222 int optind = 0; 223 224 set_progname (argv[0]); 225 initialize_asn1_error_table_r (&et_list); 226 if(getarg(args, num_args, argc, argv, &optind)) 227 usage(1); 228 if(help_flag) 229 usage(0); 230 if(version_flag) { 231 print_version(NULL); 232 exit(0); 233 } 234 argv += optind; 235 argc -= optind; 236 if (argc != 1) 237 usage (1); 238 return doit (argv[0]); 239 } 240