cacerts: refactor, add blacklist option

Previously, the list of CA certificates was generated with a perl script
which is included in curl. As this script is not very flexible, this commit
refactors the expression to use the python script that Debian uses to
generate their CA certificates from Mozilla's trust store in NSS.

Additionally, an option was added to the cacerts derivation and the
`security.pki` module to blacklist specific CAs.

authored by

Franz Pletz and committed by
Robin Gloster
0d59fc11 cefe4a81

+63 -17
+25 -3
nixos/modules/security/ca.nix
··· 4 4 5 5 let 6 6 7 + cfg = config.security.pki; 8 + 9 + cacertPackage = pkgs.cacert.override { 10 + blacklist = cfg.caCertificateBlacklist; 11 + }; 12 + 7 13 caCertificates = pkgs.runCommand "ca-certificates.crt" 8 14 { files = 9 - config.security.pki.certificateFiles ++ 10 - [ (builtins.toFile "extra.crt" (concatStringsSep "\n" config.security.pki.certificates)) ]; 15 + cfg.certificateFiles ++ 16 + [ (builtins.toFile "extra.crt" (concatStringsSep "\n" cfg.certificates)) ]; 11 17 } 12 18 '' 13 19 cat $files > $out ··· 52 58 ''; 53 59 }; 54 60 61 + security.pki.caCertificateBlacklist = mkOption { 62 + type = types.listOf types.str; 63 + default = []; 64 + example = [ 65 + "WoSign" "WoSign China" 66 + "CA WoSign ECC Root" 67 + "Certification Authority of WoSign G2" 68 + ]; 69 + description = '' 70 + A list of blacklisted CA certificate names that won't be imported from 71 + the Mozilla Trust Store into 72 + <filename>/etc/ssl/certs/ca-certificates.crt</filename>. Use the 73 + names from that file. 74 + ''; 75 + }; 76 + 55 77 }; 56 78 57 79 config = { 58 80 59 - security.pki.certificateFiles = [ "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt" ]; 81 + security.pki.certificateFiles = [ "${cacertPackage}/etc/ssl/certs/ca-bundle.crt" ]; 60 82 61 83 # NixOS canonical location + Debian/Ubuntu/Arch/Gentoo compatibility. 62 84 environment.etc."ssl/certs/ca-certificates.crt".source = caCertificates;
+38 -14
pkgs/data/misc/cacert/default.nix
··· 1 - { stdenv, nss, curl, perl }: 1 + { stdenv, fetchurl, writeText, nss, python 2 + , blacklist ? [] 3 + , includeEmail ? false 4 + }: 5 + 6 + with stdenv.lib; 7 + 8 + let 9 + 10 + certdata2pem = fetchurl { 11 + name = "certdata2pem.py"; 12 + url = "https://anonscm.debian.org/cgit/collab-maint/ca-certificates.git/plain/mozilla/certdata2pem.py?h=debian/20160104"; 13 + sha256 = "0bw11mgfrf19qziyvdnq22kirp0nn54lfsanrg5h6djs6ig1c2im"; 14 + }; 15 + 16 + in 2 17 3 18 stdenv.mkDerivation rec { 4 19 name = "nss-cacert-${nss.version}"; 5 20 6 21 src = nss.src; 7 22 8 - postPatch = '' 9 - unpackFile ${curl.src}; 23 + nativeBuildInputs = [ python ]; 10 24 11 - # Remove dependency on LWP, curl is enough. Also, since curl here 12 - # is working on a local file it will not actually get a 200 OK, so 13 - # remove that expectation. 14 - substituteInPlace curl-*/lib/mk-ca-bundle.pl \ 15 - --replace 'use LWP::UserAgent;' "" \ 16 - --replace ' && $out[0] == 200' "" 17 - ''; 25 + configurePhase = '' 26 + ln -s nss/lib/ckfw/builtins/certdata.txt 18 27 19 - nativeBuildInputs = [ curl perl ]; 28 + cat << EOF > blacklist.txt 29 + ${concatStringsSep "\n" (map (c: ''"${c}"'') blacklist)} 30 + EOF 31 + 32 + cp ${certdata2pem} certdata2pem.py 33 + ${optionalString includeEmail '' 34 + # Disable CAs used for mail signing 35 + substituteInPlace certdata2pem.py --replace \[\'CKA_TRUST_EMAIL_PROTECTION\'\] ''' 36 + ''} 37 + ''; 20 38 21 39 buildPhase = '' 22 - perl curl-*/lib/mk-ca-bundle.pl -d "file://$(pwd)/nss/lib/ckfw/builtins/certdata.txt" ca-bundle.crt 40 + python certdata2pem.py | grep -vE '^(!|UNTRUSTED)' 41 + 42 + for cert in *.crt; do 43 + echo $cert | cut -d. -f1 | sed -e 's,_, ,g' >> ca-bundle.crt 44 + cat $cert >> ca-bundle.crt 45 + echo >> ca-bundle.crt 46 + done 23 47 ''; 24 48 25 49 installPhase = '' ··· 27 51 cp -v ca-bundle.crt $out/etc/ssl/certs 28 52 ''; 29 53 30 - meta = with stdenv.lib; { 54 + meta = { 31 55 homepage = http://curl.haxx.se/docs/caextract.html; 32 56 description = "A bundle of X.509 certificates of public Certificate Authorities (CA)"; 33 57 platforms = platforms.all; 34 - maintainers = with maintainers; [ wkennington ]; 58 + maintainers = with maintainers; [ wkennington fpletz ]; 35 59 }; 36 60 }