asn1 man page on Inferno

Man page or keyword search:  
man Server   579 pages
apropos Keyword Search (all sections)
Output format
Inferno logo
[printable version]

ASN1(2)								       ASN1(2)

NAME
       asn1: decode, encode - ASN.1 (X.208), BER (X.209) encoding

SYNOPSIS
       include "asn1.m";
       asn1 := load ASN1 ASN1->PATH;
       asn1->init();

       Elem: adt {
	   tag: Tag;
	   val: ref Value;

	   is_seq:	   fn(e: self ref Elem): (int, list of ref Elem);
	   is_set:	   fn(e: self ref Elem): (int, list of ref Elem);
	   is_int:	   fn(e: self ref Elem): (int, int);
	   is_bigint:	   fn(e: self ref Elem): (int, array of byte);
	   is_bitstring:   fn(e: self ref Elem): (int, int, array of byte);
	   is_octetstring: fn(e: self ref Elem): (int, array of byte);
	   is_oid:	   fn(e: self ref Elem): (int, ref Oid);
	   is_string:	   fn(e: self ref Elem): (int, string);
	   is_time:	   fn(e: self ref Elem): (int, string);
	   tostring:	   fn(e: self ref Elem): string;
       };

       Tag: adt {
	   class: int;
	   num: int;
	   constr: int;

	   tostring: fn(t: self Tag): string;
       };

       Value: adt {
	   pick {
	       Bool or Int =>
		   v: int;
	       Octets or BigInt or Real or Other =>
		   bytes: array of byte;
	       BitString =>
		   unusedbits: int;
		   bits: array of byte;
	       Null or EOC =>
		   ;
	       ObjId =>
		   id: ref Oid;
	       String =>
		   s: string;
	       Seq or Set =>
		   l: list of ref Elem;
	   }

	   tostring: fn(v: self ref Value): string;
       };

       Oid: adt {
	   nums: array of int;
	   tostring: fn(o: self ref Oid): string;
       };

       init: fn();
       decode:	     fn(a: array of byte): (string, ref Elem);
       decode_seq:   fn(a: array of byte): (string, list of ref Elem);
       decode_value: fn(a: array of byte, kind, constr: int):
		     (string, ref Value);
       encode:	     fn(e: ref Elem): (string, array of byte);
       oid_lookup:   fn(o: ref Oid, tab: array of Oid): int;
       print_elem:   fn(e: ref Elem);

