aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--lib/compiler/test/Makefile1
-rw-r--r--lib/crypto/src/crypto.erl2
-rw-r--r--lib/ssl/doc/src/ssl.xml13
-rw-r--r--lib/ssl/src/ssl.erl67
-rw-r--r--lib/ssl/src/ssl_connection.erl40
-rw-r--r--lib/ssl/test/ssl_basic_SUITE.erl41
-rw-r--r--lib/ssl/test/ssl_packet_SUITE.erl10
-rw-r--r--lib/ssl/test/ssl_test_lib.erl12
-rw-r--r--lib/stdlib/src/otp_internal.erl176
-rw-r--r--lib/stdlib/test/erl_lint_SUITE.erl6
11 files changed, 191 insertions, 179 deletions
diff --git a/README.md b/README.md
index ccfce03a96..b3d1aaaad1 100644
--- a/README.md
+++ b/README.md
@@ -52,7 +52,7 @@ Please visit [bugs.erlang.org](https://bugs.erlang.org/issues/?jql=project%20%3D
### Security Disclosure
-We take security bugs in Erlang/OTP seriously. Please disclose the issues regarding security by sending an email to [email protected] and not by creating a public issue.
+We take security bugs in Erlang/OTP seriously. Please disclose the issues regarding security by sending an email to **erlang-security [at] erlang [dot] org** and not by creating a public issue.
## Contributing
diff --git a/lib/compiler/test/Makefile b/lib/compiler/test/Makefile
index e338dbb4e3..63763f31b2 100644
--- a/lib/compiler/test/Makefile
+++ b/lib/compiler/test/Makefile
@@ -185,6 +185,7 @@ release_tests_spec: make_emakefile
echo "-module($$module). %% dummy .erl file" >$$file; \
done
$(INSTALL_DATA) $(ERL_DUMMY_FILES) "$(RELSYSDIR)"
+ rm $(ERL_DUMMY_FILES)
chmod -R u+w "$(RELSYSDIR)"
@tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -)
diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl
index 631af62615..ce8add6559 100644
--- a/lib/crypto/src/crypto.erl
+++ b/lib/crypto/src/crypto.erl
@@ -40,6 +40,8 @@
-export([ec_curve/1, ec_curves/0]).
-export([rand_seed/1]).
+-deprecated({rand_uniform, 2, next_major_release}).
+
%% This should correspond to the similar macro in crypto.c
-define(MAX_BYTES_TO_NIF, 20000). %% Current value is: erlang:system_info(context_reductions) * 10
diff --git a/lib/ssl/doc/src/ssl.xml b/lib/ssl/doc/src/ssl.xml
index 916b41742e..91c590c247 100644
--- a/lib/ssl/doc/src/ssl.xml
+++ b/lib/ssl/doc/src/ssl.xml
@@ -935,13 +935,14 @@ fun(srp, Username :: string(), UserState :: term()) ->
<fsummary>Returns all the connection information.
</fsummary>
<type>
- <v>Item = protocol | cipher_suite | sni_hostname | ecc | atom()</v>
+ <v>Item = protocol | cipher_suite | sni_hostname | ecc | session_id | atom()</v>
<d>Meaningful atoms, not specified above, are the ssl option names.</d>
<v>Result = [{Item::atom(), Value::term()}]</v>
<v>Reason = term()</v>
</type>
- <desc><p>Returns all relevant information about the connection, ssl options that
- are undefined will be filtered out.</p>
+ <desc><p>Returns the most relevant information about the connection, ssl options that
+ are undefined will be filtered out. Note that values that affect the security of the
+ connection will only be returned if explicitly requested by connection_information/2.</p>
</desc>
</func>
@@ -952,8 +953,10 @@ fun(srp, Username :: string(), UserState :: term()) ->
</fsummary>
<type>
<v>Items = [Item]</v>
- <v>Item = protocol | cipher_suite | sni_hostname | atom()</v>
- <d>Meaningful atoms, not specified above, are the ssl option names.</d>
+ <v>Item = protocol | cipher_suite | sni_hostname | ecc | session_id | client_random
+ | server_random | master_secret | atom()</v>
+ <d>Note that client_random, server_random and master_secret are values
+ that affect the security of connection. Meaningful atoms, not specified above, are the ssl option names.</d>
<v>Result = [{Item::atom(), Value::term()}]</v>
<v>Reason = term()</v>
</type>
diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl
index 45fc29723f..b3d08bdfbe 100644
--- a/lib/ssl/src/ssl.erl
+++ b/lib/ssl/src/ssl.erl
@@ -38,16 +38,13 @@
getopts/2, setopts/2, getstat/1, getstat/2
]).
%% SSL/TLS protocol handling
--export([cipher_suites/0, cipher_suites/1, eccs/0, eccs/1,
- connection_info/1, versions/0, session_info/1, format_error/1,
- renegotiate/1, prf/5, negotiated_protocol/1, negotiated_next_protocol/1,
+
+-export([cipher_suites/0, cipher_suites/1, eccs/0, eccs/1, versions/0,
+ format_error/1, renegotiate/1, prf/5, negotiated_protocol/1,
connection_information/1, connection_information/2]).
%% Misc
-export([handle_options/2, tls_version/1]).
--deprecated({negotiated_next_protocol, 1, next_major_release}).
--deprecated({connection_info, 1, next_major_release}).
-
-include("ssl_api.hrl").
-include("ssl_internal.hrl").
-include("ssl_record.hrl").
@@ -307,7 +304,7 @@ controlling_process(#sslsocket{pid = {Listen,
%% Description: Return SSL information for the connection
%%--------------------------------------------------------------------
connection_information(#sslsocket{pid = Pid}) when is_pid(Pid) ->
- case ssl_connection:connection_information(Pid) of
+ case ssl_connection:connection_information(Pid, false) of
{ok, Info} ->
{ok, [Item || Item = {_Key, Value} <- Info, Value =/= undefined]};
Error ->
@@ -323,8 +320,8 @@ connection_information(#sslsocket{pid = {udp,_}}) ->
%%
%% Description: Return SSL information for the connection
%%--------------------------------------------------------------------
-connection_information(#sslsocket{} = SSLSocket, Items) ->
- case connection_information(SSLSocket) of
+connection_information(#sslsocket{pid = Pid}, Items) when is_pid(Pid) ->
+ case ssl_connection:connection_information(Pid, include_security_info(Items)) of
{ok, Info} ->
{ok, [Item || Item = {Key, Value} <- Info, lists:member(Key, Items),
Value =/= undefined]};
@@ -333,21 +330,6 @@ connection_information(#sslsocket{} = SSLSocket, Items) ->
end.
%%--------------------------------------------------------------------
-%% Deprecated
--spec connection_info(#sslsocket{}) -> {ok, {tls_record:tls_atom_version(), ssl_cipher:erl_cipher_suite()}} |
- {error, reason()}.
-%%
-%% Description: Returns ssl protocol and cipher used for the connection
-%%--------------------------------------------------------------------
-connection_info(#sslsocket{} = SSLSocket) ->
- case connection_information(SSLSocket) of
- {ok, Result} ->
- {ok, {proplists:get_value(protocol, Result), proplists:get_value(cipher_suite, Result)}};
- Error ->
- Error
- end.
-
-%%--------------------------------------------------------------------
-spec peername(#sslsocket{}) -> {ok, {inet:ip_address(), inet:port_number()}} | {error, reason()}.
%%
%% Description: same as inet:peername/1.
@@ -392,20 +374,6 @@ negotiated_protocol(#sslsocket{pid = Pid}) ->
ssl_connection:negotiated_protocol(Pid).
%%--------------------------------------------------------------------
--spec negotiated_next_protocol(#sslsocket{}) -> {ok, binary()} | {error, reason()}.
-%%
-%% Description: Returns the next protocol that has been negotiated. If no
-%% protocol has been negotiated will return {error, next_protocol_not_negotiated}
-%%--------------------------------------------------------------------
-negotiated_next_protocol(Socket) ->
- case negotiated_protocol(Socket) of
- {error, protocol_not_negotiated} ->
- {error, next_protocol_not_negotiated};
- Res ->
- Res
- end.
-
-%%--------------------------------------------------------------------
-spec cipher_suites() -> [ssl_cipher:erl_cipher_suite()] | [string()].
%%--------------------------------------------------------------------
cipher_suites() ->
@@ -555,19 +523,6 @@ sockname(#sslsocket{pid = Pid, fd = {Transport, Socket, _, _}}) when is_pid(Pid)
tls_socket:sockname(Transport, Socket).
%%---------------------------------------------------------------
--spec session_info(#sslsocket{}) -> {ok, list()} | {error, reason()}.
-%%
-%% Description: Returns list of session info currently [{session_id, session_id(),
-%% {cipher_suite, cipher_suite()}]
-%%--------------------------------------------------------------------
-session_info(#sslsocket{pid = Pid}) when is_pid(Pid) ->
- ssl_connection:session_info(Pid);
-session_info(#sslsocket{pid = {udp,_}}) ->
- {error, enotconn};
-session_info(#sslsocket{pid = {Listen,_}}) when is_port(Listen) ->
- {error, enotconn}.
-
-%%---------------------------------------------------------------
-spec versions() -> [{ssl_app, string()} | {supported, [tls_record:tls_atom_version()]} |
{available, [tls_record:tls_atom_version()]}].
%%
@@ -1480,3 +1435,13 @@ default_cb_info(tls) ->
{gen_tcp, tcp, tcp_closed, tcp_error};
default_cb_info(dtls) ->
{gen_udp, udp, udp_closed, udp_error}.
+
+include_security_info([]) ->
+ false;
+include_security_info([Item | Items]) ->
+ case lists:member(Item, [client_random, server_random, master_secret]) of
+ true ->
+ true;
+ false ->
+ include_security_info(Items)
+ end.
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl
index ea139ac4b1..df9b9e8a63 100644
--- a/lib/ssl/src/ssl_connection.erl
+++ b/lib/ssl/src/ssl_connection.erl
@@ -42,9 +42,9 @@
%% User Events
-export([send/2, recv/3, close/2, shutdown/2,
- new_user/2, get_opts/2, set_opts/2, session_info/1,
+ new_user/2, get_opts/2, set_opts/2,
peer_certificate/1, renegotiation/1, negotiated_protocol/1, prf/5,
- connection_information/1, handle_common_event/5
+ connection_information/2, handle_common_event/5
]).
%% General gen_statem state functions with extra callback argument
@@ -185,12 +185,12 @@ recv(Pid, Length, Timeout) ->
call(Pid, {recv, Length, Timeout}).
%%--------------------------------------------------------------------
--spec connection_information(pid()) -> {ok, list()} | {error, reason()}.
+-spec connection_information(pid(), boolean()) -> {ok, list()} | {error, reason()}.
%%
%% Description: Get the SNI hostname
%%--------------------------------------------------------------------
-connection_information(Pid) when is_pid(Pid) ->
- call(Pid, connection_information).
+connection_information(Pid, IncludeSecrityInfo) when is_pid(Pid) ->
+ call(Pid, {connection_information, IncludeSecrityInfo}).
%%--------------------------------------------------------------------
-spec close(pid(), {close, Timeout::integer() |
@@ -247,14 +247,6 @@ set_opts(ConnectionPid, Options) ->
call(ConnectionPid, {set_opts, Options}).
%%--------------------------------------------------------------------
--spec session_info(pid()) -> {ok, list()} | {error, reason()}.
-%%
-%% Description: Returns info about the ssl session
-%%--------------------------------------------------------------------
-session_info(ConnectionPid) ->
- call(ConnectionPid, session_info).
-
-%%--------------------------------------------------------------------
-spec peer_certificate(pid()) -> {ok, binary()| undefined} | {error, reason()}.
%%
%% Description: Returns the peer cert
@@ -775,14 +767,12 @@ connection({call, From}, renegotiate, #state{protocol_cb = Connection} = State,
connection({call, From}, peer_certificate,
#state{session = #session{peer_certificate = Cert}} = State, _) ->
hibernate_after(connection, State, [{reply, From, {ok, Cert}}]);
-connection({call, From}, connection_information, State, _) ->
+connection({call, From}, {connection_information, true}, State, _) ->
+ Info = connection_info(State) ++ security_info(State),
+ hibernate_after(connection, State, [{reply, From, {ok, Info}}]);
+connection({call, From}, {connection_information, false}, State, _) ->
Info = connection_info(State),
hibernate_after(connection, State, [{reply, From, {ok, Info}}]);
-connection({call, From}, session_info, #state{session = #session{session_id = Id,
- cipher_suite = Suite}} = State, _) ->
- SessionInfo = [{session_id, Id},
- {cipher_suite, ssl_cipher:erl_suite_definition(Suite)}],
- hibernate_after(connection, State, [{reply, From, SessionInfo}]);
connection({call, From}, negotiated_protocol,
#state{negotiated_protocol = undefined} = State, _) ->
hibernate_after(connection, State, [{reply, From, {error, protocol_not_negotiated}}]);
@@ -1195,7 +1185,8 @@ handle_alert(#alert{level = ?WARNING} = Alert, StateName,
%%% Internal functions
%%--------------------------------------------------------------------
connection_info(#state{sni_hostname = SNIHostname,
- session = #session{cipher_suite = CipherSuite, ecc = ECCCurve},
+ session = #session{session_id = SessionId,
+ cipher_suite = CipherSuite, ecc = ECCCurve},
protocol_cb = Connection,
negotiated_version = {_,_} = Version,
ssl_options = Opts}) ->
@@ -1210,9 +1201,18 @@ connection_info(#state{sni_hostname = SNIHostname,
[]
end,
[{protocol, RecordCB:protocol_version(Version)},
+ {session_id, SessionId},
{cipher_suite, CipherSuiteDef},
{sni_hostname, SNIHostname} | CurveInfo] ++ ssl_options_list(Opts).
+security_info(#state{connection_states = ConnectionStates}) ->
+ #{security_parameters :=
+ #security_parameters{client_random = ClientRand,
+ server_random = ServerRand,
+ master_secret = MasterSecret}} =
+ ssl_record:current_connection_state(ConnectionStates, read),
+ [{client_random, ClientRand}, {server_random, ServerRand}, {master_secret, MasterSecret}].
+
do_server_hello(Type, #hello_extensions{next_protocol_negotiation = NextProtocols} =
ServerHelloExt,
#state{negotiated_version = Version,
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
index 86426bdb60..4eabe544d7 100644
--- a/lib/ssl/test/ssl_basic_SUITE.erl
+++ b/lib/ssl/test/ssl_basic_SUITE.erl
@@ -148,6 +148,7 @@ options_tests_tls() ->
api_tests() ->
[connection_info,
+ secret_connection_info,
connection_information,
peercert,
peercert_with_client_cert,
@@ -611,7 +612,7 @@ prf(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
connection_info() ->
- [{doc,"Test the API function ssl:connection_information/1"}].
+ [{doc,"Test the API function ssl:connection_information/2"}].
connection_info(Config) when is_list(Config) ->
ClientOpts = ssl_test_lib:ssl_options(client_verification_opts, Config),
ServerOpts = ssl_test_lib:ssl_options(server_verification_opts, Config),
@@ -645,6 +646,38 @@ connection_info(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
+secret_connection_info() ->
+ [{doc,"Test the API function ssl:connection_information/2"}].
+secret_connection_info(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_verification_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_verification_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, secret_connection_info_result, []}},
+ {options, ServerOpts}]),
+
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, secret_connection_info_result, []}},
+ {options, ClientOpts}]),
+
+ ct:log("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ Version = ssl_test_lib:protocol_version(Config),
+
+ ssl_test_lib:check_result(Server, true, Client, true),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+
connection_information() ->
[{doc,"Test the API function ssl:connection_information/1"}].
connection_information(Config) when is_list(Config) ->
@@ -3414,7 +3447,6 @@ listen_socket(Config) ->
{error, enotconn} = ssl:connection_information(ListenSocket),
{error, enotconn} = ssl:peername(ListenSocket),
{error, enotconn} = ssl:peercert(ListenSocket),
- {error, enotconn} = ssl:session_info(ListenSocket),
{error, enotconn} = ssl:renegotiate(ListenSocket),
{error, enotconn} = ssl:prf(ListenSocket, 'master_secret', <<"Label">>, client_random, 256),
{error, enotconn} = ssl:shutdown(ListenSocket, read_write),
@@ -4638,6 +4670,11 @@ version_info_result(Socket) ->
{ok, [{version, Version}]} = ssl:connection_information(Socket, [version]),
{ok, Version}.
+secret_connection_info_result(Socket) ->
+ {ok, [{client_random, ClientRand}, {server_random, ServerRand}, {master_secret, MasterSecret}]}
+ = ssl:connection_information(Socket, [client_random, server_random, master_secret]),
+ is_binary(ClientRand) andalso is_binary(ServerRand) andalso is_binary(MasterSecret).
+
connect_dist_s(S) ->
Msg = term_to_binary({erlang,term}),
ok = ssl:send(S, Msg).
diff --git a/lib/ssl/test/ssl_packet_SUITE.erl b/lib/ssl/test/ssl_packet_SUITE.erl
index 3446a566c4..c8caa9c11a 100644
--- a/lib/ssl/test/ssl_packet_SUITE.erl
+++ b/lib/ssl/test/ssl_packet_SUITE.erl
@@ -1973,14 +1973,14 @@ passive_recv_packet(Socket, _, 0) ->
{error, timeout} = ssl:recv(Socket, 0, 500),
ok;
Other ->
- {other, Other, ssl:session_info(Socket), 0}
+ {other, Other, ssl:connection_information(Socket, [session_id, cipher_suite]), 0}
end;
passive_recv_packet(Socket, Data, N) ->
case ssl:recv(Socket, 0) of
{ok, Data} ->
passive_recv_packet(Socket, Data, N-1);
Other ->
- {other, Other, ssl:session_info(Socket), N}
+ {other, Other, ssl:connection_information(Socket, [session_id, cipher_suite]), N}
end.
send(Socket,_, 0) ->
@@ -2032,7 +2032,7 @@ active_once_packet(Socket,_, 0) ->
{ssl, Socket, []} ->
ok;
{ssl, Socket, Other} ->
- {other, Other, ssl:session_info(Socket), 0}
+ {other, Other, ssl:connection_information(Socket, [session_id, cipher_suite]), 0}
end;
active_once_packet(Socket, Data, N) ->
receive
@@ -2077,7 +2077,7 @@ active_packet(Socket, _, 0) ->
{ssl, Socket, []} ->
ok;
Other ->
- {other, Other, ssl:session_info(Socket), 0}
+ {other, Other, ssl:connection_information(Socket, [session_id, cipher_suite]), 0}
end;
active_packet(Socket, Data, N) ->
receive
@@ -2089,7 +2089,7 @@ active_packet(Socket, Data, N) ->
{ssl, Socket, Data} ->
active_packet(Socket, Data, N -1);
Other ->
- {other, Other, ssl:session_info(Socket),N}
+ {other, Other, ssl:connection_information(Socket, [session_id, cipher_suite]),N}
end.
assert_packet_opt(Socket, Type) ->
diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl
index 4b740c79db..3768fc2259 100644
--- a/lib/ssl/test/ssl_test_lib.erl
+++ b/lib/ssl/test/ssl_test_lib.erl
@@ -782,18 +782,18 @@ no_result(_) ->
no_result_msg.
trigger_renegotiate(Socket, [ErlData, N]) ->
- [{session_id, Id} | _ ] = ssl:session_info(Socket),
+ {ok, [{session_id, Id}]} = ssl:connection_information(Socket, [session_id]),
trigger_renegotiate(Socket, ErlData, N, Id).
trigger_renegotiate(Socket, _, 0, Id) ->
ct:sleep(1000),
- case ssl:session_info(Socket) of
- [{session_id, Id} | _ ] ->
+ case ssl:connection_information(Socket, [session_id]) of
+ {ok, [{session_id, Id}]} ->
fail_session_not_renegotiated;
%% Tests that uses this function will not reuse
%% sessions so if we get a new session id the
%% renegotiation has succeeded.
- [{session_id, _} | _ ] ->
+ {ok, [{session_id, _}]} ->
ok;
{error, closed} ->
fail_session_fatal_alert_during_renegotiation;
@@ -998,8 +998,8 @@ cipher_result(Socket, Result) ->
end.
session_info_result(Socket) ->
- ssl:session_info(Socket).
-
+ {ok, Info} = ssl:connection_information(Socket, [session_id, cipher_suite]),
+ Info.
public_key(#'PrivateKeyInfo'{privateKeyAlgorithm =
#'PrivateKeyInfo_privateKeyAlgorithm'{algorithm = ?rsaEncryption},
diff --git a/lib/stdlib/src/otp_internal.erl b/lib/stdlib/src/otp_internal.erl
index fda7a2cd8a..d89ff4a624 100644
--- a/lib/stdlib/src/otp_internal.erl
+++ b/lib/stdlib/src/otp_internal.erl
@@ -55,6 +55,11 @@ obsolete_1(erlang, now, 0) ->
obsolete_1(calendar, local_time_to_universal_time, 1) ->
{deprecated, {calendar, local_time_to_universal_time_dst, 1}};
+%% *** CRYPTO added in OTP 20 ***
+
+obsolete_1(crypto, rand_uniform, 2) ->
+ {deprecated, {rand, uniform, 1}};
+
%% *** CRYPTO added in OTP 19 ***
obsolete_1(crypto, rand_bytes, 1) ->
@@ -63,178 +68,178 @@ obsolete_1(crypto, rand_bytes, 1) ->
%% *** CRYPTO added in R16B01 ***
obsolete_1(crypto, md4, 1) ->
- {deprecated, {crypto, hash, 2}};
+ {removed, {crypto, hash, 2}, "20.0"};
obsolete_1(crypto, md5, 1) ->
- {deprecated, {crypto, hash, 2}};
+ {removed, {crypto, hash, 2}, "20.0"};
obsolete_1(crypto, sha, 1) ->
- {deprecated, {crypto, hash, 2}};
+ {removed, {crypto, hash, 2}, "20.0"};
obsolete_1(crypto, md4_init, 0) ->
- {deprecated, {crypto, hash_init, 1}};
+ {removed, {crypto, hash_init, 1}, "20.0"};
obsolete_1(crypto, md5_init, 0) ->
- {deprecated, {crypto, hash_init, 1}};
+ {removed, {crypto, hash_init, 1}, "20.0"};
obsolete_1(crypto, sha_init, 0) ->
- {deprecated, {crypto, hash_init, 1}};
+ {removed, {crypto, hash_init, 1}, "20.0"};
obsolete_1(crypto, md4_update, 2) ->
- {deprecated, {crypto, hash_update, 2}};
+ {removed, {crypto, hash_update, 2}, "20.0"};
obsolete_1(crypto, md5_update, 2) ->
- {deprecated, {crypto, hash_update, 2}};
+ {removed, {crypto, hash_update, 2}, "20.0"};
obsolete_1(crypto, sha_update, 2) ->
- {deprecated, {crypto, hash_update, 2}};
+ {removed, {crypto, hash_update, 2}, "20.0"};
obsolete_1(crypto, md4_final, 1) ->
- {deprecated, {crypto, hash_final, 1}};
+ {removed, {crypto, hash_final, 1}, "20.0"};
obsolete_1(crypto, md5_final, 1) ->
- {deprecated, {crypto, hash_final, 1}};
+ {removed, {crypto, hash_final, 1}, "20.0"};
obsolete_1(crypto, sha_final, 1) ->
- {deprecated, {crypto, hash_final, 1}};
+ {removed, {crypto, hash_final, 1}, "20.0"};
obsolete_1(crypto, md5_mac, 2) ->
- {deprecated, {crypto, hmac, 3}};
+ {removed, {crypto, hmac, 3}, "20.0"};
obsolete_1(crypto, sha_mac, 2) ->
- {deprecated, {crypto, hmac, 3}};
+ {removed, {crypto, hmac, 3}, "20.0"};
obsolete_1(crypto, sha_mac, 3) ->
- {deprecated, {crypto, hmac, 4}};
+ {removed, {crypto, hmac, 4}, "20.0"};
obsolete_1(crypto, sha_mac_96, 2) ->
- {deprecated, {crypto, hmac, 4}};
+ {removed, {crypto, hmac, 4}, "20.0"};
obsolete_1(crypto, md5_mac_96, 2) ->
- {deprecated, {crypto, hmac, 4}};
+ {removed, {crypto, hmac, 4}, "20.0"};
obsolete_1(crypto, rsa_sign, 2) ->
- {deprecated, {crypto, sign, 4}};
+ {removed, {crypto, sign, 4}, "20.0"};
obsolete_1(crypto, rsa_sign, 3) ->
- {deprecated, {crypto, sign, 4}};
+ {removed, {crypto, sign, 4}, "20.0"};
obsolete_1(crypto, rsa_verify, 3) ->
- {deprecated, {crypto, verify, 5}};
+ {removed, {crypto, verify, 5}, "20.0"};
obsolete_1(crypto, rsa_verify, 4) ->
- {deprecated, {crypto, verify, 5}};
+ {removed, {crypto, verify, 5}, "20.0"};
obsolete_1(crypto, dss_sign, 2) ->
- {deprecated, {crypto, sign, 4}};
+ {removed, {crypto, sign, 4}, "20.0"};
obsolete_1(crypto, dss_sign, 3) ->
- {deprecated, {crypto, sign, 4}};
+ {removed, {crypto, sign, 4}, "20.0"};
obsolete_1(crypto, dss_verify, 3) ->
- {deprecated, {crypto, verify, 5}};
+ {removed, {crypto, verify, 5}, "20.0"};
obsolete_1(crypto, dss_verify, 4) ->
- {deprecated, {crypto, verify, 5}};
+ {removed, {crypto, verify, 5}, "20.0"};
obsolete_1(crypto, mod_exp, 3) ->
- {deprecated, {crypto, mod_pow, 3}};
+ {removed, {crypto, mod_pow, 3}, "20.0"};
obsolete_1(crypto, dh_compute_key, 3) ->
- {deprecated, {crypto, compute_key, 4}};
+ {removed, {crypto, compute_key, 4}, "20.0"};
obsolete_1(crypto, dh_generate_key, 1) ->
- {deprecated, {crypto, generate_key, 2}};
+ {removed, {crypto, generate_key, 2}, "20.0"};
obsolete_1(crypto, dh_generate_key, 2) ->
- {deprecated, {crypto, generate_key, 3}};
+ {removed, {crypto, generate_key, 3}, "20.0"};
obsolete_1(crypto, des_cbc_encrypt, 3) ->
- {deprecated, {crypto, block_encrypt, 4}};
+ {removed, {crypto, block_encrypt, 4}, "20.0"};
obsolete_1(crypto, des3_cbc_encrypt, 5) ->
- {deprecated, {crypto, block_encrypt, 4}};
+ {removed, {crypto, block_encrypt, 4}, "20.0"};
obsolete_1(crypto, des_ecb_encrypt, 2) ->
- {deprecated, {crypto, block_encrypt, 3}};
+ {removed, {crypto, block_encrypt, 3}, "20.0"};
obsolete_1(crypto, des_ede3_cbc_encrypt, 5) ->
- {deprecated, {crypto, block_encrypt, 4}};
+ {removed, {crypto, block_encrypt, 4}, "20.0"};
obsolete_1(crypto, des_cfb_encrypt, 3) ->
- {deprecated, {crypto, block_encrypt, 4}};
+ {removed, {crypto, block_encrypt, 4}, "20.0"};
obsolete_1(crypto, des3_cfb_encrypt, 5) ->
- {deprecated, {crypto, block_encrypt, 4}};
+ {removed, {crypto, block_encrypt, 4}, "20.0"};
obsolete_1(crypto, blowfish_ecb_encrypt, 2) ->
- {deprecated, {crypto, block_encrypt, 3}};
+ {removed, {crypto, block_encrypt, 3}, "20.0"};
obsolete_1(crypto, blowfish_cbc_encrypt, 3) ->
- {deprecated, {crypto, block_encrypt, 4}};
+ {removed, {crypto, block_encrypt, 4}, "20.0"};
obsolete_1(crypto, blowfish_cfb64_encrypt, 3) ->
- {deprecated, {crypto, block_encrypt, 4}};
+ {removed, {crypto, block_encrypt, 4}, "20.0"};
obsolete_1(crypto, blowfish_ofb64_encrypt, 3) ->
- {deprecated, {crypto, block_encrypt, 4}};
+ {removed, {crypto, block_encrypt, 4}, "20.0"};
obsolete_1(crypto, aes_cfb_128_encrypt, 3) ->
- {deprecated, {crypto, block_encrypt, 4}};
+ {removed, {crypto, block_encrypt, 4}, "20.0"};
obsolete_1(crypto, aes_cbc_128_encrypt, 3) ->
- {deprecated, {crypto, block_encrypt, 4}};
+ {removed, {crypto, block_encrypt, 4}, "20.0"};
obsolete_1(crypto, aes_cbc_256_encrypt, 3) ->
- {deprecated, {crypto, block_encrypt, 4}};
+ {removed, {crypto, block_encrypt, 4}, "20.0"};
obsolete_1(crypto,rc2_cbc_encrypt, 3) ->
- {deprecated, {crypto, block_encrypt, 4}};
+ {removed, {crypto, block_encrypt, 4}, "20.0"};
obsolete_1(crypto,rc2_40_cbc_encrypt, 3) ->
- {deprecated, {crypto, block_encrypt, 4}};
+ {removed, {crypto, block_encrypt, 4}, "20.0"};
obsolete_1(crypto, des_cbc_decrypt, 3) ->
- {deprecated, {crypto, block_decrypt, 4}};
+ {removed, {crypto, block_decrypt, 4}, "20.0"};
obsolete_1(crypto, des3_cbc_decrypt, 5) ->
- {deprecated, {crypto, block_decrypt, 4}};
+ {removed, {crypto, block_decrypt, 4}, "20.0"};
obsolete_1(crypto, des_ecb_decrypt, 2) ->
- {deprecated, {crypto, block_decrypt, 3}};
+ {removed, {crypto, block_decrypt, 3}, "20.0"};
obsolete_1(crypto, des_ede3_cbc_decrypt, 5) ->
- {deprecated, {crypto, block_decrypt, 4}};
+ {removed, {crypto, block_decrypt, 4}, "20.0"};
obsolete_1(crypto, des_cfb_decrypt, 3) ->
- {deprecated, {crypto, block_decrypt, 4}};
+ {removed, {crypto, block_decrypt, 4}, "20.0"};
obsolete_1(crypto, des3_cfb_decrypt, 5) ->
- {deprecated, {crypto, block_decrypt, 4}};
+ {removed, {crypto, block_decrypt, 4}, "20.0"};
obsolete_1(crypto, blowfish_ecb_decrypt, 2) ->
- {deprecated, {crypto, block_decrypt, 3}};
+ {removed, {crypto, block_decrypt, 3}, "20.0"};
obsolete_1(crypto, blowfish_cbc_decrypt, 3) ->
- {deprecated, {crypto, block_decrypt, 4}};
+ {removed, {crypto, block_decrypt, 4}, "20.0"};
obsolete_1(crypto, blowfish_cfb64_decrypt, 3) ->
- {deprecated, {crypto, block_decrypt, 4}};
+ {removed, {crypto, block_decrypt, 4}, "20.0"};
obsolete_1(crypto, blowfish_ofb64_decrypt, 3) ->
- {deprecated, {crypto, block_decrypt, 4}};
+ {removed, {crypto, block_decrypt, 4}, "20.0"};
obsolete_1(crypto, aes_cfb_128_decrypt, 3) ->
- {deprecated, {crypto, block_decrypt, 4}};
+ {removed, {crypto, block_decrypt, 4}, "20.0"};
obsolete_1(crypto, aes_cbc_128_decrypt, 3) ->
- {deprecated, {crypto, block_decrypt, 4}};
+ {removed, {crypto, block_decrypt, 4}, "20.0"};
obsolete_1(crypto, aes_cbc_256_decrypt, 3) ->
- {deprecated, {crypto, block_decrypt, 4}};
+ {removed, {crypto, block_decrypt, 4}, "20.0"};
obsolete_1(crypto,rc2_cbc_decrypt, 3) ->
- {deprecated, {crypto, block_decrypt, 4}};
+ {removed, {crypto, block_decrypt, 4}, "20.0"};
obsolete_1(crypto,rc2_40_cbc_decrypt, 3) ->
- {deprecated, {crypto, block_decrypt, 4}};
+ {removed, {crypto, block_decrypt, 4}, "20.0"};
obsolete_1(crypto, aes_ctr_stream_decrypt, 2) ->
- {deprecated, {crypto, stream_decrypt, 2}};
+ {removed, {crypto, stream_decrypt, 2}, "20.0"};
obsolete_1(crypto, aes_ctr_stream_encrypt, 2) ->
- {deprecated, {crypto, stream_encrypt, 2}};
+ {removed, {crypto, stream_encrypt, 2}, "20.0"};
obsolete_1(crypto, aes_ctr_decrypt, 3) ->
- {deprecated, {crypto, stream_decrypt, 2}};
+ {removed, {crypto, stream_decrypt, 2}, "20.0"};
obsolete_1(crypto, aes_ctr_encrypt, 3) ->
- {deprecated, {crypto, stream_encrypt, 2}};
+ {removed, {crypto, stream_encrypt, 2}, "20.0"};
obsolete_1(crypto, rc4_encrypt, 2) ->
- {deprecated, {crypto, stream_encrypt, 2}};
+ {removed, {crypto, stream_encrypt, 2}, "20.0"};
obsolete_1(crypto, rc4_encrypt_with_state, 2) ->
- {deprecated, {crypto, stream_encrypt, 2}};
+ {removed, {crypto, stream_encrypt, 2}, "20.0"};
obsolete_1(crypto, aes_ctr_stream_init, 2) ->
- {deprecated, {crypto, stream_init, 3}};
+ {removed, {crypto, stream_init, 3}, "20.0"};
obsolete_1(crypto, rc4_set_key, 1) ->
- {deprecated, {crypto, stream_init, 2}};
+ {removed, {crypto, stream_init, 2}, "20.0"};
obsolete_1(crypto, rsa_private_decrypt, 3) ->
- {deprecated, {crypto, private_decrypt, 4}};
+ {removed, {crypto, private_decrypt, 4}, "20.0"};
obsolete_1(crypto, rsa_public_decrypt, 3) ->
- {deprecated, {crypto, public_decrypt, 4}};
+ {removed, {crypto, public_decrypt, 4}, "20.0"};
obsolete_1(crypto, rsa_private_encrypt, 3) ->
- {deprecated, {crypto, private_encrypt, 4}};
+ {removed, {crypto, private_encrypt, 4}, "20.0"};
obsolete_1(crypto, rsa_public_encrypt, 3) ->
- {deprecated, {crypto, public_encrypt, 4}};
+ {removed, {crypto, public_encrypt, 4}, "20.0"};
obsolete_1(crypto, des_cfb_ivec, 2) ->
- {deprecated, {crypto, next_iv, 3}};
+ {removed, {crypto, next_iv, 3}, "20.0"};
obsolete_1(crypto,des_cbc_ivec, 1) ->
- {deprecated, {crypto, next_iv, 2}};
+ {removed, {crypto, next_iv, 2}, "20.0"};
obsolete_1(crypto, aes_cbc_ivec, 1) ->
- {deprecated, {crypto, next_iv, 2}};
+ {removed, {crypto, next_iv, 2}, "20.0"};
obsolete_1(crypto,info, 0) ->
- {deprecated, {crypto, module_info, 0}};
+ {removed, {crypto, module_info, 0}, "20.0"};
obsolete_1(crypto, strong_rand_mpint, 3) ->
- {deprecated, "needed only by deprecated functions"};
+ {removed, "removed in 20.0; only needed by removed functions"};
obsolete_1(crypto, erlint, 1) ->
- {deprecated, "needed only by deprecated functions"};
+ {removed, "removed in 20.0; only needed by removed functions"};
obsolete_1(crypto, mpint, 1) ->
- {deprecated, "needed only by deprecated functions"};
+ {removed, "removed in 20.0; only needed by removed functions"};
%% *** SNMP ***
@@ -387,13 +392,13 @@ obsolete_1(erlang, concat_binary, 1) ->
%% Added in R14A.
obsolete_1(ssl, peercert, 2) ->
- {deprecated,"deprecated (will be removed in R15A); use ssl:peercert/1 and public_key:pkix_decode_cert/2 instead"};
+ {removed ,"removed in R15A; use ssl:peercert/1 and public_key:pkix_decode_cert/2 instead"};
%% Added in R14B.
obsolete_1(public_key, pem_to_der, 1) ->
- {deprecated,"deprecated (will be removed in R15A); use file:read_file/1 and public_key:pem_decode/1"};
+ {removed,"removed in R15A; use file:read_file/1 and public_key:pem_decode/1"};
obsolete_1(public_key, decode_private_key, A) when A =:= 1; A =:= 2 ->
- {deprecated,{public_key,pem_entry_decode,1},"R15A"};
+ {removed, "removed in R15A; use public_key:pem_entry_decode/1"};
%% Added in R14B03.
obsolete_1(docb_gen, _, _) ->
@@ -415,10 +420,10 @@ obsolete_1(inviso, _, _) ->
obsolete_1(gs, _, _) ->
{removed,"the gs application has been removed; use the wx application instead"};
obsolete_1(ssh, sign_data, 2) ->
- {deprecated,"deprecated (will be removed in R16A); use public_key:pem_decode/1, public_key:pem_entry_decode/1 "
+ {removed,"removed in R16A; use public_key:pem_decode/1, public_key:pem_entry_decode/1 "
"and public_key:sign/3 instead"};
obsolete_1(ssh, verify_data, 3) ->
- {deprecated,"deprecated (will be removed in R16A); use public_key:ssh_decode/1, and public_key:verify/4 instead"};
+ {removed,"removed in R16A; use public_key:ssh_decode/1, and public_key:verify/4 instead"};
%% Added in R16
obsolete_1(wxCalendarCtrl, enableYearChange, _) -> %% wx bug documented?
@@ -515,10 +520,9 @@ obsolete_1(erl_parse, get_attribute, 2) ->
obsolete_1(erl_lint, modify_line, 2) ->
{removed,{erl_parse,map_anno,2},"19.0"};
obsolete_1(ssl, negotiated_next_protocol, 1) ->
- {deprecated,{ssl,negotiated_protocol,1}};
-
+ {removed,"removed in 20.0; use ssl:negotiated_protocol/1 instead"};
obsolete_1(ssl, connection_info, 1) ->
- {deprecated, "deprecated; use connection_information/[1,2] instead"};
+ {removed, "removed in 20.0; use ssl:connection_information/[1,2] instead"};
obsolete_1(httpd_conf, check_enum, 2) ->
{deprecated, "deprecated; use lists:member/2 instead"};
diff --git a/lib/stdlib/test/erl_lint_SUITE.erl b/lib/stdlib/test/erl_lint_SUITE.erl
index 4af1c26c0f..fd7de65302 100644
--- a/lib/stdlib/test/erl_lint_SUITE.erl
+++ b/lib/stdlib/test/erl_lint_SUITE.erl
@@ -2099,11 +2099,11 @@ otp_5362(Config) when is_list(Config) ->
[{2,erl_lint,disallowed_nowarn_bif_clash}],[]}},
{call_deprecated_function,
- <<"t(X) -> crypto:md5(X).">>,
+ <<"t(X) -> calendar:local_time_to_universal_time(X).">>,
[],
{warnings,
- [{1,erl_lint,{deprecated,{crypto,md5,1},
- {crypto,hash,2}, "a future release"}}]}},
+ [{1,erl_lint,{deprecated,{calendar,local_time_to_universal_time,1},
+ {calendar,local_time_to_universal_time_dst,1}, "a future release"}}]}},
{call_removed_function,
<<"t(X) -> regexp:match(X).">>,