Blame lib/Convert/ASN1.pod

Packit ef9df4
=head1 NAME
Packit ef9df4
Packit ef9df4
Convert::ASN1 - ASN.1 Encode/Decode library
Packit ef9df4
Packit ef9df4
=head1 VERSION
Packit ef9df4
Packit ef9df4
version 0.27
Packit ef9df4
Packit ef9df4
=head1 SYNOPSYS
Packit ef9df4
Packit ef9df4
  use Convert::ASN1;
Packit ef9df4
Packit ef9df4
  $asn = Convert::ASN1->new;
Packit ef9df4
  $asn->prepare(q<
Packit ef9df4
Packit ef9df4
    [APPLICATION 7] SEQUENCE {
Packit ef9df4
      int INTEGER,
Packit ef9df4
      str OCTET STRING
Packit ef9df4
    }
Packit ef9df4
Packit ef9df4
  >);
Packit ef9df4
Packit ef9df4
  $pdu = $asn->encode( int => 7, str => "string");
Packit ef9df4
Packit ef9df4
  $out = $asn->decode($pdu);
Packit ef9df4
  print $out->{int}," ",$out->{str},"\n";
Packit ef9df4
Packit ef9df4
  use Convert::ASN1 qw(:io);
Packit ef9df4
Packit ef9df4
  $peer   = asn_recv($sock,$buffer,0);
Packit ef9df4
  $nbytes = asn_read($fh, $buffer);
Packit ef9df4
  $nbytes = asn_send($sock, $buffer, $peer);
Packit ef9df4
  $nbytes = asn_send($sock, $buffer);
Packit ef9df4
  $nbytes = asn_write($fh, $buffer);
Packit ef9df4
  $buffer = asn_get($fh);
Packit ef9df4
  $yes    = asn_ready($fh)
