summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorIngela Anderton Andin <ingela@erlang.org>2019-11-08 09:46:25 +0100
committerIngela Anderton Andin <ingela@erlang.org>2019-11-21 08:48:17 +0100
commit893f7f84989bc8ae558963f924f911505bb9ec4c (patch)
treeae31716c0848d8c16ecc487eb80f596a8084c8df /lib
parentb51b7b883f2615869fde5923cc4aba9999eec470 (diff)
downloaderlang-893f7f84989bc8ae558963f924f911505bb9ec4c.tar.gz
ssl: Add statfull tickets
Diffstat (limited to 'lib')
-rw-r--r--lib/ssl/src/tls_handshake_1_3.erl60
-rw-r--r--lib/ssl/src/tls_server_session_ticket.erl153
-rw-r--r--lib/ssl/src/tls_socket.erl12
-rw-r--r--lib/ssl/test/ssl_session_ticket_SUITE.erl40
4 files changed, 198 insertions, 67 deletions
diff --git a/lib/ssl/src/tls_handshake_1_3.erl b/lib/ssl/src/tls_handshake_1_3.erl
index aa74d11d69..aceb0349aa 100644
--- a/lib/ssl/src/tls_handshake_1_3.erl
+++ b/lib/ssl/src/tls_handshake_1_3.erl
@@ -54,6 +54,7 @@
maybe_add_binders/4,
maybe_automatic_session_resumption/1]).
+-export([is_valid_binder/4]).
%% crypto:hash(sha256, "HelloRetryRequest").
-define(HELLO_RETRY_REQUEST_RANDOM, <<207,33,173,116,229,154,97,17,
@@ -364,6 +365,18 @@ decode_handshake(?KEY_UPDATE, <<?BYTE(Update)>>) ->
decode_handshake(Tag, HandshakeMsg) ->
ssl_handshake:decode_handshake({3,4}, Tag, HandshakeMsg).
+is_valid_binder(Binder, HHistory, PSK, Hash) ->
+ case HHistory of
+ [ClientHello2, HRR, MessageHash|_] ->
+ Truncated = truncate_client_hello(ClientHello2),
+ FinishedKey = calculate_finished_key(PSK, Hash),
+ Binder == calculate_binder(FinishedKey, Hash, [MessageHash, HRR, Truncated]);
+ [ClientHello1|_] ->
+ Truncated = truncate_client_hello(ClientHello1),
+ FinishedKey = calculate_finished_key(PSK, Hash),
+ Binder == calculate_binder(FinishedKey, Hash, Truncated)
+ end.
+
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
@@ -551,9 +564,6 @@ do_start(#client_hello{cipher_suites = ClientCiphers,
State1 = maybe_seed_session_tickets(OfferedPSKs, State0),
- %% Exclude any incompatible PSKs.
- PSK = Maybe(handle_pre_shared_key(State1, OfferedPSKs, Cipher)),
-
Groups = Maybe(select_common_groups(ServerGroups, ClientGroups)),
Maybe(validate_client_key_share(ClientGroups, ClientShares)),
@@ -589,9 +599,14 @@ do_start(#client_hello{cipher_suites = ClientCiphers,
%% message if it is able to find an acceptable set of parameters but the
%% ClientHello does not contain sufficient information to proceed with
%% the handshake.
- NextStateTuple = Maybe(send_hello_retry_request(State2, ClientPubKey, KeyShare, SessionId)),
- Maybe(session_resumption(NextStateTuple, PSK))
-
+ case Maybe(send_hello_retry_request(State2, ClientPubKey, KeyShare, SessionId)) of
+ {_, start} = NextStateTuple ->
+ NextStateTuple;
+ {_, negotiated} = NextStateTuple ->
+ %% Exclude any incompatible PSKs.
+ PSK = Maybe(handle_pre_shared_key(State2, OfferedPSKs, Cipher)),
+ Maybe(session_resumption(NextStateTuple, PSK))
+ end
catch
{Ref, {insufficient_security, no_suitable_groups}} ->
?ALERT_REC(?FATAL, ?INSUFFICIENT_SECURITY, no_suitable_groups);
@@ -1112,9 +1127,6 @@ send_hello_retry_request(State0, _, _, _) ->
%% Suitable key found.
{ok, {State0, negotiated}}.
-
-session_resumption({State, start}, _) ->
- {ok, {State, start}};
session_resumption({#state{ssl_options = #{session_tickets := disabled}} = State, negotiated}, _) ->
{ok, {State, negotiated}};
session_resumption({#state{ssl_options = #{session_tickets := Tickets}} = State, negotiated}, undefined)
@@ -1172,9 +1184,14 @@ maybe_send_session_ticket(#state{ssl_options = #{session_tickets := SessionTicke
when SessionTickets =/= disabled ->
State;
maybe_send_session_ticket(#state{ssl_options = #{session_tickets := stateful},
+ connection_states = ConnectionStates,
static_env = #static_env{trackers = Trackers}} = State0, N) ->
Tracker = proplists:get_value(session_tickets_tracker, Trackers),
- Ticket = tls_server_session_ticket:new(Tracker),
+ #{security_parameters := SecParamsR} =
+ ssl_record:current_connection_state(ConnectionStates, read),
+ #security_parameters{prf_algorithm = HKDF,
+ resumption_master_secret = RMS} = SecParamsR,
+ Ticket = tls_server_session_ticket:new(Tracker, HKDF, RMS),
{State, _} = tls_connection:send_handshake(Ticket, State0),
maybe_send_session_ticket(State, N - 1);
maybe_send_session_ticket(#state{
@@ -2211,8 +2228,16 @@ handle_pre_shared_key(_, undefined, _) ->
{ok, undefined};
handle_pre_shared_key(#state{ssl_options = #{session_tickets := disabled}}, _, _) ->
{ok, undefined};
+handle_pre_shared_key(#state{ssl_options = #{session_tickets := stateful},
+ handshake_env = #handshake_env{tls_handshake_history = {HHistory, _}},
+ static_env = #static_env{trackers = Trackers}}, OfferedPreSharedKeys, Cipher) ->
+ Tracker = proplists:get_value(session_tickets_tracker, Trackers),
+ #{prf := CipherHash} = ssl_cipher_format:suite_bin_to_map(Cipher),
+ IndexAndPSK = tls_server_session_ticket:use(Tracker, OfferedPreSharedKeys, CipherHash, HHistory),
+ {ok, IndexAndPSK};
handle_pre_shared_key(#state{handshake_env = #handshake_env{ticket_seed = Seed},
- ssl_options = #{anti_replay := BloomFilter}} = State, PreSharedKeys, Cipher) ->
+ ssl_options = #{session_tickets := stateless,
+ anti_replay := BloomFilter}} = State, PreSharedKeys, Cipher) ->
{IV, Shard} =
case Seed of
{_, {IV0, Shard0}} ->
@@ -2243,18 +2268,7 @@ validate_binder(#state{handshake_env = #handshake_env{tls_handshake_history = {H
static_env = #static_env{trackers = Trackers}},
{PSK, Index, Hash, Binder}, BloomFilter) ->
Tracker = proplists:get_value(session_tickets_tracker, Trackers),
- IsBinderValid =
- case HHistory of
- [ClientHello2, HRR, MessageHash|_] ->
- Truncated = truncate_client_hello(ClientHello2),
- FinishedKey = calculate_finished_key(PSK, Hash),
- Binder == calculate_binder(FinishedKey, Hash, [MessageHash, HRR, Truncated]);
- [ClientHello1|_] ->
- Truncated = truncate_client_hello(ClientHello1),
- FinishedKey = calculate_finished_key(PSK, Hash),
- Binder == calculate_binder(FinishedKey, Hash, Truncated)
- end,
- case IsBinderValid of
+ case is_valid_binder(Binder, HHistory, PSK, Hash) of
true ->
case check_replay(Tracker, Binder, BloomFilter) of
anti_replay_disabled ->
diff --git a/lib/ssl/src/tls_server_session_ticket.erl b/lib/ssl/src/tls_server_session_ticket.erl
index 3b5c36d203..94d9708320 100644
--- a/lib/ssl/src/tls_server_session_ticket.erl
+++ b/lib/ssl/src/tls_server_session_ticket.erl
@@ -31,7 +31,9 @@
%% API
-export([start_link/3,
new/1,
+ new/3,
new_with_seed/1,
+ use/4,
bloom_filter_add_elem/2,
bloom_filter_contains/2]).
@@ -44,6 +46,7 @@
-record(state, {
stateless,
stateful,
+ nonce,
lifetime
}).
@@ -58,11 +61,17 @@ start_link(Mode, Lifetime, AntiReplay) ->
gen_server:start_link(?MODULE, [Mode, Lifetime, AntiReplay], []).
new(Pid) ->
- gen_server:call(Pid, new_ticket, infinity).
+ gen_server:call(Pid, new_session_ticket, infinity).
+
+new(Pid, Prf, MasterSecret) ->
+ gen_server:call(Pid, {new_session_ticket, Prf, MasterSecret}, infinity).
new_with_seed(Pid) ->
gen_server:call(Pid, new_with_seed, infinity).
+use(Pid, Identifiers, Prf, HH) ->
+ gen_server:call(Pid, {use_ticket, Identifiers, Prf, HH}, infinity).
+
bloom_filter_add_elem(Pid, Elem) ->
gen_server:cast(Pid, {add_elem, Elem}).
@@ -83,24 +92,29 @@ init(Args) ->
-spec handle_call(Request :: term(), From :: {pid(), term()}, State :: term()) ->
{reply, Reply :: term(), NewState :: term()} .
-handle_call(new_ticket, _From, #state{stateless = #{nonce := Nonce} = Stateless} = State) ->
- Ticket = new_ticket(Nonce, State#state.lifetime),
- {reply, Ticket, State#state{stateless = Stateless#{nonce => Nonce + 1}}};
-handle_call(new_ticket, _From, State) ->
- Ticket = new_ticket(State),
- {reply, Ticket, State};
-handle_call(new_with_seed, _From, #state{stateless = #{nonce := Nonce, seed := Seed} = Stateless} = State) ->
- Ticket = new_ticket(Nonce, State#state.lifetime),
+handle_call({new_session_ticket, Prf, MasterSecret}, _From, #state{nonce = Nonce,
+ lifetime = LifeTime,
+ stateful = #{}} = State0) ->
+ Id = stateful_psk_id(),
+ PSK = tls_v1:pre_shared_key(MasterSecret, ticket_nonce(Nonce), Prf),
+ SessionTicket = new_session_ticket(Id, Nonce, LifeTime),
+ State = stateful_ticket_store(Id, SessionTicket, Prf, PSK, State0),
+ {reply, SessionTicket, State};
+handle_call(new_session_ticket, _From, #state{nonce = Nonce, stateless = #{}} = State) ->
+ BaseSessionTicket = new_session_ticket_base(State),
+ {reply, BaseSessionTicket, State#state{nonce = Nonce+1}};
+handle_call({use_ticket, Identifiers, Prf, HH}, _From, #state{stateful = #{}} = State0) ->
+ {IndexAndPSK, State} = stateful_use(Identifiers, Prf, HH, State0),
+ {reply, IndexAndPSK, State};
+handle_call(new_with_seed, _From, #state{nonce = Nonce, stateless = #{seed := Seed} = Stateless} = State) ->
+ Ticket = new_session_ticket_base(State),
{reply, {Ticket, Seed}, State#state{stateless = Stateless#{nonce => Nonce + 1}}};
-handle_call(new_with_seed, _From, #state{} = State) ->
- Ticket = new_ticket(State),
- {reply, {Ticket, no_seed}, State};
handle_call({contains, Elem}, _From, #state{stateless = #{bloom_filter := BloomFilter}} = State) ->
Reply = tls_bloom_filter:contains(BloomFilter, Elem),
{reply, Reply, State}.
-spec handle_cast(Request :: term(), State :: term()) ->
- {noreply, NewState :: term()}.
+ {noreply, NewState :: term()}.
handle_cast({add_elem, Elem}, #state{stateless = #{bloom_filter := BloomFilter0} = Stateless} = State) ->
BloomFilter = tls_bloom_filter:add_elem(BloomFilter0, Elem),
{noreply, State#state{stateless = Stateless#{bloom_filter => BloomFilter}}};
@@ -108,7 +122,7 @@ handle_cast(_Request, State) ->
{noreply, State}.
-spec handle_info(Info :: timeout() | term(), State :: term()) ->
- {noreply, NewState :: term()}.
+ {noreply, NewState :: term()}.
handle_info(rotate_bloom_filters, #state{stateless = #{bloom_filter := BloomFilter0,
window := Window} = Stateless} = State) ->
BloomFilter = tls_bloom_filter:rotate(BloomFilter0),
@@ -125,7 +139,7 @@ terminate(_Reason, _State) ->
-spec code_change(OldVsn :: term() | {down, term()},
State :: term(),
Extra :: term()) -> {ok, NewState :: term()} |
- {error, Reason :: term()}.
+ {error, Reason :: term()}.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
@@ -138,26 +152,31 @@ format_status(_Opt, Status) ->
%%% Internal functions
%%%===================================================================
-
inital_state([stateless, Lifetime, undefined]) ->
- #state{stateless = #{nonce => 0,
- seed => {crypto:strong_rand_bytes(16),
+ #state{nonce = 0,
+ stateless = #{seed => {crypto:strong_rand_bytes(16),
crypto:strong_rand_bytes(32)}},
lifetime = Lifetime
};
inital_state([stateless, Lifetime, {Window, K, M}]) ->
erlang:send_after(Window * 1000, self(), rotate_bloom_filters),
- #state{stateless = #{bloom_filter => tls_bloom_filter:new(K, M),
- nonce => 0,
+ #state{nonce = 0,
+ stateless = #{bloom_filter => tls_bloom_filter:new(K, M),
seed => {crypto:strong_rand_bytes(16),
crypto:strong_rand_bytes(32)},
windows => Window},
lifetime = Lifetime
};
-inital_state([stateful, Lifetime]) ->
+inital_state([stateful, Lifetime|_]) ->
+ %% statfeful servers replay
+ %% protection is that it saves
+ %% all valid tickets
#state{lifetime = Lifetime,
- stateful = #{db => gb_trees:empty(),
- max => 1000}
+ nonce = 0,
+ stateful = #{db => stateful_store(),
+ max => 1000,
+ ref_index => #{}
+ }
}.
ticket_age_add() ->
@@ -175,14 +194,96 @@ ticket_age_add() ->
ticket_nonce(I) ->
<<?UINT64(I)>>.
-new_ticket(Nonce, Lifetime) ->
+new_session_ticket_base(#state{nonce = Nonce,
+ lifetime = Lifetime}) ->
+ new_session_ticket(undefined, Nonce, Lifetime).
+
+new_session_ticket(Id, Nonce, Lifetime) ->
TicketAgeAdd = ticket_age_add(),
#new_session_ticket{
+ ticket = Id,
ticket_lifetime = Lifetime,
ticket_age_add = TicketAgeAdd,
ticket_nonce = ticket_nonce(Nonce),
extensions = #{}
}.
-new_ticket(_) ->
- #new_session_ticket{}.
+%%%===================================================================
+%%% Stateful store
+%%%===================================================================
+
+stateful_store() ->
+ gb_trees:empty().
+
+stateful_ticket_store(Ref, NewSessionTicket, Hash, Psk,
+ #state{nonce = Nonce,
+ stateful = #{db := Tree0,
+ max := Max,
+ ref_index := Index0} = Stateful} = State0) ->
+ Id = erlang:monotonic_time(),
+ StatefulTicket = {NewSessionTicket, Hash, Psk},
+ case gb_trees:size(Tree0) of
+ Max ->
+ %% Trow away oldes ticket
+ {_, {#new_session_ticket{ticket = OldRef},_,_}, Tree1}
+ = gb_trees:take_smallest(Tree0),
+ Tree = gb_trees:insert(Id, StatefulTicket, Tree1),
+ Index = maps:without([OldRef], Index0),
+ State0#state{nonce = Nonce+1, stateful =
+ Stateful#{db => Tree, ref_index => Index#{Ref => Id}}};
+ _ ->
+ Tree = gb_trees:insert(Id, StatefulTicket, Tree0),
+ State0#state{nonce = Nonce+1, stateful =
+ Stateful#{db => Tree, ref_index => Index0#{Ref => Id}}}
+ end.
+
+stateful_use(#offered_psks{
+ identities = Identities,
+ binders = Binders
+ }, Prf, HH, State) ->
+ stateful_use(Identities, Binders, Prf, HH, 0, State).
+
+stateful_use([], [], _, _, _, State) ->
+ {undefined, State};
+stateful_use([#psk_identity{identity = Ref} | Refs], [Binder | Binders], Prf, HH,
+ Index, #state{stateful = #{db := Tree0, ref_index := RefIndex0} = Stateful} = State) ->
+ try maps:get(Ref, RefIndex0) of
+ Key ->
+ case usable_ticket(Key, Prf, Binder, HH, Tree0) of
+ true ->
+ RefIndex = maps:without([Ref], RefIndex0),
+ {{_,_, PSK}, Tree} = gb_trees:take(Key, Tree0),
+ {{Index, PSK}, State#state{stateful = Stateful#{db => Tree, ref_index => RefIndex}}};
+ false ->
+ stateful_use(Refs, Binders, Prf, HH, Index + 1, State)
+ end
+ catch
+ _:{badkey, Ref} ->
+ stateful_use(Refs, Binders, Prf, HH, Index + 1, State)
+ end.
+
+usable_ticket(Key, Prf, Binder, HH, Tree) ->
+ case gb_trees:lookup(Key, Tree) of
+ none ->
+ false;
+ {value, {NewSessionTicket, Prf, PSK}} ->
+ case living_ticket(Key, NewSessionTicket) of
+ true ->
+ tls_handshake_1_3:is_valid_binder(Binder, HH, PSK, Prf);
+ false ->
+ false
+ end;
+ _ ->
+ false
+ end.
+
+living_ticket(TimeStamp, #new_session_ticket{ticket_lifetime = LifeTime}) ->
+ Now = erlang:monotonic_time(),
+ Lived = erlang:convert_time_unit(Now-TimeStamp, native, seconds),
+ Lived < LifeTime.
+
+
+stateful_psk_id() ->
+ term_to_binary(make_ref()).
+
+
diff --git a/lib/ssl/src/tls_socket.erl b/lib/ssl/src/tls_socket.erl
index ca97e91688..031665bfe8 100644
--- a/lib/ssl/src/tls_socket.erl
+++ b/lib/ssl/src/tls_socket.erl
@@ -78,7 +78,7 @@ listen(Transport, Port, #config{transport_info = {Transport, _, _, _, _},
{ok, ListenSocket} ->
{ok, Tracker} = inherit_tracker(ListenSocket, EmOpts, SslOpts),
%% TODO not hard code
- {ok, SessionHandler} = session_tickets_tracker(stateless, 7200, SslOpts),
+ {ok, SessionHandler} = session_tickets_tracker(7200, SslOpts),
Trackers = [{option_tracker, Tracker}, {session_tickets_tracker, SessionHandler}],
Socket = #sslsocket{pid = {ListenSocket, Config#config{trackers = Trackers}}},
check_active_n(EmOpts, Socket),
@@ -249,10 +249,14 @@ inherit_tracker(ListenSocket, EmOpts, #{erl_dist := false} = SslOpts) ->
inherit_tracker(ListenSocket, EmOpts, #{erl_dist := true} = SslOpts) ->
ssl_listen_tracker_sup:start_child_dist([ListenSocket, EmOpts, SslOpts]).
-session_tickets_tracker(Mode, Lifetime, #{erl_dist := false,
- anti_replay := AntiReplay}) ->
+session_tickets_tracker(_, #{erl_dist := false,
+ session_tickets := disabled}) ->
+ {ok, disabled};
+session_tickets_tracker(Lifetime, #{erl_dist := false,
+ session_tickets := Mode,
+ anti_replay := AntiReplay}) ->
tls_server_session_ticket_sup:start_child([Mode, Lifetime, AntiReplay]);
-session_tickets_tracker(Mode, Lifetime, #{erl_dist := true}) ->
+session_tickets_tracker(Lifetime, #{erl_dist := true, session_tickets := Mode}) ->
tls_server_session_ticket_sup:start_child_dist([Mode, Lifetime]).
diff --git a/lib/ssl/test/ssl_session_ticket_SUITE.erl b/lib/ssl/test/ssl_session_ticket_SUITE.erl
index 78cae6fab3..83e8e3214d 100644
--- a/lib/ssl/test/ssl_session_ticket_SUITE.erl
+++ b/lib/ssl/test/ssl_session_ticket_SUITE.erl
@@ -40,17 +40,20 @@ all() ->
].
groups() ->
- [{'tlsv1.3', [], session_tests()}].
+ [{'tlsv1.3', [], [{group, stateful}, {group, stateless}, {group, openssl_server}]},
+ {openssl_server, [], [erlang_client_openssl_server_basic,
+ erlang_client_openssl_server_hrr,
+ erlang_client_openssl_server_hrr_multiple_tickets
+ ]},
+ {stateful, [], session_tests()},
+ {stateless, [], session_tests()}].
session_tests() ->
[erlang_client_erlang_server_basic,
- erlang_client_openssl_server_basic,
openssl_client_erlang_server_basic,
erlang_client_erlang_server_hrr,
- erlang_client_openssl_server_hrr,
openssl_client_erlang_server_hrr,
erlang_client_erlang_server_multiple_tickets,
- erlang_client_openssl_server_hrr_multiple_tickets,
erlang_client_erlang_server_multiple_tickets_2hash].
init_per_suite(Config0) ->
@@ -58,8 +61,7 @@ init_per_suite(Config0) ->
try crypto:start() of
ok ->
ssl_test_lib:clean_start(),
- Config = ssl_test_lib:make_rsa_cert(Config0),
- ssl_test_lib:make_dsa_cert(Config)
+ ssl_test_lib:make_rsa_cert(Config0)
catch _:_ ->
{skip, "Crypto did not start"}
end.
@@ -68,6 +70,10 @@ end_per_suite(_Config) ->
ssl:stop(),
application:stop(crypto).
+init_per_group(stateful, Config) ->
+ [{server_ticket_mode, stateful} | proplists:delete(server_ticket_mode, Config)];
+init_per_group(stateless, Config) ->
+ [{server_ticket_mode, stateless} | proplists:delete(server_ticket_mode, Config)];
init_per_group(GroupName, Config) ->
ssl_test_lib:clean_tls_version(Config),
case ssl_test_lib:is_tls_version(GroupName) andalso ssl_test_lib:sufficient_crypto_support(GroupName) of
@@ -112,11 +118,12 @@ erlang_client_erlang_server_basic(Config) when is_list(Config) ->
ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ ServerTicketMode = proplists:get_value(server_ticket_mode, Config),
%% Configure session tickets
ClientOpts = [{session_tickets, auto}, {log_level, debug},
{versions, ['tlsv1.2','tlsv1.3']}|ClientOpts0],
- ServerOpts = [{session_tickets, stateless}, {log_level, debug},
+ ServerOpts = [{session_tickets, ServerTicketMode}, {log_level, debug},
{versions, ['tlsv1.2','tlsv1.3']}|ServerOpts0],
Server0 =
@@ -221,11 +228,12 @@ openssl_client_erlang_server_basic(Config) when is_list(Config) ->
{_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
TicketFile0 = filename:join([proplists:get_value(priv_dir, Config), "session_ticket0"]),
TicketFile1 = filename:join([proplists:get_value(priv_dir, Config), "session_ticket1"]),
+ ServerTicketMode = proplists:get_value(server_ticket_mode, Config),
Data = "Hello world",
%% Configure session tickets
- ServerOpts = [{session_tickets, stateless}, {log_level, debug},
+ ServerOpts = [{session_tickets, ServerTicketMode}, {log_level, debug},
{versions, ['tlsv1.2','tlsv1.3']}|ServerOpts0],
Server0 =
@@ -282,12 +290,13 @@ erlang_client_erlang_server_hrr(Config) when is_list(Config) ->
ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
+ ServerTicketMode = proplists:get_value(server_ticket_mode, Config),
+
%% Configure session tickets
ClientOpts = [{session_tickets, auto}, {log_level, debug},
{versions, ['tlsv1.2','tlsv1.3']},
{supported_groups,[secp256r1, x25519]}|ClientOpts0],
- ServerOpts = [{session_tickets, stateless}, {log_level, debug},
+ ServerOpts = [{session_tickets, ServerTicketMode}, {log_level, debug},
{versions, ['tlsv1.2','tlsv1.3']},
{supported_groups, [x448, x25519]}|ServerOpts0],
@@ -398,11 +407,12 @@ openssl_client_erlang_server_hrr(Config) when is_list(Config) ->
{_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
TicketFile0 = filename:join([proplists:get_value(priv_dir, Config), "session_ticket0"]),
TicketFile1 = filename:join([proplists:get_value(priv_dir, Config), "session_ticket1"]),
+ ServerTicketMode = proplists:get_value(server_ticket_mode, Config),
Data = "Hello world",
%% Configure session tickets
- ServerOpts = [{session_tickets, stateless}, {log_level, debug},
+ ServerOpts = [{session_tickets, ServerTicketMode}, {log_level, debug},
{versions, ['tlsv1.2','tlsv1.3']},
{supported_groups,[x448, x25519]}|ServerOpts0],
@@ -462,11 +472,12 @@ erlang_client_erlang_server_multiple_tickets(Config) when is_list(Config) ->
ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ ServerTicketMode = proplists:get_value(server_ticket_mode, Config),
%% Configure session tickets
ClientOpts = [{session_tickets, enabled}, {log_level, debug},
{versions, ['tlsv1.2','tlsv1.3']}|ClientOpts0],
- ServerOpts = [{session_tickets, stateless}, {log_level, debug},
+ ServerOpts = [{session_tickets, ServerTicketMode}, {log_level, debug},
{versions, ['tlsv1.2','tlsv1.3']}|ServerOpts0],
Server0 =
@@ -582,11 +593,12 @@ erlang_client_erlang_server_multiple_tickets_2hash(Config) when is_list(Config)
ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
+ ServerTicketMode = proplists:get_value(server_ticket_mode, Config),
+
%% Configure session tickets
ClientOpts = [{session_tickets, enabled}, {log_level, debug},
{versions, ['tlsv1.2','tlsv1.3']}|ClientOpts0],
- ServerOpts = [{session_tickets, stateless}, {log_level, debug},
+ ServerOpts = [{session_tickets, ServerTicketMode}, {log_level, debug},
{versions, ['tlsv1.2','tlsv1.3']}|ServerOpts0],
Server0 =