# asn1

This is the part of the ASN1 encoder/decoder library, which is independent of the type of encoding. The classes defined in this file are allocated statically to create the definition of the ASN1 data structures.

The asn1_per or asn1_ber are used together with these definitions to do the actual Basic Encoding Rule (asn1_ber) or Packet Encoding Rules (asn1_per) encoding and decoding.

The asn1_in and asn1_out are abstract classes are used by the actual encoder/decoder to read/write the data. This way the encoder/decoder may be adapted to different data representations. Functions for reading and writing, bits, bit fields, octets and octet fields need to be provided.

## File information

File | common/ilib/asn1.h
Public functions | read_object_identifier write_object_identifier
Classes | asn1_out asn1_in asn1_context asn1 asn1_null asn1_boolean asn1_int asn1_ints asn1_inte asn1_int8 asn1_int16 asn1_bitstring asn1_enumerated asn1_octet_array asn1_ia5_string asn1_octet_string asn1_word_string asn1_object_identifier asn1_sequence asn1_choice asn1_sequence_of asn1_set_of asn1_numeric_string asn1_any
Examples | Sequence Definition

# Functions

    void read_object_identifier(byte * in, dword * out);
    void write_object_identifier(dword * in, byte * out);

read_object_identifier
  Reads an object identifier from its normal ASN1 representation as byte array into an array of dwords with each node as one dword in the array.
write_object_identifier
  Writes an object identifier to its normal ASN1 representation as byte array from an array of dword, with each node as one dword in the array.

# Classes

## asn1_out

    class asn1_out {
    public:
        virtual void bit(bool v)=0;
        virtual void bit_field(dword v, int len)=0;
        virtual void octet(byte v)=0;
        virtual void octet_field(byte * v, int len)=0;
        virtual void align()=0;
        virtual void * new_stream(void * stream)=0;
        virtual void append(void * stream)=0;
        virtual dword length()=0;
        virtual void get_reference(void * & buffer, int & offset)=0;
    };

Abstract class to write encoded data. Used by the encoder.

bit
  Write a single bit
bit_field
  write a bit field of length bits
octet
  write a single octet
octet_field
  write an octet field of length octets
align
  align the output according to encoding rules, so that next output is aligned
new_stream
  opens a new stream for output, which may be added to the output later. Multiple new streams may be used nested. The outer stream is passed as 'stream'.
append
  append a stream to the output
length
  return the total length of the output data
get_reference
  get a reference to the current output position. The meaning of buffer and offset depends on the actual output class

## asn1_in

    class asn1_in {
    public:
        virtual bool bit()=0;
        virtual dword bit_field(int len)=0;
        virtual byte octet()=0;
        virtual void octet_field(byte * v, int len)=0;
        virtual void align()=0;
        virtual int left()=0;
        virtual void abort()=0;
        virtual int get_count()=0;
        virtual void set_count(int count)=0;
        virtual void skip(int count)=0;
        virtual void save()=0;
        virtual void restore()=0;
        virtual void get_reference(void * & buffer, int & offset)=0;
    };

Abstract class to read encoded data. Used by the decoder.

bit
  read a single bit
bit_field
  read a bit field of length bits
octet
  read a single octet
octet_field
  read a octet field oflengthoctets
align
  align input according to the encoding rules
left
  return data left in the input
abort
  abort input sets count of read bytes to the end of the input
get_count
  get count of already read bytes
set_count
  set read position tocount
skip
  skipcountbytes on input
save
  save the current input position
restore
  restore the last saved input position
get_reference
  get a reference to the current input position. The meaning of buffer and offset depends on the actual output class

## asn1_context, asn1_tag

    struct asn1_tag {
        dword tag;
        void * content;
    };

    class asn1_context {
    protected:
        int tag_buffer_size;
        int tag_index;
        struct asn1_tag * tag_buffer;
        int content_buffer_size;
        int content_index;
        byte * content_buffer;
        unsigned fix_mask;
        bool trace;

    public:
        asn1_context(struct asn1_tag * tag_buffer, int tag_buffer_size, void * content_buffer, int content_buffer_size, bool trace);
        struct asn1_tag * new_tag(word tag);
        struct asn1_tag * new_tag(word tag, int size, dword align);
        struct asn1_tag * find_tag(word tag);
        void set_seq(int num);
        dword get_mask();
        dword set_mask(dword mask);
        bool trace_on() { return trace; };
        void set_fix(unsigned fix_mask) { this->fix_mask = fix_mask; };
        int get_content_index() { return content_index; };

        virtual void read(class asn1 & asn1, class asn1_in & in)=0;
        virtual void write(class asn1 & asn1, class asn1_out & out)=0;

        int level;

        dword seq_of;
        dword seq_mask;
    };

class to holding the actual decoded data or holding the data to be encoded. See documentation of specific encoder for usage.