Packit ef9df4
Packit ef9df4
=head1 DESCRIPTION
Packit ef9df4
Packit ef9df4
Convert::ASN1 encodes and decodes ASN.1 data structures using BER/DER
Packit ef9df4
rules.
Packit ef9df4
Packit ef9df4
=head1 METHODS
Packit ef9df4
Packit ef9df4
=head2 new ( [OPTIONS] )
Packit ef9df4
Packit ef9df4
Contructor, creates a new object.
Packit ef9df4
Packit ef9df4
If given, B<OPTIONS> are the same ones as for L</"configure ( OPTIONS )"> below.
Packit ef9df4
Packit ef9df4
=head2 error ()
Packit ef9df4
Packit ef9df4
Returns the last error.
Packit ef9df4
Packit ef9df4
=head2 configure ( OPTIONS )
Packit ef9df4
Packit ef9df4
Configure options to control how Convert::ASN1 will perform various tasks.
Packit ef9df4
Options are passed as name-value pairs.
Packit ef9df4
Packit ef9df4
=over 4
Packit ef9df4
Packit ef9df4
=item encode
Packit ef9df4
Packit ef9df4
Reference to a hash which contains various encode options.
Packit ef9df4
Packit ef9df4
=item decode
Packit ef9df4
Packit ef9df4
Reference to a hash which contains various decode options.
Packit ef9df4
Packit ef9df4
=item encoding
Packit ef9df4
Packit ef9df4
One of 'BER' or 'DER'. The default is 'BER'
Packit ef9df4
Packit ef9df4
=item tagdefault
Packit ef9df4
Packit ef9df4
One of 'EXPLICIT' or 'IMPLICIT'.
Packit ef9df4
Default tagging conventions are normally given in the ASN.1 module definition (not supported by the parser). The ASN.1 spec states EXPLICIT tagging is the default, but this option has IMPLICIT tagging default for backward compatibility reasons.
Packit ef9df4
Packit ef9df4
=back
Packit ef9df4
Packit ef9df4
Encode options
Packit ef9df4
Packit ef9df4
=over 4
Packit ef9df4
Packit ef9df4
=item real
Packit ef9df4
Packit ef9df4
Which encoding to use for real's. One of 'binary', 'nr1', 'nr2', 'nr3'
Packit ef9df4
Packit ef9df4
=item time
Packit ef9df4
Packit ef9df4
This controls how UTCTime and GeneralizedTime elements are encoded. The default
Packit ef9df4
is C<withzone>.
Packit ef9df4
Packit ef9df4
=over 4
Packit ef9df4
Packit ef9df4
=item utctime
Packit ef9df4
Packit ef9df4
The value passed will be encoded without a zone, ie a UTC value.
Packit ef9df4
Packit ef9df4
=item withzone
Packit ef9df4
Packit ef9df4
The value will be encoded with a zone. By default it will be encoded
Packit ef9df4
using the local time offset. The offset may be set using the C<timezone>
Packit ef9df4
configure option.
Packit ef9df4
Packit ef9df4
=item raw
Packit ef9df4
Packit ef9df4
The value passed should already be in the correct format and will be copied
Packit ef9df4
into the PDU as-is.
Packit ef9df4
Packit ef9df4
=back
Packit ef9df4
Packit ef9df4
=item timezone
Packit ef9df4
Packit ef9df4
By default UTCTime and GeneralizedTime will be encoded using the local
Packit ef9df4
time offset from UTC. This will over-ride that. It is an offset from UTC
Packit ef9df4
in seconds.  This option can be overridden by passing a reference to a
Packit ef9df4
list of two values as the time value. The list should contain the time
Packit ef9df4
value and the offset from UTC in seconds.
Packit ef9df4
Packit ef9df4
=item bigint
Packit ef9df4
Packit ef9df4
If during encoding an value greater than 32 bits is discovered and
Packit ef9df4
is not already a big integer object, then the value will first be
Packit ef9df4
converted into a big integer object. This option controls the big
Packit ef9df4
integer class into which the objects will be blessed. The default
Packit ef9df4
is to use Math::BigInt
Packit ef9df4
Packit ef9df4
=back
Packit ef9df4
Packit ef9df4
Decode options
Packit ef9df4
Packit ef9df4
=over 4
Packit ef9df4
Packit ef9df4
=item time
Packit ef9df4
Packit ef9df4
This controls how a UTCTime or a GeneralizedTime element will be decoded. The default
Packit ef9df4
is C<utctime>.
Packit ef9df4
Packit ef9df4
=over 4
Packit ef9df4
Packit ef9df4
=item utctime
Packit ef9df4
Packit ef9df4
The value returned will be a time value as returned by the C<time> function.
Packit ef9df4
Packit ef9df4
=item withzone
Packit ef9df4
Packit ef9df4
The value returned will be a reference to an array of two values. The first is the
Packit ef9df4
same as with C<utctime>, the second is the timezone offset, in seconds, that was
Packit ef9df4
used in the encoding.
Packit ef9df4
Packit ef9df4
=item raw
Packit ef9df4
Packit ef9df4
The value returned will be the raw encoding as extracted from the PDU.
Packit ef9df4
Packit ef9df4
=back
Packit ef9df4
Packit ef9df4
=item bigint
Packit ef9df4
Packit ef9df4
If during decoding any big integers are discovered (integers greater
Packit ef9df4
than 32 bits), they will be decoded into big integer objects. This option
Packit ef9df4
controls the big integer class into which the objects will be blessed.
Packit ef9df4
The default is to use Math::BigInt.
Packit ef9df4
Packit ef9df4
=item null
Packit ef9df4
Packit ef9df4
The value to decode ASN.1 NULL types into.
Packit ef9df4
If not set, it defaults to C<1>.
Packit ef9df4
Packit ef9df4
=back
Packit ef9df4
Packit ef9df4
=head2 prepare ( ASN )
Packit ef9df4
Packit ef9df4
Compile the given ASN.1 descripton which can be passed as a string
Packit ef9df4
or as a filehandle. The syntax used is very close to ASN.1, but has
Packit ef9df4
a few differences. If the ASN decribes only one macro then encode/decode can be
Packit ef9df4
called on this object. If ASN describes more than one ASN.1 macro then C<find>
Packit ef9df4
must be called. The method returns undef on error.
Packit ef9df4
Packit ef9df4
=head2 prepare_file ( ASNPATH )
Packit ef9df4
Packit ef9df4
Compile the ASN.1 description to be read from the specified pathname.
Packit ef9df4
Packit ef9df4
=head2 find ( MACRO )
Packit ef9df4
Packit ef9df4
Find a macro from a prepared ASN.1 description. Returns an object which can
Packit ef9df4
be used for encode/decode.
Packit ef9df4
Packit ef9df4
=head2 encode ( VARIABLES )
Packit ef9df4
Packit ef9df4
Encode a PDU. Top-level variable are passed as name-value pairs, or as a reference
Packit ef9df4
to a hash containing them. Returns the encoded PDU, or undef on error.
Packit ef9df4
Packit ef9df4
=head2 decode ( PDU )
Packit ef9df4
Packit ef9df4
Decode the PDU, returns a reference to a hash containg the values for the PDU. Returns
Packit ef9df4
undef if there was an error.
Packit ef9df4
Packit ef9df4
=head2 registeroid ( OID, HANDLER )
Packit ef9df4
Packit ef9df4
Register a handler for all ASN.1 elements
Packit ef9df4
that are C<DEFINED BY> the given OID.
Packit ef9df4
Packit ef9df4
B<HANDLER> must be a Convert::ASN1 object, e.g. as returned by L</"find ( MACRO )">.
Packit ef9df4
Packit ef9df4
=head2 registertype ( NAME, OID, HANDLER )
Packit ef9df4
Packit ef9df4
Register a handler for all ASN.1 elements named C<NAME>,
Packit ef9df4
that are C<DEFINED BY> the given OID.
Packit ef9df4
Packit ef9df4
B<HANDLER> must be a Convert::ASN1 object, e.g. as returned by L</"find ( MACRO )">.
Packit ef9df4
Packit ef9df4
=head1 EXPORTS
Packit ef9df4
Packit ef9df4
As well as providing an object interface for encoding/decoding PDUs Convert::ASN1
Packit ef9df4
also provides the following functions.
Packit ef9df4
Packit ef9df4
=head2 IO Functions
Packit ef9df4
Packit ef9df4
=over 4
Packit ef9df4
Packit ef9df4
=item asn_recv ( SOCK, BUFFER, FLAGS )
Packit ef9df4
Packit ef9df4
Will read a single element from the socket SOCK into BUFFER.  FLAGS may
Packit ef9df4
be MSG_PEEK as exported by C<Socket>. Returns the address of the sender,
Packit ef9df4
or undef if there was an error. Some systems do not support the return
Packit ef9df4
of the peer address when the socket is a connected socket, in these
Packit ef9df4
cases the empty string will be returned. This is the same behaviour
Packit ef9df4
as the C<recv> function in perl itself.
Packit ef9df4
Packit ef9df4
It is recommended that if the socket is of type SOCK_DGRAM then C<recv>
Packit ef9df4
be called directly instead of calling C<asn_recv>.
Packit ef9df4
Packit ef9df4
=item asn_read ( FH, BUFFER, OFFSET )
Packit ef9df4
Packit ef9df4
=item asn_read ( FH, BUFFER )
Packit ef9df4
Packit ef9df4
Will read a single element from the filehandle FH into BUFFER. Returns the
Packit ef9df4
number of bytes read if a complete element was read, -1 if an incomplete
Packit ef9df4
element was read or undef if there was an error. If OFFSET is specified
Packit ef9df4
then it is assumed that BUFFER already contains an incomplete element
Packit ef9df4
and new data will be appended starting at OFFSET.
Packit ef9df4
Packit ef9df4
If FH is a socket the asn_recv is used to read the element, so the same
Packit ef9df4
restiction applies if FH is a socket of type SOCK_DGRAM.
Packit ef9df4
Packit ef9df4
=item asn_send ( SOCK, BUFFER, FLAGS, TO )
Packit ef9df4
Packit ef9df4
=item asn_send ( SOCK, BUFFER, FLAGS )
Packit ef9df4
Packit ef9df4
Identical to calling C<send>, see L<perlfunc>
Packit ef9df4
Packit ef9df4
=item asn_write ( FH, BUFFER )
Packit ef9df4
Packit ef9df4
Identical to calling C<syswrite> with 2 arguments, see L<perlfunc>
Packit ef9df4
Packit ef9df4
=item asn_get ( FH )
Packit ef9df4
Packit ef9df4
C<asn_get> provides buffered IO. Because it needs a buffer FH must be a GLOB
Packit ef9df4
or a reference to a GLOB. C<asn_get> will use two entries in the hash element
Packit ef9df4
of the GLOB to use as its buffer:
Packit ef9df4
Packit ef9df4
  asn_buffer - input buffer
