diff --git a/CHANGES b/CHANGES index aa88f7fcda..bc5e58647d 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,5 @@ +1987. [func] DS/DLV SHA256 digest algorithm support. [RT #15608] + 1986. [func] Report when a zone is removed. [RT #15849] 1985. [protocol] DLV has now been assigned a official type code of diff --git a/bin/dnssec/dnssec-signzone.c b/bin/dnssec/dnssec-signzone.c index 433f9046fc..53f85c0be9 100644 --- a/bin/dnssec/dnssec-signzone.c +++ b/bin/dnssec/dnssec-signzone.c @@ -16,7 +16,7 @@ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dnssec-signzone.c,v 1.196 2006/02/07 21:53:36 marka Exp $ */ +/* $Id: dnssec-signzone.c,v 1.197 2006/02/21 23:49:50 marka Exp $ */ /*! \file */ @@ -632,6 +632,16 @@ loadds(dns_name_t *name, isc_uint32_t ttl, dns_rdataset_t *dsset) { ttl, &ds, &tuple); check_result(result, "dns_difftuple_create"); dns_diff_append(&diff, &tuple); + + dns_rdata_reset(&ds); + result = dns_ds_buildrdata(name, &key, DNS_DSDIGEST_SHA256, + dsbuf, &ds); + check_result(result, "dns_ds_buildrdata"); + + result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, name, + ttl, &ds, &tuple); + check_result(result, "dns_difftuple_create"); + dns_diff_append(&diff, &tuple); } result = dns_diff_apply(&diff, db, ver); check_result(result, "dns_diff_apply"); @@ -1585,6 +1595,19 @@ writeset(const char *prefix, dns_rdatatype_t type) { ds.type = dns_rdatatype_dlv; result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, name, 0, &ds, &tuple); + check_result(result, "dns_difftuple_create"); + dns_diff_append(&diff, &tuple); + + dns_rdata_reset(&ds); + result = dns_ds_buildrdata(gorigin, &rdata, + DNS_DSDIGEST_SHA256, + dsbuf, &ds); + check_result(result, "dns_ds_buildrdata"); + if (type == dns_rdatatype_dlv) + ds.type = dns_rdatatype_dlv; + result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, + name, 0, &ds, &tuple); + } else result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, gorigin, zonettl, diff --git a/lib/dns/ds.c b/lib/dns/ds.c index a952079ec0..38775401a5 100644 --- a/lib/dns/ds.c +++ b/lib/dns/ds.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: ds.c,v 1.7 2005/04/27 04:56:45 sra Exp $ */ +/* $Id: ds.c,v 1.8 2006/02/21 23:49:51 marka Exp $ */ /*! \file */ @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -42,10 +43,9 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, unsigned int digest_type, unsigned char *buffer, dns_rdata_t *rdata) { - isc_sha1_t sha1; dns_fixedname_t fname; dns_name_t *name; - unsigned char digest[ISC_SHA1_DIGESTLENGTH]; + unsigned char digest[ISC_SHA256_DIGESTLENGTH]; isc_region_t r; isc_buffer_t b; dns_rdata_ds_t ds; @@ -53,7 +53,7 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, REQUIRE(key != NULL); REQUIRE(key->type == dns_rdatatype_dnskey); - if (digest_type != DNS_DSDIGEST_SHA1) + if (!dns_ds_digest_supported(digest_type)) return (ISC_R_NOTIMPLEMENTED); dns_fixedname_init(&fname); @@ -63,21 +63,34 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, memset(buffer, 0, DNS_DS_BUFFERSIZE); isc_buffer_init(&b, buffer, DNS_DS_BUFFERSIZE); - isc_sha1_init(&sha1); - dns_name_toregion(name, &r); - isc_sha1_update(&sha1, r.base, r.length); - dns_rdata_toregion(key, &r); - INSIST(r.length >= 4); - isc_sha1_update(&sha1, r.base, r.length); - isc_sha1_final(&sha1, digest); + if (digest_type == DNS_DSDIGEST_SHA1) { + isc_sha1_t sha1; + isc_sha1_init(&sha1); + dns_name_toregion(name, &r); + isc_sha1_update(&sha1, r.base, r.length); + dns_rdata_toregion(key, &r); + INSIST(r.length >= 4); + isc_sha1_update(&sha1, r.base, r.length); + isc_sha1_final(&sha1, digest); + } else { + isc_sha256_t sha256; + isc_sha256_init(&sha256); + dns_name_toregion(name, &r); + isc_sha256_update(&sha256, r.base, r.length); + dns_rdata_toregion(key, &r); + INSIST(r.length >= 4); + isc_sha256_update(&sha256, r.base, r.length); + isc_sha256_final(digest, &sha256); + } ds.mctx = NULL; ds.common.rdclass = key->rdclass; ds.common.rdtype = dns_rdatatype_ds; ds.algorithm = r.base[3]; ds.key_tag = dst_region_computeid(&r, ds.algorithm); - ds.digest_type = DNS_DSDIGEST_SHA1; - ds.length = ISC_SHA1_DIGESTLENGTH; + ds.digest_type = digest_type; + ds.length = (digest_type == DNS_DSDIGEST_SHA1) ? + ISC_SHA1_DIGESTLENGTH : ISC_SHA256_DIGESTLENGTH; ds.digest = digest; return (dns_rdata_fromstruct(rdata, key->rdclass, dns_rdatatype_ds, @@ -86,5 +99,6 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, isc_boolean_t dns_ds_digest_supported(unsigned int digest_type) { - return (ISC_TF(digest_type == DNS_DSDIGEST_SHA1)); + return (ISC_TF(digest_type == DNS_DSDIGEST_SHA1 || + digest_type == DNS_DSDIGEST_SHA256)); } diff --git a/lib/dns/include/dns/ds.h b/lib/dns/include/dns/ds.h index 809c5cf6e4..424b6627bc 100644 --- a/lib/dns/include/dns/ds.h +++ b/lib/dns/include/dns/ds.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: ds.h,v 1.6 2005/04/27 04:56:55 sra Exp $ */ +/* $Id: ds.h,v 1.7 2006/02/21 23:49:51 marka Exp $ */ #ifndef DNS_DS_H #define DNS_DS_H 1 @@ -25,11 +25,12 @@ #include #define DNS_DSDIGEST_SHA1 (1) +#define DNS_DSDIGEST_SHA256 (2) /* - * Assuming SHA-1 digest type. + * Assuming SHA-256 digest type. */ -#define DNS_DS_BUFFERSIZE (24) +#define DNS_DS_BUFFERSIZE (36) ISC_LANG_BEGINDECLS @@ -53,7 +54,7 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, isc_boolean_t dns_ds_digest_supported(unsigned int digest_type); -/* +/*%< * Is this digest algorithm supported by dns_ds_buildrdata()? */ diff --git a/lib/dns/validator.c b/lib/dns/validator.c index 47694cd680..5534f4eb62 100644 --- a/lib/dns/validator.c +++ b/lib/dns/validator.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: validator.c,v 1.140 2006/01/04 23:50:24 marka Exp $ */ +/* $Id: validator.c,v 1.141 2006/02/21 23:49:51 marka Exp $ */ /*! \file */ @@ -1499,6 +1499,7 @@ dlv_validatezonekey(dns_validator_t *val) { isc_boolean_t supported_algorithm; isc_result_t result; unsigned char dsbuf[DNS_DS_BUFFERSIZE]; + isc_uint8_t digest_type; validator_log(val, ISC_LOG_DEBUG(3), "dlv_validatezonekey"); @@ -1509,6 +1510,31 @@ dlv_validatezonekey(dns_validator_t *val) { */ supported_algorithm = ISC_FALSE; + /* + * If DNS_DSDIGEST_SHA256 is present we are required to prefer + * it over DNS_DSDIGEST_SHA1. This in practice means that we + * need to ignore DNS_DSDIGEST_SHA1 if a DNS_DSDIGEST_SHA256 + * is present. + */ + digest_type = DNS_DSDIGEST_SHA1; + for (result = dns_rdataset_first(val->dsset); + result == ISC_R_SUCCESS; + result = dns_rdataset_next(val->dsset)) { + dns_rdata_reset(&dlvrdata); + dns_rdataset_current(&val->dlv, &dlvrdata); + dns_rdata_tostruct(&dlvrdata, &dlv, NULL); + + if (!dns_resolver_algorithm_supported(val->view->resolver, + val->event->name, + dlv.algorithm)) + continue; + + if (dlv.digest_type == DNS_DSDIGEST_SHA256) { + digest_type = DNS_DSDIGEST_SHA256; + break; + } + } + for (result = dns_rdataset_first(&val->dlv); result == ISC_R_SUCCESS; result = dns_rdataset_next(&val->dlv)) @@ -1520,6 +1546,10 @@ dlv_validatezonekey(dns_validator_t *val) { if (!dns_resolver_digest_supported(val->view->resolver, dlv.digest_type)) continue; + + if (dlv.digest_type != digest_type) + continue; + if (!dns_resolver_algorithm_supported(val->view->resolver, val->event->name, dlv.algorithm)) @@ -1643,6 +1673,7 @@ validatezonekey(dns_validator_t *val) { dst_key_t *dstkey; isc_boolean_t supported_algorithm; isc_boolean_t atsep = ISC_FALSE; + isc_uint8_t digest_type; /* * Caller must be holding the validator lock. @@ -1812,6 +1843,31 @@ validatezonekey(dns_validator_t *val) { supported_algorithm = ISC_FALSE; + /* + * If DNS_DSDIGEST_SHA256 is present we are required to prefer + * it over DNS_DSDIGEST_SHA1. This in practice means that we + * need to ignore DNS_DSDIGEST_SHA1 if a DNS_DSDIGEST_SHA256 + * is present. + */ + digest_type = DNS_DSDIGEST_SHA1; + for (result = dns_rdataset_first(val->dsset); + result == ISC_R_SUCCESS; + result = dns_rdataset_next(val->dsset)) { + dns_rdata_reset(&dsrdata); + dns_rdataset_current(val->dsset, &dsrdata); + dns_rdata_tostruct(&dsrdata, &ds, NULL); + + if (!dns_resolver_algorithm_supported(val->view->resolver, + val->event->name, + ds.algorithm)) + continue; + + if (ds.digest_type == DNS_DSDIGEST_SHA256) { + digest_type = DNS_DSDIGEST_SHA256; + break; + } + } + for (result = dns_rdataset_first(val->dsset); result == ISC_R_SUCCESS; result = dns_rdataset_next(val->dsset)) @@ -1824,6 +1880,9 @@ validatezonekey(dns_validator_t *val) { ds.digest_type)) continue; + if (ds.digest_type != digest_type) + continue; + if (!dns_resolver_algorithm_supported(val->view->resolver, val->event->name, ds.algorithm)) diff --git a/lib/dns/win32/libdns.def b/lib/dns/win32/libdns.def index da8e61758d..2a85e20707 100644 --- a/lib/dns/win32/libdns.def +++ b/lib/dns/win32/libdns.def @@ -188,6 +188,7 @@ dns_dnssec_verify dns_dnssec_verify2 dns_dnssec_verifymessage dns_ds_buildrdata +dns_ds_digest_supported dns_dumpctx_detach dns_fwdtable_add dns_fwdtable_create