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

Filecommon/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