Packit ef9df4
  asn_need   - number of bytes needed for the next element, if known
Packit ef9df4
Packit ef9df4
Returns an element or undef if there was an error.
Packit ef9df4
Packit ef9df4
=item asn_ready ( FH )
Packit ef9df4
Packit ef9df4
C<asn_ready> works with C<asn_get>. It will return true if C<asn_get> has already
Packit ef9df4
read enough data into the buffer to return a complete element.
Packit ef9df4
Packit ef9df4
=back
Packit ef9df4
Packit ef9df4
=head2 Encode/Decode Functions
Packit ef9df4
Packit ef9df4
=over 4
Packit ef9df4
Packit ef9df4
=item asn_tag ( CLASS, VALUE )
Packit ef9df4
Packit ef9df4
Given B<CLASS> and a B<VALUE>, calculate an integer which when encoded
Packit ef9df4
will become the tag.
Packit ef9df4
Packit ef9df4
=item asn_decode_tag ( TAG )
Packit ef9df4
Packit ef9df4
Decode the given ASN.1 encoded C<TAG>.
Packit ef9df4
Packit ef9df4
=item asn_encode_tag ( TAG )
Packit ef9df4
Packit ef9df4
Encode B<TAG> value for encoding.
Packit ef9df4
We assume that the tag has been correctly generated with L</"asn_tag ( CLASS, VALUE )">.
Packit ef9df4
Packit ef9df4
=item asn_decode_length ( LEN )
Packit ef9df4
Packit ef9df4
Decode the given ASN.1 decoded C<LEN>.
Packit ef9df4
Packit ef9df4
=item asn_encode_length ( LEN )
Packit ef9df4
Packit ef9df4
Encode the given C<LEN> to its ASN.1 encoding.
Packit ef9df4
Packit ef9df4
=back
Packit ef9df4
Packit ef9df4
=head2 Constants
Packit ef9df4
Packit ef9df4
=over 4
Packit ef9df4
Packit ef9df4
=item ASN_BIT_STR
Packit ef9df4
Packit ef9df4
=item ASN_BOOLEAN
Packit ef9df4
Packit ef9df4
=item ASN_ENUMERATED
Packit ef9df4
Packit ef9df4
=item ASN_GENERAL_TIME
Packit ef9df4
Packit ef9df4
=item ASN_IA5_STR
Packit ef9df4
Packit ef9df4
=item ASN_INTEGER
Packit ef9df4
Packit ef9df4
=item ASN_NULL
Packit ef9df4
Packit ef9df4
=item ASN_OBJECT_ID
Packit ef9df4
Packit ef9df4
=item ASN_OCTET_STR
Packit ef9df4
Packit ef9df4
=item ASN_PRINT_STR
Packit ef9df4
Packit ef9df4
=item ASN_REAL
Packit ef9df4
Packit ef9df4
=item ASN_SEQUENCE
Packit ef9df4
Packit ef9df4
=item ASN_SET
Packit ef9df4
Packit ef9df4
=item ASN_UTC_TIME
Packit ef9df4
Packit ef9df4
=item ASN_APPLICATION
Packit ef9df4
Packit ef9df4
=item ASN_CONTEXT
Packit ef9df4
Packit ef9df4
=item ASN_PRIVATE
Packit ef9df4
Packit ef9df4
=item ASN_UNIVERSAL
Packit ef9df4
Packit ef9df4
=item ASN_PRIMITIVE
Packit ef9df4
Packit ef9df4
=item ASN_CONSTRUCTOR
Packit ef9df4
Packit ef9df4
=item ASN_LONG_LEN
Packit ef9df4
Packit ef9df4
=item ASN_EXTENSION_ID
Packit ef9df4
Packit ef9df4
=item ASN_BIT
Packit ef9df4
Packit ef9df4
=back
Packit ef9df4
Packit ef9df4
=head2 Debug Functions
Packit ef9df4
Packit ef9df4
=over 4
Packit ef9df4
Packit ef9df4
=item asn_dump ( [FH,] BUFFER )
Packit ef9df4
Packit ef9df4
Try to decode the given buffer as ASN.1 structure and dump it to the
Packit ef9df4
given file handle, or C<STDERR> if the handle is not given.
Packit ef9df4
Packit ef9df4
=item asn_hexdump ( FH, BUFFER )
Packit ef9df4
Packit ef9df4
=back
Packit ef9df4
Packit ef9df4
=head1 EXPORT TAGS
Packit ef9df4
Packit ef9df4
=over 4
Packit ef9df4
Packit ef9df4
=item :all
Packit ef9df4
Packit ef9df4
All exported functions
Packit ef9df4
Packit ef9df4
=item :const
Packit ef9df4
Packit ef9df4
ASN_BOOLEAN,     ASN_INTEGER,      ASN_BIT_STR,      ASN_OCTET_STR,
Packit ef9df4
ASN_NULL,        ASN_OBJECT_ID,    ASN_REAL,         ASN_ENUMERATED,
Packit ef9df4
ASN_SEQUENCE,    ASN_SET,          ASN_PRINT_STR,    ASN_IA5_STR,
Packit ef9df4
ASN_UTC_TIME,    ASN_GENERAL_TIME,
Packit ef9df4
ASN_UNIVERSAL,   ASN_APPLICATION,  ASN_CONTEXT,      ASN_PRIVATE,
Packit ef9df4
ASN_PRIMITIVE,   ASN_CONSTRUCTOR,  ASN_LONG_LEN,     ASN_EXTENSION_ID, ASN_BIT
Packit ef9df4
Packit ef9df4
=item :debug
Packit ef9df4
Packit ef9df4
asn_dump, asn_hexdump
Packit ef9df4
Packit ef9df4
=item :io
Packit ef9df4
Packit ef9df4
asn_recv, asn_send, asn_read, asn_write, asn_get, asn_ready
Packit ef9df4
Packit ef9df4
=item :tag
Packit ef9df4
Packit ef9df4
asn_tag, asn_decode_tag, asn_encode_tag, asn_decode_length, asn_encode_length
Packit ef9df4
Packit ef9df4
=back
Packit ef9df4
Packit ef9df4
=head1 MAPPING ASN.1 TO PERL
Packit ef9df4
Packit ef9df4
Every element in the ASN.1 definition has a name, in perl a hash is used
Packit ef9df4
with these names as an index and the element value as the hash value.
Packit ef9df4
Packit ef9df4
  # ASN.1
