Hostname verification with Erlang/OTP 19.3

Posted 2017-03-17 06:35:40.000000

One of the features introduced in Erlang/OTP 19.3 is a callback for hostname verification. This makes it easier to protect TLS clients from man-in-the-middle attacks without external dependencies, as explained in the public_key module’s User’s Guide.

Here’s how to use the new callback (sample code in Elixir, as usual):

def verify_fun(_, {:bad_cert, _} = reason, _), do: {:fail, reason}
def verify_fun(_, {:extension, _}, state), do: {:unknown, state}
def verify_fun(_, :valid, state), do: {:valid, state}
def verify_fun(cert, :valid_peer, state) do
  if :public_key.pkix_verify_hostname(cert, state) do
    {:valid, state}
    {:fail, 'hostname mismatch'}

With this function in place, along with a variable cacertfile pointing to a CA trust store, you can now call:

:ssl.connect('', 443,
  server_name_indication: '',
  verify: :verify_peer, cacertfile: cacertfile,
  verify_fun: {&verify_fun/3, [dns_id: '']})

Replace all occurrences of ‘’ with ‘’ to see verification fail, as it should in that case.