Last active
December 21, 2016 06:19
-
-
Save Haraguroicha/943c8e514daa0866a7fc9c9d142ab967 to your computer and use it in GitHub Desktop.
OpenSSL Homebrew brew formula that allows additional configuration via env var CONFIGURE_OPTS
This file contains hidden or 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
require "formula" | |
class Openssl < Formula | |
homepage "http://openssl.org" | |
version v="1.0.2j" | |
url "https://www.openssl.org/source/openssl-#{v}.tar.gz" | |
mirror "https://dl.bintray.com/homebrew/mirror/openssl-#{v}.tar.gz" | |
mirror "http://fossies.org/linux/misc/openssl-#{v}.tar.gz" | |
mirror "https://www.mirrorservice.org/sites/ftp.openssl.org/source/openssl-#{v}.tar.gz" | |
sha256 "e7aff292be21c259c6af26469c7a9b3ba26e9abaaffd325e3dccc9785256c431" | |
option :universal | |
option "without-test", "Skip build-time tests (not recommended)" | |
option "with-blowfish", "Enable Blowfish block cipher" | |
option "without-check", "Skip build-time tests (not recommended)" | |
option "with-camellia", "Enable Camellia block cipher (PATENTED, royalty-free license and also part of NSS)" | |
option "with-cast", "Enable CAST block cipher (required by OpenSSH)" | |
# option "with-cms", "Enable S/MIME v3.1 (not recommended, see also: CVE-2012-0884, disalbing breaks make test)" | |
# option "with-des", "Enable DES (not recommended, disabling breaks make test)" | |
option "with-dtls", "Enable DTLS UDP (not recommended, see also: CVE-2014-0160)" | |
option "without-ec", "Disable elliptic curve support (ECDSA, ECDH(E), etc.)" | |
option "without-ecdsa", "Disable ECDSA" | |
option "with-engine", "Enable Engines support (enabled by GOST), needed by Nginx and OpenSSH" | |
option "with-experimental", "Enable experimental algorithms (not recommended)" | |
option "with-fips", "Enable FIPS mode (not recommended)" | |
option "with-gost", "GOST algorithms (which automatically enables engines)" | |
option "with-hw", "Crypto hardware support" | |
option "with-idea", "Enable IDEA block cipher (not recommended, PATENTED)" | |
option "with-krb5", "Enable Kerberos v5 support" | |
option "with-md2", "Enable MD2 (OBSOLETE - VERY WEAK, may be needed)" | |
option "with-md4", "Enable MD4 (OBSOLETE - VERY WEAK, needed by Erlang)" | |
option "without-md5", "Disable MD5 (weak)" | |
option "with-mdc2", "Enable MDC2 hash function (patent expired)" | |
option "with-psk", "PSK (RFC 4279) support (not recommended)" | |
# option "with-rc2", "Enable RC2 (not recommended, disabling breaks make test)" | |
option "with-rc4", "Enable RC4 (WEAK, not recommended, PATENTED, risks lawsuits from patent trolls; needed by Erlang)" | |
option "with-rc5", "Enable RC5 (not recommended, PATENTED)" | |
option "with-rdrand", "RdRand and RdSeed Ivy Bridge support (not recommended, see also: Snowden, Dual_EC_DRBG)" | |
option "with-rfc3779", "Enable rfc3779 (not recommended)" | |
option "with-sctp", "SCTP protocol support (not recommended)" | |
option "with-seed", "Enable SEED block cipher (not recommended)" | |
option "with-sha0", "Enable SHA0 (OBSOLETE - VERY WEAK, not recommended)" | |
option "without-sha1", "Disable SHA1 (weak, not recommended to disable)" | |
option "with-srp", "Enable Secure Remote Password protocol support (not recommended, see also: CVE-2014-5139)" | |
option "with-srtp", "RFC 5764 DTLS-SRTP negotiation (not recommended, see also: CVE-2014-3513)" | |
option "with-ssl2", "Enable SSLv2 support (OBSOLETE - VERY WEAK, NOT RECOMMENDED)" | |
option "with-ssl3", "Enable SSLv3 support (WEAK, NOT RECOMMENDED, POODLE risk)" | |
option "with-whirlpool", "Enable Whirlpool block cipher" | |
option "with-zlib", "Enable Zlib compression (statically-linked, may enable CRIME and BEAST attacks)" | |
option "with-zlib-dynamic", "Enable Zlib compression (dynamically-linked, may enable CRIME and BEAST attacks)" | |
option "without-chacha20-poly1305", "Disable CloudFlare's chacha20-poly1305 ciphers" | |
deprecated_option "without-check" => "without-test" | |
depends_on "makedepend" => :build | |
depends_on "nasm" => :build | |
keg_only :provided_by_osx, | |
"Apple has deprecated use of OpenSSL in favor of its own TLS and crypto libraries" | |
# Xcode 7 Clang fix introduced regression which makes older Clang versions | |
# incorrectly declare suitable instructions. | |
# https://github.com/openssl/openssl/issues/494 | |
# https://svn.macports.org/repository/macports/trunk/dports/devel/openssl/files/fix-Apple-clang-version-detection.patch | |
if MacOS.version <= :mountain_lion | |
patch do | |
url "https://raw.githubusercontent.com/Homebrew/patches/312f6228/openssl/fix-Apple-clang-version-detection.patch" | |
sha256 "a3e0e13e6c70d85d916bb88cbddc134952794d6292fbab4f2740ac9a07759606" | |
end | |
end | |
patch do | |
url "https://raw.githubusercontent.com/cloudflare/sslconfig/master/patches/openssl__chacha20_poly1305_draft_and_rfc_ossl102j.patch" | |
sha256 "d6f9427d5cb63c7299563c201cd8708c7166e0f8c98b57a1fee69767362bf0f7" | |
end if build.with?('chacha20-poly1305') | |
def arch_args | |
{ | |
:x86_64 => %w[darwin64-x86_64-cc enable-ec_nistp_64_gcc_128], | |
:i386 => %w[darwin-i386-cc], | |
} | |
end | |
def configure_args | |
args = %W[ | |
--prefix=#{prefix} | |
--openssldir=#{openssldir} | |
shared | |
enable-cms | |
] | |
args << (build.with?("blowfish") ? "enable-bf" : "no-bf") | |
args << (build.with?("camellia") ? "enable-camellia" : "no-camellia") | |
args << (build.with?("cast") ? "enable-cast" : "no-cast") | |
# args += (build.with?("cms") ? %w[enable-cms] : %w[disable-cms no-cms]) | |
# args << (build.with?("des") ? "des" : "no-des") | |
args << (build.with?("dtls") ? "enable-dtls" : "no-dtls") | |
if build.without?("ec") | |
args << "no-ec" | |
elsif build.without?("ecdsa") | |
args << "no-ecdsa" | |
else | |
args << "enable-ec" | |
end | |
args << (build.with?("experimental") ? "enable-exp" : "no-exp") | |
args << (build.with?("fips") ? "enable-fips" : "no-fips") | |
args << ((build.with?("engine") || build.with?("gost")) ? "enable-engine" : "no-engine") | |
args << (build.with?("gost") ? "enable-gost" : "no-gost") | |
args << (build.with?("hw") ? "enable-hw" : "no-hw") | |
args << (build.with?("idea") ? "enable-idea" : "no-idea") | |
args << (build.with?("krb5") ? "enable-krb5" : "no-krb5") | |
args << (build.with?("md2") ? "enable-md2" : "no-md2") | |
args << (build.with?("md4") ? "enable-md4" : "no-md4") | |
args << (build.without?("md5") ? "no-md5" : "enable-md5") | |
args << (build.with?("mdc2") ? "enable-mdc2" : "no-mdc2") | |
args << (build.with?("psk") ? "enable-psk" : "no-psk") | |
# args << (build.with?("rc2") ? "enable-rc2" : "no-rc2") | |
args << (build.with?("rc4") ? "enable-rc4" : "no-rc4") | |
args << (build.with?("rc5") ? "enable-rc5" : "no-rc5") | |
args << (build.with?("rdrand") ? "enable-rdrand" : "no-rdrand") | |
args << (build.with?("rfc3779") ? "enable-rfc3779" : "no-rfc3779") | |
args << "no-rmd160" if build.without?("rmd160") | |
args << (build.with?("sctp") ? "enable-sctp" : "no-sctp") | |
args << (build.with?("seed") ? "enable-seed" : "no-seed") | |
args << (build.with?("sha0") ? "enable-sha0" : "no-sha0") | |
args << (build.without?("sha1") ? "no-sha1" : "enable-sha1") | |
args << (build.with?("srp") ? "enable-srp" : "no-srp") | |
args << (build.with?("srtp") ? "enable-srtp" : "no-srtp") | |
args << (build.with?("ssl2") ? "enable-ssl2" : "no-ssl2") | |
args << (build.with?("ssl3") ? "enable-ssl3" : "no-ssl3") | |
args << (build.with?("whirlpool") ? "enable-whirlpool" : "no-whirlpool") | |
args << "enable-chacha-poly" if build.with?("chacha20-poly1305") | |
args += ENV["CONFIGURE_OPTS"].split(" ") if ENV.include? "CONFIGURE_OPTS" | |
if build.with?("zlib") | |
args << "zlib" | |
elsif build.with?("zlib-dynamic") | |
args << "zlib-dynamic" | |
else | |
args << "no-zlib" | |
end | |
args | |
end | |
def install | |
if build.with?("zlib-dynamic") | |
# Load zlib from an explicit path instead of relying on dyld's fallback | |
# path, which is empty in a SIP context. This patch will be unnecessary | |
# when we begin building openssl with no-comp to disable TLS compression. | |
# https://langui.sh/2015/11/27/sip-and-dlopen | |
inreplace "crypto/comp/c_zlib.c", | |
'zlib_dso = DSO_load(NULL, "z", NULL, 0);', | |
'zlib_dso = DSO_load(NULL, "/usr/lib/libz.dylib", NULL, DSO_FLAG_NO_NAME_TRANSLATION);' | |
end | |
if build.universal? | |
ENV.permit_arch_flags | |
archs = Hardware::CPU.universal_archs | |
elsif MacOS.prefer_64_bit? | |
archs = [Hardware::CPU.arch_64_bit] | |
else | |
archs = [Hardware::CPU.arch_32_bit] | |
end | |
dirs = [] | |
archs.each do |arch| | |
if build.universal? | |
dir = "build-#{arch}" | |
dirs << dir | |
mkdir dir | |
mkdir "#{dir}/engines" | |
system "make", "clean" | |
end | |
ENV.deparallelize | |
system "perl", "./Configure", *(configure_args + arch_args[arch]) | |
system "make", "depend" | |
system "make" | |
if (MacOS.prefer_64_bit? || arch == MacOS.preferred_arch) && build.with?("test") | |
system "make", "test" | |
end | |
if build.universal? | |
cp "include/openssl/opensslconf.h", dir | |
cp Dir["*.?.?.?.dylib", "*.a", "apps/openssl"], dir | |
cp Dir["engines/**/*.dylib"], "#{dir}/engines" if build.with?("engine") || build.with?("gost") | |
end | |
end | |
system "make", "install", "MANDIR=#{man}", "MANSUFFIX=ssl" | |
if build.universal? | |
%w[libcrypto libssl].each do |libname| | |
system "lipo", "-create", "#{dirs.first}/#{libname}.1.0.0.dylib", | |
"#{dirs.last}/#{libname}.1.0.0.dylib", | |
"-output", "#{lib}/#{libname}.1.0.0.dylib" | |
system "lipo", "-create", "#{dirs.first}/#{libname}.a", | |
"#{dirs.last}/#{libname}.a", | |
"-output", "#{lib}/#{libname}.a" | |
end | |
Dir.glob("#{dirs.first}/engines/*.dylib") do |engine| | |
libname = File.basename(engine) | |
system "lipo", "-create", "#{dirs.first}/engines/#{libname}", | |
"#{dirs.last}/engines/#{libname}", | |
"-output", "#{lib}/engines/#{libname}" | |
end if build.with?("engine") || build.with?("gost") | |
system "lipo", "-create", "#{dirs.first}/openssl", | |
"#{dirs.last}/openssl", | |
"-output", "#{bin}/openssl" | |
confs = archs.map do |arch| | |
<<-EOS.undent | |
#ifdef __#{arch}__ | |
#{(buildpath/"build-#{arch}/opensslconf.h").read} | |
#endif | |
EOS | |
end | |
(include/"openssl/opensslconf.h").atomic_write confs.join("\n") | |
end | |
end | |
def openssldir | |
etc/"openssl" | |
end | |
def post_install | |
keychains = %w[ | |
/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("#{bin}/openssl x509 -inform pem -checkend 0 -noout", "w") do |openssl_io| | |
openssl_io.write(cert) | |
openssl_io.close_write | |
end | |
$?.success? | |
end | |
openssldir.mkpath | |
(openssldir/"cert.pem").atomic_write(valid_certs.join("\n")) | |
end | |
def caveats; <<-EOS.undent | |
A CA file has been bootstrapped using certificates from the system | |
keychain. To add additional certificates, place .pem files in | |
#{openssldir}/certs | |
and run | |
#{opt_bin}/c_rehash | |
EOS | |
end | |
test do | |
# Make sure the necessary .cnf file exists, otherwise OpenSSL gets moody. | |
assert (HOMEBREW_PREFIX/"etc/openssl/openssl.cnf").exist?, | |
"OpenSSL requires the .cnf file for some functionality" | |
# Check OpenSSL itself functions as expected. | |
(testpath/"testfile.txt").write("This is a test file") | |
expected_checksum = "e2d0fe1585a63ec6009c8016ff8dda8b17719a637405a4e23c0ff81339148249" | |
system "#{bin}/openssl", "dgst", "-sha256", "-out", "checksum.txt", "testfile.txt" | |
open("checksum.txt") do |f| | |
checksum = f.read(100).split("=").last.strip | |
assert_equal checksum, expected_checksum | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Install for testing purposed: