TLS/SSL/DTLS OpenSSL/BoringSSL-based NIF library for Erlang using the same interface as erlang ssl module.
This module contains interface functions for the SSL/TLS protocol.
At this moment not all methods available in ssl module are implemented and also not all ssl_option are supported.
The library is implemented in top of gen_tcp and OpenSSL API. Because SSL_* API is not thread safe in order to make sure
that all calls for the same socket are not executed concurrently each socket has a gen_server to interact with native layer.
This way we don't have to use any kind of locking at native level. Also read/write operations are not taking place in the
gen_server process, they take place in calling process, in order to avoid gen_server to become a bottleneck for the socket.
The library is working with both OpenSSL or BoringSSL. Be default BoringSSL is used. To change the behavior you need to specify the
USE_BORINGSSL environment variable:
USE_BORINGSSL=0 rebar compile
Note: Using sslv3 is not available into BoringSSL because it's considered unsecure.
Add erltls as a rebar/rebar3 dependency to your project:
{deps, [
{erltls, ".*", {git, "https://github.com/silviucpp/erltls.git", "master"}},
}.
Now you can use erltls module the same way you are using ssl:
%% server side
erltls:start(),
{ok, ListenSocket} = erltls:listen(9999, [
{certfile, "test/server.pem"},
{reuseaddr, true}
]),
{ok, Socket} = erltls:transport_accept(ListenSocket),
ok = erltls:ssl_accept(Socket),
ok = erltls:setopts(Socket, [{active, once}]),
receive AMessage -> io:format("recv:~p~n", [AMessage]) end,
ok = erltls:close(Socket),
ok = erltls:close(ListenSocket).%% client side
erltls:start(),
{ok, Socket} = erltls:connect("localhost", 9999, [], infinity),
ok = erltls:send(Socket, "foo"),
ok = erltls:close(Socket).erltls can be easily used with ranch by starting a listener with ranch_erltls as the transport module:
{ok, _} = ranch:start_listener(tcp_echo, 100,
ranch_erltls, [{port, 5555}, {certfile, CertPath}],
echo_protocol, []).Currently supported options also available in erlang ssl:
{verify, verify_type()}{depth, integer()}{fail_if_no_peer_cert, boolean()}{certfile, path()}{keyfile, path()}{password, string()}{cacertfile, path()}{dhfile, path()}{ciphers, ciphers()}
Options currently related to erltls only:
{use_session_ticket, boolean() | {boolean(), binary()}}- Enables session reuse using tickets as described in RFC5077. In case the key is not specified the tickets will be signed using a random key. In order to specify the key use the format{true, <<"key_here">>}.{reuse_sessions_ttl, integer()}- The TTL of a session in seconds. In case the session is older than this TTL will not be possible to be reused. A full handshake will be negotiated.{protocol, protocol()}- Specify the desired protocol. By default will negotiate highest available SSL/TLS version. Available protocols values are:sslv3 | tlsv1 | 'tlsv1.1' | 'tlsv1.2' | dtlsv1 | 'dtlsv1.2'
renegotiate/1prf/5negotiated_protocol/1format_error/1eccs/1eccs/0connection_information/2
session_reused/1- Query, whether a reused session was negotiated during the handshake (make sense if session ticketing is enabled)
- working only with
{packet, 0}inet option - Handshake process don't have a timeout implemented yet. So in
connect/*orssl_accept/*the timeout param is actually not counting the handshake process.
For benchmarks between different drivers see here