Tls_certificate_check: TLS/SSL certificate verification for humans

Hi forum,

I’ve the pleasure to announce the release of tls_certificate_check, a library that packs the boilerplate required for verifying the authenticity of certificates presented by TLS servers against a list of trusted certificate authorities.

It wraps certifi and ssl_verify_fun together with the code required for verifying certificate chains in non canonical order.

It’s simple enough to use:

host = ""
port = 443
tls_options = :tls_certificate_check.options(host)
:ssl.connect(host, 443, tls_options)

You’ll no longer need to copy the usual CA validation boilerplate everywhere!


This looks great, thanks for the lib. Would you consider also wrapping castore as an option?

1 Like

It’s a good ideia; however, having tls_certificate_check depend on castore directly would complicate compatibility with Erlang (since it’s an Elixir dependency.)

I’m planning to add support for consumer-defined CA lists, though - that could be one way to use castore instead of certifi.

1 Like

Ah, yes, good point. And good solution too since they would allow using platform certificate stores too.

I forgot about this entirely… therefore I created an issue in GitHub to remind me of it.

tls_certificate_check 1.3.0 has been released today.

It now provides the CAs to the API through persistent_term.

(And since I forgot to announce the 1.2.0 update here: certifi is no longer the backing CA store.)

:tada: tls_certificate_check 1.9.0 is out!



:rotating_light: tls_certificate_check 1.10.0 has arrived.


  • DST Root CA X3, now expired, was removed

:lock: tls_certificate_check 1.11.0 is out.

New CAs:

  • HARICA TLS ECC Root CA 2021
  • HARICA TLS RSA Root CA 2021
  • TunTrust Root CA

tls_certificate_check 1.12.0 is out :tada:

New CAs:

  • vtrus ecc root ca
  • isrg root x2
  • vtrus root ca
  • HiPKI Root CA - G1
  • Autoridad de Certificacion Firmaprofesional CIF A62634068

Updated CAs:

  • gts root r4
  • gts root r3
  • gts root r1
  • gts root r2
  • GlobalSign ECC Root CA - R4

Removed CAs:

  • GlobalSign Root CA - R2
  • cybertrust global root

That took me a while!

tls_certificate_check 1.17.0 is out, and it does a couple of cool new things.

For OTP 25+, it now uses OTP-trusted CAs by default - if any / when available, falling back to the bundled CAs otherwise (this is tweakable).

This version also supports overriding the trusted CAs (say, if you’d wish to use CAStore instead.)

1 Like

Thanks for the great library, @g-andrade! I’ve noticed since 0.16 and up I get the following error

Generated myapp app
[info] Loading 159 CA(s) from :otp store
[error] GenServer #PID<0.500.0> terminating
** (stop) {:unexpected_info, {:EXIT, #Port<0.7>, :normal}}
Last message: {:EXIT, #Port<0.7>, :normal}
State: {:state, true}

I don’t think it’s critical because it does retry and succeed quickly thereafter, but just thought I’d throw this out there in case it was unexpected.

Thanks again!

Thanks for reporting, @cadebward ! Someone else also reported the issue on GitHub : I’ve released version 1.17.3, which should fix the problem.

1 Like

:information_source: tls_certificate_check 1.17.4 no longer fails to start on OTP 25+ when loading OTP-trusted CAs throws an error exception unrelated to undefined modules or functions - it falls back to the bundled CAs as originally intended.