The tlve program is a command-line tool for parsing different tlv (tag-length-value) structures and for printing them in various text-based formats. In order to correctly parse the input data tlve uses a text-based configuration. Default configuration file is ~/.tlverc (tlve.rc in windows).
tlve can parse text or binary (including ASN.1 BER) tlv structures. Tag, length and value can have fixed length or separated format. Values can be presented in different formats and converted to different encoding.
tlve was written by Timo Savinen.
This file documents version 2.1 of tlve.
Here are some realistic examples of running tlve.
This is the output of the command ‘cat ber.rc’:
$cat ber.rc # ASN.1 ber example configuration. # This file is for reading any ASN.1 BER encoded file, this # example contains names only for Universal class tags, add your # own tags using tlv-keyword # test this by command: # tlve -c ber.tlverc -s BER <inputfile> # or # tlve -c ber.tlverc -s BER -p dump <inputfile> tl name=asn1ber tag=ber length=ber structure name=BER content-tl=asn1ber tlv name=Boolean tag="U-1" value-type=uint tlv name=Integer tag="U-2" value-type=int tlv name=BitString tag="U-3" maybe-constructed=yes value-type=bit-string tlv name=OctetString tag="U-4" maybe-constructed=yes value-type=hex tlv name=NULL tag="U-5" value-type=hex tlv name=ObjectIdentifier tag="U-6" value-type=oid tlv name=ObjectDescriptor tag="U-7" value-type=hex tlv name=External tag="U-8" tlv name=Real tag="U-9" value-type=hex tlv name=Enumerated tag="U-10" value-type=int tlv name=EmbeddedPvd tag="U-11" value-type=hex tlv name=UTF8String tag="U-12" maybe-constructed=yes value-type=string encoding=UTF8 tlv name=RelativeOid tag="U-13" value-type=hex tlv name=Sequence tag="U-16" tlv name=Set tag="U-17" tlv name=NumericString tag="U-18" value-type=string tlv name=PrintableString tag="U-19" value-type=string tlv name=T61String tag="U-20" value-type=string tlv name=VideotexString tag="U-21" value-type=string tlv name=IA5String tag="U-22" value-type=string encoding=ISO646-FI # change encoding to suit your needs tlv name=UTCTime tag="U-23" value-type=string tlv name=GeneralizedTime tag="U-24" value-type=string tlv name=GraphicString tag="U-25" value-type=string tlv name=VisibleString tag="U-26" value-type=string tlv name=GeneralString tag="U-27" value-type=string tlv name=UniversalString tag="U-28" value-type=string tlv name=CharacterString tag="U-29" value-type=string tlv name=BMPString tag="U-30" value-type=string encoding=UCS-4 structure-end # printing definitions # XML produced using this may not be wellformed print name=XML file-start="<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n" \ value="<%n>%v</%n>\n" constructor="<%n>\n" constructor-end="</%n>\n" encoding="ISO-8859-1" indent=" " print name=dump file-start="--- File: %f ---\n\n" value="%n=%v (tag: %d, value %D)\n" constructor="%n (tag: %d)<\n" constructor-end=">\n" indent=" " |
This is the first few lines from output of the command ‘tlve -c ber.rc -s BER -p XML /usr/share/beid/certs/beid-cert-government.der’:
$tlve -c ber.rc -s BER -p XML /usr/share/beid/certs/beid-cert-government.der <?xml version="1.0" encoding="ISO-8859-1"?> <Sequence> <Sequence> <[C-0]> <Integer>2</Integer> </[C-0]> <Integer>4408622999086524144</Integer> <Sequence> <ObjectIdentifier>1 2 840 113549 1 1 5</ObjectIdentifier> <NULL></NULL> </Sequence> <Sequence> <Set> <Sequence> <ObjectIdentifier>2 5 4 6</ObjectIdentifier> <PrintableString>BE</PrintableString> </Sequence> </Set> <Set> <Sequence> <ObjectIdentifier>2 5 4 3</ObjectIdentifier> <PrintableString>Belgium Root CA</PrintableString> </Sequence> </Set> </Sequence> <Sequence> <UTCTime>030127000000Z</UTCTime> <UTCTime>090127000000Z</UTCTime> </Sequence> . . . |
The format for running the tlve program is:
tlve option ... file ...
tlve
supports the following options:
--configuration=
name-c
name--debug
-d
--name-list=
list-n
tlv
in configuration file. A tag must be enclosed in [ ]
.
--structure=
name-s
default
.
--expression
name=
value-e
name is name of a primitive element and the expression evaluates true if the contents of the element matches the regular expression in value.
--and
-a
--print=
name-p
default
.
--output=
name-o
name--start-level=
level-l
levelIf -e, --expression is used with this option and the expression(s) in level level or in lower levels evaluates true, then all elements in level or lower levels are printed in that particular hierarchy.
If both this option and -n, --name are defined, only names which appear in level or lower levels are printed.
--stop-level=
level-L
levelIf both this option and -n, --name are defined, only names which appear in level level or higher in element hierarchy are printed.
--help
-?
--version
-V
tlve uses a text-based configuration file to process and print input data. Default configuration file
is ~/.tlverc. Configuration is made up of keywords and parameter-value pairs. Comments start with #
-character.
Following chapters explain keywords and their meanings.
tl name=
string tag=
type,
length,
mask,
shift,
offset
type=
type,
length,
mask,
shift,
offset
length=
type,
length,
mask,
shift,
offset
print=
name value-term=
string tl-included=yes|no type-map=
name
tl
is used to specify characteristics of tag-length pair, which is used to parse a tlv file. Parameters and their meanings:
name=
stringtag=
type,
length,
mask,
shift,
offsettype
int
int-be
int-le
uint
uint-be
uint-le
string
ber
length
mask
0xnn
. Value zero will not be used.
shift
shift
is positive,
tag will be shifted left, if negative tag will be shifted right.
offset
offset
is given, tag will be read
from position specified by this offset.
type
and length
or value-term
are mandatory, all other values are optional.
type=
type,
length,
mask,
shift,
offsettypemap
.
type
int
int-be
int-le
uint
uint-be
uint-le
string
ber
length
mask
0xnn
. Value zero is not used.
shift
shift
is positive,
type will be shifted left, if negative type will be shifted right.
offset
type
is mandatory, all other values are optional.
length=
type,
length,
mask,
shift,
offsettype
int
int-be
int-le
uint
uint-be
uint-le
string
ber
length
mask
0xnn
. Value zero is not used.
shift
shift
is positive,
length will be shifted left, if negative length will be shifted right.
offset
type
is mandatory, all other values are optional.
print=
namevalue-term=
stringlength
are mutually exclusive.
tl-included=yes|no
type-map=
nametypemap
definition name.
typemap name=
string
map ...
map ...
map ...
.
.
.
typemap-end
name=
stringtypemap
is used to map input value types to tlve's internal value types. Input value type can be defined in tl
with keyword type
.
map
keyword has two parameters:map value=
string value-type=int|int-be|int-le|uint|uint-be|uint-le|string|hex|hexs|dec|bcd|bcds|oid|bit-string|escaped
value=
stringvalue-type=int|int-be|int-le|uint|uint-be|uint-le|string|hex|hexs|dec|bcd|bcds|oid|bit-string|escaped
tlv name=
string tag=
string end-tag=
string path=
string type=constructed|primitive|end-of-content
value-type=int|int-be|int-le|uint|uint-be|uint-le|string|hex|hexs|dec|bcd|bcds|oid|bit-string|escaped
content-tl=
name print=
name encoding=
name
form=definite|indefinite format=
string value-length-adjust=
integer maybe-constructed=yes|no hold=yes|no|
name
tlv
is used to specify characteristics of one tlv triplet by mapping additional info to it using the parameter tag
as a key.
tlv
is only used inside the structure
definition (see below). Parameters and their meanings:
name=
string%n
.
tag=
stringX-n
where
X
is the class of tag: U,A,C or P for Universal, Application, Context-specific or Private type of BER-tag. n
is decimal number.
end-tag=
stringtag
and string from this parameter are considered as value range when mapping
tlv triplets to this definition.
path=
string[ ]
is used. If path starts with asterisk (*
) then only the rest of the path must match with the current path.
type=constructed|primitive|end-of-content
constructed
primitive
end-of-content
value-type=int|int-be|int-le|uint|uint-be|uint-le|string|hex|hexs|dec|bcd|bcds|oid|bit-string|escaped
typemap
or if that is not used then escaped
is used.
int
int-be
int-le
uint
uint-be
uint-le
string
hex
hexs
dec
bcd
bcds
oid
bit-string
escaped
\xnn
, where nn
is the hexadecimal value of a character.
content-tl=
nameprint=
nameencoding=
name%v
) the contents
of the value is converted to system encoding (default) or encoding specified in printing definition. For more information about
encoding see ‘man iconv’.
form=definite|indefinite
definite
indefinite
format=
stringlong long int
and the default formats are %lli
and %llu
.
If string starts with +
or ++
the rest of the string is considered as
format string for strftime()
function and the value is considered to be UNIX time. If single +
is given time is formatted as local time, if ++
is given the time is formatted as UTC time.
value-length-adjust=
integerlength = length +
integer.
integer can be negative allowing reading less data as expressed by the length in tl data.
Note: length consumed by the tlv triplet is not affected by this parameter.
maybe-constructed=yes|no
yes
, then tlve first checks
if the beginning of the value is a valid tl pair and the tl pair's length added to the length expressed
by the tl pair matches the total length of this element. If this is true the element is treated as a constructed
element. Default is no
.
hold=yes|no|
nameyes
or name the value part of a primitive element or the name of a constructed element is put in hold.
The value in hold can be printed using notation $
name, where name is
the name of the tlv triplet or an alias name given by name. Only the latest value encountered is saved. Several
different elements can share the same alias name.
This can be used to save the value or the name for later printing. Default is no.
name
and tag
are mandatory.
Structure is a multi-line configuration element, which specifies basic characteristics of a tlv input file.
Structure can contain multiple tlv
keywords.
structure name=
name content-tl=
name print=
name filler=
string hex-caps=yes|no
tlv ...
tlv ...
tlv ...
.
.
.
structure-end
name=
namecontent-tl=
nameprint=
nameprint
in tl
or tlv
keywords.
filler=
string\xnn
, where nn
is characters hexadecimal value.
hex-caps=yes|no
yes
then the hexadecimal values are printed in capital letters.
structure
keyword there can be any number of tlv
keywords, structure
definition is
ended by structure-end
keyword. Only parameters name
and content-tl
are mandatory.
Keyword print
specifies how to print tlv triplets in text-based formats.
print name=
string file-start=
string file-end=
string constructor=
string
constructor-end=
string value=
string indent=
string encoding=
name
block-start=
string block-end=
string separator=
char
name=
stringfile-start=
stringfile-end=
stringconstructor=
stringconstructor-end=
stringvalue=
stringindent=
stringencoding=
nameencoding
parameter in tlv
, the name
is used as target encoding. Default is to used system encoding (which can be checked by tlve -V).
block-start=
stringblock-end=
stringseparator=
charstring used in parameters for print
can contain following printf-style directives:
%%
%$
%>
%l
%c
%t
%n
tlv
keyword) of the tlv triplet. If the tlv triplet cannot be associated with
any of the tlv
keywords in structure
definition, then
the tag enclosed in [ ]
is printed.
%v
%p
%o
%O
%f
%s
%d
xnnxnn...
. nn
is the hexadecimal value
of an octet.
%D
xnnxnn...
. nn
is the hexadecimal value
of an octet.
\a
, \b
, \t
, \n
, \v
, \f
, \r
, \"
and \#
.
A backslash can be escaped as \\
. If string contains white-space characters string must be
enclosed in double quotation marks "
.
Non printable characters can be escaped as \xnn
, where nn
is characters hexadecimal value.
If elements is put in "hold" (parameter hold in tlv-keyword),
then the value of a primitive element or the name of a constructed element can be printed in strings
using notation
$
name
where the name is the name of the tlv triplet or the alias name.
Tlve prints always the latest encountered value or name of the name.
This can be used e.g. to save a value from the beginning of the file to be printed with later found elements.
It is possible to define an input preprosessor for tlve. An input preprocessor is simply an executable program which writes the contents of the input file to standard output which will be read by tlve. If the input preprosessor does not write any characters on its standard output, then tlve uses the original file.
To set up an input preprocessor, set the TLVEOPEN
environment variable to a command line which will invoke your input preprocessor.
This command line should include one occurrence of the string %s
, which will be replaced by the input filename when the input preprocessor command is invoked.
The input preprocessor is not used if tlve is reading standard input.
Convenient way is to use lesspipe (or lesspipe.sh), which is availabe in many UNIX-systems, for example
export TLVEOPEN="/usr/bin/lesspipe %s"
Using the example above is it possible to give a zipped input file to tlve, then the input processor will unzip the file before it is processed by tlve.
Examples of rc-files can be found in tlve package.
If you find a bug in tlve, please send electronic mail to tjsa@iki.fi. Include the version number, which you can find by running ‘tlve --version’. Also include in your message the output that the program produced and the output you expected.
If you have other questions, comments or suggestions about tlve, contact the author via electronic mail to tjsa@iki.fi. The author will try to help you out, although he may not have time to fix your problems.