From ba4fb703a5c20ed26186d5ae968020819c1d8780 Mon Sep 17 00:00:00 2001
From: Ingela Anderton Andin <ingela@erlang.org>
Date: Fri, 4 Jan 2019 11:01:21 +0100
Subject: ssl: Add value 'save' to reuse_sessions and reuse_session client
 option

We want to be able to save a specific session to reuse, and make sure
it is reusable immediatly when the connection has been established.

Add client option {reuse_session, SessionID::binary()}

We also do not want clients to save sessions that it did not verify.

Additionaly change behaviour of the client and server to not save sessions
if reuse_session is set to false.
---
 lib/ssl/test/ssl_alpn_handshake_SUITE.erl |  44 +------
 lib/ssl/test/ssl_basic_SUITE.erl          | 196 +++++++-----------------------
 lib/ssl/test/ssl_npn_handshake_SUITE.erl  |  62 ++--------
 lib/ssl/test/ssl_session_cache_SUITE.erl  |  79 +++++++++++-
 lib/ssl/test/ssl_test_lib.erl             |  97 ++++++++++++++-
 5 files changed, 227 insertions(+), 251 deletions(-)

(limited to 'lib/ssl/test')

diff --git a/lib/ssl/test/ssl_alpn_handshake_SUITE.erl b/lib/ssl/test/ssl_alpn_handshake_SUITE.erl
index 04c4b257d9..7f7c3da5ab 100644
--- a/lib/ssl/test/ssl_alpn_handshake_SUITE.erl
+++ b/lib/ssl/test/ssl_alpn_handshake_SUITE.erl
@@ -262,52 +262,12 @@ client_renegotiate(Config) when is_list(Config) ->
 %--------------------------------------------------------------------------------
 
 session_reused(Config) when  is_list(Config)->
-    ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+    ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
     ClientOpts = [{alpn_advertised_protocols, [<<"http/1.0">>]}] ++ ClientOpts0,
     ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
     ServerOpts = [{alpn_preferred_protocols, [<<"spdy/2">>, <<"http/1.1">>, <<"http/1.0">>]}] ++  ServerOpts0,
 
-    {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-    Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
-                    {from, self()},
-                    {mfa, {ssl_test_lib, session_info_result, []}},
-					{options, ServerOpts}]),
-
-    Port = ssl_test_lib:inet_port(Server),
-    Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
-               {host, Hostname},
-               {from, self()},
-               {mfa, {ssl_test_lib, no_result_msg, []}},
-               {options, ClientOpts}]),
-
-    SessionInfo = 
-	receive
-	    {Server, Info} ->
-		Info
-	end,
-        
-    Server ! {listen, {mfa, {ssl_test_lib, no_result, []}}},
-    
-    %% Make sure session is registered
-    ct:sleep(?SLEEP),
-
-    Client1 =
-	ssl_test_lib:start_client([{node, ClientNode},
-				   {port, Port}, {host, Hostname},
-				   {mfa, {ssl_test_lib, session_info_result, []}},
-				   {from, self()},  {options, ClientOpts}]),
-
-      receive
-	{Client1, SessionInfo} ->
-	    ok;
-	{Client1, Other} ->
-	    ct:fail(Other)
-      end,
-    
-    ssl_test_lib:close(Server), 
-    ssl_test_lib:close(Client),
-    ssl_test_lib:close(Client1).
-
+    ssl_test_lib:reuse_session(ClientOpts, ServerOpts, Config).
 %--------------------------------------------------------------------------------
 
 alpn_not_supported_client(Config) when is_list(Config) ->
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
index fabc33f850..3778530a47 100644
--- a/lib/ssl/test/ssl_basic_SUITE.erl
+++ b/lib/ssl/test/ssl_basic_SUITE.erl
@@ -2688,175 +2688,69 @@ ciphers_ecdh_rsa_signed_certs_openssl_names(Config) when is_list(Config) ->
 reuse_session() ->
     [{doc,"Test reuse of sessions (short handshake)"}].
 reuse_session(Config) when is_list(Config) -> 
