ctucx.git: dns.nix

fork of https://github.com/kirelagin/dns.nix

commit 985797066ffaf8fb05693169c7c2c3222c704365
parent a78f81fdf136d1bb9c57878639a029e647c68a9f
Author: Kirill Elagin <kirelagin@gmail.com>
Date: Wed, 2 Dec 2020 09:22:13 -0500

Merge pull request #5 from AluisioASG/aasg/dnssec

Add support for DNSKEY and DS records
4 files changed, 141 insertions(+), 0 deletions(-)
A
dns/types/records/DNSKEY.nix
|
53
+++++++++++++++++++++++++++++++++++++++++++++++++++++
A
dns/types/records/DS.nix
|
44
++++++++++++++++++++++++++++++++++++++++++++
M
dns/types/records/default.nix
|
4
++++
A
dns/types/records/dnssec.nix
|
40
++++++++++++++++++++++++++++++++++++++++
diff --git a/dns/types/records/DNSKEY.nix b/dns/types/records/DNSKEY.nix
@@ -0,0 +1,53 @@
+# SPDX-FileCopyrightText: 2020 Aluísio Augusto Silva Gonçalves <https://aasg.name>
+#
+# SPDX-License-Identifier: MIT
+
+{ pkgs }:
+let
+  inherit (builtins) isInt split;
+  inherit (pkgs.lib) concatStrings flatten mkOption types;
+
+  dnssecOptions = import ./dnssec.nix { inherit pkgs; };
+  inherit (dnssecOptions) mkDNSSECAlgorithmOption;
+in
+{
+  rtype = "DNSKEY";
+  options = {
+    flags = mkOption {
+      description = "Flags pertaining to this RR.";
+      type = types.either types.ints.u16 (types.submodule {
+        options = {
+          zoneSigningKey = mkOption {
+            description = "Whether this RR holds a zone signing key (ZSK).";
+            type = types.bool;
+            default = false;
+          };
+          secureEntryPoint = mkOption {
+            type = types.bool;
+            description = ''
+              Whether this RR holds a secure entry point.
+              In general, this means the key is a key-signing key (KSK), as opposed to a zone-signing key.
+            '';
+            default = false;
+          };
+        };
+      });
+      apply = value:
+        if isInt value
+        then value
+        else
+          (if value.zoneSigningKey then 256 else 0)
+          + (if value.secureEntryPoint then 1 else 0);
+    };
+    algorithm = mkDNSSECAlgorithmOption {
+      description = "Algorithm of the key referenced by this RR.";
+    };
+    publicKey = mkOption {
+      type = types.str;
+      description = "Base64-encoded public key.";
+      apply = value: concatStrings (flatten (split "[[:space:]]" value));
+    };
+  };
+  dataToString = { flags, algorithm, publicKey, ... }:
+    "${toString flags} 3 ${toString algorithm} ${publicKey}";
+}
diff --git a/dns/types/records/DS.nix b/dns/types/records/DS.nix
@@ -0,0 +1,44 @@
+# SPDX-FileCopyrightText: 2020 Aluísio Augusto Silva Gonçalves <https://aasg.name>
+#
+# SPDX-License-Identifier: MIT
+
+{ pkgs }:
+let
+  inherit (pkgs.lib) mkOption types;
+
+  dnssecOptions = import ./dnssec.nix { inherit pkgs; };
+  inherit (dnssecOptions) mkRegisteredNumberOption mkDNSSECAlgorithmOption;
+
+  mkDSDigestTypeOption = { ... }@args: mkRegisteredNumberOption {
+    registryName = "Delegation Signer (DS) Resource Record (RR) Type Digest Algorithms";
+    numberType = types.ints.u8;
+    # These mnemonics are unofficial, unlike the DNSSEC algorithm ones.
+    mnemonics = {
+      "sha-1" = 1;
+      "sha-256" = 2;
+      "gost" = 3;
+      "sha-384" = 4;
+    };
+  };
+in
+{
+  rtype = "DS";
+  options = {
+    keyTag = mkOption {
+      description = "Tag computed over the DNSKEY referenced by this RR to identify it.";
+      type = types.ints.u16;
+    };
+    algorithm = mkDNSSECAlgorithmOption {
+      description = "Algorithm of the key referenced by this RR.";
+    };
+    digestType = mkDSDigestTypeOption {
+      description = "Type of the digest given in the `digest` attribute.";
+    };
+    digest = mkOption {
+      description = "Digest of the DNSKEY referenced by this RR.";
+      type = types.strMatching "[[:xdigit:]]+";
+    };
+  };
+  dataToString = { keyTag, algorithm, digestType, digest, ... }:
+    "${toString keyTag} ${toString algorithm} ${toString digestType} ${digest}";
+}
diff --git a/dns/types/records/default.nix b/dns/types/records/default.nix
@@ -20,6 +20,10 @@ let
     "SRV"
     "TXT"
 
+    # DNSSEC types
+    "DNSKEY"
+    "DS"
+
     # Pseudo types
     "DKIM"
     "DMARC"
diff --git a/dns/types/records/dnssec.nix b/dns/types/records/dnssec.nix
@@ -0,0 +1,40 @@
+# SPDX-FileCopyrightText: 2020 Aluísio Augusto Silva Gonçalves <https://aasg.name>
+#
+# SPDX-License-Identifier: MIT
+
+{ pkgs }:
+let
+  inherit (builtins) attrNames isInt removeAttrs;
+  inherit (pkgs.lib) mkOption types;
+in
+rec {
+  mkRegisteredNumberOption = { registryName, numberType, mnemonics }@args:
+    mkOption
+      {
+        type = types.either numberType (types.enum (attrNames mnemonics)) // {
+          name = "registeredNumber";
+          description = "number in IANA registry '${registryName}'";
+        };
+        apply = value: if isInt value then value else mnemonics.${value};
+      } // removeAttrs args [ "registryName" "numberType" "mnemonics" ];
+
+  mkDNSSECAlgorithmOption = { ... }@args: mkRegisteredNumberOption {
+    registryName = "Domain Name System Security (DNSSEC) Algorithm Numbers";
+    numberType = types.ints.u8;
+    mnemonics = {
+      "dsa" = 3;
+      "rsasha1" = 5;
+      "dsa-nsec3-sha1" = 6;
+      "rsasha1-nsec3-sha1" = 7;
+      "rsasha256" = 8;
+      "rsasha512" = 10;
+      "ecc-gost" = 12;
+      "ecdsap256sha256" = 13;
+      "ecdsap384sha384" = 14;
+      "ed25519" = 15;
+      "ed448" = 16;
+      "privatedns" = 253;
+      "privateoid" = 254;
+    };
+  };
+}