Skip to content

Commit 0dd1ed2

Browse files
committed
ssl: Remove use of insecure legacy option
Time to adopt to always use secure renegotiation for TLS-1.2 specified in RFC 5746 from 2010 is overdue. Also remove documentation of legacy options handling of Erlang distribution over TLS previous to OTP 20 that mentions secure_renegotiate option and is now scheduled for removal.
1 parent 4f95e30 commit 0dd1ed2

6 files changed

Lines changed: 49 additions & 178 deletions

File tree

lib/ssl/doc/guides/ssl_distribution.md

Lines changed: 0 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -271,11 +271,6 @@ handling decoding errors and directly verifying signatures.
271271
For more details see `{verify_fun, Verify}` [in common_option_cert](`t:ssl:common_option_cert/0`)
272272

273273

274-
> #### Note {: .info }
275-
> The legacy command line format for `verify_fun` cannot be used
276-
> in a `-ssl_dist_optfile` file as described below in
277-
> [Specifying TLS Options (Legacy)](#specifying-tls-options-legacy).
278-
279274
## Using TLS distribution over IPv6
280275

281276
It is possible to use TLS distribution over IPv6 instead of IPv4. To do this,
@@ -295,99 +290,3 @@ A node started in this way will only be able to communicate with other nodes
295290
using TLS distribution over IPv6.
296291

297292

298-
## Specifying TLS Options (Legacy)
299-
300-
> #### Note {: .info }
301-
> The following section describes TLS Option handling prior to OTP 20.2
302-
> and can only handle a small subset of the actual available options.
303-
> It is here only for the sake of backwards compatibility .
304-
305-
As in the previous section the PEM file `"/home/me/ssl/erlserver.pem"` contains
306-
both the server certificate and its private key.
307-
308-
On the `erl` command line you can specify options that the TLS distribution adds
309-
when creating a socket.
310-
311-
The simplest TLS options in the following list can be specified by adding the
312-
prefix `server_` or `client_` to the option name:
313-
314-
- `certfile`
315-
- `keyfile`
316-
- `password`
317-
- `cacertfile`
318-
- `verify`
319-
- `verify_fun` (write as `{Module, Function, InitialUserState}`)
320-
- `crl_check`
321-
- `crl_cache` (write as Erlang term)
322-
- `reuse_sessions`
323-
- `secure_renegotiate`
324-
- `depth`
325-
- `hibernate_after`
326-
- `ciphers` (use old string format)
327-
328-
Note that `verify_fun` needs to be written in a different form than the
329-
corresponding TLS option, since funs are not accepted on the command line.
330-
331-
The server can also take the options `dhfile` and `fail_if_no_peer_cert` (also
332-
prefixed).
333-
334-
`client_`\-prefixed options are used when the distribution initiates a
335-
connection to another node. `server_`\-prefixed options are used when accepting
336-
a connection from a remote node.
337-
338-
Raw socket options, such as `packet` and `size` must not be specified on the
339-
command line.
340-
341-
The command-line argument for specifying the TLS options is named
342-
`-ssl_dist_opt` and is to be followed by pairs of SSL options and their values.
343-
Argument `-ssl_dist_opt` can be repeated any number of times.
344-
345-
An example command line doing the same as the example in the previous section
346-
can now look as follows (line breaks in the command are for readability, and
347-
shall not be there when typed):
348-
349-
```text
350-
$ erl -boot /home/me/ssl/start_ssl -proto_dist inet_tls
351-
-ssl_dist_opt server_certfile "/home/me/ssl/erlserver.pem"
352-
-ssl_dist_opt server_secure_renegotiate true client_secure_renegotiate true
353-
-sname ssl_test
354-
Erlang (BEAM) emulator version 5.0 [source]
355-
356-
Eshell V5.0 (abort with ^G)
357-
(ssl_test@myhost)1>
358-
```
359-
360-
### Setting up Environment to Always Use TLS
361-
362-
A convenient way to specify arguments to Erlang is to use environment variable
363-
`ERL_FLAGS`. All the flags needed to use the TLS distribution can be specified
364-
in that variable and are then interpreted as command-line arguments for all
365-
subsequent invocations of Erlang.
366-
367-
In a Unix (Bourne) shell, it can look as follows (line breaks are for
368-
readability, they are not to be there when typed):
369-
370-
```erlang
371-
$ ERL_FLAGS="-boot /home/me/ssl/start_ssl -proto_dist inet_tls
372-
-ssl_dist_opt server_certfile /home/me/ssl/erlserver.pem
373-
-ssl_dist_opt server_secure_renegotiate true client_secure_renegotiate true"
374-
$ export ERL_FLAGS
375-
$ erl -sname ssl_test
376-
Erlang (BEAM) emulator version 5.0 [source]
377-
378-
Eshell V5.0 (abort with ^G)
379-
(ssl_test@myhost)1> init:get_arguments().
380-
[{root,["/usr/local/erlang"]},
381-
{progname,["erl "]},
382-
{sname,["ssl_test"]},
383-
{boot,["/home/me/ssl/start_ssl"]},
384-
{proto_dist,["inet_tls"]},
385-
{ssl_dist_opt,["server_certfile","/home/me/ssl/erlserver.pem"]},
386-
{ssl_dist_opt,["server_secure_renegotiate","true",
387-
"client_secure_renegotiate","true"]
388-
{home,["/home/me"]}]
389-
```
390-
391-
The `init:get_arguments()` call verifies that the correct arguments are supplied
392-
to the emulator.
393-

lib/ssl/src/ssl.erl

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -953,15 +953,13 @@ Options common to client and server side prior to TLS-1.3.
953953

954954
Elliptic curves that can be used in pre TLS-1.3 key exchange.
955955

956-
- **`{secure_renegotiate, SecureRenegotiate}`** - Inter-operate trade-off option
956+
- **`{secure_renegotiate, SecureRenegotiate}`** - Previous interoperability option
957957

958-
Specifies whether to reject renegotiation attempt that does not live
959-
up to [RFC 5746](http://www.ietf.org/rfc/rfc5746.txt). By default,
960-
`SecureRenegotiate` is `true`, meaning that secure renegotiation is
961-
enforced. If `SecureRenegotiate` is `false` secure renegotiation
962-
will still be used if possible, but it falls back to insecure
963-
renegotiation if the peer does not support if [RFC
964-
5746](http://www.ietf.org/rfc/rfc5746.txt).
958+
Since OTP 29.0 setting this option to false will fail, that is accepting
959+
possible fallback to insecure behavior preceding implementation of
960+
[RFC 5746](http://www.ietf.org/rfc/rfc5746.txt) is no longer supported.
961+
Setting it to true will continue to work but is not necessary, as the default
962+
of `true` will now always be enforced.
965963

966964
- **`{user_lookup_fun, {LookupFun, UserState}}`** - PSK/SRP cipher suite option
967965

@@ -988,7 +986,7 @@ Options common to client and server side prior to TLS-1.3.
988986
""".
989987

990988
-type common_option_pre_tls13() :: {eccs, NamedCurves::[named_curve()]} |
991-
{secure_renegotiate, SecureRenegotiate::boolean()} |
989+
{secure_renegotiate, SecureRenegotiate::true} |
992990
{user_lookup_fun, {Lookupfun :: fun(), UserState :: any()}}.
993991

994992
-doc(#{group =>

lib/ssl/src/ssl_config.erl

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,10 +1353,12 @@ opt_renegotiate(UserOpts, #{versions := Versions} = Opts, _Env) ->
13531353
{_, RA0} = get_opt_pos_int(renegotiate_at, ?DEFAULT_RENEGOTIATE_AT, UserOpts, Opts),
13541354
RA = min(RA0, ?DEFAULT_RENEGOTIATE_AT), %% Override users choice without notifying ??
13551355

1356-
{Where3, SR} = get_opt_bool(secure_renegotiate, true, UserOpts, Opts),
1356+
{Where3, _} = disable_insecure_fallback(UserOpts, Opts),
13571357
assert_version_dep(Where3 =:= new, secure_renegotiate, Versions, ['tlsv1','tlsv1.1','tlsv1.2']),
13581358

1359-
Opts#{secure_renegotiate => SR, key_update_at => KUA, renegotiate_at => RA}.
1359+
%% Do not include secure_renegotiate as option is no longer needed,
1360+
%% that is, it is treated as always set to true
1361+
Opts#{key_update_at => KUA, renegotiate_at => RA}.
13601362

13611363
opt_reuse_sessions(UserOpts, #{versions := Versions} = Opts, #{role := client}) ->
13621364
{Where1, RUSS} = get_opt_of(reuse_sessions, [true, false, save], true, UserOpts, Opts),
@@ -1388,6 +1390,15 @@ opt_identity(UserOpts, Opts, _Env) ->
13881390
Lookup = handle_user_lookup(UserOpts, Opts),
13891391
Opts#{psk_identity => PSK, srp_identity => SRP, user_lookup_fun => Lookup}.
13901392

1393+
disable_insecure_fallback(UserOpts, Opts) ->
1394+
case get_opt_bool(secure_renegotiate, true, UserOpts, Opts) of
1395+
{_, true} = Result ->
1396+
Result;
1397+
{_, What} ->
1398+
option_error(secure_renegotiate,
1399+
{What,
1400+
fallback_to_insecure_renegotiation_no_longer_supported})
1401+
end.
13911402

13921403
handle_psk(UserOpts, #{versions := Versions} = Opts) ->
13931404
case get_opt_list(psk_identity, undefined, UserOpts, Opts) of

lib/ssl/src/ssl_handshake.erl

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -753,9 +753,9 @@ encode_extensions([#sni{hostname = ""} | Rest], Acc) ->
753753
encode_extensions([#sni{hostname = Hostname} | Rest], Acc) ->
754754
HostLen = length(Hostname),
755755
HostnameBin = list_to_binary(Hostname),
756-
% Hostname type (1 byte) + Hostname length (2 bytes) + Hostname (HostLen bytes)
756+
%% Hostname type (1 byte) + Hostname length (2 bytes) + Hostname (HostLen bytes)
757757
ServerNameLength = 1 + 2 + HostLen,
758-
% ServerNameListSize (2 bytes) + ServerNameLength
758+
%% ServerNameListSize (2 bytes) + ServerNameLength
759759
ExtLength = 2 + ServerNameLength,
760760
encode_extensions(Rest, <<?UINT16(?SNI_EXT), ?UINT16(ExtLength),
761761
?UINT16(ServerNameLength),
@@ -1561,7 +1561,7 @@ handle_client_hello_extensions(RecordCB, Random, ClientCipherSuites,
15611561
Random, NegotiatedCipherSuite,
15621562
ClientCipherSuites,
15631563
ConnectionStates0,
1564-
Renegotiation, SecureRenegotation),
1564+
Renegotiation),
15651565

15661566
Empty = empty_extensions(Version, server_hello),
15671567
{ServerMaxFragEnum, ConnectionStates, Session} =
@@ -1595,7 +1595,7 @@ handle_client_hello_extensions(RecordCB, Random, ClientCipherSuites,
15951595

15961596
handle_server_hello_extensions(RecordCB, Random, CipherSuite,
15971597
Exts, Version,
1598-
SslOpts,
1598+
SslOpts,
15991599
ConnectionStates0, Renegotiation, IsNew) ->
16001600
ConnectionStates = handle_renegotiation_extension(client, RecordCB, Version,
16011601
maps:get(renegotiation_info, Exts, undefined),
@@ -1618,7 +1618,8 @@ handle_server_hello_extensions(RecordCB, Random, CipherSuite,
16181618
undefined ->
16191619
NextProtocolNegotiation = maps:get(next_protocol_negotiation, Exts, undefined),
16201620
NextProtocolSelector = maps:get(next_protocol_selector, SslOpts, undefined),
1621-
Protocol = handle_next_protocol(NextProtocolNegotiation, NextProtocolSelector, Renegotiation),
1621+
Protocol =
1622+
handle_next_protocol(NextProtocolNegotiation, NextProtocolSelector, Renegotiation),
16221623
{ConnectionStates, npn, Protocol, StaplingState};
16231624
{error, Reason} ->
16241625
throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE, Reason));
@@ -3918,12 +3919,12 @@ handle_renegotiation_info(_, _RecordCB, server, undefined, ConnectionStates, _,
39183919
{ok, ssl_record:set_renegotiation_flag(false, ConnectionStates)}
39193920
end;
39203921

3921-
handle_renegotiation_info(_, _RecordCB, _, undefined, ConnectionStates, false, _, _) ->
3922+
handle_renegotiation_info(_, _RecordCB, _, undefined, ConnectionStates, false,_) ->
39223923
{ok, ssl_record:set_renegotiation_flag(false, ConnectionStates)};
39233924

39243925
handle_renegotiation_info(_, _RecordCB, client,
39253926
#renegotiation_info{renegotiated_connection = ClientServerVerify},
3926-
ConnectionStates, true, _, _) ->
3927+
ConnectionStates, true, _) ->
39273928
#{reneg := ReNeg} = ssl_record:current_connection_state(ConnectionStates, read),
39283929
#{client_verify_data := CData, server_verify_data := SData} = ReNeg,
39293930
case <<CData/binary, SData/binary>> == ClientServerVerify of
@@ -3934,10 +3935,11 @@ handle_renegotiation_info(_, _RecordCB, client,
39343935
end;
39353936
handle_renegotiation_info(_, _RecordCB, server,
39363937
#renegotiation_info{renegotiated_connection = ClientVerify},
3937-
ConnectionStates, true, _, CipherSuites) ->
3938+
ConnectionStates, true, CipherSuites) ->
39383939
case is_member(?TLS_EMPTY_RENEGOTIATION_INFO_SCSV, CipherSuites) of
39393940
true ->
3940-
throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE, {server_renegotiation, empty_renegotiation_info_scsv}));
3941+
throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE,
3942+
{server_renegotiation, empty_renegotiation_info_scsv}));
39413943
false ->
39423944
case ssl_record:current_connection_state(ConnectionStates, read) of
39433945
#{reneg := #{client_verify_data := ClientVerify}} ->
@@ -3946,28 +3948,17 @@ handle_renegotiation_info(_, _RecordCB, server,
39463948
throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE, server_renegotiation))
39473949
end
39483950
end;
3949-
handle_renegotiation_info(_, RecordCB, client, undefined, ConnectionStates, true, SecureRenegotation, _) ->
3950-
handle_renegotiation_info(RecordCB, ConnectionStates, SecureRenegotation);
3951-
3952-
handle_renegotiation_info(_, RecordCB, server, undefined, ConnectionStates, true, SecureRenegotation, CipherSuites) ->
3951+
handle_renegotiation_info(_, _, client, undefined, _, true, _) ->
3952+
throw(?ALERT_REC(?FATAL, ?NO_RENEGOTIATION, only_allow_secure_renegotiation));
3953+
handle_renegotiation_info(_, _, server, undefined, _, true, CipherSuites) ->
39533954
case is_member(?TLS_EMPTY_RENEGOTIATION_INFO_SCSV, CipherSuites) of
39543955
true ->
3955-
throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE, {server_renegotiation, empty_renegotiation_info_scsv}));
3956+
throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE,
3957+
{server_renegotiation, empty_renegotiation_info_scsv}));
39563958
false ->
3957-
handle_renegotiation_info(RecordCB, ConnectionStates, SecureRenegotation)
3959+
throw(?ALERT_REC(?FATAL, ?NO_RENEGOTIATION, only_allow_secure_renegotiation))
39583960
end.
39593961

3960-
handle_renegotiation_info(_RecordCB, ConnectionStates, SecureRenegotation) ->
3961-
#{reneg := #{secure_renegotiation := SR}} = ssl_record:current_connection_state(ConnectionStates, read),
3962-
case {SecureRenegotation, SR} of
3963-
{_, true} ->
3964-
throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE, already_secure));
3965-
{true, false} ->
3966-
throw(?ALERT_REC(?FATAL, ?NO_RENEGOTIATION));
3967-
{false, false} ->
3968-
{ok, ConnectionStates}
3969-
end.
3970-
39713962
cert_curve(_, _, no_suite) ->
39723963
{no_curve, no_suite};
39733964
cert_curve(Cert, ECCCurve0, CipherSuite) ->

lib/ssl/test/ssl_api_SUITE.erl

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3019,17 +3019,23 @@ options_debug(_Config) -> %% debug log_level keep_secrets
30193019
ok.
30203020

30213021
options_renegotiate(_Config) -> %% key_update_at renegotiate_at secure_renegotiate
3022-
?OK(#{key_update_at := ?KEY_USAGE_LIMIT_AES_GCM, renegotiate_at := 268435456, secure_renegotiate := true},
3022+
?OK(#{key_update_at := ?KEY_USAGE_LIMIT_AES_GCM, renegotiate_at := 268435456},
30233023
[], server),
3024-
?OK(#{key_update_at := 123456, renegotiate_at := 64000, secure_renegotiate := false},
3025-
[{key_update_at, 123456}, {renegotiate_at, 64000}, {secure_renegotiate, false}],
3024+
?OK(#{key_update_at := 123456, renegotiate_at := 64000},
3025+
[{key_update_at, 123456}, {renegotiate_at, 64000}, {secure_renegotiate, true}],
30263026
server),
30273027

30283028
%% Errors
30293029
?ERR({options, incompatible, [key_update_at, {versions, _}]},
30303030
[{key_update_at, 123456}, {versions, ['tlsv1.2']}], server),
3031-
?ERR({options, incompatible, [secure_renegotiate, {versions, _}]},
3032-
[{secure_renegotiate, true}, {versions, ['tlsv1.3']}], server),
3031+
?ERR({options,
3032+
{secure_renegotiate,
3033+
{false,
3034+
fallback_to_insecure_renegotiation_no_longer_supported}
3035+
}},
3036+
[{secure_renegotiate, false}], client),
3037+
?ERR({options, {no_supported_algorithms, {signature_algs,[]}}},
3038+
[{signature_algs, []}], client),
30333039

30343040
?ERR({key_update_at, -1}, [{key_update_at, -1}], server),
30353041
?ERR({renegotiate_at, not_a_int}, [{renegotiate_at, not_a_int}], server),
@@ -3690,7 +3696,7 @@ invalid_options_tls13(Config) when is_list(Config) ->
36903696
{options, incompatible, [reuse_sessions, {versions,['tlsv1.3']}]},
36913697
common},
36923698

3693-
{{secure_renegotiate, false},
3699+
{{secure_renegotiate, true},
36943700
{options, incompatible, [secure_renegotiate, {versions,['tlsv1.3']}]},
36953701
common},
36963702

lib/ssl/test/ssl_renegotiate_SUITE.erl

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@
4949
server_renegotiate/1,
5050
client_secure_renegotiate/0,
5151
client_secure_renegotiate/1,
52-
client_secure_renegotiate_fallback/0,
53-
client_secure_renegotiate_fallback/1,
5452
client_renegotiate_reused_session/0,
5553
client_renegotiate_reused_session/1,
5654
server_renegotiate_reused_session/0,
@@ -110,7 +108,6 @@ renegotiate_tests() ->
110108
[client_renegotiate,
111109
server_renegotiate,
112110
client_secure_renegotiate,
113-
client_secure_renegotiate_fallback,
114111
client_renegotiate_reused_session,
115112
server_renegotiate_reused_session,
116113
client_no_wrap_sequence_number,
@@ -211,37 +208,6 @@ client_secure_renegotiate(Config) when is_list(Config) ->
211208
ssl_test_lib:close(Server),
212209
ssl_test_lib:close(Client).
213210

214-
%%--------------------------------------------------------------------
215-
client_secure_renegotiate_fallback() ->
216-
[{doc,"Test that we can set secure_renegotiate to false that is "
217-
"fallback option, we however do not have a insecure server to test against!"}].
218-
client_secure_renegotiate_fallback(Config) when is_list(Config) ->
219-
ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
220-
ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
221-
222-
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
223-
224-
Data = "From erlang to erlang",
225-
226-
Server =
227-
ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
228-
{from, self()},
229-
{mfa, {?MODULE, erlang_ssl_receive, [Data]}},
230-
{options, [{secure_renegotiate, false} | ServerOpts]}]),
231-
Port = ssl_test_lib:inet_port(Server),
232-
233-
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
234-
{host, Hostname},
235-
{from, self()},
236-
{mfa, {?MODULE,
237-
renegotiate, [Data]}},
238-
{options, [{reuse_sessions, false},
239-
{secure_renegotiate, false}| ClientOpts]}]),
240-
241-
ssl_test_lib:check_result(Client, ok, Server, ok),
242-
ssl_test_lib:close(Server),
243-
ssl_test_lib:close(Client).
244-
245211
%%--------------------------------------------------------------------
246212
server_renegotiate() ->
247213
[{doc,"Test ssl:renegotiate/1 on server."}].

0 commit comments

Comments
 (0)