1

[Originally posted on Slack Overflow, but comment thread complained about inappropriate venue.]

We're working on switching from StartCom SSL Certificates to Let's Encrypt, and trying to get it set up to automatically work with macOS Server + Apache HTTPD. From the command line tool (security import), macOS Server doesn't accept the straight .pem files—you have to give it a .p12 file, from which it extracts .pem files to configure in Apache. Annoying and pointless, but it's what we have to live with for now.

In order to create this .p12 file, we have to execute this command:

openssl pkcs12 -export \
-inkey /etc/letsencrypt/live/example.com/privkey.pem \
-in /etc/letsencrypt/live/example.com/cert.pem \
-certfile /etc/letsencrypt/live/example.com/chain.pem \
-out /etc/letsencrypt/live/example.com/example.com.p12

And here's where it gets weird. The output example.com.p12 file has the example.com certificate twice, followed by the Let's Encrypt intermediate CA certificate, followed by the unnecessary self-signed DST Root CA X3 anchor certificate (which all the browsers have installed in them by default), and finally followed by the private key. The result is that the Apache SSL handshake includes the server certificate twice, and the intermediate CA certificate, and the root certificate (which it should not be sending), which results in warnings on the Qualys SSL Labs tester.

We looked inside cert.pem, and it only contains the server certificate (and only once). chain.pem only contains the intermediate CA certificate (not the root anchor or the server cert). privkey.pem only contains the private key. So openssl pkcs12 -export is duplicating the server certificate and then going to the extra step of looking up the root anchor certificate and adding it.

If we run this same command on openSUSE Linux, the output .p12 file only has the server certificate (once), the intermediate CA certificate, and the private key. No root anchor.

We tried the following variations and saw no difference in output:

openssl pkcs12 -export \
-inkey /etc/letsencrypt/live/example.com/privkey.pem \
-in /etc/letsencrypt/live/example.com/fullchain.pem \
-out /etc/letsencrypt/live/example.com/example.com.p12

openssl pkcs12 -export \
-inkey /etc/letsencrypt/live/example.com/privkey.pem \
-certfile /etc/letsencrypt/live/example.com/fullchain.pem \
-out /etc/letsencrypt/live/example.com/example.com.p12

The only way I can duplicate the incorrect doubled server certificate behavior on a Linux machine is to do the following (but it still doesn't include the root anchor):

openssl pkcs12 -export \
-inkey /etc/letsencrypt/live/example.com/privkey.pem \
-in /etc/letsencrypt/live/example.com/cert.pem \
-certfile /etc/letsencrypt/live/example.com/fullchain.pem \
-out /etc/letsencrypt/live/example.com/example.com.p12

(Note the use of fullchain.pem instead of chain.pem in conjunction with the use of cert.pem ... makes perfect sense why the server cert would be duplicated, but that's not the command we're using on Mac OS X.)

Any idea how to get openssl pkcs12 -export to do the right thing here?

Nick Williams
  • 135
  • 1
  • 4
  • Have you tried installing and running a modern version of OpenSSL (perhaps via MacPorts or Homebrew)? Apple has their own security library and hasn’t shown their OpenSSL any love in a long time. – Spiff Jan 02 '18 at 22:54
  • We had not tried that yet. I was wary about upgrading OpenSSL in an otherwise-working configuration that passed security checks. However, `OpenSSL 0.9.8zh 14 Jan 2016` isn't *that* old... – Nick Williams Jan 03 '18 at 02:16
  • “In High Sierra, Apple has switched SSL libraries from OpenSSL 0.9.8zh to LibreSSL 2.2.7. LibreSSL is a fork of OpenSSL supported by OpenBSD. Secure Transport is Apple’s own API for SSL/TLS but it is primarily used for their first-party software. LibreSSL will serve as the SSL library for third-party software. This was not included in any WWDC sessions but has been observed by High Sierra beta users.” (https://www.thesslstore.com/blog/crypto-ssl-improvements-high-sierra-ios-11/) – Nick Williams Jan 03 '18 at 16:09
  • `openssl version` yields `OpenSSL 0.9.8zh 14 Jan 2016` on my local computer running Sierra, but it actually yields `LibreSSL 2.2.7` on the server on which this certificate script is running (High Sierra). So perhaps this is a bug in LibreSSL? I should update the title and tags, but first I'll test it on both tonight to see if the behavior is different. – Nick Williams Jan 03 '18 at 16:11

0 Answers0