diff options
Diffstat (limited to 'lib/asn1/src')
-rw-r--r-- | lib/asn1/src/asn1ct.erl | 29 | ||||
-rw-r--r-- | lib/asn1/src/asn1ct_check.erl | 45 | ||||
-rw-r--r-- | lib/asn1/src/asn1ct_constructed_per.erl | 68 | ||||
-rw-r--r-- | lib/asn1/src/asn1ct_gen.erl | 7 | ||||
-rw-r--r-- | lib/asn1/src/asn1ct_gen_ber_bin_v2.erl | 122 | ||||
-rw-r--r-- | lib/asn1/src/asn1ct_gen_per.erl | 22 | ||||
-rw-r--r-- | lib/asn1/src/asn1ct_imm.erl | 47 | ||||
-rw-r--r-- | lib/asn1/src/asn1ct_value.erl | 6 | ||||
-rw-r--r-- | lib/asn1/src/asn1rtt_ber.erl | 65 | ||||
-rw-r--r-- | lib/asn1/src/asn1rtt_ext.erl | 2 | ||||
-rw-r--r-- | lib/asn1/src/asn1rtt_per_common.erl | 37 |
11 files changed, 351 insertions, 99 deletions
diff --git a/lib/asn1/src/asn1ct.erl b/lib/asn1/src/asn1ct.erl index f2e9606ccb..531a4935fe 100644 --- a/lib/asn1/src/asn1ct.erl +++ b/lib/asn1/src/asn1ct.erl @@ -40,7 +40,7 @@ maybe_rename_function/3,current_sindex/0, set_current_sindex/1,maybe_saved_sindex/2, parse_and_save/2,verbose/3,warning/3,warning/4,error/3]). --export([get_bit_string_format/0]). +-export([get_bit_string_format/0,use_legacy_types/0]). -include("asn1_records.hrl"). -include_lib("stdlib/include/erl_compile.hrl"). @@ -841,6 +841,7 @@ delete_double_of_symbol1([],Acc) -> generate({M,GenTOrV}, OutFile, EncodingRule, Options) -> debug_on(Options), setup_bit_string_format(Options), + setup_legacy_erlang_types(Options), put(encoding_options,Options), asn1ct_table:new(check_functions), @@ -869,6 +870,31 @@ generate({M,GenTOrV}, OutFile, EncodingRule, Options) -> asn1ct_table:delete(check_functions), Result. +setup_legacy_erlang_types(Opts) -> + F = case lists:member(legacy_erlang_types, Opts) of + false -> + case get_bit_string_format() of + bitstring -> + false; + compact -> + legacy_forced_info(compact_bit_string), + true; + legacy -> + legacy_forced_info(legacy_bit_string), + true + end; + true -> + true + end, + put(use_legacy_erlang_types, F). + +legacy_forced_info(Opt) -> + io:format("Info: The option 'legacy_erlang_types' " + "is implied by the '~s' option.\n", [Opt]). + +use_legacy_types() -> + get(use_legacy_erlang_types). + setup_bit_string_format(Opts) -> Format = case {lists:member(compact_bit_string, Opts), lists:member(legacy_bit_string, Opts)} of @@ -1075,6 +1101,7 @@ remove_asn_flags(Options) -> X /= optimize, X /= compact_bit_string, X /= legacy_bit_string, + X /= legacy_erlang_types, X /= debug, X /= asn1config, X /= record_name_prefix]. diff --git a/lib/asn1/src/asn1ct_check.erl b/lib/asn1/src/asn1ct_check.erl index 0a13801e08..f94f3b56bc 100644 --- a/lib/asn1/src/asn1ct_check.erl +++ b/lib/asn1/src/asn1ct_check.erl @@ -2574,6 +2574,18 @@ normalize_bitstring(S, Value, Type)-> Bs end. +hstring_to_binary(L) -> + byte_align(hstring_to_bitstring(L)). + +bstring_to_binary(L) -> + byte_align(bstring_to_bitstring(L)). + +byte_align(Bs) -> + case bit_size(Bs) rem 8 of + 0 -> Bs; + N -> <<Bs/bitstring,0:(8-N)>> + end. + hstring_to_bitstring(L) -> << <<(hex_to_int(D)):4>> || D <- L >>. @@ -2592,9 +2604,9 @@ hex_to_int(D) when $A =< D, D =< $F -> D - ($A - 10). normalize_octetstring(S,Value,CType) -> case Value of {bstring,String} -> - bstring_to_octetlist(String); + bstring_to_binary(String); {hstring,String} -> - hstring_to_octetlist(String); + hstring_to_binary(String); Rec when is_record(Rec,'Externalvaluereference') -> get_normalized_value(S,Value,CType, fun normalize_octetstring/3,[]); @@ -2616,35 +2628,6 @@ normalize_octetstring(S,Value,CType) -> Value end. - -bstring_to_octetlist([]) -> - []; -bstring_to_octetlist([H|T]) when H == $0 ; H == $1 -> - bstring_to_octetlist(T,6,[(H - $0) bsl 7]). -bstring_to_octetlist([H|T],0,[Hacc|Tacc]) when H == $0; H == $1 -> - bstring_to_octetlist(T, 7, [0,Hacc + (H -$0)| Tacc]); -bstring_to_octetlist([H|T],BSL,[Hacc|Tacc]) when H == $0; H == $1 -> - bstring_to_octetlist(T, BSL-1, [Hacc + ((H - $0) bsl BSL)| Tacc]); -bstring_to_octetlist([],7,[0|Acc]) -> - lists:reverse(Acc); -bstring_to_octetlist([],_,Acc) -> - lists:reverse(Acc). - -hstring_to_octetlist([]) -> - []; -hstring_to_octetlist(L) -> - hstring_to_octetlist(L,4,[]). -hstring_to_octetlist([H|T],0,[Hacc|Tacc]) when H >= $A, H =< $F -> - hstring_to_octetlist(T,4,[Hacc + (H - $A + 10)|Tacc]); -hstring_to_octetlist([H|T],BSL,Acc) when H >= $A, H =< $F -> - hstring_to_octetlist(T,0,[(H - $A + 10) bsl BSL|Acc]); -hstring_to_octetlist([H|T],0,[Hacc|Tacc]) when H >= $0; H =< $9 -> - hstring_to_octetlist(T,4,[Hacc + (H - $0)|Tacc]); -hstring_to_octetlist([H|T],BSL,Acc) when H >= $0; H =< $9 -> - hstring_to_octetlist(T,0,[(H - $0) bsl BSL|Acc]); -hstring_to_octetlist([],_,Acc) -> - lists:reverse(Acc). - normalize_objectidentifier(S, Value) -> {ok,Val} = validate_objectidentifier(S, o_id, Value, []), Val. diff --git a/lib/asn1/src/asn1ct_constructed_per.erl b/lib/asn1/src/asn1ct_constructed_per.erl index c224f4c9fa..ed3f6f886e 100644 --- a/lib/asn1/src/asn1ct_constructed_per.erl +++ b/lib/asn1/src/asn1ct_constructed_per.erl @@ -450,8 +450,13 @@ dec_objset_default(N, C, LeadingAttr, false) -> "{value,Bytes}," "{unique_name_and_value,",{asis,LeadingAttr},",Id}}}).",nl,nl]); dec_objset_default(N, _, _, true) -> - emit([{asis,N},"(Bytes, Id) ->",nl, - "Bytes.",nl,nl]). + emit([{asis,N},"(Bytes, Id) ->",nl| + case asn1ct:use_legacy_types() of + false -> + ["{asn1_OPENTYPE,Bytes}.",nl,nl]; + true -> + ["Bytes.",nl,nl] + end]). dec_objset_1(Erule, N, {Id,Obj}, RestFields, Typename) -> emit([{asis,N},"(Bytes, ",{asis,Id},") ->",nl]), @@ -906,26 +911,36 @@ def_values(#type{def=#'Externaltypereference'{module=Mod,type=Type}}, Def) -> #typedef{typespec=T} = asn1_db:dbget(Mod, Type), def_values(T, Def); def_values(#type{def={'BIT STRING',[]}}, Bs) when is_bitstring(Bs) -> - ListBs = [B || <<B:1>> <= Bs], - IntBs = lists:foldl(fun(B, A) -> - (A bsl 1) bor B - end, 0, lists:reverse(ListBs)), - Sz = bit_size(Bs), - Compact = case 8 - Sz rem 8 of - 8 -> - {0,Bs}; - Unused -> - {Unused,<<Bs:Sz/bits,0:Unused>>} - end, - [asn1_DEFAULT,Bs,Compact,ListBs,IntBs]; + case asn1ct:use_legacy_types() of + false -> + [asn1_DEFAULT,Bs]; + true -> + ListBs = [B || <<B:1>> <= Bs], + IntBs = lists:foldl(fun(B, A) -> + (A bsl 1) bor B + end, 0, lists:reverse(ListBs)), + Sz = bit_size(Bs), + Compact = case 8 - Sz rem 8 of + 8 -> + {0,Bs}; + Unused -> + {Unused,<<Bs:Sz/bits,0:Unused>>} + end, + [asn1_DEFAULT,Bs,Compact,ListBs,IntBs] + end; def_values(#type{def={'BIT STRING',[_|_]=Ns}}, List) when is_list(List) -> Bs = asn1ct_gen:named_bitstring_value(List, Ns), - ListBs = [B || <<B:1>> <= Bs], - IntBs = lists:foldl(fun(B, A) -> - (A bsl 1) bor B - end, 0, lists:reverse(ListBs)), - Args = [List,Bs,ListBs,IntBs], - {call,per_common,is_default_bitstring,Args}; + As = case asn1ct:use_legacy_types() of + false -> + [List,Bs]; + true -> + ListBs = [B || <<B:1>> <= Bs], + IntBs = lists:foldl(fun(B, A) -> + (A bsl 1) bor B + end, 0, lists:reverse(ListBs)), + [List,Bs,ListBs,IntBs] + end, + {call,per_common,is_default_bitstring,As}; def_values(#type{def={'INTEGER',Ns}}, Def) -> [asn1_DEFAULT,Def|case lists:keyfind(Def, 2, Ns) of false -> []; @@ -1059,8 +1074,17 @@ enc_objset_imm(Erule, Component, ObjSet, RestFieldNames, Extensible) -> enc_obj(Erule, Obj, RestFieldNames, Aligned)] || {Key,Obj} <- ObjSet] ++ [['_',case Extensible of - false -> E; - true -> {put_bits,{var,"Val"},binary,[1]} + false -> + E; + true -> + case asn1ct:use_legacy_types() of + false -> + {call,per_common,open_type_to_binary, + [{var,"Val"}]}; + true -> + {call,per_common,legacy_open_type_to_binary, + [{var,"Val"}]} + end end]]}]. enc_obj(Erule, Obj, RestFieldNames0, Aligned) -> diff --git a/lib/asn1/src/asn1ct_gen.erl b/lib/asn1/src/asn1ct_gen.erl index 37b33194d0..71d870b4ce 100644 --- a/lib/asn1/src/asn1ct_gen.erl +++ b/lib/asn1/src/asn1ct_gen.erl @@ -790,7 +790,8 @@ gen_decode_constructed(Erules,Typename,InnerType,D) when is_record(D,typedef) -> pgen_exports(Erules,_Module,{Types,Values,_,_,Objects,ObjectSets}) -> - emit(["-export([encoding_rule/0,bit_string_format/0]).",nl]), + emit(["-export([encoding_rule/0,bit_string_format/0," + " legacy_erlang_types/0]).",nl]), case Types of [] -> ok; _ -> @@ -1022,7 +1023,9 @@ gen_info_functions(Erules) -> emit(["encoding_rule() -> ", {asis,Erules},".",nl,nl, "bit_string_format() -> ", - {asis,asn1ct:get_bit_string_format()},".",nl,nl]). + {asis,asn1ct:get_bit_string_format()},".",nl,nl, + "legacy_erlang_types() -> ", + {asis,asn1ct:use_legacy_types()},".",nl,nl]). gen_decode_partial_incomplete(ber) -> case {asn1ct:read_config_data(partial_incomplete_decode), diff --git a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl index de81259fcb..bea0ec8968 100644 --- a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl +++ b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl @@ -206,10 +206,32 @@ gen_encode_prim(_Erules, #type{}=D, DoTag, Value) -> {call,ber,encode_tags, [DoTag,{curr,realval},{curr,realsize}]},nl, "end"]); + {'BIT STRING',[]} -> + case asn1ct:use_legacy_types() of + false when BitStringConstraint =:= [] -> + call(encode_unnamed_bit_string, [Value,DoTag]); + false -> + call(encode_unnamed_bit_string, + [{asis,BitStringConstraint},Value,DoTag]); + true -> + call(encode_bit_string, + [{asis,BitStringConstraint},Value, + {asis,[]},DoTag]) + end; {'BIT STRING',NamedNumberList} -> - call(encode_bit_string, - [{asis,BitStringConstraint},Value, - {asis,NamedNumberList},DoTag]); + case asn1ct:use_legacy_types() of + false when BitStringConstraint =:= [] -> + call(encode_named_bit_string, + [Value,{asis,NamedNumberList},DoTag]); + false -> + call(encode_named_bit_string, + [{asis,BitStringConstraint},Value, + {asis,NamedNumberList},DoTag]); + true -> + call(encode_bit_string, + [{asis,BitStringConstraint},Value, + {asis,NamedNumberList},DoTag]) + end; 'NULL' -> call(encode_null, [Value,DoTag]); 'OBJECT IDENTIFIER' -> @@ -471,7 +493,6 @@ gen_dec_prim(_Erules, Att, BytesVar, DoTag, _TagIn, _Form, _OptOrMand) -> _ -> "" end, NewTypeName = case Typename of - 'OCTET STRING' -> restricted_string; 'NumericString' -> restricted_string; 'TeletexString' -> restricted_string; 'T61String' -> restricted_string; @@ -529,6 +550,19 @@ gen_dec_prim(_Erules, Att, BytesVar, DoTag, _TagIn, _Form, _OptOrMand) -> 'RELATIVE-OID' -> emit(["decode_relative_oid(",BytesVar,","]), need(decode_relative_oid, 2); + 'OCTET STRING' -> + F = case asn1ct:use_legacy_types() of + false -> decode_octet_string; + true -> decode_restricted_string + end, + emit([{asis,F},"(",BytesVar,","]), + case Constraint of + [] -> + need(F, 2); + _ -> + emit([{asis,Constraint},","]), + need(F, 3) + end; restricted_string -> emit(["decode_restricted_string",AsBin,"(",BytesVar,","]), case Constraint of @@ -1090,13 +1124,11 @@ gen_objset_enc(Erules, ObjSetName, UniqueName, %% See X.681 Annex E for the following case gen_objset_enc(_,ObjSetName,_UniqueName,['EXTENSIONMARK'],_ClName, _ClFields,_NthObj,Acc) -> - emit(["'getenc_",ObjSetName,"'(_) ->",nl]), - emit({indent(3),"fun(_, Val, _RestPrimFieldName) ->",nl}), - emit({indent(6),"Len = case Val of",nl,indent(9), - "Bin when is_binary(Bin) -> byte_size(Bin);",nl,indent(9), - "_ -> length(Val)",nl,indent(6),"end,"}), - emit({indent(6),"{Val,Len}",nl}), - emit({indent(3),"end.",nl,nl}), + emit(["'getenc_",ObjSetName,"'(_) ->",nl, + indent(2),"fun(_, Val, _RestPrimFieldName) ->",nl]), + emit_enc_open_type(4), + emit([nl, + indent(2),"end.",nl,nl]), Acc; gen_objset_enc(_, ObjSetName, UniqueName, [], _, _, _, Acc) -> emit_default_getenc(ObjSetName, UniqueName), @@ -1158,13 +1190,8 @@ gen_inlined_enc_funs1(Fields, [{typefield,Name,_}|Rest], ObjSetName, %% were no type in the table and we therefore generate %% code that returns the input for application %% treatment. - emit([indent(9),{asis,Name}," ->",nl, - indent(12),"Len = case Val of",nl, - indent(15),"Bin when is_binary(Bin) -> " - "byte_size(Bin);",nl, - indent(15),"_ -> length(Val)",nl, - indent(12),"end,",nl, - indent(12),"{Val,Len}"]), + emit([indent(9),{asis,Name}," ->",nl]), + emit_enc_open_type(11), {Acc0,0} end, gen_inlined_enc_funs1(Fields, Rest, ObjSetName, Sep, NthObj+NAdd, Acc); @@ -1175,6 +1202,25 @@ gen_inlined_enc_funs1(_, [], _, _, NthObj, Acc) -> indent(3),"end"]), {Acc,NthObj}. +emit_enc_open_type(I) -> + Indent = indent(I), + S = [Indent, "case Val of",nl, + Indent,indent(2),"{asn1_OPENTYPE,Bin} when is_binary(Bin) ->",nl, + Indent,indent(4),"{Bin,byte_size(Bin)}"| + case asn1ct:use_legacy_types() of + false -> + [nl, + Indent,"end"]; + true -> + [";",nl, + Indent,indent(2),"Bin when is_binary(Bin) ->",nl, + Indent,indent(4),"{Bin,byte_size(Bin)};",nl, + Indent,indent(2),"_ ->",nl, + Indent,indent(4),"{Val,length(Val)}",nl, + Indent, "end"] + end], + emit(S). + emit_inner_of_fun(TDef=#typedef{name={ExtMod,Name},typespec=Type}, InternalDefFunName) -> OTag = Type#type.tag, @@ -1258,14 +1304,9 @@ gen_objset_dec(_,ObjSetName,_UniqueName,['EXTENSIONMARK'],_ClName, _ClFields,_NthObj) -> emit(["'getdec_",ObjSetName,"'(_) ->",nl]), emit([indent(2),"fun(_,Bytes, _RestPrimFieldName) ->",nl]), - - emit([indent(4),"case Bytes of",nl, - indent(6),"Bin when is_binary(Bin) -> ",nl, - indent(8),"Bin;",nl, - indent(6),"_ ->",nl, - indent(8),{call,ber,ber_encode,["Bytes"]},nl, - indent(4),"end",nl]), - emit([indent(2),"end.",nl,nl]), + emit_dec_open_type(4), + emit([nl, + indent(2),"end.",nl,nl]), ok; gen_objset_dec(_, ObjSetName, UniqueName, [], _, _, _) -> emit_default_getdec(ObjSetName, UniqueName), @@ -1312,12 +1353,8 @@ gen_inlined_dec_funs1(Fields, [{typefield,Name,Prop}|Rest], end, 0; false -> - emit([indent(9),{asis,Name}," ->",nl, - indent(12),"Len = case Bytes of",nl, - indent(15),"B when is_binary(B) -> byte_size(B);",nl, - indent(15),"_ -> length(Bytes)",nl, - indent(12),"end,",nl, - indent(12),"{Bytes,[],Len}"]), + emit([indent(9),{asis,Name}," ->",nl]), + emit_dec_open_type(11), 0 end, gen_inlined_dec_funs1(Fields, Rest, ObjSetName, Sep, NthObj+N); @@ -1328,6 +1365,27 @@ gen_inlined_dec_funs1(_, [], _, _, NthObj) -> indent(3),"end"]), NthObj. +emit_dec_open_type(I) -> + Indent = indent(I), + S = case asn1ct:use_legacy_types() of + false -> + [Indent, "case Bytes of",nl, + Indent,indent(2),"Bin when is_binary(Bin) -> ",nl, + Indent,indent(4),"{asn1_OPENTYPE,Bin};",nl, + Indent,indent(2),"_ ->",nl, + Indent,indent(4),"{asn1_OPENTYPE,", + {call,ber,ber_encode,["Bytes"]},"}",nl, + Indent, "end"]; + true -> + [Indent, "case Bytes of",nl, + Indent,indent(2),"Bin when is_binary(Bin) -> ",nl, + Indent,indent(4),"Bin;",nl, + Indent,indent(2),"_ ->",nl, + Indent,indent(4),{call,ber,ber_encode,["Bytes"]},nl, + Indent, "end"] + end, + emit(S). + emit_inner_of_decfun(#typedef{name={ExtName,Name},typespec=Type},Prop, InternalDefFunName) -> OTag = Type#type.tag, diff --git a/lib/asn1/src/asn1ct_gen_per.erl b/lib/asn1/src/asn1ct_gen_per.erl index 7ba649c874..519ce9f054 100644 --- a/lib/asn1/src/asn1ct_gen_per.erl +++ b/lib/asn1/src/asn1ct_gen_per.erl @@ -132,7 +132,14 @@ gen_encode_prim_imm(Val, #type{def=Type0,constraint=Constraint}, Aligned) -> ToBinary = {real_common,encode_real}, asn1ct_imm:per_enc_restricted_string(Val, ToBinary, Aligned); {'BIT STRING',NNL} -> - asn1ct_imm:per_enc_bit_string(Val, NNL, Constraint, Aligned); + case asn1ct:use_legacy_types() of + false -> + asn1ct_imm:per_enc_bit_string(Val, NNL, + Constraint, Aligned); + true -> + asn1ct_imm:per_enc_legacy_bit_string(Val, NNL, + Constraint, Aligned) + end; 'NULL' -> asn1ct_imm:per_enc_null(Val, Aligned); 'OBJECT IDENTIFIER' -> @@ -144,7 +151,13 @@ gen_encode_prim_imm(Val, #type{def=Type0,constraint=Constraint}, Aligned) -> 'BOOLEAN' -> asn1ct_imm:per_enc_boolean(Val, Aligned); 'OCTET STRING' -> - asn1ct_imm:per_enc_octet_string(Val, Constraint, Aligned); + case asn1ct:use_legacy_types() of + false -> + asn1ct_imm:per_enc_octet_string(Val, Constraint, Aligned); + true -> + asn1ct_imm:per_enc_legacy_octet_string(Val, Constraint, + Aligned) + end; 'ASN1_OPEN_TYPE' -> case Constraint of [#'Externaltypereference'{type=Tname}] -> @@ -325,7 +338,10 @@ gen_dec_imm_1('GeneralizedTime', Constraint, Aligned) -> gen_dec_imm_1('OCTET STRING', Constraint, Aligned) -> SzConstr = asn1ct_imm:effective_constraint(bitstring, Constraint), Imm = asn1ct_imm:per_dec_octet_string(SzConstr, Aligned), - {convert,binary_to_list,Imm}; + case asn1ct:use_legacy_types() of + false -> {convert,{binary,copy},Imm}; + true -> {convert,binary_to_list,Imm} + end; gen_dec_imm_1('TeletexString', _Constraint, Aligned) -> gen_dec_restricted_string(Aligned); gen_dec_imm_1('T61String', _Constraint, Aligned) -> diff --git a/lib/asn1/src/asn1ct_imm.erl b/lib/asn1/src/asn1ct_imm.erl index c14f0b889f..fde39c674e 100644 --- a/lib/asn1/src/asn1ct_imm.erl +++ b/lib/asn1/src/asn1ct_imm.erl @@ -26,11 +26,13 @@ per_dec_octet_string/2,per_dec_open_type/1,per_dec_real/1, per_dec_restricted_string/1]). -export([per_dec_constrained/3,per_dec_normally_small_number/1]). --export([per_enc_bit_string/4,per_enc_boolean/2, +-export([per_enc_bit_string/4,per_enc_legacy_bit_string/4, + per_enc_boolean/2, per_enc_choice/3,per_enc_enumerated/3, per_enc_integer/3,per_enc_integer/4, per_enc_null/2, per_enc_k_m_string/4,per_enc_octet_string/3, + per_enc_legacy_octet_string/3, per_enc_open_type/2, per_enc_restricted_string/3, per_enc_small_number/2]). @@ -157,7 +159,35 @@ per_dec_restricted_string(Aligned) -> %%% Encoding. %%% -per_enc_bit_string(Val0, [], Constraint0, Aligned) -> +per_enc_bit_string(Val, [], Constraint0, Aligned) -> + {B,[[],Bits]} = mk_vars([], [bits]), + Constraint = effective_constraint(bitstring, Constraint0), + B ++ [{call,erlang,bit_size,[Val],Bits}| + per_enc_length(Val, 1, Bits, Constraint, Aligned, 'BIT STRING')]; +per_enc_bit_string(Val0, NNL0, Constraint0, Aligned) -> + {B,[Val,Bs,Bits,Positions]} = mk_vars(Val0, [bs,bits,positions]), + NNL = lists:keysort(2, NNL0), + Constraint = effective_constraint(bitstring, Constraint0), + ExtraArgs = case constr_min_size(Constraint) of + no -> []; + Lb -> [Lb] + end, + ToBs = case ExtraArgs of + [] -> + {call,per_common,bs_drop_trailing_zeroes,[Val]}; + [Lower] -> + {call,per_common,adjust_trailing_zeroes,[Val,Lower]} + end, + B ++ [{'try', + [bit_string_name2pos_fun(NNL, Val)], + {Positions, + [{call,per_common,bitstring_from_positions, + [Positions|ExtraArgs]}]}, + [ToBs],Bs}, + {call,erlang,bit_size,[Bs],Bits}| + per_enc_length(Bs, 1, Bits, Constraint, Aligned, 'BIT STRING')]. + +per_enc_legacy_bit_string(Val0, [], Constraint0, Aligned) -> {B,[Val,Bs,Bits]} = mk_vars(Val0, [bs,bits]), Constraint = effective_constraint(bitstring, Constraint0), ExtraArgs = case constr_min_size(Constraint) of @@ -167,7 +197,7 @@ per_enc_bit_string(Val0, [], Constraint0, Aligned) -> B ++ [{call,per_common,to_bitstring,[Val|ExtraArgs],Bs}, {call,erlang,bit_size,[Bs],Bits}| per_enc_length(Bs, 1, Bits, Constraint, Aligned, 'BIT STRING')]; -per_enc_bit_string(Val0, NNL0, Constraint0, Aligned) -> +per_enc_legacy_bit_string(Val0, NNL0, Constraint0, Aligned) -> {B,[Val,Bs,Bits,Positions]} = mk_vars(Val0, [bs,bits,positions]), NNL = lists:keysort(2, NNL0), Constraint = effective_constraint(bitstring, Constraint0), @@ -276,7 +306,13 @@ per_enc_open_type(Imm0, Aligned) -> {call,erlang,byte_size,[Bin],Len}| per_enc_length(Bin, 8, Len, Aligned)]. -per_enc_octet_string(Val0, Constraint0, Aligned) -> +per_enc_octet_string(Bin, Constraint0, Aligned) -> + {B,[[],Len]} = mk_vars([], [len]), + Constraint = effective_constraint(bitstring, Constraint0), + B ++ [{call,erlang,byte_size,[Bin],Len}| + per_enc_length(Bin, 8, Len, Constraint, Aligned, 'OCTET STRING')]. + +per_enc_legacy_octet_string(Val0, Constraint0, Aligned) -> {B,[Val,Bin,Len]} = mk_vars(Val0, [bin,len]), Constraint = effective_constraint(bitstring, Constraint0), B ++ [{call,erlang,iolist_to_binary,[Val],Bin}, @@ -874,6 +910,9 @@ dcg_list_outside([{call,Fun,{V,Buf},{Dst,DstBuf}}|T]) -> emit(["{",Dst,",",DstBuf,"} = "]), Fun(V, Buf), iter_dcg_list_outside(T); +dcg_list_outside([{convert,{M,F},V,Dst}|T]) -> + emit([Dst," = ",{asis,M},":",{asis,F},"(",V,")"]), + iter_dcg_list_outside(T); dcg_list_outside([{convert,Op,V,Dst}|T]) -> emit([Dst," = ",Op,"(",V,")"]), iter_dcg_list_outside(T); diff --git a/lib/asn1/src/asn1ct_value.erl b/lib/asn1/src/asn1ct_value.erl index 862b3c4ea5..a86c963b9d 100644 --- a/lib/asn1/src/asn1ct_value.erl +++ b/lib/asn1/src/asn1ct_value.erl @@ -260,7 +260,11 @@ from_type_prim(M, D) -> 'BOOLEAN' -> true; 'OCTET STRING' -> - adjust_list(size_random(C),c_string(C,"OCTET STRING")); + S0 = adjust_list(size_random(C), c_string(C, "OCTET STRING")), + case M:legacy_erlang_types() of + false -> list_to_binary(S0); + true -> S0 + end; 'NumericString' -> adjust_list(size_random(C),c_string(C,"0123456789")); 'TeletexString' -> diff --git a/lib/asn1/src/asn1rtt_ber.erl b/lib/asn1/src/asn1rtt_ber.erl index 583ff790b7..4bd814769f 100644 --- a/lib/asn1/src/asn1rtt_ber.erl +++ b/lib/asn1/src/asn1rtt_ber.erl @@ -29,6 +29,8 @@ decode_integer/2,decode_integer/3, decode_named_integer/3,decode_named_integer/4, encode_enumerated/2,decode_enumerated/3, + encode_unnamed_bit_string/2,encode_unnamed_bit_string/3, + encode_named_bit_string/3,encode_named_bit_string/4, encode_bit_string/4, decode_named_bit_string/3, decode_compact_bit_string/3, @@ -38,6 +40,7 @@ encode_relative_oid/2,decode_relative_oid/2, encode_object_identifier/2,decode_object_identifier/2, encode_restricted_string/2, + decode_octet_string/2,decode_octet_string/3, decode_restricted_string/2,decode_restricted_string/3, encode_universal_string/2,decode_universal_string/3, encode_UTF8_string/2,decode_UTF8_string/2, @@ -780,6 +783,55 @@ decode_enumerated1(Val, NamedNumberList) -> {asn1_enum,Val} end. +%%============================================================================ +%% Bitstring value, ITU_T X.690 Chapter 8.6 +%% +%% encode bitstring value +%%============================================================================ + +encode_unnamed_bit_string(Bits, TagIn) -> + Unused = (8 - (bit_size(Bits) band 7)) band 7, + Bin = <<Unused,Bits/bitstring,0:Unused>>, + encode_tags(TagIn, Bin, byte_size(Bin)). + +encode_unnamed_bit_string(C, Bits, TagIn) -> + NumBits = bit_size(Bits), + Unused = (8 - (NumBits band 7)) band 7, + Bin = <<Unused,Bits/bitstring,0:Unused>>, + case C of + {_Min,Max} -> + if + NumBits > Max -> + exit({error,{asn1, + {bitstring_length, + {{was,NumBits},{maximum,Max}}}}}); + true -> + ok + end; + Size -> + if NumBits =< Size -> + ok; + true -> + exit({error,{asn1, + {bitstring_length, + {{was,NumBits},{should_be,Size}}}}}) + end + end, + encode_tags(TagIn, Bin, byte_size(Bin)). + +encode_named_bit_string([H|_]=Bits, NamedBitList, TagIn) when is_atom(H) -> + encode_bit_string_named([], Bits, NamedBitList, TagIn); +encode_named_bit_string([{bit,_}|_]=Bits, NamedBitList, TagIn) -> + encode_bit_string_named([], Bits, NamedBitList, TagIn); +encode_named_bit_string(Bits, _NamedBitList, TagIn) when is_bitstring(Bits) -> + encode_unnamed_bit_string(Bits, TagIn). + +encode_named_bit_string(C, [H|_]=Bits, NamedBitList, TagIn) when is_atom(H) -> + encode_bit_string_named(C, Bits, NamedBitList, TagIn); +encode_named_bit_string(C, [{bit,_}|_]=Bits, NamedBitList, TagIn) -> + encode_bit_string_named(C, Bits, NamedBitList, TagIn); +encode_named_bit_string(C, Bits, _NamedBitList, TagIn) when is_bitstring(Bits) -> + encode_unnamed_bit_string(C, Bits, TagIn). %%============================================================================ %% Bitstring value, ITU_T X.690 Chapter 8.6 @@ -1251,6 +1303,19 @@ encode_restricted_string(OctetList, TagIn) when is_list(OctetList) -> encode_tags(TagIn, OctetList, length(OctetList)). %%============================================================================ +%% decode OCTET STRING to binary +%%============================================================================ + +decode_octet_string(Tlv, TagsIn) -> + Bin = match_and_collect(Tlv, TagsIn), + binary:copy(Bin). + +decode_octet_string(Tlv, Range, TagsIn) -> + Bin0 = match_and_collect(Tlv, TagsIn), + Bin = binary:copy(Bin0), + check_restricted_string(Bin, byte_size(Bin), Range). + +%%============================================================================ %% decode Numeric Printable Teletex Videotex Visible IA5 Graphic General strings %%============================================================================ diff --git a/lib/asn1/src/asn1rtt_ext.erl b/lib/asn1/src/asn1rtt_ext.erl index 46adb2007d..f3eee1cdd5 100644 --- a/lib/asn1/src/asn1rtt_ext.erl +++ b/lib/asn1/src/asn1rtt_ext.erl @@ -38,7 +38,7 @@ transform_to_EXTERNAL1990([{'context-negotiation',Context_negot}|Rest], Acc) -> transform_to_EXTERNAL1990([asn1_NOVALUE|Rest], Acc) -> transform_to_EXTERNAL1990(Rest, [asn1_NOVALUE|Acc]); transform_to_EXTERNAL1990([Data_val_desc,Data_value], Acc) - when is_list(Data_value)-> + when is_list(Data_value); is_binary(Data_value) -> list_to_tuple(lists:reverse([{'octet-aligned',Data_value}, Data_val_desc|Acc])); transform_to_EXTERNAL1990([Data_val_desc,Data_value], Acc) diff --git a/lib/asn1/src/asn1rtt_per_common.erl b/lib/asn1/src/asn1rtt_per_common.erl index 3309e6a4ca..71fec411a0 100644 --- a/lib/asn1/src/asn1rtt_per_common.erl +++ b/lib/asn1/src/asn1rtt_per_common.erl @@ -37,8 +37,10 @@ bitstring_from_positions/1,bitstring_from_positions/2, to_bitstring/1,to_bitstring/2, to_named_bitstring/1,to_named_bitstring/2, - is_default_bitstring/5, - extension_bitmap/3]). + bs_drop_trailing_zeroes/1,adjust_trailing_zeroes/2, + is_default_bitstring/3,is_default_bitstring/5, + extension_bitmap/3, + open_type_to_binary/1,legacy_open_type_to_binary/1]). -define('16K',16384). @@ -272,6 +274,25 @@ to_named_bitstring(Val, Lb) -> %% for correctness, not speed. adjust_trailing_zeroes(to_bitstring(Val), Lb). +is_default_bitstring(asn1_DEFAULT, _, _) -> + true; +is_default_bitstring(Named, Named, _) -> + true; +is_default_bitstring(Bs, _, Bs) -> + true; +is_default_bitstring(Val, _, Def) when is_bitstring(Val) -> + Sz = bit_size(Def), + case Val of + <<Def:Sz/bitstring,T/bitstring>> -> + NumZeroes = bit_size(T), + case T of + <<0:NumZeroes>> -> true; + _ -> false + end; + _ -> + false + end. + is_default_bitstring(asn1_DEFAULT, _, _, _, _) -> true; is_default_bitstring({Unused,Bin}, V0, V1, V2, V3) when is_integer(Unused) -> @@ -306,6 +327,16 @@ is_default_bitstring(_, _, _, _, _) -> false. extension_bitmap(Val, Pos, Limit) -> extension_bitmap(Val, Pos, Limit, 0). +open_type_to_binary({asn1_OPENTYPE,Bin}) when is_binary(Bin) -> + Bin. + +legacy_open_type_to_binary({asn1_OPENTYPE,Bin}) when is_binary(Bin) -> + Bin; +legacy_open_type_to_binary(Bin) when is_binary(Bin) -> + Bin; +legacy_open_type_to_binary(List) when is_list(List) -> + List. + %%% %%% Internal functions. %%% @@ -438,6 +469,8 @@ adjust_trailing_zeroes(Bs0, Lb) -> bs_drop_trailing_zeroes(Bs) -> bs_drop_trailing_zeroes(Bs, bit_size(Bs)). +bs_drop_trailing_zeroes(Bs, 0) -> + Bs; bs_drop_trailing_zeroes(Bs0, Sz0) when Sz0 < 8 -> <<Byte:Sz0>> = Bs0, Sz = Sz0 - ntz(Byte), |