Created
September 22, 2015 13:39
-
-
Save geoff-nixon/4af746ca0b8aa5624a41 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# How to "bake in" root certs in OpenSSL libcrypto (for OS X, etc), like node.js? | |
# | |
# https://hynek.me/articles/apple-openssl-verification-surprises/ | |
# | |
# https://developer.apple.com/library/mac/documentation/Security/Conceptual/cryptoservices/SecureNetworkCommunicationAPIs/SecureNetworkCommunicationAPIs.html | |
# | |
# http://daniel.haxx.se/blog/2011/11/05/apples-modified-ca-cert-handling-and-curl/ | |
# | |
# https://github.com/nodejs/node/commit/3beb880716654dbb2bbb9e333758825172951775 | |
here=$(pwd) | |
sslver=1.0.2d | |
ssltgz=https://www.openssl.org/source/openssl-$sslver.tar.gz | |
# The node.js version of mk-ca-bundle.pl (different than the curl one). | |
nodemkca=https://raw.github.com/nodejs/node/master/tools/mk-ca-bundle.pl | |
# curlmkca=http://curl.haxx.se/cvssource/lib/mk-ca-bundle.pl | |
# The latest root certs from Mozilla, and the CNNIC whitelist. | |
mozsec=https://hg.mozilla.org/mozilla-central/raw-file/tip/security/ | |
nsscerts=$mozsec/nss/lib/ckfw/builtins/certdata.txt | |
cnniclst=$mozsec/certverifier/CNNICHashWhitelist.inc | |
# Download the latest OpenSSL, then create a root_certs.h, containing the | |
# properly formatted PEMs and the CNNIC whitelist. | |
echo "Downloading OpenSSL $sslver..." >&2 | |
curl -L\# $ssltgz | tar xz | |
cd openssl-*/include/openssl | |
echo "Downloading Mozilla Root Certificates..." >&2 | |
# mk-ca-bundle.pl wants certdata.txt in $PWD. | |
curl -ORL\# $nsscerts | |
echo 'Creating `openssl/root_certs.h` using mk-ca-bundle.pl from node.js...' >&2 | |
echo '#ifndef HEADER_ROOT_CERTS_H' > root_certs.h | |
echo '# define HEADER_ROOT_CERTS_H' >> root_certs.h | |
echo >> root_certs.h | |
# As at https://github.com/nodejs/node/blob/master/src/node_crypto.cc#L128 | |
echo 'const char* const root_certs[] = {' >> root_certs.h | |
curl -L\# $nodemkca | perl - -- - >> root_certs.h | |
echo '};' >> root_certs.h | |
echo >> root_certs.h | |
rm certdata.txt | |
echo "Appending root_certs.h with whitelist of CNNIC-issued certificates..." >&2 | |
# Need to take out the uint8_t because OpenSSL is purely C89. | |
curl -L\# $cnniclst | sed 's|uint8_t|unsigned char|' >> root_certs.h | |
echo '#endif /* HEADER_ROOT_CERTS_H */' >> root_certs.h | |
echo >> root_certs.h | |
cd "$here" | |
echo >&2 | |
echo 'Now patch relevant file(s) with `#include <openssl/root_certs.h>`,' >&2 | |
echo ' ...and the magic code to make this actually work. Can you help?' >&2 | |
# The OS X system keychains, as processed by Homebrew openssl formula. | |
# I'm not sure why, but there are significantly more CA's in this list. | |
# For reference only; I'm sure the Mozilla list is fine. | |
# ruby -e 'keychains = %w[ | |
# /Library/Keychains/System.keychain | |
# /System/Library/Keychains/SystemRootCertificates.keychain | |
# ] | |
# | |
# certs_list = `security find-certificate -a -p #{keychains.join(" ")}` | |
# certs = certs_list.scan( | |
# /-----BEGIN CERTIFICATE-----.*?-----END CERTIFICATE-----/m | |
# ) | |
# | |
# valid_certs = certs.select do |cert| | |
# IO.popen("openssl x509 -inform pem -checkend 0 -noout", "w") do |openssl_io| | |
# openssl_io.write(cert) | |
# openssl_io.close_write | |
# end | |
# | |
# $?.success? | |
# end | |
# | |
# puts valid_certs' | |
# This could, I suppose, combined with the Mozilla list by piping the output and | |
# the output of the curl version of mk-ca-bundle.pl (stripped of comments) to | |
# something like: | |
# tr -d \n | sed 's|-----B|,-----B|g' | tr , \n | sed '/^$/d' | sort | uniq | |
# | |
# ... but I digress. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment