modules: introduce mkcert (development certification authority)

This commit is contained in:
David Arnold 2021-01-27 19:18:05 -05:00
parent ff6cffba08
commit a5685329f8
No known key found for this signature in database
GPG Key ID: 6D6A936E69C59D08
2 changed files with 190 additions and 1 deletions

View File

@ -1,5 +1,6 @@
imports = [
"language.go"
"language.go",
"ca.mkcert"
]
[devshell]
@ -45,3 +46,78 @@ category = "utilites"
help = "golang linter"
package = "golangci-lint"
category = "linters"
[mkcert]
enable = true
root-ca.key = """
-----BEGIN PRIVATE KEY-----
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
xS044vroff+d0i4NxpOfBXyf
-----END PRIVATE KEY-----
"""
root-ca.cert = """
-----BEGIN CERTIFICATE-----
MIIEzjCCAzagAwIBAgIRAKGyGtqQLfNkWqnQWQ5mhx0wDQYJKoZIhvcNAQELBQAw
fzEeMBwGA1UEChMVbWtjZXJ0IGRldmVsb3BtZW50IENBMSowKAYDVQQLDCFuaXhi
bGRAbG9jYWxob3N0IChOaXggYnVpbGQgdXNlcikxMTAvBgNVBAMMKG1rY2VydCBu
aXhibGRAbG9jYWxob3N0IChOaXggYnVpbGQgdXNlcikwHhcNMjEwMTI3MTg1NTM1
WhcNMzEwMTI3MTg1NTM1WjB/MR4wHAYDVQQKExVta2NlcnQgZGV2ZWxvcG1lbnQg
Q0ExKjAoBgNVBAsMIW5peGJsZEBsb2NhbGhvc3QgKE5peCBidWlsZCB1c2VyKTEx
MC8GA1UEAwwobWtjZXJ0IG5peGJsZEBsb2NhbGhvc3QgKE5peCBidWlsZCB1c2Vy
KTCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAJpNoK7FKbvIdPHxYEGu
HKoCyMNi+OxTDXRrrUPWgkDr64KIQwevv1ePddIzSE1levtOfL2l6oquzTtOqZFj
jaAzrD/VafQqXs4PBtMpN5IZzNqmrTCZ3tvVm2sjh3diPd2N2BfEuVf4KgE7aN91
BK/k5s4MFZcTvERA1CBZ1Dg6q65v6r7y2v3q/vuDN4LGsVC0Nk3ySSbhQZ1IGCPC
uqalnyghdP8SM7v2UiK9F5nyiVwmAsRE/AE0agGZO/0MDPJmLYbrBwi2L+Q+MU0n
8MBW9fGEDSmazISdKCdlxNLCZZKsA6v5ZMuQvuCGy/kN4gF66WVp+zr9+9AwCocO
F7yW7igWYdDzPoeqZvu0KsqcFnYYxCgkBFIC2LoubsuOBegPN3cqdxOVSgdTkREh
+BlUOoGtlrC8wnxXqvvD4Us/Az2DAmoIuRi6xS9wHjrN1+BkznPeAcsiFcWh917G
KCTHmEwveH74Z3UOiXhi+1CZT4Rs6LsR9WB2jJrKzsh8TwIDAQABo0UwQzAOBgNV
HQ8BAf8EBAMCAgQwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUvFZHpiR1
SsZgx18IXS4sV2goJwwwDQYJKoZIhvcNAQELBQADggGBAEhEXonraBKooVsYVdd6
EuLD5LJ9rLuVN0QCOWzMDgqc1iHX+nTEjH6OctBpdGo+1RRE4UB1SHoaCW7LcJJx
1UCPHvMTby2U0Y1E7NS9dOdt3slUQUF86KfecV8UfTLgqWvN8W3pdyNqk8X7g5FO
vnoWMRXopNyI/AnnAfEMC2rA1+fgJXFIi7Ny5vHiPoaPolvULDU8gwcBPpGB80z0
py4x/DcO4UoNB11fs2+XNV6UGHfLB1R1OJmhdCbEQ7cmIetg11ThuvD8YiomKb1O
wJO5moU86AJ52o19C3AmYKsClhGwnGLGNgOslFIozRi7eSPX7B9UdEJUvj2tGkUE
mpSjE6hTUtEinmuQ0gkf4jaqcWetJnhUVaNGsbixWdRtkNkvICkToCGhHXFKDGfr
qrM5Rs0xtUAp91/DZ+vbPsuWzvRibCrck89vyg1lGemhMf8g34U1ocf5KlyLvO3c
o3E+CRMwgG1IP4ktc63dfXPvbfN+lKjk1LVhMBPXeqhJ2A==
-----END CERTIFICATE-----
"""