-    ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
-    ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
-    {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
-    Server = 
-	ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, 
-				   {from, self()},
-				   {mfa, {ssl_test_lib, session_info_result, []}},
-				   {options, ServerOpts}]),
-    Port = ssl_test_lib:inet_port(Server),
-    Client0 =
-	ssl_test_lib:start_client([{node, ClientNode}, 
-		      {port, Port}, {host, Hostname},
-				   {mfa, {ssl_test_lib, no_result, []}},
-		      {from, self()},  {options, ClientOpts}]),   
-    SessionInfo = 
-	receive
-	    {Server, Info} ->
-		Info
-	end,
-       
-    Server ! {listen, {mfa, {ssl_test_lib, no_result, []}}},
-    
-    %% Make sure session is registered
-    ct:sleep(?SLEEP),
-
-    Client1 =
-	ssl_test_lib:start_client([{node, ClientNode},
-				   {port, Port}, {host, Hostname},
-				   {mfa, {ssl_test_lib, session_info_result, []}},
-				   {from, self()},  {options, ClientOpts}]),
-    receive
-	{Client1, SessionInfo} ->
-	    ok;
-	{Client1, Other} ->
-	    ct:log("Expected: ~p,  Unexpected: ~p~n",
-			       [SessionInfo, Other]),
-	    ct:fail(session_not_reused)
-    end,
-    
-    Server !  {listen, {mfa, {ssl_test_lib, no_result, []}}},
-    
-    Client2 =
-	ssl_test_lib:start_client([{node, ClientNode},
-		      {port, Port}, {host, Hostname},
-			    {mfa, {ssl_test_lib, session_info_result, []}},
-		      {from, self()},  {options, [{reuse_sessions, false}
-						  | ClientOpts]}]),   
-    receive
-	{Client2, SessionInfo} ->
-	    ct:fail(
-	      session_reused_when_session_reuse_disabled_by_client);
-	{Client2, _} ->
-	    ok
-    end,
-    
-    ssl_test_lib:close(Server),
-
-    Server1 = 
-	ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, 
-				   {from, self()},
-		      {mfa, {ssl_test_lib, session_info_result, []}},
-		      {options, [{reuse_sessions, false} | ServerOpts]}]),
-    
-    Port1 = ssl_test_lib:inet_port(Server1),
-    Client3 =
-	ssl_test_lib:start_client([{node, ClientNode}, 
-				   {port, Port1}, {host, Hostname},
-				   {mfa, {ssl_test_lib, no_result, []}},
-				   {from, self()},  {options, ClientOpts}]), 
-
-    SessionInfo1 = 
-	receive
-	    {Server1, Info1} ->
-		Info1
-	end,
-       
-    Server1 ! {listen, {mfa, {ssl_test_lib, no_result, []}}},
-    
-    %% Make sure session is registered
-    ct:sleep(?SLEEP),
-
-    Client4 = 
-	ssl_test_lib:start_client([{node, ClientNode}, 
-				   {port, Port1}, {host, Hostname},
-				   {mfa, {ssl_test_lib, session_info_result, []}},
-				   {from, self()},  {options, ClientOpts}]),
+    ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
+    ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
     
-    receive
-	{Client4, SessionInfo1} ->
-	    ct:fail(
-	      session_reused_when_session_reuse_disabled_by_server);
-	{Client4, _Other} ->
-	    ct:log("OTHER: ~p ~n", [_Other]),
-	    ok
-    end,
-
-    ssl_test_lib:close(Server1),
-    ssl_test_lib:close(Client0),
-    ssl_test_lib:close(Client1),
-    ssl_test_lib:close(Client2),
-    ssl_test_lib:close(Client3),
-    ssl_test_lib:close(Client4).
-
+    ssl_test_lib:reuse_session(ClientOpts, ServerOpts, Config).
 %%--------------------------------------------------------------------
 reuse_session_expired() ->
     [{doc,"Test sessions is not reused when it has expired"}].
 reuse_session_expired(Config) when is_list(Config) -> 
