2 Using the SSL API

2.1  General information

To see relevant version information for ssl you can call ssl:versions/0

To see all supported cipher suites call ssl:cipher_suites/0. Note that available cipher suites for a connection will depend on your certificate. It is also possible to specify a specific cipher suite(s) that you want your connection to use. Default is to use the strongest available.

2.2  Setting up connections

Here follows some small example of how to set up client/server connections using the erlang shell. The returned value of the sslsocket has been abbreviated with [...] as it can be fairly large and is opaque.

Minmal example

Note

The minimal setup is not the most secure setup of ssl.

Start server side

1 server> ssl:start().
ok

Create a ssl listen socket

2 server> {ok, ListenSocket} =
ssl:listen(9999, [{certfile, "cert.pem"}, {keyfile, "key.pem"},{reuseaddr, true}]).
{ok,{sslsocket, [...]}}

Do a transport accept on the ssl listen socket

3 server> {ok, Socket} = ssl:transport_accept(ListenSocket).
{ok,{sslsocket, [...]}}

Start client side

1 client> ssl:start().
ok
2 client> {ok, Socket} = ssl:connect("localhost", 9999,  [], infinity).
{ok,{sslsocket, [...]}}

Do the ssl handshake

4 server> ok = ssl:ssl_accept(Socket).
ok

Send a messag over ssl

5 server> ssl:send(Socket, "foo").
ok

Flush the shell message queue to see that we got the message sent on the server side

3 client> flush().
Shell got {ssl,{sslsocket,[...]},"foo"}
ok

Upgrade example

Note

To upgrade a TCP/IP connection to a ssl connection the client and server have to aggre to do so. Agreement may be accompliced by using a protocol such the one used by HTTP specified in RFC 2817.

Start server side

1 server> ssl:start().
ok

Create a normal tcp listen socket

2 server> {ok, ListenSocket} = gen_tcp:listen(9999, [{reuseaddr, true}]).
{ok, #Port<0.475>}

Accept client connection

3 server> {ok, Socket} = gen_tcp:accept(ListenSocket).
{ok, #Port<0.476>}

Start client side

1 client> ssl:start().
ok
2 client> {ok, Socket} = gen_tcp:connect("localhost", 9999,  [], infinity).

Make sure active is set to false before trying to upgrade a connection to a ssl connection, otherwhise ssl handshake messages may be deliverd to the wrong process.

4 server> inet:setopts(Socket, [{active, false}]).
ok

Do the ssl handshake.

5 server> {ok, SSLSocket} = ssl:ssl_accept(Socket, [{cacertfile, "cacerts.pem"},
{certfile, "cert.pem"}, {keyfile, "key.pem"}]).
{ok,{sslsocket,[...]}}

Upgrade to a ssl connection. Note that the client and server must agree upon the upgrade and the server must call ssl:accept/2 before the client calls ssl:connect/3.

3 client>{ok, SSLSocket} = ssl:connect(Socket, [{cacertfile, "cacerts.pem"},
{certfile, "cert.pem"}, {keyfile, "key.pem"}], infinity).
{ok,{sslsocket,[...]}}

Send a messag over ssl

4 client> ssl:send(SSLSocket, "foo").
ok

Set active true on the ssl socket

4 server> ssl:setopts(SSLSocket, [{active, true}]).
ok

Flush the shell message queue to see that we got the message sent on the client side

5 server> flush().
Shell got {ssl,{sslsocket,[...]},"foo"}
ok