From: Ondřej Surý Date: Wed, 8 Jul 2026 08:34:50 +0000 (+0200) Subject: Size DNSKEY rdata buffers by the maximum rdata length X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=7e22ba9ff47936b914f2807fd40b64cdf51117b0;p=thirdparty%2Fbind9.git Size DNSKEY rdata buffers by the maximum rdata length Post-quantum signature algorithms have public keys that do not fit into the fixed DST_KEY_MAXSIZE (1280 octets) buffers used when converting a dst_key to DNSKEY rdata. Use DNS_RDATA_MAXLENGTH sized buffers instead, which no DNSKEY rdata can exceed by construction. Assisted-by: Claude:claude-fable-5 --- diff --git a/bin/dnssec/dnssec-ksr.c b/bin/dnssec/dnssec-ksr.c index e44d8e368a2..904debd5708 100644 --- a/bin/dnssec/dnssec-ksr.c +++ b/bin/dnssec/dnssec-ksr.c @@ -573,7 +573,7 @@ print_dnskeys(dns_kasp_key_t *kaspkey, dns_ttl_t ttl, dns_dnsseckeylist_t *keys, isc_buffer_t *newbuf = NULL; dns_rdata_t *rdata = NULL; isc_region_t r; - unsigned char rdatabuf[DST_KEY_MAXSIZE]; + unsigned char rdatabuf[DNS_RDATA_MAXLENGTH]; rdata = isc_mem_get(isc_g_mctx, sizeof(*rdata)); dns_rdata_init(rdata); @@ -744,8 +744,7 @@ get_keymaterial(ksr_ctx_t *ksr, dns_kasp_t *kasp, isc_stdtime_t inception, isc_region_t r; isc_region_t rcds; isc_stdtime_t pub = 0, del = 0; - unsigned char kskbuf[DST_KEY_MAXSIZE]; - unsigned char cdnskeybuf[DST_KEY_MAXSIZE]; + unsigned char rdatabuf[DNS_RDATA_MAXLENGTH]; unsigned char cdsbuf[DNS_DS_BUFFERSIZE]; /* KSK */ @@ -766,7 +765,7 @@ get_keymaterial(ksr_ctx_t *ksr, dns_kasp_t *kasp, isc_stdtime_t inception, rdata = isc_mem_get(isc_g_mctx, sizeof(*rdata)); dns_rdata_init(rdata); - isc_buffer_init(&buf, kskbuf, sizeof(kskbuf)); + isc_buffer_init(&buf, rdatabuf, sizeof(rdatabuf)); CHECK(dst_key_todns(dk->key, &buf)); isc_buffer_usedregion(&buf, &r); isc_buffer_allocate(isc_g_mctx, &newbuf, r.length); @@ -810,7 +809,7 @@ get_keymaterial(ksr_ctx_t *ksr, dns_kasp_t *kasp, isc_stdtime_t inception, rdata = isc_mem_get(isc_g_mctx, sizeof(*rdata)); dns_rdata_init(rdata); - isc_buffer_init(&buf, cdnskeybuf, sizeof(cdnskeybuf)); + isc_buffer_init(&buf, rdatabuf, sizeof(rdatabuf)); CHECK(dst_key_todns(dk->key, &buf)); isc_buffer_usedregion(&buf, &r); isc_buffer_allocate(isc_g_mctx, &newbuf, r.length); diff --git a/bin/dnssec/dnssec-signzone.c b/bin/dnssec/dnssec-signzone.c index 0a526a54942..a537e822431 100644 --- a/bin/dnssec/dnssec-signzone.c +++ b/bin/dnssec/dnssec-signzone.c @@ -2942,7 +2942,7 @@ writeset(const char *prefix, dns_rdatatype_t type) { isc_region_t r; isc_result_t result; unsigned char dsbuf[DNS_DS_BUFFERSIZE]; - unsigned char keybuf[DST_KEY_MAXSIZE]; + unsigned char keybuf[DNS_RDATA_MAXLENGTH]; unsigned int filenamelen; const dns_master_style_t *style = (type == dns_rdatatype_dnskey) ? masterstyle diff --git a/lib/dns/dnssec.c b/lib/dns/dnssec.c index 8a0effb2d91..3b4c6672a6a 100644 --- a/lib/dns/dnssec.c +++ b/lib/dns/dnssec.c @@ -1725,7 +1725,7 @@ publish_key(dns_diff_t *diff, dns_dnsseckey_t *key, const dns_name_t *origin, dns_ttl_t ttl, isc_mem_t *mctx, void (*report)(const char *, ...) ISC_FORMAT_PRINTF(1, 2)) { isc_result_t result = ISC_R_SUCCESS; - unsigned char buf[DST_KEY_MAXSIZE]; + unsigned char buf[DNS_RDATA_MAXLENGTH]; char keystr[DST_KEY_FORMATSIZE]; dns_rdata_t dnskey = DNS_RDATA_INIT; @@ -1760,7 +1760,7 @@ remove_key(dns_diff_t *diff, dns_dnsseckey_t *key, const dns_name_t *origin, dns_ttl_t ttl, isc_mem_t *mctx, const char *reason, void (*report)(const char *, ...) ISC_FORMAT_PRINTF(1, 2)) { isc_result_t result = ISC_R_SUCCESS; - unsigned char buf[DST_KEY_MAXSIZE]; + unsigned char buf[DNS_RDATA_MAXLENGTH]; dns_rdata_t dnskey = DNS_RDATA_INIT; char alg[80]; char namebuf[DNS_NAME_FORMATSIZE]; @@ -1875,7 +1875,7 @@ dns_dnssec_syncupdate(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *rmkeys, isc_stdtime_t now, dns_kasp_digestlist_t *digests, bool gencdnskey, dns_ttl_t ttl, dns_diff_t *diff, isc_mem_t *mctx) { - unsigned char keybuf[DST_KEY_MAXSIZE]; + unsigned char keybuf[DNS_RDATA_MAXLENGTH]; isc_result_t result = DNS_R_UNCHANGED; dns_ttl_t cdsttl = ttl; dns_ttl_t cdnskeyttl = ttl; diff --git a/lib/dns/dst_api.c b/lib/dns/dst_api.c index 1f58fbd9e94..12aa69b34bd 100644 --- a/lib/dns/dst_api.c +++ b/lib/dns/dst_api.c @@ -1155,7 +1155,7 @@ comparekeys(const dst_key_t *key1, const dst_key_t *key2, static bool pub_compare(const dst_key_t *key1, const dst_key_t *key2) { isc_result_t result; - unsigned char buf1[DST_KEY_MAXSIZE], buf2[DST_KEY_MAXSIZE]; + unsigned char buf1[DNS_RDATA_MAXLENGTH], buf2[DNS_RDATA_MAXLENGTH]; isc_buffer_t b1, b2; isc_region_t r1, r2; @@ -1926,8 +1926,12 @@ write_public_key(const dst_key_t *key, int type, const char *directory) { isc_region_t r; char tmpname[NAME_MAX]; char filename[NAME_MAX]; - unsigned char key_array[DST_KEY_MAXSIZE]; - char text_array[DST_KEY_MAXTEXTSIZE]; + unsigned char key_array[DNS_RDATA_MAXLENGTH]; + /* + * Big enough for the base64 expansion of the key data with + * whitespace separators, plus the other rdata fields. + */ + char text_array[DNS_RDATA_MAXLENGTH * 2]; char class_array[10]; isc_result_t result; dns_rdata_t rdata = DNS_RDATA_INIT; @@ -2069,7 +2073,7 @@ buildfilename(dns_name_t *name, dns_keytag_t id, unsigned int alg, static isc_result_t computeid(dst_key_t *key) { isc_buffer_t dnsbuf; - unsigned char dns_array[DST_KEY_MAXSIZE]; + unsigned char dns_array[DNS_RDATA_MAXLENGTH]; isc_region_t r; isc_buffer_init(&dnsbuf, dns_array, sizeof(dns_array)); diff --git a/lib/dns/include/dns/dnssec.h b/lib/dns/include/dns/dnssec.h index 11d2759c7d0..be79431b1c4 100644 --- a/lib/dns/include/dns/dnssec.h +++ b/lib/dns/include/dns/dnssec.h @@ -102,7 +102,8 @@ dns_dnssec_make_dnskey(dst_key_t *key, unsigned char *buf, int bufsize, * Requires: *\li 'key' is not NULL *\li 'buf' is not NULL - *\li 'bufsize' equals DST_KEY_MAXSIZE + *\li 'bufsize' is large enough to hold the DNSKEY rdata; + * DNS_RDATA_MAXLENGTH is always sufficient *\li 'target' is not NULL * * Returns: diff --git a/lib/dns/keytable.c b/lib/dns/keytable.c index c6f39302f9d..9302d05f16a 100644 --- a/lib/dns/keytable.c +++ b/lib/dns/keytable.c @@ -424,7 +424,7 @@ dns_keytable_deletekey(dns_keytable_t *keytable, const dns_name_t *keyname, isc_result_t result; dns_keynode_t *knode = NULL; dns_rdata_t rdata = DNS_RDATA_INIT; - unsigned char data[4096], digest[DNS_DS_BUFFERSIZE]; + unsigned char data[DNS_RDATA_MAXLENGTH], digest[DNS_DS_BUFFERSIZE]; dns_rdata_ds_t ds; isc_buffer_t b; dns_qp_t *qp = NULL; diff --git a/lib/dns/view.c b/lib/dns/view.c index f5fcf239ed9..1c841a73662 100644 --- a/lib/dns/view.c +++ b/lib/dns/view.c @@ -1594,7 +1594,8 @@ dns_view_istrusted(dns_view_t *view, const dns_name_t *keyname, if (result == ISC_R_SUCCESS) { if (dns_keynode_dsset(knode, &dsset)) { dns_rdata_t rdata = DNS_RDATA_INIT; - unsigned char data[4096], digest[DNS_DS_BUFFERSIZE]; + unsigned char data[DNS_RDATA_MAXLENGTH]; + unsigned char digest[DNS_DS_BUFFERSIZE]; dns_rdata_dnskey_t tmpkey = *dnskey; dns_rdata_ds_t ds; isc_buffer_t b; diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 2fe411c2222..3d9ac836501 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -13841,7 +13841,7 @@ cdnskey_inuse(dns_zone_t *zone, dns_rdata_t *rdata, ISC_LIST_FOREACH(*keylist, k, link) { dns_rdata_t cdnskeyrdata = DNS_RDATA_INIT; - unsigned char keybuf[DST_KEY_MAXSIZE]; + unsigned char keybuf[DNS_RDATA_MAXLENGTH]; result = dns_dnssec_make_dnskey(k->key, keybuf, sizeof(keybuf), &cdnskeyrdata); @@ -13879,7 +13879,7 @@ cds_inuse(dns_zone_t *zone, dns_rdata_t *rdata, dns_dnsseckeylist_t *keylist, ISC_LIST_FOREACH(*keylist, k, link) { dns_rdata_t dnskey = DNS_RDATA_INIT; dns_rdata_t cdsrdata = DNS_RDATA_INIT; - unsigned char keybuf[DST_KEY_MAXSIZE]; + unsigned char keybuf[DNS_RDATA_MAXLENGTH]; unsigned char cdsbuf[DNS_DS_BUFFERSIZE]; if (dst_key_id(k->key) != cds.key_tag || @@ -17234,7 +17234,7 @@ checkds_done(void *arg) { dns_rdata_t rdata = DNS_RDATA_INIT; isc_result_t r; unsigned char dsbuf[DNS_DS_BUFFERSIZE]; - unsigned char keybuf[DST_KEY_MAXSIZE]; + unsigned char keybuf[DNS_RDATA_MAXLENGTH]; dns_rdataset_current(ds_rrset, &rdata); r = dns_rdata_tostruct(&rdata, &ds, NULL);