1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2012-2017. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20%%
21-module(asn1rtt_per_common).
22
23-include("asn1_records.hrl").
24
25-export([decode_fragmented/3,
26	 decode_compact_bit_string/1,
27	 decode_legacy_bit_string/1,
28	 decode_named_bit_string/2,
29	 decode_chars/2,decode_chars/3,
30	 decode_chars_16bit/1,
31	 decode_big_chars/2,
32	 decode_oid/1,decode_relative_oid/1,
33	 encode_chars/2,encode_chars/3,
34	 encode_chars_compact_map/3,
35	 encode_chars_16bit/1,encode_big_chars/1,
36	 encode_fragmented/2,
37	 encode_oid/1,encode_relative_oid/1,
38	 encode_unconstrained_number/1,
39	 bitstring_from_positions/1,bitstring_from_positions/2,
40	 to_bitstring/1,to_bitstring/2,
41	 to_named_bitstring/1,to_named_bitstring/2,
42	 bs_drop_trailing_zeroes/1,adjust_trailing_zeroes/2,
43	 is_default_bitstring/3,is_default_bitstring/5,
44	 extension_bitmap/3,
45	 open_type_to_binary/1,legacy_open_type_to_binary/1]).
46
47-define('16K',16384).
48
49decode_fragmented(SegSz0, Buf0, Unit) ->
50    SegSz = SegSz0 * Unit * ?'16K',
51    <<Res:SegSz/bitstring,Buf/bitstring>> = Buf0,
52    decode_fragmented_1(Buf, Unit, Res).
53
54decode_fragmented_1(<<0:1,N:7,Buf0/bitstring>>, Unit, Res) ->
55    Sz = N*Unit,
56    <<S:Sz/bitstring,Buf/bitstring>> = Buf0,
57    {<<Res/bitstring,S/bitstring>>,Buf};
58decode_fragmented_1(<<1:1,0:1,N:14,Buf0/bitstring>>, Unit, Res) ->
59    Sz = N*Unit,
60    <<S:Sz/bitstring,Buf/bitstring>> = Buf0,
61    {<<Res/bitstring,S/bitstring>>,Buf};
62decode_fragmented_1(<<1:1,1:1,SegSz0:6,Buf0/bitstring>>, Unit, Res0) ->
63    SegSz = SegSz0 * Unit * ?'16K',
64    <<Frag:SegSz/bitstring,Buf/bitstring>> = Buf0,
65    Res = <<Res0/bitstring,Frag/bitstring>>,
66    decode_fragmented_1(Buf, Unit, Res).
67
68decode_named_bit_string(Val, NNL) ->
69    Bits = [B || <<B:1>> <= Val],
70    decode_named_bit_string_1(0, Bits, NNL, []).
71
72decode_legacy_bit_string(Val) ->
73    [B || <<B:1>> <= Val].
74
75decode_compact_bit_string(Val) ->
76    PadLen = (8 - (bit_size(Val) band 7)) band 7,
77    {PadLen,<<Val/bitstring,0:PadLen>>}.
78
79decode_chars(Val, N) ->
80    [C || <<C:N>> <= Val].
81
82decode_chars(Val, N, Chars) ->
83    [element(C+1, Chars) || <<C:N>> <= Val].
84
85decode_chars_16bit(Val) ->
86    Cs = [C || <<C:16>> <= Val],
87    decode_chars_16bit_1(Cs).
88
89decode_big_chars(Val, N) ->
90    decode_big_chars_1(decode_chars(Val, N)).
91
92decode_oid(Octets) ->
93    [First|Rest] = dec_subidentifiers(Octets, 0, []),
94    Idlist = if
95		 First < 40 ->
96		     [0,First|Rest];
97		 First < 80 ->
98		     [1,First - 40|Rest];
99		 true ->
100		     [2,First - 80|Rest]
101	     end,
102    list_to_tuple(Idlist).
103
104decode_relative_oid(Octets) ->
105    list_to_tuple(dec_subidentifiers(Octets, 0, [])).
106
107encode_chars(Val, NumBits) ->
108    << <<C:NumBits>> || C <- Val >>.
109
110encode_chars(Val, NumBits, {Lb,Tab}) ->
111    << <<(enc_char(C, Lb, Tab)):NumBits>> || C <- Val >>.
112
113encode_chars_compact_map(Val, NumBits, {Lb,Limit}) ->
114    << <<(enc_char_cm(C, Lb, Limit)):NumBits>> || C <- Val >>.
115
116encode_chars_16bit(Val) ->
117    L = [case C of
118	     {0,0,A,B} -> [A,B];
119	     C when is_integer(C) -> [0,C]
120	 end || C <- Val],
121    iolist_to_binary(L).
122
123encode_big_chars(Val) ->
124    L = [case C of
125	     {_,_,_,_} -> tuple_to_list(C);
126	     C when is_integer(C) -> [<<0,0,0>>,C]
127	 end || C <- Val],
128    iolist_to_binary(L).
129
130encode_fragmented(Bin, Unit) ->
131    encode_fragmented_1(Bin, Unit, 4).
132
133encode_oid(Val) when is_tuple(Val) ->
134    encode_oid(tuple_to_list(Val));
135encode_oid(Val) ->
136    iolist_to_binary(e_object_identifier(Val)).
137
138encode_relative_oid(Val) when is_tuple(Val) ->
139    encode_relative_oid(tuple_to_list(Val));
140encode_relative_oid(Val) when is_list(Val) ->
141    list_to_binary([e_object_element(X)||X <- Val]).
142
143encode_unconstrained_number(Val) when not is_integer(Val) ->
144    exit({error,{asn1,{illegal_integer,Val}}});
145encode_unconstrained_number(Val) when Val >= 0 ->
146    if
147	Val < 16#80 ->
148	    [1,Val];
149	Val < 16#100 ->
150	    [<<2,0>>,Val];
151	true ->
152	    case binary:encode_unsigned(Val) of
153		<<0:1,_/bitstring>>=Bin ->
154		    case byte_size(Bin) of
155			Sz when Sz < 128 ->
156			    [Sz,Bin];
157			Sz when Sz < 16384 ->
158			    [<<2:2,Sz:14>>,Bin]
159		    end;
160		<<1:1,_/bitstring>>=Bin ->
161		    case byte_size(Bin)+1 of
162			Sz when Sz < 128 ->
163			    [Sz,0,Bin];
164			Sz when Sz < 16384 ->
165			    [<<2:2,Sz:14,0:8>>,Bin]
166		    end
167	    end
168    end;
169encode_unconstrained_number(Val) ->
170    Oct = enint(Val, []),
171    Len = length(Oct),
172    if
173        Len < 128 ->
174            [Len|Oct];
175        Len < 16384 ->
176            [<<2:2,Len:14>>|Oct]
177    end.
178
179%% bitstring_from_positions([Position]) -> BitString
180%%  Given an unsorted list of bit positions (0..MAX), construct
181%%  a BIT STRING. The rightmost bit will always be a one.
182
183bitstring_from_positions([]) -> <<>>;
184bitstring_from_positions([_|_]=L0) ->
185    L1 = lists:sort(L0),
186    L = diff(L1, -1),
187    << <<1:(N+0)>> || N <- L >>.
188
189%% bitstring_from_positions([Position], Lb) -> BitString
190%%  Given an unsorted list of bit positions (0..MAX) and a lower bound
191%%  for the number of bits, construct BIT STRING (zero-padded on the
192%%  right side if needed).
193
194bitstring_from_positions(L0, Lb) ->
195    L1 = lists:sort(L0),
196    L = diff(L1, -1, Lb-1),
197    << <<B:(N+0)>> || {B,N} <- L >>.
198
199%% to_bitstring(Val) -> BitString
200%%    Val = BitString | {Unused,Binary} | [OneOrZero] | Integer
201%%  Given one of the possible representations for a BIT STRING,
202%%  return a bitstring (without adding or removing any zero bits
203%%  at the right end).
204
205to_bitstring({0,Bs}) when is_binary(Bs) ->
206    Bs;
207to_bitstring({Unused,Bs0}) when is_binary(Bs0) ->
208    Sz = bit_size(Bs0) - Unused,
209    <<Bs:Sz/bits,_/bits>> = Bs0,
210    Bs;
211to_bitstring(Bs) when is_bitstring(Bs) ->
212    Bs;
213to_bitstring(Int) when is_integer(Int), Int >= 0 ->
214    L = int_to_bitlist(Int),
215    << <<B:1>> || B <- L >>;
216to_bitstring(L) when is_list(L) ->
217    << <<B:1>> || B <- L >>.
218
219%% to_bitstring(Val, Lb) -> BitString
220%%    Val = BitString | {Unused,Binary} | [OneOrZero] | Integer
221%%    Lb = Integer
222%%  Given one of the possible representations for a BIT STRING
223%%  and the lower bound for the number of bits,
224%%  return a bitstring at least Lb bits long (padded with zeroes
225%%  if needed).
226
227to_bitstring({0,Bs}, Lb) when is_binary(Bs) ->
228    case bit_size(Bs) of
229	Sz when Sz < Lb ->
230	    <<Bs/bits,0:(Lb-Sz)>>;
231	_ ->
232	    Bs
233    end;
234to_bitstring({Unused,Bs0}, Lb) when is_binary(Bs0) ->
235    Sz = bit_size(Bs0) - Unused,
236    if
237	Sz < Lb ->
238	    <<Bs0:Sz/bits,0:(Lb-Sz)>>;
239	true ->
240	    <<Bs:Sz/bits,_/bits>> = Bs0,
241	    Bs
242    end;
243to_bitstring(Bs, Lb) when is_bitstring(Bs) ->
244    adjust_size(Bs, Lb);
245to_bitstring(Int, Lb) when is_integer(Int), Int >= 0 ->
246    L = int_to_bitlist(Int),
247    Bs = << <<B:1>> || B <- L >>,
248    adjust_size(Bs, Lb);
249to_bitstring(L, Lb) when is_list(L) ->
250    Bs = << <<B:1>> || B <- L >>,
251    adjust_size(Bs, Lb).
252
253%% to_named_bitstring(Val) -> BitString
254%%    Val = BitString | {Unused,Binary} | [OneOrZero] | Integer
255%%  Given one of the possible representations for a BIT STRING,
256%%  return a bitstring where any trailing zeroes have been stripped.
257
258to_named_bitstring(Val) ->
259    Bs = to_bitstring(Val),
260    bs_drop_trailing_zeroes(Bs).
261
262%% to_named_bitstring(Val, Lb) -> BitString
263%%    Val = BitString | {Unused,Binary} | [OneOrZero] | Integer
264%%    Lb = Integer
265%%  Given one of the possible representations for a BIT STRING
266%%  and the lower bound for the number of bits,
267%%  return a bitstring that is at least Lb bits long. There will
268%%  be zeroes at the right only if needed to reach the lower bound
269%%  for the number of bits.
270
271to_named_bitstring({0,Bs}, Lb) when is_binary(Bs) ->
272    adjust_trailing_zeroes(Bs, Lb);
273to_named_bitstring({Unused,Bs0}, Lb) when is_binary(Bs0) ->
274    Sz = bit_size(Bs0) - Unused,
275    <<Bs:Sz/bits,_/bits>> = Bs0,
276    adjust_trailing_zeroes(Bs, Lb);
277to_named_bitstring(Bs, Lb) when is_bitstring(Bs) ->
278    adjust_trailing_zeroes(Bs, Lb);
279to_named_bitstring(Val, Lb) ->
280    %% Obsolete representations: list or integer. Optimize
281    %% for correctness, not speed.
282    adjust_trailing_zeroes(to_bitstring(Val), Lb).
283
284is_default_bitstring(asn1_DEFAULT, _, _) ->
285    true;
286is_default_bitstring(Named, Named, _) ->
287    true;
288is_default_bitstring(Bs, _, Bs) ->
289    true;
290is_default_bitstring(Val, _, Def) when is_bitstring(Val) ->
291    Sz = bit_size(Def),
292    case Val of
293	<<Def:Sz/bitstring,T/bitstring>> ->
294	    NumZeroes = bit_size(T),
295	    case T of
296		<<0:NumZeroes>> -> true;
297		_ -> false
298	    end;
299	_ ->
300	    false
301    end.
302
303is_default_bitstring(asn1_DEFAULT, _, _, _, _) ->
304    true;
305is_default_bitstring({Unused,Bin}, V0, V1, V2, V3) when is_integer(Unused) ->
306    %% Convert compact bitstring to a bitstring.
307    Sz = bit_size(Bin) - Unused,
308    <<Bs:Sz/bitstring,_:Unused>> = Bin,
309    is_default_bitstring(Bs, V0, V1, V2, V3);
310is_default_bitstring(Named, Named, _, _, _) ->
311    true;
312is_default_bitstring(Bs, _, Bs, _, _) ->
313    true;
314is_default_bitstring(List, _, _, List, _) ->
315    true;
316is_default_bitstring(Int, _, _, _, Int) ->
317    true;
318is_default_bitstring(Val, _, Def, _, _) when is_bitstring(Val) ->
319    Sz = bit_size(Def),
320    case Val of
321	<<Def:Sz/bitstring,T/bitstring>> ->
322	    NumZeroes = bit_size(T),
323	    case T of
324		<<0:NumZeroes>> -> true;
325		_ -> false
326	    end;
327	_ ->
328	    false
329    end;
330is_default_bitstring(Val, _, _, List, _) when is_list(Val) ->
331    is_default_bitstring_list(List, Val);
332is_default_bitstring(_, _, _, _, _) -> false.
333
334extension_bitmap(Val, Pos, Limit) ->
335    extension_bitmap(Val, Pos, Limit, 0).
336
337open_type_to_binary({asn1_OPENTYPE,Bin}) when is_binary(Bin) ->
338    Bin.
339
340legacy_open_type_to_binary({asn1_OPENTYPE,Bin}) when is_binary(Bin) ->
341    Bin;
342legacy_open_type_to_binary(Bin) when is_binary(Bin) ->
343    Bin;
344legacy_open_type_to_binary(List) when is_list(List) ->
345    List.
346
347%%%
348%%% Internal functions.
349%%%
350
351decode_named_bit_string_1(Pos, [0|Bt], Names, Acc) ->
352    decode_named_bit_string_1(Pos+1, Bt, Names, Acc);
353decode_named_bit_string_1(Pos, [1|Bt], Names, Acc) ->
354    case lists:keyfind(Pos, 2, Names) of
355	{Name,_} ->
356	    decode_named_bit_string_1(Pos+1, Bt, Names, [Name|Acc]);
357	false ->
358	    decode_named_bit_string_1(Pos+1, Bt, Names, [{bit,Pos}|Acc])
359    end;
360decode_named_bit_string_1(_Pos, [], _Names, Acc) ->
361    lists:reverse(Acc).
362
363decode_chars_16bit_1([H|T]) when H < 256 ->
364    [H|decode_chars_16bit_1(T)];
365decode_chars_16bit_1([H|T]) ->
366    [{0,0,H bsr 8,H band 255}|decode_chars_16bit_1(T)];
367decode_chars_16bit_1([]) -> [].
368
369decode_big_chars_1([H|T]) when H < 256 ->
370    [H|decode_big_chars_1(T)];
371decode_big_chars_1([H|T]) ->
372    [list_to_tuple(binary_to_list(<<H:32>>))|decode_big_chars_1(T)];
373decode_big_chars_1([]) -> [].
374
375dec_subidentifiers([H|T], Av, Al) when H >=16#80 ->
376    dec_subidentifiers(T, (Av bsl 7) bor (H band 16#7F), Al);
377dec_subidentifiers([H|T], Av, Al) ->
378    dec_subidentifiers(T, 0, [(Av bsl 7) bor H|Al]);
379dec_subidentifiers([], _Av, Al) ->
380    lists:reverse(Al).
381
382enc_char(C0, Lb, Tab) ->
383    try	element(C0-Lb, Tab) of
384	ill ->
385	    illegal_char_error();
386	C ->
387	    C
388    catch
389	error:badarg ->
390	    illegal_char_error()
391    end.
392
393enc_char_cm(C0, Lb, Limit) ->
394    C = C0 - Lb,
395    if
396	0 =< C, C < Limit ->
397	    C;
398	true ->
399	    illegal_char_error()
400    end.
401
402illegal_char_error() ->
403    error({error,{asn1,"value forbidden by FROM constraint"}}).
404
405encode_fragmented_1(Bin, Unit, N) ->
406    SegSz = Unit * N * ?'16K',
407    case Bin of
408	<<B:SegSz/bitstring,T/bitstring>> ->
409	    [<<3:2,N:6>>,B|encode_fragmented_1(T, Unit, N)];
410	_ when N > 1 ->
411	    encode_fragmented_1(Bin, Unit, N-1);
412	_ ->
413	    case bit_size(Bin) div Unit of
414		Len when Len < 128 ->
415		    [Len,Bin];
416		Len when Len < 16384 ->
417		    [<<2:2,Len:14>>,Bin]
418	    end
419    end.
420
421%% E1 = 0|1|2 and (E2 < 40 when E1 = 0|1)
422e_object_identifier([E1,E2|Tail]) when E1 >= 0, E1 < 2, E2 < 40; E1 =:= 2 ->
423    Head = 40*E1 + E2,
424    e_object_elements([Head|Tail], []);
425e_object_identifier([_,_|_Tail]=Oid) ->
426    exit({error,{asn1,{'illegal_value',Oid}}}).
427
428e_object_elements([], Acc) ->
429    lists:reverse(Acc);
430e_object_elements([H|T], Acc) ->
431    e_object_elements(T, [e_object_element(H)|Acc]).
432
433e_object_element(Num) when Num < 128 ->
434    [Num];
435e_object_element(Num) ->
436    [e_o_e(Num bsr 7)|[Num band 2#1111111]].
437
438e_o_e(Num) when Num < 128 ->
439    Num bor 2#10000000;
440e_o_e(Num) ->
441    [e_o_e(Num bsr 7)|[(Num band 2#1111111) bor 2#10000000]].
442
443enint(-1, [B1|T]) when B1 > 127 ->
444    [B1|T];
445enint(N, Acc) ->
446    enint(N bsr 8, [N band 16#ff|Acc]).
447
448diff([H|T], Prev) ->
449    [H-Prev|diff(T, H)];
450diff([], _) -> [].
451
452diff([H|T], Prev, Last) ->
453    [{1,H-Prev}|diff(T, H, Last)];
454diff([], Prev, Last) when Last >= Prev ->
455    [{0,Last-Prev}];
456diff([], _, _) -> [].
457
458int_to_bitlist(0) -> [];
459int_to_bitlist(Int) -> [Int band 1|int_to_bitlist(Int bsr 1)].
460
461adjust_size(Bs, Lb) ->
462    case bit_size(Bs) of
463	Sz when Sz < Lb ->
464	    <<Bs:Sz/bits,0:(Lb-Sz)>>;
465	_ ->
466	    Bs
467    end.
468
469adjust_trailing_zeroes(Bs0, Lb) ->
470    case bit_size(Bs0) of
471	Sz when Sz < Lb ->
472	    %% Too short - pad with zeroes.
473	    <<Bs0:Sz/bits,0:(Lb-Sz)>>;
474	Lb ->
475	    %% Exactly the right size - nothing to do.
476	    Bs0;
477	_ ->
478	    %% Longer than the lower bound - drop trailing zeroes.
479	    <<_:Lb/bits,Tail/bits>> = Bs0,
480	    Sz = Lb + bit_size(bs_drop_trailing_zeroes(Tail)),
481	    <<Bs:Sz/bits,_/bits>> = Bs0,
482	    Bs
483    end.
484
485bs_drop_trailing_zeroes(Bs) ->
486    bs_drop_trailing_zeroes(Bs, bit_size(Bs)).
487
488bs_drop_trailing_zeroes(Bs, 0) ->
489    Bs;
490bs_drop_trailing_zeroes(Bs0, Sz0) when Sz0 < 8 ->
491    <<Byte:Sz0>> = Bs0,
492    Sz = Sz0 - ntz(Byte),
493    <<Bs:Sz/bits,_/bits>> = Bs0,
494    Bs;
495bs_drop_trailing_zeroes(Bs0, Sz0) ->
496    Sz1 = Sz0 - 8,
497    <<Bs1:Sz1/bits,Byte:8>> = Bs0,
498    case ntz(Byte) of
499	8 ->
500	    bs_drop_trailing_zeroes(Bs1, Sz1);
501	Ntz ->
502	    Sz = Sz0 - Ntz,
503	    <<Bs:Sz/bits,_:Ntz/bits>> = Bs0,
504	    Bs
505    end.
506
507%% ntz(Byte) -> Number of trailing zeroes.
508ntz(Byte) ->
509    %% The table was calculated like this:
510    %%   NTZ = fun (B, N, NTZ) when B band 1 =:= 0 -> NTZ(B bsr 1, N+1, NTZ); (_, N, _) -> N end.
511    %%   io:format("~w\n", [list_to_tuple([NTZ(B+256, 0, NTZ) || B <- lists:seq(0, 255)])]).
512    T = {8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
513	 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
514	 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
515	 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
516	 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
517	 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
518	 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
519	 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
520	 7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
521	 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
522	 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
523	 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
524	 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
525	 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
526	 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
527	 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0},
528    element(Byte+1, T).
529
530is_default_bitstring_list([H|Def], [H|Val]) ->
531    is_default_bitstring_list(Def, Val);
532is_default_bitstring_list([], []) ->
533    true;
534is_default_bitstring_list([], [_|_]=Val) ->
535    lists:all(fun(0) -> true;
536		 (_) -> false
537	      end, Val);
538is_default_bitstring_list(_, _) -> false.
539
540extension_bitmap(_Val, Pos, Limit, Acc) when Pos >= Limit ->
541    Acc;
542extension_bitmap(Val, Pos, Limit, Acc) ->
543    Bit = case element(Pos, Val) of
544	      asn1_NOVALUE -> 0;
545	      asn1_DEFAULT -> 0;
546	      _ -> 1
547	  end,
548    extension_bitmap(Val, Pos+1, Limit, (Acc bsl 1) bor Bit).
549