Files
nix-stuff/shelved-projects/deterministic-certs.nix
Shelvacu e72e57822d stuff
2025-08-22 16:00:46 -07:00

89 lines
2.5 KiB
Nix

{
nixpkgs ? import <nixpkgs>,
}:
let
pkgs = nixpkgs;
lib = nixpkgs.lib;
defaultCertTemplate = {
serial = 1;
activation_date = "1970-01-01 00:00:00 UTC";
expiration_date = "2500-01-01 00:00:00 UTC";
};
keyValToConfigLines = (
key: value:
if (builtins.isString value) || (builtins.isPath value) then
''${key} = "${value}"''
else if builtins.isInt value then
"${key} = ${builtins.toString value}"
else if builtins.isList value then
map (innerValue: keyValToConfigLines key innerValue)
else if builtins.isBool value then
(if value then "${key}" else "# no ${key}")
else
throw "don't know how to handle ${builtins.typeOf value}"
);
mkTemplateConfig =
config:
lib.concatStringsSep "\n" (
lib.lists.flatten (lib.attrsets.mapAttrsToList keyValToConfigLines config)
);
privKeyFile =
name:
let
keySizeBits = 256;
keySizeHex = builtins.toString (keySizeBits / 4);
in
pkgs.runCommand "deterministic-privkey-${name}.pem" { } ''
seed=$(printf '%s' ${lib.escapeShellArg (builtins.toJSON name)} | ${pkgs.ruby_3_2}/bin/ruby -rjson -e 'name = JSON.parse(STDIN.gets); print name.unpack("H*")[0].ljust(${keySizeHex}, "0")')
${pkgs.gnutls}/bin/certtool --generate-privkey --outfile="$out" --key-type=rsa --sec-param=high --seed=$seed
'';
generateCert =
{
name,
config,
args,
preCommands ? "",
}:
let
deriv = pkgs.runCommand "deterministic-cert-${name}" { } ''
mkdir -p "$out"
cd "$out"
ln -s ${privKeyFile name} privkey.pem
ln -s ${
pkgs.writeText "${name}-template.cfg" (mkTemplateConfig (defaultCertTemplate // config))
} template.cfg
${preCommands}
${pkgs.gnutls}/bin/certtool ${lib.escapeShellArgs args} --load-privkey=privkey.pem --outfile=cert.pem --template=template.cfg
'';
in
deriv
// {
privateKeyPath = "${deriv}/privkey.pem";
certificatePath = "${deriv}/cert.pem";
};
in
{
inherit privKeyFile;
selfSigned =
name: config:
generateCert {
inherit name config;
args = [ "--generate-self-signed" ];
};
caSigned =
name: ca: config:
generateCert {
inherit name config;
preCommands = ''
ln -s ${ca.privateKeyPath} ca-privkey.pem
ln -s ${ca.certificatePath} ca-cert.pem
'';
args = [
"--generate-certificate"
"--load-ca-certificate=ca-cert.pem"
"--load-ca-privkey=ca-privkey.pem"
];
};
}