Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
asn1c
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
asn1c
Commits
0cb0fc52
Commit
0cb0fc52
authored
Sep 27, 2004
by
Lev Walkin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
improved xml handling
parent
cb3aabee
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
100 additions
and
41 deletions
+100
-41
asn1c/enber.1
asn1c/enber.1
+24
-2
asn1c/enber.c
asn1c/enber.c
+34
-13
asn1c/unber.1
asn1c/unber.1
+13
-3
asn1c/unber.c
asn1c/unber.c
+29
-23
No files found.
asn1c/enber.1
View file @
0cb0fc52
...
...
@@ -12,16 +12,38 @@
.SH NAME
enber \- Convert the unber XML output back into BER
.SH SYNOPSIS
enber [\fB-\fR] \fIinfile\fR...
enber [\fB-
n\fR] [\fB-
\fR] \fIinfile\fR...
.SH DESCRIPTION
enber takes the XML-
encod
ed files produced by \fIunber\fR\|(1) and converts
enber takes the XML-
formatt
ed files produced by \fIunber\fR\|(1) and converts
them back into the BER format.
A single dash represents the standard input.
.SH OPTIONS
.TP
\fB\-n\fR
Disable input validation. By default, enber performs some basic validity checks
against the XML input. This option disables such checks.
.SH EXAMPLES
Decode the BER sequence and immediately encode it back
.Vb
\& unber \fB-p\fR \fIfilename.ber\fR | enber \fB-\fR > \fIreconstructed.ber\fR
.Ve
.SH FOOTNOTES
This program does not attempt to perform full-fledged XML parsing. It is merely
compatible with \fIunber\fR\|(1)'s output.
In particular, the XML comments are not supported.
The following characters after the initial white space indicate
the start of a comment: "\fB#\fR" (a hash) and "\fB--\fR" (two dashes).
The whole comment line is ignored completely. Empty lines are ignored as well.
.P
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!
\& </C>
.Ve
.SH SEE ALSO
.TP
\&\fIunber\fR\|(1), \&\fIasn1c\fR\|(1)
...
...
asn1c/enber.c
View file @
0cb0fc52
...
...
@@ -45,7 +45,7 @@
#include <ber_tlv_tag.c>
#include <ber_tlv_length.c>
static
void
usage
(
const
char
*
av0
);
/* Print the Usage screen and exit */
static
void
usage
(
const
char
*
av0
,
int
);
/* Print the Usage screen and exit */
static
int
process
(
const
char
*
fname
);
/* Perform the BER decoding */
static
int
process_line
(
const
char
*
fname
,
char
*
line
,
int
lineno
);
...
...
@@ -53,6 +53,8 @@ static int process_line(const char *fname, char *line, int lineno);
#define COPYRIGHT \
"Copyright (c) 2004 Lev Walkin <vlm@lionet.info>\n"
static
int
no_validation
;
/* -n */
int
main
(
int
ac
,
char
**
av
)
{
int
ch
;
/* Command line character */
...
...
@@ -61,15 +63,20 @@ main(int ac, char **av) {
/*
* Process command-line options.
*/
while
((
ch
=
getopt
(
ac
,
av
,
"hv"
))
!=
-
1
)
while
((
ch
=
getopt
(
ac
,
av
,
"
n
hv"
))
!=
-
1
)
switch
(
ch
)
{
case
'n'
:
no_validation
++
;
break
;
case
'v'
:
fprintf
(
stderr
,
"ASN.1 BER Decoder, v"
VERSION
"
\n
"
COPYRIGHT
);
usage
(
av
[
0
],
1
);
fprintf
(
stderr
,
"Convert unber(1)'s output back into BER, "
"v"
VERSION
"
\n
"
COPYRIGHT
);
exit
(
0
);
break
;
case
'h'
:
default:
usage
(
av
[
0
]);
usage
(
av
[
0
]
,
0
);
}
/*
...
...
@@ -101,11 +108,15 @@ main(int ac, char **av) {
* Print the usage screen and exit(EX_USAGE).
*/
static
void
usage
(
const
char
*
av0
)
{
usage
(
const
char
*
av0
,
int
copyright_only
)
{
fprintf
(
stderr
,
"Convert unber(1)'s output back into BER, "
"v"
VERSION
"
\n
"
COPYRIGHT
);
if
(
copyright_only
)
exit
(
0
);
fprintf
(
stderr
,
"Convertor of under(1) output back into BER, v"
VERSION
"
\n
"
COPYRIGHT
"Usage: %s [-] [file ...]
\n
"
,
av0
);
"Usage: %s [-n] [-] [file ...]
\n
"
"Options:
\n
"
" -n Disable XML input validation
\n
"
,
av0
);
exit
(
EX_USAGE
);
}
...
...
@@ -184,9 +195,18 @@ process_line(const char *fname, char *line, int lineno) {
(
void
)
fname
;
/* Find a tag opening angle bracket */
for
(;
*
line
==
' '
;
line
++
);
for
(;
*
line
==
' '
||
*
line
==
'\t'
;
line
++
);
op
=
line
;
if
(
*
op
!=
'<'
)
{
switch
(
*
op
)
{
case
'<'
:
/* That's what we want! A tag opening */
break
;
case
'-'
:
/* This is a comment (dash-dash) */
if
(
op
[
1
]
==
*
op
)
case
'\r'
:
case
'\n'
:
case
'#'
:
/* This is a comment */
return
0
;
default:
fprintf
(
stderr
,
"%s: Missing '<' after whitespace
\n
"
,
fname
);
exit
(
EX_DATAERR
);
}
...
...
@@ -240,10 +260,10 @@ process_line(const char *fname, char *line, int lineno) {
tcl_pos
=
strstr
(
op
,
"T=
\"
["
);
tl_pos
=
strstr
(
op
,
"TL=
\"
"
);
v_pos
=
strstr
(
op
,
"V=
\"
"
);
if
(
!
tcl_pos
||
!
tl_pos
||
!
v_pos
)
{
if
(
!
tcl_pos
||
!
tl_pos
||
(
!
v_pos
&&
constr
!=
2
)
)
{
fprintf
(
stderr
,
"%s: Mandatory attribute %s is not found at line %d
\n
"
,
fname
,
(
!
tcl_pos
)
?
"T"
:
(
v_pos
?
"V"
:
"TC
L"
),
lineno
);
fname
,
(
!
tcl_pos
)
?
"T"
:
(
(
!
v_pos
)
?
"V"
:
"T
L"
),
lineno
);
exit
(
EX_DATAERR
);
}
errno
=
0
;
...
...
@@ -368,11 +388,12 @@ process_line(const char *fname, char *line, int lineno) {
fputc
(
v
,
stdout
);
}
if
(
len
!=
tlv_len
)
{
if
(
no_validation
)
fprintf
(
stderr
,
"Warning: "
);
fprintf
(
stderr
,
"%s: Could not encode value of %d chars "
"at line %d in %d bytes
\n
"
,
fname
,
len
,
lineno
,
tlv_len
);
exit
(
EX_DATAERR
);
if
(
!
no_validation
)
exit
(
EX_DATAERR
);
}
}
...
...
asn1c/unber.1
View file @
0cb0fc52
...
...
@@ -29,7 +29,8 @@ By default, unber continues decoding until the end of file (input stream).
Use the specified number of spaces for output indentation. Default is 4 spaces.
.TP
\fB\-p\fR
Do \fInot\fR attempt pretty-printing of known ASN.1 types (strings, INTEGER, BOOLEAN, etc).
Do \fInot\fR attempt pretty-printing of known ASN.1 types (OBJECT IDENTIFIER, INTEGER, BOOLEAN, etc). By default, some ASN.1 types are converted into
the text representation. This option is required for \&\fIenber\fR\|(1).
.TP
\fB\-t\fR \fIdata-string\fR
Interpret the data-string as a sequence of hexadecimal values representing
...
...
@@ -62,7 +63,7 @@ Likely name of the underlying ASN.1 type (for UNIVERSAL tags)
[\fIF\fR]
Indicates that the value was reformatted (pretty-printed)
.P
Example
:
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>
...
...
@@ -84,10 +85,19 @@ Decode the binary stream taken from the standard input:
.Vb
\& cat \fI...\fR | unber \fB-\fR
.Ve
Decode the binary stream into the same stream (see \fIenber\fR\|(1)):
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
.Ve
.SH FOOTNOTES
The constructed XML output is not necessarily well-formed.
.P
When indefinite length encoding is being used, the BER sequence, which is not
terminated with the end-of-content octets, will cause the terminating \fB</I>\fR
XML tag to disappear.
Thus, the invalid BER framing directly causes invalid XML output.
.P
The \&\fIenber\fR\|(1) utility understands this convention correctly.
.SH SEE ALSO
.TP
\&\fIenber\fR\|(1), \&\fIasn1c\fR\|(1)
...
...
asn1c/unber.c
View file @
0cb0fc52
...
...
@@ -158,7 +158,7 @@ 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
);
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
int
print_V
(
const
char
*
fname
,
FILE
*
fp
,
ber_tlv_tag_t
,
ber_tlv_len_t
);
...
...
@@ -169,6 +169,7 @@ static int
process
(
const
char
*
fname
)
{
FILE
*
fp
;
pd_code_e
pdc
;
ssize_t
decoded
=
0
;
if
(
strcmp
(
fname
,
"-"
))
{
fp
=
fopen
(
fname
,
"r"
);
...
...
@@ -184,7 +185,7 @@ process(const char *fname) {
* Fetch out BER-encoded data until EOF or error.
*/
do
{
pdc
=
process_deeper
(
fname
,
fp
,
0
,
-
1
);
pdc
=
process_deeper
(
fname
,
fp
,
0
,
-
1
,
&
decoded
,
0
);
}
while
(
pdc
==
PD_FINISHED
&&
!
single_type_decoding
);
if
(
fp
!=
stdin
)
...
...
@@ -198,7 +199,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
)
{
static
pd_code_e
process_deeper
(
const
char
*
fname
,
FILE
*
fp
,
int
level
,
ssize_t
limit
,
ssize_t
*
decoded
,
int
expect_eoc
)
{
unsigned
char
tagbuf
[
32
];
ssize_t
tblen
=
0
;
pd_code_e
pdc
=
PD_FINISHED
;
...
...
@@ -266,52 +267,57 @@ static pd_code_e process_deeper(const char *fname, FILE *fp, int level, ssize_t
continue
;
}
if
(
tagbuf
[
0
]
==
'\0'
&&
tagbuf
[
1
]
==
'\0'
)
{
/* End of content octets */
return
PD_FINISHED
;
}
/* Make sure the T & L decoders took exactly the whole buffer */
assert
((
t_len
+
l_len
)
==
tblen
);
print_TL
(
0
,
level
,
constr
,
tblen
,
tlv_tag
,
tlv_len
);
if
(
!
expect_eoc
||
tagbuf
[
0
]
||
tagbuf
[
1
])
print_TL
(
0
,
level
,
constr
,
tblen
,
tlv_tag
,
tlv_len
);
if
(
limit
!=
-
1
)
{
/* If limit is set, account for the TL sequence */
limit
-=
(
t_len
+
l_len
);
assert
(
limit
>=
0
);
}
if
(
limit
!=
-
1
)
{
if
(
tlv_len
>
limit
)
{
fprintf
(
stderr
,
"%s: Structure advertizes length (%ld) "
"greater than of a parent container (%ld)
\n
"
,
fname
,
(
long
)
tlv_len
,
(
long
)
limit
);
return
PD_FAILED
;
}
else
if
(
tlv_len
!=
-
1
)
{
/* Account for the V */
limit
-=
tlv_len
;
}
}
*
decoded
+=
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
);
return
PD_FINISHED
;
}
if
(
constr
)
{
ssize_t
dec
=
0
;
/*
* This is a constructed type. Process recursively.
*/
/* Get the new subframe limit from the structure tags */
if
(
tlv_len
==
-
1
)
tlv_len
=
limit
;
printf
(
">
\n
"
);
/* Close the opening tag */
pdc
=
process_deeper
(
fname
,
fp
,
level
+
1
,
tlv_len
);
pdc
=
process_deeper
(
fname
,
fp
,
level
+
1
,
tlv_len
==
-
1
?
limit
:
tlv_len
,
&
dec
,
tlv_len
==
-
1
);
if
(
pdc
==
PD_FAILED
)
return
pdc
;
if
(
limit
!=
-
1
)
limit
-=
dec
;
*
decoded
+=
dec
;
if
(
tlv_len
==
-
1
)
{
tblen
=
0
;
continue
;
}
}
else
{
assert
(
tlv_len
>=
0
);
if
(
print_V
(
fname
,
fp
,
tlv_tag
,
tlv_len
))
return
PD_FAILED
;
limit
-=
tlv_len
;
*
decoded
+=
tlv_len
;
}
print_TL
(
1
,
level
,
constr
,
tblen
,
tlv_tag
,
tlv_len
);
...
...
@@ -339,9 +345,9 @@ print_TL(int fin, int level, int constr, ssize_t tlen, ber_tlv_tag_t tlv_tag, be
ber_tlv_tag_fwrite
(
tlv_tag
,
stdout
);
printf
(
"
\"
"
);
if
(
!
fin
)
{
if
(
!
fin
||
tlv_len
==
-
1
)
printf
(
" TL=
\"
%ld
\"
"
,
(
long
)
tlen
);
if
(
!
fin
)
{
if
(
tlv_len
==
-
1
)
printf
(
" V=
\"
Indefinite
\"
"
);
else
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment