Generic asn.1 parser

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view

Generic asn.1 parser

Sean Hinde-2

I felt the need for an asn.1 parser which would decode generic asn.1 data
into a tree structure. Here's the result in case anyone else might have felt
this need!

It seems to work fine for a whole bunch of c7 MAP messages (which include
nested indefinite length constructor tags). I guess if it deals with those
it should be in a reasonably working state :)

The output format is a bit arbritrary.

Don't sue me if it causes your business to fail etc. Please let me know if
you improve it

I use atoms quite a bit - does anyone have a good feel for the performance
impact of this over using integers for matching and tagging?


%% Decode asn1 coded binary into parse tree
%% Handles indefinite length if re-assembly has already been
%% done - should be relatively easy to allow for segmented though
%% as we keep a count of unrequited indefinite length
%% constructor tags.
asn1_decode(Bin) ->
    asn1_decode(Bin, 0).
asn1_decode(<<>>, 0) ->
asn1_decode(Bin, N0) ->
    {Class, Form, Tag, Rest, N} = get_tag(Bin, N0),
    case tag_type(Class, Form, Tag) of
        indefinite_end ->
            asn1_decode(Rest, N);
        Constructor when Constructor == set;
                             Constructor == seq;
                             Constructor == constructor ->
            case get_length(Rest) of
                {indefinite, Rest1} ->
                    [{{Constructor, indef, Class, Tag}, asn1_decode(Rest1,
                {Len, Rest1} ->
                    {Data, Rest2} = get_content(Len, Rest1),
                    [{{Constructor, Class, Tag}, asn1_decode(Data, 0)}|
                     asn1_decode(Rest2, N)]
        tag ->
            {Len, Rest1} = get_length(Rest),  
            {Data, Rest2} = get_content(Len, Rest1),
            [{{tag, fmt_class(Class), Tag}, Data}|asn1_decode(Rest2, N)]

%% Get tag data. 0:1, 0:15 gets around compiler
%% bug as I haven't updated my PC yet..
get_tag(<<0:1, 0:15, Rest/binary>>, 0) ->
get_tag(<<0:1, 0:15, Rest/binary>>, N) ->
    {indefinite_end, 0, 0, Rest, N-1};
get_tag(<<Class:2, Form:1, Tag:5, Rest/binary>>, N) ->
    {Tag1, Rest1} = get_tag1(Tag, Rest),
    {Class, Form, Tag1, Rest1, N}.

%% Handle extension parts of the tag field
get_tag1(31, <<0:1, Tag:7, Rest/binary>>) ->
    {Tag, Rest};
get_tag1(31, <<1:1, Msb:7, _:1, Lsb:7, Rest/binary>>) ->
    {Msb*128+Lsb, Rest};
get_tag1(Tag, Rest) ->
    {Tag, Rest}.
% Do short and long definite length forms
% And *now*... indefinite length!
get_length(<<0:1, Len:7, Rest/binary>>) ->
    {Len, Rest};
get_length(<<1:1, 0:7, Rest/binary>>) ->
    {indefinite, Rest};
get_length(<<1:1, Len_len:7, Rest/binary>>) ->
    <<Len:Len_len/unit:8, Rest1/binary>> = Rest,
    {Len, Rest1}.

% Get actual content of field
get_content(Len, Rest) ->
    <<Data:Len/binary, Rest1/binary>> = Rest,
    {Data, Rest1}.
% tag_type(Class, Form, Tag) -> tag|seq|set|constructor
tag_type(indefinite_end, _, _) -> indefinite_end;
tag_type(Class, 0, Tag) -> tag;
tag_type(0, 1, 16)       -> seq;
tag_type(0, 1, 17)       -> set;
tag_type(Class, 1, Els) -> constructor.

fmt_class(0) -> univ;
fmt_class(1) -> app;
fmt_class(2) -> context;
fmt_class(3) -> priv.

This email (including attachments) is confidential.  If you have received
this email in error please notify the sender immediately and delete this
email from your system without copying or disseminating it or placing any
reliance upon its contents.  We cannot accept liability for any breaches of
confidence arising through use of email.  Any opinions expressed in this
email (including attachments) are those of the author and do not necessarily
reflect our opinions.  We will not accept responsibility for any commitments
made by our employees outside the scope of our business.  We do not warrant
the accuracy or completeness of such information.

Reply | Threaded
Open this post in threaded view

Generic asn.1 parser

Ulf Wiger-4
On Wed, 11 Apr 2001, Sean Hinde wrote:

>I use atoms quite a bit - does anyone have a good feel for the
>performance impact of this over using integers for matching and

There should be no performance difference.

Ulf Wiger                                    tfn: +46  8 719 81 95
Senior System Architect                      mob: +46 70 519 81 95
Strategic Product & System Management    ATM Multiservice Networks
Data Backbone & Optical Services Division      Ericsson Telecom AB