-    ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
-    ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
+    ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
+    ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
     {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
-    Server = 
-	ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, 
+    
+    Server0 =
+	ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
 				   {from, self()},
-		      {mfa, {ssl_test_lib, session_info_result, []}},
-		      {options, ServerOpts}]),
-    Port = ssl_test_lib:inet_port(Server),
-    Client0 =
-	ssl_test_lib:start_client([{node, ClientNode}, 
-		      {port, Port}, {host, Hostname},
-			    {mfa, {ssl_test_lib, no_result, []}},
-		      {from, self()},  {options, ClientOpts}]),   
-    SessionInfo = 
-	receive
-	    {Server, Info} ->
-		Info
-	end,
-
-    Server ! {listen, {mfa, {ssl_test_lib, no_result, []}}},
+				   {mfa, {ssl_test_lib, no_result, []}},
+				   {tcp_options, [{active, false}]},
+				   {options, ServerOpts}]),
+    Port0 = ssl_test_lib:inet_port(Server0),
     
-    %% Make sure session is registered
-    ct:sleep(?SLEEP),
-
-    Client1 =
-	ssl_test_lib:start_client([{node, ClientNode}, 
-		      {port, Port}, {host, Hostname},
-		      {mfa, {ssl_test_lib, session_info_result, []}},
-		      {from, self()},  {options, ClientOpts}]),    
+    Client0 = ssl_test_lib:start_client([{node, ClientNode},
+                                         {port, Port0}, {host, Hostname},
+                                         {mfa, {ssl_test_lib, session_id, []}},
+                                         {from, self()},  {options, [{reuse_sessions, save} | ClientOpts]}]),
+    Server0 ! listen,
+    
+    Client1 = ssl_test_lib:start_client([{node, ClientNode},
+                                         {port, Port0}, {host, Hostname},
+                                         {mfa, {ssl_test_lib, session_id, []}},
+                                         {from, self()},  {options, ClientOpts}]),    
+    
+    SID = receive
+              {Client0, Id0} ->
+                  Id0
+          end,
+       
     receive
-	{Client1, SessionInfo} ->
-	    ok;
-	{Client1, Other} ->
-	    ct:log("Expected: ~p,  Unexpected: ~p~n",
-			       [SessionInfo, Other]),
-	    ct:fail(session_not_reused)
+        {Client1, SID} ->
+            ok
+    after ?SLEEP ->
+              ct:fail(session_not_reused)
     end,
     
-    Server ! listen,
-
+    Server0 ! listen,
+    
     %% Make sure session is unregistered due to expiration
-    ct:sleep((?EXPIRE+1)),
-    [{session_id, Id} |_] = SessionInfo,
+    ct:sleep((?EXPIRE*2)),
 
-    make_sure_expired(Hostname, Port, Id),
+    make_sure_expired(Hostname, Port0, SID),
     
     Client2 =
 	ssl_test_lib:start_client([{node, ClientNode}, 
-				   {port, Port}, {host, Hostname},
-				   {mfa, {ssl_test_lib, session_info_result, []}},
+				   {port, Port0}, {host, Hostname},
+				   {mfa, {ssl_test_lib, session_id, []}},
 				   {from, self()}, {options, ClientOpts}]),   
     receive
-	{Client2, SessionInfo} ->
+	{Client2, SID} ->
 	    ct:fail(session_reused_when_session_expired);
 	{Client2, _} ->
 	    ok
     end,
     process_flag(trap_exit, false),
-    ssl_test_lib:close(Server),
+    ssl_test_lib:close(Server0),
     ssl_test_lib:close(Client0),
     ssl_test_lib:close(Client1),
     ssl_test_lib:close(Client2).
