In the course of trying to help a friend with a problem with pip and ssl sites (GitHub issue here), I've become confused about how the High Sierra /usr/bin/openssl finds its certificates. My "keg-only" openssl does not have any trouble with the site.

Here's the test case that I've been playing with:

(alice)[14:22:06]~>>/usr/bin/openssl s_client -connect files.pythonhosted.org:443 | head 2>&1
depth=1 C = BE, O = GlobalSign nv-sa, CN = GlobalSign CloudSSL CA - SHA256 - G3
verify error:num=20:unable to get local issuer certificate
verify return:0
Certificate chain
 0 s:/C=US/ST=California/L=San Francisco/O=Fastly, Inc/CN=r.ssl.fastly.net
   i:/C=BE/O=GlobalSign nv-sa/CN=GlobalSign CloudSSL CA - SHA256 - G3
 1 s:/C=BE/O=GlobalSign nv-sa/CN=GlobalSign CloudSSL CA - SHA256 - G3
   i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
Server certificate

I've been scratching my head because an appropriate key resides in the Keychain utility (Determined by downloading the Mozilla cert bundle from the Curl site, finding the one cert that rescues the test case when provided via -CAfile, and comparing its fingerprint to certs in the Keychain app. See the pip issue for gory details).

The value of OPENSSLDIR in the openssl version -a output suggests that /usr/bin/openssl should be using /private/etc/ssl:

(alice)[14:05:27]~>>/usr/bin/openssl version -a
LibreSSL 2.2.7
built on: date not available
platform: information not available
options:  bn(64,64) rc4(ptr,int) des(idx,cisc,16,int) blowfish(idx)
compiler: information not available
OPENSSLDIR: "/private/etc/ssl"

And, in fact, pointing at that directory with the -CApath command line option rescues the test case:

(alice)[14:26:32]~>>/usr/bin/openssl s_client -connect files.pythonhosted.org:443 -CApath /private/etc/ssl | head 2>&1 < /dev/null
depth=2 C = BE, O = GlobalSign nv-sa, OU = Root CA, CN = GlobalSign Root CA
verify return:1
depth=1 C = BE, O = GlobalSign nv-sa, CN = GlobalSign CloudSSL CA - SHA256 - G3
verify return:1
depth=0 C = US, ST = California, L = San Francisco, O = "Fastly, Inc", CN = r.ssl.fastly.net
verify return:1

What's going on? Do the CApath/CAfile commands enable behavior that doesn't otherwise occur?

I'd love to understand what's going on.

  • "pointing at that directory with the -CApath command line option rescues the test case: [...]" — the terminal output you've provided here is identical to the first case (no -CApath) and doesn't show success; can you correct this? I assume you're correctly seeing verify return:1 for the entire chain (root cert at depth=2 as I see it) in this second case? – Jivan Pal Jan 28 '20 at 23:04
  • To actually answer your question about the cert location, though, it is indeed /etc/ssl/ as you suspect (note that /etc is symlinked to /private/etc). The default certs all reside there in cert.pem, and additional certs can be stored in /etc/ssl/certs/. Perhaps check that your cert.pem is intact and up to date? For me, running LibreSSL 2.8.3 on macOS Catalina 10.15.2 (19C57), the MD5 hash of cert.pem is 6cecca9c114e4386b98e1d24a028dd95. – Jivan Pal Jan 28 '20 at 23:12
  • For me, in cert.pem, the GlobalSign root cert can be found starting on line 3018. The cert itself can be seen here: pastebin.com/KZQANumd – Jivan Pal Jan 28 '20 at 23:18
  • For me, I have a copy of the "rescuing cert" starting a line 176, its fingerprint (from the file itself) is: 233 SHA1 Fingerprint=B1:BC:96:8B:D4:F4:9D:62:2A:A8:9A:81:F2:15:01:52:A4:1D:82:9C – hartzell Jan 28 '20 at 23:26
  • 1
    There is no need to add the edit history in the post. Anybody interest in it can see all revisions anyway. – nohillside Jan 29 '20 at 6:31

This issue is the result of a known bug in OpenSSL that was reported in February 2013 and tracked here (log in using username guest and password guest). At the time, the latest public release of OpenSSL was OpenSSL 1.0.2. The issue was marked resolved in October 2016, and the bug no longer exists in releases after this date, the earliest of which is OpenSSL 1.1.1. Some users have reported that the bug was also not present in "version 1.1", to which they may be referring to OpenSSL 1.1.0 or forks of it — I have not confirmed whether the bug exists in OpenSSL 1.1.0.

The openssl binary included with macOS is LibreSSL, which is a fork of OpenSSL that originated from OpenSSL 1.0.1g. Since the bug existed in that version of OpenSSL, it persisted in LibreSSL until it was noticed and fixed by their developers, which was somewhere between the version you're using (LibreSSL 2.2.7) and the version I'm using (LibreSSL 2.8.3, which is packaged with macOS Catalina).

You must log in to answer this question.

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