Skip to content

OpenSSL on HighSierra

Recently I finally got around to reading the excellent OpenSSL Cookbook from Ivan Ristić – you can grab a free copy via https://www.openssl.org/docs/ – and the first question in my mind was “what version of OpenSSL is already installed on my Mac”. A quick check showed it’s there pre-built in HighSierra in /usr/bin:

$ /usr/bin/openssl version
LibreSSL 2.2.7

Hmm. Wikipedia tells me that this is a (somewhat controversial) OpenBSD fork from around April 2014, so not necessarily in synch with the “official” OpenSSL code.

I elected to download and build from the OpenSSL code instead, partly so that it would be easier for me to keep it updated. The instructions for obtaining and building it are quite clear, although you have a clear choice to make – pull the code from GitHub, or download it as a tarball. I opted for the latter. The build assumes you have XCode and all the other bits and pieces installed, but then again you would be unlikely to be doing this if you didn’t. The build went just as it said on the box:

./Configure darwin64-x86_64-cc shared enable-ec_nistp_64_gcc_128 no-ssl3 no-comp --openssldir=/usr/local/ssl
make depend
sudo make install

after which we can verify success:

$ openssl version -a
OpenSSL 1.1.0h  27 Mar 2018
built on: reproducible build, date unspecified
platform: darwin64-x86_64-cc
options:  bn(64,64) rc4(16x,int) des(int) idea(int) blowfish(ptr) 
compiler: cc -DDSO_DLFCN -DHAVE_DLFCN_H -DNDEBUG -DOPENSSL_THREADS -DOPENSSL_NO_STATIC_ENGINE -DOPENSSL_PIC -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DRC4_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DGHASH_ASM -DECP_NISTZ256_ASM -DPADLOCK_ASM -DPOLY1305_ASM -DOPENSSLDIR="\"/usr/local/ssl\"" -DENGINESDIR="\"/usr/local/lib/engines-1.1\"" 
OPENSSLDIR: "/usr/local/ssl"
ENGINESDIR: "/usr/local/lib/engines-1.1"

“But wait!” you say, “haven’t we just overwritten the LibreSSL installation”.

Fortunately not – unless we tell it otherwise, the build drops the binaries in /usr/local/bin rather than /usr/bin where the MacOS original install is. As long as your $PATH specifies /usr/local/bin before /usr/bin you will get the expected one:

$ openssl version
OpenSSL 1.1.0h  27 Mar 2018
$ /usr/bin/openssl version
LibreSSL 2.2.7

There’s one more thing that you should do for convenience. The SSL directory created contains an empty folder /usr/local/ssl/certs – the intention is that well known trusted root certificates can be placed there, which is a slightly opaque task.

What I did was grab the set of root certificates maintained by Mozilla:

https://hg.mozilla.org/mozilla-central/raw-file/tip/security/nss/lib/ckfw/builtins/certdata.txt

but that then needs to be converted from the format they use to a standard PEM format. There’s a number of projects to help with this, the one I selected was from agl/extract-nss-root-certs. The only pre-requisite was to install Go, then the tool Just Worked and I dropped the resulting PEM in /usr/local/ssl/certs

If you’re not familiar with OpenSSL, it’s worth having a look at. It’s an absolute Swiss-Army-Chainsaw of a tool, able to do do everything from generating keys to checking site security to running as a server – Ristić’s book covers all of the usual things you might want to do, and some unusal ones, and helps demystify what is generally well thought of as a user interface from hell.

An example of what you can do? Well, here’s creation of a self-signed certificate:

# build RSA private key
openssl genrsa -aes256 -out fd.key 2048
openssl rsa -text -in fd.key -noout

# extract public key
openssl rsa -in fd.key -pubout -out fd-public.key

# create CSR with prebuilt config file
openssl req -new -config fd.cnf -key fd.key -out fd.csr
openssl req -text -in fd.csr -noout

# create self-signed certificate
openssl x509 -req -days 365 -in fd.csr -signkey fd.key -out fd.crt -extfile fd.ext
openssl x509 -text -in fd.crt -noout

the fd.cnf was:

[req]
prompt = no
distinguished_name = dn
req_extensions = ext
input_passphrase = letmein

[dn]
CN = example.net
emailAddress = admin@example.net
O = Example Co
L = London
C = GB

and fd.ext was

subjectAltName = DNS:example.net;DNS:*.example.net

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*