Packit ef9df4
  int INTEGER,
Packit ef9df4
  str OCTET STRING
Packit ef9df4
Packit ef9df4
  # Perl
Packit ef9df4
  { int => 5, str => "text" }
Packit ef9df4
Packit ef9df4
Packit ef9df4
In the case of a SEQUENCE, SET or CHOICE then the value in the namespace will
Packit ef9df4
be a hash reference which will be the namespce for the elements with
Packit ef9df4
that element.
Packit ef9df4
Packit ef9df4
  # ASN.1
Packit ef9df4
  int INTEGER,
Packit ef9df4
  seq SEQUENCE {
Packit ef9df4
    str OCTET STRING,
Packit ef9df4
    bool BOOLEAN
Packit ef9df4
  }
Packit ef9df4
Packit ef9df4
  # Perl
Packit ef9df4
  { int => 5, seq => { str => "text", bool => 1}}
Packit ef9df4
Packit ef9df4
If the element is a SEQUENCE OF, or SET OF, then the value in the namespace
Packit ef9df4
will be an array reference. The elements in the array will be of
Packit ef9df4
the type expected by the type following the OF. For example
Packit ef9df4
with "SEQUENCE OF STRING" the array would contain strings. With
Packit ef9df4
"SEQUENCE OF SEQUENCE { ... }" the array will contain hash references
Packit ef9df4
which will be used as namespaces
Packit ef9df4
Packit ef9df4
  # ASN.1
