thousandsofthem

thousandsofthem

Issue with http clients and some https certificates

Please help me debug the issue with https certificates, need some ideas what to check next

When fetching data using http clients, some https:// urls returning “Certificate Expired”, despite being perfectly valid, e.g. https://investing.com/, https://api.amplitude.com/ .
It looks like it doesn’t depend on erlang version, elixir version, http library version.

Base system is (a) OSX 10.14.5 (b) Docker, Alpine Linux

test app #1

elixir 1.9.4
erlang 22.3.4.1 (also 22.1.8)
mojito 0.6.4
mint 1.1.0
httpoison 1.5.0
hackney 1.15.2 (also 1.16.0)

iex(8)> Mojito.request(:get, "https://api.amplitude.com/")
[info] TLS :client: In state :certify at ssl_handshake.erl:1764 generated CLIENT ALERT: Fatal - Certificate Expired

{:error,
 %Mojito.Error{
   message: nil,
   reason: %Mint.TransportError{
     reason: {:tls_alert,
      {:certificate_expired,
       'TLS client: In state certify at ssl_handshake.erl:1764 generated CLIENT ALERT: Fatal - Certificate Expired\n'}}
   }
 }}

iex(9)> HTTPoison.get("https://api.amplitude.com/")
[info] TLS :client: In state :certify at ssl_handshake.erl:1764 generated CLIENT ALERT: Fatal - Certificate Expired

{:error,
 %HTTPoison.Error{
   id: nil,
   reason: {:tls_alert,
    {:certificate_expired,
     'TLS client: In state certify at ssl_handshake.erl:1764 generated CLIENT ALERT: Fatal - Certificate Expired\n'}}
 }}


iex(10)> opts = [ssl: [cacertfile: :certifi.cacertfile(), verify: :verify_peer]]
iex(11)> HTTPoison.get("https://api.amplitude.com/", [], opts)
# same error - CLIENT ALERT: Fatal - Certificate Expired

test app #2

elixir 1.3.4
erlang 19.3.6.5
hackney 1.15.0
httpoison 1.0.0

iex(6)> HTTPoison.get("https://api.amplitude.com/")
[error] SSL: :certify: ssl_handshake.erl:1609:Fatal error: certificate expired

{:error, %HTTPoison.Error{id: nil, reason: {:tls_alert, 'certificate expired'}}}

Most Liked

kip

kip

ex_cldr Core Team

According to curl the certificate has expired for at least https://api.amplitude.com/. There was an issue over the weekend with an expired root certificate from Comodo/Sectigo CA for https://openexchangerates.org as well. Perhaps these sites are using the same certificate chain. Have you checked their support site?

kip@Kips-iMac-Pro cldr_dates_times % curl "https://api.amplitude.com/"
curl: (60) SSL certificate problem: certificate has expired
More details here: https://curl.haxx.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
voltone

voltone

Exactly. The :ssl application treats the certificates sent by the server as a linear, unbreakable chain, ignoring any self-signed certificates that may have been sent because of misconfiguration. (Recent versions do allow for servers that send the chain out-of-order). Chain validation then tries to find a root certificate in the trust store that matches the issuer of the last certificate in that chain (furthest from the end-certificate).

This approach is problematic with cross-signed certificates, as this example shows. Most other implementation treat the intermediate CA certificates sent by the server as a pool from which to draw missing elements in the chain, and they try multiple paths until a valid one is found.

The most reliable way to resolve this is to reconfigure the server to not send the cross-signing intermediate CA once the issuing root CA is invalidated. If the CA trust store used on the Erlang/Elixir side includes the (self-signed) equivalent root CA, then verification of the shorter chain will succeed.

There is no easy way to fix this on the client side in a generic way. A workaround for specific cases should be possible by passing a ‘partial chain fun’.

kip

kip

ex_cldr Core Team

I ran the check on https://ssllabs.com which I think is well respected. It shows the intermediate and root certificates sent by the server as expired.

However, it also shows that there are three paths to establishing trust, one that includes the expired certificates and two that do not. As I understand it from some reading, the :ssl app is unable to resolve alternative trust paths and therefore will fail to validate the peer in more situations than other clients. (I know that is not precise, mostly because I only understand a very small amount of this topic).

It also suggests why you are seeing different outcomes from different clients.

Where Next?

Popular in Questions Top

sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
earth10
Hi, I’m just starting to build a side-project with Elixir and Phoenix and doing some basic test with Elixir alone. What strikes me is th...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
nobody
Hi! In PHP: $SERVER['SERVERADDR'] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New

Other popular topics Top

sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
AstonJ
Please see the new poll here: Which code editor or IDE do you use? (Poll) (2022 Edition) It’s been a while since we first asked this, I...
208 31107 143
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
dogweather
I wrote this comment on r/haskell, and it’s not popular there. :wink: But I think I’m on to something… Haskell reminds me of Java, and e...
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New

We're in Beta

About us Mission Statement