aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/asn1/src/asn1ct_check.erl35
-rw-r--r--lib/asn1/test/Makefile2
-rw-r--r--lib/asn1/test/asn1_SUITE.erl12
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ChoExtension.asn12
-rw-r--r--lib/asn1/test/asn1_SUITE_data/DefaultOctetString.asn15
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SeqOfChoExt.asn127
-rw-r--r--lib/asn1/test/testChoExtension.erl1
-rw-r--r--lib/asn1/test/testDefaultOctetString.erl34
-rw-r--r--lib/asn1/test/testSeqOfChoExt.erl15
-rw-r--r--lib/compiler/src/Makefile3
-rw-r--r--lib/compiler/src/compile.erl12
-rw-r--r--lib/crypto/c_src/algorithms.c6
-rw-r--r--lib/crypto/c_src/api_ng.c7
-rw-r--r--lib/crypto/c_src/atoms.c12
-rw-r--r--lib/crypto/c_src/atoms.h6
-rw-r--r--lib/crypto/c_src/cipher.c40
-rw-r--r--lib/crypto/c_src/digest.c37
-rw-r--r--lib/crypto/c_src/engine.c10
-rw-r--r--lib/crypto/c_src/hash.c32
-rw-r--r--lib/crypto/c_src/hmac.c4
-rw-r--r--lib/crypto/c_src/openssl_config.h38
-rw-r--r--lib/crypto/doc/src/crypto.xml134
-rw-r--r--lib/crypto/src/crypto.erl170
-rw-r--r--lib/crypto/test/crypto_SUITE.erl15
-rw-r--r--lib/dialyzer/src/Makefile4
-rw-r--r--lib/hipe/cerl/Makefile5
-rw-r--r--lib/hipe/icode/hipe_beam_to_icode.erl18
-rw-r--r--lib/hipe/llvm/Makefile5
-rw-r--r--lib/hipe/main/hipe.erl12
-rw-r--r--lib/hipe/rtl/Makefile5
-rw-r--r--lib/kernel/examples/gen_tcp_dist/Makefile4
-rw-r--r--lib/kernel/examples/gen_tcp_dist/src/gen_tcp_dist.erl15
-rw-r--r--lib/kernel/src/Makefile4
-rw-r--r--lib/kernel/src/global.erl85
-rw-r--r--lib/kernel/test/Makefile6
-rw-r--r--lib/kernel/test/erl_distribution_SUITE.erl317
-rw-r--r--lib/kernel/test/file_SUITE.erl3
-rw-r--r--lib/ssl/doc/src/Makefile1
-rw-r--r--lib/ssl/doc/src/ssl.xml7
-rw-r--r--lib/ssl/doc/src/ssl_app.xml41
-rw-r--r--lib/ssl/doc/src/standards_compliance.xml2312
-rw-r--r--lib/ssl/doc/src/usersguide.xml1
-rw-r--r--lib/ssl/src/dtls_connection.erl2
-rw-r--r--lib/ssl/src/ssl.erl7
-rw-r--r--lib/ssl/src/ssl_internal.hrl7
-rw-r--r--lib/ssl/src/tls_handshake_1_3.erl3
-rw-r--r--lib/ssl/test/ssl_basic_SUITE.erl32
-rw-r--r--lib/ssl/test/ssl_certificate_verify_SUITE.erl1
-rw-r--r--lib/stdlib/src/Makefile4
-rw-r--r--lib/stdlib/test/string_SUITE.erl6
-rw-r--r--lib/tools/emacs/erlang.el2
-rw-r--r--lib/xmerl/doc/src/notes.xml22
-rw-r--r--lib/xmerl/src/xmerl_scan.erl15
-rw-r--r--lib/xmerl/vsn.mk2
54 files changed, 3288 insertions, 329 deletions
diff --git a/lib/asn1/src/asn1ct_check.erl b/lib/asn1/src/asn1ct_check.erl
index 9ec0d93e93..9eec05abd1 100644
--- a/lib/asn1/src/asn1ct_check.erl
+++ b/lib/asn1/src/asn1ct_check.erl
@@ -1710,7 +1710,7 @@ check_value(S,#valuedef{pos=Pos,name=Name,type=Type,
{valueset,
check_type(S,#typedef{pos=Pos,name=Name,typespec=NewType},NewType)};
check_value(S, #valuedef{}=V) ->
- ?dbg("check_value, V: ~p~n",[V0]),
+ ?dbg("check_value, V: ~p~n",[V]),
case V of
#valuedef{checked=true} ->
V;
@@ -1721,7 +1721,8 @@ check_value(S, #valuedef{}=V) ->
check_valuedef(#state{recordtopname=TopName}=S0, V0) ->
#valuedef{name=Name,type=Vtype0,value=Value,module=ModName} = V0,
V = V0#valuedef{checked=true},
- Vtype = check_type(S0, #typedef{name=Name,typespec=Vtype0},Vtype0),
+ Vtype1 = expand_valuedef_type(Vtype0),
+ Vtype = check_type(S0, #typedef{name=Name,typespec=Vtype1},Vtype1),
Def = Vtype#type.def,
S1 = S0#state{tname=Def},
SVal = update_state(S1, ModName),
@@ -1767,6 +1768,27 @@ check_valuedef(#state{recordtopname=TopName}=S0, V0) ->
V#valuedef{value=normalize_value(SVal, Vtype, Value, TopName)}
end.
+expand_valuedef_type(#type{def=Seq}=Type)
+ when is_record(Seq,'SEQUENCE') ->
+ NewComponents = case Seq#'SEQUENCE'.components of
+ {R1,_Ext,R2} -> R1 ++ R2;
+ {Root,_Ext} -> Root;
+ Root -> take_only_rootset(Root)
+ end,
+ NewSeq = Seq#'SEQUENCE'{components = NewComponents},
+ Type#type{def=NewSeq};
+expand_valuedef_type(#type{def=Set}=Type)
+ when is_record(Set,'SET') ->
+ NewComponents = case Set#'SET'.components of
+ {R1,_Ext,R2} -> R1 ++ R2;
+ {Root,_Ext} -> Root;
+ Root -> take_only_rootset(Root)
+ end,
+ NewSet = Set#'SET'{components = NewComponents},
+ Type#type{def=NewSet};
+expand_valuedef_type(Type) ->
+ Type.
+
is_contextswitchtype(#typedef{name='EXTERNAL'})->
true;
is_contextswitchtype(#typedef{name='EMBEDDED PDV'}) ->
@@ -1998,7 +2020,8 @@ normalize_value(S, Type, {'DEFAULT',Value}, NameList) ->
{'ENUMERATED',CType,_} ->
normalize_enumerated(S,Value,CType);
{'CHOICE',CType,NewNameList} ->
- normalize_choice(S,Value,CType,NewNameList);
+ ChoiceComponents = get_choice_components(S, {'CHOICE',CType}),
+ normalize_choice(S,Value,ChoiceComponents,NewNameList);
{'SEQUENCE',CType,NewNameList} ->
normalize_sequence(S,Value,CType,NewNameList);
{'SEQUENCE OF',CType,NewNameList} ->
@@ -2140,6 +2163,9 @@ normalize_octetstring(S, Value) ->
_ ->
asn1_error(S, illegal_octet_string_value)
end;
+ Val when is_binary(Val) ->
+ %% constant default value
+ Val;
_ ->
asn1_error(S, illegal_octet_string_value)
end.
@@ -2751,8 +2777,9 @@ check_type(S=#state{recordtopname=TopName},Type,Ts) when is_record(Ts,type) ->
TempNewDef#newt{type={'SEQUENCE OF',check_sequenceof(S,Type,Components)},
tag=
merge_tags(Tag,?TAG_CONSTRUCTED(?N_SEQUENCE))};
- {'CHOICE',Components} ->
+ {'CHOICE',_} = Choice->
Ct = maybe_illicit_implicit_tag(S, choice, Tag),
+ Components = get_choice_components(S, Choice),
TempNewDef#newt{type={'CHOICE',check_choice(S,Type,Components)},tag=Ct};
Set when is_record(Set,'SET') ->
RecordName=
diff --git a/lib/asn1/test/Makefile b/lib/asn1/test/Makefile
index c38d1c6ebd..6ff4aa8d0f 100644
--- a/lib/asn1/test/Makefile
+++ b/lib/asn1/test/Makefile
@@ -60,6 +60,7 @@ MODULES= \
testSeqOf \
testSeqOfIndefinite \
testSeqOfCho \
+ testSeqOfChoExt \
testSeqOfExternal \
testSeqOfTag \
testSetDefault \
@@ -72,6 +73,7 @@ MODULES= \
testSetTypeRefPrim \
testSetTypeRefSeq \
testSetTypeRefSet \
+ testDefaultOctetString \
testChoiceIndefinite \
testSetOf \
testSetOfCho \
diff --git a/lib/asn1/test/asn1_SUITE.erl b/lib/asn1/test/asn1_SUITE.erl
index ab78678110..a88e464996 100644
--- a/lib/asn1/test/asn1_SUITE.erl
+++ b/lib/asn1/test/asn1_SUITE.erl
@@ -99,6 +99,7 @@ groups() ->
testChoTypeRefPrim,
testChoTypeRefSeq,
testChoTypeRefSet,
+ testDefaultOctetString,
testMultipleLevels,
testOpt,
testSeqDefault,
@@ -118,6 +119,7 @@ groups() ->
{group, [], [testSeqOf,
testSeqOfIndefinite]}, % Uses 'Mvrasn*'
testSeqOfCho,
+ testSeqOfChoExt,
testSetDefault,
testExtensionAdditionGroup,
testSetOptional,
@@ -430,6 +432,11 @@ testChoTypeRefSet(Config, Rule, Opts) ->
asn1_test_lib:compile("ChoTypeRefSet", Config, [Rule|Opts]),
testChoTypeRefSet:set(Rule).
+testDefaultOctetString(Config) -> test(Config, fun testDefaultOctetString/3).
+testDefaultOctetString(Config, Rule, Opts) ->
+ asn1_test_lib:compile("DefaultOctetString", Config, [Rule|Opts]),
+ testDefaultOctetString:dos(Rule).
+
testMultipleLevels(Config) -> test(Config, fun testMultipleLevels/3).
testMultipleLevels(Config, Rule, Opts) ->
asn1_test_lib:compile("MultipleLevels", Config, [Rule|Opts]),
@@ -535,6 +542,11 @@ testSeqOfCho(Config, Rule, Opts) ->
asn1_test_lib:compile("SeqOfCho", Config, [Rule|Opts]),
testSeqOfCho:main(Rule).
+testSeqOfChoExt(Config) -> test(Config, fun testSeqOfChoExt/3).
+testSeqOfChoExt(Config, Rule, Opts) ->
+ asn1_test_lib:compile("SeqOfChoExt", Config, [Rule|Opts]),
+ testSeqOfChoExt:main(Rule).
+
testSeqOfIndefinite(Config) ->
test(Config, fun testSeqOfIndefinite/3, [ber]).
testSeqOfIndefinite(Config, Rule, Opts) ->
diff --git a/lib/asn1/test/asn1_SUITE_data/ChoExtension.asn1 b/lib/asn1/test/asn1_SUITE_data/ChoExtension.asn1
index 18473bae30..c488704196 100644
--- a/lib/asn1/test/asn1_SUITE_data/ChoExtension.asn1
+++ b/lib/asn1/test/asn1_SUITE_data/ChoExtension.asn1
@@ -41,4 +41,6 @@ ChoExt4 ::= CHOICE
str OCTET STRING
}
+choExt1 ChoExt1 ::= int : 1
+
END
diff --git a/lib/asn1/test/asn1_SUITE_data/DefaultOctetString.asn b/lib/asn1/test/asn1_SUITE_data/DefaultOctetString.asn
new file mode 100644
index 0000000000..076e965d58
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/DefaultOctetString.asn
@@ -0,0 +1,15 @@
+DefaultOctetString
+DEFINITIONS
+AUTOMATIC TAGS
+ ::=
+BEGIN
+Dos ::= SEQUENCE {
+ opt [2] OCTET STRING (SIZE(2..4)) OPTIONAL,
+ def [10] OCTET STRING (SIZE (1)) DEFAULT '05'H
+}
+
+dos Dos ::= {
+ opt '1234'H
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/SeqOfChoExt.asn1 b/lib/asn1/test/asn1_SUITE_data/SeqOfChoExt.asn1
new file mode 100644
index 0000000000..51077754fd
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/SeqOfChoExt.asn1
@@ -0,0 +1,27 @@
+SeqOfChoExt DEFINITIONS AUTOMATIC TAGS EXTENSIBILITY IMPLIED ::=
+BEGIN
+
+Seq2 ::= SEQUENCE {
+ octstr [PRIVATE 6] OCTET STRING OPTIONAL
+}
+
+SeqOfCho ::= SEQUENCE OF CHOICE {
+ nullable NULL,
+ seq2 Seq2
+}
+
+Seq1 ::= SEQUENCE {
+ int INTEGER,
+ soc SeqOfCho
+}
+
+seq1 Seq1 ::= {
+ int 10,
+ soc {
+ seq2 : {
+ octstr '01020A'H
+ }
+ }
+}
+
+END
diff --git a/lib/asn1/test/testChoExtension.erl b/lib/asn1/test/testChoExtension.erl
index 4c632aab81..cfb28be5c7 100644
--- a/lib/asn1/test/testChoExtension.erl
+++ b/lib/asn1/test/testChoExtension.erl
@@ -28,6 +28,7 @@
extension(_Rules) ->
roundtrip('ChoExt1', {bool,true}),
roundtrip('ChoExt1', {int,33}),
+ {int, 1} = 'ChoExtension':choExt1(),
%% A trick to encode with another compatible CHOICE type to test reception
%% extension alternative
diff --git a/lib/asn1/test/testDefaultOctetString.erl b/lib/asn1/test/testDefaultOctetString.erl
new file mode 100644
index 0000000000..82cd5810e5
--- /dev/null
+++ b/lib/asn1/test/testDefaultOctetString.erl
@@ -0,0 +1,34 @@
+-module(testDefaultOctetString).
+
+-export([dos/1]).
+
+-include_lib("common_test/include/ct.hrl").
+
+-record('Dos', {
+ opt = asn1_NOVALUE,
+ def = asn1_DEFAULT
+}).
+
+-define(def_DEFAULT, <<5>>).
+
+dos(Rules) ->
+ %% test roundtrip default
+ E1 = roundtrip(#'Dos'{}, #'Dos'{def = ?def_DEFAULT}),
+ %% test the value dos defined in the .asn file
+ E2 = roundtrip('DefaultOctetString':dos()),
+ %% sanity test a fully specified SEQUENCE
+ E3 = roundtrip(#'Dos'{opt = <<1,2,3>>, def = <<6>>}),
+ %% test def is/isn't encoded according to the value
+ if Rules == ber ->
+ <<48, 0>> = E1,
+ <<48, 4, 16#82, 2, 16#12, 16#34>> = E2,
+ <<48, 8, 16#82, 3, 1, 2, 3, 16#8A, 1, 6>> = E3;
+ true ->
+ ignore
+ end,
+ ok.
+
+roundtrip(Value) ->
+ roundtrip(Value, Value).
+roundtrip(Value, Exp) ->
+ asn1_test_lib:roundtrip('DefaultOctetString', 'Dos', Value, Exp).
diff --git a/lib/asn1/test/testSeqOfChoExt.erl b/lib/asn1/test/testSeqOfChoExt.erl
new file mode 100644
index 0000000000..1e72c60841
--- /dev/null
+++ b/lib/asn1/test/testSeqOfChoExt.erl
@@ -0,0 +1,15 @@
+-module(testSeqOfChoExt).
+
+-export([main/1]).
+
+%-record('Seq2', { octstr = asn1_NOVALUE }).
+%-record('Seq1', { int, soc }).
+
+main(_Rules) ->
+ roundtrip('SeqOfChoExt':seq1()).
+
+roundtrip(Value) ->
+ roundtrip(Value, Value).
+roundtrip(Value, Exp) ->
+ Type = element(1,Value),
+ asn1_test_lib:roundtrip('SeqOfChoExt', Type, Value, Exp).
diff --git a/lib/compiler/src/Makefile b/lib/compiler/src/Makefile
index c971e8844d..9f8d63baa1 100644
--- a/lib/compiler/src/Makefile
+++ b/lib/compiler/src/Makefile
@@ -129,9 +129,10 @@ APPUP_TARGET= $(EBIN)/$(APPUP_FILE)
ifeq ($(NATIVE_LIBS_ENABLED),yes)
ERL_COMPILE_FLAGS += +native
+else
+ERL_COMPILE_FLAGS += -Werror
endif
ERL_COMPILE_FLAGS += +inline +warn_unused_import \
- -Werror \
-I../../stdlib/include -I$(EGEN) -W +warn_missing_spec
# ----------------------------------------------------
diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl
index 11dea9524b..28db8986ff 100644
--- a/lib/compiler/src/compile.erl
+++ b/lib/compiler/src/compile.erl
@@ -290,6 +290,10 @@ format_error(bad_crypto_key) ->
"invalid crypto key.";
format_error(no_crypto_key) ->
"no crypto key supplied.";
+format_error({unimplemented_instruction,Instruction}) ->
+ io_lib:fwrite("native-code compilation failed because of an "
+ "unimplemented instruction (~s).",
+ [Instruction]);
format_error({native, E}) ->
io_lib:fwrite("native-code compilation failed with reason: ~tP.",
[E, 25]);
@@ -1651,18 +1655,22 @@ native_compile_1(Code, St) ->
case IgnoreErrors of
true ->
Ws = [{St#compile.ifile,[{none,?MODULE,{native,R}}]}],
- {ok,St#compile{warnings=St#compile.warnings ++ Ws}};
+ {ok,Code,St#compile{warnings=St#compile.warnings ++ Ws}};
false ->
Es = [{St#compile.ifile,[{none,?MODULE,{native,R}}]}],
{error,St#compile{errors=St#compile.errors ++ Es}}
end
catch
+ exit:{unimplemented_instruction,_}=Unimplemented ->
+ Ws = [{St#compile.ifile,
+ [{none,?MODULE,Unimplemented}]}],
+ {ok,Code,St#compile{warnings=St#compile.warnings ++ Ws}};
Class:R:Stack ->
case IgnoreErrors of
true ->
Ws = [{St#compile.ifile,
[{none,?MODULE,{native_crash,R,Stack}}]}],
- {ok,St#compile{warnings=St#compile.warnings ++ Ws}};
+ {ok,Code,St#compile{warnings=St#compile.warnings ++ Ws}};
false ->
erlang:raise(Class, R, Stack)
end
diff --git a/lib/crypto/c_src/algorithms.c b/lib/crypto/c_src/algorithms.c
index 06cd109fc1..1d45ed9df2 100644
--- a/lib/crypto/c_src/algorithms.c
+++ b/lib/crypto/c_src/algorithms.c
@@ -68,9 +68,15 @@ void init_algorithms_types(ErlNifEnv* env)
// Non-validated algorithms follow
algo_hash_fips_cnt = algo_hash_cnt;
+#ifdef HAVE_MD4
algo_hash[algo_hash_cnt++] = enif_make_atom(env, "md4");
+#endif
+#ifdef HAVE_MD5
algo_hash[algo_hash_cnt++] = enif_make_atom(env, "md5");
+#endif
+#ifdef HAVE_RIPEMD160
algo_hash[algo_hash_cnt++] = enif_make_atom(env, "ripemd160");
+#endif
algo_pubkey_cnt = 0;
algo_pubkey[algo_pubkey_cnt++] = enif_make_atom(env, "rsa");
diff --git a/lib/crypto/c_src/api_ng.c b/lib/crypto/c_src/api_ng.c
index 6a833a0984..f4312114ed 100644
--- a/lib/crypto/c_src/api_ng.c
+++ b/lib/crypto/c_src/api_ng.c
@@ -207,7 +207,7 @@ static int get_init_args(ErlNifEnv* env,
goto err;
}
-
+#ifdef HAVE_RC2
if (EVP_CIPHER_type((*cipherp)->cipher.p) == NID_rc2_cbc) {
if (key_bin.size > INT_MAX / 8) {
*return_term = EXCP_BADARG(env, "To large rc2_cbc key");
@@ -218,6 +218,7 @@ static int get_init_args(ErlNifEnv* env,
goto err;
}
}
+#endif
if (ivec_arg == atom_undefined || ivec_len == 0)
{
@@ -346,7 +347,7 @@ ERL_NIF_TERM ng_crypto_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg
ret = enif_make_resource(env, ctx_res);
if(ctx_res) enif_release_resource(ctx_res);
- } else if (enif_get_resource(env, argv[0], evp_cipher_ctx_rtype, (void**)&ctx_res)) {
+ } else if (enif_get_resource(env, argv[0], (ErlNifResourceType*)evp_cipher_ctx_rtype, (void**)&ctx_res)) {
/* Fetch the flag telling if we are going to encrypt (=true) or decrypt (=false) */
if (argv[3] == atom_true)
encflg = 1;
@@ -426,7 +427,7 @@ ERL_NIF_TERM ng_crypto_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
struct evp_cipher_ctx *ctx_res;
ERL_NIF_TERM ret;
- if (!enif_get_resource(env, argv[0], evp_cipher_ctx_rtype, (void**)&ctx_res))
+ if (!enif_get_resource(env, argv[0], (ErlNifResourceType*)evp_cipher_ctx_rtype, (void**)&ctx_res))
return EXCP_BADARG(env, "Bad 1:st arg");
if (argc == 3) {
diff --git a/lib/crypto/c_src/atoms.c b/lib/crypto/c_src/atoms.c
index 114e3c1985..0793ffa6ca 100644
--- a/lib/crypto/c_src/atoms.c
+++ b/lib/crypto/c_src/atoms.c
@@ -52,6 +52,12 @@ ERL_NIF_TERM atom_ecb_mode;
ERL_NIF_TERM atom_cbc_mode;
ERL_NIF_TERM atom_cfb_mode;
ERL_NIF_TERM atom_ofb_mode;
+ERL_NIF_TERM atom_ctr_mode;
+ERL_NIF_TERM atom_gcm_mode;
+ERL_NIF_TERM atom_ccm_mode;
+ERL_NIF_TERM atom_xts_mode;
+ERL_NIF_TERM atom_wrap_mode;
+ERL_NIF_TERM atom_ocb_mode;
ERL_NIF_TERM atom_stream_cipher;
#if defined(HAVE_EC)
@@ -164,6 +170,12 @@ int init_atoms(ErlNifEnv *env, const ERL_NIF_TERM fips_mode, const ERL_NIF_TERM
atom_cbc_mode = enif_make_atom(env,"cbc_mode");
atom_cfb_mode = enif_make_atom(env,"cfb_mode");
atom_ofb_mode = enif_make_atom(env,"ofb_mode");
+ atom_ctr_mode = enif_make_atom(env,"ctr_mode");
+ atom_gcm_mode = enif_make_atom(env,"gcm_mode");
+ atom_ccm_mode = enif_make_atom(env,"ccm_mode");
+ atom_xts_mode = enif_make_atom(env,"xts_mode");
+ atom_wrap_mode = enif_make_atom(env,"wrap_mode");
+ atom_ocb_mode = enif_make_atom(env,"ocb_mode");
atom_stream_cipher = enif_make_atom(env,"stream_cipher");
#if defined(HAVE_EC)
diff --git a/lib/crypto/c_src/atoms.h b/lib/crypto/c_src/atoms.h
index fc46d838aa..24f6dc26fd 100644
--- a/lib/crypto/c_src/atoms.h
+++ b/lib/crypto/c_src/atoms.h
@@ -56,6 +56,12 @@ extern ERL_NIF_TERM atom_ecb_mode;
extern ERL_NIF_TERM atom_cbc_mode;
extern ERL_NIF_TERM atom_cfb_mode;
extern ERL_NIF_TERM atom_ofb_mode;
+extern ERL_NIF_TERM atom_ctr_mode;
+extern ERL_NIF_TERM atom_gcm_mode;
+extern ERL_NIF_TERM atom_ccm_mode;
+extern ERL_NIF_TERM atom_xts_mode;
+extern ERL_NIF_TERM atom_wrap_mode;
+extern ERL_NIF_TERM atom_ocb_mode;
extern ERL_NIF_TERM atom_stream_cipher;
#if defined(HAVE_EC)
diff --git a/lib/crypto/c_src/cipher.c b/lib/crypto/c_src/cipher.c
index 5c57898c50..2652e1db4e 100644
--- a/lib/crypto/c_src/cipher.c
+++ b/lib/crypto/c_src/cipher.c
@@ -28,12 +28,12 @@
static struct cipher_type_t cipher_types[] =
{
-#ifndef OPENSSL_NO_RC2
+#ifdef HAVE_RC2
{{"rc2_cbc"}, {&EVP_rc2_cbc}, 0, NO_FIPS_CIPHER},
#else
{{"rc2_cbc"}, {NULL}, 0, NO_FIPS_CIPHER},
#endif
-#ifndef OPENSSL_NO_RC4
+#ifdef HAVE_RC4
{{"rc4"}, {&EVP_rc4}, 0, NO_FIPS_CIPHER},
#else
{{"rc4"}, {NULL}, 0, NO_FIPS_CIPHER},
@@ -274,6 +274,42 @@ ERL_NIF_TERM cipher_info_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
ret_mode = atom_ofb_mode;
break;
+#ifdef EVP_CIPH_CTR_MODE
+ case EVP_CIPH_CTR_MODE:
+ ret_mode = atom_ctr_mode;
+ break;
+#endif
+
+#ifdef EVP_CIPH_GCM_MODE
+ case EVP_CIPH_GCM_MODE:
+ ret_mode = atom_gcm_mode;
+ break;
+#endif
+
+#ifdef EVP_CIPH_CCM_MODE
+ case EVP_CIPH_CCM_MODE:
+ ret_mode = atom_ccm_mode;
+ break;
+#endif
+
+#ifdef EVP_CIPH_XTS_MODE
+ case EVP_CIPH_XTS_MODE:
+ ret_mode = atom_xts_mode;
+ break;
+#endif
+
+#ifdef EVP_CIPH_WRAP_MODE
+ case EVP_CIPH_WRAP_MODE:
+ ret_mode = atom_wrap_mode;
+ break;
+#endif
+
+#ifdef EVP_CIPH_OCB_MODE
+ case EVP_CIPH_OCB_MODE:
+ ret_mode = atom_ocb_mode;
+ break;
+#endif
+
case EVP_CIPH_STREAM_CIPHER:
ret_mode = atom_stream_cipher;
break;
diff --git a/lib/crypto/c_src/digest.c b/lib/crypto/c_src/digest.c
index fec286c000..c987a664d5 100644
--- a/lib/crypto/c_src/digest.c
+++ b/lib/crypto/c_src/digest.c
@@ -22,10 +22,32 @@
static struct digest_type_t digest_types[] =
{
- {{"md4"}, {&EVP_md4}},
- {{"md5"}, {&EVP_md5}},
- {{"ripemd160"}, {&EVP_ripemd160}},
+ {{"md4"},
+#ifdef HAVE_MD4
+ {&EVP_md4}
+#else
+ {NULL}
+#endif
+ },
+
+ {{"md5"},
+#ifdef HAVE_MD5
+ {&EVP_md5}
+#else
+ {NULL}
+#endif
+ },
+
+ {{"ripemd160"},
+#ifdef HAVE_RIPEMD160
+ {&EVP_ripemd160}
+#else
+ {NULL}
+#endif
+ },
+
{{"sha"}, {&EVP_sha1}},
+
{{"sha224"},
#ifdef HAVE_SHA224
{&EVP_sha224}
@@ -33,6 +55,7 @@ static struct digest_type_t digest_types[] =
{NULL}
#endif
},
+
{{"sha256"},
#ifdef HAVE_SHA256
{&EVP_sha256}
@@ -40,6 +63,7 @@ static struct digest_type_t digest_types[] =
{NULL}
#endif
},
+
{{"sha384"},
#ifdef HAVE_SHA384
{&EVP_sha384}
@@ -47,6 +71,7 @@ static struct digest_type_t digest_types[] =
{NULL}
#endif
},
+
{{"sha512"},
#ifdef HAVE_SHA512
{&EVP_sha512}
@@ -54,6 +79,7 @@ static struct digest_type_t digest_types[] =
{NULL}
#endif
},
+
{{"sha3_224"},
#ifdef HAVE_SHA3_224
{&EVP_sha3_224}
@@ -61,6 +87,7 @@ static struct digest_type_t digest_types[] =
{NULL}
#endif
},
+
{{"sha3_256"},
#ifdef HAVE_SHA3_256
{&EVP_sha3_256}
@@ -68,6 +95,7 @@ static struct digest_type_t digest_types[] =
{NULL}
#endif
},
+
{{"sha3_384"},
#ifdef HAVE_SHA3_384
{&EVP_sha3_384}
@@ -75,6 +103,7 @@ static struct digest_type_t digest_types[] =
{NULL}
#endif
},
+
{{"sha3_512"},
#ifdef HAVE_SHA3_512
{&EVP_sha3_512}
@@ -82,6 +111,7 @@ static struct digest_type_t digest_types[] =
{NULL}
#endif
},
+
{{"blake2b"},
#ifdef HAVE_BLAKE2
{&EVP_blake2b512}
@@ -89,6 +119,7 @@ static struct digest_type_t digest_types[] =
{NULL}
#endif
},
+
{{"blake2s"},
#ifdef HAVE_BLAKE2
{&EVP_blake2s256}
diff --git a/lib/crypto/c_src/engine.c b/lib/crypto/c_src/engine.c
index 7ffbb9e70d..ea5d9a588f 100644
--- a/lib/crypto/c_src/engine.c
+++ b/lib/crypto/c_src/engine.c
@@ -106,15 +106,13 @@ int init_engine_ctx(ErlNifEnv *env) {
(ErlNifResourceDtor*) engine_ctx_dtor,
ERL_NIF_RT_CREATE|ERL_NIF_RT_TAKEOVER,
NULL);
- if (engine_ctx_rtype == NULL)
- goto err;
+ if (engine_ctx_rtype == NULL) {
+ PRINTF_ERR0("CRYPTO: Could not open resource type 'ENGINE_CTX'");
+ return 0;
+ }
#endif
return 1;
-
- err:
- PRINTF_ERR0("CRYPTO: Could not open resource type 'ENGINE_CTX'");
- return 0;
}
ERL_NIF_TERM engine_by_id_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
diff --git a/lib/crypto/c_src/hash.c b/lib/crypto/c_src/hash.c
index 0a9f64acef..9b79258585 100644
--- a/lib/crypto/c_src/hash.c
+++ b/lib/crypto/c_src/hash.c
@@ -21,9 +21,15 @@
#include "hash.h"
#include "digest.h"
-#define MD5_CTX_LEN (sizeof(MD5_CTX))
-#define MD4_CTX_LEN (sizeof(MD4_CTX))
-#define RIPEMD160_CTX_LEN (sizeof(RIPEMD160_CTX))
+#ifdef HAVE_MD5
+# define MD5_CTX_LEN (sizeof(MD5_CTX))
+#endif
+#ifdef HAVE_MD4
+# define MD4_CTX_LEN (sizeof(MD4_CTX))
+#endif
+#ifdef HAVE_RIPEMD160
+# define RIPEMD160_CTX_LEN (sizeof(RIPEMD160_CTX))
+#endif
#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(1,0,0)
struct evp_md_ctx {
@@ -261,18 +267,24 @@ ERL_NIF_TERM hash_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
switch (EVP_MD_type(digp->md.p))
{
+#ifdef HAVE_MD4
case NID_md4:
ctx_size = MD4_CTX_LEN;
ctx_init = (init_fun)(&MD4_Init);
break;
+#endif
+#ifdef HAVE_MD5
case NID_md5:
ctx_size = MD5_CTX_LEN;
ctx_init = (init_fun)(&MD5_Init);
break;
+#endif
+#ifdef HAVE_RIPEMD160
case NID_ripemd160:
ctx_size = RIPEMD160_CTX_LEN;
ctx_init = (init_fun)(&RIPEMD160_Init);
break;
+#endif
case NID_sha1:
ctx_size = sizeof(SHA_CTX);
ctx_init = (init_fun)(&SHA1_Init);
@@ -352,18 +364,24 @@ ERL_NIF_TERM hash_update_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
switch (EVP_MD_type(digp->md.p))
{
+#ifdef HAVE_MD4
case NID_md4:
ctx_size = MD4_CTX_LEN;
ctx_update = (update_fun)(&MD4_Update);
break;
+#endif
+#ifdef HAVE_MD5
case NID_md5:
ctx_size = MD5_CTX_LEN;
ctx_update = (update_fun)(&MD5_Update);
break;
+#endif
+#ifdef HAVE_RIPEMD160
case NID_ripemd160:
ctx_size = RIPEMD160_CTX_LEN;
ctx_update = (update_fun)(&RIPEMD160_Update);
break;
+#endif
case NID_sha1:
ctx_size = sizeof(SHA_CTX);
ctx_update = (update_fun)(&SHA1_Update);
@@ -448,18 +466,24 @@ ERL_NIF_TERM hash_final_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
switch (EVP_MD_type(md))
{
+#ifdef HAVE_MD4
case NID_md4:
ctx_size = MD4_CTX_LEN;
ctx_final = (final_fun)(&MD4_Final);
break;
+#endif
+#ifdef HAVE_MD5
case NID_md5:
ctx_size = MD5_CTX_LEN;
ctx_final = (final_fun)(&MD5_Final);
break;
- case NID_ripemd160:
+#endif
+#ifdef HAVE_RIPEMD160
+ case NID_ripemd160:
ctx_size = RIPEMD160_CTX_LEN;
ctx_final = (final_fun)(&RIPEMD160_Final);
break;
+#endif
case NID_sha1:
ctx_size = sizeof(SHA_CTX);
ctx_final = (final_fun)(&SHA1_Final);
diff --git a/lib/crypto/c_src/hmac.c b/lib/crypto/c_src/hmac.c
index c41e50eb35..ff7005d75e 100644
--- a/lib/crypto/c_src/hmac.c
+++ b/lib/crypto/c_src/hmac.c
@@ -181,7 +181,7 @@ ERL_NIF_TERM hmac_update_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
ASSERT(argc == 2);
- if (!enif_get_resource(env, argv[0], hmac_context_rtype, (void**)&obj))
+ if (!enif_get_resource(env, argv[0], (ErlNifResourceType*)hmac_context_rtype, (void**)&obj))
goto bad_arg;
if (!enif_inspect_iolist_as_binary(env, argv[1], &data))
goto bad_arg;
@@ -224,7 +224,7 @@ ERL_NIF_TERM hmac_final_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
ASSERT(argc == 1 || argc == 2);
- if (!enif_get_resource(env, argv[0], hmac_context_rtype, (void**)&obj))
+ if (!enif_get_resource(env, argv[0], (ErlNifResourceType*)hmac_context_rtype, (void**)&obj))
goto bad_arg;
if (argc == 2) {
if (!enif_get_uint(env, argv[1], &req_len))
diff --git a/lib/crypto/c_src/openssl_config.h b/lib/crypto/c_src/openssl_config.h
index 46868cb987..f926f8af13 100644
--- a/lib/crypto/c_src/openssl_config.h
+++ b/lib/crypto/c_src/openssl_config.h
@@ -166,6 +166,28 @@
# define HAVE_BLAKE2
#endif
+#ifndef OPENSSL_NO_MD4
+# define HAVE_MD4
+#endif
+
+#ifndef OPENSSL_NO_MD5
+# define HAVE_MD5
+#endif
+
+#ifndef OPENSSL_NO_RC2
+# define HAVE_RC2
+#endif
+
+#ifndef OPENSSL_NO_RC4
+# define HAVE_RC4
+#endif
+
+#ifndef OPENSSL_NO_RMD160
+/* Note RMD160 vs RIPEMD160 */
+# define HAVE_RIPEMD160
+#endif
+
+
#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION(0,9,8,'o') \
&& !defined(OPENSSL_NO_EC) \
&& !defined(OPENSSL_NO_ECDH) \
@@ -192,7 +214,9 @@
# define HAVE_AEAD
# define HAVE_GCM
# define HAVE_CCM
-# define HAVE_CMAC
+# ifndef OPENSSL_NO_CMAC
+# define HAVE_CMAC
+# endif
# if defined(RSA_PKCS1_OAEP_PADDING)
# define HAVE_RSA_OAEP_PADDING
# endif
@@ -204,21 +228,27 @@
#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(1,1,0)
# ifndef HAS_LIBRESSL
-# define HAVE_CHACHA20_POLY1305
+# if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
+# define HAVE_CHACHA20_POLY1305
+# endif
# define HAVE_RSA_OAEP_MD
# endif
#endif
#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION(1,1,0,'d')
# ifndef HAS_LIBRESSL
-# define HAVE_CHACHA20
+# ifndef OPENSSL_NO_CHACHA
+# define HAVE_CHACHA20
+# endif
# endif
#endif
// OPENSSL_VERSION_NUMBER >= 1.1.1-pre8
#if OPENSSL_VERSION_NUMBER >= (PACKED_OPENSSL_VERSION_PLAIN(1,1,1)-7)
# ifndef HAS_LIBRESSL
-# define HAVE_POLY1305
+# if !defined(OPENSSL_NO_POLY1305)
+# define HAVE_POLY1305
+# endif
# endif
#endif
diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml
index 83e10c4c78..8a4fad67de 100644
--- a/lib/crypto/doc/src/crypto.xml
+++ b/lib/crypto/doc/src/crypto.xml
@@ -192,7 +192,16 @@
<datatypes>
<datatype_title>Ciphers</datatype_title>
<datatype>
+ <name name="cipher"/>
<name name="stream_cipher"/>
+ <name name="block_cipher"/>
+ <desc>
+ <p>Ciphers known byt the CRYPTO application. Note that this list might be reduced if the
+ underlying libcrypto does not support all of them.</p>
+ </desc>
+ </datatype>
+
+ <datatype>
<name name="stream_cipher_iv"/>
<name name="stream_cipher_no_iv"/>
<desc>
@@ -204,7 +213,7 @@
</datatype>
<datatype>
- <name name="block_cipher_with_iv"/>
+ <name name="block_cipher_iv"/>
<name name="cbc_cipher"/>
<name name="cfb_cipher"/>
<desc>
@@ -228,7 +237,7 @@
</datatype>
<datatype>
- <name name="block_cipher_without_iv"/>
+ <name name="block_cipher_no_iv"/>
<name name="ecb_cipher"/>
<desc>
<p>Block ciphers without initialization vector for
@@ -248,20 +257,16 @@
</desc>
</datatype>
- <datatype_title>Digests</datatype_title>
+ <datatype_title>Digests and hash</datatype_title>
<datatype>
- <name name="sha1"/>
- <name name="sha2"/>
- <name name="sha3"/>
- <name name="blake2"/>
+ <name name="hash_algorithm"/>
<desc>
</desc>
</datatype>
<datatype>
- <name name="compatibility_only_hash"/>
+ <name name="hmac_hash_algorithm"/>
<desc>
- <p>The <c>compatibility_only_hash()</c> algorithms are recommended only for compatibility with existing applications.</p>
</desc>
</datatype>
@@ -283,6 +288,17 @@
</desc>
</datatype>
+ <datatype>
+ <name name="sha1"/>
+ <name name="sha2"/>
+ <name name="sha3"/>
+ <name name="blake2"/>
+ <name name="compatibility_only_hash"/>
+ <desc>
+ <p>The <c>compatibility_only_hash()</c> algorithms are recommended only for compatibility with existing applications.</p>
+ </desc>
+ </datatype>
+
<datatype_title>Elliptic Curves</datatype_title>
<datatype>
<name name="ec_named_curve"/>
@@ -537,6 +553,52 @@
</desc>
</datatype>
+ <datatype_title>Error types</datatype_title>
+
+ <datatype>
+ <name name="run_time_error"/>
+ <desc>
+ <p>The exception <c>error:badarg</c> signifies that one or more arguments are of wrong data type,
+ or are otherwise badly formed.
+ </p>
+ <p>The exception <c>error:notsup</c> signifies that the algorithm is known but is not supported
+ by current underlying libcrypto or explicitly disabled when building that.
+ </p>
+ <p>For a list of supported algorithms, see <seealso marker="#supports-0">supports/0</seealso>.
+ </p>
+ </desc>
+ </datatype>
+
+ <datatype>
+ <name name="descriptive_error"/>
+ <desc>
+ <p>This is a more developed variant of the older
+ <seealso marker="#type-run_time_error">run_time_error()</seealso>.
+ </p>
+ <p>It is like the older type an exception of the <c>error</c> class. In addition they contain
+ a descriptive text in English. That text is targeted to a developer. Examples are "Bad key size"
+ or "Cipher id is not an atom".
+ </p>
+ <p>The exceptions are:</p>
+ <taglist>
+ <tag><c>{badarg, Description::string()}</c></tag>
+ <item><p>Signifies that one or more arguments are of wrong data type or are otherwise badly formed.</p>
+ </item>
+
+ <tag><c>{notsup, Description::string()}</c></tag>
+ <item><p>Signifies that the algorithm is known but is not supported by current underlying libcrypto
+ or explicitly disabled when building that one.</p>
+ </item>
+
+ <tag><c>{error, Description::string()}</c></tag>
+ <item><p>An error condition that should not occur, for example a memory allocation failed or
+ the underlying cryptolib returned an error code, for example "Can't initialize context, step 1".
+ Thoose text usually needs searching the C-code to be understood.</p>
+ </item>
+ </taglist>
+ </desc>
+ </datatype>
+
</datatypes>
<!--================ FUNCTIONS ================-->
@@ -568,17 +630,18 @@
</func>
<func>
- <name since="OTP R16B01">block_encrypt(Type, Key, Ivec, PlainText) -> CipherText</name>
- <name since="OTP R16B01">block_encrypt(AeadType, Key, Ivec, {AAD, PlainText}) -> {CipherText, CipherTag}</name>
- <name since="OTP R16B01">block_encrypt(aes_gcm | aes_ccm, Key, Ivec, {AAD, PlainText, TagLength}) -> {CipherText, CipherTag}</name>
+ <name since="OTP R16B01">block_encrypt(Type, Key, Ivec, PlainText) -> CipherText | Error</name>
+ <name since="OTP R16B01">block_encrypt(AeadType, Key, Ivec, {AAD, PlainText}) -> {CipherText, CipherTag} | Error</name>
+ <name since="OTP R16B01">block_encrypt(aes_gcm | aes_ccm, Key, Ivec, {AAD, PlainText, TagLength}) -> {CipherText, CipherTag} | Error </name>
<fsummary>Encrypt <c>PlainText</c> according to <c>Type</c> block cipher</fsummary>
<type>
- <v>Type = <seealso marker="#type-block_cipher_with_iv">block_cipher_with_iv()</seealso></v>
+ <v>Type = <seealso marker="#type-block_cipher_iv">block_cipher_iv()</seealso></v>
<v>AeadType = <seealso marker="#type-aead_cipher">aead_cipher()</seealso></v>
<v>Key = <seealso marker="#type-key">key()</seealso> | <seealso marker="#type-des3_key">des3_key()</seealso></v>
<v>PlainText = iodata()</v>
<v>AAD = IVec = CipherText = CipherTag = binary()</v>
<v>TagLength = 1..16</v>
+ <v>Error = <seealso marker="#type-run_time_error">run_time_error()</seealso></v>
</type>
<desc>
<p>Encrypt <c>PlainText</c> according to <c>Type</c> block cipher.
@@ -595,15 +658,17 @@
</func>
<func>
- <name since="OTP R16B01">block_decrypt(Type, Key, Ivec, CipherText) -> PlainText</name>
- <name since="OTP R16B01">block_decrypt(AeadType, Key, Ivec, {AAD, CipherText, CipherTag}) -> PlainText | error</name>
+ <name since="OTP R16B01">block_decrypt(Type, Key, Ivec, CipherText) -> PlainText | Error</name>
+ <name since="OTP R16B01">block_decrypt(AeadType, Key, Ivec, {AAD, CipherText, CipherTag}) -> PlainText | Error</name>
<fsummary>Decrypt <c>CipherText</c> according to <c>Type</c> block cipher</fsummary>
<type>
- <v>Type = <seealso marker="#type-block_cipher_with_iv">block_cipher_with_iv()</seealso></v>
+ <v>Type = <seealso marker="#type-block_cipher_iv">block_cipher_iv()</seealso></v>
<v>AeadType = <seealso marker="#type-aead_cipher">aead_cipher()</seealso></v>
<v>Key = <seealso marker="#type-key">key()</seealso> | <seealso marker="#type-des3_key">des3_key()</seealso></v>
<v>PlainText = iodata()</v>
<v>AAD = IVec = CipherText = CipherTag = binary()</v>
+ <v>Error = BadTag | <seealso marker="#type-run_time_error">run_time_error()</seealso></v>
+ <v>BadTag = error</v>
</type>
<desc>
<p>Decrypt <c>CipherText</c> according to <c>Type</c> block cipher.
@@ -844,6 +909,39 @@
</func>
<func>
+ <name name="hash_info" arity="1" since="OTP 22.0"/>
+ <fsummary>Information about supported hash algorithms.</fsummary>
+ <desc>
+ <p>Provides a map with information about block_size, size and possibly other properties of the
+ hash algorithm in question.
+ </p>
+ <p>For a list of supported hash algorithms, see <seealso marker="#supports-0">supports/0</seealso>.
+ </p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="cipher_info" arity="1" since="OTP 22.0"/>
+ <fsummary>Information about supported ciphers.</fsummary>
+ <desc>
+ <p>Provides a map with information about block_size, key_length, iv_length and possibly other properties of the
+ cipher algorithm in question.
+ </p>
+ <note>
+ <p>The ciphers <c>aes_cbc</c>, <c>aes_cfb8</c>, <c>aes_cfb128</c>, <c>aes_ctr</c>,
+ <c>aes_ecb</c>, <c>aes_gcm</c> and <c>aes_ccm</c>
+ has no keylength in the <c>Type</c> as opposed to for example <c>aes_128_ctr</c>. They adapt to the length of
+ the key provided in the encrypt and decrypt function. Therefor it is impossible to return a valid keylength
+ in the map.</p>
+ <p>Always use a <c>Type</c> with an explicit key length,
+ </p>
+ </note>
+ <p>For a list of supported cipher algorithms, see <seealso marker="#supports-0">supports/0</seealso>.
+ </p>
+ </desc>
+ </func>
+
+ <func>
<name name="mod_pow" arity="3" since="OTP R16B01"/>
<fsummary>Computes the function: N^P mod M</fsummary>
<desc>
@@ -1289,8 +1387,8 @@ FloatValue = rand:uniform(). % again
<desc>
<p> Can be used to determine which crypto algorithms that are supported
by the underlying libcrypto library</p>
- <p>Note: the <c>rsa_opts</c> entry is in an experimental state and may change or be removed without notice.
- No guarantee for the accuarcy of the rsa option's value list should be assumed.
+ <p>See <seealso marker="#hash_info-1">hash_info/1</seealso> and <seealso marker="#cipher_info-1">cipher_info/1</seealso>
+ for information about the hash and cipher algorithms.
</p>
</desc>
</func>
diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl
index 5cf34f8069..a5e60fbe75 100644
--- a/lib/crypto/src/crypto.erl
+++ b/lib/crypto/src/crypto.erl
@@ -277,7 +277,13 @@
-type edwards_curve_ed() :: ed25519 | ed448 .
%%%
--type block_cipher_with_iv() :: cbc_cipher()
+-type cipher() :: block_cipher()
+ | stream_cipher()
+ | aead_cipher() .
+
+-type block_cipher() :: block_cipher_iv() | block_cipher_no_iv() .
+
+-type block_cipher_iv() :: cbc_cipher()
| cfb_cipher()
| aes_ige256
| blowfish_ofb64
@@ -310,7 +316,7 @@
| des3_cfb .
--type block_cipher_without_iv() :: ecb_cipher() .
+-type block_cipher_no_iv() :: ecb_cipher() .
-type ecb_cipher() :: des_ecb | blowfish_ecb | aes_ecb .
-type key() :: iodata().
@@ -330,6 +336,20 @@
-type crypto_integer() :: binary() | integer().
+%%%
+%% Exceptions
+%% error:badarg
+%% error:notsup
+-type run_time_error() :: no_return().
+
+%% Exceptions
+%% error:{badarg,Reason::term()}
+%% error:{notsup,Reason::term()}
+%% error:{error,Reason::term()}
+-type descriptive_error() :: no_return() .
+
+
+%%--------------------------------------------------------------------
-compile(no_native).
-on_load(on_load/0).
-define(CRYPTO_NIF_VSN,302).
@@ -368,10 +388,7 @@ stop() ->
| {curves, Curves}
| {rsa_opts, RSAopts},
Hashs :: [sha1() | sha2() | sha3() | blake2() | ripemd160 | compatibility_only_hash()],
- Ciphers :: [stream_cipher()
- | block_cipher_with_iv() | block_cipher_without_iv()
- | aead_cipher()
- ],
+ Ciphers :: [cipher()],
PKs :: [rsa | dss | ecdsa | dh | ecdh | ec_gf2m],
Macs :: [hmac | cmac | poly1305],
Curves :: [ec_named_curve() | edwards_curve_dh() | edwards_curve_ed()],
@@ -405,14 +422,18 @@ enable_fips_mode(_) -> ?nif_stub.
%%%
%%%================================================================
--define(HASH_HASH_ALGORITHM, sha1() | sha2() | sha3() | blake2() | ripemd160 | compatibility_only_hash() ).
-
--spec hash_info(Type) -> map() when Type :: ?HASH_HASH_ALGORITHM.
+-type hash_algorithm() :: sha1() | sha2() | sha3() | blake2() | ripemd160 | compatibility_only_hash() .
+-spec hash_info(Type) -> Result | run_time_error()
+ when Type :: hash_algorithm(),
+ Result :: #{size := integer(),
+ block_size := integer(),
+ type := integer()
+ } .
hash_info(Type) ->
notsup_to_error(hash_info_nif(Type)).
--spec hash(Type, Data) -> Digest when Type :: ?HASH_HASH_ALGORITHM,
+-spec hash(Type, Data) -> Digest when Type :: hash_algorithm(),
Data :: iodata(),
Digest :: binary().
hash(Type, Data) ->
@@ -422,7 +443,7 @@ hash(Type, Data) ->
-opaque hash_state() :: reference().
--spec hash_init(Type) -> State when Type :: ?HASH_HASH_ALGORITHM,
+-spec hash_init(Type) -> State when Type :: hash_algorithm(),
State :: hash_state().
hash_init(Type) ->
notsup_to_error(hash_init_nif(Type)).
@@ -448,12 +469,12 @@ hash_final(Context) ->
%%%---- HMAC
--define(HMAC_HASH_ALGORITHM, sha1() | sha2() | sha3() | compatibility_only_hash()).
+-type hmac_hash_algorithm() :: sha1() | sha2() | sha3() | compatibility_only_hash().
%%%---- hmac/3,4
-spec hmac(Type, Key, Data) ->
- Mac when Type :: ?HMAC_HASH_ALGORITHM,
+ Mac when Type :: hmac_hash_algorithm(),
Key :: iodata(),
Data :: iodata(),
Mac :: binary() .
@@ -462,7 +483,7 @@ hmac(Type, Key, Data) ->
hmac(Type, Key, Data1, undefined, erlang:byte_size(Data1), max_bytes()).
-spec hmac(Type, Key, Data, MacLength) ->
- Mac when Type :: ?HMAC_HASH_ALGORITHM,
+ Mac when Type :: hmac_hash_algorithm(),
Key :: iodata(),
Data :: iodata(),
MacLength :: integer(),
@@ -477,7 +498,7 @@ hmac(Type, Key, Data, MacLength) ->
-opaque hmac_state() :: binary().
-spec hmac_init(Type, Key) ->
- State when Type :: ?HMAC_HASH_ALGORITHM,
+ State when Type :: hmac_hash_algorithm(),
Key :: iodata(),
State :: hmac_state() .
hmac_init(Type, Key) ->
@@ -547,19 +568,53 @@ poly1305(Key, Data) ->
error(E)
end).
--spec cipher_info(Type) -> map() when Type :: block_cipher_with_iv()
- | aead_cipher()
- | block_cipher_without_iv().
+%%%---- Cipher info
+%%%----------------------------------------------------------------
+-spec cipher_info(Type) -> Result | run_time_error()
+ when Type :: cipher(),
+ Result :: #{key_length := integer(),
+ iv_length := integer(),
+ block_size := integer(),
+ mode := CipherModes,
+ type := undefined | integer()
+ },
+ CipherModes :: undefined
+ | cbc_mode
+ | ccm_mode
+ | cfb_mode
+ | ctr_mode
+ | ecb_mode
+ | gcm_mode
+ | ige_mode
+ | ocb_mode
+ | ofb_mode
+ | wrap_mode
+ | xts_mode
+ .
+
+%% These ciphers are not available via the EVP interface on older cryptolibs.
+cipher_info(aes_ctr) ->
+ #{block_size => 1,iv_length => 16,key_length => 32,mode => ctr_mode,type => undefined};
+cipher_info(aes_128_ctr) ->
+ #{block_size => 1,iv_length => 16,key_length => 16,mode => ctr_mode,type => undefined};
+cipher_info(aes_192_ctr) ->
+ #{block_size => 1,iv_length => 16,key_length => 24,mode => ctr_mode,type => undefined};
+cipher_info(aes_256_ctr) ->
+ #{block_size => 1,iv_length => 16,key_length => 32,mode => ctr_mode,type => undefined};
+%% This cipher is handled specialy.
+cipher_info(aes_ige256) ->
+ #{block_size => 16,iv_length => 32,key_length => 16,mode => ige_mode,type => undefined};
cipher_info(Type) ->
- cipher_info_nif(Type).
+ cipher_info_nif(alias(Type)).
%%%---- Block ciphers
%%%----------------------------------------------------------------
--spec block_encrypt(Type::block_cipher_with_iv(), Key::key()|des3_key(), Ivec::binary(), PlainText::iodata()) -> binary();
+-spec block_encrypt(Type::block_cipher_iv(), Key::key()|des3_key(), Ivec::binary(), PlainText::iodata()) ->
+ binary() | run_time_error();
(Type::aead_cipher(), Key::iodata(), Ivec::binary(), {AAD::binary(), PlainText::iodata()}) ->
- {binary(), binary()};
+ {binary(), binary()} | run_time_error();
(aes_gcm | aes_ccm, Key::iodata(), Ivec::binary(), {AAD::binary(), PlainText::iodata(), TagLength::1..16}) ->
- {binary(), binary()}.
+ {binary(), binary()} | run_time_error().
block_encrypt(Type, Key, Ivec, Data) ->
@@ -584,16 +639,19 @@ do_block_encrypt(Type, Key, Ivec, PlainText) ->
?COMPAT(crypto_one_shot(Type, Key, Ivec, PlainText, true)).
--spec block_encrypt(Type::block_cipher_without_iv(), Key::key(), PlainText::iodata()) -> binary().
+-spec block_encrypt(Type::block_cipher_no_iv(), Key::key(), PlainText::iodata()) ->
+ binary() | run_time_error().
block_encrypt(Type, Key, PlainText) ->
?COMPAT(crypto_one_shot(Type, Key, <<>>, PlainText, true)).
%%%----------------------------------------------------------------
%%%----------------------------------------------------------------
--spec block_decrypt(Type::block_cipher_with_iv(), Key::key()|des3_key(), Ivec::binary(), Data::iodata()) -> binary();
+-spec block_decrypt(Type::block_cipher_iv(), Key::key()|des3_key(), Ivec::binary(), Data::iodata()) ->
+ binary() | run_time_error();
(Type::aead_cipher(), Key::iodata(), Ivec::binary(),
- {AAD::binary(), Data::iodata(), Tag::binary()}) -> binary() | error.
+ {AAD::binary(), Data::iodata(), Tag::binary()}) ->
+ binary() | error | run_time_error() .
block_decrypt(Type, Key, Ivec, Data) ->
do_block_decrypt(alias(Type), Key, Ivec, Data).
@@ -610,7 +668,8 @@ do_block_decrypt(Type, Key, Ivec, Data) ->
?COMPAT(crypto_one_shot(Type, Key, Ivec, Data, false)).
--spec block_decrypt(Type::block_cipher_without_iv(), Key::key(), Data::iodata()) -> binary().
+-spec block_decrypt(Type::block_cipher_no_iv(), Key::key(), Data::iodata()) ->
+ binary() | run_time_error().
block_decrypt(Type, Key, Data) ->
?COMPAT(crypto_one_shot(Type, Key, <<>>, Data, false)).
@@ -630,7 +689,7 @@ block_decrypt(Type, Key, Data) ->
| chacha20 .
%%%---- stream_init
--spec stream_init(Type, Key, IVec) -> State | no_return()
+-spec stream_init(Type, Key, IVec) -> State | run_time_error()
when Type :: stream_cipher_iv(),
Key :: iodata(),
IVec ::binary(),
@@ -643,7 +702,7 @@ stream_init(Type, Key, IVec) when is_binary(IVec) ->
{Type, {Ref,flg_undefined}}.
--spec stream_init(Type, Key) -> State | no_return()
+-spec stream_init(Type, Key) -> State | run_time_error()
when Type :: stream_cipher_no_iv(),
Key :: iodata(),
State :: stream_state() .
@@ -655,7 +714,7 @@ stream_init(rc4 = Type, Key) ->
{Type, {Ref,flg_undefined}}.
%%%---- stream_encrypt
--spec stream_encrypt(State, PlainText) -> {NewState, CipherText} | no_return()
+-spec stream_encrypt(State, PlainText) -> {NewState, CipherText} | run_time_error()
when State :: stream_state(),
PlainText :: iodata(),
NewState :: stream_state(),
@@ -664,7 +723,7 @@ stream_encrypt(State, Data) ->
crypto_stream_emulate(State, Data, true).
%%%---- stream_decrypt
--spec stream_decrypt(State, CipherText) -> {NewState, PlainText} | no_return()
+-spec stream_decrypt(State, CipherText) -> {NewState, PlainText} | run_time_error()
when State :: stream_state(),
CipherText :: iodata(),
NewState :: stream_state(),
@@ -723,8 +782,8 @@ next_iv(Type, Data, _Ivec) ->
%%% Create and initialize a new state for encryption or decryption
%%%
--spec crypto_init(Cipher, Key, EncryptFlag) -> State | ng_crypto_error()
- when Cipher :: block_cipher_without_iv()
+-spec crypto_init(Cipher, Key, EncryptFlag) -> State | descriptive_error()
+ when Cipher :: block_cipher_no_iv()
| stream_cipher_no_iv(),
Key :: iodata(),
EncryptFlag :: boolean(),
@@ -734,9 +793,9 @@ crypto_init(Cipher, Key, EncryptFlag) ->
ng_crypto_init_nif(alias(Cipher), iolist_to_binary(Key), <<>>, EncryptFlag).
--spec crypto_init(Cipher, Key, IV, EncryptFlag) -> State | ng_crypto_error()
+-spec crypto_init(Cipher, Key, IV, EncryptFlag) -> State | descriptive_error()
when Cipher :: stream_cipher_iv()
- | block_cipher_with_iv(),
+ | block_cipher_iv(),
Key :: iodata(),
IV :: iodata(),
EncryptFlag :: boolean(),
@@ -747,9 +806,9 @@ crypto_init(Cipher, Key, IV, EncryptFlag) ->
%%%----------------------------------------------------------------
--spec crypto_init_dyn_iv(Cipher, Key, EncryptFlag) -> State | ng_crypto_error()
+-spec crypto_init_dyn_iv(Cipher, Key, EncryptFlag) -> State | descriptive_error()
when Cipher :: stream_cipher_iv()
- | block_cipher_with_iv(),
+ | block_cipher_iv(),
Key :: iodata(),
EncryptFlag :: boolean(),
State :: crypto_state() .
@@ -764,7 +823,7 @@ crypto_init_dyn_iv(Cipher, Key, EncryptFlag) ->
%%% blocksize.
%%%
--spec crypto_update(State, Data) -> Result | ng_crypto_error()
+-spec crypto_update(State, Data) -> Result | descriptive_error()
when State :: crypto_state(),
Data :: iodata(),
Result :: binary() .
@@ -778,7 +837,7 @@ crypto_update(State, Data0) ->
%%%----------------------------------------------------------------
--spec crypto_update_dyn_iv(State, Data, IV) -> Result | ng_crypto_error()
+-spec crypto_update_dyn_iv(State, Data, IV) -> Result | descriptive_error()
when State :: crypto_state(),
Data :: iodata(),
IV :: iodata(),
@@ -798,15 +857,16 @@ crypto_update_dyn_iv(State, Data0, IV) ->
%%% The size must be an integer multiple of the crypto's blocksize.
%%%
--spec crypto_one_shot(Cipher, Key, IV, Data, EncryptFlag) -> Result | ng_crypto_error()
- when Cipher :: stream_cipher()
- | block_cipher_with_iv()
- | block_cipher_without_iv(),
- Key :: iodata(),
- IV :: iodata() | undefined,
- Data :: iodata(),
- EncryptFlag :: boolean(),
- Result :: binary() .
+-spec crypto_one_shot(Cipher, Key, IV, Data, EncryptFlag) ->
+ Result | descriptive_error()
+ when Cipher :: stream_cipher()
+ | block_cipher(),
+ Key :: iodata(),
+ IV :: iodata() | undefined,
+ Data :: iodata(),
+ EncryptFlag :: boolean(),
+ Result :: binary() .
+
crypto_one_shot(Cipher, Key, undefined, Data, EncryptFlag) ->
crypto_one_shot(Cipher, Key, <<>>, Data, EncryptFlag);
@@ -823,21 +883,25 @@ crypto_one_shot(Cipher, Key, IV, Data0, EncryptFlag) ->
%%%----------------------------------------------------------------
%%% NIFs
--type ng_crypto_error() :: no_return() .
+-spec ng_crypto_init_nif(atom(), binary(), binary()|undefined, boolean()|undefined ) ->
+ crypto_state() | descriptive_error()
+ ; (crypto_state(), <<>>, <<>>, boolean())
+ -> crypto_state() | descriptive_error().
--spec ng_crypto_init_nif(atom(), binary(), binary()|undefined, boolean()|undefined ) -> crypto_state() | ng_crypto_error()
- ; (crypto_state(), <<>>, <<>>, boolean()) -> crypto_state() | ng_crypto_error().
ng_crypto_init_nif(_Cipher, _Key, _IVec, _EncryptFlg) -> ?nif_stub.
--spec ng_crypto_update_nif(crypto_state(), binary()) -> binary() | ng_crypto_error() .
+-spec ng_crypto_update_nif(crypto_state(), binary()) ->
+ binary() | descriptive_error() .
ng_crypto_update_nif(_State, _Data) -> ?nif_stub.
--spec ng_crypto_update_nif(crypto_state(), binary(), binary()) -> binary() | ng_crypto_error() .
+-spec ng_crypto_update_nif(crypto_state(), binary(), binary()) ->
+ binary() | descriptive_error() .
ng_crypto_update_nif(_State, _Data, _IV) -> ?nif_stub.
--spec ng_crypto_one_shot_nif(atom(), binary(), binary(), binary(), boolean() ) -> binary() | ng_crypto_error().
+-spec ng_crypto_one_shot_nif(atom(), binary(), binary(), binary(), boolean() ) ->
+ binary() | descriptive_error().
ng_crypto_one_shot_nif(_Cipher, _Key, _IVec, _Data, _EncryptFlg) -> ?nif_stub.
%%%----------------------------------------------------------------
diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl
index 7dbbde68e9..ce5097de47 100644
--- a/lib/crypto/test/crypto_SUITE.erl
+++ b/lib/crypto/test/crypto_SUITE.erl
@@ -323,12 +323,11 @@ end_per_group(_GroupName, Config) ->
init_per_testcase(info, Config) ->
Config;
init_per_testcase(cmac, Config) ->
- case crypto:info_lib() of
- [{<<"OpenSSL">>,LibVer,_}] when is_integer(LibVer), LibVer > 16#10001000 ->
+ case is_supported(cmac) of
+ true ->
Config;
- _Else ->
- % The CMAC functionality was introduced in OpenSSL 1.0.1
- {skip, "OpenSSL is too old"}
+ false ->
+ {skip, "CMAC is not supported"}
end;
init_per_testcase(generate, Config) ->
case proplists:get_value(type, Config) of
@@ -848,7 +847,8 @@ cipher_info(Config) when is_list(Config) ->
#{type := _,key_length := _,iv_length := _,
block_size := _,mode := _} = crypto:cipher_info(aes_128_cbc),
{'EXIT',_} = (catch crypto:cipher_info(not_a_cipher)),
- ok.
+ lists:foreach(fun(C) -> crypto:cipher_info(C) end,
+ proplists:get_value(ciphers, crypto:supports())).
%%--------------------------------------------------------------------
hash_info() ->
@@ -856,7 +856,8 @@ hash_info() ->
hash_info(Config) when is_list(Config) ->
#{type := _,size := _,block_size := _} = crypto:hash_info(sha256),
{'EXIT',_} = (catch crypto:hash_info(not_a_hash)),
- ok.
+ lists:foreach(fun(H) -> crypto:hash_info(H) end,
+ proplists:get_value(hashs, crypto:supports())).
%%--------------------------------------------------------------------
%% Internal functions ------------------------------------------------
diff --git a/lib/dialyzer/src/Makefile b/lib/dialyzer/src/Makefile
index fc08e7ca2f..bddd761705 100644
--- a/lib/dialyzer/src/Makefile
+++ b/lib/dialyzer/src/Makefile
@@ -90,8 +90,10 @@ APPUP_TARGET= $(EBIN)/$(APPUP_FILE)
ifeq ($(NATIVE_LIBS_ENABLED),yes)
ERL_COMPILE_FLAGS += +native
+else
+ERL_COMPILE_FLAGS += -Werror
endif
-ERL_COMPILE_FLAGS += +warn_export_vars +warn_unused_import +warn_untyped_record +warn_missing_spec +warnings_as_errors
+ERL_COMPILE_FLAGS += +warn_export_vars +warn_unused_import +warn_untyped_record +warn_missing_spec
# ----------------------------------------------------
# Targets
diff --git a/lib/hipe/cerl/Makefile b/lib/hipe/cerl/Makefile
index f653dce36f..5c367b5b77 100644
--- a/lib/hipe/cerl/Makefile
+++ b/lib/hipe/cerl/Makefile
@@ -66,7 +66,10 @@ DOC_FILES= $(MODULES:%=$(DOCS)/%.html)
include ../native.mk
-ERL_COMPILE_FLAGS += +inline -Werror +warn_export_vars +warn_unused_import +warn_missing_spec #+warn_untyped_record
+ERL_COMPILE_FLAGS += +inline +warn_export_vars +warn_unused_import +warn_missing_spec #+warn_untyped_record
+ifneq ($(NATIVE_LIBS_ENABLED),yes)
+ERL_COMPILE_FLAGS += -Werror
+endif
# ----------------------------------------------------
# Targets
diff --git a/lib/hipe/icode/hipe_beam_to_icode.erl b/lib/hipe/icode/hipe_beam_to_icode.erl
index ffe81ef9b8..8e7e56b6c4 100644
--- a/lib/hipe/icode/hipe_beam_to_icode.erl
+++ b/lib/hipe/icode/hipe_beam_to_icode.erl
@@ -1189,6 +1189,21 @@ trans_fun([raw_raise|Instructions], Env) ->
[hipe_icode:mk_primop(Dst,raw_raise,Vars) |
trans_fun(Instructions, Env)];
%%--------------------------------------------------------------------
+%% New binary matching added in OTP 22.
+%%--------------------------------------------------------------------
+%%--- bs_get_tail ---
+trans_fun([{bs_get_tail=Name,_,_,_}|_Instructions], _Env) ->
+ nyi(Name);
+%%--- bs_start_match3 ---
+trans_fun([{bs_start_match3=Name,_,_,_,_}|_Instructions], _Env) ->
+ nyi(Name);
+%%--- bs_get_position ---
+trans_fun([{bs_get_position=Name,_,_,_}|_Instructions], _Env) ->
+ nyi(Name);
+%%--- bs_set_position ---
+trans_fun([{bs_set_position=Name,_,_}|_Instructions], _Env) ->
+ nyi(Name);
+%%--------------------------------------------------------------------
%%--- ERROR HANDLING ---
%%--------------------------------------------------------------------
trans_fun([X|_], _) ->
@@ -1196,6 +1211,9 @@ trans_fun([X|_], _) ->
trans_fun([], _) ->
[].
+nyi(Name) ->
+ throw({unimplemented_instruction,Name}).
+
%%--------------------------------------------------------------------
%% trans_call and trans_enter generate correct Icode calls/tail-calls,
%% recognizing explicit fails.
diff --git a/lib/hipe/llvm/Makefile b/lib/hipe/llvm/Makefile
index 817ff67dcd..9f7a2def6d 100644
--- a/lib/hipe/llvm/Makefile
+++ b/lib/hipe/llvm/Makefile
@@ -70,7 +70,10 @@ TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
include ../native.mk
-ERL_COMPILE_FLAGS += -Werror +inline +warn_export_vars #+warn_missing_spec
+ERL_COMPILE_FLAGS += +inline +warn_export_vars #+warn_missing_spec
+ifneq ($(NATIVE_LIBS_ENABLED),yes)
+ERL_COMPILE_FLAGS += -Werror
+endif
# if in 32 bit backend define BIT32 symbol
ifneq ($(BITS64),yes)
diff --git a/lib/hipe/main/hipe.erl b/lib/hipe/main/hipe.erl
index 2348e9b1f6..094b7bc508 100644
--- a/lib/hipe/main/hipe.erl
+++ b/lib/hipe/main/hipe.erl
@@ -583,9 +583,8 @@ fix_beam_exports([], Exports) ->
Exports.
get_beam_icode(Mod, {BeamCode, Exports}, File, Options) ->
- {ok, Icode} =
- ?option_time((catch {ok, hipe_beam_to_icode:module(BeamCode, Options)}),
- "BEAM-to-Icode", Options),
+ Icode = ?option_time(hipe_beam_to_icode:module(BeamCode, Options),
+ "BEAM-to-Icode", Options),
BeamBin = get_beam_code(File),
{{Mod, Exports, Icode}, BeamBin}.
@@ -662,9 +661,12 @@ run_compiler_1(Name, DisasmFun, IcodeFun, Options) ->
{Icode, WholeModule} = IcodeFun(Code, Opts),
CompRes = compile_finish(Icode, WholeModule, Opts),
compiler_return(CompRes, Parent)
- catch error:Error:StackTrace ->
+ catch
+ error:Error:StackTrace ->
print_crash_message(Name, Error, StackTrace),
- exit(Error)
+ exit(Error);
+ throw:{unimplemented_instruction,_Instruction}=Error ->
+ exit(Error)
end
end),
Timeout = case proplists:get_value(timeout, Options) of
diff --git a/lib/hipe/rtl/Makefile b/lib/hipe/rtl/Makefile
index becdd0b7d8..0c0f6e24f5 100644
--- a/lib/hipe/rtl/Makefile
+++ b/lib/hipe/rtl/Makefile
@@ -75,7 +75,10 @@ TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
include ../native.mk
-ERL_COMPILE_FLAGS += -Werror +inline +warn_unused_import +warn_export_vars
+ERL_COMPILE_FLAGS += +inline +warn_unused_import +warn_export_vars
+ifneq ($(NATIVE_LIBS_ENABLED),yes)
+ERL_COMPILE_FLAGS += -Werror
+endif
# ----------------------------------------------------
# Targets
diff --git a/lib/kernel/examples/gen_tcp_dist/Makefile b/lib/kernel/examples/gen_tcp_dist/Makefile
index 65513a1729..0c916835ea 100644
--- a/lib/kernel/examples/gen_tcp_dist/Makefile
+++ b/lib/kernel/examples/gen_tcp_dist/Makefile
@@ -2,9 +2,7 @@ RM=rm -f
CP=cp
EBIN=ebin
ERLC=erlc
-# Works if building in open source source tree
-KERNEL_INCLUDE=$(ERL_TOP)/lib/kernel/include
-ERLCFLAGS+= -W -I$(KERNEL_INCLUDE)
+ERLCFLAGS+= -W
MODULES=gen_tcp_dist
diff --git a/lib/kernel/examples/gen_tcp_dist/src/gen_tcp_dist.erl b/lib/kernel/examples/gen_tcp_dist/src/gen_tcp_dist.erl
index 98554ed805..cda4c470f9 100644
--- a/lib/kernel/examples/gen_tcp_dist/src/gen_tcp_dist.erl
+++ b/lib/kernel/examples/gen_tcp_dist/src/gen_tcp_dist.erl
@@ -53,10 +53,10 @@
-import(error_logger,[error_msg/2]).
--include("net_address.hrl").
+-include_lib("kernel/include/net_address.hrl").
--include("dist.hrl").
--include("dist_util.hrl").
+-include_lib("kernel/include/dist.hrl").
+-include_lib("kernel/include/dist_util.hrl").
%% ------------------------------------------------------------
%% Select this protocol based on node name
@@ -679,7 +679,14 @@ dist_cntrlr_setup_loop(Socket, TickHandler, Sup) ->
%% From now on we execute on normal priority
process_flag(priority, normal),
erlang:dist_ctrl_get_data_notification(DHandle),
- dist_cntrlr_output_loop(DHandle, Socket)
+ case init:get_argument(gen_tcp_dist_output_loop) of
+ error ->
+ dist_cntrlr_output_loop(DHandle, Socket);
+ {ok, [[ModStr, FuncStr]]} -> % For testing...
+ apply(list_to_atom(ModStr),
+ list_to_atom(FuncStr),
+ [DHandle, Socket])
+ end
end.
%% We use active 10 for good throughput while still
diff --git a/lib/kernel/src/Makefile b/lib/kernel/src/Makefile
index 43b776f37e..fcb599859b 100644
--- a/lib/kernel/src/Makefile
+++ b/lib/kernel/src/Makefile
@@ -175,8 +175,10 @@ APPUP_TARGET= $(EBIN)/$(APPUP_FILE)
ifeq ($(NATIVE_LIBS_ENABLED),yes)
ERL_COMPILE_FLAGS += +native
+else
+ERL_COMPILE_FLAGS += -Werror
endif
-ERL_COMPILE_FLAGS += -I../include -Werror
+ERL_COMPILE_FLAGS += -I../include
# ----------------------------------------------------
# Targets
diff --git a/lib/kernel/src/global.erl b/lib/kernel/src/global.erl
index a38522eb5c..3875074d74 100644
--- a/lib/kernel/src/global.erl
+++ b/lib/kernel/src/global.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2019. 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.
@@ -50,10 +50,9 @@
%% This is for backward compatibility only; the functionality is broken.
-define(WARN_DUPLICATED_NAME, global_multi_name_action).
-%% Undocumented Kernel variable. Set this to 0 (zero) to get the old
-%% behaviour.
+%% Undocumented Kernel variable.
-define(N_CONNECT_RETRIES, global_connect_retries).
--define(DEFAULT_N_CONNECT_RETRIES, 5).
+-define(DEFAULT_N_CONNECT_RETRIES, 0).
%%% In certain places in the server, calling io:format hangs everything,
%%% so we'd better use erlang:display/1.
@@ -125,16 +124,12 @@
%%% There are also ETS tables used for bookkeeping of locks and names
%%% (the first position is the key):
%%%
-%%% global_locks (set): {ResourceId, LockRequesterId, [{Pid,RPid,ref()]}
+%%% global_locks (set): {ResourceId, LockRequesterId, [{Pid,ref()]}
%%% Pid is locking ResourceId, ref() is the monitor ref.
-%%% RPid =/= Pid if there is an extra process calling erlang:monitor().
-%%% global_names (set): {Name, Pid, Method, RPid, ref()}
+%%% global_names (set): {Name, Pid, Method, ref()}
%%% Registered names. ref() is the monitor ref.
-%%% RPid =/= Pid if there is an extra process calling erlang:monitor().
%%% global_names_ext (set): {Name, Pid, RegNode}
%%% External registered names (C-nodes).
-%%% (The RPid:s can be removed when/if erlang:monitor() returns before
-%%% trying to connect to the other node.)
%%%
%%% Helper tables:
%%% global_pid_names (bag): {Pid, Name} | {ref(), Name}
@@ -310,7 +305,7 @@ re_register_name(Name, Pid, Method0) when is_pid(Pid) ->
-spec registered_names() -> [Name] when
Name :: term().
registered_names() ->
- MS = ets:fun2ms(fun({Name,_Pid,_M,_RP,_R}) -> Name end),
+ MS = ets:fun2ms(fun({Name,_Pid,_M,_R}) -> Name end),
ets:select(global_names, MS).
%%-----------------------------------------------------------------
@@ -1235,7 +1230,7 @@ ins_name_ext(Name, Pid, Method, RegNode, FromPidOrNode, ExtraInfo, S0) ->
where(Name) ->
case ets:lookup(global_names, Name) of
- [{_Name, Pid, _Method, _RPid, _Ref}] ->
+ [{_Name, Pid, _Method, _Ref}] ->
if node(Pid) == node() ->
case is_process_alive(Pid) of
true -> Pid;
@@ -1272,10 +1267,10 @@ can_set_lock({ResourceId, LockRequesterId}) ->
end.
insert_lock({ResourceId, LockRequesterId}=Id, Pid, PidRefs, S) ->
- {RPid, Ref} = do_monitor(Pid),
+ Ref = erlang:monitor(process, Pid),
true = ets:insert(global_pid_ids, {Pid, ResourceId}),
true = ets:insert(global_pid_ids, {Ref, ResourceId}),
- Lock = {ResourceId, LockRequesterId, [{Pid,RPid,Ref} | PidRefs]},
+ Lock = {ResourceId, LockRequesterId, [{Pid,Ref} | PidRefs]},
true = ets:insert(global_locks, Lock),
trace_message(S, {ins_lock, node(Pid)}, [Id, Pid]).
@@ -1293,10 +1288,9 @@ handle_del_lock({ResourceId, LockReqId}, Pid, S0) ->
_ -> S0
end.
-remove_lock(ResourceId, LockRequesterId, Pid, [{Pid,RPid,Ref}], Down, S0) ->
+remove_lock(ResourceId, LockRequesterId, Pid, [{Pid,Ref}], Down, S0) ->
?trace({remove_lock_1, {id,ResourceId},{pid,Pid}}),
true = erlang:demonitor(Ref, [flush]),
- kill_monitor_proc(RPid, Pid),
true = ets:delete(global_locks, ResourceId),
true = ets:delete_object(global_pid_ids, {Pid, ResourceId}),
true = ets:delete_object(global_pid_ids, {Ref, ResourceId}),
@@ -1309,9 +1303,8 @@ remove_lock(ResourceId, LockRequesterId, Pid, [{Pid,RPid,Ref}], Down, S0) ->
remove_lock(ResourceId, LockRequesterId, Pid, PidRefs0, _Down, S) ->
?trace({remove_lock_2, {id,ResourceId},{pid,Pid}}),
PidRefs = case lists:keyfind(Pid, 1, PidRefs0) of
- {Pid, RPid, Ref} ->
+ {Pid, Ref} ->
true = erlang:demonitor(Ref, [flush]),
- kill_monitor_proc(RPid, Pid),
true = ets:delete_object(global_pid_ids,
{Ref, ResourceId}),
lists:keydelete(Pid, 1, PidRefs0);
@@ -1324,11 +1317,6 @@ remove_lock(ResourceId, LockRequesterId, Pid, PidRefs0, _Down, S) ->
trace_message(S, {rem_lock, node(Pid)},
[{ResourceId, LockRequesterId}, Pid]).
-kill_monitor_proc(Pid, Pid) ->
- ok;
-kill_monitor_proc(RPid, _Pid) ->
- exit(RPid, kill).
-
do_ops(Ops, ConnNode, Names_ext, ExtraInfo, S0) ->
?trace({do_ops, {ops,Ops}}),
@@ -1394,8 +1382,8 @@ sync_other(Node, N) ->
% exit(normal).
insert_global_name(Name, Pid, Method, FromPidOrNode, ExtraInfo, S) ->
- {RPid, Ref} = do_monitor(Pid),
- true = ets:insert(global_names, {Name, Pid, Method, RPid, Ref}),
+ Ref = erlang:monitor(process, Pid),
+ true = ets:insert(global_names, {Name, Pid, Method, Ref}),
true = ets:insert(global_pid_names, {Pid, Name}),
true = ets:insert(global_pid_names, {Ref, Name}),
case lock_still_set(FromPidOrNode, ExtraInfo, S) of
@@ -1437,7 +1425,7 @@ extra_info(Tag, ExtraInfo) ->
del_name(Ref, S) ->
NameL = [Name ||
{_, Name} <- ets:lookup(global_pid_names, Ref),
- {_, _Pid, _Method, _RPid, Ref1} <-
+ {_, _Pid, _Method, Ref1} <-
ets:lookup(global_names, Name),
Ref1 =:= Ref],
case NameL of
@@ -1450,24 +1438,23 @@ del_name(Ref, S) ->
%% Keeps the entry in global_names for whereis_name/1.
delete_global_name_keep_pid(Name, S) ->
case ets:lookup(global_names, Name) of
- [{Name, Pid, _Method, RPid, Ref}] ->
- delete_global_name2(Name, Pid, RPid, Ref, S);
+ [{Name, Pid, _Method, Ref}] ->
+ delete_global_name2(Name, Pid, Ref, S);
[] ->
S
end.
delete_global_name2(Name, S) ->
case ets:lookup(global_names, Name) of
- [{Name, Pid, _Method, RPid, Ref}] ->
+ [{Name, Pid, _Method, Ref}] ->
true = ets:delete(global_names, Name),
- delete_global_name2(Name, Pid, RPid, Ref, S);
+ delete_global_name2(Name, Pid, Ref, S);
[] ->
S
end.
-delete_global_name2(Name, Pid, RPid, Ref, S) ->
+delete_global_name2(Name, Pid, Ref, S) ->
true = erlang:demonitor(Ref, [flush]),
- kill_monitor_proc(RPid, Pid),
delete_global_name(Name, Pid),
?trace({delete_global_name,{item,Name},{pid,Pid}}),
true = ets:delete_object(global_pid_names, {Pid, Name}),
@@ -1929,9 +1916,9 @@ reset_node_state(Node) ->
%% from the same partition.
exchange_names([{Name, Pid, Method} | Tail], Node, Ops, Res) ->
case ets:lookup(global_names, Name) of
- [{Name, Pid, _Method, _RPid2, _Ref2}] ->
+ [{Name, Pid, _Method, _Ref2}] ->
exchange_names(Tail, Node, Ops, Res);
- [{Name, Pid2, Method2, _RPid2, _Ref2}] when node() < Node ->
+ [{Name, Pid2, Method2, _Ref2}] when node() < Node ->
%% Name clash! Add the result of resolving to Res(olved).
%% We know that node(Pid) =/= node(), so we don't
%% need to link/unlink to Pid.
@@ -1960,7 +1947,7 @@ exchange_names([{Name, Pid, Method} | Tail], Node, Ops, Res) ->
Op = {delete, Name},
exchange_names(Tail, Node, [Op | Ops], [Op | Res])
end;
- [{Name, _Pid2, _Method, _RPid, _Ref}] ->
+ [{Name, _Pid2, _Method, _Ref}] ->
%% The other node will solve the conflict.
exchange_names(Tail, Node, Ops, Res);
_ ->
@@ -2036,7 +2023,7 @@ pid_is_locking(Pid, PidRefs) ->
delete_lock(Ref, S0) ->
Locks = pid_locks(Ref),
F = fun({ResourceId, LockRequesterId, PidRefs}, S) ->
- {Pid, _RPid, Ref} = lists:keyfind(Ref, 3, PidRefs),
+ {Pid, Ref} = lists:keyfind(Ref, 2, PidRefs),
remove_lock(ResourceId, LockRequesterId, Pid, PidRefs, true, S)
end,
lists:foldl(F, S0, Locks).
@@ -2046,10 +2033,10 @@ pid_locks(Ref) ->
ets:lookup(global_locks, ResourceId)
end, ets:lookup(global_pid_ids, Ref)),
[Lock || Lock = {_Id, _Req, PidRefs} <- L,
- rpid_is_locking(Ref, PidRefs)].
+ ref_is_locking(Ref, PidRefs)].
-rpid_is_locking(Ref, PidRefs) ->
- lists:keyfind(Ref, 3, PidRefs) =/= false.
+ref_is_locking(Ref, PidRefs) ->
+ lists:keyfind(Ref, 2, PidRefs) =/= false.
handle_nodedown(Node, S) ->
%% DOWN signals from monitors have removed locks and registered names.
@@ -2062,7 +2049,7 @@ handle_nodedown(Node, S) ->
get_names() ->
ets:select(global_names,
- ets:fun2ms(fun({Name, Pid, Method, _RPid, _Ref}) ->
+ ets:fun2ms(fun({Name, Pid, Method, _Ref}) ->
{Name, Pid, Method}
end)).
@@ -2205,24 +2192,6 @@ unexpected_message(Message, What) ->
%%% Utilities
-%% When/if erlang:monitor() returns before trying to connect to the
-%% other node this function can be removed.
-do_monitor(Pid) ->
- case (node(Pid) =:= node()) orelse lists:member(node(Pid), nodes()) of
- true ->
- %% Assume the node is still up
- {Pid, erlang:monitor(process, Pid)};
- false ->
- F = fun() ->
- Ref = erlang:monitor(process, Pid),
- receive
- {'DOWN', Ref, process, Pid, _Info} ->
- exit(normal)
- end
- end,
- erlang:spawn_monitor(F)
- end.
-
intersection(_, []) ->
[];
intersection(L1, L2) ->
diff --git a/lib/kernel/test/Makefile b/lib/kernel/test/Makefile
index d203597fc2..6763a04d9f 100644
--- a/lib/kernel/test/Makefile
+++ b/lib/kernel/test/Makefile
@@ -57,6 +57,7 @@ MODULES= \
prim_file_SUITE \
ram_file_SUITE \
gen_tcp_api_SUITE \
+ gen_tcp_dist \
gen_tcp_echo_SUITE \
gen_tcp_misc_SUITE \
gen_udp_SUITE \
@@ -137,7 +138,10 @@ TARGETS = $(MODULES:%=$(EBIN)/%.$(EMULATOR))
# Targets
# ----------------------------------------------------
-make_emakefile:
+gen_tcp_dist.erl: ../examples/gen_tcp_dist/src/gen_tcp_dist.erl
+ cp $< $@
+
+make_emakefile: $(ERL_FILES)
$(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) '*_SUITE_make' \
> $(EMAKEFILE)
$(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES) \
diff --git a/lib/kernel/test/erl_distribution_SUITE.erl b/lib/kernel/test/erl_distribution_SUITE.erl
index 5a8bbd56c4..8dd4ef1987 100644
--- a/lib/kernel/test/erl_distribution_SUITE.erl
+++ b/lib/kernel/test/erl_distribution_SUITE.erl
@@ -40,7 +40,8 @@
monitor_nodes_errors/1,
monitor_nodes_combinations/1,
monitor_nodes_cleanup/1,
- monitor_nodes_many/1]).
+ monitor_nodes_many/1,
+ dist_ctrl_proc_smoke/1]).
%% Performs the test at another node.
-export([get_socket_priorities/0,
@@ -52,7 +53,7 @@
-export([init_per_testcase/2, end_per_testcase/2]).
--export([start_node/2]).
+-export([dist_cntrlr_output_test/2]).
-export([pinger/1]).
@@ -67,10 +68,11 @@
suite() ->
[{ct_hooks,[ts_install_cth]},
- {timetrap,{minutes,4}}].
+ {timetrap,{minutes,12}}].
all() ->
- [tick, tick_change, nodenames, hostnames, illegal_nodenames,
+ [dist_ctrl_proc_smoke,
+ tick, tick_change, nodenames, hostnames, illegal_nodenames,
connect_node,
hidden_node, setopts,
table_waste, net_setuptime, inet_dist_options_options,
@@ -116,10 +118,12 @@ connect_node(Config) when is_list(Config) ->
ok.
tick(Config) when is_list(Config) ->
- PaDir = filename:dirname(code:which(erl_distribution_SUITE)),
+ run_dist_configs(fun tick/2, Config).
+tick(DCfg, _Config) ->
%% First check that the normal case is OK!
- {ok, Node} = start_node(dist_test, "-pa " ++ PaDir),
+ [Name1, Name2] = get_nodenames(2, dist_test),
+ {ok, Node} = start_node(DCfg, Name1),
rpc:call(Node, erl_distribution_SUITE, tick_cli_test, [node()]),
erlang:monitor_node(Node, true),
@@ -143,14 +147,12 @@ tick(Config) when is_list(Config) ->
%% Set the ticktime on the server node to 100 secs so the server
%% node doesn't tick the client node within the interval ...
- {ok, ServNode} = start_node(dist_test_server,
- "-kernel net_ticktime 100 "
- "-pa " ++ PaDir),
+ {ok, ServNode} = start_node(DCfg, Name2,
+ "-kernel net_ticktime 100"),
rpc:call(ServNode, erl_distribution_SUITE, tick_serv_test, [Node, node()]),
- {ok, _} = start_node(dist_test,
- "-kernel net_ticktime 12 "
- "-pa " ++ PaDir),
+ {ok, Node} = start_node(DCfg, Name1,
+ "-kernel net_ticktime 12"),
rpc:call(Node, erl_distribution_SUITE, tick_cli_test, [ServNode]),
spawn_link(erl_distribution_SUITE, keep_conn, [Node]),
@@ -180,6 +182,9 @@ tick(Config) when is_list(Config) ->
%% Checks that pinging nonexistyent nodes does not waste space in distribution table.
table_waste(Config) when is_list(Config) ->
+ run_dist_configs(fun table_waste/2, Config).
+
+table_waste(DCfg, _Config) ->
{ok, HName} = inet:gethostname(),
F = fun(0,_F) -> [];
(N,F) ->
@@ -189,7 +194,7 @@ table_waste(Config) when is_list(Config) ->
F(N-1,F)
end,
F(256,F),
- {ok, N} = start_node(erl_distribution_300,""),
+ {ok, N} = start_node(DCfg, erl_distribution_300),
stop_node(N),
ok.
@@ -295,13 +300,16 @@ gethostname() ->
%% Test that pinging an illegal nodename does not kill the node.
illegal_nodenames(Config) when is_list(Config) ->
- PaDir = filename:dirname(code:which(erl_distribution_SUITE)),
- {ok, Node}=start_node(illegal_nodenames, "-pa " ++ PaDir),
+ run_dist_configs(fun illegal_nodenames/2, Config).
+
+illegal_nodenames(DCfg, _Config) ->
+ {ok, Node}=start_node(DCfg, illegal_nodenames),
monitor_node(Node, true),
RPid=rpc:call(Node, erlang, spawn,
[?MODULE, pinger, [self()]]),
receive
{RPid, pinged} ->
+ monitor_node(Node, false),
ok;
{nodedown, Node} ->
ct:fail("Remote node died.")
@@ -318,22 +326,25 @@ pinger(Starter) ->
%% Test that you can set the net_setuptime properly.
net_setuptime(Config) when is_list(Config) ->
+ run_dist_configs(fun net_setuptime/2, Config).
+
+net_setuptime(DCfg, _Config) ->
+
%% In this test case, we reluctantly accept shorter times than the given
%% setup time, because the connection attempt can end in a
%% "Host unreachable" error before the timeout fires.
- Res0 = do_test_setuptime("2"),
+ Res0 = do_test_setuptime(DCfg, "2"),
io:format("Res0 = ~p", [Res0]),
true = (Res0 =< 4000),
- Res1 = do_test_setuptime("0.3"),
+ Res1 = do_test_setuptime(DCfg, "0.3"),
io:format("Res1 = ~p", [Res1]),
true = (Res1 =< 500),
ok.
-do_test_setuptime(Setuptime) when is_list(Setuptime) ->
- PaDir = filename:dirname(code:which(?MODULE)),
- {ok, Node} = start_node(dist_setuptime_test, "-pa " ++ PaDir ++
- " -kernel net_setuptime " ++ Setuptime),
+do_test_setuptime(DCfg, Setuptime) when is_list(Setuptime) ->
+ {ok, Node} = start_node(DCfg, dist_setuptime_test,
+ "-kernel net_setuptime " ++ Setuptime),
Res = rpc:call(Node,?MODULE,time_ping,[?DUMMY_NODE]),
stop_node(Node),
Res.
@@ -399,32 +410,36 @@ tick_cli_test1(Node) ->
end.
setopts(Config) when is_list(Config) ->
+ run_dist_configs(fun setopts/2, Config).
+
+setopts(DCfg, _Config) ->
register(setopts_regname, self()),
[N1,N2,N3,N4] = get_nodenames(4, setopts),
- {_N1F,Port1} = start_node_unconnected(N1, ?MODULE, run_remote_test,
+ {_N1F,Port1} = start_node_unconnected(DCfg, N1, ?MODULE, run_remote_test,
["setopts_do", atom_to_list(node()), "1", "ping"]),
0 = wait_for_port_exit(Port1),
- {_N2F,Port2} = start_node_unconnected(N2, ?MODULE, run_remote_test,
+ {_N2F,Port2} = start_node_unconnected(DCfg, N2, ?MODULE, run_remote_test,
["setopts_do", atom_to_list(node()), "2", "ping"]),
0 = wait_for_port_exit(Port2),
{ok, LSock} = gen_tcp:listen(0, [{packet,2}, {active,false}]),
{ok, LTcpPort} = inet:port(LSock),
- {N3F,Port3} = start_node_unconnected(N3, ?MODULE, run_remote_test,
+ {N3F,Port3} = start_node_unconnected(DCfg, N3, ?MODULE, run_remote_test,
["setopts_do", atom_to_list(node()),
"1", integer_to_list(LTcpPort)]),
wait_and_connect(LSock, N3F, Port3),
0 = wait_for_port_exit(Port3),
- {N4F,Port4} = start_node_unconnected(N4, ?MODULE, run_remote_test,
+ {N4F,Port4} = start_node_unconnected(DCfg, N4, ?MODULE, run_remote_test,
["setopts_do", atom_to_list(node()),
"2", integer_to_list(LTcpPort)]),
wait_and_connect(LSock, N4F, Port4),
0 = wait_for_port_exit(Port4),
+ unregister(setopts_regname),
ok.
wait_and_connect(LSock, NodeName, NodePort) ->
@@ -518,9 +533,9 @@ opt_from_nr("2") -> {nodelay, false}.
change_val(true) -> false;
change_val(false) -> true.
-start_node_unconnected(Name, Mod, Func, Args) ->
+start_node_unconnected(DCfg, Name, Mod, Func, Args) ->
FullName = full_node_name(Name),
- CmdLine = mk_node_cmdline(Name,Mod,Func,Args),
+ CmdLine = mk_node_cmdline(DCfg, Name,Mod,Func,Args),
io:format("Starting node ~p: ~s~n", [FullName, CmdLine]),
case open_port({spawn, CmdLine}, [exit_status]) of
Port when is_port(Port) ->
@@ -534,7 +549,7 @@ full_node_name(PreName) ->
atom_to_list(node())),
list_to_atom(atom_to_list(PreName) ++ HostSuffix).
-mk_node_cmdline(Name,Mod,Func,Args) ->
+mk_node_cmdline(DCfg, Name,Mod,Func,Args) ->
Static = "-noinput",
Pa = filename:dirname(code:which(?MODULE)),
Prog = case catch init:get_argument(progname) of
@@ -551,6 +566,7 @@ mk_node_cmdline(Name,Mod,Func,Args) ->
Prog ++ " "
++ Static ++ " "
++ NameSw ++ " " ++ NameStr
+ ++ " " ++ DCfg
++ " -pa " ++ Pa
++ " -env ERL_CRASH_DUMP " ++ Pwd ++ "/erl_crash_dump." ++ NameStr
++ " -setcookie " ++ atom_to_list(erlang:get_cookie())
@@ -560,7 +576,9 @@ mk_node_cmdline(Name,Mod,Func,Args) ->
%% OTP-4255.
tick_change(Config) when is_list(Config) ->
- PaDir = filename:dirname(code:which(?MODULE)),
+ run_dist_configs(fun tick_change/2, Config).
+
+tick_change(DCfg, _Config) ->
[BN, CN] = get_nodenames(2, tick_change),
DefaultTT = net_kernel:get_net_ticktime(),
unchanged = net_kernel:set_net_ticktime(DefaultTT, 60),
@@ -577,14 +595,13 @@ tick_change(Config) when is_list(Config) ->
end,
wait_until(fun () -> 10 == net_kernel:get_net_ticktime() end),
- {ok, B} = start_node(BN, "-kernel net_ticktime 10 -pa " ++ PaDir),
- {ok, C} = start_node(CN, "-kernel net_ticktime 10 -hidden -pa "
- ++ PaDir),
+ {ok, B} = start_node(DCfg, BN, "-kernel net_ticktime 10"),
+ {ok, C} = start_node(DCfg, CN, "-kernel net_ticktime 10 -hidden"),
OTE = process_flag(trap_exit, true),
case catch begin
- run_tick_change_test(B, C, 10, 1, PaDir),
- run_tick_change_test(B, C, 1, 10, PaDir)
+ run_tick_change_test(DCfg, B, C, 10, 1),
+ run_tick_change_test(DCfg, B, C, 1, 10)
end of
{'EXIT', Reason} ->
stop_node(B),
@@ -626,7 +643,7 @@ wait_for_nodedowns(Tester, Ref) ->
end,
wait_for_nodedowns(Tester, Ref).
-run_tick_change_test(B, C, PrevTT, TT, PaDir) ->
+run_tick_change_test(DCfg, B, C, PrevTT, TT) ->
[DN, EN] = get_nodenames(2, tick_change),
Tester = self(),
@@ -640,8 +657,8 @@ run_tick_change_test(B, C, PrevTT, TT, PaDir) ->
wait_for_nodedowns(Tester, Ref)
end,
- {ok, D} = start_node(DN, "-kernel net_ticktime "
- ++ integer_to_list(PrevTT) ++ " -pa " ++ PaDir),
+ {ok, D} = start_node(DCfg, DN, "-kernel net_ticktime "
+ ++ integer_to_list(PrevTT)),
NMA = spawn_link(fun () -> MonitorNodes([B, C, D]) end),
NMB = spawn_link(B, fun () -> MonitorNodes([node(), C, D]) end),
@@ -674,8 +691,8 @@ run_tick_change_test(B, C, PrevTT, TT, PaDir) ->
sleep(7),
change_initiated = rpc:call(C,net_kernel,set_net_ticktime,[TT,10]),
- {ok, E} = start_node(EN, "-kernel net_ticktime "
- ++ integer_to_list(TT) ++ " -pa " ++ PaDir),
+ {ok, E} = start_node(DCfg, EN, "-kernel net_ticktime "
+ ++ integer_to_list(TT)),
NME = spawn_link(E, fun () -> MonitorNodes([node(), B, C, D]) end),
NMA2 = spawn_link(fun () -> MonitorNodes([E]) end),
NMB2 = spawn_link(B, fun () -> MonitorNodes([E]) end),
@@ -735,12 +752,13 @@ run_tick_change_test(B, C, PrevTT, TT, PaDir) ->
%%
%% Basic test of hidden node.
hidden_node(Config) when is_list(Config) ->
- PaDir = filename:dirname(code:which(?MODULE)),
- VArgs = "-pa " ++ PaDir,
- HArgs = "-hidden -pa " ++ PaDir,
- {ok, V} = start_node(visible_node, VArgs),
+ run_dist_configs(fun hidden_node/2, Config).
+
+hidden_node(DCfg, _Config) ->
+ HArgs = "-hidden",
+ {ok, V} = start_node(DCfg, visible_node),
VMN = start_monitor_nodes_proc(V),
- {ok, H} = start_node(hidden_node, HArgs),
+ {ok, H} = start_node(DCfg, hidden_node, HArgs),
%% Connect visible_node -> hidden_node
connect_nodes(V, H),
test_nodes(V, H),
@@ -748,9 +766,9 @@ hidden_node(Config) when is_list(Config) ->
sleep(5),
check_monitor_nodes_res(VMN, H),
stop_node(V),
- {ok, H} = start_node(hidden_node, HArgs),
+ {ok, H} = start_node(DCfg, hidden_node, HArgs),
HMN = start_monitor_nodes_proc(H),
- {ok, V} = start_node(visible_node, VArgs),
+ {ok, V} = start_node(DCfg, visible_node),
%% Connect hidden_node -> visible_node
connect_nodes(H, V),
test_nodes(V, H),
@@ -850,9 +868,9 @@ do_inet_dist_options_options(Prio) ->
"-kernel inet_dist_connect_options "++PriorityString++" "
"-kernel inet_dist_listen_options "++PriorityString,
{ok,Node1} =
- start_node(inet_dist_options_1, InetDistOptions),
+ start_node("", inet_dist_options_1, InetDistOptions),
{ok,Node2} =
- start_node(inet_dist_options_2, InetDistOptions),
+ start_node("", inet_dist_options_2, InetDistOptions),
%%
pong =
rpc:call(Node1, net_adm, ping, [Node2]),
@@ -885,6 +903,9 @@ get_socket_priorities() ->
%%
monitor_nodes_nodedown_reason(Config) when is_list(Config) ->
+ run_dist_configs(fun monitor_nodes_nodedown_reason/2, Config).
+
+monitor_nodes_nodedown_reason(DCfg, _Config) ->
MonNodeState = monitor_node_state(),
ok = net_kernel:monitor_nodes(true),
ok = net_kernel:monitor_nodes(true, [nodedown_reason]),
@@ -892,10 +913,10 @@ monitor_nodes_nodedown_reason(Config) when is_list(Config) ->
Names = get_numbered_nodenames(5, node),
[NN1, NN2, NN3, NN4, NN5] = Names,
- {ok, N1} = start_node(NN1),
- {ok, N2} = start_node(NN2),
- {ok, N3} = start_node(NN3),
- {ok, N4} = start_node(NN4, "-hidden"),
+ {ok, N1} = start_node(DCfg, NN1),
+ {ok, N2} = start_node(DCfg, NN2),
+ {ok, N3} = start_node(DCfg, NN3),
+ {ok, N4} = start_node(DCfg, NN4, "-hidden"),
receive {nodeup, N1} -> ok end,
receive {nodeup, N2} -> ok end,
@@ -925,7 +946,7 @@ monitor_nodes_nodedown_reason(Config) when is_list(Config) ->
ok = net_kernel:monitor_nodes(false, [nodedown_reason]),
- {ok, N5} = start_node(NN5),
+ {ok, N5} = start_node(DCfg, NN5),
stop_node(N5),
receive {nodeup, N5} -> ok end,
@@ -938,11 +959,14 @@ monitor_nodes_nodedown_reason(Config) when is_list(Config) ->
monitor_nodes_complex_nodedown_reason(Config) when is_list(Config) ->
+ run_dist_configs(fun monitor_nodes_complex_nodedown_reason/2, Config).
+
+monitor_nodes_complex_nodedown_reason(DCfg, _Config) ->
MonNodeState = monitor_node_state(),
Me = self(),
ok = net_kernel:monitor_nodes(true, [nodedown_reason]),
[Name] = get_nodenames(1, monitor_nodes_complex_nodedown_reason),
- {ok, Node} = start_node(Name, ""),
+ {ok, Node} = start_node(DCfg, Name, ""),
Pid = spawn(Node,
fun() ->
Me ! {stuff,
@@ -981,16 +1005,19 @@ monitor_nodes_complex_nodedown_reason(Config) when is_list(Config) ->
%%
monitor_nodes_node_type(Config) when is_list(Config) ->
+ run_dist_configs(fun monitor_nodes_node_type/2, Config).
+
+monitor_nodes_node_type(DCfg, _Config) ->
MonNodeState = monitor_node_state(),
ok = net_kernel:monitor_nodes(true),
ok = net_kernel:monitor_nodes(true, [{node_type, all}]),
Names = get_numbered_nodenames(9, node),
[NN1, NN2, NN3, NN4, NN5, NN6, NN7, NN8, NN9] = Names,
- {ok, N1} = start_node(NN1),
- {ok, N2} = start_node(NN2),
- {ok, N3} = start_node(NN3, "-hidden"),
- {ok, N4} = start_node(NN4, "-hidden"),
+ {ok, N1} = start_node(DCfg, NN1),
+ {ok, N2} = start_node(DCfg, NN2),
+ {ok, N3} = start_node(DCfg, NN3, "-hidden"),
+ {ok, N4} = start_node(DCfg, NN4, "-hidden"),
receive {nodeup, N1} -> ok end,
receive {nodeup, N2} -> ok end,
@@ -1014,15 +1041,15 @@ monitor_nodes_node_type(Config) when is_list(Config) ->
receive {nodedown, N4, [{node_type, hidden}]} -> ok end,
ok = net_kernel:monitor_nodes(false, [{node_type, all}]),
- {ok, N5} = start_node(NN5),
+ {ok, N5} = start_node(DCfg, NN5),
receive {nodeup, N5} -> ok end,
stop_node(N5),
receive {nodedown, N5} -> ok end,
ok = net_kernel:monitor_nodes(true, [{node_type, hidden}]),
- {ok, N6} = start_node(NN6),
- {ok, N7} = start_node(NN7, "-hidden"),
+ {ok, N6} = start_node(DCfg, NN6),
+ {ok, N7} = start_node(DCfg, NN7, "-hidden"),
receive {nodeup, N6} -> ok end,
@@ -1037,8 +1064,8 @@ monitor_nodes_node_type(Config) when is_list(Config) ->
ok = net_kernel:monitor_nodes(false, [{node_type, hidden}]),
ok = net_kernel:monitor_nodes(false),
- {ok, N8} = start_node(NN8),
- {ok, N9} = start_node(NN9, "-hidden"),
+ {ok, N8} = start_node(DCfg, NN8),
+ {ok, N9} = start_node(DCfg, NN9, "-hidden"),
receive {nodeup, N8, [{node_type, visible}]} -> ok end,
stop_node(N8),
@@ -1058,6 +1085,9 @@ monitor_nodes_node_type(Config) when is_list(Config) ->
%%
monitor_nodes_misc(Config) when is_list(Config) ->
+ run_dist_configs(fun monitor_nodes_misc/2, Config).
+
+monitor_nodes_misc(DCfg, _Config) ->
MonNodeState = monitor_node_state(),
ok = net_kernel:monitor_nodes(true),
ok = net_kernel:monitor_nodes(true, [{node_type, all}, nodedown_reason]),
@@ -1065,8 +1095,8 @@ monitor_nodes_misc(Config) when is_list(Config) ->
Names = get_numbered_nodenames(3, node),
[NN1, NN2, NN3] = Names,
- {ok, N1} = start_node(NN1),
- {ok, N2} = start_node(NN2, "-hidden"),
+ {ok, N1} = start_node(DCfg, NN1),
+ {ok, N2} = start_node(DCfg, NN2, "-hidden"),
receive {nodeup, N1} -> ok end,
@@ -1092,7 +1122,7 @@ monitor_nodes_misc(Config) when is_list(Config) ->
ok = net_kernel:monitor_nodes(false, [{node_type, all}, nodedown_reason]),
- {ok, N3} = start_node(NN3),
+ {ok, N3} = start_node(DCfg, NN3),
receive {nodeup, N3} -> ok end,
stop_node(N3),
receive {nodedown, N3} -> ok end,
@@ -1107,15 +1137,18 @@ monitor_nodes_misc(Config) when is_list(Config) ->
%% messages from Node and that {nodedown, Node} messages are
%% received after messages from Node.
monitor_nodes_otp_6481(Config) when is_list(Config) ->
+ run_dist_configs(fun monitor_nodes_otp_6481/2, Config).
+
+monitor_nodes_otp_6481(DCfg, Config) ->
io:format("Testing nodedown...~n"),
- monitor_nodes_otp_6481_test(Config, nodedown),
+ monitor_nodes_otp_6481_test(DCfg, Config, nodedown),
io:format("ok~n"),
io:format("Testing nodeup...~n"),
- monitor_nodes_otp_6481_test(Config, nodeup),
+ monitor_nodes_otp_6481_test(DCfg, Config, nodeup),
io:format("ok~n"),
ok.
-monitor_nodes_otp_6481_test(Config, TestType) when is_list(Config) ->
+monitor_nodes_otp_6481_test(DCfg, Config, TestType) when is_list(Config) ->
MonNodeState = monitor_node_state(),
NodeMsg = make_ref(),
Me = self(),
@@ -1164,7 +1197,7 @@ monitor_nodes_otp_6481_test(Config, TestType) when is_list(Config) ->
end
++ MonNodeState,
- {ok, Node} = start_node(Name, "", this),
+ {ok, Node} = start_node(DCfg, Name, "", this),
receive {nodeup, Node} -> ok end,
RemotePid = spawn(Node,
@@ -1249,17 +1282,20 @@ monitor_nodes_errors(Config) when is_list(Config) ->
ok.
monitor_nodes_combinations(Config) when is_list(Config) ->
+ run_dist_configs(fun monitor_nodes_combinations/2, Config).
+
+monitor_nodes_combinations(DCfg, _Config) ->
MonNodeState = monitor_node_state(),
monitor_nodes_all_comb(true),
[VisibleName, HiddenName] = get_nodenames(2,
monitor_nodes_combinations),
- {ok, Visible} = start_node(VisibleName, ""),
+ {ok, Visible} = start_node(DCfg, VisibleName, ""),
receive_all_comb_nodeup_msgs(visible, Visible),
no_msgs(),
stop_node(Visible),
receive_all_comb_nodedown_msgs(visible, Visible, connection_closed),
no_msgs(),
- {ok, Hidden} = start_node(HiddenName, "-hidden"),
+ {ok, Hidden} = start_node(DCfg, HiddenName, "-hidden"),
receive_all_comb_nodeup_msgs(hidden, Hidden),
no_msgs(),
stop_node(Hidden),
@@ -1395,6 +1431,9 @@ monitor_nodes_cleanup(Config) when is_list(Config) ->
ok.
monitor_nodes_many(Config) when is_list(Config) ->
+ run_dist_configs(fun monitor_nodes_many/2, Config).
+
+monitor_nodes_many(DCfg, _Config) ->
MonNodeState = monitor_node_state(),
[Name] = get_nodenames(1, monitor_nodes_many),
%% We want to perform more than 2^16 net_kernel:monitor_nodes
@@ -1402,7 +1441,7 @@ monitor_nodes_many(Config) when is_list(Config) ->
No = (1 bsl 16) + 17,
repeat(fun () -> ok = net_kernel:monitor_nodes(true) end, No),
No = length(monitor_node_state()) - length(MonNodeState),
- {ok, Node} = start_node(Name),
+ {ok, Node} = start_node(DCfg, Name),
repeat(fun () -> receive {nodeup, Node} -> ok end end, No),
stop_node(Node),
repeat(fun () -> receive {nodedown, Node} -> ok end end, No),
@@ -1411,8 +1450,118 @@ monitor_nodes_many(Config) when is_list(Config) ->
MonNodeState = monitor_node_state(),
ok.
+dist_ctrl_proc_smoke(Config) when is_list(Config) ->
+ ThisNode = node(),
+ [Name1, Name2] = get_nodenames(2, dist_ctrl_proc_example_smoke),
+ GetSizeArg = " -gen_tcp_dist_output_loop "
+ ++ atom_to_list(?MODULE) ++ " "
+ ++ "dist_cntrlr_output_test",
+ {ok, Node1} = start_node("", Name1, "-proto_dist gen_tcp"),
+ {ok, Node2} = start_node("", Name2, "-proto_dist gen_tcp" ++ GetSizeArg),
+ pong = rpc:call(Node1, net_adm, ping, [Node2]),
+ NL1 = lists:sort([ThisNode, Node2]),
+ NL2 = lists:sort([ThisNode, Node1]),
+ NL1 = lists:sort(rpc:call(Node1, erlang, nodes, [])),
+ NL2 = lists:sort(rpc:call(Node2, erlang, nodes, [])),
+
+ %% Verify that we actually are executing the distribution
+ %% module we expect and also massage message passing over
+ %% it a bit...
+ Ps1 = rpc:call(Node1, erlang, processes, []),
+ try
+ lists:foreach(
+ fun (P) ->
+ case rpc:call(Node1, erlang, process_info, [P, current_stacktrace]) of
+ undefined ->
+ ok;
+ {current_stacktrace, StkTrace} ->
+ lists:foreach(fun ({gen_tcp_dist,
+ dist_cntrlr_output_loop,
+ 2, _}) ->
+ io:format("~p ~p~n", [P, StkTrace]),
+ throw(found_it);
+ (_) ->
+ ok
+ end, StkTrace)
+ end
+ end, Ps1),
+ exit({missing, dist_cntrlr_output_loop})
+ catch
+ throw:found_it -> ok
+ end,
+
+ Ps2 = rpc:call(Node2, erlang, processes, []),
+ try
+ lists:foreach(
+ fun (P) ->
+ case rpc:call(Node2, erlang, process_info, [P, current_stacktrace]) of
+ undefined ->
+ ok;
+ {current_stacktrace, StkTrace} ->
+ lists:foreach(fun ({erl_distribution_SUITE,
+ dist_cntrlr_output_loop,
+ 2, _}) ->
+ io:format("~p ~p~n", [P, StkTrace]),
+ throw(found_it);
+ (_) ->
+ ok
+ end, StkTrace)
+ end
+ end, Ps2),
+ exit({missing, dist_cntrlr_output_loop})
+ catch
+ throw:found_it -> ok
+ end,
+
+ stop_node(Node1),
+ stop_node(Node2),
+ ok.
+
%% Misc. functions
+run_dist_configs(Func, Config) ->
+ GetSizeArg = " -gen_tcp_dist_output_loop "
+ ++ atom_to_list(?MODULE) ++ " "
+ ++ "dist_cntrlr_output_test",
+ lists:map(fun ({DCfgName, DCfg}) ->
+ io:format("~n~n=== Running ~s configuration ===~n~n",
+ [DCfgName]),
+ Func(DCfg, Config)
+ end,
+ [{"default", ""},
+ {"gen_tcp_dist", "-proto_dist gen_tcp"},
+ {"gen_tcp_dist (get_size)", "-proto_dist gen_tcp" ++ GetSizeArg}]).
+
+dist_cntrlr_output_test(DHandle, Socket) ->
+ false = erlang:dist_ctrl_get_opt(DHandle, get_size),
+ false = erlang:dist_ctrl_set_opt(DHandle, get_size, true),
+ true = erlang:dist_ctrl_get_opt(DHandle, get_size),
+ true = erlang:dist_ctrl_set_opt(DHandle, get_size, false),
+ false = erlang:dist_ctrl_get_opt(DHandle, get_size),
+ false = erlang:dist_ctrl_set_opt(DHandle, get_size, true),
+ true = erlang:dist_ctrl_get_opt(DHandle, get_size),
+ dist_cntrlr_output_loop(DHandle, Socket).
+
+dist_cntrlr_send_data(DHandle, Socket) ->
+ case erlang:dist_ctrl_get_data(DHandle) of
+ none ->
+ erlang:dist_ctrl_get_data_notification(DHandle);
+ {Size, Data} ->
+ Size = erlang:iolist_size(Data),
+ ok = gen_tcp:send(Socket, Data),
+ dist_cntrlr_send_data(DHandle, Socket)
+ end.
+
+dist_cntrlr_output_loop(DHandle, Socket) ->
+ receive
+ dist_data ->
+ %% Outgoing data from this node...
+ dist_cntrlr_send_data(DHandle, Socket);
+ _ ->
+ ok %% Drop garbage message...
+ end,
+ dist_cntrlr_output_loop(DHandle, Socket).
+
monitor_node_state() ->
erts_debug:set_internal_state(available_internal_state, true),
MonitoringNodes = erts_debug:get_internal_state(monitoring_nodes),
@@ -1438,25 +1587,25 @@ print_my_messages() ->
sleep(T) -> receive after T * 1000 -> ok end.
-start_node(Name, Param, this) ->
+start_node(DCfg, Name, Param, this) ->
NewParam = Param ++ " -pa " ++ filename:dirname(code:which(?MODULE)),
test_server:start_node(Name, peer, [{args, NewParam}, {erl, [this]}]);
-start_node(Name, Param, "this") ->
- NewParam = Param ++ " -pa " ++ filename:dirname(code:which(?MODULE)),
+start_node(DCfg, Name, Param, "this") ->
+ NewParam = Param ++ " -pa " ++ filename:dirname(code:which(?MODULE)) ++ " " ++ DCfg,
test_server:start_node(Name, peer, [{args, NewParam}, {erl, [this]}]);
-start_node(Name, Param, Rel) when is_atom(Rel) ->
- NewParam = Param ++ " -pa " ++ filename:dirname(code:which(?MODULE)),
+start_node(DCfg, Name, Param, Rel) when is_atom(Rel) ->
+ NewParam = Param ++ " -pa " ++ filename:dirname(code:which(?MODULE)) ++ " " ++ DCfg,
test_server:start_node(Name, peer, [{args, NewParam}, {erl, [{release, atom_to_list(Rel)}]}]);
-start_node(Name, Param, Rel) when is_list(Rel) ->
- NewParam = Param ++ " -pa " ++ filename:dirname(code:which(?MODULE)),
+start_node(DCfg, Name, Param, Rel) when is_list(Rel) ->
+ NewParam = Param ++ " -pa " ++ filename:dirname(code:which(?MODULE)) ++ " " ++ DCfg,
test_server:start_node(Name, peer, [{args, NewParam}, {erl, [{release, Rel}]}]).
-start_node(Name, Param) ->
- NewParam = Param ++ " -pa " ++ filename:dirname(code:which(?MODULE)),
+start_node(DCfg, Name, Param) ->
+ NewParam = Param ++ " -pa " ++ filename:dirname(code:which(?MODULE)) ++ " " ++ DCfg,
test_server:start_node(Name, slave, [{args, NewParam}]).
-start_node(Name) ->
- start_node(Name, "").
+start_node(DCfg, Name) ->
+ start_node(DCfg, Name, "").
stop_node(Node) ->
test_server:stop_node(Node).
diff --git a/lib/kernel/test/file_SUITE.erl b/lib/kernel/test/file_SUITE.erl
index a51025cba6..711ffccb67 100644
--- a/lib/kernel/test/file_SUITE.erl
+++ b/lib/kernel/test/file_SUITE.erl
@@ -2191,6 +2191,9 @@ unc_paths(Config) when is_list(Config) ->
{ok, _} = file:read_file_info("C:\\Windows\\explorer.exe"),
{ok, _} = file:read_file_info("\\\\localhost\\c$\\Windows\\explorer.exe"),
+ {ok, Files} = file:list_dir("C:\\Windows\\"),
+ {ok, Files} = file:list_dir("\\\\localhost\\c$\\Windows\\"),
+
{ok, Cwd} = file:get_cwd(),
try
diff --git a/lib/ssl/doc/src/Makefile b/lib/ssl/doc/src/Makefile
index 7cf251d8f9..064131944c 100644
--- a/lib/ssl/doc/src/Makefile
+++ b/lib/ssl/doc/src/Makefile
@@ -47,6 +47,7 @@ XML_CHAPTER_FILES = \
ssl_protocol.xml \
using_ssl.xml \
ssl_distribution.xml \
+ standards_compliance.xml \
notes.xml
BOOK_FILES = book.xml
diff --git a/lib/ssl/doc/src/ssl.xml b/lib/ssl/doc/src/ssl.xml
index 37bf9033a1..74a0a0a03e 100644
--- a/lib/ssl/doc/src/ssl.xml
+++ b/lib/ssl/doc/src/ssl.xml
@@ -145,8 +145,13 @@
</datatype>
<datatype>
- <name name="legacy_version"/>
+ <name name="tls_legacy_version"/>
</datatype>
+
+ <datatype>
+ <name name="dtls_legacy_version"/>
+ </datatype>
+
<datatype>
<name name="prf_random"/>
diff --git a/lib/ssl/doc/src/ssl_app.xml b/lib/ssl/doc/src/ssl_app.xml
index 893919aeb4..b05caf44ea 100644
--- a/lib/ssl/doc/src/ssl_app.xml
+++ b/lib/ssl/doc/src/ssl_app.xml
@@ -35,45 +35,10 @@
<description>
<p>
- The ssl application is an implementation of the SSL/TLS/DTLS protocol in Erlang.
+ The ssl application is an implementation of the SSL, TLS and DTLS protocols in Erlang.
</p>
- <list type="bulleted">
- <item>Supported SSL/TLS/DTLS-versions are SSL-3.0, TLS-1.0,
- TLS-1.1, TLS-1.2, DTLS-1.0 (based on TLS-1.1), DTLS-1.2 (based on TLS-1.2)</item>
- <item>For security reasons SSL-2.0 is not supported.
- Interoperability with SSL-2.0 enabled clients dropped. (OTP 21) </item>
- <item>For security reasons SSL-3.0 is no longer supported by default,
- but can be configured. (OTP 19) </item>
- <item>For security reasons RSA key exchange cipher suites are no longer supported by default,
- but can be configured. (OTP 21) </item>
- <item>For security reasons DES cipher suites are no longer supported by default,
- but can be configured. (OTP 20) </item>
- <item>For security reasons 3DES cipher suites are no longer supported by default,
- but can be configured. (OTP 21) </item>
- <item> Renegotiation Indication Extension <url href="http://www.ietf.org/rfc/rfc5746.txt">RFC 5746</url> is supported
- </item>
- <item>Ephemeral Diffie-Hellman cipher suites are supported,
- but not Diffie Hellman Certificates cipher suites.</item>
- <item>Elliptic Curve cipher suites are supported if the Crypto
- application supports it and named curves are used.
- </item>
- <item>Export cipher suites are not supported as the
- U.S. lifted its export restrictions in early 2000.</item>
- <item>IDEA cipher suites are not supported as they have
- become deprecated by the latest TLS specification so it is not
- motivated to implement them.</item>
- <item>Compression is not supported.</item>
- <item>CRL validation is supported.</item>
- <item>Policy certificate extensions are not supported.</item>
- <item>'Server Name Indication' extension
- (<url href="http://www.ietf.org/rfc/rfc6066.txt">RFC 6066</url>) is supported.</item>
- <item>Application Layer Protocol Negotiation (ALPN) and its successor Next Protocol Negotiation (NPN)
- are supported. </item>
- <item>It is possible to use Pre-Shared Key (PSK) and Secure Remote Password (SRP)
- cipher suites, but they are not enabled by default.
- </item>
- </list>
- </description>
+ <p>For current statement of standards compliance see the <seealso marker="standards_compliance">User's Guide</seealso>.</p>
+ </description>
<section>
<title>DEPENDENCIES</title>
diff --git a/lib/ssl/doc/src/standards_compliance.xml b/lib/ssl/doc/src/standards_compliance.xml
new file mode 100644
index 0000000000..c20bab4e50
--- /dev/null
+++ b/lib/ssl/doc/src/standards_compliance.xml
@@ -0,0 +1,2312 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2015</year>
+ <year>2019</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ 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.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>Standards Compliance</title>
+ <prepared>OTP team</prepared>
+ <docno></docno>
+ <date>2019-03-20</date>
+ <rev>A</rev>
+ <file>standards_compliance.xml</file>
+ </header>
+
+ <section>
+ <title>Purpose</title>
+ <p>This section describes the current state of standards compliance of the ssl application.</p>
+ </section>
+
+ <section>
+ <title>Common (pre TLS 1.3)</title>
+ <list type="bulleted">
+ <item>For security reasons RSA key exchange cipher suites are no longer supported by default,
+ but can be configured. (OTP 21)
+ </item>
+ <item>For security reasons DES cipher suites are no longer supported by default,
+ but can be configured. (OTP 20)
+ </item>
+ <item>For security reasons 3DES cipher suites are no longer supported by default,
+ but can be configured. (OTP 21)
+ </item>
+ <item>Renegotiation Indication Extension <url href="http://www.ietf.org/rfc/rfc5746.txt">RFC 5746</url> is supported
+ </item>
+ <item>Ephemeral Diffie-Hellman cipher suites are supported,
+ but not Diffie Hellman Certificates cipher suites.
+ </item>
+ <item>Elliptic Curve cipher suites are supported if the Crypto
+ application supports it and named curves are used.
+ </item>
+ <item>Export cipher suites are not supported as the
+ U.S. lifted its export restrictions in early 2000.
+ </item>
+ <item>IDEA cipher suites are not supported as they have
+ become deprecated by the TLS 1.2 specification so it is not
+ motivated to implement them.
+ </item>
+ <item>Compression is not supported.
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Common</title>
+ <list type="bulleted">
+ <item>CRL validation is supported.</item>
+ <item>Policy certificate extensions are not supported.</item>
+ <item>'Server Name Indication' extension
+ (<url href="http://www.ietf.org/rfc/rfc6066.txt">RFC 6066</url>) is supported.</item>
+ <item>Application Layer Protocol Negotiation (ALPN) and its successor Next Protocol Negotiation (NPN) are supported. </item>
+ <item>It is possible to use Pre-Shared Key (PSK) and Secure Remote Password (SRP)
+ cipher suites, but they are not enabled by default.
+ </item>
+ </list>
+ </section>
+
+
+ <section>
+ <title>SSL 2.0</title>
+ <p>For security reasons SSL-2.0 is not supported. Interoperability with SSL-2.0 enabled clients dropped. (OTP 21)</p>
+ </section>
+
+ <section>
+ <title>SSL 3.0</title>
+ <p>For security reasons SSL-3.0 is no longer supported by default, but can be configured. (OTP 19)</p>
+ </section>
+
+ <section>
+ <title>TLS 1.0</title>
+ <p>For security reasons TLS-1.0 is no longer supported by default, but can be configured. (OTP 22)</p>
+ </section>
+
+ <section>
+ <title>TLS 1.1</title>
+ <p>For security reasons TLS-1.1 is no longer supported by default, but can be configured. (OTP 22)</p>
+ </section>
+
+ <section>
+ <title>TLS 1.2</title>
+ <p>Supported</p>
+ </section>
+
+ <section>
+ <title>DTLS 1.0</title>
+ <p>For security reasons DTLS-1.0 (based on TLS 1.1) is no longer supported by default, but can be configured. (OTP 22)</p>
+ </section>
+
+ <section>
+ <title>DTLS 1.2</title>
+ <p>Supported (based on TLS 1.2)</p>
+ </section>
+
+ <section>
+ <title>DTLS 1.3</title>
+ <p>Not yet supported</p>
+ </section>
+
+ <section>
+ <title>TLS 1.3</title>
+ <p> This section describes the current state of standards compliance for TLS 1.3.</p>
+ <p>(C = Compliant, NC = Non-Compliant, P = Partially-Compliant, NA = Not Applicable)</p>
+ <table>
+ <row>
+ <cell align="left" valign="middle"><em>Section</em></cell>
+ <cell align="left" valign="middle"><em>Feature</em></cell>
+ <cell align="left" valign="middle"><em>State</em></cell>
+ <cell align="left" valign="middle"><em>Since</em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-1.2">
+ 1.3. Updates Affecting TLS 1.2
+ </url>
+ </cell>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">Version downgrade protection mechanism</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">RSASSA-PSS signature schemes</cell>
+ <cell align="left" valign="middle"><em>P</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">supported_versions (ClientHello) extension</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">signature_algorithms_cert extension</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-2">
+ 2. Protocol Overview
+ </url>
+ </cell>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>P</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">(EC)DHE</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">PSK-only</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">PSK with (EC)DHE</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-2.1">
+ 2.1. Incorrect DHE share
+ </url>
+ </cell>
+ <cell align="left" valign="middle">HelloRetryRequest</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-2.2">
+ 2.2. Resumption and Pre-Shared Key (PSK)
+ </url>
+ </cell>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-2.3">
+ 2.3. 0-RTT Data
+ </url>
+ </cell>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.1.1">
+ 4.1.1. Cryptographic Negotiation
+ </url>
+ </cell>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>P</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">supported_groups extension</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">signature_algorithms extension</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">pre_shared_key extension</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.1.2">
+ 4.1.2. Client Hello
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em>Client</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">server_name (RFC6066)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">max_fragment_length (RFC6066)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">status_request (RFC6066)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">supported_groups (RFC7919)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">signature_algorithms (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">use_srtp (RFC5764)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">heartbeat (RFC6520)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">application_layer_protocol_negotiation (RFC7301)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">signed_certificate_timestamp (RFC6962)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">client_certificate_type (RFC7250)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">server_certificate_type (RFC7250)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">padding (RFC7685)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">key_share (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">pre_shared_key (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">psk_key_exchange_modes (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">early_data (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">cookie (RFC8446) </cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">supported_versions (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">certificate_authorities (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">oid_filters (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">post_handshake_auth (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">signature_algorithms_cert (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>Server</em></cell>
+ <cell align="left" valign="middle"><em>PC</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">server_name (RFC6066)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">max_fragment_length (RFC6066)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">status_request (RFC6066)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">supported_groups (RFC7919)</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">signature_algorithms (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">use_srtp (RFC5764)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">heartbeat (RFC6520)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">application_layer_protocol_negotiation (RFC7301)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">signed_certificate_timestamp (RFC6962)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">client_certificate_type (RFC7250)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">server_certificate_type (RFC7250)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">padding (RFC7685)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">key_share (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">pre_shared_key (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">psk_key_exchange_modes (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">early_data (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">cookie (RFC8446) </cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">supported_versions (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">certificate_authorities (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">oid_filters (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">post_handshake_auth (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">signature_algorithms_cert (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.1.3">
+ 4.1.3. Server Hello
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em>Client</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">Version downgrade protection</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">key_share (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">pre_shared_key (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">supported_versions (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>Server</em></cell>
+ <cell align="left" valign="middle"><em>PC</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">Version downgrade protection</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">key_share (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">pre_shared_key (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">supported_versions (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.1.4">
+ 4.1.4. Hello Retry Request
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em>Server</em></cell>
+ <cell align="left" valign="middle"><em>PC</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">key_share (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">cookie (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">supported_versions (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.2.1">
+ 4.2.1. Supported Versions
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em>Client</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>Server</em></cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.2.2">
+ 4.2.2. Cookie
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em>Client</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>Server</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.2.3">
+ 4.2.3. Signature Algorithms
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em>Client</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">rsa_pkcs1_sha256</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">rsa_pkcs1_sha384</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">rsa_pkcs1_sha512</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">ecdsa_secp256r1_sha256</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">ecdsa_secp384r1_sha384</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">ecdsa_secp521r1_sha512</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">rsa_pss_rsae_sha256</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">rsa_pss_rsae_sha384</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">rsa_pss_rsae_sha512</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">ed25519</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">ed448</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">rsa_pss_pss_sha256</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">rsa_pss_pss_sha384</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">rsa_pss_pss_sha512</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">rsa_pkcs1_sha1</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">ecdsa_sha1</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>Server</em></cell>
+ <cell align="left" valign="middle"><em>P</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">rsa_pkcs1_sha256</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">rsa_pkcs1_sha384</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">rsa_pkcs1_sha512</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">ecdsa_secp256r1_sha256</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">ecdsa_secp384r1_sha384</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">ecdsa_secp521r1_sha512</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">rsa_pss_rsae_sha256</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">rsa_pss_rsae_sha384</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">rsa_pss_rsae_sha512</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">ed25519</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">ed448</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">rsa_pss_pss_sha256</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">rsa_pss_pss_sha384</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">rsa_pss_pss_sha512</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">rsa_pkcs1_sha1</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">ecdsa_sha1</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.2.4">
+ 4.2.4. Certificate Authorities
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em>Client</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>Server</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.2.5">
+ 4.2.5. OID Filters
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em>Client</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>Server</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.2.6">
+ 4.2.6. Post-Handshake Client Authentication
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em>Client</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>Server</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.2.7">
+ 4.2.7. Supported Groups
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em>Client</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">secp256r1</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">secp384r1</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">secp521r1</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">x25519</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">x448</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">ffdhe2048</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">ffdhe3072</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">ffdhe4096</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">ffdhe6144</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">ffdhe8192</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>Server</em></cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">secp256r1</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">secp384r1</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">secp521r1</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">x25519</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">x448</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">ffdhe2048</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">ffdhe3072</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">ffdhe4096</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">ffdhe6144</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">ffdhe8192</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.2.8">
+ 4.2.8. Key Share
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em>Client</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>Server</em></cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.2.9">
+ 4.2.9. Pre-Shared Key Exchange Modes
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em>Client</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>Server</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.2.10">
+ 4.2.10. Early Data Indication
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em>Client</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>Server</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.2.11">
+ 4.2.11. Pre-Shared Key Extension
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em>Client</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>Server</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.2.11.1">
+ 4.2.11.1. Ticket Age
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em>Client</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>Server</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.2.11.2">
+ 4.2.11.2. PSK Binder
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em>Client</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>Server</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.2.11.3">
+ 4.2.11.3. Processing Order
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em>Client</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>Server</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.3.1">
+ 4.3.1. Encrypted Extensions
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em>Client</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">server_name (RFC6066)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">max_fragment_length (RFC6066)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">supported_groups (RFC7919)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">use_srtp (RFC5764)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">heartbeat (RFC6520)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">application_layer_protocol_negotiation (RFC7301)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">client_certificate_type (RFC7250)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">server_certificate_type (RFC7250)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">early_data (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">supported_versions (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>Server</em></cell>
+ <cell align="left" valign="middle"><em>P</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">server_name (RFC6066)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">max_fragment_length (RFC6066)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">supported_groups (RFC7919)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">use_srtp (RFC5764)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">heartbeat (RFC6520)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">application_layer_protocol_negotiation (RFC7301)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">client_certificate_type (RFC7250)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">server_certificate_type (RFC7250)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">early_data (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">supported_versions (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.3.2">
+ 4.3.2. Certificate Request
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em>Client</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">status_request (RFC6066)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">signature_algorithms (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">signed_certificate_timestamp (RFC6962)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">certificate_authorities (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">oid_filters (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">signature_algorithms_cert (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>Server</em></cell>
+ <cell align="left" valign="middle"><em>P</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">status_request (RFC6066)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">signature_algorithms (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">signed_certificate_timestamp (RFC6962)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">certificate_authorities (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">oid_filters (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">signature_algorithms_cert (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.4.1">
+ 4.4.1. The Transcript Hash
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.4.2">
+ 4.4.2. Certificate
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em>Client</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">status_request (RFC6066)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">signed_certificate_timestamp (RFC6962)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>Server</em></cell>
+ <cell align="left" valign="middle"><em>P</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">status_request (RFC6066)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">signed_certificate_timestamp (RFC6962)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.4.2.1">
+ 4.4.2.1. OCSP Status and SCT Extensions
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em>Client</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>Server</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.4.2.2">
+ 4.4.2.2. Server Certificate Selection
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em>Client</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">certificate type MUST be X.509v3</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">certificate's public key is compatible</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">The certificate MUST allow the key to be used for signing</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">server_name and certificate_authorities are used</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>Server</em></cell>
+ <cell align="left" valign="middle"><em>P</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">certificate type MUST be X.509v3</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">certificate's public key is compatible</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">The certificate MUST allow the key to be used for signing</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">server_name and certificate_authorities are used</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.4.2.3">
+ 4.4.2.3. Client Certificate Selection
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.4.2.4">
+ 4.4.2.4. Receiving a Certificate Message
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em>Client</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>Server</em></cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.4.3">
+ 4.4.3. Certificate Verify
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em>Client</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>Server</em></cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.4.4">
+ 4.4.4. Finished
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em>Client</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>Server</em></cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.5">
+ 4.5. End of Early Data
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em>Client</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>Server</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.6.1">
+ 4.6.1. New Session Ticket Message
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em>Client</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">early_data (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>Server</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">early_data (RFC8446)</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.6.2">
+ 4.6.2. Post-Handshake Authentication
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em>Client</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>Server</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-4.6.3">
+ 4.6.3. Key and Initialization Vector Update
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em>Client</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>Server</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-5.1">
+ 5.1. Record Layer
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">MUST NOT be interleaved with other record types</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">MUST NOT span key changes</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">MUST NOT send zero-length fragments</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">Alert messages MUST NOT be fragmented</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-5.2">
+ 5.2. Record Payload Protection
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-5.3">
+ 5.3. Per-Record Nonce
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-5.4">
+ 5.4. Record Padding
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ <cell align="left" valign="middle"><em>P</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">MAY choose to pad</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">MUST NOT send Handshake and Alert records that have a zero-length TLSInnerPlaintext.content</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">The padding sent is automatically verified</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-5.5">
+ 5.5. Limits on Key Usage
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-6.1">
+ 6.1. Closure Alerts
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">close_notify</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">user_cancelled</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-6.2">
+ 6.2. Error Alerts
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ <cell align="left" valign="middle"><em>PC</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-7.1">
+ 7.1. Key Schedule
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-7.2">
+ 7.2. Updating Traffic Secrets
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-7.3">
+ 7.3. Traffic Key Calculation
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-7.5">
+ 7.5. Exporters
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-8">
+ 8. 0-RTT and Anti-Replay
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-8.1">
+ 8.1. Single-Use Tickets
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-8.2">
+ 8.2. Client Hello Recording
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-8.3">
+ 8.3. Freshness Checks
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-9.1">
+ 9.1. Mandatory-to-Implement Cipher Suites
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ <cell align="left" valign="middle"><em>P</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">MUST implement the TLS_AES_128_GCM_SHA256</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">SHOULD implement the TLS_AES_256_GCM_SHA384</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">SHOULD implement the TLS_CHACHA20_POLY1305_SHA256</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>Digital signatures</em></cell>
+ <cell align="left" valign="middle"><em>P</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">MUST support rsa_pkcs1_sha256 (for certificates)</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">MUST support rsa_pss_rsae_sha256 (for CertificateVerify and certificates)</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">MUST support ecdsa_secp256r1_sha256</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>Key Exchange</em></cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">MUST support key exchange with secp256r1</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">SHOULD support key exchange with X25519</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-9.2">
+ 9.2. Mandatory-to-Implement Extensions
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ <cell align="left" valign="middle"><em>P</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">Supported Versions</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">Cookie</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">Signature Algorithms</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">Signature Algorithms Certificate</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">Negotiated Groups</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">Key Share</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">Server Name Indication</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>MUST send and use these extensions</em></cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">"supported_versions" is REQUIRED for ClientHello, ServerHello and HelloRetryRequest</cell>
+ <cell align="left" valign="middle"><em>PC</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">"signature_algorithms" is REQUIRED for certificate authentication</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">"supported_groups" is REQUIRED for ClientHello messages using (EC)DHE key exchange</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">"key_share" is REQUIRED for (EC)DHE key exchange</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">"pre_shared_key" is REQUIRED for PSK key agreement</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">"psk_key_exchange_modes" is REQUIRED for PSK key agreement</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>TLS 1.3 ClientHello</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">If not containing a "pre_shared_key" extension, it MUST contain both a "signature_algorithms" extension and a "supported_groups" extension.</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">If containing a "supported_groups" extension, it MUST also contain a "key_share" extension, and vice versa. An empty KeyShare.client_shares vector is permitted.</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>TLS 1.3 ServerHello</em></cell>
+ <cell align="left" valign="middle"><em>P</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">MUST support the use of the "server_name" extension</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-9.3">
+ 9.3. Protocol Invariants
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle"><em>MUST correctly handle extensible fields</em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">A client sending a ClientHello MUST support all parameters advertised in it.</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">A middlebox which terminates a TLS connection MUST behave as a compliant TLS server</cell>
+ <cell align="left" valign="middle"><em>NA</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">A middlebox which forwards ClientHello parameters it does not understand MUST NOT process any messages beyond that ClientHello.</cell>
+ <cell align="left" valign="middle"><em>NA</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-B.4">
+ B.4. Cipher Suites
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ <cell align="left" valign="middle"><em>P</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">TLS_AES_128_GCM_SHA256</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">TLS_AES_256_GCM_SHA384</cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle">22</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">TLS_CHACHA20_POLY1305_SHA256</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">TLS_AES_128_CCM_SHA256</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">TLS_AES_128_CCM_8_SHA256</cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-C.1">
+ C.1. Random Number Generation and Seeding
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-C.2">
+ C.2. Certificates and Authentication
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-C.3">
+ C.3. Implementation Pitfalls
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ <cell align="left" valign="middle"><em>P</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-C.4">
+ C.4. Client Tracking Prevention
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-C.5">
+ C.5. Unauthenticated Operation
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-D.1">
+ D.1. Negotiating with an Older Server
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-D.2">
+ D.2. Negotiating with an Older Client
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-D.3">
+ D.3. 0-RTT Backward Compatibility
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ <cell align="left" valign="middle"><em>NC</em></cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-D.4">
+ D.4. Middlebox Compatibility Mode
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ <cell align="left" valign="middle"><em>P</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+
+ <row>
+ <cell align="left" valign="middle">
+ <url href="https://tools.ietf.org/html/rfc8446#section-D.5">
+ D.5. Security Restrictions Related to Backward Compatibility
+ </url>
+ </cell>
+ <cell align="left" valign="middle"><em></em></cell>
+ <cell align="left" valign="middle"><em>C</em></cell>
+ <cell align="left" valign="middle"><em>22</em></cell>
+ </row>
+
+ <tcaption>Standards Compliance</tcaption>
+ </table>
+
+ </section>
+
+</chapter>
diff --git a/lib/ssl/doc/src/usersguide.xml b/lib/ssl/doc/src/usersguide.xml
index 23ccf668c3..b22b2456e4 100644
--- a/lib/ssl/doc/src/usersguide.xml
+++ b/lib/ssl/doc/src/usersguide.xml
@@ -38,6 +38,7 @@
<xi:include href="ssl_protocol.xml"/>
<xi:include href="using_ssl.xml"/>
<xi:include href="ssl_distribution.xml"/>
+ <xi:include href="standards_compliance.xml"/>
</part>
diff --git a/lib/ssl/src/dtls_connection.erl b/lib/ssl/src/dtls_connection.erl
index ed47980a69..30b2ab7c4f 100644
--- a/lib/ssl/src/dtls_connection.erl
+++ b/lib/ssl/src/dtls_connection.erl
@@ -840,7 +840,7 @@ next_dtls_record(Data, StateName, #state{protocol_buffers = #protocol_buffers{
end.
acceptable_record_versions(hello, _) ->
- [dtls_record:protocol_version(Vsn) || Vsn <- ?ALL_DATAGRAM_SUPPORTED_VERSIONS];
+ [dtls_record:protocol_version(Vsn) || Vsn <- ?ALL_AVAILABLE_DATAGRAM_VERSIONS];
acceptable_record_versions(_, #state{connection_env = #connection_env{negotiated_version = Version}}) ->
[Version].
diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl
index bfa349c8d8..c7c96370b3 100644
--- a/lib/ssl/src/ssl.erl
+++ b/lib/ssl/src/ssl.erl
@@ -103,9 +103,10 @@
-type ip_address() :: inet:ip_address().
-type session_id() :: binary().
-type protocol_version() :: tls_version() | dtls_version().
--type tls_version() :: tlsv1 | 'tlsv1.1' | 'tlsv1.2' | 'tlsv1.3' | legacy_version().
--type dtls_version() :: 'dtlsv1' | 'dtlsv1.2'.
--type legacy_version() :: sslv3.
+-type tls_version() :: 'tlsv1.2' | 'tlsv1.3' | tls_legacy_version().
+-type dtls_version() :: 'dtlsv1.2' | dtls_legacy_version().
+-type tls_legacy_version() :: tlsv1 | 'tlsv1.1' | sslv3.
+-type dtls_legacy_version() :: 'dtlsv1'.
-type verify_type() :: verify_none | verify_peer.
-type cipher() :: aes_128_cbc |
aes_256_cbc |
diff --git a/lib/ssl/src/ssl_internal.hrl b/lib/ssl/src/ssl_internal.hrl
index 3d117a655f..4ee0230d88 100644
--- a/lib/ssl/src/ssl_internal.hrl
+++ b/lib/ssl/src/ssl_internal.hrl
@@ -72,12 +72,13 @@
%% sslv3 is considered insecure due to lack of padding check (Poodle attack)
%% Keep as interop with legacy software but do not support as default
+%% tlsv1.0 and tlsv1.1 is now also considered legacy
%% tlsv1.3 is under development (experimental).
-define(ALL_AVAILABLE_VERSIONS, ['tlsv1.3', 'tlsv1.2', 'tlsv1.1', tlsv1, sslv3]).
-define(ALL_AVAILABLE_DATAGRAM_VERSIONS, ['dtlsv1.2', dtlsv1]).
%% Defines the default versions when not specified by an ssl option.
--define(ALL_SUPPORTED_VERSIONS, ['tlsv1.2', 'tlsv1.1', tlsv1]).
--define(MIN_SUPPORTED_VERSIONS, ['tlsv1.1', tlsv1]).
+-define(ALL_SUPPORTED_VERSIONS, ['tlsv1.2']).
+-define(MIN_SUPPORTED_VERSIONS, ['tlsv1.1']).
%% Versions allowed in TLSCiphertext.version (TLS 1.2 and prior) and
%% TLSCiphertext.legacy_record_version (TLS 1.3).
@@ -86,7 +87,7 @@
%% Thus, the allowed range is limited to 0x0300 - 0x0303.
-define(ALL_TLS_RECORD_VERSIONS, ['tlsv1.2', 'tlsv1.1', tlsv1, sslv3]).
--define(ALL_DATAGRAM_SUPPORTED_VERSIONS, ['dtlsv1.2', dtlsv1]).
+-define(ALL_DATAGRAM_SUPPORTED_VERSIONS, ['dtlsv1.2']).
-define(MIN_DATAGRAM_SUPPORTED_VERSIONS, [dtlsv1]).
%% TLS 1.3 - Section 4.1.3
diff --git a/lib/ssl/src/tls_handshake_1_3.erl b/lib/ssl/src/tls_handshake_1_3.erl
index 1e8b046c1e..0efedf3400 100644
--- a/lib/ssl/src/tls_handshake_1_3.erl
+++ b/lib/ssl/src/tls_handshake_1_3.erl
@@ -1007,7 +1007,8 @@ update_start_state(#state{connection_states = ConnectionStates0,
session = Session#session{session_id = SessionId,
ecc = Group,
sign_alg = SelectedSignAlg,
- dh_public_value = ClientPubKey},
+ dh_public_value = ClientPubKey,
+ cipher_suite = Cipher},
connection_env = CEnv#connection_env{negotiated_version = {3,4}}}.
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
index ff5638ff34..41a502b846 100644
--- a/lib/ssl/test/ssl_basic_SUITE.erl
+++ b/lib/ssl/test/ssl_basic_SUITE.erl
@@ -289,7 +289,8 @@ tls13_test_group() ->
tls13_hrr_client_auth_empty_cert_ssl_server_openssl_client,
tls13_hrr_client_auth_ssl_server_openssl_client,
tls13_unsupported_sign_algo_client_auth_ssl_server_openssl_client,
- tls13_unsupported_sign_algo_cert_client_auth_ssl_server_openssl_client].
+ tls13_unsupported_sign_algo_cert_client_auth_ssl_server_openssl_client,
+ tls13_connection_information].
%%--------------------------------------------------------------------
init_per_suite(Config0) ->
@@ -3463,9 +3464,9 @@ defaults(Config) when is_list(Config)->
true = lists:member(sslv3, proplists:get_value(available, Versions)),
false = lists:member(sslv3, proplists:get_value(supported, Versions)),
true = lists:member('tlsv1', proplists:get_value(available, Versions)),
- true = lists:member('tlsv1', proplists:get_value(supported, Versions)),
+ false = lists:member('tlsv1', proplists:get_value(supported, Versions)),
true = lists:member('tlsv1.1', proplists:get_value(available, Versions)),
- true = lists:member('tlsv1.1', proplists:get_value(supported, Versions)),
+ false = lists:member('tlsv1.1', proplists:get_value(supported, Versions)),
true = lists:member('tlsv1.2', proplists:get_value(available, Versions)),
true = lists:member('tlsv1.2', proplists:get_value(supported, Versions)),
false = lists:member({rsa,rc4_128,sha}, ssl:cipher_suites()),
@@ -3477,7 +3478,7 @@ defaults(Config) when is_list(Config)->
true = lists:member('dtlsv1.2', proplists:get_value(available_dtls, Versions)),
true = lists:member('dtlsv1', proplists:get_value(available_dtls, Versions)),
true = lists:member('dtlsv1.2', proplists:get_value(supported_dtls, Versions)),
- true = lists:member('dtlsv1', proplists:get_value(supported_dtls, Versions)).
+ false = lists:member('dtlsv1', proplists:get_value(supported_dtls, Versions)).
%%--------------------------------------------------------------------
reuseaddr() ->
@@ -5849,6 +5850,29 @@ tls13_unsupported_sign_algo_cert_client_auth_ssl_server_openssl_client(Config) -
ssl_test_lib:close_port(Client).
+tls13_connection_information() ->
+ [{doc,"Test the API function ssl:connection_information/1 in a TLS 1.3 connection"}].
+
+tls13_connection_information(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ %% Set versions
+ ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']}|ServerOpts0],
+ {_ClientNode, ServerNode, _Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, connection_information_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_basic_client(openssl, 'tlsv1.3', Port, ClientOpts),
+
+ ssl_test_lib:check_result(Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close_port(Client).
+
+
%%--------------------------------------------------------------------
%% Internal functions ------------------------------------------------
%%--------------------------------------------------------------------
diff --git a/lib/ssl/test/ssl_certificate_verify_SUITE.erl b/lib/ssl/test/ssl_certificate_verify_SUITE.erl
index 8690faed54..4f340af4f5 100644
--- a/lib/ssl/test/ssl_certificate_verify_SUITE.erl
+++ b/lib/ssl/test/ssl_certificate_verify_SUITE.erl
@@ -147,6 +147,7 @@ init_per_testcase(_TestCase, Config) ->
ssl:stop(),
ssl:start(),
ssl_test_lib:ct_log_supported_protocol_versions(Config),
+ ct:pal(" ~p", [ dtls_record:supported_protocol_versions()]),
ct:timetrap({seconds, 10}),
Config.
diff --git a/lib/stdlib/src/Makefile b/lib/stdlib/src/Makefile
index c95f7637f7..86003c953d 100644
--- a/lib/stdlib/src/Makefile
+++ b/lib/stdlib/src/Makefile
@@ -155,8 +155,10 @@ APPUP_TARGET= $(EBIN)/$(APPUP_FILE)
ifeq ($(NATIVE_LIBS_ENABLED),yes)
ERL_COMPILE_FLAGS += +native
+else
+ERL_COMPILE_FLAGS += -Werror
endif
-ERL_COMPILE_FLAGS += -I../include -I../../kernel/include -Werror
+ERL_COMPILE_FLAGS += -I../include -I../../kernel/include
# ----------------------------------------------------
# Targets
diff --git a/lib/stdlib/test/string_SUITE.erl b/lib/stdlib/test/string_SUITE.erl
index 6afe9e7a76..248912c3f2 100644
--- a/lib/stdlib/test/string_SUITE.erl
+++ b/lib/stdlib/test/string_SUITE.erl
@@ -52,7 +52,7 @@
suite() ->
[{ct_hooks,[ts_install_cth]},
- {timetrap,{minutes,2}}].
+ {timetrap,{minutes,1}}].
all() ->
[{group, chardata}, {group, list_string}].
@@ -737,10 +737,10 @@ meas(Config) ->
case ct:get_timetrap_info() of
{_,{_,Scale}} when Scale > 1 ->
{skip,{will_not_run_in_debug,Scale}};
- _ -> % No scaling, run at most 2 mins
+ _ -> % No scaling, run at most 1.5 min
Tester = spawn(Exec),
receive {test_done, Tester} -> ok
- after 120000 ->
+ after 90000 ->
io:format("Timelimit reached stopping~n",[]),
exit(Tester, die)
end,
diff --git a/lib/tools/emacs/erlang.el b/lib/tools/emacs/erlang.el
index 3cbe9daa60..38c0eba92b 100644
--- a/lib/tools/emacs/erlang.el
+++ b/lib/tools/emacs/erlang.el
@@ -905,8 +905,10 @@ resulting regexp is surrounded by \\_< and \\_>."
"dist_get_stat"
"dist_ctrl_get_data"
"dist_ctrl_get_data_notification"
+ "dist_ctrl_get_opt"
"dist_ctrl_input_handler"
"dist_ctrl_put_data"
+ "dist_ctrl_set_opt"
"dmonitor_node"
"dt_append_vm_tag_data"
"dt_get_tag"
diff --git a/lib/xmerl/doc/src/notes.xml b/lib/xmerl/doc/src/notes.xml
index 7f6874e36b..d6b6dfdfb5 100644
--- a/lib/xmerl/doc/src/notes.xml
+++ b/lib/xmerl/doc/src/notes.xml
@@ -32,6 +32,28 @@
<p>This document describes the changes made to the Xmerl application.</p>
+<section><title>Xmerl 1.3.20</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Handling of character references in attributes are fixed.</p>
+ <p>
+ Own Id: OTP-15684 Aux Id: ERL-837 </p>
+ </item>
+ <item>
+ <p>
+ Normalization of whitespace characters in attributes are
+ fixed so it works when character references are used.</p>
+ <p>
+ Own Id: OTP-15685 Aux Id: ERL-475 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Xmerl 1.3.19</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/xmerl/src/xmerl_scan.erl b/lib/xmerl/src/xmerl_scan.erl
index e543a5a11e..d76ed5c820 100644
--- a/lib/xmerl/src/xmerl_scan.erl
+++ b/lib/xmerl/src/xmerl_scan.erl
@@ -2410,15 +2410,22 @@ scan_att_chars("&" ++ T, S0, Delim, Acc, TmpAcc,AT,IsNorm) -> % Reference
true ->
scan_att_chars(T1,S1,Delim,[ExpRef|Acc],[ExpRef|TmpAcc],AT,IsNorm);
_ ->
- Ch = string_to_char_set(S#xmerl_scanner.encoding, ExpRef),
case T of
"#" ++ _ ->
%% normalization rules (sec 3.3.3) require that for
%% character references, the referenced character be
%% added directly to the normalized value
- scan_att_chars(T1, S1, Delim, Ch ++ Acc,TmpAcc, AT,IsNorm);
+ {T2,S2,IsNorm2} =
+ if
+ ?whitespace(hd(ExpRef)) ->
+ normalize(T1, S1, IsNorm);
+ true ->
+ {T1, S1, IsNorm}
+ end,
+ scan_att_chars(T2, S2, Delim, ExpRef ++ Acc, TmpAcc, AT, IsNorm2);
_ ->
- scan_att_chars(Ch ++ T1, S1, Delim, Acc,TmpAcc, AT,IsNorm)
+ Ch = string_to_char_set(S#xmerl_scanner.encoding, ExpRef),
+ scan_att_chars(Ch ++ T1, S1, Delim, Acc, TmpAcc, AT, IsNorm)
end
end;
scan_att_chars("<" ++ _T, S0, _Delim, _Acc,_, _,_) -> % Tags not allowed here
@@ -3964,7 +3971,7 @@ normalize(T,S,IsNorm) ->
{_,T,S} ->
{T,S,IsNorm};
{_,T1,S1} ->
- {T1,S1,true}
+ normalize(T1,S1,true)
end.
diff --git a/lib/xmerl/vsn.mk b/lib/xmerl/vsn.mk
index b6486681c2..31ffa6e749 100644
--- a/lib/xmerl/vsn.mk
+++ b/lib/xmerl/vsn.mk
@@ -1 +1 @@
-XMERL_VSN = 1.3.19
+XMERL_VSN = 1.3.20