class Gnutls < Formula desc "GNU Transport Layer Security (TLS) Library" homepage "https://gnutls.org/" url "https://www.gnupg.org/ftp/gcrypt/gnutls/v3.6/gnutls-3.6.16.tar.xz" mirror "https://www.mirrorservice.org/sites/ftp.gnupg.org/gcrypt/gnutls/v3.6/gnutls-3.6.16.tar.xz" sha256 "1b79b381ac283d8b054368b335c408fedcb9b7144e0c07f531e3537d4328f3b3" license all_of: ["LGPL-2.1-or-later", "GPL-3.0-only"] livecheck do url "https://www.gnupg.org/ftp/gcrypt/gnutls/v3.6/" regex(/href=.*?gnutls[._-]v?(\d+(?:\.\d+)+)\.t/i) end bottle do sha256 arm64_big_sur: "f63ca35051efae87447075f5d0ab1fcccb4503c8c94b7fa9c3a0c59710066390" sha256 big_sur: "49e6f4d5d47e7d241b1c931593a74cbdef02e74ed01788b8b8c8ff2da75e22db" sha256 catalina: "d9af37a7677414243fc1aa2359c388f090f86d893d50d88c2c5dd66191252980" sha256 mojave: "80bb92867bb86086d301658ff182b145699c3baa14cbfe83dcb9da48598b0237" sha256 x86_64_linux: "a14f5b6bda7cb3ca845771ffa0ea931ecf45d8877878403e2f6d72dce0d0f238" end depends_on "autoconf" => :build depends_on "automake" => :build depends_on "pkg-config" => :build depends_on "gmp" depends_on "guile" depends_on "libidn2" depends_on "libtasn1" depends_on "libunistring" depends_on "nettle" depends_on "p11-kit" depends_on "unbound" on_linux do depends_on "autogen" resource "cacert" do # homepage "http://curl.haxx.se/docs/caextract.html" url "https://curl.haxx.se/ca/cacert-2020-01-01.pem" mirror "https://gist.githubusercontent.com/dawidd6/16d94180a019f31fd31bc679365387bc/raw/ef02c78b9d6427585d756528964d18a2b9e318f7/cacert-2020-01-01.pem" sha256 "adf770dfd574a0d6026bfaa270cb6879b063957177a991d453ff1d302c02081f" end end def install # Fix build with Xcode 12 # https://gitlab.com/gnutls/gnutls/-/issues/1116 ENV.append "CFLAGS", "-Wno-implicit-function-declaration" args = %W[ --disable-dependency-tracking --disable-silent-rules --disable-static --prefix=#{prefix} --sysconfdir=#{etc} --with-default-trust-store-file=#{pkgetc}/cert.pem --with-guile-site-dir=#{share}/guile/site/3.0 --with-guile-site-ccache-dir=#{lib}/guile/3.0/site-ccache --with-guile-extension-dir=#{lib}/guile/3.0/extensions --disable-heartbeat-support --with-p11-kit ] system "./configure", *args # Adding LDFLAGS= to allow the build on Catalina 10.15.4 # See https://gitlab.com/gnutls/gnutls/-/issues/966 system "make", "LDFLAGS=", "install" # certtool shadows the macOS certtool utility mv bin/"certtool", bin/"gnutls-certtool" mv man1/"certtool.1", man1/"gnutls-certtool.1" end def post_install if OS.mac? macos_post_install else linux_post_install end end def macos_post_install ohai "Regenerating CA certificate bundle from keychain, this may take a while..." keychains = %w[ /Library/Keychains/System.keychain /System/Library/Keychains/SystemRootCertificates.keychain ] certs_list = `/usr/bin/security find-certificate -a -p #{keychains.join(" ")}` certs = certs_list.scan( /-----BEGIN CERTIFICATE-----.*?-----END CERTIFICATE-----/m, ) # Check that the certificate has not expired valid_certs = certs.select do |cert| IO.popen("openssl x509 -inform pem -checkend 0 -noout &>/dev/null", "w") do |openssl_io| openssl_io.write(cert) openssl_io.close_write end next unless $CHILD_STATUS.success? # XXX And drop Kerberos certs which may invalidate the whole trust store # due to bug in gnutls (https://gitlab.com/gnutls/gnutls/-/issues/1255) IO.popen("openssl x509 -inform pem -issuer -noout 2>/dev/null", "r+") do |openssl_io| openssl_io.write(cert) openssl_io.close_write cn = openssl_io.read openssl_io.close_read cn.exclude? "CN=com.apple.kerberos.kdc" end end # Check that the certificate is trusted in keychain trusted_certs = begin tmpfile = Tempfile.new valid_certs.select do |cert| tmpfile.rewind tmpfile.write cert tmpfile.truncate cert.size tmpfile.flush IO.popen("/usr/bin/security verify-cert -l -L -R offline -c #{tmpfile.path} &>/dev/null") $CHILD_STATUS.success? end ensure tmpfile&.close! end pkgetc.mkpath (pkgetc/"cert.pem").atomic_write(trusted_certs.join("\n") << "\n") # Touch gnutls.go to avoid Guile recompilation. # See https://github.com/Homebrew/homebrew-core/pull/60307#discussion_r478917491 touch "#{lib}/guile/3.0/site-ccache/gnutls.go" end def linux_post_install # Download and install cacert.pem from curl.haxx.se cacert = resource("cacert") cacert.fetch rm_f pkgetc/"cert.pem" filename = Pathname.new(cacert.url).basename pkgetc.install cacert.files(filename => "cert.pem") end def caveats <<~EOS If you are going to use the Guile bindings you will need to add the following to your .bashrc or equivalent in order for Guile to find the TLS certificates database: export GUILE_TLS_CERTIFICATE_DIRECTORY=#{pkgetc}/ EOS end test do system bin/"gnutls-cli", "--version" gnutls = testpath/"gnutls.scm" gnutls.write <<~EOS (use-modules (gnutls)) (gnutls-version) EOS ENV["GUILE_AUTO_COMPILE"] = "0" ENV["GUILE_LOAD_PATH"] = HOMEBREW_PREFIX/"share/guile/site/3.0" ENV["GUILE_LOAD_COMPILED_PATH"] = HOMEBREW_PREFIX/"lib/guile/3.0/site-ccache" ENV["GUILE_SYSTEM_EXTENSIONS_PATH"] = HOMEBREW_PREFIX/"lib/guile/3.0/extensions" system "guile", gnutls end end