diff options
Diffstat (limited to 'lib/ssl/src/ssl_session.erl')
-rw-r--r-- | lib/ssl/src/ssl_session.erl | 39 |
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 -> |