Skip to main content
4 of 4
deleted 120 characters in body; edited tags
nohillside
  • 104.5k
  • 42
  • 222
  • 275

openssl claims to use /private/etc/ssl, but appears not to, What The Heck?

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
CONNECTED(00000005)
---
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
-----BEGIN CERTIFICATE-----
^C

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
^C
(alice)[15:21:22]~>>

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.