Convert-BER-XS
view release on metacpan or search on metacpan
Revision history for Perl extension Convert::BER::XS
TODO: max_depth? yes max_size? no...
1.21 Sat May 4 00:57:15 CEST 2019
- more guesswork on what's actually in ISO 6093.
- reduce aggressiveness of REAL tests for higher portability.
1.2 Fri Apr 26 00:27:59 CEST 2019
- the snmp profile wrongly decoded opaque types as ipaddress.
- implement the indefinite encoding (when decoding only).
- implement REAL encoding - implementation complexity easily
competes with the whole rest of BER. sheesh.
- lots more tests for corner cases.
- changed "illegal" to "invalid" in diagnostics.
- work around a bug in perl 5.16.3 regex matching in the testsuite.
soon there will be more failures in the testsuites than in the code
proper :/
1.11 Tue Apr 23 22:16:20 CEST 2019
"SNMP_COUNTER32", "SNMP_UNSIGNED32", "SNMP_TIMETICKS" and
"SNMP_COUNTER64".
The *FLAGS* value is really just a boolean at this time (but might get
extended) - if it is 0, the value is "primitive" and contains no
subvalues, kind of like a non-reference perl scalar. If it is 1, then
the value is "constructed" which just means it contains a list of
subvalues which this module will en-/decode as BER tuples themselves.
The *DATA* value is either a reference to an array of further tuples (if
the value is *FLAGS*), some decoded representation of the value, if this
module knows how to decode it (e.g. for the integer types above) or a
binary string with the raw octets if this module doesn't know how to
interpret the namespace/tag.
Thus, you can always decode a BER data structure and at worst you get a
string in place of some nice decoded value.
See the SYNOPSIS for an example of such an encoded tuple representation.
DECODING AND ENCODING
$tuple = ber_decode $bindata[, $profile]
Decodes binary BER data in $bindata and returns the resulting BER
tuple. Croaks on any decoding error, so the returned $tuple is
always valid.
How tags are interpreted is defined by the second argument, which
will be decided as raw strings.
$tuple = ber_decode $data;
Example: as above, but use the provided SNMP profile.
$tuple = ber_encode $data, $Convert::BER::XS::SNMP_PROFILE;
($tuple, $bytes) = ber_decode_prefix $bindata[, $profile]
Works like "ber_decode", except it doesn't croak when there is data
after the BER data, but instead returns the decoded value and the
number of bytes it decoded.
This is useful when you have BER data at the start of a buffer and
other data after, and you need to find the length.
Also, since BER is self-delimited, this can be used to decode
multiple BER values joined together.
$bindata = ber_encode $tuple[, $profile]
Encodes the BER tuple into a BER/DER data structure. As with
Cyber_decode>, an optional profile can be given.
| CONTEXT (7) CONSTRUCTED
| | INTEGER int 1058588941
| | INTEGER int 0
| | INTEGER int 0
| | SEQUENCE
| | | SEQUENCE
| | | | OID oid 1.3.6.1.2.1.1.3.0
| | | | TIMETICKS int 638085796
PROFILES
While any BER data can be correctly encoded and decoded out of the box,
it can be inconvenient to have to manually decode some values into a
"better" format: for instance, SNMP TimeTicks values are decoded into
the raw octet strings of their BER representation, which is quite hard
to decode. With profiles, you can change which class/tag combinations
map to which decoder function inside "ber_decode" (and of course also
which encoder functions are used in "ber_encode").
This works by mapping specific class/tag combinations to an internal
"ber type".
The default profile supports the standard ASN.1 types, but no
application-specific ones. This means that class/tag combinations not in
the base set of ASN.1 are decoded into their raw octet strings.
"Convert::BER::XS" defines two profile variables you can use out of the
box:
$Convert::BER::XS::DEFAULT_PROFILE
This is the default profile, i.e. the profile that is used when no
profile is specified for de-/encoding.
You can modify it, but remember that this modifies the defaults for
all callers that rely on the default profile.
$profile->set (ASN_APPLICATION, SNMP_COUNTER32, BER_TYPE_INT);
$ber = ber_decode $data, $profile;
$type = $profile->get ($class, $tag)
Returns the BER type mapped to the given $class/$tag combination.
BER Types
This lists the predefined BER types. BER types are formatters used
internally to format and encode BER values. You can assign any
"BER_TYPE" to any "CLASS"/"TAG" combination tgo change how that tag is
decoded or encoded.
"BER_TYPE_BYTES"
The raw octets of the value. This is the default type for unknown
tags and de-/encodes the value as if it were an octet string, i.e.
by copying the raw bytes.
"BER_TYPE_UTF8"
Like "BER_TYPE_BYTES", but decodes the value as if it were a UTF-8
string (without validation!) and encodes a perl unicode string into
a UTF-8 BER string.
something other than "BER_TYPE_OID").
This module does not generally care about ranges, i.e. it will happily
de-/encode 64 bit integers into an "SNMP_UNSIGNED32" value, or a
negative number into an "SNMP_COUNTER64".
OBJECT IDENTIFIEERs cannot have unlimited length, although the limit is
much larger than e.g. the one imposed by SNMP or other protocols, and is
about 4kB.
Constructed strings are decoded just fine, but there should be a way to
join them for convenience.
REAL values will always be encoded in decimal form and ssometimes is
forced into a perl "NV" type, potentially losing precision.
ITHREADS SUPPORT
This module is unlikely to work in any other than the loading thread
when the (officially discouraged) ithreads are in use.
AUTHOR
C<SNMP_COUNTER32>, C<SNMP_UNSIGNED32>, C<SNMP_TIMETICKS> and
C<SNMP_COUNTER64>.
The I<FLAGS> value is really just a boolean at this time (but might
get extended) - if it is C<0>, the value is "primitive" and contains
no subvalues, kind of like a non-reference perl scalar. If it is C<1>,
then the value is "constructed" which just means it contains a list of
subvalues which this module will en-/decode as BER tuples themselves.
The I<DATA> value is either a reference to an array of further tuples
(if the value is I<FLAGS>), some decoded representation of the value, if
this module knows how to decode it (e.g. for the integer types above) or
a binary string with the raw octets if this module doesn't know how to
interpret the namespace/tag.
Thus, you can always decode a BER data structure and at worst you get a
string in place of some nice decoded value.
See the SYNOPSIS for an example of such an encoded tuple representation.
=head2 DECODING AND ENCODING
=over
=item $tuple = ber_decode $bindata[, $profile]
Decodes binary BER data in C<$bindata> and returns the resulting BER
$tuple = ber_decode $data;
Example: as above, but use the provided SNMP profile.
$tuple = ber_encode $data, $Convert::BER::XS::SNMP_PROFILE;
=item ($tuple, $bytes) = ber_decode_prefix $bindata[, $profile]
Works like C<ber_decode>, except it doesn't croak when there is data after
the BER data, but instead returns the decoded value and the number of
bytes it decoded.
This is useful when you have BER data at the start of a buffer and other
data after, and you need to find the length.
Also, since BER is self-delimited, this can be used to decode multiple BER
values joined together.
=item $bindata = ber_encode $tuple[, $profile]
Encodes the BER tuple into a BER/DER data structure. As with
}
}
}
sub ber_dump($;$$) {
_ber_dump $_[0], $_[1] || $DEFAULT_PROFILE, $_[2];
}
=head1 PROFILES
While any BER data can be correctly encoded and decoded out of the box, it
can be inconvenient to have to manually decode some values into a "better"
format: for instance, SNMP TimeTicks values are decoded into the raw octet
strings of their BER representation, which is quite hard to decode. With
profiles, you can change which class/tag combinations map to which decoder
function inside C<ber_decode> (and of course also which encoder functions
are used in C<ber_encode>).
This works by mapping specific class/tag combinations to an internal "ber
type".
The default profile supports the standard ASN.1 types, but no
application-specific ones. This means that class/tag combinations not in
the base set of ASN.1 are decoded into their raw octet strings.
C<Convert::BER::XS> defines two profile variables you can use out of the box:
=over
=item C<$Convert::BER::XS::DEFAULT_PROFILE>
This is the default profile, i.e. the profile that is used when no
profile is specified for de-/encoding.
=item $type = $profile->get ($class, $tag)
Returns the BER type mapped to the given C<$class>/C<$tag> combination.
=back
=head2 BER Types
This lists the predefined BER types. BER types are formatters used
internally to format and encode BER values. You can assign any C<BER_TYPE>
to any C<CLASS>/C<TAG> combination tgo change how that tag is decoded or
encoded.
=over
=item C<BER_TYPE_BYTES>
The raw octets of the value. This is the default type for unknown tags and
de-/encodes the value as if it were an octet string, i.e. by copying the
raw bytes.
other than C<BER_TYPE_OID>).
This module does not generally care about ranges, i.e. it will happily
de-/encode 64 bit integers into an C<SNMP_UNSIGNED32> value, or a negative
number into an C<SNMP_COUNTER64>.
OBJECT IDENTIFIEERs cannot have unlimited length, although the limit is
much larger than e.g. the one imposed by SNMP or other protocols, and is
about 4kB.
Constructed strings are decoded just fine, but there should be a way to
join them for convenience.
REAL values will always be encoded in decimal form and ssometimes is
forced into a perl "NV" type, potentially losing precision.
=head2 ITHREADS SUPPORT
This module is unlikely to work in any other than the loading thread when
the (officially discouraged) ithreads are in use.
( run in 0.313 second using v1.01-cache-2.11-cpan-26ccb49234f )