## asn1

    class asn1 {

    public:
        word tag;
        word type;
        const char * name;

        asn1(int & tag, const char * name);

        bool is_present(class asn1_context & context);
        virtual void fix(unsigned fix_mask) {};
    };

For each supported datatype a class is available for the definition, which uses the class asn1 as base class. These classes have type specific put_content and get_content functions. To put data into the coder context or get data from the coder context.

All the classes, which use asn1 as base class have arguments tag and base as first arguments of their constructor. Tag is used to increment a tag variable, so that each data gets a unique tag. The name is used just for creating debug information, when encoding or decoding.

A third argumenet properties, if present, is used for the flag ASN1_EXTENSION, which indicates that the datatype may be extended.

### asn1_null

    class asn1_null : public asn1 {

    public:
        asn1_null(int & tag, const char * name);

        void put_content(class asn1_context & context);
    };

ASN1 NULL datatype. The put_content sets the element as present.

### asn1_boolean

    class asn1_boolean : public asn1 {

    public:
        asn1_boolean(int & tag, const char * name);

        bool get_content(class asn1_context & context);
        void put_content(class asn1_context & context, bool content);
    };

ASN1 BOOLEAN datatype

### asn1_int

    class asn1_int : public asn1 {

    public:
        byte count_bits;

        asn1_int(int & tag, const char * name, byte count_bits);

        dword get_content(class asn1_context & context);
        void put_content(class asn1_context & context, dword content);
    };

ASN1 INTEGER datatype, assumes positve values

count_bits
  Number of bits needed for the integer value. 0 means no restriction

### asn1_ints

    class asn1_ints : public asn1 {

    public:
        asn1_ints(int & tag, const char * name);

        int get_content(class asn1_context & context);
        void put_content(class asn1_context & context, int content);
    };

ASN1 INTEGER datatype which allows negative values. No restrictions can be defined with this type.

### asn1_inte

    class asn1_inte : public asn1 {

    public:
        byte count_bits;
        dword max;

        asn1_inte(int & tag, const char * name, byte count_bits, dword max);

        dword get_content(class asn1_context & context);
        void put_content(class asn1_context & context, dword content);
    };

ASN1 INTEGER datatype, which may be extended. count_bits is the not extended size. max the maximum value.

### asn1_int8

    class asn1_int8 : public asn1 {

    public:
        asn1_int8(int & tag, const char * name);

        dword get_content(class asn1_context & context);
        void put_content(class asn1_context & context, dword content);
    };

ASN1 INTEGER datatype. Optimization for the common case of an restriction to 8 bits.

### asn1_int16

    class asn1_int16 : public asn1 {

    public:
        asn1_int16(int & tag, const char * name);

        dword get_content(class asn1_context & context);
        void put_content(class asn1_context & context, dword content);
    };

ASN1 INTEGER datatype. Optimization for the common case of an restriction to 16 bits.

### asn1_bitstring

    class asn1_bitstring : public asn1 {

    public:
        word min_length;
        word max_length;
        byte len_bits;

        asn1_bitstring(int & tag, const char * name, int min_length, int max_length, int len_bits);

        byte * get_content(class asn1_context & context, int * length);
        void put_content(class asn1_context & context, byte * s, int length);
        void put_content(class asn1_context & context, class packet * data);
        word get_offset(class asn1_context & context, class packet * data);
    };

ASN1 BITSTRING datatype.

min_length
  The minimum number of bits
max_length
  The maximum length of bits
len_bits
  Bits needed to represent the length, which is the number of bits needed to represent max_length - min_length

### asn1_enumerated

    class asn1_enumerated : public asn1 {

    public:
        byte properties;
        dword count;
        byte count_bits;

        asn1_enumerated(int & tag, const char * name, byte properties, byte count, byte count_bits);

        dword get_content(class asn1_context & context);
        void put_content(class asn1_context & context, dword content);
    };

ASN1 ENUMERATED datatype

count
  Number of enumerated values
count_bits
  Number of bits needed to represent count

### asn1_octet_array

    class asn1_octet_array : public asn1 {

    public:
        word length;

        asn1_octet_array(int & tag, const char * name, word length);

        byte * get_content(class asn1_context & context);
        void put_content(class asn1_context & context, byte * content);
    };

ASN1 OCTET ARRAY

length
  length of the array

### asn1_ia5_string

    class asn1_ia5_string : public asn1 {

    public:
        word min_length;
        word max_length;
        byte len_bits;
        byte char_bits;
        const char * from;

        asn1_ia5_string(int & tag, const char * name, int min_length, int max_length, byte len_bits, byte char_bits, const char * from);

        byte * get_content(class asn1_context & context, int * length);
        void put_content(class asn1_context & context, byte * s, int length);
    };

ASN1 IA5 STRING

min_length
  The minimum length of the string
max_length
  The maximum length of the string
