%% %% %CopyrightBegin% %% %% Copyright Ericsson AB 2012-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% %% %CopyrightEnd% %% -module(asn1rtt_check). -export([check_fail/1, check_int/3, check_legacy_bitstring/2, check_legacy_named_bitstring/3, check_legacy_named_bitstring/4, check_named_bitstring/3, check_named_bitstring/4, check_literal_sof/2, check_octetstring/2, check_objectidentifier/2, check_objectdescriptor/2, check_real/2, check_restrictedstring/2]). check_fail(_) -> throw(false). check_int(Value, Value, _) when is_integer(Value) -> true; check_int(Value, DefValue, NNL) when is_atom(Value) -> case lists:keyfind(Value, 1, NNL) of {_,DefValue} -> true; _ -> throw(false) end; check_int(_, _, _) -> throw(false). check_legacy_bitstring(Value, Default) -> check_bitstring(Default, Value). %% check_bitstring(Default, UserBitstring) -> true|false %% Default = bitstring() %% UserBitstring = integeger() | list(0|1) | {Unused,binary()} | bitstring() check_bitstring(DefVal, {Unused,Binary}) -> %% User value in compact format. Sz = bit_size(Binary) - Unused, <<Val:Sz/bitstring,_:Unused>> = Binary, check_bitstring(DefVal, Val); check_bitstring(DefVal, Val) when is_bitstring(Val) -> case Val =:= DefVal of false -> throw(false); true -> true end; check_bitstring(Def, Val) when is_list(Val) -> check_bitstring_list(Def, Val); check_bitstring(Def, Val) when is_integer(Val) -> check_bitstring_integer(Def, Val). check_bitstring_list(<<H:1,T1/bitstring>>, [H|T2]) -> check_bitstring_list(T1, T2); check_bitstring_list(<<>>, []) -> true; check_bitstring_list(_, _) -> throw(false). check_bitstring_integer(<<H:1,T1/bitstring>>, Int) when H =:= Int band 1 -> check_bitstring_integer(T1, Int bsr 1); check_bitstring_integer(<<>>, 0) -> true; check_bitstring_integer(_, _) -> throw(false). check_legacy_named_bitstring([Int|_]=Val, Bs, BsSize) when is_integer(Int) -> check_named_bitstring(<< <<B:1>> || B <- Val >>, Bs, BsSize); check_legacy_named_bitstring({Unused,Val0}, Bs, BsSize) -> Sz = bit_size(Val0) - Unused, <<Val:Sz/bits,_/bits>> = Val0, check_named_bitstring(Val, Bs, BsSize); check_legacy_named_bitstring(Val, Bs, BsSize) when is_integer(Val) -> L = legacy_int_to_bitlist(Val), check_named_bitstring(<< <<B:1>> || B <- L >>, Bs, BsSize); check_legacy_named_bitstring(Val, Bs, BsSize) -> check_named_bitstring(Val, Bs, BsSize). check_legacy_named_bitstring([Int|_]=Val, Names, Bs, BsSize) when is_integer(Int) -> check_named_bitstring(<< <<B:1>> || B <- Val >>, Names, Bs, BsSize); check_legacy_named_bitstring({Unused,Val0}, Names, Bs, BsSize) -> Sz = bit_size(Val0) - Unused, <<Val:Sz/bits,_/bits>> = Val0, check_named_bitstring(Val, Names, Bs, BsSize); check_legacy_named_bitstring(Val, Names, Bs, BsSize) when is_integer(Val) -> L = legacy_int_to_bitlist(Val), check_named_bitstring(<< <<B:1>> || B <- L >>, Names, Bs, BsSize); check_legacy_named_bitstring(Val, Names, Bs, BsSize) -> check_named_bitstring(Val, Names, Bs, BsSize). legacy_int_to_bitlist(0) -> []; legacy_int_to_bitlist(Int) -> [Int band 1|legacy_int_to_bitlist(Int bsr 1)]. check_named_bitstring(Bs, Bs, _) -> true; check_named_bitstring(Val, Bs, BsSize) -> Rest = bit_size(Val) - BsSize, case Val of <<Bs:BsSize/bits,0:Rest>> -> true; _ -> throw(false) end. check_named_bitstring([_|_]=Val, Names, _, _) -> case lists:sort(Val) of Names -> true; _ -> throw(false) end; check_named_bitstring(Bs, _, Bs, _) -> true; check_named_bitstring(Val, _, Bs, BsSize) -> Rest = bit_size(Val) - BsSize, case Val of <<Bs:BsSize/bits,0:Rest>> -> true; _ -> throw(false) end. check_octetstring(V, V) -> true; check_octetstring(V, Def) when is_list(V) -> case list_to_binary(V) of Def -> true; _ -> throw(false) end; check_octetstring(_, _) -> throw(false). check_objectidentifier(Value, {Prefix,Tail}) when is_tuple(Value) -> check_oid(tuple_to_list(Value), Prefix, Tail); check_objectidentifier(_, _) -> throw(false). check_oid([H|T], [K|Ks], Tail) -> case lists:member(H, K) of false -> throw(false); true -> check_oid(T, Ks, Tail) end; check_oid(Tail, [], Tail) -> true; check_oid(_, _, _) -> throw(false). check_objectdescriptor(_, asn1_DEFAULT) -> true; check_objectdescriptor(OD, OD) -> true; check_objectdescriptor(OD, OD) -> throw({error,{not_implemented_yet,check_objectdescriptor}}). check_real(_, asn1_DEFAULT) -> true; check_real(R, R) -> true; check_real(_, _) -> throw({error,{not_implemented_yet,check_real}}). check_restrictedstring(Val, Val) -> true; check_restrictedstring([V|Rest1], [V|Rest2]) -> check_restrictedstring(Rest1, Rest2); check_restrictedstring([V1|Rest1], [V2|Rest2]) -> check_restrictedstring(V1, V2), check_restrictedstring(Rest1, Rest2); %% tuple format of value check_restrictedstring({V1,V2}, [V1,V2]) -> true; check_restrictedstring([V1,V2], {V1,V2}) -> true; %% quadruple format of value check_restrictedstring({V1,V2,V3,V4}, [V1,V2,V3,V4]) -> true; check_restrictedstring([V1,V2,V3,V4], {V1,V2,V3,V4}) -> true; %% character string list check_restrictedstring(V1, V2) when is_tuple(V1) -> check_restrictedstring(tuple_to_list(V1), V2); check_restrictedstring(_, _) -> throw(false). check_literal_sof(Value, Default) -> case lists:sort(Value) of Default -> true; _ -> throw(false) end.