diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 523d3c051e0..c7b21432b58 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -81,6 +81,7 @@ in corerad = handleTest ./corerad.nix {}; couchdb = handleTest ./couchdb.nix {}; cri-o = handleTestOn ["x86_64-linux"] ./cri-o.nix {}; + custom-ca = handleTest ./custom-ca.nix {}; deluge = handleTest ./deluge.nix {}; dhparams = handleTest ./dhparams.nix {}; dnscrypt-proxy2 = handleTestOn ["x86_64-linux"] ./dnscrypt-proxy2.nix {}; diff --git a/nixos/tests/custom-ca.nix b/nixos/tests/custom-ca.nix new file mode 100644 index 00000000000..67f7b3ff1f1 --- /dev/null +++ b/nixos/tests/custom-ca.nix @@ -0,0 +1,161 @@ +# Checks that `security.pki` options are working in curl and the main browser +# engines: Gecko (via Firefox), Chromium, QtWebEngine (Falkon) and WebKitGTK +# (via Midori). The test checks that certificates issued by a custom trusted +# CA are accepted but those from an unknown CA are rejected. + +import ./make-test-python.nix ({ pkgs, lib, ... }: + +let + makeCert = { caName, domain }: pkgs.runCommand "example-cert" + { buildInputs = [ pkgs.gnutls ]; } + '' + mkdir $out + + # CA cert template + cat >ca.template <server.template < Tuple[int, str]: + """ + Run a shell command as a specific user. + """ + return machine.execute(f"sudo -u {user} {cmd}") + + + def wait_for_window_as(user: str, cls: str) -> None: + """ + Wait until a X11 window of a given user appears. + """ + + def window_is_visible(last_try: bool) -> bool: + ret, stdout = execute_as(user, f"xdotool search --onlyvisible --class {cls}") + if last_try: + machine.log(f"Last chance to match {cls} on the window list") + return ret == 0 + + with machine.nested("Waiting for a window to appear"): + retry(window_is_visible) + + + machine.start() + + with subtest("Good certificate is trusted in curl"): + machine.wait_for_unit("nginx") + machine.wait_for_open_port(443) + machine.succeed("curl -fv https://good.example.com") + + with subtest("Unknown CA is untrusted in curl"): + machine.fail("curl -fv https://bad.example.com") + + browsers = ["firefox", "chromium", "falkon", "midori"] + errors = ["Security Risk", "not private", "Certificate Error", "Security"] + + machine.wait_for_x() + for browser, error in zip(browsers, errors): + with subtest("Good certificate is trusted in " + browser): + execute_as( + "alice", f"env P11_KIT_DEBUG=trust {browser} https://good.example.com & >&2" + ) + wait_for_window_as("alice", browser) + machine.wait_for_text("It works!") + machine.screenshot("good" + browser) + execute_as("alice", "xdotool key ctrl+w") # close tab + + with subtest("Unknown CA is untrusted in " + browser): + execute_as("alice", f"{browser} https://bad.example.com & >&2") + machine.wait_for_text(error) + machine.screenshot("bad" + browser) + machine.succeed("pkill " + browser) + ''; +}) diff --git a/pkgs/development/libraries/nss/default.nix b/pkgs/development/libraries/nss/default.nix index 8c98d7ae9bb..aa691092f85 100644 --- a/pkgs/development/libraries/nss/default.nix +++ b/pkgs/development/libraries/nss/default.nix @@ -1,4 +1,7 @@ -{ lib, stdenv, fetchurl, nspr, perl, zlib, sqlite, darwin, fixDarwinDylibNames, buildPackages, ninja +{ lib, stdenv, fetchurl, nspr, perl, zlib +, sqlite, ninja +, darwin, fixDarwinDylibNames, buildPackages +, useP11kit ? true, p11-kit , # allow FIPS mode. Note that this makes the output non-reproducible. # https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/NSS_Tech_Notes/nss_tech_note6 enableFIPS ? false @@ -139,6 +142,11 @@ in stdenv.mkDerivation rec { chmod 0755 $out/bin/nss-config ''; + postInstall = stdenv.lib.optionalString useP11kit '' + # Replace built-in trust with p11-kit connection + ln -sf ${p11-kit}/lib/pkcs11/p11-kit-trust.so $out/lib/libnssckbi.so + ''; + postFixup = let isCross = stdenv.hostPlatform != stdenv.buildPlatform; nss = if isCross then buildPackages.nss.tools else "$out";