28
28
-include("ssl_internal.hrl").
30
30
%% Internal application API
31
-export([is_new/2, id/3, id/6, valid_session/2]).
31
-export([is_new/2, id/4, id/7, valid_session/2]).
33
33
-define(GEN_UNIQUE_ID_MAX_TRIES, 10).
35
-type seconds() :: integer().
35
37
%%--------------------------------------------------------------------
36
%% Function: is_new(ClientSuggestedId, ServerDecidedId) -> true | false
38
%% ClientSuggestedId = binary()
39
%% ServerDecidedId = binary()
38
-spec is_new(session_id(), session_id()) -> boolean().
41
40
%% Description: Checks if the session id decided by the server is a
42
41
%% new or resumed sesion id.
46
45
is_new(SessionId, SessionId) ->
47
is_new(_ClientSuggestion, _ServerDecision) ->
51
50
%%--------------------------------------------------------------------
52
%% Function: id(ClientInfo, Cache, CacheCb) -> SessionId
54
%% ClientInfo = {HostIP, Port, SslOpts}
55
%% HostIP = ipadress()
58
%% SessionId = binary()
51
-spec id({host(), port_num(), #ssl_options{}}, cache_ref(), atom(),
52
undefined | binary()) -> binary().
60
54
%% Description: Should be called by the client side to get an id
61
55
%% for the client hello message.
62
56
%%--------------------------------------------------------------------
63
id(ClientInfo, Cache, CacheCb) ->
64
case select_session(ClientInfo, Cache, CacheCb) of
57
id(ClientInfo, Cache, CacheCb, OwnCert) ->
58
case select_session(ClientInfo, Cache, CacheCb, OwnCert) of
71
65
%%--------------------------------------------------------------------
72
%% Function: id(Port, SuggestedSessionId, ReuseFun, CacheCb,
73
%% SecondLifeTime) -> SessionId
76
%% SuggestedSessionId = SessionId = binary()
77
%% ReuseFun = fun(SessionId, PeerCert, Compression, CipherSuite) ->
66
-spec id(port_num(), binary(), #ssl_options{}, cache_ref(),
67
atom(), seconds(), binary()) -> binary().
81
69
%% Description: Should be called by the server side to get an id
82
70
%% for the server hello message.
83
71
%%--------------------------------------------------------------------
84
id(Port, <<>>, _, Cache, CacheCb, _) ->
72
id(Port, <<>>, _, Cache, CacheCb, _, _) ->
85
73
new_id(Port, ?GEN_UNIQUE_ID_MAX_TRIES, Cache, CacheCb);
87
75
id(Port, SuggestedSessionId, #ssl_options{reuse_sessions = ReuseEnabled,
88
76
reuse_session = ReuseFun},
89
Cache, CacheCb, SecondLifeTime) ->
77
Cache, CacheCb, SecondLifeTime, OwnCert) ->
90
78
case is_resumable(SuggestedSessionId, Port, ReuseEnabled,
91
ReuseFun, Cache, CacheCb, SecondLifeTime) of
79
ReuseFun, Cache, CacheCb, SecondLifeTime, OwnCert) of
93
81
SuggestedSessionId;
95
83
new_id(Port, ?GEN_UNIQUE_ID_MAX_TRIES, Cache, CacheCb)
97
85
%%--------------------------------------------------------------------
98
%% Function: valid_session(Session, LifeTime) -> true | false
100
%% Session = #session{}
101
%% LifeTime = integer() - seconds
86
-spec valid_session(#session{}, seconds()) -> boolean().
103
88
%% Description: Check that the session has not expired
104
89
%%--------------------------------------------------------------------
109
94
%%--------------------------------------------------------------------
110
95
%%% Internal functions
111
96
%%--------------------------------------------------------------------
112
select_session({HostIP, Port, SslOpts}, Cache, CacheCb) ->
97
select_session({HostIP, Port, SslOpts}, Cache, CacheCb, OwnCert) ->
113
98
Sessions = CacheCb:select_session(Cache, {HostIP, Port}),
114
select_session(Sessions, SslOpts).
99
select_session(Sessions, SslOpts, OwnCert).
116
select_session([], _) ->
101
select_session([], _, _) ->
119
104
select_session(Sessions, #ssl_options{ciphers = Ciphers,
120
reuse_sessions = ReuseSession}) ->
105
reuse_sessions = ReuseSession}, OwnCert) ->
123
108
ReuseSession andalso (Session#session.is_resumable) andalso
124
109
lists:member(Session#session.cipher_suite, Ciphers)
110
andalso (OwnCert == Session#session.own_certificate)
126
112
case [Id || [Id, Session] <- Sessions, IsResumable(Session)] of
158
144
is_resumable(SuggestedSessionId, Port, ReuseEnabled, ReuseFun, Cache,
159
CacheCb, SecondLifeTime) ->
145
CacheCb, SecondLifeTime, OwnCert) ->
160
146
case CacheCb:lookup(Cache, {Port, SuggestedSessionId}) of
161
147
#session{cipher_suite = CipherSuite,
148
own_certificate = SessionOwnCert,
162
149
compression_method = Compression,
163
150
is_resumable = Is_resumable,
164
151
peer_certificate = PeerCert} = Session ->
166
153
andalso Is_resumable
154
andalso (OwnCert == SessionOwnCert)
167
155
andalso valid_session(Session, SecondLifeTime)
168
156
andalso ReuseFun(SuggestedSessionId, PeerCert,
169
157
Compression, CipherSuite);