11

An open source app running on my macOS 10.13.6 and 10.14.6 system is failing to access a website via https that uses a Let's Encrypt certificate. If I use curl to access the same site, it also gets an error about the certificate being expired.

Here's the output of curl -vv with the hostname and IP address redacted:

* Rebuilt URL to: https://hostname/
*   Trying x.x.x.x...
* TCP_NODELAY set
* Connected to hostname (x.x.x.x) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (OUT), TLS alert, Server hello (2):
* SSL certificate problem: certificate has expired
* stopped the pause stream!
* Closing connection 0
curl: (60) SSL certificate problem: certificate has expired
More details here: https://curl.haxx.se/docs/sslcerts.html

curl performs SSL certificate verification by default...
(rest of text not relevant and removed)

I've confirmed that the ISRG Root X1 certificate is installed in Keychain Access and is trusted.

Further, I can access the site using Safari or any other web browser. However, the app in question still fails, as does curl.

What do I need to do to fix this? I can't just use insecure mode on curl as the issue I'm trying to fix is the app that can't access the site. I'm not sure what library the app is using for https -- it may be libcurl, but I suspect it's failing for the same reason curl is.

Small addendum: the open source app is using OpenSSL 1.1.1j.

1 Answer 1

20

OpenSSL on macOS does not use the system keychain (which makes sense as it's a cross platform library) but rather has its own .pem file containing its root certificates. Even though my systems have a newer version of OpenSSL installed using homebrew and/or MacPorts, the system-wide OpenSSL pem file located at /etc/ssl/cert.pem was out of date and did not include the ISRG Root X1 certificate.

The solution:

  1. Rename /etc/ssl/cert.pem to something else. (I suggest /etc/ssl/cert.pem.org)

  2. Download the latest cacert.pem from https://curl.se/docs/caextract.html

  3. Rename it to cert.pem

  4. Copy it to /etc/ssl/cert.pem

Now curl and any other app using OpenSSL can access websites signed using current Let's Encrypt certificates.

Alternatively, the MacPorts package curl-ca-bundle installs a pem file containing ISRG Root X1 to /opt/local/etc/openssl/cert.pem which can be used as well.

Other possible solutions:

  • Manually add the ISRG Root X1 certificate to /etc/ssl/cert.pem

  • Configure OpenSSL to use a different .pem file for its root certificates, such as /opt/local/etc/openssl/cert.pem

4
  • 1
    Nice. But there's a potential chicken-and-egg problem because curl.se is using a cert derived from the new ISRG Root X1, which you apparently don't trust yet. If you have a browser that does trust it, you can use that; otherwise you can get around the problem by downloading the new root collection with: curl --insecure https://curl.se/ca/cacert.pem -o cert.pem Commented Oct 6, 2021 at 4:56
  • Fortunately that wasn't a problem for me since I'm not stuck using only curl. I just downloaded the new certificates using a browser. But if someone were in a position where they had to fix curl with curl then that's a good tip.
    – Bri Bri
    Commented Oct 6, 2021 at 13:40
  • 1
    Thank you. This helped after trying 5 different solutions.
    – vijaycs85
    Commented Dec 31, 2021 at 11:48
  • Excellent. I called my old one .expired instead of .org
    – gbarry
    Commented Jan 4, 2022 at 19:44

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .