File 3821-ssl-test-cuddle.patch of Package erlang

From e39b40c78ae784d934fe446468a5cf04f14c5e6a Mon Sep 17 00:00:00 2001
From: Dan Gudmundsson <dgud@erlang.org>
Date: Fri, 28 Oct 2022 16:56:47 +0200
Subject: [PATCH] ssl test cuddle

Cache openssl versions, speed up tests on windows where
starting openssl via wsl takes ~0.5 seconds and have become
slower on windows 11 which causes tests to time out.
---
 lib/ssl/test/openssl_ECC_SUITE.erl            |  28 ++--
 lib/ssl/test/openssl_alpn_SUITE.erl           |  42 ++---
 lib/ssl/test/openssl_cipher_suite_SUITE.erl   |  31 ++--
 lib/ssl/test/openssl_client_cert_SUITE.erl    |  24 +--
 lib/ssl/test/openssl_key_update_SUITE.erl     |  25 ++-
 lib/ssl/test/openssl_mfl_SUITE.erl            |  26 ++--
 lib/ssl/test/openssl_npn_SUITE.erl            |  29 +---
 lib/ssl/test/openssl_ocsp_SUITE.erl           |  39 ++---
 lib/ssl/test/openssl_reject_SUITE.erl         |  26 +---
 lib/ssl/test/openssl_renegotiate_SUITE.erl    |  24 +--
 lib/ssl/test/openssl_server_cert_SUITE.erl    |  17 +-
 lib/ssl/test/openssl_session_SUITE.erl        |  32 ++--
 lib/ssl/test/openssl_session_ticket_SUITE.erl |  17 +-
 lib/ssl/test/openssl_sni_SUITE.erl            |  39 ++---
 .../test/openssl_tls_1_3_version_SUITE.erl    |  25 ++-
 lib/ssl/test/ssl_mfl_SUITE.erl                |  18 +--
 lib/ssl/test/ssl_test_lib.erl                 | 145 +++++++++++++-----
 17 files changed, 243 insertions(+), 344 deletions(-)

diff --git a/lib/ssl/test/openssl_ECC_SUITE.erl b/lib/ssl/test/openssl_ECC_SUITE.erl
index ec84deda85..cfbb71b266 100644
--- a/lib/ssl/test/openssl_ECC_SUITE.erl
+++ b/lib/ssl/test/openssl_ECC_SUITE.erl
@@ -60,26 +60,22 @@ groups() ->
         false ->
             [{'tlsv1.2', [], [mix_sign]}]
     end.
-  
+
 init_per_suite(Config0) ->
-    end_per_suite(Config0),
-    try crypto:start() of
-	ok ->
-            ssl_test_lib:clean_start(),
-            case  ssl_test_lib:sufficient_crypto_support(cipher_ec) of
+    case ssl_test_lib:init_per_suite(Config0, openssl) of
+        {skip, _} = Skip ->
+            Skip;
+        Config ->
+            case ssl_test_lib:sufficient_crypto_support(cipher_ec) of
                 true ->
-                    Config0;
+                    Config;
                 false ->
                     {skip, "Openssl does not support ECC"}
             end
-    catch _:_ ->
-            {skip, "Crypto did not start"}
     end.
 
-end_per_suite(_Config) ->
-    application:stop(ssl),
-    application:stop(crypto),
-    ssl_test_lib:kill_openssl().
+end_per_suite(Config) ->
+    ssl_test_lib:end_per_suite(Config).
 
 init_per_group(GroupName, Config) ->
     ssl_test_lib:init_per_group_openssl(GroupName, Config).
@@ -90,15 +86,13 @@ end_per_group(GroupName, Config) ->
 init_per_testcase(skip, Config) ->
     Config;
 init_per_testcase(TestCase, Config) ->
-    ssl_test_lib:ct_log_supported_protocol_versions(Config),
-    Version = proplists:get_value(tls_version, Config),
-    ct:log("Ciphers: ~p~n ", [ssl:cipher_suites(default, Version)]),
     end_per_testcase(TestCase, Config),
     ssl:start(),
+    ssl_test_lib:ct_log_supported_protocol_versions(Config),
     ct:timetrap({seconds, 30}),
     Config.
 
-end_per_testcase(_TestCase, Config) ->     
+end_per_testcase(_TestCase, Config) ->
     application:stop(ssl),
     Config.
 
diff --git a/lib/ssl/test/openssl_alpn_SUITE.erl b/lib/ssl/test/openssl_alpn_SUITE.erl
index d43f198943..2836e9a0a7 100644
--- a/lib/ssl/test/openssl_alpn_SUITE.erl
+++ b/lib/ssl/test/openssl_alpn_SUITE.erl
@@ -116,30 +116,16 @@ rengotiation_tests() ->
     ].
 
 init_per_suite(Config0) ->
-    case os:find_executable("openssl") of
+    Config1 = ssl_test_lib:init_per_suite(Config0, openssl),
+    case check_openssl_alpn_support(Config1) of
         false ->
-            {skip, "Openssl not found"};
-        _ ->
-            case check_openssl_alpn_support(Config0) of
-                false ->
-                    {skip, "No ALPN support"};
-                true ->
-                    ct:pal("Version: ~p", [os:cmd("openssl version")]),
-                    catch crypto:stop(),
-                    try crypto:start() of
-                        ok ->
-                            ssl_test_lib:clean_start(),
-                            ssl_test_lib:make_rsa_cert(Config0)
-                    catch _:_  ->
-                            {skip, "Crypto did not start"}
-                    end
-            end
+            {skip, "No ALPN support"};
+        true ->
+            ssl_test_lib:make_rsa_cert(Config1)
     end.
 
-end_per_suite(_Config) ->
-    ssl:stop(),
-    application:stop(crypto),
-    ssl_test_lib:kill_openssl().
+end_per_suite(Config) ->
+    ssl_test_lib:end_per_suite(Config).
 
 init_per_group(GroupName, Config) ->
     ssl_test_lib:init_per_group_openssl(GroupName, Config).