len_bits
  The number of bits needed to represent max_length - min_length
char_bits
  The bits for a single character
from
  Array of characters represented by char_bits

### asn1_octet_string

    class asn1_octet_string : public asn1 {

    public:
    	int std_tag;
    	word min_length;
        word max_length;
        byte len_bits;

        asn1_octet_string(int & tag, const char * name, int min_length, int max_length, int len_bits);

        byte * get_content(class asn1_context & context, int * length);
        void put_content(class asn1_context & context, byte * s, int length);
        void put_content(class asn1_context & context, class packet * data);
    };

ASN1 OCTET STRING

min_length
  The minimum length of the string
max_length
  The maximum length of the string
len_bits
  The number of bits needed to represent max_length - min_length

### asn1_word_string

    class asn1_word_string : public asn1 {

    public:
        word min_length;
        word max_length;
        byte len_bits;

        asn1_word_string(int & tag, const char * name, int min_length, int max_length, int len_bits);

        word * get_content(class asn1_context & context, int * length);
        void put_content(class asn1_context & context, word * s, int length);
    };

ASN1 WORD STRING

min_length
  The minimum length of the string
max_length
  The maximum length of the string
len_bits
  The number of bits needed to represent max_length - min_length

### asn1_object_identifier

    class asn1_object_identifier : public asn1 {

    public:
        asn1_object_identifier(int & tag, const char * name);

        byte * get_content(class asn1_context & context);
        void put_content(class asn1_context & context, byte * content);
    };

ASN1 OBJECT IDENTIFIER

### asn1_sequence

    class asn1_sequence : public asn1 {

    public:
        byte properties;
        byte count;
        class asn1 ** table;
        byte * flags;
        word * tag_table;
        byte ext_count;

        asn1_sequence(int & tag, const char * name, byte properties, byte count, class asn1 ** table, byte * flags, byte ext_count=0, word * tag_table=0);

        bool get_content(class asn1_context & context);
        void put_content(class asn1_context & context, bool content);
    };

ASN1 SEQUENCE

count
  number of elements in sequence
table
  array of asn1 elements in the sequence
flags
  array of flags corresponding to the elements. Only ASN1_OPTIONAL is used
ext_count
  Number of asn1 elements extending the sequence
tag_count
  used for BER only

### asn1_choice

    class asn1_choice : public asn1 {

    public:
        byte properties;
        byte count;
        byte count_bits;
        class asn1 ** table;
        word * tag_table;
        byte ext_count;

        asn1_choice(int & tag, const char * name, byte properties, byte count, byte count_bits, class asn1 ** table, byte ext_count=0, word * tag_table=0);

        dword get_content(class asn1_context & context);
        void put_content(class asn1_context & context, dword content);
    };

ASN1 CHOICE

count
  number of elements in choice
count_bits
  number of bits needed to represent count
table
  array of asn1 elements in choice
ext_count
  Number of asn1 elements extending the choice
tag_count
  used for BER only

### asn1_sequence_of

    class asn1_sequence_of : public asn1 {

    public:
    	byte count_bits;
        byte min_length;
        class asn1 * seq;

        asn1_sequence_of(int & tag, const char * name, byte count_bits, byte min_length, class asn1 * seq);

        dword set_mask(class asn1_context & context);
        dword get_content(class asn1_context & context);
        void put_content(class asn1_context & context, dword content);
    };

ASN1 SEQUENCE OF

count_bits
  number of bits needed to represent the number of elements
min_length
  minimum number of elements in sequence of
asn1
  pointer to asn1 class for the type of elements in the sequence of

### asn1_set_of

    class asn1_set_of : public asn1 {

    public:
    	byte count_bits;
        byte min_length;
        class asn1 * seq;

        asn1_set_of(int & tag, const char * name, byte count_bits, byte min_length, class asn1 * seq);

        dword set_mask(class asn1_context & context);
        dword get_content(class asn1_context & context);
        void put_content(class asn1_context & context, dword content);
    };

ASN1 SET OF

### asn1_numeric_string

    class asn1_numeric_string : public asn1 {

    public:
        word min_length;
        word max_length;
        byte len_bits;

        asn1_numeric_string(int & tag, const char * name, int min_length, int max_length, int len_bits);

        byte * get_content(class asn1_context & context, int * length);
        void put_content(class asn1_context & context, byte * s, int length);
        void put_content(class asn1_context & context, class packet * data);
    };

ASN1 NUMERIC STRING

### asn1_any

    class asn1_any : public asn1 {
    public:
        asn1_any(int & tag, const char * name);

        bool get_content(class asn1_context & context);
        void put_content(class asn1_context & context);

        virtual class asn1 * get_actual(class asn1_context & context) {
            return 0;
        }
    };

ASN1 ANY datatype which may hold any asn1 datatype, which means it is encoded containing a length field, because the total length cannot determined by the content