diff options
author | Lev Walkin <vlm@lionet.info> | 2005-06-08 00:06:59 +0000 |
---|---|---|
committer | Lev Walkin <vlm@lionet.info> | 2005-06-08 00:06:59 +0000 |
commit | f9854347fef55a3c3e3b109de0126246676c1235 (patch) | |
tree | 4fa859f1d101ec923c7fad97db5b0d5306fc0d01 | |
parent | 4a4bdf7b89290ebc1593b2c63756bbe057dbce88 (diff) |
offset printing
-rw-r--r-- | asn1c/enber.1 | 8 | ||||
-rw-r--r-- | asn1c/enber.c | 8 | ||||
-rw-r--r-- | asn1c/unber.1 | 43 | ||||
-rw-r--r-- | asn1c/unber.c | 72 |
4 files changed, 76 insertions, 55 deletions
diff --git a/asn1c/enber.1 b/asn1c/enber.1 index 4a9edfc2..365bc46a 100644 --- a/asn1c/enber.1 +++ b/asn1c/enber.1 @@ -12,7 +12,7 @@ .SH NAME enber \- Convert the unber XML output back into BER .SH SYNOPSIS -enber [\fB-n\fR] [\fB-\fR] \fIinfile\fR... +enber [\fB-n\fR] [\fB-\fR] [\fIinfile\fR...] .SH DESCRIPTION enber takes the XML-formatted files produced by \fIunber\fR\|(1) and converts them back into the BER format. @@ -39,9 +39,9 @@ The following example demostrates the use of comments: .Vb \& <C T="[1]" TL="2" V="2"> \& <I T="[1]" TL="2" V="Indefinite"> -\& -- </I> -\& # Do not terminate: -\& # the absence of end-of-content octets is intentional! +\& \fB--\fR </I> +\& \fB#\fR Do not terminate: +\& \fB#\fR the absence of end-of-content octets is intentional! \& </C> .Ve .SH SEE ALSO diff --git a/asn1c/enber.c b/asn1c/enber.c index 1ecef6f5..12dae96e 100644 --- a/asn1c/enber.c +++ b/asn1c/enber.c @@ -179,8 +179,10 @@ process_line(const char *fname, char *line, int lineno) { ssize_t ret; (void)fname; - /* Find a tag opening angle bracket */ + /* Skip the whitespace */ for(; *line == ' ' || *line == '\t'; line++); + + /* Find a tag opening angle bracket */ op = line; switch(*op) { case '<': /* That's what we want! A tag opening */ @@ -192,7 +194,9 @@ process_line(const char *fname, char *line, int lineno) { case '#': /* This is a comment */ return 0; default: - fprintf(stderr, "%s: Missing '<' after whitespace at line %d\n", fname, lineno); + fprintf(stderr, + "%s: Missing '<' after whitespace at line %d\n", + fname, lineno); exit(EX_DATAERR); } diff --git a/asn1c/unber.1 b/asn1c/unber.1 index a31fabd1..7f203d0b 100644 --- a/asn1c/unber.1 +++ b/asn1c/unber.1 @@ -12,7 +12,7 @@ .SH NAME unber \- ASN.1 BER Decoder .SH SYNOPSIS -unber [\fB-1\fR] [\fB-i\fRindent] [\fB-p\fR] [\fB\-t\fR\fIdata-string\fR] [\fB-\fR] \fIinfile\fR... +unber [\fB-1\fR] [\fB-i\fRindent] [\fB-p\fR] [\fB\-t\fR\fIdata-string\fR] [\fB-\fR] [\fIinfile\fR...] .SH DESCRIPTION unber takes the BER-encoded files and dumps their internal structure as human readable text. A single dash represents the standard input. @@ -41,36 +41,39 @@ information from the underlying binary encoding. .P The XML opening tag format is as follows: .Vb -\& <\fItform\fR T="\fItag\fR" TL="\fItl_len\fR" V="{Indefinite|\fIv_len\fR}" [A="\fItype\fR"] [\fIF\fR]> +\&<\fBtform\fR O="\fBoff\fR" T="\fBtag\fR" TL="\fBtl_len\fR" V="{Indefinite|\fBv_len\fR}" [A="\fBtype\fR"] [\fBF\fR]> .Ve Where: .TP -\fItform\fR +\fBtform\fR Which form the value is in: primitive ("P") or constructed ("C") or constructed with indefinite length ("I") .TP -\fItag\fR -The tag class and value +\fBoff\fR +Offset of the encoded element in the unber input stream. .TP -\fItl_len\fR -The length of the TL (BER Tag and Length) encoding +\fBtag\fR +The tag class and value in human readable form. .TP -\fIv_len\fR -The length of the value (V, encoded by the L), may be "Indefinite" +\fBtl_len\fR +The length of the TL (BER Tag and Length) encoding. .TP -\fItype\fR -Likely name of the underlying ASN.1 type (for UNIVERSAL tags) +\fBv_len\fR +The length of the value (V, encoded by the L), may be "Indefinite". .TP -[\fIF\fR] -Indicates that the value was reformatted (pretty-printed) +\fBtype\fR +Likely name of the underlying ASN.1 type (for UNIVERSAL tags). +.TP +[\fBF\fR] +Indicates that the value was reformatted (pretty-printed). This may only appear in the output as long \fB-p\fR command line option is \fInot\fR specified. .P Sample XML output: .Vb -\& <I T="[UNIVERSAL 16]" TL="2" V="Indefinite" A="SEQUENCE"> -\& <P T="[UNIVERSAL 19]" TL="2" V="2" A="PrintableString">US</P> -\& <C T="[UNIVERSAL 16]" TL="2" V="11" A="SEQUENCE"> -\& <P T="[UNIVERSAL 2]" TL="2" V="4" A="INTEGER" F>832970823</P> -\& </C T="[UNIVERSAL 16]" A="SEQUENCE"> -\& </I T="[UNIVERSAL 16]" A="SEQUENCE"> +\&<I O="0" T="[UNIVERSAL 16]" TL="2" V="Indefinite" A="SEQUENCE"> +\& <P O="2" T="[UNIVERSAL 19]" TL="2" V="2" A="PrintableString">US</P> +\& <C O="6" T="[UNIVERSAL 16]" TL="2" V="11" A="SEQUENCE"> +\& <P O="8" T="[UNIVERSAL 2]" TL="2" V="4" A="INTEGER" F>832970823</P> +\& </C T="[UNIVERSAL 16]" A="SEQUENCE"> +\&</I T="[UNIVERSAL 16]" A="SEQUENCE"> .Ve .SH EXAMPLES Decode the given Tag/Length sequence given in hexadecimal form: @@ -87,7 +90,7 @@ Decode the binary stream taken from the standard input: .Ve Decode the binary stream into the same stream (see \&\fIenber\fR\|(1)): .Vb -\& cat \fI...\fR | unber \fB-p\fR \fB-\fR | enber \fB-\fR > filename.ber\fI\fR +\& cat \fI...\fR | unber \fB-p\fR \fB-\fR | enber \fB-\fR > \fIfilename.ber\fR .Ve .SH FOOTNOTES The constructed XML output is not necessarily well-formed. diff --git a/asn1c/unber.c b/asn1c/unber.c index 4a68c685..db00157f 100644 --- a/asn1c/unber.c +++ b/asn1c/unber.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004 Lev Walkin <vlm@lionet.info>. All rights reserved. + * Copyright (c) 2004, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -38,7 +38,7 @@ #undef COPYRIGHT #define COPYRIGHT \ - "Copyright (c) 2004 Lev Walkin <vlm@lionet.info>\n" + "Copyright (c) 2004, 2005 Lev Walkin <vlm@lionet.info>\n" static void usage(const char *av0); /* Print the Usage screen and exit */ static int process(const char *fname); /* Perform the BER decoding */ @@ -128,10 +128,11 @@ usage(const char *av0) { " -t <data-string> Decode the given tag[/length] sequence (e.g. -t \"bf20\")\n" "\n" "The XML opening tag format is as follows:\n" -" <tform T=\"tag\" TL=\"tl_len\" V=\"{Indefinite|v_len}\" [A=\"type\"] [F]>\n" +" <tform O=\"off\" T=\"tag\" TL=\"tl_len\" V=\"{Indefinite|v_len}\" [A=\"type\"] [F]>\n" "Where:\n" " tform Which form the value is in: constructed (\"C\", \"I\") or primitive (\"P\")\n" -" tag The tag class and value\n" +" off Offset of the encoded element in the unber input stream\n" +" tag The tag class and value in human readable form\n" " tl_len The length of the TL (BER Tag and Length) encoding\n" " v_len The length of the value (V, encoded by the L), may be \"Indefinite\"\n" " type Likely name of the underlying ASN.1 type (for [UNIVERSAL n] tags)\n" @@ -146,8 +147,8 @@ typedef enum pd_code { PD_FINISHED = 0, PD_EOF = 1, } pd_code_e; -static pd_code_e process_deeper(const char *fname, FILE *fp, int level, ssize_t limit, ssize_t *decoded, int expect_eoc); -static void print_TL(int fin, int level, int constr, ssize_t tlen, ber_tlv_tag_t, ber_tlv_len_t); +static pd_code_e process_deeper(const char *fname, FILE *fp, asn1c_integer_t *offset, int level, ssize_t limit, ssize_t *frame_size, int expect_eoc); +static void print_TL(int fin, asn1c_integer_t offset, int level, int constr, ssize_t tlen, ber_tlv_tag_t, ber_tlv_len_t); static int print_V(const char *fname, FILE *fp, ber_tlv_tag_t, ber_tlv_len_t); /* @@ -157,7 +158,8 @@ static int process(const char *fname) { FILE *fp; pd_code_e pdc; - ssize_t decoded = 0; + asn1c_integer_t offset = 0; /* Stream decoding position */ + ssize_t frame_size = 0; /* Single frame size */ if(strcmp(fname, "-")) { fp = fopen(fname, "r"); @@ -173,7 +175,7 @@ process(const char *fname) { * Fetch out BER-encoded data until EOF or error. */ do { - pdc = process_deeper(fname, fp, 0, -1, &decoded, 0); + pdc = process_deeper(fname, fp, &offset, 0, -1, &frame_size, 0); } while(pdc == PD_FINISHED && !single_type_decoding); if(fp != stdin) @@ -187,7 +189,7 @@ process(const char *fname) { /* * Process the TLV recursively. */ -static pd_code_e process_deeper(const char *fname, FILE *fp, int level, ssize_t limit, ssize_t *decoded, int expect_eoc) { +static pd_code_e process_deeper(const char *fname, FILE *fp, asn1c_integer_t *offset, int level, ssize_t limit, ssize_t *frame_size, int expect_eoc) { unsigned char tagbuf[32]; ssize_t tblen = 0; pd_code_e pdc = PD_FINISHED; @@ -205,18 +207,21 @@ static pd_code_e process_deeper(const char *fname, FILE *fp, int level, ssize_t if(limit >= 0 && tblen >= limit) { fprintf(stderr, - "%s: Too long TL sequence (%ld >= %ld). " - "Dangerous file\n", - fname, (long)tblen, (long)limit); + "%s: Too long TL sequence (%ld >= %ld)" + " at %" PRIdASN ". " + "Broken or maliciously constructed file\n", + fname, (long)tblen, (long)limit, *offset); return PD_FAILED; } + /* Get the next byte from the input stream */ ch = fgetc(fp); if(ch == -1) { - if(tblen) { + if(tblen || limit) { fprintf(stderr, - "%s: Unexpected end of file (TL)\n", - fname); + "%s: Unexpected end of file (TL)" + " at %" PRIdASN "\n", + fname, *offset); return PD_FAILED; } else { return PD_EOF; @@ -231,8 +236,9 @@ static pd_code_e process_deeper(const char *fname, FILE *fp, int level, ssize_t t_len = ber_fetch_tag(tagbuf, tblen, &tlv_tag); switch(t_len) { case -1: - fprintf(stderr, "%s: Fatal error deciphering tag\n", - fname); + fprintf(stderr, "%s: Fatal error decoding tag" + " at %" PRIdASN "+%ld\n", + fname, *offset, (long)tblen); return PD_FAILED; case 0: /* More data expected */ @@ -247,8 +253,10 @@ static pd_code_e process_deeper(const char *fname, FILE *fp, int level, ssize_t tagbuf + t_len, tblen - t_len, &tlv_len); switch(l_len) { case -1: - fprintf(stderr, "%s: Fatal error deciphering length\n", - fname); + fprintf(stderr, + "%s: Fatal error decoding value length" + " at %" PRIdASN "\n", + fname, *offset + t_len); return PD_FAILED; case 0: /* More data expected */ @@ -259,7 +267,7 @@ static pd_code_e process_deeper(const char *fname, FILE *fp, int level, ssize_t assert((t_len + l_len) == tblen); if(!expect_eoc || tagbuf[0] || tagbuf[1]) - print_TL(0, level, constr, tblen, tlv_tag, tlv_len); + print_TL(0, *offset, level, constr, tblen, tlv_tag, tlv_len); if(limit != -1) { /* If limit is set, account for the TL sequence */ @@ -275,11 +283,12 @@ static pd_code_e process_deeper(const char *fname, FILE *fp, int level, ssize_t } } - *decoded += t_len + l_len; + *offset += t_len + l_len; + *frame_size += t_len + l_len; if(expect_eoc && tagbuf[0] == '\0' && tagbuf[1] == '\0') { /* End of content octets */ - print_TL(1, level - 1, 1, 2, 0, -1); + print_TL(1, *offset, level - 1, 1, 2, 0, -1); return PD_FINISHED; } @@ -292,7 +301,7 @@ static pd_code_e process_deeper(const char *fname, FILE *fp, int level, ssize_t if(tlv_len != -1 && limit != -1) { assert(limit >= tlv_len); } - pdc = process_deeper(fname, fp, level + 1, + pdc = process_deeper(fname, fp, offset, level + 1, tlv_len == -1 ? limit : tlv_len, &dec, tlv_len == -1); if(pdc == PD_FAILED) return pdc; @@ -300,7 +309,7 @@ static pd_code_e process_deeper(const char *fname, FILE *fp, int level, ssize_t assert(limit >= dec); limit -= dec; } - *decoded += dec; + *frame_size += dec; if(tlv_len == -1) { tblen = 0; continue; @@ -314,10 +323,11 @@ static pd_code_e process_deeper(const char *fname, FILE *fp, int level, ssize_t assert(limit >= tlv_len); limit -= tlv_len; } - *decoded += tlv_len; + *offset += tlv_len; + *frame_size += tlv_len; } - print_TL(1, level, constr, tblen, tlv_tag, tlv_len); + print_TL(1, *offset, level, constr, tblen, tlv_tag, tlv_len); tblen = 0; } while(1); @@ -326,7 +336,7 @@ static pd_code_e process_deeper(const char *fname, FILE *fp, int level, ssize_t } static void -print_TL(int fin, int level, int constr, ssize_t tlen, ber_tlv_tag_t tlv_tag, ber_tlv_len_t tlv_len) { +print_TL(int fin, asn1c_integer_t offset, int level, int constr, ssize_t tlen, ber_tlv_tag_t tlv_tag, ber_tlv_len_t tlv_len) { if(fin && !constr) { printf("</P>\n"); @@ -338,6 +348,10 @@ print_TL(int fin, int level, int constr, ssize_t tlen, ber_tlv_tag_t tlv_tag, be printf(constr ? ((tlv_len == -1) ? "I" : "C") : "P"); + /* In case of <P>, <C>, <I>, </I> print out the offset */ + if(fin == 0 || tlv_len == -1) + printf(" O=\"%" PRIdASN "\"", offset); + printf(" T=\""); ber_tlv_tag_fwrite(tlv_tag, stdout); printf("\""); @@ -645,7 +659,7 @@ decode_tlv_from_string(const char *datastring) { len = ber_fetch_tag(data, dsize, &tlv_tag); switch(len) { case -1: - fprintf(stderr, "TAG: Fatal error deciphering tag\n"); + fprintf(stderr, "TAG: Fatal error decoding tag\n"); return -1; case 0: fprintf(stderr, "TAG: More data expected\n"); @@ -675,7 +689,7 @@ decode_tlv_from_string(const char *datastring) { switch(len) { case -1: fprintf(stderr, - "LEN: Fatal error deciphering length\n"); + "LEN: Fatal error decoding length\n"); return -1; case 0: fprintf(stderr, "LEN: More data expected\n"); |