Using the SSL application

## 2 Using the SSL application

Here we provide an introduction to using the Erlang/OTP SSL application, which is accessed through the ssl interface module.

We also present example code in the Erlang module client_server, also provided in the directory ssl-X.Y.Z/examples, with source code in src and the compiled module in ebin of that directory.

### 2.1 The ssl Module

The ssl module provides the user interface to the Erlang/OTP SSL application. The interface functions provided are very similar to those provided by the gen_tcp and inet modules.

Servers use the interface functions listen and accept. The listen function specifies a TCP port to to listen to, and each call to the accept function establishes an incoming connection.

Clients use the connect function which specifies the address and port of a server to connect to, and a successful call establishes such a connection.

The listen and connect functions have almost all the options that the corresponding functions in gen_tcp/ have, but there are also additional options specific to the SSL protocol.

The most important SSL specific option is the cacertfile option which specifies a local file containing trusted CA certificates which are and used for peer authentication. This option is used by clients and servers in case they want to authenticate their peers.

The certfile option specifies a local path to a file containing the certificate of the holder of the connection endpoint. In case of a server endpoint this option is mandatory since the contents of the sever certificate is needed in the the handshake preceeding the establishment of a connection.

Similarly, the keyfile option points to a local file containing the private key of the holder of the endpoint. If the certfile option is present, this option has to be specified as well, unless the private key is provided in the same file as specified by the certfile option (a certificate and a private key can thus coexist in the same file).

The verify option specifies how the peer should be verified:

0
  Do not verify the peer,
1
  Verify peer,
2
  Verify peer, fail the verification if the peer has no certificate.

The depth option specifies the maximum length of the verification certificate chain. Depth = 0 means the peer certificate, depth = 1 the CA certificate, depth = 2 the next CA certificate etc. If the verification process does not find a trusted CA certificate within the maximum length, the verification fails.

The ciphers option specifies which ciphers to use (a string of colon separated cipher names). To obtain a list of available ciphers, evaluate the ssl:ciphers/0 function (the SSL application has to be running).

### 2.2 A Client-Server Example

Here is a simple client server example.

    %%% Purpose: Example of SSL client and server using example certificates.

    -module(client_server).

    -export([start/0, start/1, init_connect/1]).

    start() ->
        start([ssl, subject]).

    start(CertOpts) ->
        %% Start ssl application
        application:start(ssl),

        %% Always seed
        ssl:seed("ellynatefttidppohjeh"),

        %% Let the current process be the server that listens and accepts
        %% Listen
        {ok, LSock} = ssl:listen(0, mk_opts(listen)),
        {ok, LPort} = ssl:port(LSock),
        io:fwrite("Listen: port = ~w.~n", [LPort]),

        %% Spawn the client process that connects to the server
        spawn(?MODULE, init_connect, [{LPort, CertOpts}]),

        %% Accept
        {ok, ASock} = ssl:accept(LSock),
        io:fwrite("Accept: accepted.~n"),
        {ok, Cert} = ssl:peercert(ASock, CertOpts),
        io:fwrite("Accept: peer cert:~n~p~n", [Cert]),
        io:fwrite("Accept: sending \"hello\".~n"),
        ssl:send(ASock, "hello"),
        {error, closed} = ssl:recv(ASock, 0),
        io:fwrite("Accept: detected closed.~n"),
        ssl:close(ASock),
        io:fwrite("Listen: closing and terminating.~n"),
        ssl:close(LSock),
        application:stop(ssl).

    %% Client connect
    init_connect({LPort, CertOpts}) ->
        {ok, Host} = inet:gethostname(),
        {ok, CSock} = ssl:connect(Host, LPort, mk_opts(connect)),
        io:fwrite("Connect: connected.~n"),
        {ok, Cert} = ssl:peercert(CSock, CertOpts),
        io:fwrite("Connect: peer cert:~n~p~n", [Cert]),
        {ok, Data} = ssl:recv(CSock, 0),
        io:fwrite("Connect: got data: ~p~n", [Data]),
        io:fwrite("Connect: closing and terminating.~n"),
        ssl:close(CSock).

    mk_opts(listen) ->
        mk_opts("server");
    mk_opts(connect) ->
        mk_opts("client");
    mk_opts(Role) ->
        Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]),
        [{active, false},
         {verify, 2},
         {depth, 2},
         {cacertfile, filename:join([Dir, Role, "cacerts.pem"])},
         {certfile, filename:join([Dir, Role, "cert.pem"])},
         {keyfile, filename:join([Dir, Role, "key.pem"])}].

ssl 3.10
Copyright © 1991-2008 Ericsson AB