Lev Walkin | b47d1ad | 2019-01-21 14:54:50 -0800 | [diff] [blame] | 1 | /* |
Lev Walkin | b386d24 | 2006-03-27 21:40:26 +0000 | [diff] [blame] | 2 | * Copyright (c) 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>. |
| 3 | * All rights reserved. |
Lev Walkin | 1298467 | 2004-09-24 21:00:15 +0000 | [diff] [blame] | 4 | * |
| 5 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that the following conditions |
| 7 | * are met: |
| 8 | * 1. Redistributions of source code must retain the above copyright |
| 9 | * notice, this list of conditions and the following disclaimer. |
| 10 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. |
| 13 | * |
| 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
| 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
| 18 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| 20 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 21 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 22 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 23 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 24 | * SUCH DAMAGE. |
| 25 | * |
Lev Walkin | 1298467 | 2004-09-24 21:00:15 +0000 | [diff] [blame] | 26 | */ |
Lev Walkin | b47d1ad | 2019-01-21 14:54:50 -0800 | [diff] [blame] | 27 | #include "asn1_common.h" |
Lev Walkin | ccfaf2a | 2019-01-21 17:45:31 -0800 | [diff] [blame^] | 28 | #include "libasn1_unber_tool.h" |
Lev Walkin | 06b8d7a | 2004-09-23 22:06:02 +0000 | [diff] [blame] | 29 | |
Lev Walkin | 41a1da6 | 2016-01-23 08:50:28 -0800 | [diff] [blame] | 30 | #undef COPYRIGHT |
Lev Walkin | ccfaf2a | 2019-01-21 17:45:31 -0800 | [diff] [blame^] | 31 | #define COPYRIGHT "Copyright (c) 2004-2019 Lev Walkin <vlm@lionet.info>\n" |
Lev Walkin | c0d0491 | 2005-02-25 12:52:27 +0000 | [diff] [blame] | 32 | |
Lev Walkin | 41a1da6 | 2016-01-23 08:50:28 -0800 | [diff] [blame] | 33 | static void usage(const char *av0); /* Print the Usage screen and exit */ |
Lev Walkin | 06b8d7a | 2004-09-23 22:06:02 +0000 | [diff] [blame] | 34 | |
| 35 | int |
| 36 | main(int ac, char **av) { |
Lev Walkin | 41a1da6 | 2016-01-23 08:50:28 -0800 | [diff] [blame] | 37 | int ch; /* Command line character */ |
Lev Walkin | 06b8d7a | 2004-09-23 22:06:02 +0000 | [diff] [blame] | 38 | |
Lev Walkin | 41a1da6 | 2016-01-23 08:50:28 -0800 | [diff] [blame] | 39 | /* |
| 40 | * Process command-line options. |
| 41 | */ |
Lev Walkin | ccfaf2a | 2019-01-21 17:45:31 -0800 | [diff] [blame^] | 42 | while((ch = getopt(ac, av, "1hi:mps:t:v")) != -1) { |
| 43 | switch(ch) { |
Lev Walkin | 41a1da6 | 2016-01-23 08:50:28 -0800 | [diff] [blame] | 44 | case '1': |
Lev Walkin | ccfaf2a | 2019-01-21 17:45:31 -0800 | [diff] [blame^] | 45 | set_single_type_decoding(1); |
Lev Walkin | 41a1da6 | 2016-01-23 08:50:28 -0800 | [diff] [blame] | 46 | break; |
| 47 | case 'i': |
Lev Walkin | ccfaf2a | 2019-01-21 17:45:31 -0800 | [diff] [blame^] | 48 | if(set_indent_size(atoi(optarg)) != 0) { |
Lev Walkin | 41a1da6 | 2016-01-23 08:50:28 -0800 | [diff] [blame] | 49 | fprintf(stderr, "-i %s: Invalid indent value\n", optarg); |
| 50 | exit(EX_USAGE); |
| 51 | } |
| 52 | break; |
| 53 | case 'm': |
Lev Walkin | ccfaf2a | 2019-01-21 17:45:31 -0800 | [diff] [blame^] | 54 | set_minimalistic_output(1); |
Lev Walkin | 41a1da6 | 2016-01-23 08:50:28 -0800 | [diff] [blame] | 55 | break; |
| 56 | case 'p': |
Lev Walkin | ccfaf2a | 2019-01-21 17:45:31 -0800 | [diff] [blame^] | 57 | set_pretty_printing(0); |
Lev Walkin | 41a1da6 | 2016-01-23 08:50:28 -0800 | [diff] [blame] | 58 | break; |
| 59 | case 's': |
Lev Walkin | ccfaf2a | 2019-01-21 17:45:31 -0800 | [diff] [blame^] | 60 | if(set_skip_bytes(atol(optarg)) != 0) { |
Lev Walkin | 41a1da6 | 2016-01-23 08:50:28 -0800 | [diff] [blame] | 61 | fprintf(stderr, "-s %s: positive value expected\n", optarg); |
| 62 | exit(EX_USAGE); |
| 63 | } |
| 64 | break; |
| 65 | case 't': |
Lev Walkin | ccfaf2a | 2019-01-21 17:45:31 -0800 | [diff] [blame^] | 66 | if(decode_tlv_from_hex_string(optarg)) exit(EX_DATAERR); |
Lev Walkin | 41a1da6 | 2016-01-23 08:50:28 -0800 | [diff] [blame] | 67 | exit(0); |
| 68 | case 'v': |
| 69 | fprintf(stderr, "ASN.1 BER Decoder, v" VERSION "\n" COPYRIGHT); |
| 70 | exit(0); |
| 71 | break; |
| 72 | case 'h': |
| 73 | default: |
| 74 | usage(av[0]); |
| 75 | } |
Lev Walkin | ccfaf2a | 2019-01-21 17:45:31 -0800 | [diff] [blame^] | 76 | } |
Lev Walkin | 06b8d7a | 2004-09-23 22:06:02 +0000 | [diff] [blame] | 77 | |
Lev Walkin | 41a1da6 | 2016-01-23 08:50:28 -0800 | [diff] [blame] | 78 | /* |
| 79 | * Ensure that there are some input files present. |
| 80 | */ |
| 81 | if(ac > optind) { |
| 82 | ac -= optind; |
| 83 | av += optind; |
| 84 | } else { |
| 85 | fprintf(stderr, "%s: No input files specified\n", av[0]); |
| 86 | exit(1); |
| 87 | } |
Lev Walkin | 06b8d7a | 2004-09-23 22:06:02 +0000 | [diff] [blame] | 88 | |
Lev Walkin | 41a1da6 | 2016-01-23 08:50:28 -0800 | [diff] [blame] | 89 | setvbuf(stdout, 0, _IOLBF, 0); |
Lev Walkin | 06b8d7a | 2004-09-23 22:06:02 +0000 | [diff] [blame] | 90 | |
Lev Walkin | 41a1da6 | 2016-01-23 08:50:28 -0800 | [diff] [blame] | 91 | /* |
| 92 | * Iterate over input files and parse each. |
| 93 | * All syntax trees from all files will be bundled together. |
| 94 | */ |
Lev Walkin | ccfaf2a | 2019-01-21 17:45:31 -0800 | [diff] [blame^] | 95 | for(int i = 0; i < ac; i++) { |
| 96 | if(unber_file(av[i])) exit(EX_DATAERR); |
Lev Walkin | 41a1da6 | 2016-01-23 08:50:28 -0800 | [diff] [blame] | 97 | } |
Lev Walkin | 06b8d7a | 2004-09-23 22:06:02 +0000 | [diff] [blame] | 98 | |
Lev Walkin | 41a1da6 | 2016-01-23 08:50:28 -0800 | [diff] [blame] | 99 | return 0; |
Lev Walkin | 06b8d7a | 2004-09-23 22:06:02 +0000 | [diff] [blame] | 100 | } |
| 101 | |
| 102 | /* |
| 103 | * Print the usage screen and exit(EX_USAGE). |
| 104 | */ |
| 105 | static void |
| 106 | usage(const char *av0) { |
Lev Walkin | 41a1da6 | 2016-01-23 08:50:28 -0800 | [diff] [blame] | 107 | /* clang-format off */ |
Lev Walkin | 06b8d7a | 2004-09-23 22:06:02 +0000 | [diff] [blame] | 108 | fprintf(stderr, |
| 109 | "ASN.1 BER Decoder, v" VERSION "\n" COPYRIGHT |
| 110 | "Usage: %s [options] [-] [file ...]\n" |
| 111 | "Options:\n" |
Lev Walkin | 9044779 | 2005-09-30 05:23:40 +0000 | [diff] [blame] | 112 | " -1 Decode only the first BER structure (otherwise, until EOF)\n" |
| 113 | " -i <indent> Amount of spaces for output indentation (default is 4)\n" |
| 114 | " -m Minimalistic mode: print as little as possible\n" |
| 115 | " -p Do not attempt pretty-printing of known ASN.1 types\n" |
| 116 | " -s <skip> Ignore first <skip> bytes of input\n" |
| 117 | " -t <hex-string> Decode the given tag[/length] sequence (e.g. -t \"bf20\")\n" |
Lev Walkin | 1298467 | 2004-09-24 21:00:15 +0000 | [diff] [blame] | 118 | "\n" |
| 119 | "The XML opening tag format is as follows:\n" |
Lev Walkin | f985434 | 2005-06-08 00:06:59 +0000 | [diff] [blame] | 120 | " <tform O=\"off\" T=\"tag\" TL=\"tl_len\" V=\"{Indefinite|v_len}\" [A=\"type\"] [F]>\n" |
Lev Walkin | 1298467 | 2004-09-24 21:00:15 +0000 | [diff] [blame] | 121 | "Where:\n" |
| 122 | " tform Which form the value is in: constructed (\"C\", \"I\") or primitive (\"P\")\n" |
Lev Walkin | f985434 | 2005-06-08 00:06:59 +0000 | [diff] [blame] | 123 | " off Offset of the encoded element in the unber input stream\n" |
| 124 | " tag The tag class and value in human readable form\n" |
Lev Walkin | 1298467 | 2004-09-24 21:00:15 +0000 | [diff] [blame] | 125 | " tl_len The length of the TL (BER Tag and Length) encoding\n" |
| 126 | " v_len The length of the value (V, encoded by the L), may be \"Indefinite\"\n" |
| 127 | " type Likely name of the underlying ASN.1 type (for [UNIVERSAL n] tags)\n" |
| 128 | " [F] Indicates that the value was reformatted (pretty-printed)\n" |
| 129 | "See the manual page for details\n" |
Lev Walkin | 06b8d7a | 2004-09-23 22:06:02 +0000 | [diff] [blame] | 130 | , av0); |
Lev Walkin | 41a1da6 | 2016-01-23 08:50:28 -0800 | [diff] [blame] | 131 | /* clang-format on */ |
| 132 | exit(EX_USAGE); |
Lev Walkin | 06b8d7a | 2004-09-23 22:06:02 +0000 | [diff] [blame] | 133 | } |
| 134 | |