113
extra/ca/mkcert.nix Normal file
View File

@ -0,0 +1,113 @@
{ lib, pkgs, config, ... }:
with lib;
let
cfg = config.mkcert;
maybeReadFile = obj:
if (builtins.typeOf obj == "path") then
builtins.readFile obj
else
obj
;
# These are all the options available for specifying a certificate/key file.
rootCAOption = {
key = mkOption {
description = "Text or file of the root CA key to install";
default = null;
type = types.nullOr (types.either types.str types.path);
};
cert = mkOption {
description = "Text or file of the root CA certificate to install";
default = null;
type = types.nullOr (types.either types.str types.path);
};
};
# A collection of development certificate authority files
rootCADir =
let
adHoc = pkgs.runCommandLocal "rootCA" {} ''
export CAROOT=$out
${pkgs.mkcert}/bin/mkcert 2>/dev/null
'';
isPreconfigured =
assert assertMsg (
cfg.root-ca != {} && cfg.root-ca.cert != null && cfg.root-ca.key != null
) "[mkcert]: either set, both, root CA key and certificate or none.";
(cfg.root-ca.key != null && cfg.root-ca.cert != null);
key = pkgs.writeText "rootCA-key.pem" (maybeReadFile cfg.root-ca.key);
cert = pkgs.writeText "rootCA.pem" (maybeReadFile cfg.root-ca.cert);
preconfigured = pkgs.runCommand "rootCA" {} ''
mkdir $out
cp ${key} $out/${key.name}
cp ${cert} $out/${cert.name}
'';
in
if isPreconfigured then preconfigured else adHoc;
# Execute this script to install the project's development certificate authority
install-mkcert-ca = pkgs.writeShellScriptBin "install-mkcert-ca" ''
set -euo pipefail
shopt -s nullglob
log() {
IFS=$'\n' loglines=($*)
for line in ${"$"}{loglines[@]}; do echo -e "[mkcert] $line" >&2; done
}
# Set the CA root files directory for mkcert via env variable
export CAROOT=${rootCADir}
# Install local CA into system, java and nss (includes Firefox) trust stores
log "Install development CA into the system stores..."
log $(sudo -K; ${pkgs.mkcert}/bin/mkcert -install 2>&1)
log "root CA directory: $(${pkgs.mkcert}/bin/mkcert -CAROOT 2>&1)"
uninstall() {
log $(${pkgs.mkcert}/bin/mkcert -uninstall 2>&1)
}
# TODO: Uninstall when leaving the devshell
# trap uninstall EXIT
'';
in
{
options.mkcert = {
enable = mkEnableOption "provide a development CA within the shell";
root-ca = mkOption {
type = types.submodule { options = rootCAOption; };
default = {};
description = "preconfigure root CA files";
example = literalExample "
{
key = ''
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
'';
cert = ./path/tocert.pem;
}
";
};
};
config = mkIf cfg.enable {
env = [{
name = "CAROOT";
value = "${rootCADir}";
}];
commands = [ { package = pkgs.mkcert; category = "certs"; } ];
devshell = {
packages = [ install-mkcert-ca ];
startup.install-mkcert-ca.text = "
$DEVSHELL_DIR/bin/install-mkcert-ca
";
};
};
}