File 3797-Improve-test-cases.patch of Package erlang

From 97766d2f488c9c1a2fb0cac16de00180d01fd291 Mon Sep 17 00:00:00 2001
From: Raimo Niskanen <raimo@erlang.org>
Date: Thu, 15 Sep 2022 16:19:54 +0200
Subject: [PATCH 07/11] Improve test cases

---
 lib/ssl/src/inet_tls_dist.erl   |   8 +-
 lib/ssl/test/ssl_dist_SUITE.erl | 250 ++++++++++++++++++++++++--------
 2 files changed, 197 insertions(+), 61 deletions(-)

diff --git a/lib/ssl/src/inet_tls_dist.erl b/lib/ssl/src/inet_tls_dist.erl
index be0357240e..f93457478f 100644
--- a/lib/ssl/src/inet_tls_dist.erl
+++ b/lib/ssl/src/inet_tls_dist.erl
@@ -918,7 +918,13 @@ ssl_option(client, Opt) ->
         "secure_renegotiate" -> fun atomize/1;
         "depth" -> fun erlang:list_to_integer/1;
         "hibernate_after" -> fun erlang:list_to_integer/1;
-        "ciphers" -> fun listify/1;
+        "ciphers" ->
+            %% Allows just one cipher, for now (could be , separated)
+            fun (Val) -> [listify(Val)] end;
+        "versions" ->
+            %% Allows just one version, for now (could be , separated)
+            fun (Val) -> [atomize(Val)] end;
+        "ktls" -> fun atomize/1;
         _ -> error
     end.
 