DESCRIPTION
       ASN1  supports  decoding and encoding of the ASN.1 Basic Encoding Rules
       (BER, ITU-T Recommendation X.209).  Despite its name, the module is not
       a  parser for Abstract Syntax Notation One (ASN.1, ITU-T Recommendation
       X.208).

       ASN1 handles the BER encodings of all types from	 the  ASN.1  Universal
       class, and provides a simple OBJECT IDENTIFIER comparison facility.

       For simplicity, ASN1 does not take a description of the ASN.1 module of
       the data being processed.  Consequently, the (de)composition of	tagged
       types  must  be	performed  by the application.	ASN1 does not know the
       context of tagged values and so cannot determine the underlying Univer‐
       sal  type  to be able to encode or decode the value automatically.  See
       the section on Tagging for details on how the application should handle
       both implicit and explicit tagging.

       init() The  module  must be initialised by calling this function before
	      any other module functions or associated	adt  member  functions
	      are called.

       decode(a)
	      Convert  the BER encoding given by the byte array a into an Elem
	      representing the ASN.1 value.  The byte array must  contain  the
	      entire BER encoding of the value and any component values.

	      Item  values  not tagged as a Universal type are converted to an
	      Elem comprised of the decoded Tag	 and  a	 value	given  by  the
	      Value.Octets  variant,  which  contains the original encoding of
	      the value stripped of the BER tag and length header.

	      The function returns a tuple composed of an error string and the
	      decoded  Elem.  If no errors are encountered the error string is
	      nil.

       decode_seq(a)
	      Like decode except that the data in a is the encoding of an item
	      of  type	SEQUENCE,  SEQUENCE  OF,  SET or SET OF which has been
	      stripped of its tag and length header.  The function decodes all
	      of the items in the SEQUENCE or SET.

	      The  return value is a tuple composed of an error string and the
	      list of Elems forming the SEQUENCE or SET.

       decode_value(a, kind, constr)
	      Convert the encoding of a single item  value  to	a  Value  data
	      structure.

	      The  array  a  does  not	include	 the  tag  and	length header.
	      Instead, the value's Universal type is given by the  kind	 argu‐
	      ment and length is given by that of the array.  The constr argu‐
	      ment indicates if the encoding is in the BER constructed form or
	      not.   A	value  of  0  indicates that the primitive encoding is
	      used, all other values indicate the constructed encoding.

	      The function returns a tuple composed of an error string	and  a
	      Value reference.

       encode(e)
	      Convert  the  Elem  e  to a BER encoding of the element.	If the
	      element is of a structured type, such as SEQUENCE or  SET,  then
	      all component values are also exhaustively encoded.

	      The  encoding  can  fail if the Tag and Value of the element are
	      not compatible.  The  constr  field  of  the  Tag	 is  currently
	      ignored.

	      The  function returns a tuple comprising an error string and the
	      BER encoding.  If no errors are encountered the error string  is
	      nil and the second part of the returned tuple is a byte array of
	      the BER encoding.

       oid_lookup(o, tab)
	      Lookup an OBJECT IDENTIFIER value in an array  of	 such  values.
	      Returns  the  index  of  the  first  exact match of o in the tab
	      array.  Returns -1 if no match is found.

       print_elem(e)
	      Print a textual representation of the element to	standard  out‐
	      put.  The output is that given by Elem.tostring(), followed by a
	      newline character.

   Elem adt
       This is the principal data structure,  representing  the	 value	of  an
       ASN.1 item.  The adt couples a data representation, the Value, with its
       type specifier, the Tag.

       Elem.tag
	      Specifies the ASN.1 type of the element value.  See the descrip‐
	      tion of the Tag adt for more details.

       Elem.val
	      The  value of the element.  See the description of the Value adt
	      for more details.

       All of the e.is_Type member functions test whether the  specific	 Value
       pick  variant  of  Elem.val  and the ASN.1 Universal type, given by the
       tag, match and are of the requested form.  A  successful	 match	yields
       the type specific data from the Value pick variant.  The association of
       Universal types to Value pick variants is given in the section  on  the
       Value adt.

       The  function  e.is_int	succeeds  for BOOLEAN and INTEGER ASN.1 types.
       The function e.is_string succeeds for all of the ASN.1 Universal string
       types.

       Except  for  is_bitstring, each function returns a tuple of two values.
       The first tuple item is an integer, 1 for success, 0 for failure.   The
       second item is the type specific data from the Value pick variant.

       e.is_bitstring()
	      Like the is_Type functions described above.  Tests that the ele‐
	      ment is a BIT STRING and returns its data.

	      The return value is a tuple comprised of	two  integers  and  an
	      array  of bytes.	The byte array represents the bit string.  The
	      first integer is 1 for success, 0 for failure.  The second inte‐
	      ger  is  the  number of unused bits in the last byte of the data
	      array.  See the description of the Value.BitString  variant  for
	      more information.

       e.tostring()
	      returns  a textual representation of the element formed by join‐
	      ing   the	  strings   returned   from    e.tag.tostring()	   and
	      e.val.tostring().

   Tag adt
       The Tag adt denotes the ASN.1 type of a Value instance.

       Tag.class
	      Specifies	 the class of the type and can take one of the values:
	      ASN1->Universal, ASN1->Application, ASN1->Context or  ASN1->Pri‐
	      vate.

       Tag.num
	      Identifies  the  particular  type,  or tag, within the specified
	      class.  Tag numbers for the Universal class  are	given  in  the
	      asn1.m  header  file.   The  inconsistent	 use of upper-case and
	      mixed-case identifiers comes straight from the ITU-T Recommenda‐
	      tion.

       Tag.constr
	      This flag is set by the ASN1 decode functions to mark if the BER
	      constructed encoding was used for the value.  A zero value indi‐
	      cates  the  BER  primitive encoding, non-zero indicates the con‐
	      structed encoding.

       t.tostring()
	      Returns a string representation of the Tag.  For Universal class
	      tags  the	 function returns the string ``UNIVERSAL Name'', where
	      Name is the standard name of the specified Universal type.   For
	      other  classes  the  function  returns the class name, in upper-
	      case, followed by the tag number.

   Value adt
       This pick adt provides the representation for values  of	 each  of  the
       various	Universal class types.	Values of all other classes are repre‐
       sented by the Value.Octets branch of the pick.

       v.tostring()
	      Returns a string representation of the Value.

       The following table lists each variant  of  the	pick,  indicating  the
       ASN.1 Universal type values it represents, followed by a brief descrip‐
       tion.  For each variant of the pick, v is taken to be of that  particu‐
       lar type.

       Value.Bool
	      BOOLEAN

	      v.v equals zero for FALSE, non-zero values represent TRUE.

       Value.Int
	      INTEGER, ENUMERATED

	      The value is given by v.v

       Value.BigInt
	      Used for INTEGER values too large to fit a Limbo int.

	      The array v.bytes contains the encoding of the value.  The array
	      does not include the tag and length prefix.

       Value.Octets
	      OCTET_STRING, ObjectDescriptor

	      The octet string is given by the v.bytes array.

       Value.Null
	      NULL

       Value.ObjId
	      OBJECT_ID

	      The OBJECT_ID value is represented by the Oid adt given by v.id.

       Value.Real
	      REAL

	      ASN1 does not convert the value into the Limbo real  data	 type.
	      The  encoding  of the value is given by the v.bytes array, which
	      does not include the tag and length prefix.

       Value.Other
	      EXTERNAL, EMBEDDED_PDV and Unknown Universal types

	      The raw bytes of the value, excluding the tag nad length header,
	      are given by the v.bytes array.

       Value.BitString
	      BIT_STRING

	      The number of bits in the BIT_STRING value does not have to be a
	      multiple of 8.  Bits are packed into bytes MSB first.  The bytes
	      representing  the	 BIT_STRING  value,  including the potentially
	      incomplete last byte, are given by the v.bits array.  The number
	      of  unused  bits	in  the	 last  byte  of	 the array is given by
	      v.unused, counting from the LSB.

	      The BER constructed encoding of values other than zero-length is
	      not implemented.

       Value.EOC
	      End of Contents octets marker.

	      This  value  is  not normally returned to the application; it is
	      used privately by BER to support indefinite length value	encod‐
	      ings.

       Value.String
	      NumericString,  PrintableString,	TeletexString, VideotexString,
	      IA5String,  UTCTime,   GeneralizedTime,	GraphicString,	 Visi‐
	      bleString, GeneralString, UniversalString or BMPString.

	      The text is given by the v.s Limbo string.  Currently no charac‐
	      ter-set conversion is performed between the  ASN.1  string  byte
	      codes and the Unicode code-points of the Limbo string.

       Value.Seq
	      SEQUENCE, SEQUENCE OF

	      ASN.1 assigns both constructs the same type tag.	The difference
	      between them is that, within the ASN.1 notation, the elements of
	      a	 SEQUENCE OF structure are constrained to be of the same type.
	      BER and, consequently, ASN1 do not directly enforce the restric‐
	      tion.

	      The elements of the sequence are given by the v.l list.

       Value.Set
	      SET, SET OF

	      ASN.1 assigns both constructs the same type tag.	The difference
	      between them is that, within the ASN.1 notation, SET  items  are
	      formed  from an unordered list of distinct types, whereas SET OF
	      items are formed from an unordered list of the same  type.   BER
	      and ASN1 do not enforce these constraints.

	      The elements of the set are given by the v.l list.

   Oid adt
       The  Oid	 adt  provides the value representation for OBJECT IDENTIFERs.
       Within the ASN.1 notation  OBJECT  IDENTIFIERs  ultimately  map	to  an
       ordered list of INTEGERs.

       Oid.nums
	      The value of the OBJECT IDENTIFIER, given as an array of int.

       o.tostring()
	      Returns a textual representation of the OBJECT IDENTIFIER in the
	      form of a `.' separated list of numbers.

   Tagging
       Tagging is an ASN.1 mechanism for disambiguating values.	 It is usually
       applied	to  component  types, where several components of a structured
       type have the same underlying Universal class type.  Tagging allows the
       client  application to determine to which item of the structured type a
       value instance belongs.

       There are two types of tagging, implicit	 and  explicit,	 defining  the
       manner in which the values are encoded.

       Implicitly  tagged values are encoded in the same way as the underlying
       type, but with the tag class and number replaced by that specified.

       Explicitly tagged values are encoded in a nested fashion.   The	outer‐
       most item bears the specified tag and its contents is the full encoding
       of the original value using the tag of its underlying type.

       The following examples of how to decode and encode simple tagged	 types
       should make the distinction clear.

   Decoding Tagged Values
       Consider the following ASN.1 type definitions:

	   Type1 ::= INTEGER
	   Type2 ::= [Application 2] Type1     -- Explicitly tagged
	   Type3 ::= [3] IMPLICIT Type1	       -- Implicitly tagged

       For each of the types the value 16r55 will be decoded as follows:

	    (error, elem) := asn1->decode(data);

       Type1 (primitive type)
	      elem.tag.class == Universal
	      elem.tag.num == INTEGER
	      tagof elem.val == tagof Value.Int
	      elem.is_int() == (1, 16r55)

       Type2 (explicitly tagged)
	      elem.tag.class == Application
	      elem.tag.num == 2
	      tagof elem.val == tagof Value.Octets

	      The  bytes array of the Value.Octets value contains the complete
	      encoding of the Type1 value.  The actual value can  be  obtained
	      as follows:

	      pick v := elem.val {
	      Octets =>
		   (err2, e2) := asn1->decode(v.bytes);
	      }
	      with  e2 having exactly the same properties as elem in the Type1
	      case above.

       Type3 (implicitly tagged)
	      elem.tag.class == Context
	      elem.tag.num == 3
	      tagof elem.val == tagof Value.Octets

	      In this case the bytes array of the Value.Octets value  contains
	      the  encoding of just the value part of the Type1 value, not the
	      complete encoding.  The actual value can be obtained as follows:

	      pick v := e.val {
	      Octets =>
		  constr := e.tag.constr;
		  (err, val) := asn1->decode_value(v.bytes, INTEGER, constr);
	      }

	      Note that the application has to infer the  type	of  the	 value
	      from  the	 context  in which it occurs.  The resultant val is of
	      the type Value.Int with the value 16r55 stored in the  v	member
	      variable.

   Encoding Tagged Values
       To  encode  the	value  16r55 in each of the above types, the following
       data structures are required.

       Type1(primitive type)
	      tag := Tag(Universal, INTEGER, 0);
	      val := Value.Int(16r55);
	      elem := ref Elem(tag, val);
	      (err, data) := asn1->encode(elem);

       Type2(explicitly tagged)
	      tag1	    := Tag(Universal, INTEGER, 0);
	      val1	    := Value.Int(16r55);
	      elem1	    := ref Elem(tag1, val1);
	      (err1, data1) := asn1->encode(elem1);
	      tag2	    := Tag(Application, 2, 0);
	      val2	    := Value.Octets(data1);
	      elem2	    := ref Elem(tag2, val2);
	      (err, data)   := asn1->encode(elem2);

       Type3(implicitly tagged)
	      tag	  := Tag(Context, 3, 0);
	      val	  := Value.Int(16r55);
	      elem	  := ref Elem(tag, val);
	      (err, data) := asn1->encode(elem);

SOURCE
       /appl/lib/asn1.b

BUGS
       It is irritating that REAL values are  not  converted  by  the  module.
       This  forces  the  application to do the conversion to and from the raw
       BER encoding.  Fortunately they are rarely used.

       String encodings are converted as  UTF-8	 byte  sequences.   This  will
       result in strings comprising any character codes above 127 being incor‐
       rectly converted.

       There is a particular form of BER encoding that the module will	handle
       incorrectly,  resulting	in  a decoding error.  The error occurs when a
       tagged value is encoded using the indefinite length specifier  and  the
       constructed representation.

								       ASN1(2)
[top]

List of man pages available for Inferno

Copyright (c) for man pages and the logo by the respective OS vendor.

For those who want to learn more, the polarhome community provides shell access and support.

[legal] [privacy] [GNU] [policy] [cookies] [netiquette] [sponsors] [FAQ]
Tweet
Polarhome, production since 1999.
Member of Polarhome portal.
Based on Fawad Halim's script.
....................................................................
Vote for polarhome
Free Shell Accounts :: the biggest list on the net