commit f4fc3edca8663e501320def0b04ec78a8f484a39
parent de87b0f9435558cb03a1f7e2f2bece3bcbf0c09c
Author: Aluísio Augusto Silva Gonçalves <aluisio@aasg.name>
Date: Thu, 19 Nov 2020 22:56:04 -0300
parent de87b0f9435558cb03a1f7e2f2bece3bcbf0c09c
Author: Aluísio Augusto Silva Gonçalves <aluisio@aasg.name>
Date: Thu, 19 Nov 2020 22:56:04 -0300
Add support for DNSKEY and DS records
4 files changed, 141 insertions(+), 0 deletions(-)
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; + }; + }; +}