Packit ef9df4
  int INTEGER,
Packit ef9df4
  str SEQUENCE OF OCTET STRING
Packit ef9df4
Packit ef9df4
  # Perl
Packit ef9df4
  { int => 5, str => [ "text1", "text2"]}
Packit ef9df4
Packit ef9df4
  # ASN.1
Packit ef9df4
  int INTEGER,
Packit ef9df4
  str SEQUENCE OF SEQUENCE {
Packit ef9df4
    type OCTET STRING,
Packit ef9df4
    value INTEGER
Packit ef9df4
  }
Packit ef9df4
Packit ef9df4
  # Perl
Packit ef9df4
  { int => 5, str => [
Packit ef9df4
    { type => "abc", value => 4 },
Packit ef9df4
    { type => "def", value => -1 },
Packit ef9df4
  ]}
Packit ef9df4
Packit ef9df4
Finally, if you wish to pre-parse ASN.1 and hold it to include
Packit ef9df4
inline in your PDU, you can coerce it into the ASN.1 spec by
Packit ef9df4
defining the value as ANY in the schema, and then pass the pre
Packit ef9df4
encoded value inline.
Packit ef9df4
Packit ef9df4
  # ASN.1
Packit ef9df4
  int INTEGER,
Packit ef9df4
  str OCTET STRING,
