Commit c4dc71ed25 for bind
commit c4dc71ed258aa38f0765bb34f759d4c25370259f
Author: Evan Hunt <each@isc.org>
Date: Wed Sep 17 03:54:51 2025 -0700
Add more ADT flag support in dnssec tools
An ADT flag in a DNSSEC key will be used to indicate to validators
that they must check for the nonexistence of a DELEG record before
accepting an NS delegation.
The flag can now be set using the "-fA" option in dnssec-keygen or
dnssec-keyfromlabel. (It was already possible to set the flag with a
dnssec-policy statement, either inside named or or via "dnssec-keygen -k".)
diff --git a/bin/dnssec/dnssec-keyfromlabel.c b/bin/dnssec/dnssec-keyfromlabel.c
index fc2f5b549a..eba45b1afc 100644
--- a/bin/dnssec/dnssec-keyfromlabel.c
+++ b/bin/dnssec/dnssec-keyfromlabel.c
@@ -112,7 +112,7 @@ main(int argc, char **argv) {
dst_key_t *key = NULL;
dns_fixedname_t fname;
dns_name_t *name;
- uint16_t flags = 0, kskflag = 0, revflag = 0;
+ uint16_t flags = 0, kskflag = 0, revflag = 0, adtflag = 0;
dst_algorithm_t alg;
int ch;
isc_result_t result;
@@ -171,6 +171,8 @@ main(int argc, char **argv) {
kskflag = DNS_KEYFLAG_KSK;
} else if (toupper(c) == 'R') {
revflag = DNS_KEYFLAG_REVOKE;
+ } else if (toupper(c) == 'A') {
+ adtflag = DNS_KEYFLAG_ADT;
} else {
fatal("unknown flag '%s'",
isc_commandline_argument);
@@ -544,6 +546,7 @@ main(int argc, char **argv) {
flags |= DNS_KEYOWNER_ZONE; /* DNSKEY: name type ZONE */
flags |= kskflag;
flags |= revflag;
+ flags |= adtflag;
}
isc_buffer_init(&buf, filename, sizeof(filename) - 1);
diff --git a/bin/dnssec/dnssec-keyfromlabel.rst b/bin/dnssec/dnssec-keyfromlabel.rst
index 8fb5672931..1bcad8faa0 100644
--- a/bin/dnssec/dnssec-keyfromlabel.rst
+++ b/bin/dnssec/dnssec-keyfromlabel.rst
@@ -82,7 +82,8 @@ Options
.. option:: -f flag
This option sets the specified flag in the ``flag`` field of the KEY/DNSKEY record.
- The only recognized flags are KSK (Key-Signing Key) and REVOKE.
+ The only recognized flags are KSK (Key-Signing Key), ADT (Authoritative
+ Delegation Types), and REVOKE.
.. option:: -G
diff --git a/bin/dnssec/dnssec-keygen.c b/bin/dnssec/dnssec-keygen.c
index 57dbf4d25a..e2cb16d4e7 100644
--- a/bin/dnssec/dnssec-keygen.c
+++ b/bin/dnssec/dnssec-keygen.c
@@ -90,6 +90,7 @@ struct keygen_ctx {
bool wantzsk;
bool wantksk;
bool wantrev;
+ bool wantadt;
dst_algorithm_t alg;
/* timing data */
int prepub;
@@ -165,7 +166,8 @@ usage(int ret) {
" algorithm and usage (ZSK or KSK)\n");
fprintf(stderr, " -c <class>: (default: IN)\n");
fprintf(stderr, " -d <digest bits> (0 => max, default)\n");
- fprintf(stderr, " -f <keyflag>: ZSK | KSK | REVOKE\n");
+ fprintf(stderr, " -f <keyflag>: [-]ZSK | [-]KSK | [-]ADT | "
+ "[-]REVOKE\n");
fprintf(stderr, " -F: FIPS mode\n");
fprintf(stderr, " -L <ttl>: default key TTL\n");
fprintf(stderr, " -M <min>:<max>: allowed Key ID range\n");
@@ -717,10 +719,10 @@ int
main(int argc, char **argv) {
char *algname = NULL, *freeit = NULL;
char *classname = NULL;
- char *endp;
+ char *endp = NULL;
isc_result_t result;
isc_textregion_t r;
- unsigned char c;
+ uint8_t c;
int ch;
keygen_ctx_t ctx = {
@@ -794,13 +796,15 @@ main(int argc, char **argv) {
fatal("%s", isc_result_totext(DST_R_NOENGINE));
break;
case 'f':
- c = (unsigned char)(isc_commandline_argument[0]);
+ c = (uint8_t)(isc_commandline_argument[0]);
if (toupper(c) == 'K') {
ctx.wantksk = true;
} else if (toupper(c) == 'Z') {
ctx.wantzsk = true;
} else if (toupper(c) == 'R') {
ctx.wantrev = true;
+ } else if (toupper(c) == 'A') {
+ ctx.wantadt = true;
} else {
fatal("unknown flag '%s'",
isc_commandline_argument);
@@ -1138,6 +1142,9 @@ main(int argc, char **argv) {
if (ctx.wantrev) {
ctx.flags |= DNS_KEYFLAG_REVOKE;
}
+ if (ctx.wantadt) {
+ ctx.flags |= DNS_KEYFLAG_ADT;
+ }
}
keygen(&ctx, argv[isc_commandline_index]);
diff --git a/bin/dnssec/dnssec-keygen.rst b/bin/dnssec/dnssec-keygen.rst
index 9efea3ea67..19b3e93f1f 100644
--- a/bin/dnssec/dnssec-keygen.rst
+++ b/bin/dnssec/dnssec-keygen.rst
@@ -83,14 +83,21 @@ Options
.. option:: -f flag
- This option sets the specified flag in the flag field of the KEY/DNSKEY record.
- The only recognized flags are ZSK (Zone-Signing Key), KSK (Key-Signing Key)
- and REVOKE.
+ This option sets (or unsets) the specified flag in the flag field of the
+ KEY/DNSKEY record. The only recognized flags are ZSK (Zone-Signing
+ Key), KSK (Key-Signing Key), ADT (Authoritative Delegation Types), and
+ REVOKE.
- Note that ZSK is not a physical flag in the DNSKEY record, it is merely used
- to explicitly tell that you want to create a ZSK. Setting :option:`-f` in
- conjunction with :option:`-k` will result in generating keys that only
- match the given role set with this option.
+ Flags are case-insensitive and can be abbreviated to a single letter.
+ Note that only one flag can be specified per ``-f`` option. For example,
+ ``-fa -fk`` sets ADT and KSK, but ``-fak`` only sets ADT and has no
+ effect on KSK.
+
+ ZSK is not a physical flag in the DNSKEY record, it is merely used
+ to explicitly state that you want to create a ZSK.
+
+ Setting :option:`-f` in conjunction with :option:`-k` will result in
+ generating keys that only match the given role set with this option.
.. option:: -F
@@ -114,13 +121,13 @@ Options
.. option:: -k policy
- This option creates keys for a specific ``dnssec-policy``. If a policy uses multiple keys,
- :program:`dnssec-keygen` generates multiple keys. This also
- creates a ".state" file to keep track of the key state.
+ This option creates keys for a specific ``dnssec-policy``. If a policy
+ uses multiple keys, :program:`dnssec-keygen` generates multiple keys.
+ This also creates a ".state" file to keep track of the key state.
- This option creates keys according to the ``dnssec-policy`` configuration, hence
- it cannot be used at the same time as many of the other options that
- :program:`dnssec-keygen` provides.
+ This option creates keys according to the ``dnssec-policy``
+ configuration, hence it cannot be used at the same time as many of the
+ other options that :program:`dnssec-keygen` provides.
.. option:: -L ttl
diff --git a/bin/named/server.c b/bin/named/server.c
index f588dbe363..143ff506a2 100644
--- a/bin/named/server.c
+++ b/bin/named/server.c
@@ -14457,7 +14457,9 @@ mkey_dumpzone(dns_view_t *view, isc_buffer_t *text) {
CHECK(putstr(text, buf));
revoked = ((kd.flags & DNS_KEYFLAG_REVOKE) != 0);
- snprintf(buf, sizeof(buf), "\n\tflags:%s%s%s",
+ snprintf(buf, sizeof(buf), "\n\tflags:%s%s%s%s",
+ ((kd.flags & DNS_KEYFLAG_ADT) != 0) ? " ADT"
+ : "",
revoked ? " REVOKE" : "",
((kd.flags & DNS_KEYFLAG_KSK) != 0) ? " SEP"
: "",
diff --git a/bin/tests/system/dnssectools/tests.sh b/bin/tests/system/dnssectools/tests.sh
index 8170a329ff..c23cd3604d 100644
--- a/bin/tests/system/dnssectools/tests.sh
+++ b/bin/tests/system/dnssectools/tests.sh
@@ -1126,5 +1126,21 @@ test $(wc -l <dsfromkey.out.test$n) -eq 1 || ret=1
n=$((n + 1))
test "$ret" -eq 0 || echo_i "failed"
+echo_i "check dnssec-keygen flag options ($n)"
+ret=0
+zone=example
+key=$("$KEYGEN" -K signer -f ZSK -q -a $DEFAULT_ALGORITHM "$zone")
+grep -q 256 "signer/${key}.key" || ret=1
+key=$("$KEYGEN" -K signer -f KSK -q -a $DEFAULT_ALGORITHM "$zone")
+grep -q 257 "signer/${key}.key" || ret=1
+key=$("$KEYGEN" -K signer -f ADT -q -a $DEFAULT_ALGORITHM "$zone")
+grep -q 258 "signer/${key}.key" || ret=1
+key=$("$KEYGEN" -K signer -f ADT -f KSK -q -a $DEFAULT_ALGORITHM "$zone")
+grep -q 259 "signer/${key}.key" || ret=1
+key=$("$KEYGEN" -K signer -f KSK -f REVOKE -q -a $DEFAULT_ALGORITHM "$zone")
+grep -q 385 "signer/${key}.key" || ret=1
+n=$((n + 1))
+test "$ret" -eq 0 || echo_i "failed"
+
echo_i "exit status: $status"
[ $status -eq 0 ] || exit 1
diff --git a/bin/tests/system/isctest/kasp.py b/bin/tests/system/isctest/kasp.py
index 5a749f230e..fae5c9e2cd 100644
--- a/bin/tests/system/isctest/kasp.py
+++ b/bin/tests/system/isctest/kasp.py
@@ -191,7 +191,7 @@ class KeyProperties:
legacy: bool = False,
role: str = "csk",
ttl: int = 3600,
- flags: int = 257,
+ flags: int = KEYFLAG_SEP | KEYFLAG_ZONE,
keytag_min: int = 0,
keytag_max: int = 65535,
offset: timedelta | int = 0,
diff --git a/lib/dns/include/dns/keyvalues.h b/lib/dns/include/dns/keyvalues.h
index 322db9b06f..ef3ded5d2e 100644
--- a/lib/dns/include/dns/keyvalues.h
+++ b/lib/dns/include/dns/keyvalues.h
@@ -33,7 +33,12 @@
enum {
DNS_KEYOWNER_ZONE = 1 << 8, /* zone key (mandatory for DNSKEY). */
DNS_KEYFLAG_REVOKE = 1 << 7, /* key revoked (per rfc5011) */
- DNS_KEYFLAG_ADT = 1 << 1, /* DELEG */
+ DNS_KEYFLAG_ADT = 1 << 1, /* authoritative delegation types:
+ zone may contain DELEG.
+ this tells validators that a
+ nonexistence proof for a DELEG
+ record will be included with NS
+ referrals and must be verified. */
DNS_KEYFLAG_KSK = 1 << 0, /* key signing key */
};
diff --git a/lib/dns/keymgr.c b/lib/dns/keymgr.c
index a3737ee40c..80a3a033a0 100644
--- a/lib/dns/keymgr.c
+++ b/lib/dns/keymgr.c
@@ -484,7 +484,6 @@ keymgr_keyid_conflict(dst_key_t *newkey, uint16_t min, uint16_t max,
* Create a new key for 'origin' given the kasp key configuration 'kkey'.
* This will check for key id collisions with keys in 'keylist'.
* The created key will be stored in 'dst_key'.
- *
*/
static isc_result_t
keymgr_createkey(dns_kasp_key_t *kkey, const dns_name_t *origin,
diff --git a/lib/dns/rcode.c b/lib/dns/rcode.c
index 290d0528f8..b58b330d75 100644
--- a/lib/dns/rcode.c
+++ b/lib/dns/rcode.c
@@ -197,6 +197,8 @@ static struct keyflag {
{ "FLAG9", 0x0040, 0x0040 },
{ "FLAG10", 0x0020, 0x0020 },
{ "FLAG11", 0x0010, 0x0010 },
+ { "FLAG12", 0x0008, 0x0008 },
+ { "FLAG13", 0x0004, 0x0004 },
{ "SIG0", 0x0000, 0x000F },
{ "SIG1", 0x0001, 0x000F },
{ "SIG2", 0x0002, 0x000F },
@@ -213,6 +215,7 @@ static struct keyflag {
{ "SIG13", 0x000D, 0x000F },
{ "SIG14", 0x000E, 0x000F },
{ "SIG15", 0x000F, 0x000F },
+ { "ADT", DNS_KEYFLAG_ADT, DNS_KEYFLAG_ADT },
{ "KSK", DNS_KEYFLAG_KSK, DNS_KEYFLAG_KSK },
{ NULL, 0, 0 } };