@@ -2865,16 +2759,16 @@ make_sure_expired(Host, Port, Id) ->
     {status, _, _, StatusInfo} = sys:get_status(whereis(ssl_manager)),
     [_, _,_, _, Prop] = StatusInfo,
     State = ssl_test_lib:state(Prop),
-    Cache = element(2, State),
+    ClientCache = element(2, State),
 
-    case ssl_session_cache:lookup(Cache, {{Host,  Port}, Id}) of
+    case ssl_session_cache:lookup(ClientCache, {{Host,  Port}, Id}) of
 	undefined ->
-	   ok;
+   	   ok; 
 	#session{is_resumable = false} ->
-	   ok;
+   	   ok;
 	_ ->
 	    ct:sleep(?SLEEP),
-	    make_sure_expired(Host, Port, Id)
+            make_sure_expired(Host, Port, Id)
     end.     
 
 %%--------------------------------------------------------------------
diff --git a/lib/ssl/test/ssl_npn_handshake_SUITE.erl b/lib/ssl/test/ssl_npn_handshake_SUITE.erl
index 1c7d6b5f9f..878e983bb9 100644
--- a/lib/ssl/test/ssl_npn_handshake_SUITE.erl
+++ b/lib/ssl/test/ssl_npn_handshake_SUITE.erl
@@ -64,13 +64,12 @@ next_protocol_not_supported() ->
      npn_not_supported_server
     ].
 
-init_per_suite(Config) ->
+init_per_suite(Config0) ->
     catch crypto:stop(),
     try crypto:start() of
 	ok ->
 	    ssl_test_lib:clean_start(),
-	    {ok, _} = make_certs:all(proplists:get_value(data_dir, Config),
-				      proplists:get_value(priv_dir, Config)),
+	    Config = ssl_test_lib:make_rsa_cert(Config0),
 	    ssl_test_lib:cert_options(Config)
     catch _:_ ->
 	    {skip, "Crypto did not start"}
@@ -196,10 +195,10 @@ client_negotiate_server_does_not_support(Config) when is_list(Config) ->
 renegotiate_from_client_after_npn_handshake(Config) when is_list(Config) ->
     Data = "hello world",
     
-    ClientOpts0 = ssl_test_lib:ssl_options(client_opts, Config),
+    ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
     ClientOpts = [{client_preferred_next_protocols,
 		   {client, [<<"http/1.0">>], <<"http/1.1">>}}] ++ ClientOpts0,
-    ServerOpts0 = ssl_test_lib:ssl_options(server_opts, Config),
+    ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
     ServerOpts = [{next_protocols_advertised,
 		   [<<"spdy/2">>, <<"http/1.1">>, <<"http/1.0">>]}] ++  ServerOpts0,
     ExpectedProtocol = {ok, <<"http/1.0">>},
@@ -221,7 +220,7 @@ renegotiate_from_client_after_npn_handshake(Config) when is_list(Config) ->
 
 %--------------------------------------------------------------------------------
 npn_not_supported_client(Config) when is_list(Config) ->
-    ClientOpts0 = ssl_test_lib:ssl_options(client_opts, Config),
+    ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
     PrefProtocols = {client_preferred_next_protocols,
 		     {client, [<<"http/1.0">>], <<"http/1.1">>}},
     ClientOpts = [PrefProtocols] ++ ClientOpts0,
@@ -236,7 +235,7 @@ npn_not_supported_client(Config) when is_list(Config) ->
 
 %--------------------------------------------------------------------------------
 npn_not_supported_server(Config) when is_list(Config)->
-    ServerOpts0 = ssl_test_lib:ssl_options(server_opts, Config),
+    ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
     AdvProtocols = {next_protocols_advertised, [<<"spdy/2">>, <<"http/1.1">>, <<"http/1.0">>]},
     ServerOpts = [AdvProtocols] ++  ServerOpts0,
   
@@ -244,63 +243,24 @@ npn_not_supported_server(Config) when is_list(Config)->
 
 %--------------------------------------------------------------------------------
 npn_handshake_session_reused(Config) when  is_list(Config)->
