Resolving Let's Encrypt Issues with CURL on macOS

Resolving Let's Encrypt Issues with CURL on macOS

Fixing CURL issues for macOS versions up to 10.15

ยท

3 min read

On 30 September, the DST Root CA X3 certificate, which Let's Encrypt were using to "cross-sign", expired. This root certificate was important as it allowed older clients to trust, relatively, new Let's Encrypt certificates which were also signed with their own root certificate (ISRG Root X1).

Now that the DST Root CA X3 root certificate has expired, clients that do not trust ISRG Root X1, now the only valid root for Let's Encrypt, will not be able to verify a Let's Encrypt SSL certificate is valid.

For most people, this is not a problem, as the supported platforms list is fairly extensive and covers most modern platforms that end users will be using. In the case of macOS, this is supported from macOS 10.12.1 which was released in October 2016. However, if you use the curl command in macOS, you may find yourself hitting a roadblock, which can be especially problematic in a CI/CD environment.

The Problem ๐Ÿค”

If you try to curl a website which is using a Let's Encrypt certificate, like Let's Encrypt's own homepage, you will find you receive the following error:

$ curl https://letsencrypt.org

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.

Exited with code exit status 60

Yet if you open Safari and head to the same URL, there will be no problem at all! Why is this?

It appears that the default installation of curl in macOS does not use the default system keychain, or security framework, in macOS. The system keychain includes a copy of the new ISRG Root X1 certificate which allows any apps that use the security framework in macOS to trust Let's Encrypt SSL certificates. Therefore curl does not know this new certificate as it appears that Apple has not updated curl's certificate store to add the ISRG Root X1 certificate - this only works out of the box in Big Sur and higher.

The Solution ๐Ÿ™Œ

Thankfully all is not lost! We can point curl to include an additional CA bundle to allow validation of Let's Encrypt certificates.

The curl project provides updated certificate stores every few months on their website, so we can use this to resolve the error message seen above.

Firstly, we need to download the certificate bundle. You can either do this by heading to the download page, or by using curl. It is important to note that if you use curl, you will need to use the -k option to skip validation of the SSL certificate as the curl project website also uses the ISRG Root X1 certificate - a chicken and the egg scenario ๐Ÿฃ!

curl -k https://curl.se/ca/cacert.pem -o ~/.cacert.pem

We then simply need to set CURL_CA_BUNDLE to the path of the new CA bundle which contains the ISRG Root X1 certificate. The easiest way to do this is to add it to your .bash_profile:

echo 'export CURL_CA_BUNDLE=~/.cacert.pem' >> ~/.bash_profile

Now reload your shell, or source ~/.bash_profile and you will once again be able to use curl with any URL using Let's Encrypt!

ย