aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssl/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ssl/src')
-rw-r--r--lib/ssl/src/ssl.appup.src2
-rw-r--r--lib/ssl/src/ssl.erl111
-rw-r--r--lib/ssl/src/ssl_alert.erl2
-rw-r--r--lib/ssl/src/ssl_connection.erl60
4 files changed, 94 insertions, 81 deletions
diff --git a/lib/ssl/src/ssl.appup.src b/lib/ssl/src/ssl.appup.src
index 76e14860ec..a8a494b2fc 100644
--- a/lib/ssl/src/ssl.appup.src
+++ b/lib/ssl/src/ssl.appup.src
@@ -1,12 +1,14 @@
%% -*- erlang -*-
{"%VSN%",
[
+ {<<"5.2">>, [{restart_application, ssl}]},
{<<"5.1\\*">>, [{restart_application, ssl}]},
{<<"5.0\\*">>, [{restart_application, ssl}]},
{<<"4\\.*">>, [{restart_application, ssl}]},
{<<"3\\.*">>, [{restart_application, ssl}]}
],
[
+ {<<"5.2">>, [{restart_application, ssl}]},
{<<"5.1\\*">>, [{restart_application, ssl}]},
{<<"5.0\\*">>, [{restart_application, ssl}]},
{<<"4\\.*">>, [{restart_application, ssl}]},
diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl
index 647daeb1ac..0ba59cede2 100644
--- a/lib/ssl/src/ssl.erl
+++ b/lib/ssl/src/ssl.erl
@@ -162,7 +162,7 @@ connect(Host, Port, Options, Timeout) ->
%% Description: Creates an ssl listen socket.
%%--------------------------------------------------------------------
listen(_Port, []) ->
- {error, enooptions};
+ {error, nooptions};
listen(Port, Options0) ->
try
{ok, Config} = handle_options(Options0, server),
@@ -380,13 +380,13 @@ getopts(#sslsocket{pid = {ListenSocket, #config{cb = {Transport,_,_,_}}}},
{ok, _} = Result ->
Result;
{error, InetError} ->
- {error, {eoptions, {socket_options, OptionTags, InetError}}}
+ {error, {options, {socket_options, OptionTags, InetError}}}
catch
_:_ ->
- {error, {eoptions, {socket_options, OptionTags}}}
+ {error, {options, {socket_options, OptionTags}}}
end;
getopts(#sslsocket{}, OptionTags) ->
- {error, {eoptions, {socket_options, OptionTags}}}.
+ {error, {options, {socket_options, OptionTags}}}.
%%--------------------------------------------------------------------
-spec setopts(#sslsocket{}, [gen_tcp:option()]) -> ok | {error, reason()}.
@@ -400,7 +400,7 @@ setopts(#sslsocket{pid = Pid}, Options0) when is_pid(Pid), is_list(Options0) ->
ssl_connection:set_opts(Pid, Options)
catch
_:_ ->
- {error, {eoptions, {not_a_proplist, Options0}}}
+ {error, {options, {not_a_proplist, Options0}}}
end;
setopts(#sslsocket{pid = {ListenSocket, #config{cb = {Transport,_,_,_}}}}, Options) when is_list(Options) ->
@@ -408,13 +408,13 @@ setopts(#sslsocket{pid = {ListenSocket, #config{cb = {Transport,_,_,_}}}}, Optio
ok ->
ok;
{error, InetError} ->
- {error, {eoptions, {socket_options, Options, InetError}}}
+ {error, {options, {socket_options, Options, InetError}}}
catch
_:Error ->
- {error, {eoptions, {socket_options, Options, Error}}}
+ {error, {options, {socket_options, Options, Error}}}
end;
setopts(#sslsocket{}, Options) ->
- {error, {eoptions,{not_a_proplist, Options}}}.
+ {error, {options,{not_a_proplist, Options}}}.
%%---------------------------------------------------------------
-spec shutdown(#sslsocket{}, read | write | read_write) -> ok | {error, reason()}.
@@ -503,24 +503,26 @@ format_error({error, Reason}) ->
format_error(Reason) when is_list(Reason) ->
Reason;
format_error(closed) ->
- "The connection is closed";
-format_error({ecacertfile, _}) ->
- "Own CA certificate file is invalid.";
-format_error({ecertfile, _}) ->
- "Own certificate file is invalid.";
-format_error({ekeyfile, _}) ->
- "Own private key file is invalid.";
-format_error({essl, Description}) ->
- Description;
-format_error({eoptions, Options}) ->
- lists:flatten(io_lib:format("Error in options list: ~p~n", [Options]));
+ "TLS connection is closed";
+format_error({tls_alert, Description}) ->
+ "TLS Alert: " ++ Description;
+format_error({options,{FileType, File, Reason}}) when FileType == cacertfile;
+ FileType == certfile;
+ FileType == keyfile;
+ FileType == dhfile ->
+ Error = file_error_format(Reason),
+ file_desc(FileType) ++ File ++ ": " ++ Error;
+format_error({options, {socket_options, Option, Error}}) ->
+ lists:flatten(io_lib:format("Invalid transport socket option ~p: ~s", [Option, format_error(Error)]));
+format_error({options, {socket_options, Option}}) ->
+ lists:flatten(io_lib:format("Invalid socket option: ~p", [Option]));
+format_error({options, Options}) ->
+ lists:flatten(io_lib:format("Invalid TLS option: ~p", [Options]));
format_error(Error) ->
- case (catch inet:format_error(Error)) of
- "unkknown POSIX" ++ _ ->
- no_format(Error);
- {'EXIT', _} ->
- no_format(Error);
+ case inet:format_error(Error) of
+ "unknown POSIX" ++ _ ->
+ unexpected_format(Error);
Other ->
Other
end.
@@ -541,8 +543,6 @@ random_bytes(N) ->
crypto:rand_bytes(N)
end.
-
-
%%%--------------------------------------------------------------
%%% Internal functions
%%%--------------------------------------------------------------------
@@ -559,11 +559,11 @@ do_connect(Address, Port,
{error, Reason}
catch
exit:{function_clause, _} ->
- {error, {eoptions, {cb_info, CbInfo}}};
+ {error, {options, {cb_info, CbInfo}}};
exit:badarg ->
- {error, {eoptions, {socket_options, UserOpts}}};
+ {error, {options, {socket_options, UserOpts}}};
exit:{badarg, _} ->
- {error, {eoptions, {socket_options, UserOpts}}}
+ {error, {options, {socket_options, UserOpts}}}
end.
handle_options(Opts0, _Role) ->
@@ -607,7 +607,7 @@ handle_options(Opts0, _Role) ->
{verify_peer, UserFailIfNoPeerCert,
ca_cert_default(verify_peer, UserVerifyFun, CaCerts), UserVerifyFun};
Value ->
- throw({error, {eoptions, {verify, Value}}})
+ throw({error, {options, {verify, Value}}})
end,
CertFile = handle_option(certfile, Opts, <<>>),
@@ -754,9 +754,9 @@ validate_option(ciphers, Value) when is_list(Value) ->
try cipher_suites(Version, Value)
catch
exit:_ ->
- throw({error, {eoptions, {ciphers, Value}}});
+ throw({error, {options, {ciphers, Value}}});
error:_->
- throw({error, {eoptions, {ciphers, Value}}})
+ throw({error, {options, {ciphers, Value}}})
end;
validate_option(reuse_session, Value) when is_function(Value) ->
Value;
@@ -781,7 +781,7 @@ validate_option(client_preferred_next_protocols = Opt, {Precedence, PreferredPro
when is_list(PreferredProtocols) ->
case ssl_record:highest_protocol_version([]) of
{3,0} ->
- throw({error, {eoptions, {not_supported_in_sslv3, {Opt, Value}}}});
+ throw({error, {options, {not_supported_in_sslv3, {Opt, Value}}}});
_ ->
validate_binary_list(client_preferred_next_protocols, PreferredProtocols),
validate_npn_ordering(Precedence),
@@ -792,7 +792,7 @@ validate_option(client_preferred_next_protocols = Opt, {Precedence, PreferredPro
byte_size(Default) > 0, byte_size(Default) < 256 ->
case ssl_record:highest_protocol_version([]) of
{3,0} ->
- throw({error, {eoptions, {not_supported_in_sslv3, {Opt, Value}}}});
+ throw({error, {options, {not_supported_in_sslv3, {Opt, Value}}}});
_ ->
validate_binary_list(client_preferred_next_protocols, PreferredProtocols),
validate_npn_ordering(Precedence),
@@ -804,7 +804,7 @@ validate_option(client_preferred_next_protocols, undefined) ->
validate_option(next_protocols_advertised = Opt, Value) when is_list(Value) ->
case ssl_record:highest_protocol_version([]) of
{3,0} ->
- throw({error, {eoptions, {not_supported_in_sslv3, {Opt, Value}}}});
+ throw({error, {options, {not_supported_in_sslv3, {Opt, Value}}}});
_ ->
validate_binary_list(next_protocols_advertised, Value),
Value
@@ -813,14 +813,14 @@ validate_option(next_protocols_advertised = Opt, Value) when is_list(Value) ->
validate_option(next_protocols_advertised, undefined) ->
undefined;
validate_option(Opt, Value) ->
- throw({error, {eoptions, {Opt, Value}}}).
+ throw({error, {options, {Opt, Value}}}).
validate_npn_ordering(client) ->
ok;
validate_npn_ordering(server) ->
ok;
validate_npn_ordering(Value) ->
- throw({error, {eoptions, {client_preferred_next_protocols, {invalid_precedence, Value}}}}).
+ throw({error, {options, {client_preferred_next_protocols, {invalid_precedence, Value}}}}).
validate_binary_list(Opt, List) ->
lists:foreach(
@@ -829,7 +829,7 @@ validate_binary_list(Opt, List) ->
byte_size(Bin) < 256 ->
ok;
(Bin) ->
- throw({error, {eoptions, {Opt, {invalid_protocol, Bin}}}})
+ throw({error, {options, {Opt, {invalid_protocol, Bin}}}})
end, List).
validate_versions([], Versions) ->
@@ -840,23 +840,23 @@ validate_versions([Version | Rest], Versions) when Version == 'tlsv1.2';
Version == sslv3 ->
validate_versions(Rest, Versions);
validate_versions([Ver| _], Versions) ->
- throw({error, {eoptions, {Ver, {versions, Versions}}}}).
+ throw({error, {options, {Ver, {versions, Versions}}}}).
validate_inet_option(mode, Value)
when Value =/= list, Value =/= binary ->
- throw({error, {eoptions, {mode,Value}}});
+ throw({error, {options, {mode,Value}}});
validate_inet_option(packet, Value)
when not (is_atom(Value) orelse is_integer(Value)) ->
- throw({error, {eoptions, {packet,Value}}});
+ throw({error, {options, {packet,Value}}});
validate_inet_option(packet_size, Value)
when not is_integer(Value) ->
- throw({error, {eoptions, {packet_size,Value}}});
+ throw({error, {options, {packet_size,Value}}});
validate_inet_option(header, Value)
when not is_integer(Value) ->
- throw({error, {eoptions, {header,Value}}});
+ throw({error, {options, {header,Value}}});
validate_inet_option(active, Value)
when Value =/= true, Value =/= false, Value =/= once ->
- throw({error, {eoptions, {active,Value}}});
+ throw({error, {options, {active,Value}}});
validate_inet_option(_, _) ->
ok.
@@ -935,8 +935,27 @@ cipher_suites(Version, Ciphers0) ->
Ciphers = [ssl_cipher:openssl_suite(C) || C <- string:tokens(Ciphers0, ":")],
cipher_suites(Version, Ciphers).
-no_format(Error) ->
- lists:flatten(io_lib:format("No format string for error: \"~p\" available.", [Error])).
+unexpected_format(Error) ->
+ lists:flatten(io_lib:format("Unexpected error: ~p", [Error])).
+
+file_error_format({error, Error})->
+ case file:format_error(Error) of
+ "unknown POSIX error" ->
+ "decoding error";
+ Str ->
+ Str
+ end;
+file_error_format(_) ->
+ "decoding error".
+
+file_desc(cacertfile) ->
+ "Invalid CA certificate file ";
+file_desc(certfile) ->
+ "Invalid certificate file ";
+file_desc(keyfile) ->
+ "Invalid key file ";
+file_desc(dhfile) ->
+ "Invalid DH params file ".
detect(_Pred, []) ->
undefined;
diff --git a/lib/ssl/src/ssl_alert.erl b/lib/ssl/src/ssl_alert.erl
index f94a1136a0..94e95d3cd3 100644
--- a/lib/ssl/src/ssl_alert.erl
+++ b/lib/ssl/src/ssl_alert.erl
@@ -45,7 +45,7 @@
reason_code(#alert{description = ?CLOSE_NOTIFY}, _) ->
closed;
reason_code(#alert{description = Description}, _) ->
- {essl, description_txt(Description)}.
+ {tls_alert, description_txt(Description)}.
%%--------------------------------------------------------------------
-spec alert_txt(#alert{}) -> string().
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl
index f51f1c6115..8f4fd88d42 100644
--- a/lib/ssl/src/ssl_connection.erl
+++ b/lib/ssl/src/ssl_connection.erl
@@ -987,7 +987,7 @@ handle_info({ErrorTag, Socket, econnaborted}, StateName,
#state{socket = Socket, transport_cb = Transport,
start_or_recv_from = StartFrom, role = Role,
error_tag = ErrorTag} = State) when StateName =/= connection ->
- alert_user(Transport, Socket, StartFrom, ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE), Role),
+ alert_user(Transport, Socket, StartFrom, ?ALERT_REC(?FATAL, ?CLOSE_NOTIFY), Role),
{stop, normal, State};
handle_info({ErrorTag, Socket, Reason}, StateName, #state{socket = Socket,
@@ -1136,9 +1136,8 @@ init_certificates(#ssl_options{cacerts = CaCerts,
end,
{ok, _, _, _, _, _} = ssl_manager:connection_init(Certs, Role)
catch
- Error:Reason ->
- handle_file_error(?LINE, Error, Reason, CACertFile, {ecacertfile, Reason},
- erlang:get_stacktrace())
+ _:Reason ->
+ file_error(CACertFile, {cacertfile, Reason})
end,
init_certificates(Cert, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheHandle, CertFile, Role).
@@ -1158,9 +1157,8 @@ init_certificates(undefined, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHan
[OwnCert] = ssl_certificate:file_to_certificats(CertFile, PemCacheHandle),
{ok, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheRef, OwnCert}
catch
- Error:Reason ->
- handle_file_error(?LINE, Error, Reason, CertFile, {ecertfile, Reason},
- erlang:get_stacktrace())
+ _:Reason ->
+ file_error(CertFile, {certfile, Reason})
end;
init_certificates(Cert, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheRef, _, _) ->
{ok, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheRef, Cert}.
@@ -1177,9 +1175,8 @@ init_private_key(DbHandle, undefined, KeyFile, Password, _) ->
],
private_key(public_key:pem_entry_decode(PemEntry, Password))
catch
- Error:Reason ->
- handle_file_error(?LINE, Error, Reason, KeyFile, {ekeyfile, Reason},
- erlang:get_stacktrace())
+ _:Reason ->
+ file_error(KeyFile, {keyfile, Reason})
end;
%% First two clauses are for backwards compatibility
@@ -1205,18 +1202,14 @@ private_key(#'PrivateKeyInfo'{privateKeyAlgorithm =
private_key(Key) ->
Key.
--spec(handle_file_error(_,_,_,_,_,_) -> no_return()).
-handle_file_error(Line, Error, {badmatch, Reason}, File, Throw, Stack) ->
- file_error(Line, Error, Reason, File, Throw, Stack);
-handle_file_error(Line, Error, Reason, File, Throw, Stack) ->
- file_error(Line, Error, Reason, File, Throw, Stack).
-
--spec(file_error(_,_,_,_,_,_) -> no_return()).
-file_error(Line, Error, Reason, File, Throw, Stack) ->
- Report = io_lib:format("SSL: ~p: ~p:~p ~s~n ~p~n",
- [Line, Error, Reason, File, Stack]),
- error_logger:error_report(Report),
- throw(Throw).
+-spec(file_error(_,_) -> no_return()).
+file_error(File, Throw) ->
+ case Throw of
+ {Opt,{badmatch, {error, {badmatch, Error}}}} ->
+ throw({options, {Opt, binary_to_list(File), Error}});
+ _ ->
+ throw(Throw)
+ end.
init_diffie_hellman(_,Params, _,_) when is_binary(Params)->
public_key:der_decode('DHParameter', Params);
@@ -1234,9 +1227,8 @@ init_diffie_hellman(DbHandle,_, DHParamFile, server) ->
?DEFAULT_DIFFIE_HELLMAN_PARAMS
end
catch
- Error:Reason ->
- handle_file_error(?LINE, Error, Reason,
- DHParamFile, {edhfile, Reason}, erlang:get_stacktrace())
+ _:Reason ->
+ file_error(DHParamFile, {dhfile, Reason})
end.
sync_send_all_state_event(FsmPid, Event) ->
@@ -2179,13 +2171,13 @@ get_socket_opts(Transport, Socket, [Tag | Tags], SockOpts, Acc) ->
{ok, [Opt]} ->
get_socket_opts(Transport, Socket, Tags, SockOpts, [Opt | Acc]);
{error, Error} ->
- {error, {eoptions, {socket_option, Tag, Error}}}
+ {error, {options, {socket_options, Tag, Error}}}
catch
%% So that inet behavior does not crash our process
- _:Error -> {error, {eoptions, {socket_option, Tag, Error}}}
+ _:Error -> {error, {options, {socket_options, Tag, Error}}}
end;
get_socket_opts(_, _,Opts, _,_) ->
- {error, {eoptions, {socket_options, Opts, function_clause}}}.
+ {error, {options, {socket_options, Opts, function_clause}}}.
set_socket_opts(_,_, [], SockOpts, []) ->
{ok, SockOpts};
@@ -2195,18 +2187,18 @@ set_socket_opts(Transport, Socket, [], SockOpts, Other) ->
ok ->
{ok, SockOpts};
{error, InetError} ->
- {{error, {eoptions, {socket_option, Other, InetError}}}, SockOpts}
+ {{error, {options, {socket_options, Other, InetError}}}, SockOpts}
catch
_:Error ->
%% So that inet behavior does not crash our process
- {{error, {eoptions, {socket_option, Other, Error}}}, SockOpts}
+ {{error, {options, {socket_options, Other, Error}}}, SockOpts}
end;
set_socket_opts(Transport,Socket, [{mode, Mode}| Opts], SockOpts, Other) when Mode == list; Mode == binary ->
set_socket_opts(Transport, Socket, Opts,
SockOpts#socket_options{mode = Mode}, Other);
set_socket_opts(_, _, [{mode, _} = Opt| _], SockOpts, _) ->
- {{error, {eoptions, {socket_option, Opt}}}, SockOpts};
+ {{error, {options, {socket_options, Opt}}}, SockOpts};
set_socket_opts(Transport,Socket, [{packet, Packet}| Opts], SockOpts, Other) when Packet == raw;
Packet == 0;
Packet == 1;
@@ -2225,19 +2217,19 @@ set_socket_opts(Transport,Socket, [{packet, Packet}| Opts], SockOpts, Other) whe
set_socket_opts(Transport, Socket, Opts,
SockOpts#socket_options{packet = Packet}, Other);
set_socket_opts(_, _, [{packet, _} = Opt| _], SockOpts, _) ->
- {{error, {eoptions, {socket_option, Opt}}}, SockOpts};
+ {{error, {options, {socket_options, Opt}}}, SockOpts};
set_socket_opts(Transport, Socket, [{header, Header}| Opts], SockOpts, Other) when is_integer(Header) ->
set_socket_opts(Transport, Socket, Opts,
SockOpts#socket_options{header = Header}, Other);
set_socket_opts(_, _, [{header, _} = Opt| _], SockOpts, _) ->
- {{error,{eoptions, {socket_option, Opt}}}, SockOpts};
+ {{error,{options, {socket_options, Opt}}}, SockOpts};
set_socket_opts(Transport, Socket, [{active, Active}| Opts], SockOpts, Other) when Active == once;
Active == true;
Active == false ->
set_socket_opts(Transport, Socket, Opts,
SockOpts#socket_options{active = Active}, Other);
set_socket_opts(_, _, [{active, _} = Opt| _], SockOpts, _) ->
- {{error, {eoptions, {socket_option, Opt}} }, SockOpts};
+ {{error, {options, {socket_options, Opt}} }, SockOpts};
set_socket_opts(Transport, Socket, [Opt | Opts], SockOpts, Other) ->
set_socket_opts(Transport, Socket, Opts, SockOpts, [Opt | Other]).