@@ -163,9 +149,9 @@ special_init(TestCase, Config) when TestCase == erlang_client_alpn_openssl_serve
 special_init(TestCase, Config) when TestCase == erlang_client_alpn_npn_openssl_server_alpn_npn;
                                     TestCase == erlang_server_alpn_npn_openssl_client_alpn_npn ->
     case ssl_test_lib:check_openssl_npn_support(Config) of
-        {skip, _} = Skip ->
-            Skip;
-        Config ->
+        false ->
+            {skip, "npn not supported"};
+        true ->
             Config
     end;
 special_init(_, Config) ->
@@ -427,8 +413,8 @@ erlang_client_alpn_npn_openssl_server_alpn_npn(Config) when is_list(Config) ->
                                            return_socket],
                                   [{client_opts,
                                     [{alpn_advertised_protocols, [AlpnProtocol]},
-                                     {next_protocols_advertised,
-                                      [<<"spdy/3">>, <<"http/1.1">>]}]} | ClientOpts] ++ Config),
+                                     {client_preferred_next_protocols,
+                                      {client, [<<"spdy/3">>, <<"http/1.1">>]}}]} | ClientOpts] ++ Config),
     case ssl:negotiated_protocol(CSocket) of
         {ok, AlpnProtocol} ->
             ok;
@@ -474,8 +460,8 @@ erlang_server_alpn_npn_openssl_client_alpn_npn(Config) when is_list(Config) ->
 %%--------------------------------------------------------------------
 %% Internal functions  -----------------------------------------------
 %%--------------------------------------------------------------------
-check_openssl_alpn_support(_Config) ->
-    case ssl_test_lib:portable_cmd("openssl", ["version"]) of
+check_openssl_alpn_support(Config) ->
+    case proplists:get_value(openssl_version, Config) of
         "OpenSSL 1.0."  ++ _ = Str->
             SubStr = Str -- "OpenSSL 1.0.",
             atleast(SubStr, 2);
diff --git a/lib/ssl/test/openssl_cipher_suite_SUITE.erl b/lib/ssl/test/openssl_cipher_suite_SUITE.erl
index bf854d44a7..8724595724 100644
--- a/lib/ssl/test/openssl_cipher_suite_SUITE.erl
+++ b/lib/ssl/test/openssl_cipher_suite_SUITE.erl
@@ -95,13 +95,8 @@
 %% Common Test interface functions -----------------------------------
 %%--------------------------------------------------------------------
 all() ->
-     case ssl_test_lib:working_openssl_client() of
-         true ->
-             [{group,  openssl_server},
-              {group,  openssl_client}];
-         false ->
-             [{group,  openssl_server}]
-     end.
+    [{group,  openssl_server},
+     {group,  openssl_client}].
 
 all_protocol_groups() ->
     [
@@ -260,22 +255,18 @@ anonymous() ->
     ].
 
 init_per_suite(Config) ->
-    catch crypto:stop(),
-    try crypto:start() of
-	ok ->
-	    ssl_test_lib:clean_start(),
-            Config
-    catch _:_ ->
-	    {skip, "Crypto did not start"}
-    end.
+    ssl_test_lib:init_per_suite(Config, openssl).
 
-end_per_suite(_Config) ->
-    ssl:stop(),
-    application:stop(crypto),
-    ssl_test_lib:kill_openssl().
+end_per_suite(Config) ->
+    ssl_test_lib:end_per_suite(Config).
 
 %%--------------------------------------------------------------------
 init_per_group(GroupName, Config) ->
+    case ssl_test_lib:working_openssl_client(Config) of
+        false when GroupName =:= openssl_client ->
+            throw({skip, "Ignore non-working openssl_client"});
+        _ -> ok
+    end,
     case ssl_test_lib:is_protocol_version(GroupName) of
         true ->
             ssl_test_lib:init_per_group_openssl(GroupName, Config);
@@ -388,7 +379,7 @@ init_per_testcase(TestCase, Config) when TestCase == psk_3des_ede_cbc;
     SupCiphers = proplists:get_value(ciphers, crypto:supports()),
     case lists:member(des_ede3_cbc, SupCiphers) of
         true ->
-            ct:timetrap({seconds, ?DEFAULT_TIMEOUT}),
+            ct:timetrap(?DEFAULT_TIMEOUT),
             Config;
         _ ->
             {skip, "Missing 3DES crypto support"}
diff --git a/lib/ssl/test/openssl_client_cert_SUITE.erl b/lib/ssl/test/openssl_client_cert_SUITE.erl
index e895f70861..018b49e0b7 100644
--- a/lib/ssl/test/openssl_client_cert_SUITE.erl
+++ b/lib/ssl/test/openssl_client_cert_SUITE.erl
@@ -148,25 +148,15 @@ all_version_tests() ->
      missing_root_cert_no_auth
     ].
 
-init_per_suite(Config) ->
-    catch crypto:stop(),
-    try crypto:start() of
-	ok ->
-            case ssl_test_lib:working_openssl_client() of
-                true ->
-                    ssl_test_lib:clean_start(),
-                    Config;
-                false ->
-                    {skip, "Broken OpenSSL s_client"}
-            end
-    catch _:_ ->
-            {skip, "Crypto did not start"}
+init_per_suite(Config0) ->
+    Config = ssl_test_lib:init_per_suite(Config0, openssl),
+    case ssl_test_lib:working_openssl_client(Config) of
+        true -> Config;
+        false -> throw({skip, "Broken OpenSSL s_client"})
     end.
 
-end_per_suite(_Config) ->
-    ssl:stop(),
-    application:unload(ssl),
-    application:stop(crypto).
+end_per_suite(Config) ->
+    ssl_test_lib:end_per_suite(Config).
 
 init_per_group(openssl_client, Config) ->
     [{client_type, openssl}, {server_type, erlang} | Config];
