{ config, lib, pkgs, ... }: with lib; let cfg = config.local.pki.ca; inherit (pkgs.buildPackages) openssl; certsType = leafOf: with lib.types; attrsOf (submodule ({ config, name, ... }: { options = { cert = mkOption { type = path; readOnly = true; }; fingerprint.sha256 = mkOption { type = str; readOnly = true; }; fullchain = mkOption { type = path; readOnly = true; }; issuer = mkOption { type = nullOr str; readOnly = true; }; path = mkOption { type = str; readOnly = true; }; } // optionalAttrs (leafOf != null) { commonName = mkOption { type = str; readOnly = true; }; } // optionalAttrs (leafOf == null) { crl = mkOption { type = path; readOnly = true; }; certWithCrl = mkOption { type = path; readOnly = true; }; leaves = mkOption { type = certsType name; readOnly = true; }; }; config = { fingerprint.sha256 = readFile (pkgs.runCommandNoCCLocal "cert-${config.path}-fprint-sha256" { } '' ${openssl}/bin/openssl x509 -in ${config.cert} -noout -sha256 -fingerprint \ | sed 's/^.*=//' \ | tr -d $'\n' \ >$out ''); fullchain = pkgs.writeText "${name}-fullchain-crl.pem" (concatStrings (map readFile (singleton (if leafOf != null then config.cert else config.certWithCrl) ++ optional (config.issuer != null) cfg.${config.issuer}.fullchain))); path = optionalString (config.issuer != null) (cfg.${config.issuer}.path + ".") + name; } // optionalAttrs (leafOf != null) { commonName = readFile (pkgs.runCommandNoCCLocal "cert-${config.path}-fprint-sha256" { } '' ${openssl}/bin/openssl x509 -in ${config.cert} -noout -subject -nameopt multiline \ | grep commonName \ | sed 's/^.*=\s*//' \ | tr -d $'\n' \ >$out ''); issuer = leafOf; } // optionalAttrs (leafOf == null) { certWithCrl = pkgs.writeText "${name}-cert-crl.pem" (concatStrings (map readFile [ config.cert config.crl ])); }; })); in { options.local.pki.ca = mkOption { type = certsType null; readOnly = true; }; config.local.pki.ca = { home = { crl = ./public/home-crl.pem; cert = ./public/home-ca.pem; issuer = "root"; leaves = { user-firefox.cert = ./public/home-user-firefox.pem; }; }; mail = { crl = ./public/mail-crl.pem; cert = ./public/mail-ca.pem; issuer = "root"; leaves = { kiev.cert = ./public/mail-kiev.pem; larsa.cert = ./public/mail-larsa.pem; }; }; root = { crl = ./public/root-crl.pem; cert = ./public/root-ca.pem; issuer = null; leaves = { }; }; }; }