aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeoff Cant <[email protected]>2013-04-28 01:15:45 -0700
committerGeoff Cant <[email protected]>2013-04-28 01:15:45 -0700
commit3cc134ef693e6c8184d82635faa195d1010603c7 (patch)
tree8d42ec8bca4e84e5051d302315afb38f3685d6d0
parent138b8d788ca056dcfed1f3092531020481ffa345 (diff)
downloadranch-3cc134ef693e6c8184d82635faa195d1010603c7.tar.gz
ranch-3cc134ef693e6c8184d82635faa195d1010603c7.tar.bz2
ranch-3cc134ef693e6c8184d82635faa195d1010603c7.zip
Allow ranch_ssl to use DER cert/key/ca options.
The Erlang SSL library allows keys, certs and cacerts to be passed either as DER encoded binaries or in PEM encoded files. This patch allows ranch_ssl to be configured in either manner.
-rw-r--r--src/ranch_ssl.erl14
-rw-r--r--test/acceptor_SUITE.erl27
2 files changed, 35 insertions, 6 deletions
diff --git a/src/ranch_ssl.erl b/src/ranch_ssl.erl
index 3c2d6fb..6fb2ce8 100644
--- a/src/ranch_ssl.erl
+++ b/src/ranch_ssl.erl
@@ -88,25 +88,27 @@ messages() -> {ssl, ssl_closed, ssl_error}.
%% ranch:get_port/1 instead.
%%
%% @see ssl:listen/2
--spec listen([{backlog, non_neg_integer()} | {cacertfile, string()}
+-spec listen([{backlog, non_neg_integer()} | {cacerts, [Der::binary()]}
+ | {cacertfile, string()} | {cert, Der::binary()}
| {certfile, string()} | {ciphers, [ssl:erl_cipher_suite()] | string()}
| {fail_if_no_peer_cert, boolean()}
- | {ip, inet:ip_address()} | {keyfile, string()}
+ | {ip, inet:ip_address()} | {key, Der::binary()} | {keyfile, string()}
| {next_protocols_advertised, [binary()]} | {nodelay, boolean()}
| {password, string()} | {port, inet:port_number()}
| {verify, ssl:verify_type()}])
-> {ok, ssl:sslsocket()} | {error, atom()}.
listen(Opts) ->
ranch:require([crypto, public_key, ssl]),
- {certfile, _} = lists:keyfind(certfile, 1, Opts),
+ true = lists:keymember(cert, 1, Opts)
+ orelse lists:keymember(certfile, 1, Opts),
Opts2 = ranch:set_option_default(Opts, backlog, 1024),
%% We set the port to 0 because it is given in the Opts directly.
%% The port in the options takes precedence over the one in the
%% first argument.
ssl:listen(0, ranch:filter_options(Opts2,
- [backlog, cacertfile, certfile, ciphers, fail_if_no_peer_cert, ip,
- keyfile, next_protocols_advertised, nodelay, password, port,
- raw, verify],
+ [backlog, cacerts, cacertfile, cert, certfile, ciphers,
+ fail_if_no_peer_cert, ip, key, keyfile, next_protocols_advertised,
+ nodelay, password, port, raw, verify],
[binary, {active, false}, {packet, raw},
{reuseaddr, true}, {nodelay, true}])).
diff --git a/test/acceptor_SUITE.erl b/test/acceptor_SUITE.erl
index 861ea33..f7f3b31 100644
--- a/test/acceptor_SUITE.erl
+++ b/test/acceptor_SUITE.erl
@@ -30,6 +30,7 @@
%% ssl.
-export([ssl_accept_error/1]).
-export([ssl_accept_socket/1]).
+-export([ssl_accept_socket_nofile/1]).
-export([ssl_active_echo/1]).
-export([ssl_echo/1]).
@@ -70,6 +71,7 @@ groups() ->
]}, {ssl, [
ssl_accept_error,
ssl_accept_socket,
+ ssl_accept_socket_nofile,
ssl_active_echo,
ssl_echo
]}, {misc, [
@@ -136,6 +138,31 @@ ssl_accept_error(Config) ->
true = is_process_alive(AcceptorPid),
ranch:stop_listener(Name).
+ssl_accept_socket_nofile(Config) ->
+ %%% XXX we can't do the spawn to test the controlling process change
+ %%% because of the bug in ssl
+ {ok, Pem} = file:read_file(filename:join(?config(data_dir, Config),
+ "cert.pem")),
+ [{KeyType, Key, not_encrypted},
+ {_CertType, Cert, not_encrypted}] = public_key:pem_decode(Pem),
+ Name = ssl_accept_socket,
+ {ok, S} = ssl:listen(0,
+ [{cert, Cert}, {key, {KeyType, Key}}, binary,
+ {active, false}, {packet, raw}, {reuseaddr, true}]),
+ {ok, _} = ranch:start_listener(Name, 1,
+ ranch_ssl, [{socket, S}], echo_protocol, []),
+ Port = ranch:get_port(Name),
+ {ok, Socket} = ssl:connect("localhost", Port,
+ [binary, {active, false}, {packet, raw},
+ {certfile, ?config(data_dir, Config) ++ "cert.pem"}]),
+ ok = ssl:send(Socket, <<"TCP Ranch is working!">>),
+ {ok, <<"TCP Ranch is working!">>} = ssl:recv(Socket, 21, 1000),
+ ok = ranch:stop_listener(Name),
+ {error, closed} = ssl:recv(Socket, 0, 1000),
+ %% Make sure the listener stopped.
+ {'EXIT', _} = begin catch ranch:get_port(Name) end,
+ ok.
+
ssl_accept_socket(Config) ->
%%% XXX we can't do the spawn to test the controlling process change
%%% because of the bug in ssl