diff --git a/lib/ssl/test/openssl_key_update_SUITE.erl b/lib/ssl/test/openssl_key_update_SUITE.erl
index b619084c7a..d24f42a297 100644
--- a/lib/ssl/test/openssl_key_update_SUITE.erl
+++ b/lib/ssl/test/openssl_key_update_SUITE.erl
@@ -48,24 +48,17 @@ tls_1_3_tests() ->
      openssl_server_explicit_key_update].
 
 init_per_suite(Config0) ->
-    catch crypto:stop(),
-    try crypto:start() of
-        ok ->
-            ssl_test_lib:clean_start(),
-            case proplists:get_bool(ecdh, proplists:get_value(public_keys, crypto:supports())) of
-                true ->
-                    ssl_test_lib:make_ecdsa_cert(Config0);
-                false ->
-                    {skip, "Missing EC crypto support"}
-            end
-    catch _:_ ->
-            {skip, "Crypto did not start"}
+    Config1 = ssl_test_lib:init_per_suite(Config0, openssl),
+    case proplists:get_bool(ecdh, proplists:get_value(public_keys, crypto:supports()))
+    of
+        true ->
+            ssl_test_lib:make_ecdsa_cert(Config1);
+        false ->
+            {skip, "Missing EC crypto support"}
     end.
 
-end_per_suite(_Config) ->
-    ssl:stop(),
-    application:unload(ssl),
-    application:stop(crypto).
+end_per_suite(Config) ->
+    ssl_test_lib:end_per_suite(Config).
 
 init_per_group(GroupName, Config) ->
     ssl_test_lib:init_per_group_openssl(GroupName, Config).
diff --git a/lib/ssl/test/openssl_mfl_SUITE.erl b/lib/ssl/test/openssl_mfl_SUITE.erl
index 2fbf580535..54a6788966 100644
--- a/lib/ssl/test/openssl_mfl_SUITE.erl
+++ b/lib/ssl/test/openssl_mfl_SUITE.erl
@@ -64,25 +64,17 @@ groups() ->
     ].
 
 init_per_suite(Config0) ->
-    catch crypto:stop(),
-    try crypto:start() of
-	ok ->
-            case ssl_test_lib:openssl_maxfraglen_support() of
-                true ->
-                    ssl_test_lib:clean_start(),
-                    ssl:clear_pem_cache(),
-                    Config = ssl_test_lib:make_rsa_cert(Config0),
-                    ssl_test_lib:cert_options(Config);
-                false ->
-                    {skip, "max_fragment_length not supported by OpenSSL"} 
-            end
-    catch _:_ ->
-	    {skip, "Crypto did not start"}
+    Config1 = ssl_test_lib:init_per_suite(Config0, openssl),
+    case ssl_test_lib:openssl_maxfraglen_support() of
+        true ->
+            Config = ssl_test_lib:make_rsa_cert(Config1),
+            ssl_test_lib:cert_options(Config);
+        false ->
+            {skip, "max_fragment_length not supported by OpenSSL"} 
     end.
 
-end_per_suite(_Config) ->
-    ssl:stop(),
-    application:stop(crypto).
+end_per_suite(Config) ->
+    ssl_test_lib:end_per_suite(Config).
 
 init_per_group(GroupName, Config) ->
     ssl_test_lib:init_per_group_openssl(GroupName, Config).
diff --git a/lib/ssl/test/openssl_npn_SUITE.erl b/lib/ssl/test/openssl_npn_SUITE.erl
index dbeef3d2f8..485efd7f45 100644
--- a/lib/ssl/test/openssl_npn_SUITE.erl
+++ b/lib/ssl/test/openssl_npn_SUITE.erl
@@ -82,31 +82,16 @@ npn_renegotiate_tests() ->
            ].
 
 init_per_suite(Config0) ->
-    case os:find_executable("openssl") of
+    Config1 = ssl_test_lib:init_per_suite(Config0, openssl),
+    case ssl_test_lib:check_openssl_npn_support(Config1) of
+        true ->
+            ssl_test_lib:make_rsa_cert(Config1);
         false ->
-            {skip, "Openssl not found"};
-        _ ->
-            case ssl_test_lib:check_openssl_npn_support(Config0) of
-                {skip, _} = Skip ->
-                    Skip;
-                _ ->
-                    ct:pal("Version: ~p", [os:cmd("openssl version")]),
-                    catch crypto:stop(),
-                    try crypto:start() of
-                        ok ->
-                            ssl_test_lib:clean_start(),
-                            ssl:clear_pem_cache(),
-                            ssl_test_lib:make_rsa_cert(Config0)
-                    catch _:_  ->
-                            {skip, "Crypto did not start"}
-                    end
-            end
+            {skip, "npn_not_supported"}
     end.
 
-end_per_suite(_Config) ->
-    ssl:stop(),
-    application:stop(crypto),
-    ssl_test_lib:kill_openssl().
+end_per_suite(Config) ->
+    ssl_test_lib:end_per_suite(Config).
 
 init_per_group(GroupName, Config) ->
     ssl_test_lib:init_per_group_openssl(GroupName, Config).
diff --git a/lib/ssl/test/openssl_ocsp_SUITE.erl b/lib/ssl/test/openssl_ocsp_SUITE.erl
index 888a0ab3c4..800ce3ce78 100644
--- a/lib/ssl/test/openssl_ocsp_SUITE.erl
+++ b/lib/ssl/test/openssl_ocsp_SUITE.erl
@@ -70,8 +70,9 @@ ocsp_tests() ->
     ].
 
 %%--------------------------------------------------------------------
-init_per_suite(Config) ->
-    case ssl_test_lib:openssl_ocsp_support() of
+init_per_suite(Config0) ->
+    Config = ssl_test_lib:init_per_suite(Config0, openssl),
+    case ssl_test_lib:openssl_ocsp_support(Config) of
         true ->
             do_init_per_suite(Config);
         false ->
@@ -79,38 +80,28 @@ init_per_suite(Config) ->
     end.
 
 do_init_per_suite(Config) ->
-    catch crypto:stop(),
-    try crypto:start() of
-	ok ->
-        ssl_test_lib:clean_start(),
-        DataDir = proplists:get_value(data_dir, Config),
-        PrivDir = proplists:get_value(priv_dir, Config),
+    DataDir = proplists:get_value(data_dir, Config),
+    PrivDir = proplists:get_value(priv_dir, Config),
 
-        %% Prepare certs
-        {ok, _} = make_certs:all(DataDir, PrivDir),
+    %% Prepare certs
+    {ok, _} = make_certs:all(DataDir, PrivDir),
 
-        ResponderPort = get_free_port(),
-        Pid = start_ocsp_responder(ResponderPort, PrivDir),
+    ResponderPort = get_free_port(),
+    Pid = start_ocsp_responder(ResponderPort, PrivDir),
 
-        NewConfig =
+    NewConfig =
         lists:merge(
-            [{responder_port, ResponderPort},
-             {responder_pid, Pid}
-            ], Config),
+          [{responder_port, ResponderPort},
+           {responder_pid, Pid}
+          ], Config),
 
-	    ssl_test_lib:cert_options(NewConfig)
-    catch _:_ ->
-	    {skip, "Crypto did not start"}
-    end.
+    ssl_test_lib:cert_options(NewConfig).
 
 
 end_per_suite(Config) ->
     ResponderPid = proplists:get_value(responder_pid, Config),
     ssl_test_lib:close(ResponderPid),
-    ok = ssl:stop(),
-    %% terminate OpenSSL processes (OCSP responder in particular)
-    ssl_test_lib:kill_openssl(),
-    application:stop(crypto).
+    ssl_test_lib:end_per_suite(Config).
 
 %%--------------------------------------------------------------------
 init_per_group(GroupName, Config) ->
diff --git a/lib/ssl/test/openssl_reject_SUITE.erl b/lib/ssl/test/openssl_reject_SUITE.erl
index ddb350dd46..35d165f155 100644
--- a/lib/ssl/test/openssl_reject_SUITE.erl
+++ b/lib/ssl/test/openssl_reject_SUITE.erl
@@ -74,25 +74,11 @@ all_versions_tests() ->
     ].
 
 init_per_suite(Config0) ->
-    case os:find_executable("openssl") of
-        false ->
-            {skip, "Openssl not found"};
-        _ ->
-            ct:pal("Version: ~p", [os:cmd("openssl version")]),
-            catch crypto:stop(),
-            try crypto:start() of
-                ok ->
-                    ssl_test_lib:clean_start(),
-                    ssl_test_lib:make_rsa_cert(Config0)
-            catch _:_  ->
-                    {skip, "Crypto did not start"}
-            end
-    end.
+    Config = ssl_test_lib:init_per_suite(Config0, openssl),
+    ssl_test_lib:make_rsa_cert(Config).
 
-end_per_suite(_Config) ->
-    ssl:stop(),
-    application:stop(crypto),
-    ssl_test_lib:kill_openssl().
+end_per_suite(Config) ->
+    ssl_test_lib:end_per_suite(Config).
 
 init_per_group(GroupName, Config) ->
     ssl_test_lib:init_per_group_openssl(GroupName, Config).
@@ -105,14 +91,14 @@ init_per_testcase(TestCase, Config) ->
     special_init(TestCase, Config).
 
 special_init(erlang_server_reject_sslv2, Config) ->
-    case ssl_test_lib:check_sane_openssl_version(sslv2) of
+    case ssl_test_lib:check_sane_openssl_version(sslv2, Config) of
         true ->
             Config;
         false ->
             {skip, "sslv2 not supported by openssl"}
      end;
 special_init(erlang_server_reject_sslv3, Config) ->
-    case ssl_test_lib:check_sane_openssl_version(sslv3) of
+    case ssl_test_lib:check_sane_openssl_version(sslv3, Config) of
         true ->
             Config;
         false ->
diff --git a/lib/ssl/test/openssl_renegotiate_SUITE.erl b/lib/ssl/test/openssl_renegotiate_SUITE.erl
index 1b8769f2fd..08237f960a 100644
--- a/lib/ssl/test/openssl_renegotiate_SUITE.erl
+++ b/lib/ssl/test/openssl_renegotiate_SUITE.erl
@@ -98,28 +98,14 @@ all_versions_tests() ->
 
 
 init_per_suite(Config0) ->
-    case os:find_executable("openssl") of
-        false ->
-            {skip, "Openssl not found"};
-        _ ->
-            ct:pal("Version: ~p", [os:cmd("openssl version")]),
-            catch crypto:stop(),
-            try crypto:start() of
-                ok ->
-                    ssl_test_lib:clean_start(),
-                    ssl_test_lib:make_rsa_cert(Config0)
-            catch _:_  ->
-                    {skip, "Crypto did not start"}
-            end
-    end.
+    Config = ssl_test_lib:init_per_suite(Config0, openssl),
+    ssl_test_lib:make_rsa_cert(Config).
 
-end_per_suite(_Config) ->
-    ssl:stop(),
-    application:stop(crypto),
-    ssl_test_lib:kill_openssl().
+end_per_suite(Config) ->
+    ssl_test_lib:end_per_suite(Config).
 
 init_per_group(GroupName, Config) ->
-    case ssl_test_lib:check_sane_openssl_version(GroupName) of
+    case ssl_test_lib:check_sane_openssl_version(GroupName, Config) of
         true ->
             case ssl_test_lib:check_sane_openssl_renegotiate(Config, GroupName) of
                 {skip,_} = Skip ->
diff --git a/lib/ssl/test/openssl_server_cert_SUITE.erl b/lib/ssl/test/openssl_server_cert_SUITE.erl
index 55b7acbc2b..7f7a9b739e 100644
--- a/lib/ssl/test/openssl_server_cert_SUITE.erl
+++ b/lib/ssl/test/openssl_server_cert_SUITE.erl
@@ -149,19 +149,10 @@ all_version_tests() ->
     ].
 
 init_per_suite(Config) ->
