> ## 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"])}].

Copyright © 1991-2003 Ericsson Utvecklings AB