Skip to content

Commit ac94173

Browse files
committed
ssl: Add max value for CRL cache
1 parent c388a2d commit ac94173

5 files changed

Lines changed: 100 additions & 59 deletions

File tree

lib/ssl/doc/ssl_app.md

Lines changed: 48 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,53 @@ The environment parameters can be set on the command line, for example:
6363
might be configurable, by the SSL application. This option can be overridden
6464
by the version option to `ssl:connect/2,3` and `ssl:listen/2`.
6565

66+
- **`max_crl_cacche = pos_integer() <optional>`** - Sets the
67+
maximum number of entries allowed in the default crl store. Defaults to 150. Size limit
68+
is enforced by emptying cache when limit is reached.
69+
70+
- **`ssl_pem_cache_clean = pos_integer() <optional>`** - Number of milliseconds
71+
between PEM cache validations. Defaults to 2 minutes.
72+
73+
Note: The cache can be reloaded by calling `ssl:clear_pem_cache/0`.
74+
75+
- **`bypass_pem_cache = boolean() <optional>`** - Introduced in ssl-8.0.2.
76+
Disables the PEM-cache. Can be used as a workaround for the PEM-cache
77+
bottleneck before ssl-8.1.1. Defaults to false.
78+
79+
- **`internal_active_n = integer() <optional>`** - For TLS connections this
80+
value is used to handle the internal socket. As the implementation was changed
81+
from an active once to an active N behavior (N = 100), for performance
82+
reasons, this option exist for possible tweaking or restoring of the old
83+
behavior (internal_active_n = 1) in unforeseen scenarios. The option will not
84+
affect erlang distribution over TLS that will always run in active N mode.
85+
Added in ssl-9.1 (OTP-21.2).
86+
87+
- **`server_session_tickets_amount = integer() <optional>`** - Number of session
88+
tickets sent by the server. It must be greater than 0. Defaults to 3.
89+
90+
- **`server_session_ticket_lifetime = integer() <optional>`** - Lifetime of
91+
session tickets sent by the server. Servers must not use any value greater
92+
than 604800 seconds (7 days). Expired tickets are automatically removed.
93+
Defaults to 7200 seconds (2 hours).
94+
95+
- **`server_session_ticket_store_size = integer() <optional>`** - Sets the
96+
maximum size of the server session ticket store (stateful tickets). Defaults
97+
to 1000. Size limit is enforced by dropping old tickets.
98+
99+
- **`server_session_ticket_max_early_data = integer() <optional>`** - Sets the
100+
maximum size of the early data that the server accepts and also configures its
101+
NewSessionTicket messages to include this same size limit in their
102+
early_data_indication extension. Defaults to 16384. Size limit is enforced by
103+
both client and server.
104+
105+
- **`client_session_ticket_lifetime = integer() <optional>`** - Lifetime of
106+
session tickets in the client ticket store. Expired tickets are automatically
107+
removed. Defaults to 7200 seconds (2 hours).
108+
109+
- **`client_session_ticket_store_size = integer() <optional>`** - Sets the
110+
maximum size of the client session ticket store. Defaults to 1000. Size limit
111+
is enforced by dropping old tickets.
112+
66113
- **`session_lifetime = integer() <optional>`** - Maximum lifetime of the
67114
session data in seconds. Defaults to 24 hours which is the maximum recommended
68115
lifetime by [RFC 5246](http://www.ietf.org/rfc/5246rfc.txt). However sessions
@@ -106,54 +153,11 @@ The environment parameters can be set on the command line, for example:
106153
entries will be invalidated regardless of their remaining lifetime. Defaults
107154
to 1000. Recommended ssl-8.2.1 or later for this option to work as intended.
108155

109-
- **`ssl_pem_cache_clean = integer() <optional>`** - Number of milliseconds
110-
between PEM cache validations. Defaults to 2 minutes.
111-
112-
Note: The cache can be reloaded by calling `ssl:clear_pem_cache/0`.
113-
114-
- **`bypass_pem_cache = boolean() <optional>`** - Introduced in ssl-8.0.2.
115-
Disables the PEM-cache. Can be used as a workaround for the PEM-cache
116-
bottleneck before ssl-8.1.1. Defaults to false.
117-
118-
- **`alert_timeout = integer() <optional>`** - Number of milliseconds between
156+
- **`alert_timeout = pos_integer() <optional>`** - Number of milliseconds between
119157
sending of a fatal alert and closing the connection. Waiting a little while
120158
improves the peers chances to properly receiving the alert so it may shutdown
121159
gracefully. Defaults to 5000 milliseconds.
122160

123-
- **`internal_active_n = integer() <optional>`** - For TLS connections this
124-
value is used to handle the internal socket. As the implementation was changed
125-
from an active once to an active N behavior (N = 100), for performance
126-
reasons, this option exist for possible tweaking or restoring of the old
127-
behavior (internal_active_n = 1) in unforeseen scenarios. The option will not
128-
affect erlang distribution over TLS that will always run in active N mode.
129-
Added in ssl-9.1 (OTP-21.2).
130-
131-
- **`server_session_tickets_amount = integer() <optional>`** - Number of session
132-
tickets sent by the server. It must be greater than 0. Defaults to 3.
133-
134-
- **`server_session_ticket_lifetime = integer() <optional>`** - Lifetime of
135-
session tickets sent by the server. Servers must not use any value greater
136-
than 604800 seconds (7 days). Expired tickets are automatically removed.
137-
Defaults to 7200 seconds (2 hours).
138-
139-
- **`server_session_ticket_store_size = integer() <optional>`** - Sets the
140-
maximum size of the server session ticket store (stateful tickets). Defaults
141-
to 1000. Size limit is enforced by dropping old tickets.
142-
143-
- **`server_session_ticket_max_early_data = integer() <optional>`** - Sets the
144-
maximum size of the early data that the server accepts and also configures its
145-
NewSessionTicket messages to include this same size limit in their
146-
early_data_indication extension. Defaults to 16384. Size limit is enforced by
147-
both client and server.
148-
149-
- **`client_session_ticket_lifetime = integer() <optional>`** - Lifetime of
150-
session tickets in the client ticket store. Expired tickets are automatically
151-
removed. Defaults to 7200 seconds (2 hours).
152-
153-
- **`client_session_ticket_store_size = integer() <optional>`** - Sets the
154-
maximum size of the client session ticket store. Defaults to 1000. Size limit
155-
is enforced by dropping old tickets.
156-
157161
## Error Logger and Event Handlers
158162

159163
The SSL application uses [OTP logger](`m:logger`). TLS/DTLS alerts are logged on

lib/ssl/src/ssl_config.erl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,12 @@
2828
-include_lib("public_key/include/public_key.hrl").
2929

3030
-define(DEFAULT_MAX_SESSION_CACHE, 1000).
31+
-define(DEFAULT_MAX_CRL_CACHE, 150).
3132

3233
-export([init/2,
3334
pre_1_3_session_opts/1,
3435
get_max_early_data_size/0,
36+
get_max_crl_cache/0,
3537
get_ticket_lifetime/0,
3638
get_ticket_store_size/0,
3739
get_internal_active_n/0,
@@ -211,6 +213,14 @@ get_max_early_data_size() ->
211213
?DEFAULT_MAX_EARLY_DATA_SIZE
212214
end.
213215

216+
get_max_crl_cache() ->
217+
case application:get_env(ssl, server_session_ticket_max_early_data) of
218+
{ok, Size} when is_integer(Size) ->
219+
Size;
220+
_ ->
221+
?DEFAULT_MAX_CRL_CACHE
222+
end.
223+
214224
get_internal_active_n() ->
215225
get_internal_active_n(false).
216226

lib/ssl/src/ssl_crl_cache.erl

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -232,10 +232,12 @@ cache_lookup(URL, {{Cache, _}, _}) ->
232232

233233
handle_http(URI, Rest, {_, [{http, Timeout}]} = CRLDbInfo) ->
234234
CRLs = http_lookup(URI, Rest, CRLDbInfo, Timeout),
235-
%% Uncomment to improve performance, but need to
236-
%% implement cache limit and or cleaning to prevent
237-
%% DoS attack possibilities
238-
%%insert(URI, {der, CRLs}),
235+
case CRLs of
236+
not_available ->
237+
ok;
238+
_ ->
239+
insert(URI, {der, CRLs})
240+
end,
239241
CRLs;
240242
handle_http(_, Rest, CRLDbInfo) ->
241243
get_crls(Rest, CRLDbInfo).

lib/ssl/src/ssl_manager.erl

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@
6666
session_cache_client_max :: integer(),
6767
session_client_invalidator :: undefined | pid(),
6868
options :: list(),
69-
client_session_order :: gb_trees:tree()
69+
client_session_order :: gb_trees:tree(),
70+
max_crl_db_entries :: pos_integer()
7071
}).
7172

7273
-define(GEN_UNIQUE_ID_MAX_TRIES, 10).
@@ -266,7 +267,8 @@ init([ManagerName, PemCacheName, Opts]) ->
266267
session_cache_client_max = ClientSessMax,
267268
session_client_invalidator = undefined,
268269
options = Opts,
269-
client_session_order = gb_trees:empty()
270+
client_session_order = gb_trees:empty(),
271+
max_crl_db_entries = ssl_config:get_max_crl_cache()
270272
}}.
271273