-    catch crypto:stop(),
-    try crypto:start() of
-	ok ->
-	    ssl_test_lib:clean_start(),
-            Config
-    catch _:_ ->
-	    {skip, "Crypto did not start"}
-    end.
+    ssl_test_lib:init_per_suite(Config, openssl).
 
-end_per_suite(_Config) ->
-    ssl:stop(),
-    application:unload(ssl),
-    application:stop(crypto).
+end_per_suite(Config) ->
+    ssl_test_lib:end_per_suite(Config).
 
 init_per_group(openssl_server, Config0) ->
     Config = proplists:delete(server_type, proplists:delete(client_type, Config0)),
@@ -352,7 +343,7 @@ init_per_group(dsa = Group, Config0) ->
 init_per_group(GroupName, Config) ->
     case ssl_test_lib:is_protocol_version(GroupName) of
         true  ->
-            case ssl_test_lib:check_sane_openssl_version(GroupName) of
+            case ssl_test_lib:check_sane_openssl_version(GroupName, Config) of
                 true ->
                     ssl_test_lib:init_per_group_openssl(GroupName, Config);
                 false  ->
diff --git a/lib/ssl/test/openssl_session_SUITE.erl b/lib/ssl/test/openssl_session_SUITE.erl
index 92568716f3..4e081cd5bb 100644
--- a/lib/ssl/test/openssl_session_SUITE.erl
+++ b/lib/ssl/test/openssl_session_SUITE.erl
@@ -86,29 +86,15 @@ tests() ->
 
 
 init_per_suite(Config0) ->
-    case os:find_executable("openssl") of
-        false ->
-            {skip, "Openssl not found"};
-        _ ->
-            ct:pal("Version: ~p", [os:cmd("openssl version")]),
-            catch crypto:stop(),
-            try crypto:start() of
-                ok ->
-                    ssl_test_lib:clean_start(),
-                    {ClientOpts, ServerOpts} = 
-                        ssl_test_lib:make_rsa_cert_chains([{server_chain, ssl_test_lib:default_cert_chain_conf()},
-                                                           {client_chain, ssl_test_lib:default_cert_chain_conf()}], 
-                                                          Config0, "openssl_session_SUITE"),
-                    [{client_opts, ClientOpts}, {server_opts, ServerOpts} | Config0]
-            catch _:_  ->
-                    {skip, "Crypto did not start"}
-            end
-    end.
+    Config = ssl_test_lib:init_per_suite(Config0, openssl),
+    {ClientOpts, ServerOpts} = ssl_test_lib:make_rsa_cert_chains(
+                                 [{server_chain, ssl_test_lib:default_cert_chain_conf()},
+                                  {client_chain, ssl_test_lib:default_cert_chain_conf()}],
+                                 Config, "openssl_session_SUITE"),
+    [{client_opts, ClientOpts}, {server_opts, ServerOpts} | Config].
 
-end_per_suite(_Config) ->
-    ssl:stop(),
-    application:stop(crypto),
-    ssl_test_lib:kill_openssl().
+end_per_suite(Config) ->
+    ssl_test_lib:end_per_suite(Config).
 
 init_per_group(GroupName, Config) ->
     ssl_test_lib:init_per_group_openssl(GroupName, Config).
@@ -124,7 +110,7 @@ init_per_testcase(reuse_session_erlang_client, Config) ->
     ssl:start(),
     Config;
 init_per_testcase(reuse_session_erlang_server, Config) ->
-    case ssl_test_lib:working_openssl_client() of
+    case ssl_test_lib:working_openssl_client(Config) of
         true ->
             Version = ssl_test_lib:protocol_version(Config),
             case ssl_test_lib:is_dtls_version(Version) of
diff --git a/lib/ssl/test/openssl_session_ticket_SUITE.erl b/lib/ssl/test/openssl_session_ticket_SUITE.erl
index 8529afef77..caff7458d4 100644
--- a/lib/ssl/test/openssl_session_ticket_SUITE.erl
+++ b/lib/ssl/test/openssl_session_ticket_SUITE.erl
@@ -93,18 +93,11 @@ session_tests() ->
      openssl_client_early_data_basic].
 
 init_per_suite(Config0) ->
-    catch crypto:stop(),
-    try crypto:start() of
-	ok ->
-	    ssl_test_lib:clean_start(),
-            ssl_test_lib:make_rsa_cert(Config0)
-    catch _:_ ->
-	    {skip, "Crypto did not start"}
-    end.
-
-end_per_suite(_Config) ->
-    ssl:stop(),
-    application:stop(crypto).
+    Config = ssl_test_lib:init_per_suite(Config0, openssl),
+    ssl_test_lib:make_rsa_cert(Config).
+
+end_per_suite(Config) ->
+    ssl_test_lib:end_per_suite(Config).
 
 init_per_group(stateful, Config) ->
     [{server_ticket_mode, stateful} | proplists:delete(server_ticket_mode, Config)];
diff --git a/lib/ssl/test/openssl_sni_SUITE.erl b/lib/ssl/test/openssl_sni_SUITE.erl
index a6d9746164..a5ebbb35c4 100644
--- a/lib/ssl/test/openssl_sni_SUITE.erl
+++ b/lib/ssl/test/openssl_sni_SUITE.erl
@@ -98,33 +98,20 @@ sni_tests() ->
      sni_no_header_fun].
 
 init_per_suite(Config0) ->