Packit ef9df4
  pre ANY
Packit ef9df4
Packit ef9df4
  # Perl
Packit ef9df4
  { int => 5, str => "text", pre=>"\x03\x03\x00\x0a\x05" }
Packit ef9df4
Packit ef9df4
passes a pre-encoded BIT STRING instance as hex text. -But
Packit ef9df4
it could be a previous run of $obj->encode() from another run
Packit ef9df4
held in some variable.
Packit ef9df4
Packit ef9df4
Packit ef9df4
=head2 Exceptions
Packit ef9df4
Packit ef9df4
There are some exceptions where Convert::ASN1 does not require an element to be named.
Packit ef9df4
These are SEQUENCE {...}, SET {...} and CHOICE. In each case if the element is not
Packit ef9df4
given a name then the elements inside the {...} will share the same namespace as
Packit ef9df4
the elements outside of the {...}.
Packit ef9df4
Packit ef9df4
=head1 TODO
Packit ef9df4
Packit ef9df4
=over 4
Packit ef9df4
Packit ef9df4
=item *
Packit ef9df4
Packit ef9df4
XS implementation.
Packit ef9df4
Packit ef9df4
=item *
Packit ef9df4
Packit ef9df4
More documentation.
Packit ef9df4
Packit ef9df4
=item *
Packit ef9df4
Packit ef9df4
More tests.
Packit ef9df4
Packit ef9df4
=back
Packit ef9df4
Packit ef9df4
=head1 AUTHOR
Packit ef9df4
Packit ef9df4
Graham Barr <gbarr@cpan.org>
Packit ef9df4
Packit ef9df4
=head1 SUPPORT
Packit ef9df4
Packit ef9df4
Report issues via github at https://github.com/gbarr/perl-Convert-ASN1/issues
Packit ef9df4
Packit ef9df4
To contribute I encourage you to create a git fork of the repository at
Packit ef9df4
https://github.com/gbarr/perl-Convert-ASN1 do you work on a fresh branch
Packit ef9df4
created from master and submit a pull request
Packit ef9df4
Packit ef9df4
=head1 COPYRIGHT
Packit ef9df4
Packit ef9df4
Copyright (c) 2000-2012 Graham Barr <gbarr@cpan.org>. All rights reserved.
Packit ef9df4
This program is free software; you can redistribute it and/or
Packit ef9df4
modify it under the same terms as Perl itself.
Packit ef9df4
Packit ef9df4
=cut