Warning: Description: "Authenticity is not established by certificate path validation"

$ elixir --version
Erlang/OTP 24 [erts-12.0.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [jit]

Elixir 1.12.2 (compiled with Erlang/OTP 24)

warning: Description: "Authenticity is not established by certificate path validation", Reason: "Option {verify, verify_peer} and cacertfile/cacerts is missing"

What steps are required to address this warning?

That’s a warning from the erlang ssl library, without knowing where and when you’re getting the error maybe this blog post can help.

It describes configuring :httpc for ssl verification, which doesn’t come pre-configured out the box. In particular this part at the end:

Adding hostname verification with the ssl_verify_fun package is very similar to what we did for HTTPotion: in order to pass the expected hostname value as part of the verify_fun option, we need to pass in ssl options as part of the request. With httpc this means using the more elaborate request/4 API:

iex(7)> :httpc.request(:get, {'https://mismatch.voltone.net', []}, [ssl: [verify: :verify_peer, cacertfile: cacertfile, verify_fun: {&:ssl_verify_hostname.verify_fun/3, [check_hostname: 'mismatch.voltone.net']}]], [])
{:error,
 {:failed_connect,
  [{:to_address, {'mismatch.voltone.net', 443}},
   {:inet, [:inet], {:tls_alert, 'handshake failure'}}]}}
1 Like

The question is which client is establishing the connection. It could be your own code, but it is likely some HTTP or other protocol client that you pulled in as a dependency. Some clients use appropriate defaults, others require you to pass in ssl options yourself, and yet others are safe by default unless you pass in custom ssl options, in which case it is entirely your responsibility to set all options correctly.

If you have some time to spare, may I humbly suggest you watch this talk of mine from a few years ago: Bram Verburg - Learn you some 'ssl' for much security! - ElixirConfEU 2019 - YouTube

Another, more recent resource is Erlang standard library: ssl | EEF Security WG

5 Likes

Thank you for those insights Based on your clarifications, it seems the issue is with HTTPoison settings.

defmodule APIConnection do
  require Logger

  def validate_api_results({:ok, results}, _, _) do 
    Logger.info("APIConnection - line 5: #{inspect(results)}")
    {:ok, results}
  end

  def validate_api_results({:error, error_message}, api_url, _) do 
    Logger.error("APIConnection - line 10: #{inspect(error_message)}")
    Print.error("APIConnection - line 11: #{inspect(error_message)}")

    Logger.warn("APIConnection - Retrying #{api_url} . . . ")
    Print.warning("APIConnection - Retrying #{api_url} . . . ")

    fetch(api_url)
  end


  def fetch(api_url) do
    HTTPoison.get(api_url, [], ssl: [{:versions, [:"tlsv1.2"]}])
  end

  def main(api_url, opts \\ []) do
    fetch(api_url)
    |> validate_api_results(api_url, opts)
  end
end

What do you think?

I really recommend watching Bran’s video as it warns about overriding the defaults in this way:

Check it out specifically from this timestamp 21:23 (youtube.com)

Once you specify your own ssl: config you’re on your own as it clobbers the rest of the default configuration by design. The Q&A at the end also touches on this.

3 Likes

Gotcha!

Changed fetch back to:

  def fetch(api_url) do
    HTTPoison.get(api_url)
  end

Goodbye warnings :slight_smile:

1 Like