272274
%%--------------------------------------------------------------------
@@ -305,8 +307,9 @@ handle_call({{connection_init, Trustedcerts, Role, {CRLCb, UserCRLDb}}, Pid}, _F
305307
end;
306308

307309
handle_call({{insert_crls, Path, CRLs}, _}, _From,
308-
#state{certificate_db = Db} = State) ->
309-
ssl_pkix_db:add_crls(Db, Path, CRLs),
310+
#state{certificate_db = Db,
311+
max_crl_db_entries = Max} = State) ->
312+
ssl_pkix_db:add_crls(Db, Path, CRLs, Max),
310313
{reply, ok, State};
311314

312315
handle_call({{delete_crls, CRLsOrPath}, _}, _From,
@@ -343,8 +346,8 @@ handle_cast({invalidate_session, Host, Port,
343346
session_cache_client_cb = CacheCb} = State) ->
344347
invalidate_session(Cache, CacheCb, {{Host, Port}, ID}, Session, State);
345348
handle_cast({insert_crls, Path, CRLs},
346-
#state{certificate_db = Db} = State) ->
347-
ssl_pkix_db:add_crls(Db, Path, CRLs),
349+
#state{certificate_db = Db, max_crl_db_entries = Max} = State) ->
350+
ssl_pkix_db:add_crls(Db, Path, CRLs, Max),
348351
{noreply, State};
349352

350353
handle_cast({delete_crls, CRLsOrPath},

lib/ssl/src/ssl_pkix_db.erl

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,27 @@
3030
-include_lib("kernel/include/file.hrl").
3131
-include_lib("kernel/include/logger.hrl").
3232

33-
-export([create/1, create_pem_cache/1,
34-
add_crls/3, remove_crls/2, remove/1, add_trusted_certs/3,
33+
-export([create/1,
34+
create_pem_cache/1,
35+
add_crls/4,
36+
remove_crls/2,
37+
remove/1,
38+
add_trusted_certs/3,
3539
refresh_trusted_certs/2,
3640
refresh_trusted_certs/3,
3741
extract_trusted_certs/1,
38-
remove_trusted_certs/2, insert/3, remove/2, clear/1, db_size/1,
39-
ref_count/3, lookup_trusted_cert/4, foldl/3, select_certentries_by_ref/2,
40-
select_certs_by_ref/2, decode_pem_file/1, lookup/2]).
42+
remove_trusted_certs/2,
43+
insert/3,
44+
remove/2,
45+
clear/1,
46+
db_size/1,
47+
ref_count/3,
48+
lookup_trusted_cert/4,
49+
foldl/3,
50+
select_certentries_by_ref/2,
51+
select_certs_by_ref/2,
52+
decode_pem_file/1,
53+
lookup/2]).
4154

4255
%%====================================================================
4356
%% Internal application API
@@ -363,6 +376,15 @@ new_trusted_cert_entry(File, [CertsDb, RefsDb, _ | _]) ->
363376
Error
364377
end.
365378

379+
add_crls([_,_,_, {Cache, _} | _]= DB, Path, CRLs, MaxSize) ->
380+
case ets:info(Cache, size) + length(CRLs) > MaxSize of
381+
true ->
382+
ets:delete_all_objects(Cache),
383+
add_crls(DB, Path, CRLs);
384+
false ->
385+
add_crls(DB, Path, CRLs)
386+
end.
387+
366388
add_crls([_,_,_, {_, Mapping} | _], ?NO_DIST_POINT, CRLs) ->
367389
[add_crls(CRL, Mapping) || CRL <- CRLs];
368390
add_crls([_,_,_, {Cache, Mapping} | _], Path, CRLs) ->

0 commit comments

Comments
 (0)