-    ClientOpts0 = ssl_test_lib:ssl_options(client_opts, Config),
+    ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
     ClientOpts = [{client_preferred_next_protocols,
 		   {client, [<<"http/1.0">>], <<"http/1.1">>}}] ++ ClientOpts0,
-    ServerOpts0 = ssl_test_lib:ssl_options(server_opts, Config),
+    ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
     ServerOpts =[{next_protocols_advertised,
 		   [<<"spdy/2">>, <<"http/1.1">>, <<"http/1.0">>]}]  ++ ServerOpts0,
 
-    {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-    Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
-                    {from, self()},
-                    {mfa, {ssl_test_lib, session_info_result, []}},
-					{options, ServerOpts}]),
-
-    Port = ssl_test_lib:inet_port(Server),
-    Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
-               {host, Hostname},
-               {from, self()},
-               {mfa, {ssl_test_lib, no_result_msg, []}},
-               {options, ClientOpts}]),
-
-    SessionInfo = 
-	receive
-	    {Server, Info} ->
-		Info
-	end,
-        
-    Server ! {listen, {mfa, {ssl_test_lib, no_result, []}}},
-    
-    %% Make sure session is registered
-    ct:sleep(?SLEEP),
-
-    Client1 =
-	ssl_test_lib:start_client([{node, ClientNode},
-				   {port, Port}, {host, Hostname},
-				   {mfa, {ssl_test_lib, session_info_result, []}},
-				   {from, self()},  {options, ClientOpts}]),
-
-      receive
-	{Client1, SessionInfo} ->
-	    ok;
-	{Client1, Other} ->
-	    ct:fail(Other)
-      end,
+    ssl_test_lib:reuse_session(ClientOpts, ServerOpts, Config).
     
-    ssl_test_lib:close(Server), 
-    ssl_test_lib:close(Client),
-    ssl_test_lib:close(Client1).
-
 %%--------------------------------------------------------------------
 %% Internal functions ------------------------------------------------
 %%--------------------------------------------------------------------
 run_npn_handshake(Config, ClientExtraOpts, ServerExtraOpts, ExpectedProtocol) ->
     Data = "hello world",
 
-    ClientOpts0 = ssl_test_lib:ssl_options(client_opts, Config),
+    ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
     ClientOpts = ClientExtraOpts ++ ClientOpts0,
-    ServerOpts0 = ssl_test_lib:ssl_options(server_opts, Config),
+    ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_opts, Config),
     ServerOpts = ServerExtraOpts ++  ServerOpts0,
 
     {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
diff --git a/lib/ssl/test/ssl_session_cache_SUITE.erl b/lib/ssl/test/ssl_session_cache_SUITE.erl
index 8c96f4b2bf..7f33fe3204 100644
--- a/lib/ssl/test/ssl_session_cache_SUITE.erl
+++ b/lib/ssl/test/ssl_session_cache_SUITE.erl
@@ -48,7 +48,8 @@ all() ->
      session_cache_process_list,
      session_cache_process_mnesia,
      client_unique_session,
-     max_table_size
+     max_table_size,
+     save_specific_session
      ].
 
 groups() ->
@@ -94,7 +95,10 @@ init_per_testcase(session_cleanup, Config) ->
 init_per_testcase(client_unique_session, Config) ->
     ct:timetrap({seconds, 40}),
     Config;
-
+init_per_testcase(save_specific_session, Config) ->
+    ssl_test_lib:clean_start(),
+    ct:timetrap({seconds, 5}),
+    Config;
 init_per_testcase(max_table_size, Config) ->
     ssl:stop(),
     application:load(ssl),
@@ -138,7 +142,7 @@ end_per_testcase(max_table_size, Config) ->
     end_per_testcase(default_action, Config);
 end_per_testcase(Case, Config) when Case == session_cache_process_list;
 				    Case == session_cache_process_mnesia ->
