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
06b8d7aa
Commit
06b8d7aa
authored
Sep 23, 2004
by
Lev Walkin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
implemented unber - the ASN.1 BER Decoder
parent
60a1403a
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
511 additions
and
44 deletions
+511
-44
asn1c/Makefile.am
asn1c/Makefile.am
+3
-6
asn1c/Makefile.in
asn1c/Makefile.in
+16
-15
asn1c/README
asn1c/README
+2
-1
asn1c/asn1c.1
asn1c/asn1c.1
+4
-7
asn1c/asn1c.c
asn1c/asn1c.c
+5
-15
asn1c/unber.c
asn1c/unber.c
+481
-0
No files found.
asn1c/Makefile.am
View file @
06b8d7aa
...
...
@@ -10,18 +10,15 @@ AM_CPPFLAGS = \
-I
${top_srcdir}
/skeletons
\
-DDATADIR
=
\"
$(pkgdatadir)
\"
LDADD
=
\
asn1c_
LDADD
=
\
$(top_builddir)
/libasn1parser/libasn1parser.la
\
$(top_builddir)
/libasn1print/libasn1print.la
\
$(top_builddir)
/libasn1fix/libasn1fix.la
\
$(top_builddir)
/libasn1compiler/libasn1compiler.la
asn1c_SOURCES
=
asn1c.c
\
tlv_decoder.c tlv_decoder.h
bin_PROGRAMS
=
asn1c unber
bin_PROGRAMS
=
asn1c
dist_man1_MANS
=
asn1c.1
dist_man1_MANS
=
asn1c.1 unber.1
check_SCRIPTS
=
check-parsing.sh
TESTS
=
check-parsing.sh
...
...
asn1c/Makefile.in
View file @
06b8d7aa
...
...
@@ -14,7 +14,7 @@
@SET_MAKE@
SOURCES
=
$(asn1c_SOURCES)
SOURCES
=
asn1c.c unber.c
srcdir
=
@srcdir@
top_srcdir
=
@top_srcdir@
...
...
@@ -37,7 +37,7 @@ NORMAL_UNINSTALL = :
PRE_UNINSTALL
=
:
POST_UNINSTALL
=
:
host_triplet
=
@host@
bin_PROGRAMS
=
asn1c
$(EXEEXT)
bin_PROGRAMS
=
asn1c
$(EXEEXT)
unber
$(EXEEXT)
subdir
=
asn1c
DIST_COMMON
=
README
$(dist_man1_MANS)
$(srcdir)
/Makefile.am
\
$(srcdir)
/Makefile.in
...
...
@@ -51,18 +51,19 @@ CONFIG_CLEAN_FILES =
am__installdirs
=
"
$(DESTDIR)$(bindir)
"
"
$(DESTDIR)$(man1dir)
"
binPROGRAMS_INSTALL
=
$(INSTALL_PROGRAM)
PROGRAMS
=
$(bin_PROGRAMS)
am_asn1c_OBJECTS
=
asn1c.
$(OBJEXT)
tlv_decoder.
$(OBJEXT)
asn1c_OBJECTS
=
$(am_asn1c_OBJECTS)
asn1c_LDADD
=
$(LDADD)
asn1c_SOURCES
=
asn1c.c
asn1c_OBJECTS
=
asn1c.
$(OBJEXT)
asn1c_DEPENDENCIES
=
$(top_builddir)
/libasn1parser/libasn1parser.la
\
$(top_builddir)
/libasn1print/libasn1print.la
\
$(top_builddir)
/libasn1fix/libasn1fix.la
\
$(top_builddir)
/libasn1compiler/libasn1compiler.la
unber_SOURCES
=
unber.c
unber_OBJECTS
=
unber.
$(OBJEXT)
unber_LDADD
=
$(LDADD)
DEFAULT_INCLUDES
=
-I
.
-I
$(srcdir)
-I
$(top_builddir)
depcomp
=
$(SHELL)
$(top_srcdir)
/depcomp
am__depfiles_maybe
=
depfiles
@AMDEP_TRUE@
DEP_FILES
=
./
$(DEPDIR)
/asn1c.Po
\
@AMDEP_TRUE@ ./
$(DEPDIR)
/tlv_decoder.Po
@AMDEP_TRUE@
DEP_FILES
=
./
$(DEPDIR)
/asn1c.Po ./
$(DEPDIR)
/unber.Po
COMPILE
=
$(CC)
$(DEFS)
$(DEFAULT_INCLUDES)
$(INCLUDES)
$(AM_CPPFLAGS)
\
$(CPPFLAGS)
$(AM_CFLAGS)
$(CFLAGS)
LTCOMPILE
=
$(LIBTOOL)
--mode
=
compile
$(CC)
$(DEFS)
\
...
...
@@ -71,8 +72,8 @@ LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) \
CCLD
=
$(CC)
LINK
=
$(LIBTOOL)
--mode
=
link
$(CCLD)
$(AM_CFLAGS)
$(CFLAGS)
\
$(AM_LDFLAGS)
$(LDFLAGS)
-o
$@
SOURCES
=
$(asn1c_SOURCES)
DIST_SOURCES
=
$(asn1c_SOURCES)
SOURCES
=
asn1c.c unber.c
DIST_SOURCES
=
asn1c.c unber.c
RECURSIVE_TARGETS
=
all-recursive check-recursive dvi-recursive
\
html-recursive info-recursive install-data-recursive
\
install-exec-recursive install-info-recursive
\
...
...
@@ -205,16 +206,13 @@ AM_CPPFLAGS = \
-I
${top_srcdir}
/skeletons
\
-DDATADIR
=
\"
$(pkgdatadir)
\"
LDADD
=
\
asn1c_
LDADD
=
\
$(top_builddir)
/libasn1parser/libasn1parser.la
\
$(top_builddir)
/libasn1print/libasn1print.la
\
$(top_builddir)
/libasn1fix/libasn1fix.la
\
$(top_builddir)
/libasn1compiler/libasn1compiler.la
asn1c_SOURCES
=
asn1c.c
\
tlv_decoder.c tlv_decoder.h
dist_man1_MANS
=
asn1c.1
dist_man1_MANS
=
asn1c.1 unber.1
check_SCRIPTS
=
check-parsing.sh
TESTS
=
check-parsing.sh
EXTRA_DIST
=
check-parsing.sh
...
...
@@ -283,6 +281,9 @@ clean-binPROGRAMS:
asn1c$(EXEEXT)
:
$(asn1c_OBJECTS) $(asn1c_DEPENDENCIES)
@
rm
-f
asn1c
$(EXEEXT)
$(LINK)
$(asn1c_LDFLAGS)
$(asn1c_OBJECTS)
$(asn1c_LDADD)
$(LIBS)
unber$(EXEEXT)
:
$(unber_OBJECTS) $(unber_DEPENDENCIES)
@
rm
-f
unber
$(EXEEXT)
$(LINK)
$(unber_LDFLAGS)
$(unber_OBJECTS)
$(unber_LDADD)
$(LIBS)
mostlyclean-compile
:
-
rm
-f
*
.
$(OBJEXT)
...
...
@@ -291,7 +292,7 @@ distclean-compile:
-
rm
-f
*
.tab.c
@AMDEP_TRUE@@am__include@
@am__quote@./$(DEPDIR)/asn1c.Po@am__quote@
@AMDEP_TRUE@@am__include@
@am__quote@./$(DEPDIR)/
tlv_decod
er.Po@am__quote@
@AMDEP_TRUE@@am__include@
@am__quote@./$(DEPDIR)/
unb
er.Po@am__quote@
.c.o
:
@am__fastdepCC_TRUE@
if
$(COMPILE)
-MT
$@
-MD
-MP
-MF
"$(DEPDIR)/$*.Tpo"
-c
-o
$@
$<;
\
...
...
asn1c/README
View file @
06b8d7aa
The ASN.1 Compiler
asn1c - The ASN.1 Compiler
unber - The ASN.1 BER Decoder
asn1c/asn1c.1
View file @
06b8d7aa
...
...
@@ -4,9 +4,8 @@
.TH ASN1C 1 "\*(Dt" "ASN.1 Compiler" "ASN.1 Compiler"
.SH NAME
asn1c \- ASN.1 Compiler
.ND ASN.1 compiler
.SH SYNOPSIS
asn1c [\fB\-E\fR [\fB-F\fR] | \fB\-P\fR | \fB\-R\fR
| \fB\-t\fR\fIdata-string\fR
]
asn1c [\fB\-E\fR [\fB-F\fR] | \fB\-P\fR | \fB\-R\fR]
[\fB\-S\fR\fIdir\fR]
[\fB\-W\fR\fIdebug-\fR...] [\fB\-f\fR\fIoption\fR...] [\fB\-p\fR\fIrint-\fR...]
\fIinfile\fR...
...
...
@@ -19,7 +18,6 @@ and other encoding standards.
\fIOverall Options\fR
\fB\-E \-F \-P \-R\fR
.BI "\-S " directory
.BI "\-t " data-string
.TP
\fIWarning Options\fR
.br
...
...
@@ -55,10 +53,6 @@ omitting the usual support code.
.TP
\fB\-S\fR \fIdirectory\fR
Use the specified directory with ASN.1 skeleton files.
.TP
\fB\-t\fR \fIdata-string\fR
Interpret the data-string as a sequence of hexadecimal values representing
the start of BER TLV encoding. Print the human readable explanation.
.SH WARNING OPTIONS
.TP
.B \-Werror
...
...
@@ -104,5 +98,8 @@ its internal understanding of subtype constraints.
.TP
.B \-print-lines
Generate "-- #line" comments in \fB-E\fR output.
.SH SEE ALSO
.TP
\&\fIunber\fR\|(1)
.SH AUTHORS
Lev Walkin <vlm@lionet.info>
asn1c/asn1c.c
View file @
06b8d7aa
...
...
@@ -19,9 +19,7 @@
#include <asn1c_compat.h>
/* Portable basename(3) and dirname(3) */
#include "tlv_decoder.h"
/* -t: decode TL[V?] string */
static
void
usage
(
char
*
av0
);
/* Print the Usage screen and exit(EX_USAGE) */
static
void
usage
(
const
char
*
av0
);
/* Print the Usage screen and exit */
#undef COPYRIGHT
#define COPYRIGHT \
...
...
@@ -45,7 +43,7 @@ main(int ac, char **av) {
/*
* Process command-line options.
*/
while
((
ch
=
getopt
(
ac
,
av
,
"EFf:hLPp:RS:
t:
vW:"
))
!=
-
1
)
while
((
ch
=
getopt
(
ac
,
av
,
"EFf:hLPp:RS:vW:"
))
!=
-
1
)
switch
(
ch
)
{
case
'E'
:
print_arg__print_out
=
1
;
...
...
@@ -97,10 +95,6 @@ main(int ac, char **av) {
case
'S'
:
skeletons_dir
=
optarg
;
break
;
case
't'
:
if
(
decode_tlv_from_string
(
optarg
))
exit
(
EX_DATAERR
);
exit
(
0
);
case
'v'
:
fprintf
(
stderr
,
"ASN.1 Compiler, v"
VERSION
"
\n
"
COPYRIGHT
);
exit
(
0
);
...
...
@@ -264,11 +258,11 @@ main(int ac, char **av) {
* Print the usage screen and exit(EX_USAGE).
*/
static
void
usage
(
char
*
av0
)
{
usage
(
c
onst
c
har
*
av0
)
{
fprintf
(
stderr
,
"ASN.1 Compiler, v"
VERSION
"
\n
"
COPYRIGHT
"Usage: %s [options]
infile
...
\n
"
"
Where [options] are
:
\n
"
"Usage: %s [options]
file
...
\n
"
"
Options
:
\n
"
" -E Run only the ASN.1 parser and print out the tree
\n
"
" -F During -E operation, also perform tree fixing
\n
"
"
\n
"
...
...
@@ -278,10 +272,6 @@ usage(char *av0) {
" (Default is
\"
%s
\"
)
\n
"
"
\n
"
" -t <data-string> Decode the given tag[/length] sequence
\n
"
" (e.g. -t
\"
bf 20
\"
)
\n
"
"
\n
"
" -Werror Treat warnings as errors; abort if any warning
\n
"
" -Wdebug-lexer Enable verbose debugging output from lexer
\n
"
" -Wdebug-fixer --//-- semantics processor
\n
"
...
...
asn1c/unber.c
0 → 100644
View file @
06b8d7aa
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <sysexits.h>
/* for EX_USAGE */
#include <assert.h>
#include <errno.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <asn1parser.h>
/* For static string tables */
#include <asn_types.h>
#include <ber_tlv_tag.h>
#include <ber_tlv_length.h>
#include <ber_tlv_tag.c>
#include <ber_tlv_length.c>
static
void
usage
(
const
char
*
av0
);
/* Print the Usage screen and exit */
static
int
process
(
const
char
*
fname
);
/* Perform the BER decoding */
static
int
decode_tlv_from_string
(
const
char
*
datastring
);
#undef COPYRIGHT
#define COPYRIGHT \
"Copyright (c) 2004 Lev Walkin <vlm@lionet.info>\n"
static
char
*
indent_buffer
=
" "
;
int
main
(
int
ac
,
char
**
av
)
{
int
ch
;
/* Command line character */
int
i
;
/* Index in some loops */
/*
* Process command-line options.
*/
while
((
ch
=
getopt
(
ac
,
av
,
"i:t:v"
))
!=
-
1
)
switch
(
ch
)
{
case
't'
:
if
(
decode_tlv_from_string
(
optarg
))
exit
(
EX_DATAERR
);
exit
(
0
);
case
'i'
:
i
=
atoi
(
optarg
);
if
(
i
>=
0
&&
i
<
16
)
{
indent_buffer
=
alloca
(
i
+
1
);
memset
(
indent_buffer
,
' '
,
i
);
indent_buffer
[
i
]
=
'\0'
;
}
else
{
fprintf
(
stderr
,
"-i %s: Invalid indent value
\n
"
,
optarg
);
exit
(
EX_USAGE
);
}
break
;
case
'v'
:
fprintf
(
stderr
,
"ASN.1 BER Decoder, v"
VERSION
"
\n
"
COPYRIGHT
);
exit
(
0
);
break
;
default:
usage
(
av
[
0
]);
}
/*
* Ensure that there are some input files present.
*/
if
(
ac
>
optind
)
{
ac
-=
optind
;
av
+=
optind
;
}
else
{
fprintf
(
stderr
,
"%s: No input files specified
\n
"
,
av
[
0
]);
exit
(
1
);
}
setvbuf
(
stdout
,
0
,
_IOLBF
,
0
);
/*
* Iterate over input files and parse each.
* All syntax trees from all files will be bundled together.
*/
for
(
i
=
0
;
i
<
ac
;
i
++
)
{
if
(
process
(
av
[
i
]))
exit
(
EX_DATAERR
);
}
return
0
;
}
/*
* Print the usage screen and exit(EX_USAGE).
*/
static
void
usage
(
const
char
*
av0
)
{
fprintf
(
stderr
,
"ASN.1 BER Decoder, v"
VERSION
"
\n
"
COPYRIGHT
"Usage: %s [options] [-] [file ...]
\n
"
"Options:
\n
"
" -i <indent> Amount of spaces for indentation (default is 4)
\n
"
" -t <data-string> Decode the given tag[/length] sequence
\n
"
" (e.g. -t
\"
bf 20
\"
)
\n
"
,
av0
);
exit
(
EX_USAGE
);
}
typedef
enum
pd_code
{
PD_FAILED
=
-
1
,
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
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
);
/*
* Open the file and initiate recursive processing.
*/
static
int
process
(
const
char
*
fname
)
{
FILE
*
fp
;
pd_code_e
pdc
;
if
(
strcmp
(
fname
,
"-"
))
{
fp
=
fopen
(
fname
,
"r"
);
if
(
!
fp
)
{
perror
(
fname
);
return
-
1
;
}
}
else
{
fp
=
stdin
;
}
/*
* Fetch out BER-encoded data until EOF or error.
*/
do
{
pdc
=
process_deeper
(
fname
,
fp
,
0
,
-
1
);
}
while
(
pdc
==
PD_FINISHED
);
/* Wait until PD_EOF */
if
(
fp
!=
stdin
)
fclose
(
fp
);
if
(
pdc
==
PD_FAILED
)
return
-
1
;
return
0
;
}
/*
* Process the TLV recursively.
*/
static
pd_code_e
process_deeper
(
const
char
*
fname
,
FILE
*
fp
,
int
level
,
ssize_t
limit
)
{
unsigned
char
tagbuf
[
32
];
ssize_t
tblen
=
0
;
pd_code_e
pdc
=
PD_FINISHED
;
ber_tlv_tag_t
tlv_tag
;
ber_tlv_len_t
tlv_len
;
ssize_t
t_len
;
ssize_t
l_len
;
do
{
int
constr
;
int
ch
;
if
(
limit
==
0
)
return
PD_FINISHED
;
if
(
limit
>=
0
&&
tblen
>=
limit
)
{
fprintf
(
stderr
,
"%s: Too long TL sequence (%ld >= %ld). "
"Dangerous file
\n
"
,
fname
,
(
long
)
tblen
,
(
long
)
limit
);
return
PD_FAILED
;
}
ch
=
fgetc
(
fp
);
if
(
ch
==
-
1
)
{
if
(
tblen
)
{
fprintf
(
stderr
,
"%s: Unexpected end of file (TL)
\n
"
,
fname
);
return
PD_FAILED
;
}
else
{
return
PD_EOF
;
}
}
tagbuf
[
tblen
++
]
=
ch
;
/*
* Decode the TLV tag.
*/
t_len
=
ber_fetch_tag
(
tagbuf
,
tblen
,
&
tlv_tag
);
switch
(
t_len
)
{
case
-
1
:
fprintf
(
stderr
,
"%s: Fatal error deciphering tag
\n
"
,
fname
);
return
PD_FAILED
;
case
0
:
/* More data expected */
continue
;
}
/*
* Decode the TLV length.
*/
constr
=
BER_TLV_CONSTRUCTED
(
tagbuf
);
l_len
=
ber_fetch_length
(
constr
,
tagbuf
+
t_len
,
tblen
-
t_len
,
&
tlv_len
);
switch
(
l_len
)
{
case
-
1
:
fprintf
(
stderr
,
"%s: Fatal error deciphering length
\n
"
,
fname
);
return
PD_FAILED
;
case
0
:
/* More data expected */
continue
;
}
/* 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
(
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
;
}
}
if
(
constr
)
{
/*
* This is a constructed type. Process recursively.
*/
/* Get the new subframe limit from the structure tags */
if
(
tlv_len
==
-
1
)
tlv_len
=
limit
;
pdc
=
process_deeper
(
fname
,
fp
,
level
+
1
,
tlv_len
);
if
(
pdc
==
PD_FAILED
)
return
pdc
;
}
else
{
assert
(
tlv_len
>=
0
);
if
(
print_V
(
fname
,
fp
,
tlv_tag
,
tlv_len
))
return
PD_FAILED
;
}
print_TL
(
1
,
level
,
constr
,
tblen
,
tlv_tag
,
tlv_len
);
tblen
=
0
;
}
while
(
1
);
return
pdc
;
}
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
)
{
if
(
fin
&&
tlen
==
2
&&
!
constr
&&
!
tlv_tag
&&
!
tlv_len
)
{
/* end of content octets */
return
;
}
if
(
fin
&&
!
constr
)
{
printf
(
"</P>
\n
"
);
return
;
}
while
(
level
--
>
0
)
printf
(
indent_buffer
);
/* Print indent */
printf
(
fin
?
"</"
:
"<"
);
printf
(
constr
?
"C"
:
"P"
);
printf
(
" T=
\"
"
);
ber_tlv_tag_fwrite
(
tlv_tag
,
stdout
);
printf
(
"
\"
"
);
if
(
!
fin
)
{
printf
(
" tL=
\"
%ld
\"
"
,
(
long
)
tlen
);
if
(
tlv_len
==
-
1
)
printf
(
" L=
\"
Indefinite
\"
"
);
else
printf
(
" L=
\"
%ld
\"
"
,
(
long
)
tlv_len
);
}
if
(
BER_TAG_CLASS
(
tlv_tag
)
==
ASN_TAG_CLASS_UNIVERSAL
)
{
const
char
*
str
;
ber_tlv_tag_t
tvalue
=
BER_TAG_VALUE
(
tlv_tag
);
str
=
ASN_UNIVERSAL_TAG2STR
(
tvalue
);
if
(
str
)
printf
(
" A=
\"
%s
\"
"
,
str
);
}
if
(
fin
||
constr
)
printf
(
">
\n
"
);
else
printf
(
">"
);
}
static
int
print_V
(
const
char
*
fname
,
FILE
*
fp
,
ber_tlv_tag_t
tlv_tag
,
ber_tlv_len_t
tlv_len
)
{
asn1p_expr_type_e
etype
=
0
;
long
collector
=
0
;
ssize_t
i
;
/* Figure out what type is it */
if
(
BER_TAG_CLASS
(
tlv_tag
)
==
ASN_TAG_CLASS_UNIVERSAL
)
{
ber_tlv_tag_t
tvalue
=
BER_TAG_VALUE
(
tlv_tag
);
etype
=
ASN_UNIVERSAL_TAG2TYPE
(
tvalue
);
}
/*
* Print the value in binary or text form.
*/
for
(
i
=
0
;
i
<
tlv_len
;
i
++
)
{
int
ch
=
fgetc
(
fp
);
if
(
ch
==
-
1
)
{
fprintf
(
stderr
,
"%s: Unexpected end of file (V)
\n
"
,
fname
);
return
-
1
;
}
switch
(
etype
)
{
case
ASN_BASIC_UTCTime
:
case
ASN_BASIC_GeneralizedTime
:
case
ASN_STRING_NumericString
:
case
ASN_STRING_PrintableString
:
case
ASN_STRING_VisibleString
:
case
ASN_STRING_UTF8String
:
switch
(
ch
)
{
default:
if
(((
etype
==
ASN_STRING_UTF8String
)
||
!
(
ch
&
0x80
))
&&
(
ch
>=
0x20
)
)
{
printf
(
"%c"
,
ch
);
break
;
}
/* Fall through */
case
'<'
:
case
'>'
:
case
'&'
:
printf
(
"&x%02x;"
,
ch
);
}
break
;
case
ASN_BASIC_BOOLEAN
:
if
(
tlv_len
==
1
)
{
switch
(
ch
)
{
case
0
:
printf
(
"<false/>"
);
break
;
case
0xff
:
printf
(
"<true/>"
);
break
;
default:
printf
(
"<true value=
\"
&x%02x
\"
/>"
,
ch
);
}
break
;
}
/* Fall through */
case
ASN_BASIC_INTEGER
:
case
ASN_BASIC_ENUMERATED
:
if
((
size_t
)
tlv_len
<=
sizeof
(
collector
))
{
if
(
i
)
{
collector
=
collector
*
256
+
ch
;
}
else
{
collector
=
(
int
)(
signed
char
)
ch
;
}
if
((
i
+
1
)
==
tlv_len
)
printf
(
"%ld"
,
collector
);
break
;
}
/* Fall through */
default:
printf
(
"&x%02x;"
,
ch
);
}
}
return
0
;
}
static
int
decode_tlv_from_string
(
const
char
*
datastring
)
{
unsigned
char
*
data
,
*
dp
;
size_t
dsize
;
/* Data size */
ssize_t
len
;
ber_tlv_tag_t
tlv_tag
;
ber_tlv_len_t
tlv_len
;
const
char
*
p
;
int
half
;
dsize
=
strlen
(
datastring
)
+
1
;
dp
=
data
=
calloc
(
1
,
dsize
);
assert
(
data
);
for
(
half
=
0
,
p
=
datastring
;
*
p
;
p
++
)
{
switch
(
*
p
)
{
case
'0'
:
case
'1'
:
case
'2'
:
case
'3'
:
case
'4'
:
case
'5'
:
case
'6'
:
case
'7'
:
case
'8'
:
case
'9'
:
*
dp
|=
*
p
-
'0'
;
break
;
case
'A'
:
case
'B'
:
case
'C'
:
case
'D'
:
case
'E'
:
case
'F'
:
*
dp
|=
*
p
-
'A'
+
10
;
break
;
case
'a'
:
case
'b'
:
case
'c'
:
case
'd'
:
case
'e'
:
case
'f'
:
*
dp
|=
*
p
-
'a'
+
10
;
break
;
case
' '
:
case
'\t'
:
case
'\r'
:
case
'\n'
:
continue
;
default:
fprintf
(
stderr
,
"Unexpected symbols in data string:
\n
"
);
fprintf
(
stderr
,
"%s
\n
"
,
datastring
);
for
(
dp
=
data
;
datastring
<
p
;
datastring
++
,
dp
++
)
*
dp
=
' '
;
*
dp
=
'\0'
;
fprintf
(
stderr
,
"%s^ <- here
\n
"
,
(
char
*
)
data
);
return
-
1
;
}
if
(
half
)
dp
++
;
else
(
*
dp
)
<<=
4
;
half
=
!
half
;
}
assert
((
size_t
)(
dp
-
data
)
<=
dsize
);
dsize
=
dp
-
data
;
printf
(
"BER: "
);
for
(
dp
=
data
;
dp
<
data
+
dsize
;
dp
++
)
printf
(
"%02X"
,
*
dp
);
printf
(
"
\n
"
);
len
=
ber_fetch_tag
(
data
,
dsize
,
&
tlv_tag
);
switch
(
len
)
{
case
-
1
:
fprintf
(
stderr
,
"TAG: Fatal error deciphering tag
\n
"
);
return
-
1
;
case
0
:
fprintf
(
stderr
,
"TAG: More data expected
\n
"
);
return
-
1
;
default:
printf
(
"TAG: "
);
ber_tlv_tag_fwrite
(
tlv_tag
,
stdout
);
if
(
BER_TLV_CONSTRUCTED
(
data
))
{
printf
(
" (constructed)"
);
}
else
if
(
dsize
>=
2
&&
data
[
0
]
==
0
&&
data
[
1
]
==
0
)
{
printf
(
" (end-of-content)"
);
}
else
{
printf
(
" (primitive)"
);
}
if
(
BER_TAG_CLASS
(
tlv_tag
)
==
ASN_TAG_CLASS_UNIVERSAL
)
{
const
char
*
str
;
ber_tlv_tag_t
tvalue
=
BER_TAG_VALUE
(
tlv_tag
);
str
=
ASN_UNIVERSAL_TAG2STR
(
tvalue
);
if
(
str
)
printf
(
"
\"
%s
\"
"
,
str
);
}
printf
(
"
\n
"
);
}
if
(
dsize
>
(
size_t
)
len
)
{
len
=
ber_fetch_length
(
BER_TLV_CONSTRUCTED
(
data
),
data
+
len
,
dsize
-
len
,
&
tlv_len
);
switch
(
len
)
{
case
-
1
:
fprintf
(
stderr
,
"LEN: Fatal error deciphering length
\n
"
);
return
-
1
;
case
0
:
fprintf
(
stderr
,
"LEN: More data expected
\n
"
);
return
-
1
;
default:
if
(
tlv_len
==
(
ber_tlv_len_t
)
-
1
)
printf
(
"LEN: Indefinite length encoding
\n
"
);
else
printf
(
"LEN: %ld bytes
\n
"
,
(
long
)
tlv_len
);
}
}
return
0
;
}
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