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
12984671
Commit
12984671
authored
Sep 24, 2004
by
Lev Walkin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
unber and enber
parent
5beb7deb
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
778 additions
and
63 deletions
+778
-63
asn1c/Makefile.am
asn1c/Makefile.am
+3
-3
asn1c/Makefile.in
asn1c/Makefile.in
+15
-7
asn1c/asn1c.1
asn1c/asn1c.1
+1
-4
asn1c/asn1c.c
asn1c/asn1c.c
+27
-0
asn1c/enber.1
asn1c/enber.1
+29
-0
asn1c/enber.c
asn1c/enber.c
+381
-0
asn1c/unber.1
asn1c/unber.1
+79
-6
asn1c/unber.c
asn1c/unber.c
+243
-43
No files found.
asn1c/Makefile.am
View file @
12984671
SUBDIRS
=
.
tests webcgi
SUBDIRS
=
.
webcgi tests
AM_CFLAGS
=
@ADD_CFLAGS@
AM_CPPFLAGS
=
\
...
...
@@ -16,9 +16,9 @@ asn1c_LDADD = \
$(top_builddir)
/libasn1fix/libasn1fix.la
\
$(top_builddir)
/libasn1compiler/libasn1compiler.la
bin_PROGRAMS
=
asn1c unber
bin_PROGRAMS
=
asn1c unber
enber
dist_man1_MANS
=
asn1c.1 unber.1
dist_man1_MANS
=
asn1c.1 unber.1
enber.1
check_SCRIPTS
=
check-parsing.sh
TESTS
=
check-parsing.sh
...
...
asn1c/Makefile.in
View file @
12984671
...
...
@@ -14,7 +14,7 @@
@SET_MAKE@
SOURCES
=
asn1c.c unber.c
SOURCES
=
asn1c.c
enber.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)
unber
$(EXEEXT)
bin_PROGRAMS
=
asn1c
$(EXEEXT)
unber
$(EXEEXT)
enber
$(EXEEXT)
subdir
=
asn1c
DIST_COMMON
=
README
$(dist_man1_MANS)
$(srcdir)
/Makefile.am
\
$(srcdir)
/Makefile.in
...
...
@@ -57,13 +57,17 @@ asn1c_DEPENDENCIES = $(top_builddir)/libasn1parser/libasn1parser.la \
$(top_builddir)
/libasn1print/libasn1print.la
\
$(top_builddir)
/libasn1fix/libasn1fix.la
\
$(top_builddir)
/libasn1compiler/libasn1compiler.la
enber_SOURCES
=
enber.c
enber_OBJECTS
=
enber.
$(OBJEXT)
enber_LDADD
=
$(LDADD)
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 ./
$(DEPDIR)
/unber.Po
@AMDEP_TRUE@
DEP_FILES
=
./
$(DEPDIR)
/asn1c.Po ./
$(DEPDIR)
/enber.Po
\
@AMDEP_TRUE@ ./
$(DEPDIR)
/unber.Po
COMPILE
=
$(CC)
$(DEFS)
$(DEFAULT_INCLUDES)
$(INCLUDES)
$(AM_CPPFLAGS)
\
$(CPPFLAGS)
$(AM_CFLAGS)
$(CFLAGS)
LTCOMPILE
=
$(LIBTOOL)
--mode
=
compile
$(CC)
$(DEFS)
\
...
...
@@ -72,8 +76,8 @@ LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) \
CCLD
=
$(CC)
LINK
=
$(LIBTOOL)
--mode
=
link
$(CCLD)
$(AM_CFLAGS)
$(CFLAGS)
\
$(AM_LDFLAGS)
$(LDFLAGS)
-o
$@
SOURCES
=
asn1c.c unber.c
DIST_SOURCES
=
asn1c.c unber.c
SOURCES
=
asn1c.c
enber.c
unber.c
DIST_SOURCES
=
asn1c.c
enber.c
unber.c
RECURSIVE_TARGETS
=
all-recursive check-recursive dvi-recursive
\
html-recursive info-recursive install-data-recursive
\
install-exec-recursive install-info-recursive
\
...
...
@@ -196,7 +200,7 @@ target_alias = @target_alias@
target_cpu
=
@target_cpu@
target_os
=
@target_os@
target_vendor
=
@target_vendor@
SUBDIRS
=
.
tests webcgi
SUBDIRS
=
.
webcgi tests
AM_CFLAGS
=
@ADD_CFLAGS@
AM_CPPFLAGS
=
\
-I
${top_srcdir}
/libasn1compiler
\
...
...
@@ -212,7 +216,7 @@ asn1c_LDADD = \
$(top_builddir)
/libasn1fix/libasn1fix.la
\
$(top_builddir)
/libasn1compiler/libasn1compiler.la
dist_man1_MANS
=
asn1c.1 unber.1
dist_man1_MANS
=
asn1c.1 unber.1
enber.1
check_SCRIPTS
=
check-parsing.sh
TESTS
=
check-parsing.sh
EXTRA_DIST
=
check-parsing.sh
...
...
@@ -281,6 +285,9 @@ clean-binPROGRAMS:
asn1c$(EXEEXT)
:
$(asn1c_OBJECTS) $(asn1c_DEPENDENCIES)
@
rm
-f
asn1c
$(EXEEXT)
$(LINK)
$(asn1c_LDFLAGS)
$(asn1c_OBJECTS)
$(asn1c_LDADD)
$(LIBS)
enber$(EXEEXT)
:
$(enber_OBJECTS) $(enber_DEPENDENCIES)
@
rm
-f
enber
$(EXEEXT)
$(LINK)
$(enber_LDFLAGS)
$(enber_OBJECTS)
$(enber_LDADD)
$(LIBS)
unber$(EXEEXT)
:
$(unber_OBJECTS) $(unber_DEPENDENCIES)
@
rm
-f
unber
$(EXEEXT)
$(LINK)
$(unber_LDFLAGS)
$(unber_OBJECTS)
$(unber_LDADD)
$(LIBS)
...
...
@@ -292,6 +299,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)/enber.Po@am__quote@
@AMDEP_TRUE@@am__include@
@am__quote@./$(DEPDIR)/unber.Po@am__quote@
.c.o
:
...
...
asn1c/asn1c.1
View file @
12984671
.de Id
..
.Id $Id"
.TH ASN1C 1 "\*(Dt" "ASN.1 Compiler" "ASN.1 Compiler"
.SH NAME
asn1c \- ASN.1 Compiler
...
...
@@ -100,6 +97,6 @@ its internal understanding of subtype constraints.
Generate "-- #line" comments in \fB-E\fR output.
.SH SEE ALSO
.TP
\&\fIunber\fR\|(1)
\&\fIunber\fR\|(1)
, \&\fIenber\fR\|(1)
.SH AUTHORS
Lev Walkin <vlm@lionet.info>
asn1c/asn1c.c
View file @
12984671
/*-
* Copyright (c) 2003, 2004 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
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
*/
/*
* This is the program that connects the libasn1* libraries together.
* It uses them in turn to parse, fix and then compile or print the ASN.1 tree.
...
...
asn1c/enber.1
0 → 100644
View file @
12984671
.de Vb
.sp
.ft CW
.nf
..
.de Ve
.ft R
.fi
.sp
..
.TH ENBER 1 "\*(Dt" "unber counterpart" "unber counterpart"
.SH NAME
enber \- Convert the unber XML output back into BER
.SH SYNOPSIS
enber [\fB-\fR] \fIinfile\fR...
.SH DESCRIPTION
enber takes the XML-encoded files produced by \fIunber\fR\|(1) and converts
them back into the BER format.
A single dash represents the standard input.
.SH EXAMPLES
Decode the BER sequence and immediately encode it back
.Vb
\& enber \fB-p\fR \fIfilename.ber\fR | unber \fB-\fR > \fIreconstructed.ber\fR
.Ve
.SH SEE ALSO
.TP
\&\fIunber\fR\|(1), \&\fIasn1c\fR\|(1)
.SH AUTHORS
Lev Walkin <vlm@lionet.info>
asn1c/enber.c
0 → 100644
View file @
12984671
/*-
* Copyright (c) 2004 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
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
*/
#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_application.h>
#include <constraints.c>
#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
process_line
(
const
char
*
fname
,
char
*
line
,
int
lineno
);
#undef COPYRIGHT
#define COPYRIGHT \
"Copyright (c) 2004 Lev Walkin <vlm@lionet.info>\n"
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
,
"hv"
))
!=
-
1
)
switch
(
ch
)
{
case
'v'
:
fprintf
(
stderr
,
"ASN.1 BER Decoder, v"
VERSION
"
\n
"
COPYRIGHT
);
exit
(
0
);
break
;
case
'h'
:
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
,
"Convertor of under(1) output back into BER, v"
VERSION
"
\n
"
COPYRIGHT
"Usage: %s [-] [file ...]
\n
"
,
av0
);
exit
(
EX_USAGE
);
}
/*
* Open the file and initiate recursive processing.
*/
static
int
process
(
const
char
*
fname
)
{
char
buf
[
8192
];
char
*
collector
=
0
;
size_t
collector_size
=
sizeof
(
buf
);
size_t
collector_offset
=
0
;
int
lineno
=
0
;
FILE
*
fp
;
if
(
strcmp
(
fname
,
"-"
))
{
fp
=
fopen
(
fname
,
"r"
);
if
(
!
fp
)
{
perror
(
fname
);
return
-
1
;
}
}
else
{
fp
=
stdin
;
}
while
(
fgets
(
buf
,
sizeof
(
buf
),
fp
)
||
!
feof
(
fp
))
{
size_t
len
=
strlen
(
buf
);
if
(
!
len
)
continue
;
if
(
collector_offset
||
buf
[
len
-
1
]
!=
'\n'
)
{
if
((
collector_size
-
collector_offset
)
<=
len
||
!
collector
)
{
collector_size
<<=
1
;
collector
=
realloc
(
collector
,
collector_size
);
if
(
!
collector
)
{
perror
(
"realloc()"
);
exit
(
EX_OSERR
);
}
}
memcpy
(
collector
+
collector_offset
,
buf
,
len
+
1
);
collector_offset
+=
len
;
}
if
(
buf
[
len
-
1
]
!=
'\n'
)
continue
;
if
(
collector_offset
)
{
assert
(
collector
[
collector_offset
-
1
]
==
'\n'
);
process_line
(
fname
,
collector
,
++
lineno
);
collector_offset
=
0
;
}
else
{
process_line
(
fname
,
buf
,
++
lineno
);
}
}
if
(
fp
!=
stdin
)
fclose
(
fp
);
return
0
;
}
static
int
process_line
(
const
char
*
fname
,
char
*
line
,
int
lineno
)
{
char
buf
[
32
];
char
*
op
;
/* '<' */
char
*
cl
;
/* '>' */
char
*
tcl_pos
;
/* tag class position */
char
*
tl_pos
;
char
*
v_pos
;
int
constr
;
ber_tlv_tag_t
tag_value
;
ber_tlv_tag_t
tag_class
;
ber_tlv_tag_t
tlv_tag
;
ber_tlv_len_t
tlv_len
;
ber_tlv_len_t
tl_len
;
ssize_t
ret
;
(
void
)
fname
;
/* Find a tag opening angle bracket */
for
(;
*
line
==
' '
;
line
++
);
op
=
line
;
if
(
*
op
!=
'<'
)
{
fprintf
(
stderr
,
"%s: Missing '<' after whitespace
\n
"
,
fname
);
exit
(
EX_DATAERR
);
}
/* Find a tag closing angle bracket */
for
(;
*
line
&&
*
line
!=
'>'
;
line
++
)
{
if
(
*
line
<
' '
)
{
fprintf
(
stderr
,
"%s: Invalid charset (%d)
\n
"
,
fname
,
*
(
const
unsigned
char
*
)
line
);
exit
(
EX_DATAERR
);
}
}
cl
=
line
;
if
(
*
cl
!=
'>'
)
{
fprintf
(
stderr
,
"%s: Missing '>'
\n
"
,
fname
);
exit
(
EX_DATAERR
);
}
/* Ignore closing tags */
if
(
op
[
1
]
==
'/'
)
{
if
(
strchr
(
cl
,
'<'
))
{
/* We are not very robust */
fprintf
(
stderr
,
"%s: Multiple tags per line
\n
"
,
fname
);
exit
(
EX_DATAERR
);
}
/* End-of-content octets */
if
(
op
[
2
]
==
'I'
)
{
buf
[
0
]
=
buf
[
1
]
=
0x00
;
fwrite
(
buf
,
1
,
2
,
stdout
);
}
return
0
;
}
switch
(
op
[
1
])
{
case
'C'
:
constr
=
1
;
break
;
case
'P'
:
constr
=
0
;
break
;
case
'I'
:
constr
=
2
;
break
;
default:
fprintf
(
stderr
,
"%s: Expected
\"
C
\"
/
\"
P
\"
/
\"
I
\"
as the XML tag name (%c)
\n
"
,
fname
,
op
[
1
]);
exit
(
EX_DATAERR
);
}
*
cl
=
'\0'
;
if
(
cl
[
-
1
]
==
'F'
)
{
fprintf
(
stderr
,
"%s: Uses pretty-printing of values. "
"Use -p option to unber
\n
"
,
fname
);
exit
(
EX_DATAERR
);
}
tcl_pos
=
strstr
(
op
,
"T=
\"
["
);
tl_pos
=
strstr
(
op
,
"TL=
\"
"
);
v_pos
=
strstr
(
op
,
"V=
\"
"
);
if
(
!
tcl_pos
||
!
tl_pos
||
!
v_pos
)
{
fprintf
(
stderr
,
"%s: Mandatory attribute %s is not found at line %d
\n
"
,
fname
,
(
!
tcl_pos
)
?
"T"
:
(
v_pos
?
"V"
:
"TCL"
),
lineno
);
exit
(
EX_DATAERR
);
}
errno
=
0
;
tl_len
=
strtoul
(
tl_pos
+
4
,
0
,
10
);
if
(
constr
==
2
)
{
tlv_len
=
0
;
}
else
{
tlv_len
=
strtoul
(
v_pos
+
3
,
0
,
10
);
}
if
(
errno
||
tl_len
<
2
||
tlv_len
<
0
)
{
fprintf
(
stderr
,
"%s: Invalid TL or V value at line %d
\n
"
,
fname
,
lineno
);
exit
(
EX_DATAERR
);
}
tcl_pos
+=
4
;
switch
(
*
tcl_pos
)
{
case
'U'
:
/* UNIVERSAL */
tag_class
=
ASN_TAG_CLASS_UNIVERSAL
;
break
;
case
'P'
:
/* PRIVATE */
tag_class
=
ASN_TAG_CLASS_PRIVATE
;
break
;
case
'A'
:
/* APPLICATION */
tag_class
=
ASN_TAG_CLASS_APPLICATION
;
break
;
case
'0'
:
case
'1'
:
case
'2'
:
case
'3'
:
case
'4'
:
case
'5'
:
case
'6'
:
case
'7'
:
case
'8'
:
case
'9'
:
/* context */
tag_class
=
ASN_TAG_CLASS_CONTEXT
;
break
;
default:
fprintf
(
stderr
,
"%s: Invalid tag class (%c) at line %d
\n
"
,
fname
,
tcl_pos
[
4
],
lineno
);
exit
(
EX_DATAERR
);
}
for
(;;
tcl_pos
++
)
{
switch
(
*
tcl_pos
)
{
case
'"'
:
tcl_pos
=
""
;
case
'\0'
:
case
'0'
:
case
'1'
:
case
'2'
:
case
'3'
:
case
'4'
:
case
'5'
:
case
'6'
:
case
'7'
:
case
'8'
:
case
'9'
:
break
;
default:
continue
;
}
break
;
}
errno
=
0
;
if
(
!*
tcl_pos
||
((
long
)(
tag_value
=
strtoul
(
tcl_pos
,
0
,
10
)))
<
0
||
errno
)
{
fprintf
(
stderr
,
"%s: Invalid tag value (%c) at line %d
\n
"
,
fname
,
*
tcl_pos
,
lineno
);
exit
(
EX_DATAERR
);
}
tlv_tag
=
((
tag_value
<<
2
)
|
tag_class
);
if
(
0
)
{
printf
(
"[%s>]
\n
"
,
op
);
printf
(
" <%c T=
\"
%s
\"
TL=
\"
%d
\"
V=
\"
%d
\"
>
\n
"
,
constr
?
'C'
:
'P'
,
ber_tlv_tag_string
(
tlv_tag
),
tl_len
,
tlv_len
);
}
ret
=
ber_tlv_tag_serialize
(
tlv_tag
,
buf
,
sizeof
(
buf
));
assert
(
ret
>=
1
&&
(
size_t
)
ret
<
sizeof
(
buf
));
if
(
constr
==
2
)
{
buf
[
ret
]
=
0x80
;
ret
+=
1
;
}
else
{
ret
+=
der_tlv_length_serialize
(
tlv_len
,
buf
+
ret
,
sizeof
(
buf
)
-
ret
);
assert
(
ret
>=
2
&&
(
size_t
)
ret
<
sizeof
(
buf
));
}
if
(
ret
!=
tl_len
)
{
fprintf
(
stderr
,
"%s: Cannot encode TL at line %d "
"in the given number of bytes (%d!=%d)
\n
"
,
fname
,
lineno
,
ret
,
tl_len
);
exit
(
EX_DATAERR
);
}
if
(
constr
)
*
buf
|=
0x20
;
/* Enable "constructed" bit */
fwrite
(
buf
,
1
,
tl_len
,
stdout
);
if
(
!
constr
)
{
ber_tlv_len_t
len
;
for
(
len
=
0
,
cl
++
;
*
cl
&&
*
cl
!=
'<'
;
cl
++
,
len
++
)
{
unsigned
char
v
;
int
h
;
if
(
*
cl
!=
'&'
)
{
fputc
(
*
cl
,
stdout
);
continue
;
}
cl
++
;
if
(
*
cl
!=
'x'
)
{
fprintf
(
stderr
,
"%s: Expected
\"
&xNN;
\"
at line %d
\n
"
,
fname
,
lineno
);
exit
(
EX_DATAERR
);
}
for
(
v
=
0
,
h
=
0
;
h
<
2
;
h
++
)
{
unsigned
char
clv
=
*++
cl
;
v
<<=
4
;
switch
(
clv
)
{
case
'0'
:
case
'1'
:
case
'2'
:
case
'3'
:
case
'4'
:
case
'5'
:
case
'6'
:
case
'7'
:
case
'8'
:
case
'9'
:
v
|=
clv
-
'0'
;
break
;
case
'A'
:
case
'B'
:
case
'C'
:
case
'D'
:
case
'E'
:
case
'F'
:
v
|=
clv
-
'A'
+
10
;
break
;
case
'a'
:
case
'b'
:
case
'c'
:
case
'd'
:
case
'e'
:
case
'f'
:
v
|=
clv
-
'a'
+
10
;
break
;
default:
fprintf
(
stderr
,
"%s: Expected
\"
&xNN;
\"
at line %d (%c)
\n
"
,
fname
,
lineno
,
clv
);
exit
(
EX_DATAERR
);
}
}
cl
++
;
if
(
*
cl
!=
';'
)
{
fprintf
(
stderr
,
"%s: Expected
\"
&xNN;
\"
at line %d
\n
"
,
fname
,
lineno
);
exit
(
EX_DATAERR
);
}
fputc
(
v
,
stdout
);
}
if
(
len
!=
tlv_len
)
{
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
);
}
}
return
0
;
}
asn1c/unber.1
View file @
12984671
.de Id
.de Vb
.sp
.ft CW
.nf
..
.de Ve
.ft R
.fi
.sp
..
.Id $Id"
.TH UNBER 1 "\*(Dt" "ASN.1 BER Decoder" "ASN.1 BER Decoder"
.SH NAME
unber \- ASN.1 BER Decoder
.SH SYNOPSIS
unber [\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 to stdout.
(The DER and CER formats are both subsets of the BER, and are also supported.)
unber takes the BER-encoded files and dumps their internal structure as human readable text.
A single dash represents the standard input.
.sp
(The DER and CER formats are both subsets of the BER, and are also supported.)
.SH OPTIONS
.TP
\fB\-1\fR
Do \fInot\fR attempt to read the next BER structure after the first one.
This may be useful if the input contains garbage past the single BER sequence.
By default, unber continues decoding until the end of file (input stream).
.TP
\fB\-i\fR \fIindent\fR
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).
.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 XML FORMAT
unber dumps the output in the regular XML format which preserves most of the
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]>
.Ve
Where:
.TP
\fItform\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
.TP
\fItl_len\fR
The length of the TL (BER Tag and Length) encoding
.TP
\fIv_len\fR
The length of the value (V, encoded by the L), may be "Indefinite"
.TP
\fItype\fR
Likely name of the underlying ASN.1 type (for UNIVERSAL tags)
.TP
[\fIF\fR]
Indicates that the value was reformatted (pretty-printed)
.P
Example:
.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">
.Ve
.SH EXAMPLES
Decode the given Tag/Length sequence given in hexadecimal form:
.Vb
\& unber \fB-t\fR "\fIbf 20\fR"
.Ve
Decode the given DER file using two-spaces indentation:
.Vb
\& unber \fB-i\fR \fI2\fR \fIfilename.der\fR
.Ve
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)):
.Vb
\& cat \fI...\fR | unber \fB-\fR | enber \fB-\fR > filename.ber\fI\fR
.Ve
.SH SEE ALSO
.TP
\&\fIasn1c\fR\|(1)
\&\fI
enber\fR\|(1), \&\fI
asn1c\fR\|(1)
.SH AUTHORS
Lev Walkin <vlm@lionet.info>
asn1c/unber.c
View file @
12984671
/*-
* Copyright (c) 2004 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
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
...
...
@@ -13,11 +40,13 @@
#include <asn1parser.h>
/* For static string tables */
#include <asn_types.h>
#include <ber_tlv_tag.h>
#include <ber_tlv_length.h>
#include <asn_application.h>
#include <constraints.c>
#include <ber_tlv_tag.c>
#include <ber_tlv_length.c>
#include <OBJECT_IDENTIFIER.c>
#include <RELATIVE-OID.c>
#include <INTEGER.c>
static
void
usage
(
const
char
*
av0
);
/* Print the Usage screen and exit */
static
int
process
(
const
char
*
fname
);
/* Perform the BER decoding */
...
...
@@ -27,7 +56,9 @@ static int decode_tlv_from_string(const char *datastring);
#define COPYRIGHT \
"Copyright (c) 2004 Lev Walkin <vlm@lionet.info>\n"
static
char
*
indent_buffer
=
" "
;
static
int
single_type_decoding
=
0
;
/* -1 enables that */
static
int
pretty_printing
=
1
;
/* -p disables that */
static
char
*
indent_buffer
=
" "
;
/* -i controls that */
int
main
(
int
ac
,
char
**
av
)
{
...
...
@@ -37,12 +68,18 @@ main(int ac, char **av) {
/*
* Process command-line options.
*/
while
((
ch
=
getopt
(
ac
,
av
,
"
i:
t:v"
))
!=
-
1
)
while
((
ch
=
getopt
(
ac
,
av
,
"
1hi:p
t:v"
))
!=
-
1
)
switch
(
ch
)
{
case
'1'
:
single_type_decoding
=
1
;
break
;
case
't'
:
if
(
decode_tlv_from_string
(
optarg
))
exit
(
EX_DATAERR
);
exit
(
0
);
case
'p'
:
pretty_printing
=
0
;
break
;
case
'i'
:
i
=
atoi
(
optarg
);
if
(
i
>=
0
&&
i
<
16
)
{
...
...
@@ -58,6 +95,7 @@ main(int ac, char **av) {
fprintf
(
stderr
,
"ASN.1 BER Decoder, v"
VERSION
"
\n
"
COPYRIGHT
);
exit
(
0
);
break
;
case
'h'
:
default:
usage
(
av
[
0
]);
}
...
...
@@ -96,9 +134,21 @@ usage(const char *av0) {
"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
"
" -1 Decode only the first BER structure (otherwise, until EOF)
\n
"
" -i <indent> Amount of spaces for output indentation (default is 4)
\n
"
" -p Do not attempt pretty-printing of known ASN.1 types
\n
"
" -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
"
"Where:
\n
"
" tform Which form the value is in: constructed (
\"
C
\"
,
\"
I
\"
) or primitive (
\"
P
\"
)
\n
"
" tag The tag class and value
\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
"
" [F] Indicates that the value was reformatted (pretty-printed)
\n
"
"See the manual page for details
\n
"
,
av0
);
exit
(
EX_USAGE
);
}
...
...
@@ -135,7 +185,7 @@ process(const char *fname) {
*/
do
{
pdc
=
process_deeper
(
fname
,
fp
,
0
,
-
1
);
}
while
(
pdc
==
PD_FINISHED
);
/* Wait until PD_EOF */
}
while
(
pdc
==
PD_FINISHED
&&
!
single_type_decoding
);
if
(
fp
!=
stdin
)
fclose
(
fp
);
...
...
@@ -216,6 +266,11 @@ 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
);
...
...
@@ -249,6 +304,7 @@ static pd_code_e process_deeper(const char *fname, FILE *fp, int level, ssize_t
if
(
tlv_len
==
-
1
)
tlv_len
=
limit
;
printf
(
">
\n
"
);
/* Close the opening tag */
pdc
=
process_deeper
(
fname
,
fp
,
level
+
1
,
tlv_len
);
if
(
pdc
==
PD_FAILED
)
return
pdc
;
}
else
{
...
...
@@ -269,11 +325,6 @@ 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
)
{
if
(
fin
&&
tlen
==
2
&&
!
constr
&&
!
tlv_tag
&&
!
tlv_len
)
{
/* end of content octets */
return
;
}
if
(
fin
&&
!
constr
)
{
printf
(
"</P>
\n
"
);
return
;
...
...
@@ -282,19 +333,19 @@ print_TL(int fin, int level, int constr, ssize_t tlen, ber_tlv_tag_t tlv_tag, be
while
(
level
--
>
0
)
printf
(
indent_buffer
);
/* Print indent */
printf
(
fin
?
"</"
:
"<"
);
printf
(
constr
?
"C"
:
"P"
);
printf
(
constr
?
((
tlv_len
==
-
1
)
?
"I"
:
"C"
)
:
"P"
);
printf
(
" T=
\"
"
);
ber_tlv_tag_fwrite
(
tlv_tag
,
stdout
);
printf
(
"
\"
"
);
if
(
!
fin
)
{
printf
(
"
t
L=
\"
%ld
\"
"
,
(
long
)
tlen
);
printf
(
"
T
L=
\"
%ld
\"
"
,
(
long
)
tlen
);
if
(
tlv_len
==
-
1
)
printf
(
"
L
=
\"
Indefinite
\"
"
);
printf
(
"
V
=
\"
Indefinite
\"
"
);
else
printf
(
"
L
=
\"
%ld
\"
"
,
(
long
)
tlv_len
);
printf
(
"
V
=
\"
%ld
\"
"
,
(
long
)
tlv_len
);
}
if
(
BER_TAG_CLASS
(
tlv_tag
)
==
ASN_TAG_CLASS_UNIVERSAL
)
{
...
...
@@ -304,24 +355,85 @@ print_TL(int fin, int level, int constr, ssize_t tlen, ber_tlv_tag_t tlv_tag, be
if
(
str
)
printf
(
" A=
\"
%s
\"
"
,
str
);
}
if
(
fin
||
constr
)
printf
(
">
\n
"
);
else
printf
(
">"
);
if
(
fin
)
printf
(
">
\n
"
);
}
/*
* Print the value in binary form, or reformat for pretty-printing.
*/
static
int
print_V
(
const
char
*
fname
,
FILE
*
fp
,
ber_tlv_tag_t
tlv_tag
,
ber_tlv_len_t
tlv_len
)
{
asn1_integer_t
*
arcs
=
0
;
/* Object identifier arcs */
unsigned
char
*
vbuf
=
0
;
asn1p_expr_type_e
etype
=
0
;
long
collector
=
0
;
asn1_integer_t
collector
=
0
;
int
special_format
=
0
;
ssize_t
i
;
/* Figure out what type is it */
if
(
BER_TAG_CLASS
(
tlv_tag
)
==
ASN_TAG_CLASS_UNIVERSAL
)
{
if
(
BER_TAG_CLASS
(
tlv_tag
)
==
ASN_TAG_CLASS_UNIVERSAL
&&
pretty_printing
)
{
ber_tlv_tag_t
tvalue
=
BER_TAG_VALUE
(
tlv_tag
);
etype
=
ASN_UNIVERSAL_TAG2TYPE
(
tvalue
);
}
/*
* Determine how to print the value, either in its native binary form,
* encoded with &xNN characters, or using pretty-printing.
* The basic string types (including "useful types", like UTCTime)
* are excempt from this determination logic, because their alphabets
* are subsets of the XML's native UTF-8 encoding.
*/
switch
(
etype
)
{
case
ASN_BASIC_BOOLEAN
:
if
(
tlv_len
==
1
)
special_format
=
1
;
else
etype
=
0
;
break
;
case
ASN_BASIC_INTEGER
:
case
ASN_BASIC_ENUMERATED
:
if
((
size_t
)
tlv_len
<=
sizeof
(
collector
))
special_format
=
1
;
else
etype
=
0
;
break
;
case
ASN_BASIC_OBJECT_IDENTIFIER
:
case
ASN_BASIC_RELATIVE_OID
:
if
(
tlv_len
>
0
&&
tlv_len
<
128
*
1024
/* VERY long OID! */
)
{
arcs
=
malloc
(
sizeof
(
*
arcs
)
*
(
tlv_len
+
1
));
if
(
arcs
)
{
vbuf
=
malloc
(
tlv_len
+
1
);
/* Not checking is intentional */
}
}
case
ASN_BASIC_UTCTime
:
case
ASN_BASIC_GeneralizedTime
:
case
ASN_STRING_NumericString
:
case
ASN_STRING_PrintableString
:
case
ASN_STRING_VisibleString
:
case
ASN_STRING_IA5String
:
case
ASN_STRING_UTF8String
:
break
;
/* Directly compatible with UTF-8 */
case
ASN_STRING_BMPString
:
case
ASN_STRING_UniversalString
:
break
;
/* Not directly compatible with UTF-8 */
default:
/* Conditionally compatible with UTF-8 */
if
((
(
etype
&
ASN_STRING_MASK
)
||
(
etype
==
ASN_BASIC_OCTET_STRING
)
)
&&
(
tlv_len
>
0
&&
tlv_len
<
128
*
1024
))
{
vbuf
=
malloc
(
tlv_len
+
1
);
/* Not checking is intentional */
}
break
;
}
/* If collection vbuf is present, defer printing the F flag. */
if
(
!
vbuf
)
printf
(
special_format
?
" F>"
:
">"
);
/*
* Print the value in binary or text form.
*/
...
...
@@ -330,6 +442,8 @@ print_V(const char *fname, FILE *fp, ber_tlv_tag_t tlv_tag, ber_tlv_len_t tlv_le
if
(
ch
==
-
1
)
{
fprintf
(
stderr
,
"%s: Unexpected end of file (V)
\n
"
,
fname
);
if
(
vbuf
)
free
(
vbuf
);
if
(
arcs
)
free
(
arcs
);
return
-
1
;
}
switch
(
etype
)
{
...
...
@@ -338,6 +452,7 @@ print_V(const char *fname, FILE *fp, ber_tlv_tag_t tlv_tag, ber_tlv_len_t tlv_le
case
ASN_STRING_NumericString
:
case
ASN_STRING_PrintableString
:
case
ASN_STRING_VisibleString
:
case
ASN_STRING_IA5String
:
case
ASN_STRING_UTF8String
:
switch
(
ch
)
{
default:
...
...
@@ -354,33 +469,112 @@ print_V(const char *fname, FILE *fp, ber_tlv_tag_t tlv_tag, ber_tlv_len_t tlv_le
}
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
;
switch
(
ch
)
{
case
0
:
printf
(
"<false/>"
);
break
;
case
0xff
:
printf
(
"<true/>"
);
break
;
default:
printf
(
"<true value=
\"
&x%02x
\"
/>"
,
ch
);
}
/* Fall through */
break
;
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
)
collector
=
collector
*
256
+
ch
;
else
collector
=
(
int
)(
signed
char
)
ch
;
break
;
default:
if
(
vbuf
)
{
vbuf
[
i
]
=
ch
;
}
else
{
printf
(
"&x%02x;"
,
ch
);
}
}
}
/* Do post-processing */
switch
(
etype
)
{
case
ASN_BASIC_INTEGER
:
case
ASN_BASIC_ENUMERATED
:
printf
(
"%"
PRIdMAX
,
collector
);
break
;
case
ASN_BASIC_OBJECT_IDENTIFIER
:
if
(
vbuf
)
{
OBJECT_IDENTIFIER_t
oid
;
int
arcno
;
oid
.
buf
=
vbuf
;
oid
.
size
=
tlv_len
;
arcno
=
OBJECT_IDENTIFIER_get_arcs
(
&
oid
,
arcs
,
sizeof
(
*
arcs
),
tlv_len
+
1
);
if
(
arcno
>=
0
)
{
assert
(
arcno
<=
(
tlv_len
+
1
));
printf
(
" F>"
);
for
(
i
=
0
;
i
<
arcno
;
i
++
)
{
if
(
i
)
printf
(
"."
);
printf
(
"%"
PRIuASN
,
arcs
[
i
]);
}
if
((
i
+
1
)
==
tlv_len
)
printf
(
"%ld"
,
collector
);
break
;
free
(
vbuf
);
vbuf
=
0
;
}
}
break
;
case
ASN_BASIC_RELATIVE_OID
:
if
(
vbuf
)
{
RELATIVE_OID_t
oid
;
int
arcno
;
oid
.
buf
=
vbuf
;
oid
.
size
=
tlv_len
;
arcno
=
RELATIVE_OID_get_arcs
(
&
oid
,
arcs
,
sizeof
(
*
arcs
),
tlv_len
);
if
(
arcno
>=
0
)
{
assert
(
arcno
<=
(
tlv_len
+
1
));
printf
(
" F>"
);
for
(
i
=
0
;
i
<
arcno
;
i
++
)
{
if
(
i
)
printf
(
"."
);
printf
(
"%"
PRIuASN
,
arcs
[
i
]);
}
free
(
vbuf
);
vbuf
=
0
;
}
/* Fall through */
default:
printf
(
"&x%02x;"
,
ch
);
}
break
;
default:
break
;
}
/*
* If the buffer was not consumed, print it out.
*/
if
(
vbuf
)
{
int
binary
;
/*
* Check whether the data could be represented as text
*/
binary
=
-
1
*
(
tlv_len
>>
2
);
/* Threshold is 25% binary */
for
(
i
=
0
;
i
<
tlv_len
;
i
++
)
{
switch
(
vbuf
[
i
])
{
case
0x1b
:
binary
=
1
;
break
;
case
0x09
:
case
0x0a
:
case
0x0d
:
continue
;
default:
if
(
vbuf
[
i
]
<
0x20
||
(
vbuf
[
i
]
&
0x80
))
if
(
++
binary
>
0
)
/* Way too many */
break
;
continue
;
}
break
;
}
printf
(
">"
);
for
(
i
=
0
;
i
<
tlv_len
;
i
++
)
{
if
(
binary
>
0
||
vbuf
[
i
]
<
0x20
||
(
vbuf
[
i
]
&
0x80
))
printf
(
"&x%02x;"
,
vbuf
[
i
]);
else
printf
(
"%c"
,
vbuf
[
i
]);
}
free
(
vbuf
);
}
if
(
arcs
)
free
(
arcs
);
return
0
;
}
...
...
@@ -479,3 +673,9 @@ decode_tlv_from_string(const char *datastring) {
return
0
;
}
/*
* Dummy functions.
*/
ber_dec_rval_t
ber_check_tags
(
asn1_TYPE_descriptor_t
*
td
,
ber_dec_ctx_t
*
opt_ctx
,
void
*
ptr
,
size_t
size
,
int
tag_mode
,
ber_tlv_len_t
*
last_length
,
int
*
opt_tlv_form
)
{
ber_dec_rval_t
rv
;
(
void
)
td
;
(
void
)
opt_ctx
;
(
void
)
ptr
;
(
void
)
size
;
(
void
)
tag_mode
;
(
void
)
last_length
;
(
void
)
opt_tlv_form
;
return
rv
;
}
ssize_t
der_write_tags
(
asn1_TYPE_descriptor_t
*
td
,
size_t
slen
,
int
tag_mode
,
ber_tlv_tag_t
tag
,
asn_app_consume_bytes_f
*
cb
,
void
*
app_key
)
{
(
void
)
td
;
(
void
)
slen
;
(
void
)
tag_mode
;
(
void
)
tag
;
(
void
)
cb
;
(
void
)
app_key
;
return
-
1
;
}
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