-    ets:delete(ssl_test),
+    catch ets:delete(ssl_test),
     Config;
 end_per_testcase(_, Config) ->
     Config.
@@ -249,6 +253,68 @@ session_cache_process_mnesia() ->
 session_cache_process_mnesia(Config) when is_list(Config) ->
     session_cache_process(mnesia,Config).
 
+%%--------------------------------------------------------------------
+save_specific_session() ->
+    [{doc, "Test that we can save a specific client session"
+     }].
+save_specific_session(Config) when is_list(Config) ->
+    process_flag(trap_exit, true),
+    ClientOpts = proplists:get_value(client_rsa_verify_opts, Config),
+    ServerOpts = proplists:get_value(server_rsa_opts, Config),
+    {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+    Server =
+	ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+				   {from, self()},
+				   {mfa, {ssl_test_lib, no_result, []}},
+				   {tcp_options, [{active, false}]},
+				   {options, ServerOpts}]),
+    Port = ssl_test_lib:inet_port(Server),
+    
+    Client1 = ssl_test_lib:start_client([{node, ClientNode},
+                                         {port, Port}, {host, Hostname},
+                                         {mfa, {ssl_test_lib, session_id, []}},
+                                         {from, self()},  {options, ClientOpts}]),
+    Server ! listen,
+    
+    Client2 = ssl_test_lib:start_client([{node, ClientNode},
+                                         {port, Port}, {host, Hostname},
+                                         {mfa, {ssl_test_lib, session_id, []}},
+                                         {from, self()},  {options, [{reuse_sessions, save} | ClientOpts]}]),    
+    SessionID1 =
+        receive 
+            {Client1, S1} ->
+                S1
+        end,
+    
+    SessionID2 =
+        receive 
+            {Client2, S2} ->
+                S2
+        end,
+    
+    true = SessionID1 =/= SessionID2,
+
+    {status, _, _, StatusInfo} = sys:get_status(whereis(ssl_manager)),
+    [_, _,_, _, Prop] = StatusInfo,
+    State = ssl_test_lib:state(Prop),
+    ClientCache = element(2, State),
+    2 = ssl_session_cache:size(ClientCache),
+
+    Server ! listen,
+
+    Client3 = ssl_test_lib:start_client([{node, ClientNode},
+                                         {port, Port}, {host, Hostname},
+                                         {mfa, {ssl_test_lib, session_id, []}},
+                                         {from, self()},  {options, [{reuse_session, SessionID2} | ClientOpts]}]), 
+    receive 
+        {Client3, SessionID2} ->
+            ok;
+        {Client3, SessionID3}->
+            ct:fail({got, SessionID3, expected, SessionID2});
+        Other ->
+            ct:fail({got,Other})
+    end.
+
 %%--------------------------------------------------------------------
 
 max_table_size() ->
@@ -422,9 +488,10 @@ session_loop(Sess) ->
 %%--------------------------------------------------------------------
 
 session_cache_process(_Type,Config) when is_list(Config) ->
-    ClientOpts = proplists:get_value(client_rsa_verify_opts, Config),
-    ServerOpts = proplists:get_value(server_rsa_opts, Config),
-    ssl_basic_SUITE:reuse_session([{client_opts, ClientOpts}, {server_opts, ServerOpts}| Config]).
+    ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
+    ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+    ssl_test_lib:reuse_session(ClientOpts, ServerOpts, Config).
+
 
 clients_start(_Server, ClientNode, Hostname, Port, ClientOpts, 0) ->
     %% Make sure session is registered
diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl
index 929b1ae12a..681bc14f10 100644
--- a/lib/ssl/test/ssl_test_lib.erl
+++ b/lib/ssl/test/ssl_test_lib.erl
@@ -523,7 +523,7 @@ cert_options(Config) ->
      {client_verification_opts, [{cacertfile, ServerCaCertFile}, 
 				{certfile, ClientCertFile},  
 				{keyfile, ClientKeyFile},
-				{ssl_imp, new}]}, 
+				{verify, verify_peer}]}, 
      {client_verification_opts_digital_signature_only, [{cacertfile, ServerCaCertFile},
 				{certfile, ClientCertFileDigitalSignatureOnly},
 				{keyfile, ClientKeyFile},
@@ -2186,3 +2186,98 @@ server_msg(Server, ServerMsg) ->
 	Unexpected ->
 	    ct:fail(Unexpected)
     end.
+
+session_id(Socket) ->
+    {ok, [{session_id, ID}]} = ssl:connection_information(Socket, [session_id]),
+    ID.
+    
+reuse_session(ClientOpts, ServerOpts, Config) ->
+    {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+    
+    Server0 =
+	ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+				   {from, self()},
+				   {mfa, {ssl_test_lib, no_result, []}},
+				   {tcp_options, [{active, false}]},
+				   {options, ServerOpts}]),
+    Port0 = ssl_test_lib:inet_port(Server0),
+    
+    Client0 = ssl_test_lib:start_client([{node, ClientNode},
+                                         {port, Port0}, {host, Hostname},
+                                         {mfa, {ssl_test_lib, session_id, []}},
+                                         {from, self()},  {options, [{reuse_sessions, save} | ClientOpts]}]),
+    Server0 ! listen,
+    
+    Client1 = ssl_test_lib:start_client([{node, ClientNode},
+                                         {port, Port0}, {host, Hostname},
+                                         {mfa, {ssl_test_lib, session_id, []}},
+                                         {from, self()},  {options, ClientOpts}]),    
+
+    SID = receive
+              {Client0, Id0} ->
+                  Id0
+          end,
+       
+    receive
+        {Client1, SID} ->
+            ok
+    after ?SLEEP ->
+              ct:fail(session_not_reused)
+    end,
+  
+    Server0 ! listen,
+    
+    Client2 =
+        ssl_test_lib:start_client([{node, ClientNode},
+                                   {port, Port0}, {host, Hostname},
+                                   {mfa, {ssl_test_lib, session_id, []}},
+                                   {from, self()},  {options, [{reuse_sessions, false}
+         					  | ClientOpts]}]),   
+    receive
+         {Client2, SID} ->
+            ct:fail(session_reused_when_session_reuse_disabled_by_client);
+         {Client2, _} ->
+            ok
+    end,
+    
+    ssl_test_lib:close(Server0),
+    ssl_test_lib:close(Client0),
+    ssl_test_lib:close(Client1),
+    ssl_test_lib:close(Client2),
+    
+    Server1 =
+	ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+				   {from, self()},
+				   {mfa, {ssl_test_lib, no_result, []}},
+				   {tcp_options, [{active, false}]},
+				   {options, [{reuse_sessions, false} |ServerOpts]}]),
+    Port1 = ssl_test_lib:inet_port(Server1),
+    
+    Client3 = ssl_test_lib:start_client([{node, ClientNode},
+                                         {port, Port1}, {host, Hostname},
+                                         {mfa, {ssl_test_lib, session_id, []}},
+                                         {from, self()},  {options, [{reuse_sessions, save} | ClientOpts]}]),
+    SID1 = receive
+               {Client3, Id3} ->
+                   Id3
+           end,
+
+    Server1 ! listen,
+    
+    Client4 =
+        ssl_test_lib:start_client([{node, ClientNode},
+                                   {port, Port1}, {host, Hostname},
+                                   {mfa, {ssl_test_lib, session_id, []}},
+                                   {from, self()},  {options, ClientOpts}]),   
+   
+    receive
+        {Client4, SID1} ->
+            ct:fail(session_reused_when_session_reuse_disabled_by_server);
+        {Client4, _} ->
+            ok
+    end,
+    
+    ssl_test_lib:close(Server1),
+    ssl_test_lib:close(Client3),
+    ssl_test_lib:close(Client4).
+    
-- 
cgit v1.2.3