Aw: Any ASN.1 API exploitable for network protocols?

Oliver Korpilla Oliver.Korpilla@REDACTED
Wed Jul 1 13:13:26 CEST 2020


Hi,

so instead of using a Erlang binaries to decode bits and bytes to meaningful fields you would prefer to write it as ASN.1 syntax, right?

How ASN.1 does do the bit encoding/decoding of a particular ASN.1 definition is defined in the "encoding rules."

BER stands for Basic Encoding Rules. IIRC this replicates a lot of the structure information into the encoding itself, sacrificing space for increased decodability. I think structures get prefixed with information helpful in decoding them.

PER stands for Packed Encoding Rules, UPER stands for Unaligned PER. UPER saves bytes for encoding arrays IIRC by not aligning arrays to byte boundaries, and PER in general contains less information as to how to decode an ASN.1 payload. PER/UPER are used in Telco protocols like RRC, S1AP, NGAP, X2AP, F1AP, etc.

In order to use ASN.1 as a description protocol for anything else I would assume ideally you would write a matching encoding rule. I don't know if other rules than BER/PER/UPER have been implemented in asn1ct or if it is extensible in that way. I only use it for PER/UPER protocols myself.

The problem is that for example PER tries to save space wherever possible by knowing what it is meant to decode. If you have 4 entries maximum in an array, the length field of that array will be shrunk to 2 bits, saving wire bits. So, emulating a regular protocol with PER or UPER would require understanding the rules, then making length fields the right size, inserting padding bytes if necessary manually (depends on protocols, we have a protocol emulating what the C compiler does manually, and hence you have padding bytes). But in principle you could probably approximate it with PER somewhat. It might break down with choice fields as these follow the same "only as many bits as needed" rule and that might always come down to the number of choices... 

I think with BER you would run into the problem that you have these prefixes for structured content...

So, this is my guess on what you are trying to do and what you might run into. You can compile some ASN.1 with asn1ct and look at what you get, the code is... readable, to an extent.

You might be better off with Erlang binaries who are good at matching information out of protocol bits, that said.

Best regards,
Oliver 

Gesendet: Mittwoch, 01. Juli 2020 um 12:49 Uhr
Von: "Papa Tana" <papa.tana101@REDACTED>
An: erlang-questions@REDACTED
Betreff: Any ASN.1 API exploitable for network protocols?
Hi All,

NTP is just taken as an example here.

I have built a simple NTP client.

create_ntp_request() -> << 0:2, 3:3, ... >>.

% 0 1 2 3
% 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
% +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
% |LI | VN |Mode | Stratum | Poll | Precision |
% +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
% | Root Delay |
% +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
..........

The NTP server is answering me and I can decode the response.

display_result(<<
LI:2,
VN:3,
.....
>>) ->
// DO SOME JOB
;

HERE comes my problem:

The NTP server is not speaking ASN.1 at all.
I am sending a binary request, he is answering me with binary response.
And this is the way it should be.

It would be great if it was possible to do something like below:

Protocols
DEFINITIONS AUTOMATIC TAGS ::=
BEGIN
NTPRequest ::= SEQUENCE {
li BIT STRING (SIZE(2)),
version BIT STRING (SIZE(3)),
blablablabla...........
}
NTPResponse ::= SEQUENCE {
li BIT STRING (SIZE(2)),
version BIT STRING (SIZE(3)),
blablablabla...........
}
END

> SomeNtpRequest = {'NTPRequest'}.
> setElement(2, <<0:2>>, SomeNtpRequest).
> setElement(3, <<3:3>>, SomeNtpRequest).

> Standard = 'Protocols':transform2Standard('NTPRequest', SomeNtpRequest).

> ok = gen_udp:send(Skt, Host, ?NTP_UDP_PORT, Standard).


> Response = /* receive dummy NTP response from server <<28,2,3,...>> */
> BAsn = 'Protocols':transform2Asn('NTPResponse', Response).

> 'Protocols':decode('NTPResponse', BAsn).
> {ok,{'NTPResponse',<<1:2>>, <<3:3>>,...

Any suggestion please?

This question is interesting because it would be really useful to
manipulate network protocols like GTP, Diameter, PFCP, etc... if any
API.

Thank you,


More information about the erlang-questions mailing list