summaryrefslogtreecommitdiff
path: root/lib/ssl/src/ssl_session.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ssl/src/ssl_session.erl')
-rw-r--r--lib/ssl/src/ssl_session.erl39
1 files changed, 29 insertions, 10 deletions
diff --git a/lib/ssl/src/ssl_session.erl b/lib/ssl/src/ssl_session.erl
index 1b04f88d12..ccc5c9ded7 100644
--- a/lib/ssl/src/ssl_session.erl
+++ b/lib/ssl/src/ssl_session.erl
@@ -30,11 +30,22 @@
-include("ssl_api.hrl").
%% Internal application API
--export([is_new/2, client_select_session/4, server_select_session/5, valid_session/2]).
+-export([is_new/2, client_select_session/4, server_select_session/5, valid_session/2, legacy_session_id/0]).
-type seconds() :: integer().
%%--------------------------------------------------------------------
+-spec legacy_session_id() -> ssl:session_id().
+%%
+%% Description: TLS-1.3 deprecates the session id but has a dummy
+%% value for it for protocol backwards-compatibility reasons.
+%% If now lower versions are configured this function can be called
+%% for a dummy value.
+%%--------------------------------------------------------------------
+legacy_session_id() ->
+ crypto:strong_rand_bytes(32).
+
+%%--------------------------------------------------------------------
-spec is_new(ssl:session_id(), ssl:session_id()) -> boolean().
%%
%% Description: Checks if the session id decided by the server is a
@@ -63,7 +74,7 @@ client_select_session({_, _, #{versions := Versions,
case Version of
{3, N} when N >= 4 ->
- NewSession#session{session_id = crypto:strong_rand_bytes(32)};
+ NewSession#session{session_id = legacy_session_id()};
_ ->
do_client_select_session(ClientInfo, Cache, CacheCb, NewSession)
end.
@@ -100,7 +111,15 @@ valid_session(#session{time_stamp = TimeStamp}, LifeTime) ->
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
-
+do_client_select_session({_, _, #{reuse_session := {SessionId, SessionData}}}, _, _, NewSession) when is_binary(SessionId) andalso
+ is_binary(SessionData) ->
+ try binary_to_term(SessionData, [safe]) of
+ Session ->
+ Session
+ catch
+ _:_ ->
+ NewSession#session{session_id = <<>>}
+ end;
do_client_select_session({Host, Port, #{reuse_session := SessionId}}, Cache, CacheCb, NewSession) when is_binary(SessionId)->
case CacheCb:lookup(Cache, {{Host, Port}, SessionId}) of
undefined ->
@@ -109,8 +128,8 @@ do_client_select_session({Host, Port, #{reuse_session := SessionId}}, Cache, Cac
Session
end;
do_client_select_session(ClientInfo,
- Cache, CacheCb, #session{own_certificate = OwnCert} = NewSession) ->
- case select_session(ClientInfo, Cache, CacheCb, OwnCert) of
+ Cache, CacheCb, #session{own_certificates = OwnCerts} = NewSession) ->
+ case select_session(ClientInfo, Cache, CacheCb, OwnCerts) of
no_session ->
NewSession#session{session_id = <<>>};
Session ->
@@ -120,18 +139,18 @@ do_client_select_session(ClientInfo,
select_session({_, _, #{reuse_sessions := Reuse}}, _Cache, _CacheCb, _OwnCert) when Reuse =/= true ->
%% If reuse_sessions == false | save a new session should be created
no_session;
-select_session({HostIP, Port, SslOpts}, Cache, CacheCb, OwnCert) ->
+select_session({HostIP, Port, SslOpts}, Cache, CacheCb, OwnCerts) ->
Sessions = CacheCb:select_session(Cache, {HostIP, Port}),
- select_session(Sessions, SslOpts, OwnCert).
+ select_session(Sessions, SslOpts, OwnCerts).
select_session([], _, _) ->
no_session;
-select_session(Sessions, #{ciphers := Ciphers}, OwnCert) ->
+select_session(Sessions, #{ciphers := Ciphers}, OwnCerts) ->
IsNotResumable =
fun(Session) ->
not (resumable(Session#session.is_resumable) andalso
lists:member(Session#session.cipher_suite, Ciphers)
- andalso (OwnCert == Session#session.own_certificate))
+ andalso (OwnCerts == Session#session.own_certificates))
end,
case lists:dropwhile(IsNotResumable, Sessions) of
[] -> no_session;
@@ -143,7 +162,7 @@ is_resumable(_, _, #{reuse_sessions := false}, _) ->
is_resumable(SuggestedSessionId, SessIdTracker, #{reuse_session := ReuseFun} = Options, OwnCert) ->
case ssl_server_session_cache:reuse_session(SessIdTracker, SuggestedSessionId) of
#session{cipher_suite = CipherSuite,
- own_certificate = SessionOwnCert,
+ own_certificates = [SessionOwnCert | _],
compression_method = Compression,
is_resumable = IsResumable,
peer_certificate = PeerCert} = Session ->