about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--nixos/modules/services/misc/taskserver/default.nix66
-rw-r--r--nixos/modules/services/misc/taskserver/helper-tool.py11
2 files changed, 63 insertions, 14 deletions
diff --git a/nixos/modules/services/misc/taskserver/default.nix b/nixos/modules/services/misc/taskserver/default.nix
index dc73ad26eb6c4..70e162904e98d 100644
--- a/nixos/modules/services/misc/taskserver/default.nix
+++ b/nixos/modules/services/misc/taskserver/default.nix
@@ -17,7 +17,7 @@ let
     result = "${key} = ${mkVal val}";
   in optionalString (val != null && val != []) result;
 
-  mkPkiOption = desc: mkOption {
+  mkManualPkiOption = desc: mkOption {
     type = types.nullOr types.path;
     default = null;
     description = desc + ''
@@ -27,24 +27,60 @@ let
     '';
   };
 
-  pkiOptions = {
-    ca.cert = mkPkiOption ''
+  manualPkiOptions = {
+    ca.cert = mkManualPkiOption ''
       Fully qualified path to the CA certificate.
     '';
 
-    server.cert = mkPkiOption ''
+    server.cert = mkManualPkiOption ''
       Fully qualified path to the server certificate.
     '';
 
-    server.crl = mkPkiOption ''
+    server.crl = mkManualPkiOption ''
       Fully qualified path to the server certificate revocation list.
     '';
 
-    server.key = mkPkiOption ''
+    server.key = mkManualPkiOption ''
       Fully qualified path to the server key.
     '';
   };
 
+  mkAutoDesc = preamble: ''
+    ${preamble}
+
+    <note><para>
+    This option is for the automatically handled CA and will be ignored if any
+    of the <option>services.taskserver.pki.manual.*</option> options are set.
+    </para></note>
+  '';
+
+  mkExpireOption = desc: mkOption {
+    type = types.nullOr types.int;
+    default = null;
+    example = 365;
+    apply = val: if isNull val then -1 else val;
+    description = mkAutoDesc ''
+      The expiration time of ${desc} in days or <literal>null</literal> for no
+      expiration time.
+    '';
+  };
+
+  autoPkiOptions = {
+    bits = mkOption {
+      type = types.int;
+      default = 4096;
+      example = 2048;
+      description = mkAutoDesc "The bit size for generated keys.";
+    };
+
+    expiration = {
+      ca = mkExpireOption "the CA certificate";
+      server = mkExpireOption "the server certificate";
+      client = mkExpireOption "client certificates";
+      crl = mkExpireOption "the certificate revocation list (CRL)";
+    };
+  };
+
   needToCreateCA = let
     notFound = path: let
       dotted = concatStringsSep "." path;
@@ -53,10 +89,10 @@ let
       mkSublist = key: val: let
         newPath = path ++ singleton key;
       in if isOption val
-         then attrByPath newPath (notFound newPath) cfg.pki
+         then attrByPath newPath (notFound newPath) cfg.pki.manual
          else findPkiDefinitions newPath val;
     in flatten (mapAttrsToList mkSublist attrs);
-  in all isNull (findPkiDefinitions [] pkiOptions);
+  in all isNull (findPkiDefinitions [] manualPkiOptions);
 
   configFile = pkgs.writeText "taskdrc" ''
     # systemd related
@@ -130,6 +166,9 @@ let
         src = ./helper-tool.py;
         inherit taskd certtool;
         inherit (cfg) dataDir user group fqdn;
+        certBits = cfg.pki.auto.bits;
+        clientExpiration = cfg.pki.auto.expiration.client;
+        crlExpiration = cfg.pki.auto.expiration.crl;
       }}" > "$out/main.py"
       cat > "$out/setup.py" <<EOF
       from setuptools import setup
@@ -322,7 +361,8 @@ in {
         '';
       };
 
-      pki = pkiOptions;
+      pki.manual = manualPkiOptions;
+      pki.auto = autoPkiOptions;
     };
   };
 
@@ -364,11 +404,12 @@ in {
 
         if [ ! -e "${cfg.dataDir}/keys/ca.key" ]; then
           silent_certtool -p \
-            --bits 2048 \
+            --bits ${toString cfg.pki.auto.bits} \
             --outfile "${cfg.dataDir}/keys/ca.key"
           silent_certtool -s \
             --template "${pkgs.writeText "taskserver-ca.template" ''
               cn = ${cfg.fqdn}
+              expiration_days = ${toString cfg.pki.auto.expiration.ca}
               cert_signing_key
               ca
             ''}" \
@@ -381,12 +422,13 @@ in {
 
         if [ ! -e "${cfg.dataDir}/keys/server.key" ]; then
           silent_certtool -p \
-            --bits 2048 \
+            --bits ${toString cfg.pki.auto.bits} \
             --outfile "${cfg.dataDir}/keys/server.key"
 
           silent_certtool -c \
             --template "${pkgs.writeText "taskserver-cert.template" ''
               cn = ${cfg.fqdn}
+              expiration_days = ${toString cfg.pki.auto.expiration.server}
               tls_www_server
               encryption_key
               signing_key
@@ -408,7 +450,7 @@ in {
         if [ ! -e "${cfg.dataDir}/keys/server.crl" ]; then
           silent_certtool --generate-crl \
             --template "${pkgs.writeText "taskserver-crl.template" ''
-              expiration_days = 3650
+              expiration_days = ${toString cfg.pki.auto.expiration.crl}
             ''}" \
             --load-ca-privkey "${cfg.dataDir}/keys/ca.key" \
             --load-ca-certificate "${cfg.dataDir}/keys/ca.cert" \
diff --git a/nixos/modules/services/misc/taskserver/helper-tool.py b/nixos/modules/services/misc/taskserver/helper-tool.py
index 512aaa4ab9f83..abc7362cf7c58 100644
--- a/nixos/modules/services/misc/taskserver/helper-tool.py
+++ b/nixos/modules/services/misc/taskserver/helper-tool.py
@@ -14,6 +14,10 @@ from tempfile import NamedTemporaryFile
 import click
 
 CERTTOOL_COMMAND = "@certtool@"
+CERT_BITS = "@certBits@"
+CLIENT_EXPIRATION = "@clientExpiration@"
+CRL_EXPIRATION = "@crlExpiration@"
+
 TASKD_COMMAND = "@taskd@"
 TASKD_DATA_DIR = "@dataDir@"
 TASKD_USER = "@user@"
@@ -153,11 +157,12 @@ def generate_key(org, user):
     try:
         os.makedirs(basedir, mode=0700)
 
-        certtool_cmd("-p", "--bits", "2048", "--outfile", privkey)
+        certtool_cmd("-p", "--bits", CERT_BITS, "--outfile", privkey)
 
         template_data = [
             "organization = {0}".format(org),
             "cn = {}".format(FQDN),
+            "expiration_days = {}".format(CLIENT_EXPIRATION),
             "tls_www_client",
             "encryption_key",
             "signing_key"
@@ -188,7 +193,9 @@ def revoke_key(org, user):
 
     pubcert = os.path.join(basedir, "public.cert")
 
-    with create_template(["expiration_days = 3650"]) as template:
+    expiration = "expiration_days = {}".format(CRL_EXPIRATION)
+
+    with create_template([expiration]) as template:
         oldcrl = NamedTemporaryFile(mode="wb", prefix="old-crl")
         oldcrl.write(open(crl, "rb").read())
         oldcrl.flush()