diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl index c16c076afd8a..5437ead9e46a 100644 --- a/lib/ssl/src/ssl.erl +++ b/lib/ssl/src/ssl.erl @@ -94,8 +94,9 @@ connection_information/1, connection_information/2]). %% Misc --export([handle_options/2, - handle_options/3, +-export([handle_options/3, + update_options/3, + option_rules/0, tls_version/1, suite_to_str/1, suite_to_openssl_str/1, @@ -640,7 +641,7 @@ listen(_Port, []) -> {error, nooptions}; listen(Port, Options0) -> try - {ok, Config} = handle_options(Options0, server), + {ok, Config} = handle_options(Options0, server, undefined), do_listen(Port, Config, Config#config.connection_cb) catch Error = {error, _} -> @@ -1513,36 +1514,31 @@ do_listen(Port, #config{transport_info = {Transport, _, _, _,_}} = Config, tls_g do_listen(Port, Config, dtls_gen_connection) -> dtls_socket:listen(Port, Config). --spec handle_options([any()], client | server) -> {ok, #config{}}; - ([any()], ssl_options()) -> ssl_options(). - -handle_options(Opts, Role) -> - handle_options(undefined, undefined, Opts, Role, undefined). +%% Handle ssl options at handshake, handshake_continue +-spec update_options([any()], client | server, map()) -> map(). +update_options(Opts, Role, InheritedSslOpts) when is_map(InheritedSslOpts) -> + {SslOpts, _} = split_options(Opts, option_rules()), + process_options(SslOpts, InheritedSslOpts, #{role => Role, rules => option_rules()}). -handle_options(Opts, Role, InheritedSslOpts) -> - handle_options(undefined, undefined, Opts, Role, InheritedSslOpts). +-spec handle_options([any()], client | server, undefined|host()) -> {ok, #config{}}. +handle_options(Opts, Role, Host) -> + handle_options(undefined, undefined, Opts, Role, Host). -%% Handle ssl options at handshake, handshake_continue -handle_options(_, _, Opts0, Role, InheritedSslOpts) when is_map(InheritedSslOpts) -> - {SslOpts, _} = expand_options(Opts0, ?RULES), - process_options(SslOpts, InheritedSslOpts, #{role => Role, - rules => ?RULES}); %% Handle all options in listen, connect and handshake handle_options(Transport, Socket, Opts0, Role, Host) -> - {SslOpts0, SockOpts0} = expand_options(Opts0, ?RULES), - + {SslOpts0, SockOpts0} = split_options(Opts0, option_rules()), + %% Ensure all options are evaluated at startup - SslOpts1 = add_missing_options(SslOpts0, ?RULES), - SslOpts2 = #{protocol := Protocol} - = process_options(SslOpts1, - #{}, - #{role => Role, - host => Host, - rules => ?RULES}), - + SslOpts1 = add_missing_options(SslOpts0, option_rules()), + + Env = #{role => Role, host => Host, rules => option_rules()}, + SslOpts2 = process_options(SslOpts1, #{}, Env), + maybe_client_warn_no_verify(SslOpts2, Role), SslOpts = maps:without([warn_verify_none], SslOpts2), + %% Handle special options + #{protocol := Protocol} = SslOpts2, {Sock, Emulated} = emulated_options(Transport, Socket, Protocol, SockOpts0), ConnetionCb = connection_cb(Protocol), CbInfo = handle_option_cb_info(Opts0, Protocol), @@ -1557,6 +1553,110 @@ handle_options(Transport, Socket, Opts0, Role, Host) -> }}. +%% This map stores all supported options with default values and +%% list of dependencies: +%% #{