diff options
23 files changed, 462 insertions, 94 deletions
diff --git a/lib/asn1/src/asn1ct_constructed_per.erl b/lib/asn1/src/asn1ct_constructed_per.erl index efb55cf015..d279e9697f 100644 --- a/lib/asn1/src/asn1ct_constructed_per.erl +++ b/lib/asn1/src/asn1ct_constructed_per.erl @@ -354,8 +354,7 @@ gen_dec_constructed_imm_2(Typename, CompList, %% we don't return named lists any more Cnames = mkcnamelist(CompList), demit({"Result = "}), %dbg %% return value as record - RecordName = lists:concat([get_record_name_prefix(), - asn1ct_gen:list2rname(Typename)]), + RecordName = record_name(Typename), case Typename of ['EXTERNAL'] -> emit({" OldFormat={'",RecordName, @@ -377,6 +376,29 @@ gen_dec_constructed_imm_2(Typename, CompList, end, emit({{curr,bytes},"}"}). +%% record_name([TypeName]) -> RecordNameString +%% Construct a record name for the constructed type, ignoring any +%% fake sequences that are used to represent an extension addition +%% group. Such fake sequences never appear as a top type, and their +%% name always start with "ExtAddGroup". + +record_name(Typename0) -> + [TopType|Typename1] = lists:reverse(Typename0), + Typename = filter_ext_add_groups(Typename1, [TopType]), + lists:concat([get_record_name_prefix(), + asn1ct_gen:list2rname(Typename)]). + +filter_ext_add_groups([H|T], Acc) when is_atom(H) -> + case atom_to_list(H) of + "ExtAddGroup"++_ -> + filter_ext_add_groups(T, Acc); + _ -> + filter_ext_add_groups(T, [H|Acc]) + end; +filter_ext_add_groups([H|T], Acc) -> + filter_ext_add_groups(T, [H|Acc]); +filter_ext_add_groups([], Acc) -> Acc. + textual_order([#'ComponentType'{textual_order=undefined}|_],TermList) -> TermList; textual_order(CompList,TermList) when is_list(CompList) -> diff --git a/lib/asn1/src/asn1ct_gen_per.erl b/lib/asn1/src/asn1ct_gen_per.erl index 30c9ab9365..69d9d51bf1 100644 --- a/lib/asn1/src/asn1ct_gen_per.erl +++ b/lib/asn1/src/asn1ct_gen_per.erl @@ -250,7 +250,8 @@ emit_enc_enumerated_case(Erules, C, EnumName, Count) -> enc_ext_and_val(per, E, F, Args) -> [E|apply(asn1ct_eval_per, F, Args)]; enc_ext_and_val(uper, E, F, Args) -> - <<E:1,(apply(asn1ct_eval_uper, F, Args))/bitstring>>. + Bs = list_to_bitstring([apply(asn1ct_eval_uper, F, Args)]), + <<E:1,Bs/bitstring>>. %% Object code generating for encoding and decoding diff --git a/lib/asn1/src/asn1ct_imm.erl b/lib/asn1/src/asn1ct_imm.erl index c6803a0f96..bf362db843 100644 --- a/lib/asn1/src/asn1ct_imm.erl +++ b/lib/asn1/src/asn1ct_imm.erl @@ -86,7 +86,7 @@ per_dec_enumerated(BaseNamedList, NamedListExt0, Aligned) -> bit_case(Base, Ext). per_dec_extension_map(Aligned) -> - Len = {add,per_dec_normally_small_number(Aligned),1}, + Len = per_dec_normally_small_length(Aligned), {get_bits,Len,[1,bitstring]}. per_dec_integer(Constraint0, Aligned) -> @@ -240,6 +240,11 @@ per_dec_normally_small_number(Aligned) -> Unlimited = per_decode_semi_constrained(0, Aligned), bit_case(Small, Unlimited). +per_dec_normally_small_length(Aligned) -> + Small = {add,{get_bits,6,[1]},1}, + Unlimited = decode_unconstrained_length(false, Aligned), + bit_case(Small, Unlimited). + per_decode_semi_constrained(Lb, Aligned) -> add_lb(Lb, {get_bits,decode_unconstrained_length(false, Aligned),[8]}). diff --git a/lib/asn1/test/asn1_SUITE.erl b/lib/asn1/test/asn1_SUITE.erl index 6be493320c..f00b23a8b2 100644 --- a/lib/asn1/test/asn1_SUITE.erl +++ b/lib/asn1/test/asn1_SUITE.erl @@ -454,10 +454,13 @@ testSeqDefault(Config, Rule, Opts) -> testSeqExtension(Config) -> test(Config, fun testSeqExtension/3). testSeqExtension(Config, Rule, Opts) -> - asn1_test_lib:compile_all(["External", "SeqExtension"], Config, + asn1_test_lib:compile_all(["External", + "SeqExtension", + "SeqExtension2"], + Config, [Rule|Opts]), DataDir = ?config(data_dir, Config), - testSeqExtension:main(DataDir, [Rule|Opts]). + testSeqExtension:main(Rule, DataDir, [Rule|Opts]). testSeqExternal(Config) -> test(Config, fun testSeqExternal/3). testSeqExternal(Config, Rule, Opts) -> diff --git a/lib/asn1/test/asn1_SUITE_data/EnumExt.asn1 b/lib/asn1/test/asn1_SUITE_data/EnumExt.asn1 index 3a727e46bb..8dc5f3d7e1 100644 --- a/lib/asn1/test/asn1_SUITE_data/EnumExt.asn1 +++ b/lib/asn1/test/asn1_SUITE_data/EnumExt.asn1 @@ -31,5 +31,25 @@ Seq ::= SEQUENCE { i INTEGER } +EnumExtBig ::= ENUMERATED { + base, + ..., + e00,e01,e02,e03,e04,e05,e06,e07,e08,e09,e0a,e0b,e0c,e0d,e0e,e0f, + e10,e11,e12,e13,e14,e15,e16,e17,e18,e19,e1a,e1b,e1c,e1d,e1e,e1f, + e20,e21,e22,e23,e24,e25,e26,e27,e28,e29,e2a,e2b,e2c,e2d,e2e,e2f, + e30,e31,e32,e33,e34,e35,e36,e37,e38,e39,e3a,e3b,e3c,e3d,e3e,e3f, + e40,e41,e42,e43,e44,e45,e46,e47,e48,e49,e4a,e4b,e4c,e4d,e4e,e4f, + e50,e51,e52,e53,e54,e55,e56,e57,e58,e59,e5a,e5b,e5c,e5d,e5e,e5f, + e60,e61,e62,e63,e64,e65,e66,e67,e68,e69,e6a,e6b,e6c,e6d,e6e,e6f, + e70,e71,e72,e73,e74,e75,e76,e77,e78,e79,e7a,e7b,e7c,e7d,e7e,e7f, + e80 +} + +SeqBig ::= SEQUENCE { + b BOOLEAN, + e EnumExtBig, + i INTEGER +} + END diff --git a/lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn b/lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn index b07dcd8baa..0e905d8839 100644 --- a/lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn +++ b/lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn @@ -118,4 +118,23 @@ AC-BarringConfig ::= SEQUENCE { ac-BarringForSpecialAC BIT STRING (SIZE(5)) } +InlinedSeq ::= SEQUENCE { + ..., + [[ + s SEQUENCE { + a INTEGER, + b BOOLEAN + } + ]] +} + +-- 'ExtAddGroup1' is used internally to represent fake sequences for +-- extension addition groups. Make sure that a real sequence with that +-- name at the top-level doesn't cause a problem. + +ExtAddGroup1 ::= SEQUENCE { + x INTEGER, + y INTEGER +} + END diff --git a/lib/asn1/test/asn1_SUITE_data/SeqExtension2.asn1 b/lib/asn1/test/asn1_SUITE_data/SeqExtension2.asn1 new file mode 100644 index 0000000000..44900d9d39 --- /dev/null +++ b/lib/asn1/test/asn1_SUITE_data/SeqExtension2.asn1 @@ -0,0 +1,208 @@ +SeqExtension2 DEFINITIONS AUTOMATIC TAGS ::= +BEGIN + +SeqExt66 ::= SEQUENCE { + ..., + i0 INTEGER (0..127) OPTIONAL, + i1 INTEGER (0..127) OPTIONAL, + i2 INTEGER (0..127) OPTIONAL, + i3 INTEGER (0..127) OPTIONAL, + i4 INTEGER (0..127) OPTIONAL, + i5 INTEGER (0..127) OPTIONAL, + i6 INTEGER (0..127) OPTIONAL, + i7 INTEGER (0..127) OPTIONAL, + i8 INTEGER (0..127) OPTIONAL, + i9 INTEGER (0..127) OPTIONAL, + i10 INTEGER (0..127) OPTIONAL, + i11 INTEGER (0..127) OPTIONAL, + i12 INTEGER (0..127) OPTIONAL, + i13 INTEGER (0..127) OPTIONAL, + i14 INTEGER (0..127) OPTIONAL, + i15 INTEGER (0..127) OPTIONAL, + i16 INTEGER (0..127) OPTIONAL, + i17 INTEGER (0..127) OPTIONAL, + i18 INTEGER (0..127) OPTIONAL, + i19 INTEGER (0..127) OPTIONAL, + i20 INTEGER (0..127) OPTIONAL, + i21 INTEGER (0..127) OPTIONAL, + i22 INTEGER (0..127) OPTIONAL, + i23 INTEGER (0..127) OPTIONAL, + i24 INTEGER (0..127) OPTIONAL, + i25 INTEGER (0..127) OPTIONAL, + i26 INTEGER (0..127) OPTIONAL, + i27 INTEGER (0..127) OPTIONAL, + i28 INTEGER (0..127) OPTIONAL, + i29 INTEGER (0..127) OPTIONAL, + i30 INTEGER (0..127) OPTIONAL, + i31 INTEGER (0..127) OPTIONAL, + i32 INTEGER (0..127) OPTIONAL, + i33 INTEGER (0..127) OPTIONAL, + i34 INTEGER (0..127) OPTIONAL, + i35 INTEGER (0..127) OPTIONAL, + i36 INTEGER (0..127) OPTIONAL, + i37 INTEGER (0..127) OPTIONAL, + i38 INTEGER (0..127) OPTIONAL, + i39 INTEGER (0..127) OPTIONAL, + i40 INTEGER (0..127) OPTIONAL, + i41 INTEGER (0..127) OPTIONAL, + i42 INTEGER (0..127) OPTIONAL, + i43 INTEGER (0..127) OPTIONAL, + i44 INTEGER (0..127) OPTIONAL, + i45 INTEGER (0..127) OPTIONAL, + i46 INTEGER (0..127) OPTIONAL, + i47 INTEGER (0..127) OPTIONAL, + i48 INTEGER (0..127) OPTIONAL, + i49 INTEGER (0..127) OPTIONAL, + i50 INTEGER (0..127) OPTIONAL, + i51 INTEGER (0..127) OPTIONAL, + i52 INTEGER (0..127) OPTIONAL, + i53 INTEGER (0..127) OPTIONAL, + i54 INTEGER (0..127) OPTIONAL, + i55 INTEGER (0..127) OPTIONAL, + i56 INTEGER (0..127) OPTIONAL, + i57 INTEGER (0..127) OPTIONAL, + i58 INTEGER (0..127) OPTIONAL, + i59 INTEGER (0..127) OPTIONAL, + i60 INTEGER (0..127) OPTIONAL, + i61 INTEGER (0..127) OPTIONAL, + i62 INTEGER (0..127) OPTIONAL, + i63 INTEGER (0..127) OPTIONAL, + i64 INTEGER (0..127) OPTIONAL, + i65 INTEGER (0..127) OPTIONAL +} + +SeqExt130 ::= SEQUENCE { + ..., + i0 INTEGER (0..255) OPTIONAL, + i1 INTEGER (0..255) OPTIONAL, + i2 INTEGER (0..255) OPTIONAL, + i3 INTEGER (0..255) OPTIONAL, + i4 INTEGER (0..255) OPTIONAL, + i5 INTEGER (0..255) OPTIONAL, + i6 INTEGER (0..255) OPTIONAL, + i7 INTEGER (0..255) OPTIONAL, + i8 INTEGER (0..255) OPTIONAL, + i9 INTEGER (0..255) OPTIONAL, + i10 INTEGER (0..255) OPTIONAL, + i11 INTEGER (0..255) OPTIONAL, + i12 INTEGER (0..255) OPTIONAL, + i13 INTEGER (0..255) OPTIONAL, + i14 INTEGER (0..255) OPTIONAL, + i15 INTEGER (0..255) OPTIONAL, + i16 INTEGER (0..255) OPTIONAL, + i17 INTEGER (0..255) OPTIONAL, + i18 INTEGER (0..255) OPTIONAL, + i19 INTEGER (0..255) OPTIONAL, + i20 INTEGER (0..255) OPTIONAL, + i21 INTEGER (0..255) OPTIONAL, + i22 INTEGER (0..255) OPTIONAL, + i23 INTEGER (0..255) OPTIONAL, + i24 INTEGER (0..255) OPTIONAL, + i25 INTEGER (0..255) OPTIONAL, + i26 INTEGER (0..255) OPTIONAL, + i27 INTEGER (0..255) OPTIONAL, + i28 INTEGER (0..255) OPTIONAL, + i29 INTEGER (0..255) OPTIONAL, + i30 INTEGER (0..255) OPTIONAL, + i31 INTEGER (0..255) OPTIONAL, + i32 INTEGER (0..255) OPTIONAL, + i33 INTEGER (0..255) OPTIONAL, + i34 INTEGER (0..255) OPTIONAL, + i35 INTEGER (0..255) OPTIONAL, + i36 INTEGER (0..255) OPTIONAL, + i37 INTEGER (0..255) OPTIONAL, + i38 INTEGER (0..255) OPTIONAL, + i39 INTEGER (0..255) OPTIONAL, + i40 INTEGER (0..255) OPTIONAL, + i41 INTEGER (0..255) OPTIONAL, + i42 INTEGER (0..255) OPTIONAL, + i43 INTEGER (0..255) OPTIONAL, + i44 INTEGER (0..255) OPTIONAL, + i45 INTEGER (0..255) OPTIONAL, + i46 INTEGER (0..255) OPTIONAL, + i47 INTEGER (0..255) OPTIONAL, + i48 INTEGER (0..255) OPTIONAL, + i49 INTEGER (0..255) OPTIONAL, + i50 INTEGER (0..255) OPTIONAL, + i51 INTEGER (0..255) OPTIONAL, + i52 INTEGER (0..255) OPTIONAL, + i53 INTEGER (0..255) OPTIONAL, + i54 INTEGER (0..255) OPTIONAL, + i55 INTEGER (0..255) OPTIONAL, + i56 INTEGER (0..255) OPTIONAL, + i57 INTEGER (0..255) OPTIONAL, + i58 INTEGER (0..255) OPTIONAL, + i59 INTEGER (0..255) OPTIONAL, + i60 INTEGER (0..255) OPTIONAL, + i61 INTEGER (0..255) OPTIONAL, + i62 INTEGER (0..255) OPTIONAL, + i63 INTEGER (0..255) OPTIONAL, + i64 INTEGER (0..255) OPTIONAL, + i65 INTEGER (0..255) OPTIONAL, + i66 INTEGER (0..255) OPTIONAL, + i67 INTEGER (0..255) OPTIONAL, + i68 INTEGER (0..255) OPTIONAL, + i69 INTEGER (0..255) OPTIONAL, + i70 INTEGER (0..255) OPTIONAL, + i71 INTEGER (0..255) OPTIONAL, + i72 INTEGER (0..255) OPTIONAL, + i73 INTEGER (0..255) OPTIONAL, + i74 INTEGER (0..255) OPTIONAL, + i75 INTEGER (0..255) OPTIONAL, + i76 INTEGER (0..255) OPTIONAL, + i77 INTEGER (0..255) OPTIONAL, + i78 INTEGER (0..255) OPTIONAL, + i79 INTEGER (0..255) OPTIONAL, + i80 INTEGER (0..255) OPTIONAL, + i81 INTEGER (0..255) OPTIONAL, + i82 INTEGER (0..255) OPTIONAL, + i83 INTEGER (0..255) OPTIONAL, + i84 INTEGER (0..255) OPTIONAL, + i85 INTEGER (0..255) OPTIONAL, + i86 INTEGER (0..255) OPTIONAL, + i87 INTEGER (0..255) OPTIONAL, + i88 INTEGER (0..255) OPTIONAL, + i89 INTEGER (0..255) OPTIONAL, + i90 INTEGER (0..255) OPTIONAL, + i91 INTEGER (0..255) OPTIONAL, + i92 INTEGER (0..255) OPTIONAL, + i93 INTEGER (0..255) OPTIONAL, + i94 INTEGER (0..255) OPTIONAL, + i95 INTEGER (0..255) OPTIONAL, + i96 INTEGER (0..255) OPTIONAL, + i97 INTEGER (0..255) OPTIONAL, + i98 INTEGER (0..255) OPTIONAL, + i99 INTEGER (0..255) OPTIONAL, + i100 INTEGER (0..255) OPTIONAL, + i101 INTEGER (0..255) OPTIONAL, + i102 INTEGER (0..255) OPTIONAL, + i103 INTEGER (0..255) OPTIONAL, + i104 INTEGER (0..255) OPTIONAL, + i105 INTEGER (0..255) OPTIONAL, + i106 INTEGER (0..255) OPTIONAL, + i107 INTEGER (0..255) OPTIONAL, + i108 INTEGER (0..255) OPTIONAL, + i109 INTEGER (0..255) OPTIONAL, + i110 INTEGER (0..255) OPTIONAL, + i111 INTEGER (0..255) OPTIONAL, + i112 INTEGER (0..255) OPTIONAL, + i113 INTEGER (0..255) OPTIONAL, + i114 INTEGER (0..255) OPTIONAL, + i115 INTEGER (0..255) OPTIONAL, + i116 INTEGER (0..255) OPTIONAL, + i117 INTEGER (0..255) OPTIONAL, + i118 INTEGER (0..255) OPTIONAL, + i119 INTEGER (0..255) OPTIONAL, + i120 INTEGER (0..255) OPTIONAL, + i121 INTEGER (0..255) OPTIONAL, + i122 INTEGER (0..255) OPTIONAL, + i123 INTEGER (0..255) OPTIONAL, + i124 INTEGER (0..255) OPTIONAL, + i125 INTEGER (0..255) OPTIONAL, + i126 INTEGER (0..255) OPTIONAL, + i127 INTEGER (0..255) OPTIONAL, + i128 INTEGER (0..255) OPTIONAL, + i129 INTEGER (0..255) OPTIONAL +} + +END diff --git a/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl b/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl index 00e4c707dd..8e21e6ca84 100644 --- a/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl +++ b/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl @@ -34,6 +34,9 @@ run(Erule) -> run3(), run3(Erule), + roundtrip('InlinedSeq', #'InlinedSeq'{s=#'InlinedSeq_s'{a=42,b=true}}), + roundtrip('ExtAddGroup1', #'ExtAddGroup1'{x=42,y=1023}), + ok. %% From X.691 (07/2002) A.4. diff --git a/lib/asn1/test/asn1_test_lib.erl b/lib/asn1/test/asn1_test_lib.erl index b839dfcf2a..7d7364e2a4 100644 --- a/lib/asn1/test/asn1_test_lib.erl +++ b/lib/asn1/test/asn1_test_lib.erl @@ -22,6 +22,7 @@ -export([compile/3]). -export([compile_all/3]). -export([compile_erlang/3]). +-export([hex_to_bin/1]). -export([ticket_7407_compile/2,ticket_7407_code/1, ticket_7678/2, ticket_7708/2, ticket_7763/1, ticket_7876/3]). @@ -61,6 +62,13 @@ compile_erlang(Mod, Config, Options) -> {ok, M} = compile:file(filename:join(DataDir, Mod), [report,{i,CaseDir},{outdir,CaseDir}|Options]). +hex_to_bin(S) -> + << <<(hex2num(C)):4>> || C <- S, C =/= $\s >>. + +%%% +%%% Internal functions. +%%% + should_load(File, Options) -> case lists:member(abs, Options) of true -> @@ -79,6 +87,10 @@ strip_extension(File, Ext) when Ext == ".asn"; Ext == ".set"; Ext == ".asn1"-> strip_extension(File, _Ext) -> File. +hex2num(C) when $0 =< C, C =< $9 -> C - $0; +hex2num(C) when $A =< C, C =< $F -> C - $A + 10; +hex2num(C) when $a =< C, C =< $f -> C - $a + 10. + ticket_7407_compile(Config,Option) -> ?line DataDir = ?config(data_dir,Config), diff --git a/lib/asn1/test/testConstraints.erl b/lib/asn1/test/testConstraints.erl index e825302629..14e508d2b5 100644 --- a/lib/asn1/test/testConstraints.erl +++ b/lib/asn1/test/testConstraints.erl @@ -126,19 +126,29 @@ int_constraints(Rules) -> %%========================================================== roundtrip('SemiConstrained', 100), + v_roundtrip(Rules, 'SemiConstrained', 100+128), roundtrip('SemiConstrained', 397249742397243), + roundtrip('SemiConstrained', 100 + 1 bsl 128*8), + roundtrip('SemiConstrained', 100 + 1 bsl 256*8), + roundtrip('NegSemiConstrained', -128), + v_roundtrip(Rules, 'NegSemiConstrained', 0), roundtrip('NegSemiConstrained', -1), roundtrip('NegSemiConstrained', 500), roundtrip('SemiConstrainedExt', -65536), roundtrip('SemiConstrainedExt', 0), roundtrip('SemiConstrainedExt', 42), + v_roundtrip(Rules, 'SemiConstrainedExt', 42+128), roundtrip('SemiConstrainedExt', 100), roundtrip('SemiConstrainedExt', 47777789), + roundtrip('SemiConstrainedExt', 42 + 1 bsl 128*8), + roundtrip('SemiConstrainedExt', 42 + 1 bsl 256*8), + roundtrip('NegSemiConstrainedExt', -1023), roundtrip('NegSemiConstrainedExt', -128), roundtrip('NegSemiConstrainedExt', -1), + v_roundtrip(Rules, 'NegSemiConstrainedExt', 0), roundtrip('NegSemiConstrainedExt', 500), %%========================================================== @@ -174,6 +184,21 @@ int_constraints(Rules) -> ok. +%% PER: Ensure that if the lower bound is Lb, Lb+16#80 is encoded +%% in two bytes as 16#0180. (Not in three bytes as 16#010080.) +v(ber, 'SemiConstrained', 100+128) -> "020200E4"; +v(per, 'SemiConstrained', 100+128) -> "0180"; +v(uper, 'SemiConstrained', 100+128) -> "0180"; +v(ber, 'NegSemiConstrained', 0) -> "020100"; +v(per, 'NegSemiConstrained', 0) -> "0180"; +v(uper, 'NegSemiConstrained', 0) -> "0180"; +v(ber, 'SemiConstrainedExt', 42+128) -> "020200AA"; +v(per, 'SemiConstrainedExt', 42+128) -> "000180"; +v(uper, 'SemiConstrainedExt', 42+128) -> "00C000"; +v(ber, 'NegSemiConstrainedExt', 0) -> "020100"; +v(per, 'NegSemiConstrainedExt', 0) -> "000180"; +v(uper, 'NegSemiConstrainedExt', 0) -> "00C000". + shorter_ext(per, "a") -> <<16#80,16#01,16#61>>; shorter_ext(uper, "a") -> <<16#80,16#E1>>; shorter_ext(ber, _) -> none. @@ -183,13 +208,17 @@ refed_NNL_name(_Erule) -> ?line {error,_Reason} = asn1_wrapper:encode('Constraints','AnotherThing',fred3). +v_roundtrip(Erule, Type, Value) -> + Encoded = asn1_test_lib:hex_to_bin(v(Erule, Type, Value)), + Encoded = roundtrip('Constraints', Type, Value). + roundtrip(Type, Value) -> roundtrip('Constraints', Type, Value). roundtrip(Module, Type, Value) -> {ok,Encoded} = Module:encode(Type, Value), {ok,Value} = Module:decode(Type, Encoded), - ok. + Encoded. roundtrip_enc(Type, Value, Enc) -> Module = 'Constraints', diff --git a/lib/asn1/test/testEnumExt.erl b/lib/asn1/test/testEnumExt.erl index 8840ed6d2f..8779f3b83b 100644 --- a/lib/asn1/test/testEnumExt.erl +++ b/lib/asn1/test/testEnumExt.erl @@ -38,7 +38,7 @@ main(Rule) when Rule =:= per; Rule =:= uper -> %% ENUMERATED no extensionmark B64 = <<64>>, B64 = roundtrip('Noext', red), - common(); + common(Rule); main(ber) -> io:format("main(ber)~n",[]), %% ENUMERATED with extensionmark (value is in root set) @@ -56,18 +56,38 @@ main(ber) -> roundtrip('Globalstate', preop), roundtrip('Globalstate', com), - common(). + common(ber). -common() -> +common(Erule) -> roundtrip('Seq', {'Seq',blue,42}), roundtrip('Seq', {'Seq',red,42}), roundtrip('Seq', {'Seq',green,42}), roundtrip('Seq', {'Seq',orange,47}), roundtrip('Seq', {'Seq',black,4711}), roundtrip('Seq', {'Seq',magenta,4712}), + + [begin + S = io_lib:format("e~2.016.0b", [I]), + E = list_to_atom(lists:flatten(S)), + roundtrip('SeqBig', {'SeqBig',true,E,9357}) + end || I <- lists:seq(0, 128)], + + v_roundtrip(Erule, 'SeqBig', {'SeqBig',true,e40,9357}), + v_roundtrip(Erule, 'SeqBig', {'SeqBig',true,e80,9357}), ok. roundtrip(Type, Value) -> {ok,Encoded} = 'EnumExt':encode(Type, Value), {ok,Value} = 'EnumExt':decode(Type, Encoded), Encoded. + +v_roundtrip(Erule, Type, Value) -> + Encoded = roundtrip(Type, Value), + Encoded = asn1_test_lib:hex_to_bin(v(Erule, Value)). + +v(ber, {'SeqBig',true,e40,9357}) -> "300A8001 FF810141 8202248D"; +v(ber, {'SeqBig',true,e80,9357}) -> "300B8001 FF810200 81820224 8D"; +v(per, {'SeqBig',true,e40,9357}) -> "E0014002 248D"; +v(per, {'SeqBig',true,e80,9357}) -> "E0018002 248D"; +v(uper, {'SeqBig',true,e40,9357}) -> "E0280044 91A0"; +v(uper, {'SeqBig',true,e80,9357}) -> "E0300044 91A0". diff --git a/lib/asn1/test/testSeqExtension.erl b/lib/asn1/test/testSeqExtension.erl index 1128d9a7c3..724f485fa0 100644 --- a/lib/asn1/test/testSeqExtension.erl +++ b/lib/asn1/test/testSeqExtension.erl @@ -20,7 +20,7 @@ -module(testSeqExtension). -include("External.hrl"). --export([main/2]). +-export([main/3]). -include_lib("test_server/include/test_server.hrl"). @@ -32,7 +32,7 @@ -record('SeqExt6',{i1,i2,i3,i4,i5,i6,i7}). -record('SuperSeq',{s1,s2,s3,s4,s5,s6,i}). -main(DataDir, Opts) -> +main(Erule, DataDir, Opts) -> roundtrip('SeqExt1', #'SeqExt1'{}), roundtrip('SeqExt2', #'SeqExt2'{bool=true,int=99}), @@ -92,9 +92,38 @@ main(DataDir, Opts) -> s5={'SeqExt5'}, s6={'SeqExt6',531,601,999,777,11953}, i=BigInt} = DecodedSuperSeq, + + + %% Test more than 64 extensions. + roundtrip2('SeqExt66', + list_to_tuple(['SeqExt66'|lists:seq(0, 65)])), + v_roundtrip2(Erule, 'SeqExt66', + list_to_tuple(['SeqExt66'| + lists:duplicate(65, asn1_NOVALUE)++[125]])), + roundtrip2('SeqExt130', + list_to_tuple(['SeqExt130'|lists:seq(0, 129)])), + v_roundtrip2(Erule, 'SeqExt130', + list_to_tuple(['SeqExt130'| + lists:duplicate(129, asn1_NOVALUE)++[199]])), ok. roundtrip(Type, Value) -> {ok,Encoded} = 'SeqExtension':encode(Type, Value), {ok,Value} = 'SeqExtension':decode(Type, Encoded), ok. + +v_roundtrip2(Erule, Type, Value) -> + Encoded = asn1_test_lib:hex_to_bin(v(Erule, Type)), + Encoded = roundtrip2(Type, Value). + +roundtrip2(Type, Value) -> + {ok,Encoded} = 'SeqExtension2':encode(Type, Value), + {ok,Value} = 'SeqExtension2':decode(Type, Encoded), + Encoded. + +v(ber, 'SeqExt66') -> "30049F41 017D"; +v(per, 'SeqExt66') -> "C0420000 00000000 00004001 FA"; +v(uper, 'SeqExt66') -> "D0800000 00000000 00101FA0"; +v(ber, 'SeqExt130') -> "30069F81 010200C7"; +v(per, 'SeqExt130') -> "C0808200 00000000 00000000 00000000 00000040 01C7"; +v(uper, 'SeqExt130') -> "E0208000 00000000 00000000 00000000 0000101C 70". diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml index 2df407018e..99d167bfa9 100644 --- a/lib/crypto/doc/src/crypto.xml +++ b/lib/crypto/doc/src/crypto.xml @@ -208,7 +208,7 @@ </type> <desc> <p>Computes the shared secret from the private key and the other party's public key. - See also <seealso marker="public_key:public_key#compute_key/2">public_key:compute_key/2</seealso> + See also <seealso marker="public_key:public_key#compute_key-2">public_key:compute_key/2</seealso> </p> </desc> </func> @@ -240,7 +240,7 @@ </type> <desc> <p>Generates public keys of type <c>Type</c>. - See also <seealso marker="public_key:public_key#generate_key/1">public_key:generate_key/1</seealso> + See also <seealso marker="public_key:public_key#generate_key-1">public_key:generate_key/1</seealso> </p> </desc> </func> @@ -269,7 +269,7 @@ <desc> <p>Initializes the context for streaming hash operations. <c>Type</c> determines which digest to use. The returned context should be used as argument - to <seealso marker="#hash_update/2">hash_update</seealso>.</p> + to <seealso marker="#hash_update-2">hash_update</seealso>.</p> <p>May throw exception <c>notsup</c> in case the chosen <c>Type</c> is not supported by the underlying OpenSSL implementation.</p> </desc> @@ -283,10 +283,10 @@ </type> <desc> <p>Updates the digest represented by <c>Context</c> using the given <c>Data</c>. <c>Context</c> - must have been generated using <seealso marker="#hash_init/1">hash_init</seealso> + must have been generated using <seealso marker="#hash_init-1">hash_init</seealso> or a previous call to this function. <c>Data</c> can be any length. <c>NewContext</c> must be passed into the next call to <c>hash_update</c> - or <seealso marker="#hash_final/1">hash_final</seealso>.</p> + or <seealso marker="#hash_final-1">hash_final</seealso>.</p> </desc> </func> <func> @@ -297,7 +297,7 @@ </type> <desc> <p>Finalizes the hash operation referenced by <c>Context</c> returned - from a previous call to <seealso marker="#hash_update/2">hash_update</seealso>. + from a previous call to <seealso marker="#hash_update-2">hash_update</seealso>. The size of <c>Digest</c> is determined by the type of hash function used to generate it.</p> </desc> @@ -346,10 +346,10 @@ <desc> <p>Updates the HMAC represented by <c>Context</c> using the given <c>Data</c>. <c>Context</c> must have been generated using an HMAC init function (such as - <seealso marker="#hmac_init/2">hmac_init</seealso>). <c>Data</c> can be any length. <c>NewContext</c> + <seealso marker="#hmac_init-2">hmac_init</seealso>). <c>Data</c> can be any length. <c>NewContext</c> must be passed into the next call to <c>hmac_update</c> - or to one of the functions <seealso marker="#hmac_final/1">hmac_final</seealso> and - <seealso marker="#hmac_final_n/1">hmac_final_n</seealso> + or to one of the functions <seealso marker="#hmac_final-1">hmac_final</seealso> and + <seealso marker="#hmac_final_n-2">hmac_final_n</seealso> </p> </desc> @@ -447,36 +447,36 @@ <v>PlainText = binary()</v> </type> <desc> - <p>Decrypts the <c>ChipherText</c> (usually a session key encrypted with - <seealso marker="#public_encrypt/3">public_encrypt/3</seealso>) - using the <c>PrivateKey</c> and returns the - message. The <c>Padding</c> is the padding mode that was - used to encrypt the data, - see <seealso marker="#public_encrypt/3">public_encrypt/3</seealso>. - See also <seealso marker="public_key:public_key#decrypt_private/2">public_key:decrypt_private/[2,3]</seealso> + <p>Decrypts the <c>ChipherText</c>, encrypted with + <seealso marker="#public_encrypt-4">public_encrypt/4</seealso> (or equivalent function) + using the <c>PrivateKey</c>, and returns the + plaintext (message digest). This is a low level signature verification operation + used for instance by older versions of the SSL protocol. + See also <seealso marker="public_key:public_key#decrypt_private-2">public_key:decrypt_private/[2,3]</seealso> </p> </desc> </func> - + <func> <name>private_encrypt(Type, PlainText, PrivateKey, Padding) -> ChipherText</name> - <fsummary>Encrypts Msg using the private Key.</fsummary> + <fsummary>Encrypts PlainText using the private Key.</fsummary> <type> <v>Type = rsa</v> <v>PlainText = binary()</v> + <d> The size of the <c>PlainText</c> must be less + than <c>byte_size(N)-11</c> if <c>rsa_pkcs1_padding</c> is + used, and <c>byte_size(N)</c> if <c>rsa_no_padding</c> is + used, where N is public modulus of the RSA key.</d> <v>PrivateKey = rsa_private()</v> <v>Padding = rsa_pkcs1_padding | rsa_no_padding</v> <v>ChipherText = binary()</v> </type> <desc> <p>Encrypts the <c>PlainText</c> using the <c>PrivateKey</c> - and returns the cipher. The <c>Padding</c> decides what padding mode is used, - <c>rsa_pkcs1_padding</c> is PKCS #1 v1.5 currently the most - used mode. - The size of the <c>Msg</c> must be less than <c>byte_size(N)-11</c> if - <c>rsa_pkcs1_padding</c> is used, and <c>byte_size(N)</c> if <c>rsa_no_padding</c> - is used, where N is public modulus of the RSA key. - See also <seealso marker="public_key:public_key#encrypt_private/2">public_key:encrypt_private/[2,3]</seealso> + and returns the ciphertext. This is a low level signature operation + used for instance by older versions of the SSL protocol. See + also <seealso + marker="public_key:public_key#encrypt_private-2">public_key:encrypt_private/[2,3]</seealso> </p> </desc> </func> @@ -491,42 +491,35 @@ <v>PlainText = binary()</v> </type> <desc> - <p>Decrypts the <c>ChipherText</c> (encrypted with - <seealso marker="#private_encrypt/3">private_encrypt/3</seealso>) - using the <c>PrivateKey</c> and returns the - message. The <c>Padding</c> is the padding mode that was - used to encrypt the data, - see <seealso marker="#private_encrypt/3">private_encrypt/3</seealso>. - See also <seealso marker="public_key:public_key#decrypt_public/2">public_key:decrypt_public/[2,3]</seealso> + <p>Decrypts the <c>ChipherText</c>, encrypted with + <seealso marker="#private_encrypt-4">private_encrypt/4</seealso>(or equivalent function) + using the <c>PrivateKey</c>, and returns the + plaintext (message digest). This is a low level signature verification operation + used for instance by older versions of the SSL protocol. + See also <seealso marker="public_key:public_key#decrypt_public-2">public_key:decrypt_public/[2,3]</seealso> </p> </desc> </func> <func> <name>public_encrypt(Type, PlainText, PublicKey, Padding) -> ChipherText</name> - <fsummary>Encrypts Msg using the public Key.</fsummary> + <fsummary>Encrypts PlainText using the public Key.</fsummary> <type> <v>Type = rsa</v> <v>PlainText = binary()</v> + <d> The size of the <c>PlainText</c> must be less + than <c>byte_size(N)-11</c> if <c>rsa_pkcs1_padding</c> is + used, and <c>byte_size(N)</c> if <c>rsa_no_padding</c> is + used, where N is public modulus of the RSA key.</d> <v>PublicKey = rsa_public()</v> <v>Padding = rsa_pkcs1_padding | rsa_pkcs1_oaep_padding | rsa_no_padding</v> <v>ChipherText = binary()</v> </type> <desc> - <p>Encrypts the <c>PlainText</c> (usually a session key) using - the <c>PublicKey</c> and returns the <c>CipherText</c>. The - <c>Padding</c> decides what padding mode is used, - <c>rsa_pkcs1_padding</c> is PKCS #1 v1.5 currently the most - used mode and <c>rsa_pkcs1_oaep_padding</c> is EME-OAEP as - defined in PKCS #1 v2.0 with SHA-1, MGF1 and an empty encoding - parameter. This mode is recommended for all new - applications. The size of the <c>Msg</c> must be less than - <c>byte_size(N)-11</c> if <c>rsa_pkcs1_padding</c> is - used, <c>byte_size(N)-41</c> if - <c>rsa_pkcs1_oaep_padding</c> is used and - <c>byte_size(N)</c> if <c>rsa_no_padding</c> is used, where N is public modulus of the RSA key. - See also <seealso - marker="public_key:public_key#encrypt_public/2">public_key:encrypt_public/[2,3]</seealso> + <p>Encrypts the <c>PlainText</c> (message digest) using the <c>PublicKey</c> + and returns the <c>CipherText</c>. This is a low level signature operation + used for instance by older versions of the SSL protocol. See also <seealso + marker="public_key:public_key#encrypt_public-2">public_key:encrypt_public/[2,3]</seealso> </p> </desc> </func> @@ -563,9 +556,9 @@ <type> <v>Algorithm = rsa | dss | ecdsa </v> <v>Msg = binary() | {digest,binary()}</v> - <d>The msg is either the binary "plain text" data to be - signed or it is the hashed value of "plain text" i.e. the - digest.</d> + <d>The msg is either the binary "cleartext" data to be + signed or it is the hashed value of "cleartext" i.e. the + digest (plaintext).</d> <v>DigestType = digest_type()</v> <v>Key = rsa_private() | dss_private() | [ecdh_private(),ecdh_params()]</v> </type> @@ -573,7 +566,7 @@ <p>Creates a digital signature.</p> <p>Algorithm <c>dss</c> can only be used together with digest type <c>sha</c>.</p> - See also <seealso marker="public_key:public_key#sign/3">public_key:sign/3</seealso> + See also <seealso marker="public_key:public_key#sign-3">public_key:sign/3</seealso> </desc> </func> @@ -617,8 +610,8 @@ </type> <desc> <p>Initializes the state for use in RC4 stream encryption - <seealso marker="#stream_encrypt/2">stream_encrypt</seealso> and - <seealso marker="#stream_decrypt/2">stream_decrypt</seealso></p> + <seealso marker="#stream_encrypt-2">stream_encrypt</seealso> and + <seealso marker="#stream_decrypt-2">stream_decrypt</seealso></p> </desc> </func> @@ -635,8 +628,8 @@ <p>Initializes the state for use in streaming AES encryption using Counter mode (CTR). <c>Key</c> is the AES key and must be either 128, 192, or 256 bts long. <c>IVec</c> is an arbitrary initializing vector of 128 bits (16 bytes). This state is for use with - <seealso marker="#stream_encrypt/2">stream_encrypt</seealso> and - <seealso marker="#stream_decrypt/2">stream_decrypt</seealso>.</p> + <seealso marker="#stream_encrypt-2">stream_encrypt</seealso> and + <seealso marker="#stream_decrypt-2">stream_decrypt</seealso>.</p> </desc> </func> @@ -650,7 +643,7 @@ <desc> <p>Encrypts <c>PlainText</c> according to the stream cipher <c>Type</c> specified in stream_init/3. <c>Text</c> can be any number of bytes. The initial <c>State</c> is created using - <seealso marker="#stream_init/2">stream_init</seealso>. + <seealso marker="#stream_init-2">stream_init</seealso>. <c>NewState</c> must be passed into the next call to <c>stream_encrypt</c>.</p> </desc> </func> @@ -665,7 +658,7 @@ <desc> <p>Decrypts <c>CipherText</c> according to the stream cipher <c>Type</c> specified in stream_init/3. <c>PlainText</c> can be any number of bytes. The initial <c>State</c> is created using - <seealso marker="#stream_init/2">stream_init</seealso>. + <seealso marker="#stream_init-2">stream_init</seealso>. <c>NewState</c> must be passed into the next call to <c>stream_encrypt</c>.</p> </desc> </func> @@ -692,8 +685,8 @@ <type> <v> Algorithm = rsa | dss | ecdsa </v> <v>Msg = binary() | {digest,binary()}</v> - <d>The msg is either the binary "plain text" data - or it is the hashed value of "plain text" i.e. the digest.</d> + <d>The msg is either the binary "cleartext" data + or it is the hashed value of "cleartext" i.e. the digest (plaintext).</d> <v>DigestType = digest_type()</v> <v>Signature = binary()</v> <v>Key = rsa_public() | dss_public() | [ecdh_public(),ecdh_params()]</v> @@ -703,7 +696,7 @@ <p>Algorithm <c>dss</c> can only be used together with digest type <c>sha</c>.</p> - See also <seealso marker="public_key:public_key#sign/3">public_key:verify/3</seealso> + See also <seealso marker="public_key:public_key#verify-4">public_key:verify/4</seealso> </desc> </func> diff --git a/lib/erl_interface/vsn.mk b/lib/erl_interface/vsn.mk index 9287e105df..6f08d380ca 100644 --- a/lib/erl_interface/vsn.mk +++ b/lib/erl_interface/vsn.mk @@ -1 +1 @@ -EI_VSN = 3.7.12 +EI_VSN = 3.7.13 diff --git a/lib/et/vsn.mk b/lib/et/vsn.mk index 99532ee3f3..40cdc2b298 100644 --- a/lib/et/vsn.mk +++ b/lib/et/vsn.mk @@ -1 +1 @@ -ET_VSN = 1.4.4.3 +ET_VSN = 1.4.4.4 diff --git a/lib/os_mon/vsn.mk b/lib/os_mon/vsn.mk index 7d6c5484a7..e3acea0258 100644 --- a/lib/os_mon/vsn.mk +++ b/lib/os_mon/vsn.mk @@ -1 +1 @@ -OS_MON_VSN = 2.2.11 +OS_MON_VSN = 2.2.12 diff --git a/lib/public_key/doc/src/public_key.xml b/lib/public_key/doc/src/public_key.xml index 10c95a39ac..c8236b94ca 100644 --- a/lib/public_key/doc/src/public_key.xml +++ b/lib/public_key/doc/src/public_key.xml @@ -154,8 +154,8 @@ <funcs> <func> - <name> compute_key(OthersKey, MyKey)-></name> - <name> compute_key(OthersKey, MyKey, Params)-></name> + <name>compute_key(OthersKey, MyKey)-></name> + <name>compute_key(OthersKey, MyKey, Params)-></name> <fsummary> Compute shared secret</fsummary> <type> <v>OthersKey = #'ECPoint'{} | binary(), MyKey = #'ECPrivateKey'{} | binary()</v> @@ -176,7 +176,8 @@ <v>Options = public_crypt_options()</v> </type> <desc> - <p>Public key decryption using the private key.</p> + <p>Public key decryption using the private key. See also <seealso + marker="crypto:crypto#private_decrypt/4">crypto:private_decrypt/4</seealso></p> </desc> </func> @@ -190,7 +191,8 @@ <v>Options = public_crypt_options()</v> </type> <desc> - <p> Public key decryption using the public key.</p> + <p> Public key decryption using the public key. See also <seealso + marker="crypto:crypto#public_decrypt/4">crypto:public_decrypt/4</seealso></p> </desc> </func> @@ -304,7 +306,9 @@ <v>Key = rsa_private_key()</v> </type> <desc> - <p> Public key encryption using the private key.</p> + <p> Public key encryption using the private key. + See also <seealso + marker="crypto:crypto#private_encrypt/4">crypto:private_encrypt/4</seealso></p> </desc> </func> @@ -316,7 +320,8 @@ <v>Key = rsa_public_key()</v> </type> <desc> - <p> Public key encryption using the public key.</p> + <p> Public key encryption using the public key. See also <seealso + marker="crypto:crypto#public_encrypt/4">crypto:public_encrypt/4</seealso></p> </desc> </func> diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl index 3eea6f6ec4..cdbfe6e07c 100644 --- a/lib/public_key/src/public_key.erl +++ b/lib/public_key/src/public_key.erl @@ -252,8 +252,7 @@ decrypt_private(CipherText, Key) -> decrypt_private(CipherText, Key, []). decrypt_private(CipherText, - #'RSAPrivateKey'{modulus = N, publicExponent = E, - privateExponent = D} = Key, + #'RSAPrivateKey'{} = Key, Options) when is_binary(CipherText), is_list(Options) -> diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl index 75c17b14db..0c1e47311d 100644 --- a/lib/ssl/src/ssl.erl +++ b/lib/ssl/src/ssl.erl @@ -214,8 +214,8 @@ prf(Socket, Secret, Label, Seed, WantedLength) -> clear_pem_cache() -> tls:clear_pem_cache(). -format_error(Reason) when is_list(Reason) -> - tls:format_error(Reason). +format_error(Error) -> + tls:format_error(Error). random_bytes(N) -> tls:random_bytes(N). diff --git a/lib/ssl/src/ssl_cipher.erl b/lib/ssl/src/ssl_cipher.erl index 898b421dff..ec5d793d65 100644 --- a/lib/ssl/src/ssl_cipher.erl +++ b/lib/ssl/src/ssl_cipher.erl @@ -1190,14 +1190,16 @@ hash_size(md5) -> 16; hash_size(sha) -> 20; -hash_size(sha224) -> - 28; +%% Uncomment when adding cipher suite that needs it +%% hash_size(sha224) -> +%% 28; hash_size(sha256) -> 32; hash_size(sha384) -> - 48; -hash_size(sha512) -> - 64. + 48. +%% Uncomment when adding cipher suite that needs it +%% hash_size(sha512) -> +%% 64. %% RFC 5246: 6.2.3.2. CBC Block Cipher %% diff --git a/lib/ssl/src/ssl_manager.erl b/lib/ssl/src/ssl_manager.erl index 1b06e351cf..7af4a68461 100644 --- a/lib/ssl/src/ssl_manager.erl +++ b/lib/ssl/src/ssl_manager.erl @@ -104,7 +104,6 @@ connection_init(Trustedcerts, Role) -> %%-------------------------------------------------------------------- cache_pem_file(File, DbHandle) -> MD5 = crypto:hash(md5, File), - MD5 = crypto:md5(File), case ssl_pkix_db:lookup_cached_pem(DbHandle, MD5) of [{Content,_}] -> {ok, Content}; diff --git a/lib/ssl/src/tls_connection.erl b/lib/ssl/src/tls_connection.erl index 6a0461e805..246fecf34a 100644 --- a/lib/ssl/src/tls_connection.erl +++ b/lib/ssl/src/tls_connection.erl @@ -673,8 +673,7 @@ certify_client_key_exchange(#encrypted_premaster_secret{premaster_secret= EncPMS certify_client_key_exchange(#client_diffie_hellman_public{dh_public = ClientPublicDhKey}, #state{negotiated_version = Version, - diffie_hellman_params = #'DHParameter'{prime = P, - base = G} = Params, + diffie_hellman_params = #'DHParameter'{} = Params, diffie_hellman_keys = {_, ServerDhPrivateKey}} = State0) -> case dh_master_secret(Params, ClientPublicDhKey, ServerDhPrivateKey, State0) of #state{} = State1 -> diff --git a/lib/ssl/src/tls_handshake.erl b/lib/ssl/src/tls_handshake.erl index fea75736f7..51fd2e1dc9 100644 --- a/lib/ssl/src/tls_handshake.erl +++ b/lib/ssl/src/tls_handshake.erl @@ -866,7 +866,7 @@ handle_ecc_point_fmt_extension(undefined) -> handle_ecc_point_fmt_extension(_) -> #ec_point_formats{ec_point_format_list = [?ECPOINT_UNCOMPRESSED]}. -handle_ecc_curves_extension(Version, undefined) -> +handle_ecc_curves_extension(_Version, undefined) -> undefined; handle_ecc_curves_extension(Version, _) -> #elliptic_curves{elliptic_curve_list = ssl_tls1:ecc_curves(Version)}. |