-    catch crypto:stop(),
-    try crypto:start() of
-        ok ->
-            case check_openssl_sni_support(Config0) of
-                {skip, _} = Skip ->
-                    Skip;
-                Config1 ->
-                    %% Needed by version interop test in ssl_test_lib
-                    Config = ssl_test_lib:make_rsa_cert(Config1),
-                    ssl_test_lib:clean_start(),
-                    Hostname = net_adm:localhost(),
-                    {#{server_config := ServerConf,
-                       client_config := ClientConf},
-                     #{server_config := LServerConf,
-                       client_config := LClientConf}} = ssl_test_lib:make_rsa_sni_configs(),
-                    [{client_opts, ClientConf}, {client_local_opts, LClientConf},
-                     {sni_server_opts, [{sni_hosts, [{Hostname, ServerConf}]} | LServerConf]} | Config]
-            end
-    catch _:_  ->
-            {skip, "Crypto did not start"}
-    end.
+    Config1 = ssl_test_lib:init_per_suite(Config0, openssl),
+    Config2 = check_openssl_sni_support(Config1),
+    Config = ssl_test_lib:make_rsa_cert(Config2),
+    Hostname = net_adm:localhost(),
+    {#{server_config := ServerConf,
+       client_config := ClientConf},
+     #{server_config := LServerConf,
+       client_config := LClientConf}} = ssl_test_lib:make_rsa_sni_configs(),
+    [{client_opts, ClientConf}, {client_local_opts, LClientConf},
+     {sni_server_opts, [{sni_hosts, [{Hostname, ServerConf}]} | LServerConf]} | Config].
 
 
-end_per_suite(_Config) ->
-    ssl:stop(),
-    application:stop(crypto),
-    ssl_test_lib:kill_openssl().
+end_per_suite(Config) ->
+    ssl_test_lib:end_per_suite(Config).
 
 init_per_group(GroupName, Config) ->
     ssl_test_lib:init_per_group_openssl(GroupName, Config).
@@ -289,7 +276,7 @@ check_openssl_sni_support(Config) ->
     HelpText = ssl_test_lib:portable_cmd("openssl", ["s_client", "--help"]),
     case string:str(HelpText, "-servername") of
         0 ->
-            {skip, "Current openssl doesn't support SNI"};
+            throw({skip, "Current openssl doesn't support SNI"});
         _ ->
             case string:str(HelpText, "-noservername") of
                 0 ->
diff --git a/lib/ssl/test/openssl_tls_1_3_version_SUITE.erl b/lib/ssl/test/openssl_tls_1_3_version_SUITE.erl
index 7135d96b18..f7d4a33c7c 100644
--- a/lib/ssl/test/openssl_tls_1_3_version_SUITE.erl
+++ b/lib/ssl/test/openssl_tls_1_3_version_SUITE.erl
@@ -67,24 +67,17 @@ tests() ->
      %%tls13_client_with_ext_tls12_server,
      tls12_client_tls13_server].
     
-init_per_suite(Config) ->
-    catch crypto:stop(),
-    try crypto:start() of
-	ok ->
-            case ssl_test_lib:check_sane_openssl_version('tlsv1.3') of
-                true ->
-                    ssl_test_lib:clean_start(),
-                    Config;
-                false ->
-                    {skip, openssl_does_not_support_version}
-            end
-    catch _:_ ->
-	    {skip, "Crypto did not start"}
+init_per_suite(Config0) ->
+    Config = ssl_test_lib:init_per_suite(Config0, openssl),
+    case ssl_test_lib:check_sane_openssl_version('tlsv1.3', Config) of
+        true ->
+            Config;
+        false ->
+            {skip, openssl_does_not_support_version}
     end.
 
-end_per_suite(_Config) ->
-    ssl:stop(),
-    application:stop(crypto).
+end_per_suite(Config) ->
+    ssl_test_lib:end_per_suite(Config).
 
 init_per_group(GroupName, Config) ->
     case ssl_test_lib:is_protocol_version(GroupName) of
diff --git a/lib/ssl/test/ssl_mfl_SUITE.erl b/lib/ssl/test/ssl_mfl_SUITE.erl
index 0f9aeb1c67..a111c40339 100644
--- a/lib/ssl/test/ssl_mfl_SUITE.erl
+++ b/lib/ssl/test/ssl_mfl_SUITE.erl
@@ -72,20 +72,12 @@ pre_tls_1_3() ->
     [reuse_session].
 
 init_per_suite(Config0) ->
-    catch crypto:stop(),
-    try crypto:start() of
-	ok ->
-            ssl_test_lib:clean_start(),
-            ssl:clear_pem_cache(),
-	    Config = ssl_test_lib:make_rsa_cert(Config0),
-	    ssl_test_lib:cert_options(Config)
-    catch _:_ ->
-	    {skip, "Crypto did not start"}
-    end.
+    Config1 = ssl_test_lib:init_per_suite(Config0, openssl),
+    Config = ssl_test_lib:make_rsa_cert(Config1),
+    ssl_test_lib:cert_options(Config).
 
-end_per_suite(_Config) ->
-    ssl:stop(),
-    application:stop(crypto).
+end_per_suite(Config) ->
+    ssl_test_lib:end_per_suite(Config).
 
 init_per_group(GroupName, Config) ->
     ssl_test_lib:init_per_group(GroupName, Config).
diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl
index ba2493bd72..a190053b37 100644
--- a/lib/ssl/test/ssl_test_lib.erl
+++ b/lib/ssl/test/ssl_test_lib.erl
@@ -29,6 +29,7 @@
 -export([clean_start/0,
          clean_start/1,
          clean_env/0,
+         init_per_suite/2, end_per_suite/1,
          init_per_group/2,
          init_per_group_openssl/2,
          end_per_group/2,
@@ -105,7 +106,7 @@
          verify_server_early_data/3,
          verify_session_ticket_extension/2,
          update_session_ticket_extension/2,
-         check_sane_openssl_version/1,
+         check_sane_openssl_version/2,
          check_ok/1,
          check_result/4,
          check_result/2,
@@ -129,7 +130,7 @@
          hardcode_dsa_key/1,
          bigger_buffers/0,
          stop/2,
-         working_openssl_client/0,
+         working_openssl_client/1,
          hostname_format/1
         ]).
 
