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.
This commit is contained in:
Franz Pletz 2016-09-01 23:40:05 +02:00 committed by Robin Gloster
parent cefe4a816d
commit 0d59fc1169
No known key found for this signature in database
GPG key ID: 5E4C836C632C2882
2 changed files with 63 additions and 17 deletions

View file

@ -4,10 +4,16 @@ with lib;
let
cfg = config.security.pki;
cacertPackage = pkgs.cacert.override {
blacklist = cfg.caCertificateBlacklist;
};
caCertificates = pkgs.runCommand "ca-certificates.crt"
{ files =
config.security.pki.certificateFiles ++
[ (builtins.toFile "extra.crt" (concatStringsSep "\n" config.security.pki.certificates)) ];
cfg.certificateFiles ++
[ (builtins.toFile "extra.crt" (concatStringsSep "\n" cfg.certificates)) ];
}
''
cat $files > $out
@ -52,11 +58,27 @@ in
'';
};
security.pki.caCertificateBlacklist = mkOption {
type = types.listOf types.str;
default = [];
example = [
"WoSign" "WoSign China"
"CA WoSign ECC Root"
"Certification Authority of WoSign G2"
];
description = ''
A list of blacklisted CA certificate names that won't be imported from
the Mozilla Trust Store into
<filename>/etc/ssl/certs/ca-certificates.crt</filename>. Use the
names from that file.
'';
};
};
config = {
security.pki.certificateFiles = [ "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt" ];
security.pki.certificateFiles = [ "${cacertPackage}/etc/ssl/certs/ca-bundle.crt" ];
# NixOS canonical location + Debian/Ubuntu/Arch/Gentoo compatibility.
environment.etc."ssl/certs/ca-certificates.crt".source = caCertificates;

View file

@ -1,25 +1,49 @@
{ stdenv, nss, curl, perl }:
{ stdenv, fetchurl, writeText, nss, python
, blacklist ? []
, includeEmail ? false
}:
with stdenv.lib;
let
certdata2pem = fetchurl {
name = "certdata2pem.py";
url = "https://anonscm.debian.org/cgit/collab-maint/ca-certificates.git/plain/mozilla/certdata2pem.py?h=debian/20160104";
sha256 = "0bw11mgfrf19qziyvdnq22kirp0nn54lfsanrg5h6djs6ig1c2im";
};
in
stdenv.mkDerivation rec {
name = "nss-cacert-${nss.version}";
src = nss.src;
postPatch = ''
unpackFile ${curl.src};
nativeBuildInputs = [ python ];
# Remove dependency on LWP, curl is enough. Also, since curl here
# is working on a local file it will not actually get a 200 OK, so
# remove that expectation.
substituteInPlace curl-*/lib/mk-ca-bundle.pl \
--replace 'use LWP::UserAgent;' "" \
--replace ' && $out[0] == 200' ""
configurePhase = ''
ln -s nss/lib/ckfw/builtins/certdata.txt
cat << EOF > blacklist.txt
${concatStringsSep "\n" (map (c: ''"${c}"'') blacklist)}
EOF
cp ${certdata2pem} certdata2pem.py
${optionalString includeEmail ''
# Disable CAs used for mail signing
substituteInPlace certdata2pem.py --replace \[\'CKA_TRUST_EMAIL_PROTECTION\'\] '''
''}
'';
nativeBuildInputs = [ curl perl ];
buildPhase = ''
perl curl-*/lib/mk-ca-bundle.pl -d "file://$(pwd)/nss/lib/ckfw/builtins/certdata.txt" ca-bundle.crt
python certdata2pem.py | grep -vE '^(!|UNTRUSTED)'
for cert in *.crt; do
echo $cert | cut -d. -f1 | sed -e 's,_, ,g' >> ca-bundle.crt
cat $cert >> ca-bundle.crt
echo >> ca-bundle.crt
done
'';
installPhase = ''
@ -27,10 +51,10 @@ stdenv.mkDerivation rec {
cp -v ca-bundle.crt $out/etc/ssl/certs
'';
meta = with stdenv.lib; {
meta = {
homepage = http://curl.haxx.se/docs/caextract.html;
description = "A bundle of X.509 certificates of public Certificate Authorities (CA)";
platforms = platforms.all;
maintainers = with maintainers; [ wkennington ];
maintainers = with maintainers; [ wkennington fpletz ];
};
}