443 lines
9.1 KiB
Text
443 lines
9.1 KiB
Text
=head1 NAME
|
|
|
|
Convert::ASN1 - ASN.1 Encode/Decode library
|
|
|
|
=head1 SYNOPSYS
|
|
|
|
use Convert::ASN1;
|
|
|
|
$asn = Convert::ASN1->new;
|
|
$asn->prepare(q<
|
|
|
|
[APPLICATION 7] SEQUENCE {
|
|
int INTEGER,
|
|
str OCTET STRING
|
|
}
|
|
|
|
>);
|
|
|
|
$pdu = $asn->encode( int => 7, str => "string");
|
|
|
|
$out = $asn->decode($pdu);
|
|
print $out->{int}," ",$out->{str},"\n";
|
|
|
|
use Convert::ASN1 qw(:io);
|
|
|
|
$peer = asn_recv($sock,$buffer,0);
|
|
$nbytes = asn_read($fh, $buffer);
|
|
$nbytes = asn_send($sock, $buffer, $peer);
|
|
$nbytes = asn_send($sock, $buffer);
|
|
$nbytes = asn_write($fh, $buffer);
|
|
$buffer = asn_get($fh);
|
|
$yes = asn_ready($fh)
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
Convert::ASN1 encodes and decodes ASN.1 data structures using BER/DER
|
|
rules.
|
|
|
|
=head1 METHODS
|
|
|
|
=head2 new
|
|
|
|
Contructor, creates a new object.
|
|
|
|
=head2 error
|
|
|
|
Returns the last error.
|
|
|
|
=head2 configure ( OPTIONS )
|
|
|
|
Configure options to control how Convert::ASN1 will perform various tasks.
|
|
Options are passed as name-value pairs.
|
|
|
|
=over 4
|
|
|
|
=item encode
|
|
|
|
Reference to a hash which contains various encode options.
|
|
|
|
=item decode
|
|
|
|
Reference to a hash which contains various decode options.
|
|
|
|
=item encoding
|
|
|
|
One of 'ber', 'der', 'per'. I<Currently not used>
|
|
|
|
=back
|
|
|
|
Encode options
|
|
|
|
=over 4
|
|
|
|
=item real
|
|
|
|
Which encoding to use for real's. One of 'binary', 'nr1', 'nr2', 'nr3'
|
|
|
|
=item time
|
|
|
|
This controls how UTCTime and GeneralizedTime elements are encoded. The default
|
|
is C<withzone>.
|
|
|
|
=over 4
|
|
|
|
=item utctime
|
|
|
|
The value passed will be encoded without a zone, ie a UTC value.
|
|
|
|
=item withzone
|
|
|
|
The value will be encoded with a zone. By default it will be encoded
|
|
using the local time offset. The offset may be set using the C<timezone>
|
|
configure option.
|
|
|
|
=item raw
|
|
|
|
The value passed should already be in the correct format and will be copied
|
|
into the PDU as-is.
|
|
|
|
=back
|
|
|
|
=item timezone
|
|
|
|
By default UTCTime and GeneralizedTime will be encoded using the local
|
|
time offset from UTC. This will over-ride that. It is an offset from UTC
|
|
in seconds. This option can be overriden by passing a reference to a
|
|
list of two values as the time value. The list should contain the time
|
|
value and the offset from UTC in seconds.
|
|
|
|
=item bigint
|
|
|
|
If during encoding an value greater than 32 bits is discovered and
|
|
is not already a big integer object, then the value will first be
|
|
converted into a big integer object. This option controls the big
|
|
integer class into which the objects will be blessed. The default
|
|
is to use Math::BigInt
|
|
|
|
=back
|
|
|
|
Decode options
|
|
|
|
=over 4
|
|
|
|
=item time
|
|
|
|
This controls how a UTCTime or a GeneralizedTime element will be decoded. The default
|
|
is C<utctime>.
|
|
|
|
=over 4
|
|
|
|
=item utctime
|
|
|
|
The value returned will be a time value as returned by the C<time> function.
|
|
|
|
=item withzone
|
|
|
|
The value returned will be a reference to an array of two values. The first is the
|
|
same as with C<utctime>, the second is the timezone offset, in seconds, that was
|
|
used in the encoding.
|
|
|
|
=item raw
|
|
|
|
The value returned will be the raw encoding as extracted from the PDU.
|
|
|
|
=back
|
|
|
|
=item bigint
|
|
|
|
If during decoding any big integers are discovered (integers greater
|
|
than 32 bits), they will be decoded into big integer objects. This option
|
|
controls the big integer class into which the objects will be blessed.
|
|
The default is to use Math::BigInt.
|
|
|
|
=back
|
|
|
|
=head2 prepare ( ASN )
|
|
|
|
Compile the given ASN.1 descripton. The syntax used is very close to ASN.1, but has
|
|
a few differnces. If the ASN decribes only one macro then encode/decode can be
|
|
called on this object. If ASN describes more than one ASN.1 macro then C<find>
|
|
must be called.
|
|
|
|
=head2 find ( MACRO )
|
|
|
|
Find a macro froma prepared ASN.1 description. Returns an object which can
|
|
be used for encode/decode.
|
|
|
|
=head2 encode ( VARIABLES )
|
|
|
|
Encode a PDU. Top-level variable are passed as name-value pairs, or as a reference
|
|
to a hash containing them. Returns the encoded PDU, or undef on error.
|
|
|
|
=head2 decode ( PDU )
|
|
|
|
Decode the PDU, returns a reference to a hash containg the values for the PDU. Returns
|
|
undef if there was an error.
|
|
|
|
=head1 EXPORTS
|
|
|
|
As well as providing an object interface for encoding/decoding PDUs Convert::ASN1
|
|
also provides the follow functions.
|
|
|
|
=head2 IO Functions
|
|
|
|
=over 4
|
|
|
|
=item asn_recv SOCK, BUFFER, FLAGS
|
|
|
|
Will read a single element from the socket SOCK into BUFFER. FLAGS may
|
|
be MSG_PEEK as exported by C<Socket>. Returns the address of the sender,
|
|
or undef if there was an error. Some systems do not support the return
|
|
of the peer address when the socket is a connected socket, in these
|
|
cases the empty string will be returned. This is the same behaviour
|
|
as the C<recv> function in perl itself.
|
|
|
|
It is reccomended that if the socket is of type SOCK_DGRAM then C<recv>
|
|
be called directly instead of calling C<asn_recv>.
|
|
|
|
=item asn_read FH, BUFFER, OFFSET
|
|
|
|
=item asn_read FH, BUFFER
|
|
|
|
Will read a single element from the filehandle FH into BUFFER. Returns the
|
|
number of bytes read if a complete element was read, -1 if an incomplete
|
|
element was read or undef if there was an error. If OFFSET is specified
|
|
then it is assumed that BUFFER already contains an incomplete element
|
|
and new data will be appended starting at OFFSET.
|
|
|
|
If FH is a socket the asn_recv is used to read the element, so the same
|
|
restiction applies if FH is a socket of type SOCK_DGRAM.
|
|
|
|
=item asn_send SOCK, BUFFER, FLAGS, TO
|
|
|
|
=item asn_send SOCK, BUFFER, FLAGS
|
|
|
|
Identical to calling C<send>, see L<perlfunc>
|
|
|
|
=item asn_write FH, BUFFER
|
|
|
|
Identical to calling C<syswrite> with 2 arguments, see L<perlfunc>
|
|
|
|
=item asn_get FH
|
|
|
|
C<asn_get> provides buffered IO. Because it needs a buffer FH must be a GLOB
|
|
or a reference to a GLOB. C<asn_get> will use two entries in the hash element
|
|
of the GLOB to use as it's buffer
|
|
|
|
asn_buffer - input buffer
|
|
asn_need - number of bytes needed for the next element, if known
|
|
|
|
Returns an element or undef if there was an error.
|
|
|
|
=item asn_ready FH
|
|
|
|
C<asn_ready> works with C<asn_get>. It will return true if C<asn_get> has already
|
|
read enough data into the buffer to return a complete element.
|
|
|
|
=back
|
|
|
|
=head2 Encode/Decode Functions
|
|
|
|
=over 4
|
|
|
|
=item asn_tag
|
|
|
|
=item asn_decode_tag
|
|
|
|
=item asn_encode_tag
|
|
|
|
=item asn_decode_length
|
|
|
|
=item asn_encode_length
|
|
|
|
=back
|
|
|
|
=head2 Constants
|
|
|
|
=over 4
|
|
|
|
=item ASN_BIT_STR
|
|
|
|
=item ASN_BOOLEAN
|
|
|
|
=item ASN_ENUMERATED
|
|
|
|
=item ASN_GENERAL_TIME
|
|
|
|
=item ASN_IA5_STR
|
|
|
|
=item ASN_INTEGER
|
|
|
|
=item ASN_NULL
|
|
|
|
=item ASN_OBJECT_ID
|
|
|
|
=item ASN_OCTET_STR
|
|
|
|
=item ASN_PRINT_STR
|
|
|
|
=item ASN_REAL
|
|
|
|
=item ASN_SEQUENCE
|
|
|
|
=item ASN_SET
|
|
|
|
=item ASN_UTC_TIME
|
|
|
|
=item ASN_APPLICATION
|
|
|
|
=item ASN_CONTEXT
|
|
|
|
=item ASN_PRIVATE
|
|
|
|
=item ASN_UNIVERSAL
|
|
|
|
=item ASN_PRIMITIVE
|
|
|
|
=item ASN_CONSTRUCTOR
|
|
|
|
=item ASN_LONG_LEN
|
|
|
|
=item ASN_EXTENSION_ID
|
|
|
|
=item ASN_BIT
|
|
|
|
=back
|
|
|
|
=head2 Debug Functions
|
|
|
|
=over 4
|
|
|
|
=item asn_dump
|
|
|
|
=item asn_hexdump
|
|
|
|
=back
|
|
|
|
=head1 EXPORT TAGS
|
|
|
|
=over 4
|
|
|
|
=item :all
|
|
|
|
All exported functions
|
|
|
|
=item :const
|
|
|
|
ASN_BOOLEAN, ASN_INTEGER, ASN_BIT_STR, ASN_OCTET_STR,
|
|
ASN_NULL, ASN_OBJECT_ID, ASN_REAL, ASN_ENUMERATED,
|
|
ASN_SEQUENCE, ASN_SET, ASN_PRINT_STR, ASN_IA5_STR,
|
|
ASN_UTC_TIME, ASN_GENERAL_TIME,
|
|
ASN_UNIVERSAL, ASN_APPLICATION, ASN_CONTEXT, ASN_PRIVATE,
|
|
ASN_PRIMITIVE, ASN_CONSTRUCTOR, ASN_LONG_LEN, ASN_EXTENSION_ID, ASN_BIT
|
|
|
|
=item :debug
|
|
|
|
asn_dump, asn_dumphex
|
|
|
|
=item :io
|
|
|
|
asn_recv, asn_send, asn_read, asn_write, asn_get, asn_ready
|
|
|
|
=item :tag
|
|
|
|
asn_tag, asn_decode_tag, asn_encode_tag, asn_decode_length, asn_encode_length
|
|
|
|
=back
|
|
|
|
=head1 MAPPING ASN.1 TO PERL
|
|
|
|
Every element in the ASN.1 definition has a name, in perl a hash is used
|
|
with these names as an index and the element value as the hash value.
|
|
|
|
# ASN.1
|
|
int INTEGER,
|
|
str OCTET STRING
|
|
|
|
# Perl
|
|
{ int => 5, str => "text" }
|
|
|
|
|
|
In the case of a SEQUENCE, SET or CHOICE then the value in the namespace will
|
|
be a hash reference which will be the namespce for the elements with
|
|
that element.
|
|
|
|
# ASN.1
|
|
int INTEGER,
|
|
seq SEQUENCE {
|
|
str OCTET STRING,
|
|
bool BOOLEAN
|
|
}
|
|
|
|
# Perl
|
|
{ int => 5, seq => { str => "text", bool => 1}}
|
|
|
|
If the element is a SEQUENCE OF, or SET OF, then the value in the namespace
|
|
will be an array reference. The elements in the array will be of
|
|
the type expected by the type following the OF. For example
|
|
with "SEQUENCE OF STRING" the array would contain strings. With
|
|
"SEQUENCE OF SEQUENCE { ... }" the array will contain hash references
|
|
which will be used as namespaces
|
|
|
|
# ASN.1
|
|
int INTEGER,
|
|
str SEQUENCE OF OCTET STRING
|
|
|
|
# Perl
|
|
{ int => 5, str => [ "text1", "text2"]}
|
|
|
|
# ASN.1
|
|
int INTEGER,
|
|
str SEQUENCE OF SEQUENCE {
|
|
type OCTET STRING,
|
|
value INTEGER
|
|
}
|
|
|
|
# Perl
|
|
{ int => 5, str => [
|
|
{ type => "abc", value => 4 },
|
|
{ type => "def", value => -1 },
|
|
]}
|
|
|
|
=head2 Exceptions
|
|
|
|
There are some exceptions where Convert::ASN1 does not require an element to be named.
|
|
These are SEQUENCE {...}, SET {...} and CHOICE. In each case if the element is not
|
|
given a name then the elements inside the {...} will share the same namespace as
|
|
the elements outside of the {...}.
|
|
|
|
=head1 TODO
|
|
|
|
=over 4
|
|
|
|
=item *
|
|
|
|
Indefinite length encoding
|
|
|
|
=item *
|
|
|
|
XS implementation.
|
|
|
|
=item *
|
|
|
|
More documentation.
|
|
|
|
=item *
|
|
|
|
More tests.
|
|
|
|
=back
|
|
|
|
=head1 AUTHOR
|
|
|
|
Graham Barr <gbarr@pobox.xom>
|
|
|
|
=head1 COPYRIGHT
|
|
|
|
Copyright (c) 2000-2002 Graham Barr <gbarr@pobox.com>. All rights reserved.
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the same terms as Perl itself.
|
|
|
|
=cut
|
|
|