@@ -198,7 +199,6 @@
          openssl_allows_server_renegotiate/1,
          openssl_maxfraglen_support/0,
          is_sane_oppenssl_pss/1,
-         is_fips/1,
          consume_port_exit/1,
          is_sane_oppenssl_client/0,
          openssl_sane_dtls_session_reuse/0,
@@ -207,7 +207,7 @@
          openssl_ecdsa_suites/0,
          openssl_dsa_suites/0,
          enough_openssl_crl_support/1,
-         openssl_ocsp_support/0,
+         openssl_ocsp_support/1,
          openssl_allows_client_renegotiate/1,
          version_flag/1,
          portable_cmd/2,
@@ -301,8 +301,43 @@ get_client_opts(Config) ->
     COpts = proplists:get_value(client_opts, Config, DCOpts),
     ssl_options(COpts, Config).
 
+
+init_per_suite(Config0, Type) ->
+    end_per_suite(Config0),
+    try crypto:start() of
+	ok ->
+            clean_start(),
+            ssl:clear_pem_cache(),
+            case Type of
+                openssl ->
+                    Version = portable_cmd("openssl", ["version"]),
+                    case Version of
+                        "OpenSSL" ++ _ -> ok;
+                        "LibreSSL" ++ _ -> ok;
+                        _ -> throw({skip, "Unknown openssl version: " ++ Version})
+                    end,
+                    [{openssl_version, Version}|Config0];
+                _ ->
+                    Config0
+            end
+    catch _:_ ->
+            throw({skip, "Crypto did not start"})
+    end.
+
+end_per_suite(_Config) ->
+    application:stop(ssl),
+    application:stop(crypto),
+    ssl_test_lib:kill_openssl().
+
+
 %% Default callback functions
 init_per_group(GroupName, Config0) ->
+    case proplists:get_value(openssl_version, Config0) of
+        undefined ->
+            ok;
+        Version ->
+            put(openssl_version, Version)
+    end,
     case is_protocol_version(GroupName) andalso sufficient_crypto_support(GroupName) of
 	true ->
             Config = clean_protocol_version(Config0),
@@ -317,8 +352,8 @@ init_per_group(GroupName, Config0) ->
 	    end
     end.
 
-working_openssl_client() ->
-    case portable_cmd("openssl", ["version"]) of
+working_openssl_client(Config) ->
+    case proplists:get_value(openssl_version, Config) of
         %% These versions of OpenSSL has a client that
         %% can not handle hello extensions. And will
         %% fail with bad packet length if they are present
@@ -327,14 +362,25 @@ working_openssl_client() ->
             false;
         "OpenSSL 0.9.8k" ++ _ ->
             false;
-        _  ->
+        "OpenSSL" ++ _ ->
+            true;
+        "LibreSSL" ++ _ ->
             true
     end.
 
 init_per_group_openssl(GroupName, Config0) ->
-    case is_protocol_version(GroupName) andalso sufficient_crypto_support(GroupName) of
-	true ->
+    case proplists:get_value(openssl_version, Config0) of
+        undefined ->
+            ok;
+        Version ->
+            put(openssl_version, Version)
+    end,
+    CryptoSupport = sufficient_crypto_support(GroupName),
+    IsProtocolVersion = is_protocol_version(GroupName),
+    if
+	CryptoSupport andalso IsProtocolVersion ->
             Config = clean_protocol_version(Config0),
+            ssl:start(),
 	    case openssl_tls_version_support(GroupName, Config)
             of
 		true ->
@@ -342,14 +388,11 @@ init_per_group_openssl(GroupName, Config0) ->
 		false ->
 		    {skip, "Missing openssl support"}
 	    end;
-	_ ->
-            case sufficient_crypto_support(GroupName) of
-		true ->
-		    ssl:start(),
-		    Config0;
-		false ->
-		    {skip, "Missing crypto support"}
-	    end
+        CryptoSupport ->
+            ssl:start(),
+            Config0;
+        true ->
+            {skip, "Missing crypto support"}
     end.
 
 end_per_group(GroupName, Config) ->
@@ -360,8 +403,8 @@ end_per_group(GroupName, Config) ->
           Config
   end.
 
-openssl_ocsp_support() ->
-    case portable_cmd("openssl", ["version"]) of
+openssl_ocsp_support(Config) ->
+    case proplists:get_value(openssl_version, Config) of
         "OpenSSL 1.1.1" ++ _Rest ->
             true;
         _ ->
@@ -726,7 +769,12 @@ init_openssl_server(openssl, _, Options) ->
     DOpenssl = proplists:get_value(debug_openssl, Options, false),
     Port = inet_port(node()),
     Pid = proplists:get_value(from, Options),
-     
+
+    case proplists:get_value(openssl_version, Options) of
+        undefined -> ok;
+        Version -> put(openssl_version, Version)
+    end,
+
     Exe = "openssl",
     Ciphers = proplists:get_value(ciphers, Options, default_ciphers(Version)),
     Groups0 = proplists:get_value(groups, Options),
@@ -868,6 +916,11 @@ init_openssl_client(Options) ->
     Port = proplists:get_value(port, Options),
     Pid = proplists:get_value(from, Options),
     SslPort = start_client(openssl, Port, Options, [{version, Version}]),
+    case proplists:get_value(openssl_version, Options) of
+        undefined -> ok;
+        Version -> put(openssl_version, Version)
+    end,
+
     openssl_client_loop(Pid, SslPort, []).
 
 
@@ -3142,8 +3195,8 @@ is_sane_oppenssl_pss(rsa_pss_rsae) ->
             false
     end.
 
-is_fips(openssl) ->
-    VersionStr = portable_cmd("openssl",["version"]),
+is_fips(openssl, Config) ->
+    VersionStr = proplists:get_value(openssl_version, Config),
     case re:split(VersionStr, "fips") of
 	[_] ->
             case re:split(VersionStr, "FIPS") of
@@ -3155,16 +3208,14 @@ is_fips(openssl) ->
         _ ->
 	    true
     end;
