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