Commit a1ad78ae06 for bind
commit a1ad78ae0656c65026c609e6b3d1add5faed88cf
Author: Martin Basti <mbasti@isc.org>
Date: Tue Sep 1 08:44:29 2026 +0000
Use dst_algorithm_format for dnssec-policy and tool algorithms
dnssec-keygen, dnssec-keyfromlabel, dnssec-ksr and the dnssec-policy
nsec3 check format a dst_algorithm_t parsed by dst_algorithm_fromtext,
so passing it to dns_secalg_format truncated PRIVATEOID based
algorithms to 8 bits and printed the wrong name.
Two existing dst_algorithm_format callers still sized their buffers
with DNS_SECALG_FORMATSIZE; switch them to DST_ALG_FORMATSIZE so all
callers share one size.
Assisted-by: Claude:claude-fable-5
diff --git a/bin/dnssec/dnssec-keyfromlabel.c b/bin/dnssec/dnssec-keyfromlabel.c
index ac3871df96..4aeb58a5a4 100644
--- a/bin/dnssec/dnssec-keyfromlabel.c
+++ b/bin/dnssec/dnssec-keyfromlabel.c
@@ -35,7 +35,6 @@
#include <dns/lib.h>
#include <dns/name.h>
#include <dns/rdataclass.h>
-#include <dns/secalg.h>
#include <dst/dst.h>
@@ -521,8 +520,8 @@ main(int argc, char **argv) {
switch (alg) {
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1: {
- char algstr[DNS_SECALG_FORMATSIZE];
- dns_secalg_format(alg, algstr, sizeof(algstr));
+ char algstr[DST_ALG_FORMATSIZE];
+ dst_algorithm_format(alg, algstr, sizeof(algstr));
fprintf(stderr,
"WARNING: DNSKEY algorithm '%s' is deprecated. Please "
"migrate to another algorithm\n",
@@ -553,9 +552,9 @@ main(int argc, char **argv) {
if (result != ISC_R_SUCCESS) {
char namestr[DNS_NAME_FORMATSIZE];
- char algstr[DNS_SECALG_FORMATSIZE];
+ char algstr[DST_ALG_FORMATSIZE];
dns_name_format(name, namestr, sizeof(namestr));
- dns_secalg_format(alg, algstr, sizeof(algstr));
+ dst_algorithm_format(alg, algstr, sizeof(algstr));
fatal("failed to get key %s/%s: %s", namestr, algstr,
isc_result_totext(result));
UNREACHABLE();
diff --git a/bin/dnssec/dnssec-keygen.c b/bin/dnssec/dnssec-keygen.c
index 4abf054823..ed307c6093 100644
--- a/bin/dnssec/dnssec-keygen.c
+++ b/bin/dnssec/dnssec-keygen.c
@@ -54,7 +54,6 @@
#include <dns/lib.h>
#include <dns/name.h>
#include <dns/rdataclass.h>
-#include <dns/secalg.h>
#include <dst/dst.h>
@@ -230,7 +229,7 @@ progress(int p) {
static void
keygen(keygen_ctx_t *ctx, const char *keyname) {
char filename[255];
- char algstr[DNS_SECALG_FORMATSIZE];
+ char algstr[DST_ALG_FORMATSIZE];
uint16_t flags = 0;
bool conflict = false;
bool show_progress = false;
@@ -451,7 +450,7 @@ keygen(keygen_ctx_t *ctx, const char *keyname) {
switch (ctx->alg) {
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
- dns_secalg_format(ctx->alg, algstr, sizeof(algstr));
+ dst_algorithm_format(ctx->alg, algstr, sizeof(algstr));
fprintf(stderr,
"WARNING: DNSKEY algorithm '%s' is deprecated. Please "
"migrate to another algorithm\n",
diff --git a/bin/dnssec/dnssec-ksr.c b/bin/dnssec/dnssec-ksr.c
index c43d520432..6346fe967b 100644
--- a/bin/dnssec/dnssec-ksr.c
+++ b/bin/dnssec/dnssec-ksr.c
@@ -304,7 +304,7 @@ create_key(ksr_ctx_t *ksr, dns_kasp_t *kasp, dns_kasp_key_t *kaspkey,
bool conflict = false;
bool freekey = false;
bool show_progress = true;
- char algstr[DNS_SECALG_FORMATSIZE];
+ char algstr[DST_ALG_FORMATSIZE];
char filename[PATH_MAX + 1];
char timestr[26]; /* Minimal buf as per ctime_r() spec. */
dst_key_t *key = NULL;
@@ -530,7 +530,7 @@ print_rdata(dns_rdataset_t *rrset) {
static isc_stdtime_t
print_dnskeys(dns_kasp_key_t *kaspkey, dns_ttl_t ttl, dns_dnsseckeylist_t *keys,
isc_stdtime_t inception, isc_stdtime_t next_inception) {
- char algstr[DNS_SECALG_FORMATSIZE];
+ char algstr[DST_ALG_FORMATSIZE];
char timestr[26]; /* Minimal buf as per ctime_r() spec. */
dns_rdatalist_t *rdatalist = NULL;
dns_rdataset_t rdataset = DNS_RDATASET_INIT;
@@ -538,8 +538,8 @@ print_dnskeys(dns_kasp_key_t *kaspkey, dns_ttl_t ttl, dns_dnsseckeylist_t *keys,
isc_stdtime_t next_bundle = next_inception;
isc_stdtime_tostring(inception, timestr, sizeof(timestr));
- dns_secalg_format(dns_kasp_key_algorithm(kaspkey), algstr,
- sizeof(algstr));
+ dst_algorithm_format(dns_kasp_key_algorithm(kaspkey), algstr,
+ sizeof(algstr));
/* Fetch matching key pair. */
rdatalist = isc_mem_get(isc_g_mctx, sizeof(*rdatalist));
diff --git a/bin/tests/system/ksr/ns1/named.conf.j2 b/bin/tests/system/ksr/ns1/named.conf.j2
index 1dd240f972..d556b3d087 100644
--- a/bin/tests/system/ksr/ns1/named.conf.j2
+++ b/bin/tests/system/ksr/ns1/named.conf.j2
@@ -23,6 +23,14 @@ dnssec-policy "csk" {
};
};
+dnssec-policy "privateoid" {
+ offline-ksk yes;
+ keys {
+ ksk lifetime unlimited algorithm RSASHA256OID 2048;
+ zsk lifetime P6M algorithm RSASHA256OID 2048;
+ };
+};
+
dnssec-policy "unlimited" {
offline-ksk yes;
keys {
diff --git a/bin/tests/system/ksr/tests_ksr.py b/bin/tests/system/ksr/tests_ksr.py
index f8db9a81cf..b51f7805ad 100644
--- a/bin/tests/system/ksr/tests_ksr.py
+++ b/bin/tests/system/ksr/tests_ksr.py
@@ -36,6 +36,7 @@ pytestmark = pytest.mark.extra_artifacts(
"ksk-roll.test.*",
"last-bundle.test.*",
"past.test.*",
+ "privateoid.test.*",
"two-tone.test.*",
"unlimited.test.*",
"invalid-skr.test.*",
@@ -1565,3 +1566,54 @@ def test_ksr_oversize(ns1):
# - check if named is still running
ns1.rndc("status")
+
+
+def test_ksr_privateoid():
+ # A policy with a PRIVATEOID based algorithm: key files and error
+ # messages must use the full 16-bit DST algorithm, which used to be
+ # truncated to the 8-bit DNSSEC algorithm octet.
+ zone = "privateoid.test"
+ policy = "privateoid"
+ alg = 256 # DST_ALG_RSASHA256PRIVATEOID
+ size = 2048
+ n = 1
+
+ # create ksk
+ kskdir = "ns1/offline"
+ cmd = ksr(zone, policy, "keygen", options=f"-K {kskdir} -i now -e +1y -o")
+ ksks = isctest.kasp.keystr_to_keylist(cmd.out, kskdir)
+ assert len(ksks) == 1
+ check_keys(ksks, None, CONFIG, alg=alg, size=size)
+
+ # check that 'dnssec-ksr keygen' pregenerates right amount of keys
+ zskdir = "ns1"
+ cmd = ksr(zone, policy, "keygen", options=f"-K {zskdir} -i now -e +1y")
+ zsks = isctest.kasp.keystr_to_keylist(cmd.out, zskdir)
+ assert len(zsks) == 2
+ lifetime = timedelta(days=31 * 6)
+ check_keys(zsks, lifetime, CONFIG, alg=alg, size=size)
+
+ # check that 'dnssec-ksr request' creates correct ksr
+ now = zsks[0].get_timing("Created")
+ until = now + timedelta(days=365)
+ ksr_fname = f"{zone}.ksr.{n}"
+ ksr(
+ zone,
+ policy,
+ "request",
+ options=f"-K {zskdir} -i {now} -e +1y",
+ to_file=ksr_fname,
+ )
+ check_keysigningrequest(ksr_fname, zsks, now, until)
+
+ # check that 'dnssec-ksr request' errors if there are not enough
+ # keys, naming the private algorithm mnemonic
+ cmd = ksr(
+ zone,
+ policy,
+ "request",
+ options=f"-K {zskdir} -i {now} -e +2y",
+ raise_on_exception=False,
+ )
+ errmsg = f"dnssec-ksr: fatal: no {zone}/RSASHA256OID zsk key pair found for bundle"
+ assert errmsg in cmd.err
diff --git a/lib/isccfg/kaspconf.c b/lib/isccfg/kaspconf.c
index 30f9bc0057..297fa2ed0d 100644
--- a/lib/isccfg/kaspconf.c
+++ b/lib/isccfg/kaspconf.c
@@ -28,7 +28,6 @@
#include <dns/keystore.h>
#include <dns/keyvalues.h>
#include <dns/nsec3.h>
-#include <dns/secalg.h>
#include <dns/ttl.h>
#include <dst/dst.h>
@@ -441,8 +440,8 @@ cfg_nsec3param_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp,
dns_kasp_thaw(kasp);
if (badalg > 0) {
- char algstr[DNS_SECALG_FORMATSIZE];
- dns_secalg_format((dns_secalg_t)badalg, algstr, sizeof(algstr));
+ char algstr[DST_ALG_FORMATSIZE];
+ dst_algorithm_format(badalg, algstr, sizeof(algstr));
if (log_errors) {
kaspcfg_log(obj, ISC_LOG_ERROR,
"dnssec-policy: cannot use nsec3 with "