-is_fips(crypto) ->
+is_fips(crypto, _) ->
     [{_,_, Bin}]  = crypto:info_lib(),
     case re:split(Bin, <<"fips">>) of
 	[_] ->
 	    false;
 	_ ->
 	    true
-    end;
-is_fips(_) ->
-    false.
+    end.
 
 %% Actual support is tested elsewhere, this is to exclude some LibreSSL and OpenSSL versions
 openssl_sane_dtls() -> 
@@ -3187,10 +3238,10 @@ openssl_sane_dtls() ->
             false
         end.
 
-check_sane_openssl_version(Version) ->
-    case supports_ssl_tls_version(Version) of 
+check_sane_openssl_version(Version, Config) ->
+    case supports_ssl_tls_version(Version, Config) of
 	true ->
-	    case {Version, portable_cmd("openssl",["version"])} of
+	    case {Version, proplists:get_value(openssl_version, Config)} of
                 {'dtlsv1', "OpenSSL 0" ++ _} ->
 		    false;
 		{'dtlsv1.2', "OpenSSL 0" ++ _} ->
@@ -3200,9 +3251,9 @@ check_sane_openssl_version(Version) ->
 		{'dtlsv1',  "OpenSSL 1.0.0" ++ _} ->
 		    false;
                 {'dtlsv1', _} ->
-		    not is_fips(openssl);
+		    not is_fips(openssl, Config);
 		{'dtlsv1.2', _} ->
-		    not is_fips(openssl);
+		    not is_fips(openssl, Config);
 		{_, "OpenSSL 1.0.2" ++ _} ->
 		    true;
 		{_, "OpenSSL 1.0.1" ++ _} ->
@@ -3226,7 +3277,7 @@ check_sane_openssl_version(Version) ->
 check_sane_openssl_renegotiate(Config, Version) when  Version == 'tlsv1';
                                                       Version == 'tlsv1.1';
                                                       Version == 'tlsv1.2' ->
-    case portable_cmd("openssl", ["version"]) of
+    case proplists:get_value(openssl_version, Config) of
 	"OpenSSL 1.0.1c" ++ _ ->
 	    {skip, "Known renegotiation bug in OpenSSL"};
 	"OpenSSL 1.0.1b" ++ _ ->
@@ -3246,7 +3297,7 @@ check_sane_openssl_renegotiate(Config, _) ->
     check_sane_openssl_renegotiate(Config).
 
 check_sane_openssl_renegotiate(Config) ->
-    case portable_cmd("openssl", ["version"]) of
+    case proplists:get_value(openssl_version, Config) of
 	"OpenSSL 1.0.0" ++ _ ->
 	    {skip, "Known renegotiation bug in OpenSSL"};
 	"OpenSSL 0.9.8" ++ _ ->
@@ -3262,7 +3313,7 @@ check_sane_openssl_renegotiate(Config) ->
     end.
 
 openssl_allows_client_renegotiate(Config) ->
-    case portable_cmd("openssl", ["version"]) of
+    case proplists:get_value(openssl_version, Config) of
         "OpenSSL 3" ++ _ ->
             {skip, "OpenSSL does not allow client renegotiation"};
 	"OpenSSL 1.1" ++ _ ->
@@ -3274,7 +3325,7 @@ openssl_allows_client_renegotiate(Config) ->
      end.
 
 openssl_allows_server_renegotiate(Config) ->
-     case portable_cmd("openssl", ["version"]) of
+    case proplists:get_value(openssl_version, Config) of
 	"LibreSSL 3.1" ++ _ ->
 	    {skip, "LibreSSL 3.1 does not allow server renegotiation"};
          _ ->
@@ -3392,6 +3443,17 @@ portable_open_port(Exe, Args) ->
     open_port({spawn_executable, AbsPath},
 	      [{args, Args}, stderr_to_stdout]).
 
+
+portable_cmd("openssl", ["version"]) ->
+    case get(openssl_version) of
+        undefined ->
+            Port = portable_open_port("openssl", ["version"]),
+            Version = collect_port_data(Port),
+            put(openssl_version, Version),
+            Version;
+        Version ->
+            Version
+    end;
 portable_cmd(Exe, Args) ->
     Port = portable_open_port(Exe, Args),
     collect_port_data(Port).
@@ -3413,12 +3475,13 @@ maybe_collect_more_port_data(Port, Acc) ->
             Acc
     end.
 
-supports_ssl_tls_version(Version) when Version == sslv2;
-                                       Version == sslv3 ->
+supports_ssl_tls_version(Version, Config) 
+  when Version == sslv2;
+       Version == sslv3 ->
 
     case ubuntu_legacy_support() of
         true ->   
-            case portable_cmd("openssl", ["version"]) of
+            case proplists:get_value(openssl_version, Config) of
                 "OpenSSL 1.0.1" ++ _ ->
                     Version =/= sslv2;
                 "OpenSSL 1" ++ _ ->
@@ -3441,7 +3504,7 @@ supports_ssl_tls_version(Version) when Version == sslv2;
         false ->
             false             
     end;
-supports_ssl_tls_version(Version) ->
+supports_ssl_tls_version(Version, _) ->
     VersionFlag = version_flag(Version),
     Exe = "openssl",
     Args = ["s_client", VersionFlag],
@@ -3883,8 +3946,8 @@ erlang_ssl_receive_and_assert_negotiated_protocol(Socket, Protocol, Data) ->
             {error, {{expected, Protocol}, {got, Result}}}
     end. 
 
-check_openssl_npn_support(_Config) ->
-    case ssl_test_lib:portable_cmd("openssl", ["version"]) of
+check_openssl_npn_support(Config) ->
+    case proplists:get_value(openssl_version, Config) of
         "OpenSSL 1.0"  ++ _  ->
             false;
         "OpenSSL 1.1" ++ _ ->
-- 
2.35.3

openSUSE Build Service is sponsored by