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-ntlv in configuration file. A tag must be enclosed in [ ].
--structure=name-sdefault.
--expression name=value-ename 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-pdefault.
--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-Vtlve 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,offsettypeintint-beint-leuintuint-beuint-lestringberlengthmask0xnn. Value zero will not be used.
shiftshift is positive,
tag will be shifted left, if negative tag will be shifted right.
offsetoffset 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.
typeintint-beint-leuintuint-beuint-lestringberlengthmask0xnn. Value zero is not used.
shiftshift is positive,
type will be shifted left, if negative type will be shifted right.
offsettype is mandatory, all other values are optional.
length=type,length,mask,shift,offsettypeintint-beint-leuintuint-beuint-lestringberlengthmask0xnn. Value zero is not used.
shiftshift is positive,
length will be shifted left, if negative length will be shifted right.
offsettype is mandatory, all other values are optional.
print=namevalue-term=stringlength are mutually exclusive.
tl-included=yes|notype-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|escapedtlv 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-contentconstructedprimitiveend-of-contentvalue-type=int|int-be|int-le|uint|uint-be|uint-le|string|hex|hexs|dec|bcd|bcds|oid|bit-string|escapedtypemap or if that is not used then escaped is used.
intint-beint-leuintuint-beuint-lestringhexhexsdecbcdbcdsoidbit-stringescaped\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|indefinitedefiniteindefiniteformat=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|noyes, 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|noyes 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%ntlv 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%dxnnxnn.... nn is the hexadecimal value
of an octet.
%Dxnnxnn.... 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.