diff --git a/lib/ssl/test/ssl_dist_SUITE.erl b/lib/ssl/test/ssl_dist_SUITE.erl
index 0fef5eed45..47596b1ffa 100644
--- a/lib/ssl/test/ssl_dist_SUITE.erl
+++ b/lib/ssl/test/ssl_dist_SUITE.erl
@@ -37,8 +37,14 @@
 %% Test cases
 -export([basic/0,
          basic/1,
+         ktls_encrypt_decrypt/0,
+         ktls_encrypt_decrypt/1,
          ktls_basic/0,
          ktls_basic/1,
+         ktls_verify/0,
+         ktls_verify/1,
+         ktls_verify_asymmetric/0,
+         ktls_verify_asymmetric/1,
          monitor_nodes/1,
          payload/0,
          payload/1,
@@ -108,7 +114,10 @@ start_ssl_node_name(Name, Args) ->
 %%--------------------------------------------------------------------
 all() ->
     [basic,
+     ktls_encrypt_decrypt,
      ktls_basic,
+     ktls_verify,
+     ktls_verify_asymmetric,
      monitor_nodes,
      payload,
      dist_port_overload,
@@ -157,64 +166,25 @@ init_per_testcase(plain_verify_options = Case, Config) when is_list(Config) ->
     end,
     common_init(Case, [{old_flags, Flags} | Config]);
 
-init_per_testcase(ktls_basic = Case, Config) when is_list(Config) ->
-    case {os:type(), os:version()} of
-        {{unix,linux}, OsVersion} when {5,2,0} =< OsVersion ->
-            %% We need a connected socket
-            {ok, Listen} = gen_tcp:listen(0, [{active, false}]),
-            {ok, Port} = inet:port(Listen),
-            {ok, Client} =
-                gen_tcp:connect({127,0,0,1}, Port, [{active, false}]),
-            {ok, Server} = gen_tcp:accept(Listen),
-            %% We'll use the Server socket
-            Skip = make_ref(),
-            try
-                SOL_TCP = 6, TCP_ULP = 31,
-                _ = inet:setopts(
-                      Server, [{raw, SOL_TCP, TCP_ULP, <<"tls">>}]),
-                (GetULP =
-                     inet:getopts(Server, [{raw, SOL_TCP, TCP_ULP, 4}]))
-                    =:=
-                    {ok, [{raw, SOL_TCP, TCP_ULP, <<"tls",0>>}]}
-                    orelse
-                    throw({Skip,{get_ulp, GetULP}}),
-                TLS_VER    = ((3 bsl 8) bor 4),
-                TLS_CIPHER = 52,
-                TLS_SALT   = <<1,1,1,1>>,
-                TLS_IV     = <<2,2,2,2,2,2,2,2>>,
-                TLS_KEY    =
-                    <<3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
-                      3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3>>,
-                TLS_crypto_info =
-                    <<TLS_VER:16/native, TLS_CIPHER:16/native,
-                      TLS_IV/binary, TLS_KEY/binary, TLS_SALT/binary,
-                      0:64/native>>,
-                SOL_TLS = 282, TLS_TX = 1,
-                RawOpt =
-                    {raw, SOL_TLS, TLS_TX, TLS_crypto_info},
-                _ = inet:setopts(Server, [RawOpt]),
-                (GetCryptoInfo =
-                    inet:getopts(
-                      Server,
-                      [{raw, SOL_TLS, TLS_TX, byte_size(TLS_crypto_info)}]))
-                    =:=
-                    {ok, [RawOpt]}
-                    orelse throw({Skip,{get_crypto_info,GetCryptoInfo}}),
-                common_init(Case, Config)
-                %%
-            catch {Skip,SkipReason} ->
-                    {skip,
-                     lists:flatten(
-                       io_lib:format("kTLS not supported, ~p", [SkipReason]))}
-            after
-                _ = gen_tcp:close(Server),
-                _ = gen_tcp:close(Client),
-                _ = gen_tcp:close(Listen)
-            end;
-        OS ->
-            {skip,
-             lists:flatten(
-               io_lib:format("kTLS not supported by OS: ~p", [OS]))}
+init_per_testcase(Case, Config)
+  when Case =:= ktls_basic, is_list(Config);
+       Case =:= ktls_verify, is_list(Config);
+       Case =:= ktls_verify_asymmetric, is_list(Config) ->
+    %% We need a connected socket
+    {ok, Listen} = gen_tcp:listen(0, [{active, false}]),
+    {ok, Port} = inet:port(Listen),
+    {ok, Client} =
+        gen_tcp:connect({127,0,0,1}, Port, [{active, false}]),
+    {ok, Server} = gen_tcp:accept(Listen),
+    try ktls_encrypt_decrypt(Client, Server, false) of
+        ok ->
+            common_init(Case, Config);
+        Other ->
+            Other
+    after
+        _ = gen_tcp:close(Server),
+        _ = gen_tcp:close(Client),
+        _ = gen_tcp:close(Listen)
     end;
 
 init_per_testcase(Case, Config) when is_list(Config) ->
@@ -241,12 +211,166 @@ basic() ->
 basic(Config) when is_list(Config) ->
     gen_dist_test(basic_test, Config).
 
+%%--------------------------------------------------------------------
+ktls_encrypt_decrypt() ->
+    [{doc,"Test that kTLS encryption offloading works"}].
+ktls_encrypt_decrypt(Config) when is_list(Config) ->
+    %% We need a connected socket
+    {ok, Listen} = gen_tcp:listen(0, [{active, false}]),
+    {ok, Port} = inet:port(Listen),
+    {ok, Client} =
+        gen_tcp:connect({127,0,0,1}, Port, [{active, false}]),
+    {ok, Server} = gen_tcp:accept(Listen),
+    try ktls_encrypt_decrypt(Client, Server, true)
+    after
+        _ = gen_tcp:close(Server),
+        _ = gen_tcp:close(Client),
+        _ = gen_tcp:close(Listen)
+    end.
+
+ktls_encrypt_decrypt(Client, Server, Test) ->
+    Done = make_ref(),
+    try
+        case {os:type(), os:version()} of
+            {{unix,linux}, OsVersion} when {5,2,0} =< OsVersion ->
+                ok;
+            OS ->
+                throw({Done, skip, {os,OS}})
+        end,
+        %%
+        SOL_TCP = 6, TCP_ULP = 31,
+        _ = inet:setopts(Server, [{raw, SOL_TCP, TCP_ULP, <<"tls">>}]),
+        (GetULP =
+             inet:getopts(Server, [{raw, SOL_TCP, TCP_ULP, 4}]))
+            =:= {ok, [{raw, SOL_TCP, TCP_ULP, <<"tls",0>>}]}
+            orelse
+            throw({Done, skip, {get_ulp, GetULP}}),
+        ok = inet:setopts(Client, [{raw, SOL_TCP, TCP_ULP, <<"tls">>}]),
+        TLS_VER    = ((3 bsl 8) bor 4),
+        TLS_CIPHER = 52,
+        TLS_SALT   = <<1,1,1,1>>,
+        TLS_IV     = <<2,2,2,2,2,2,2,2>>,
+        TLS_KEY    =
+            <<3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
+              3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3>>,
+        TLS_crypto_info =
+            <<TLS_VER:16/native, TLS_CIPHER:16/native,
+              TLS_IV/binary, TLS_KEY/binary, TLS_SALT/binary,
+              0:64/native>>,
+        SOL_TLS = 282, TLS_TX = 1, TLS_RX = 2,
+        RawOptTX = {raw, SOL_TLS, TLS_TX, TLS_crypto_info},
+        (SetoptsResult = inet:setopts(Server, [RawOptTX])) =:= ok
+            orelse throw({Done, skip, {setopts_error,SetoptsResult}}),
+        (GetCryptoInfo =
+             inet:getopts(
+               Server,
+               [{raw, SOL_TLS, TLS_TX, byte_size(TLS_crypto_info)}]))
+            =:= {ok, [RawOptTX]}
+            orelse throw({Done, skip, {get_crypto_info,GetCryptoInfo}}),
+        %%
+        %%
+        %%
+        Test orelse throw(Done),
+        %%
+        %%
+        %%
+        Data = "The quick brown fox jumps over a lazy dog 0123456789",
+        %% Send from Server when Client has no decryption parameters
+        ok = gen_tcp:send(Server, Data),
+        case gen_tcp:recv(Client, 0, 1000) of
+            {ok, Data} ->
+                ct:fail(recv_cleartext_data);
+            {ok, _RandomData} ->
+                ok
+        end,
+        %% Configure Client -> Server
+        RawOptRX = {raw, SOL_TLS, TLS_RX, TLS_crypto_info},
+        ok = inet:setopts(Client, [RawOptTX]),
+        ok = inet:setopts(Server, [RawOptRX]),
+        %% Send encrypted Client -> Server
+        ok = gen_tcp:send(Client, Data),
+        {ok, Data} = gen_tcp:recv(Server, 0, 1000),
+        ok
+    catch
+        Done ->
+            ok;
+        {Done, skip,SkipReason} ->
+            {skip,
+             lists:flatten(
+               io_lib:format("kTLS not supported: ~p", [SkipReason]))}
+    end.
+
+
+
+
 %%--------------------------------------------------------------------
 ktls_basic() ->
     [{doc,"Test that two nodes can connect via ssl distribution"}].
 ktls_basic(Config) when is_list(Config) ->
     gen_dist_test(ktls_basic_test, Config).
 
+%%--------------------------------------------------------------------
+ktls_verify() ->
+    [{doc,
+      "Test that two nodes can connect via ssl distribution over kTLS"}].
+ktls_verify(Config) ->
+    KTLSOpts = "-ssl_dist_opt "
+        "client_versions tlsv1.3 "
+        "server_versions tlsv1.3 "
+        "client_ciphers TLS_AES_256_GCM_SHA384 "
+        "server_ciphers TLS_AES_256_GCM_SHA384 "
+        "client_ktls true "
+        "server_ktls true ",
+    gen_dist_test(basic_test, [{tls_verify_opts, KTLSOpts} | Config]).
+
+%%--------------------------------------------------------------------
+ktls_verify_asymmetric() ->
+    [{doc,
+      "Test that two nodes can connect via ssl distribution "
+      "when one uses kTLS and the other our regular TSL"}].
+ktls_verify_asymmetric(Config) ->
+    KTLSOpts = "-ssl_dist_opt "
+        "client_versions tlsv1.3 "
+        "server_versions tlsv1.3 "
+        "client_ciphers TLS_AES_256_GCM_SHA384 "
+        "server_ciphers TLS_AES_256_GCM_SHA384 "
+        "server_ktls true "
+        "client_ktls false ",
+    KTLSConfig = [{tls_verify_opts, KTLSOpts} | Config],
+    gen_dist_test(
+      fun (NH1, NH2) ->
+              basic_test(NH1, NH2, KTLSConfig),
+              %%
+              %% NH1 should have connected to NH2 so the connection should
+              %% use the client on NH1 and the server on NH2, therefore
+              %% NH2 should run kTLS but NH1 should run regular TLS
+              %%
+              case ktls_count_tls_dist(NH1) of
+                  N when 0 < N -> ok
+              end,
+              0 = ktls_count_tls_dist(NH2),
+              ok
+      end, KTLSConfig).
+
+%% Verify that kTLS was activated (whitebox verification);
+%% check that a specific supervisor has no child supervisor
+%% which indicates that ssl_gen_statem:ktls_handover/1 has succeeded
+%%
+ktls_count_tls_dist(Node) ->
+    Key = supervisors,
+    case
+        lists:keyfind(
+          Key, 1,
+          apply_on_ssl_node(
+            Node, supervisor, count_children,
+            [tls_dist_connection_sup]))
+    of
+        {Key, N} ->
+            N;
+        false ->
+            0
+    end.
+
 %%--------------------------------------------------------------------
 %% Test net_kernel:monitor_nodes with nodedown_reason (OTP-17838)
 monitor_nodes(Config) when is_list(Config) ->
@@ -541,8 +665,13 @@ address_please(_, _, _) ->
 gen_dist_test(Test, Config) ->
     NH1 = start_ssl_node(Config),
     NH2 = start_ssl_node(Config),
-    try 
-	?MODULE:Test(NH1, NH2, Config)
+    try
+        if
+            is_atom(Test) ->
+                ?MODULE:Test(NH1, NH2, Config);
+            is_function(Test, 2) ->
+                Test(NH1, NH2)
+        end
     catch
 	Class:Reason:Stacktrace ->
 	    ct:fail({Class,Reason,Stacktrace})
@@ -572,6 +701,7 @@ try_setting_priority(TestFun, Config) ->
 	{error,_} ->
 	    {skip, "Can not set priority on socket"}
     end.
+
 basic_test(NH1, NH2, _) ->
     Node1 = NH1#node_handle.nodename,
     Node2 = NH2#node_handle.nodename,
-- 
2.35.3

openSUSE Build Service is sponsored by